aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/common/Android.mk8
-rw-r--r--tests/common/AndroidManifest.xml2
-rw-r--r--tests/common/src/com/android/tv/input/TunerHelper.java23
-rw-r--r--tests/common/src/com/android/tv/testing/ChannelNumberSubject.java66
-rw-r--r--tests/common/src/com/android/tv/testing/ComparableTester.java48
-rw-r--r--tests/common/src/com/android/tv/testing/ComparatorTester.java55
-rw-r--r--tests/common/src/com/android/tv/testing/Constants.java42
-rw-r--r--tests/common/src/com/android/tv/testing/DbTestingUtils.java40
-rw-r--r--tests/common/src/com/android/tv/testing/EpgTestData.java198
-rw-r--r--tests/common/src/com/android/tv/testing/FakeClock.java25
-rw-r--r--tests/common/src/com/android/tv/testing/FakeEpgFetcher.java57
-rw-r--r--tests/common/src/com/android/tv/testing/FakeEpgReader.java164
-rw-r--r--tests/common/src/com/android/tv/testing/FakeRemoteConfig.java55
-rw-r--r--tests/common/src/com/android/tv/testing/FakeTvInputManager.java117
-rw-r--r--tests/common/src/com/android/tv/testing/FakeTvInputManagerHelper.java32
-rw-r--r--tests/common/src/com/android/tv/testing/FakeTvProvider.java2605
-rw-r--r--tests/common/src/com/android/tv/testing/SingletonProvider.java37
-rw-r--r--tests/common/src/com/android/tv/testing/TestSingletonApp.java247
-rw-r--r--tests/common/src/com/android/tv/testing/activities/BaseMainActivityTestCase.java (renamed from tests/unit/src/com/android/tv/BaseMainActivityTestCase.java)52
-rw-r--r--tests/common/src/com/android/tv/testing/constants/ConfigConstants.java28
-rw-r--r--tests/common/src/com/android/tv/testing/constants/Constants.java47
-rw-r--r--tests/common/src/com/android/tv/testing/constants/TvContentRatingConstants.java (renamed from tests/common/src/com/android/tv/testing/TvContentRatingConstants.java)18
-rw-r--r--tests/common/src/com/android/tv/testing/data/ChannelInfo.java (renamed from tests/common/src/com/android/tv/testing/ChannelInfo.java)159
-rw-r--r--tests/common/src/com/android/tv/testing/data/ChannelUtils.java (renamed from tests/common/src/com/android/tv/testing/ChannelUtils.java)32
-rw-r--r--tests/common/src/com/android/tv/testing/data/ProgramInfo.java (renamed from tests/common/src/com/android/tv/testing/ProgramInfo.java)167
-rw-r--r--tests/common/src/com/android/tv/testing/data/ProgramUtils.java (renamed from tests/common/src/com/android/tv/testing/ProgramUtils.java)68
-rw-r--r--tests/common/src/com/android/tv/testing/dvr/DvrDataManagerInMemoryImpl.java (renamed from tests/unit/src/com/android/tv/dvr/DvrDataManagerInMemoryImpl.java)80
-rw-r--r--tests/common/src/com/android/tv/testing/dvr/RecordingTestUtils.java36
-rw-r--r--tests/common/src/com/android/tv/testing/robo/ContentProviders.java40
-rw-r--r--tests/common/src/com/android/tv/testing/robo/RobotTestAppHelper.java36
-rw-r--r--tests/common/src/com/android/tv/testing/shadows/ShadowMediaSession.java89
-rw-r--r--tests/common/src/com/android/tv/testing/testdata/TestData.java86
-rw-r--r--tests/common/src/com/android/tv/testing/testinput/ChannelState.java35
-rw-r--r--tests/common/src/com/android/tv/testing/testinput/ChannelStateData.java31
-rw-r--r--tests/common/src/com/android/tv/testing/testinput/TestInputControlConnection.java13
-rw-r--r--tests/common/src/com/android/tv/testing/testinput/TestInputControlUtils.java14
-rw-r--r--tests/common/src/com/android/tv/testing/testinput/TvTestInputConstants.java13
-rw-r--r--tests/common/src/com/android/tv/testing/uihelper/BaseUiDeviceHelper.java4
-rw-r--r--tests/common/src/com/android/tv/testing/uihelper/ByResource.java7
-rw-r--r--tests/common/src/com/android/tv/testing/uihelper/Constants.java6
-rw-r--r--tests/common/src/com/android/tv/testing/uihelper/DialogHelper.java9
-rw-r--r--tests/common/src/com/android/tv/testing/uihelper/LiveChannelsUiDeviceHelper.java44
-rw-r--r--tests/common/src/com/android/tv/testing/uihelper/MenuHelper.java89
-rw-r--r--tests/common/src/com/android/tv/testing/uihelper/SidePanelHelper.java11
-rw-r--r--tests/common/src/com/android/tv/testing/uihelper/UiDeviceAsserts.java73
-rw-r--r--tests/common/src/com/android/tv/testing/uihelper/UiDeviceUtils.java73
-rw-r--r--tests/common/src/com/android/tv/testing/uihelper/UiObject2Asserts.java29
-rw-r--r--tests/common/src/com/android/tv/testing/uihelper/UiObject2Utils.java7
-rw-r--r--tests/common/src/com/android/tv/testing/utils/TestUtils.java193
-rw-r--r--tests/common/src/com/android/tv/testing/utils/Utils.java (renamed from tests/common/src/com/android/tv/testing/Utils.java)39
-rw-r--r--tests/func/Android.mk6
-rw-r--r--tests/func/AndroidManifest.xml2
-rw-r--r--tests/func/src/com/android/tv/tests/ui/ChannelBannerViewTest.java49
-rw-r--r--tests/func/src/com/android/tv/tests/ui/ChannelSourcesTest.java72
-rw-r--r--tests/func/src/com/android/tv/tests/ui/LiveChannelsAppTest.java139
-rw-r--r--tests/func/src/com/android/tv/tests/ui/LiveChannelsTestCase.java103
-rw-r--r--tests/func/src/com/android/tv/tests/ui/LiveChannelsTestController.java231
-rw-r--r--tests/func/src/com/android/tv/tests/ui/ParentalControlsTest.java172
-rw-r--r--tests/func/src/com/android/tv/tests/ui/PlayControlsRowViewTest.java127
-rw-r--r--tests/func/src/com/android/tv/tests/ui/ProgramGuideTest.java34
-rw-r--r--tests/func/src/com/android/tv/tests/ui/TimeoutTest.java52
-rw-r--r--tests/func/src/com/android/tv/tests/ui/dvr/DvrLibraryTest.java377
-rw-r--r--tests/func/src/com/android/tv/tests/ui/sidepanel/CustomizeChannelListFragmentTest.java112
-rw-r--r--tests/input/Android.mk2
-rw-r--r--tests/input/AndroidManifest.xml2
-rw-r--r--tests/input/func.sh24
-rw-r--r--tests/input/jank.sh24
-rw-r--r--tests/input/src/com/android/tv/testinput/TestInputControl.java26
-rw-r--r--tests/input/src/com/android/tv/testinput/TestInputControlService.java4
-rw-r--r--tests/input/src/com/android/tv/testinput/TestTvInputService.java156
-rw-r--r--tests/input/src/com/android/tv/testinput/TestTvInputSetupActivity.java69
-rw-r--r--tests/input/src/com/android/tv/testinput/instrument/TestSetupInstrumentation.java41
-rwxr-xr-xtests/input/tools/get_test_logos.sh57
-rw-r--r--tests/input/unit.sh24
-rw-r--r--tests/jank/Android.mk6
-rw-r--r--tests/jank/AndroidManifest.xml2
-rw-r--r--tests/jank/src/com/android/tv/tests/jank/ChannelZappingJankTest.java21
-rw-r--r--tests/jank/src/com/android/tv/tests/jank/LiveChannelsTestCase.java10
-rw-r--r--tests/jank/src/com/android/tv/tests/jank/MenuJankTest.java16
-rw-r--r--tests/jank/src/com/android/tv/tests/jank/ProgramGuideJankTest.java39
-rw-r--r--tests/jank/src/com/android/tv/tests/jank/Utils.java9
-rw-r--r--tests/tunerscripts/measure-tuning-time.awk32
-rwxr-xr-xtests/tunerscripts/usbtuner-test.sh159
-rw-r--r--tests/unit/Android.mk7
-rw-r--r--tests/unit/AndroidManifest.xml2
-rw-r--r--tests/unit/src/com/android/tv/CurrentPositionMediatorTest.java40
-rw-r--r--tests/unit/src/com/android/tv/FeaturesTest.java12
-rw-r--r--tests/unit/src/com/android/tv/MainActivityTest.java50
-rw-r--r--tests/unit/src/com/android/tv/TimeShiftManagerTest.java46
-rw-r--r--tests/unit/src/com/android/tv/data/ChannelDataManagerTest.java325
-rw-r--r--tests/unit/src/com/android/tv/data/ChannelImplTest.java381
-rw-r--r--tests/unit/src/com/android/tv/data/ChannelNumberTest.java97
-rw-r--r--tests/unit/src/com/android/tv/data/ChannelTest.java312
-rw-r--r--tests/unit/src/com/android/tv/data/GenreItemTest.java94
-rw-r--r--tests/unit/src/com/android/tv/data/ProgramDataManagerTest.java542
-rw-r--r--tests/unit/src/com/android/tv/data/ProgramTest.java182
-rw-r--r--tests/unit/src/com/android/tv/data/TvInputNewComparatorTest.java83
-rw-r--r--tests/unit/src/com/android/tv/data/WatchedHistoryManagerTest.java59
-rw-r--r--tests/unit/src/com/android/tv/dvr/BaseDvrDataManagerTest.java90
-rw-r--r--tests/unit/src/com/android/tv/dvr/DvrDataManagerImplTest.java76
-rw-r--r--tests/unit/src/com/android/tv/dvr/DvrScheduleManagerTest.java693
-rw-r--r--tests/unit/src/com/android/tv/dvr/ScheduledRecordingTest.java117
-rw-r--r--tests/unit/src/com/android/tv/dvr/data/SeriesRecordingTest.java133
-rw-r--r--tests/unit/src/com/android/tv/dvr/provider/DvrDbSyncTest.java143
-rw-r--r--tests/unit/src/com/android/tv/dvr/provider/EpisodicProgramLoadTaskTest.java83
-rw-r--r--tests/unit/src/com/android/tv/dvr/recorder/DvrRecordingServiceTest.java93
-rw-r--r--tests/unit/src/com/android/tv/dvr/recorder/InputTaskSchedulerTest.java231
-rw-r--r--tests/unit/src/com/android/tv/dvr/recorder/RecordingTaskTest.java149
-rw-r--r--tests/unit/src/com/android/tv/dvr/recorder/ScheduledProgramReaperTest.java137
-rw-r--r--tests/unit/src/com/android/tv/dvr/recorder/SchedulerTest.java125
-rw-r--r--tests/unit/src/com/android/tv/dvr/recorder/SeriesRecordingSchedulerTest.java129
-rw-r--r--tests/unit/src/com/android/tv/dvr/ui/SortedArrayAdapterTest.java250
-rw-r--r--tests/unit/src/com/android/tv/experiments/ExperimentsTest.java53
-rw-r--r--tests/unit/src/com/android/tv/menu/MenuTest.java61
-rw-r--r--tests/unit/src/com/android/tv/menu/TvOptionsRowAdapterTest.java73
-rw-r--r--tests/unit/src/com/android/tv/recommendation/ChannelRecordTest.java42
-rw-r--r--tests/unit/src/com/android/tv/recommendation/EvaluatorTestCase.java74
-rw-r--r--tests/unit/src/com/android/tv/recommendation/FavoriteChannelEvaluatorTest.java73
-rw-r--r--tests/unit/src/com/android/tv/recommendation/RecentChannelEvaluatorTest.java47
-rw-r--r--tests/unit/src/com/android/tv/recommendation/RecommendationUtils.java95
-rw-r--r--tests/unit/src/com/android/tv/recommendation/RecommenderTest.java287
-rw-r--r--tests/unit/src/com/android/tv/recommendation/RoutineWatchEvaluatorTest.java219
-rw-r--r--tests/unit/src/com/android/tv/search/LocalSearchProviderTest.java132
-rw-r--r--tests/unit/src/com/android/tv/tests/TvActivityTest.java43
-rw-r--r--tests/unit/src/com/android/tv/util/MockTvSingletons.java (renamed from tests/unit/src/com/android/tv/util/MockApplicationSingletons.java)81
-rw-r--r--tests/unit/src/com/android/tv/util/MultiLongSparseArrayTest.java108
-rw-r--r--tests/unit/src/com/android/tv/util/ScaledBitmapInfoTest.java59
-rw-r--r--tests/unit/src/com/android/tv/util/TestUtils.java115
-rw-r--r--tests/unit/src/com/android/tv/util/TvInputManagerHelperTest.java258
-rw-r--r--tests/unit/src/com/android/tv/util/TvTrackInfoUtilsTest.java52
-rw-r--r--tests/unit/src/com/android/tv/util/UtilsTest_GetDurationString.java273
-rw-r--r--tests/unit/src/com/android/tv/util/UtilsTest_GetMultiAudioString.java94
-rw-r--r--tests/unit/src/com/android/tv/util/UtilsTest_IsInGivenDay.java68
-rw-r--r--tests/unit/src/com/android/tv/util/images/ImageCacheTest.java (renamed from tests/unit/src/com/android/tv/util/ImageCacheTest.java)43
-rw-r--r--tests/unit/src/com/android/tv/util/images/ScaledBitmapInfoTest.java79
135 files changed, 7933 insertions, 6825 deletions
diff --git a/tests/common/Android.mk b/tests/common/Android.mk
index 27c9f031..2e80aa2b 100644
--- a/tests/common/Android.mk
+++ b/tests/common/Android.mk
@@ -8,8 +8,12 @@ LOCAL_SRC_FILES := \
LOCAL_STATIC_JAVA_LIBRARIES := \
android-support-annotations \
+ android-support-test \
+ guava \
mockito-target \
- ub-uiautomator
+ platform-robolectric-3.6.1-prebuilt \
+ truth-0-36-prebuilt-jar \
+ ub-uiautomator \
# Link tv-common as shared library to avoid the problem of initialization of the constants
LOCAL_JAVA_LIBRARIES := tv-common
@@ -17,7 +21,7 @@ LOCAL_JAVA_LIBRARIES := tv-common
LOCAL_INSTRUMENTATION_FOR := LiveTv
LOCAL_MODULE := tv-test-common
LOCAL_MODULE_TAGS := optional
-LOCAL_SDK_VERSION := current
+LOCAL_SDK_VERSION := system_current
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
LOCAL_AIDL_INCLUDES += $(LOCAL_PATH)/src
diff --git a/tests/common/AndroidManifest.xml b/tests/common/AndroidManifest.xml
index f3ed9a9f..8afd8dc9 100644
--- a/tests/common/AndroidManifest.xml
+++ b/tests/common/AndroidManifest.xml
@@ -18,6 +18,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.tv.testing"
android:versionCode="1">
- <uses-sdk android:targetSdkVersion="23" android:minSdkVersion="21"/>
+ <uses-sdk android:targetSdkVersion="26" android:minSdkVersion="21"/>
<application />
</manifest>
diff --git a/tests/common/src/com/android/tv/input/TunerHelper.java b/tests/common/src/com/android/tv/input/TunerHelper.java
index 126d5027..08c4b041 100644
--- a/tests/common/src/com/android/tv/input/TunerHelper.java
+++ b/tests/common/src/com/android/tv/input/TunerHelper.java
@@ -19,14 +19,11 @@ package com.android.tv.input;
import android.net.Uri;
import android.support.annotation.Nullable;
import android.util.Log;
-
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
-/**
- * A class to manage fake tuners for the tune and the recording.
- */
+/** A class to manage fake tuners for the tune and the recording. */
public class TunerHelper {
private static final String TAG = "TunerHelper";
private static final boolean DEBUG = false;
@@ -38,9 +35,7 @@ public class TunerHelper {
mTunerCount = tunerCount;
}
- /**
- * Checks whether there are available tuners for the recording.
- */
+ /** Checks whether there are available tuners for the recording. */
public boolean tunerAvailableForRecording() {
if (mTuners.size() < mTunerCount) {
return true;
@@ -54,8 +49,8 @@ public class TunerHelper {
}
/**
- * Checks whether there is available tuner.
- * If there's available tuner, it is assigned to the channel.
+ * Checks whether there is available tuner. If there's available tuner, it is assigned to the
+ * channel.
*/
public boolean tune(@Nullable Uri channelUri, boolean forRecording) {
if (channelUri == null) {
@@ -82,9 +77,7 @@ public class TunerHelper {
return false;
}
- /**
- * Releases the tuner which was being used for the tune.
- */
+ /** Releases the tuner which was being used for the tune. */
public void stopTune(@Nullable Uri channelUri) {
if (channelUri == null) {
return;
@@ -110,9 +103,7 @@ public class TunerHelper {
}
}
- /**
- * Releases the tuner which was being used for the recording.
- */
+ /** Releases the tuner which was being used for the recording. */
public void stopRecording(@Nullable Uri channelUri) {
if (channelUri == null) {
return;
@@ -146,7 +137,7 @@ public class TunerHelper {
public boolean tuning;
public boolean recording;
- public Tuner (Uri channelUri, boolean forRecording) {
+ public Tuner(Uri channelUri, boolean forRecording) {
this.channelUri = channelUri;
this.tuning = !forRecording;
this.recording = forRecording;
diff --git a/tests/common/src/com/android/tv/testing/ChannelNumberSubject.java b/tests/common/src/com/android/tv/testing/ChannelNumberSubject.java
new file mode 100644
index 00000000..ba4662ee
--- /dev/null
+++ b/tests/common/src/com/android/tv/testing/ChannelNumberSubject.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2017 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.testing;
+
+import android.support.annotation.Nullable;
+import com.android.tv.data.ChannelNumber;
+import com.google.common.truth.ComparableSubject;
+import com.google.common.truth.FailureMetadata;
+import com.google.common.truth.Subject;
+import com.google.common.truth.Truth;
+
+/** Propositions for {@link ChannelNumber} subjects. */
+public final class ChannelNumberSubject
+ extends ComparableSubject<ChannelNumberSubject, ChannelNumber> {
+ private static final Subject.Factory<ChannelNumberSubject, ChannelNumber> FACTORY =
+ ChannelNumberSubject::new;
+
+ public static Subject.Factory<ChannelNumberSubject, ChannelNumber> channelNumbers() {
+ return FACTORY;
+ }
+
+ public static ChannelNumberSubject assertThat(@Nullable ChannelNumber actual) {
+ return Truth.assertAbout(channelNumbers()).that(actual);
+ }
+
+ public ChannelNumberSubject(FailureMetadata failureMetadata, @Nullable ChannelNumber subject) {
+ super(failureMetadata, subject);
+ }
+
+ public void displaysAs(int major) {
+ if (!getSubject().majorNumber.equals(Integer.toString(major))
+ || getSubject().hasDelimiter) {
+ fail("displaysAs", major);
+ }
+ }
+
+ public void displaysAs(int major, int minor) {
+ if (!getSubject().majorNumber.equals(Integer.toString(major))
+ || !getSubject().minorNumber.equals(Integer.toString(minor))
+ || !getSubject().hasDelimiter) {
+ fail("displaysAs", major + "-" + minor);
+ }
+ }
+
+ public void isEmpty() {
+ if (!getSubject().majorNumber.isEmpty()
+ || !getSubject().minorNumber.isEmpty()
+ || getSubject().hasDelimiter) {
+ fail("isEmpty");
+ }
+ }
+}
diff --git a/tests/common/src/com/android/tv/testing/ComparableTester.java b/tests/common/src/com/android/tv/testing/ComparableTester.java
index fe6e72f5..4328deb9 100644
--- a/tests/common/src/com/android/tv/testing/ComparableTester.java
+++ b/tests/common/src/com/android/tv/testing/ComparableTester.java
@@ -16,22 +16,19 @@
package com.android.tv.testing;
-import junit.framework.Assert;
-
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
+import junit.framework.Assert;
/**
* Tester for {@link java.lang.Comparable}s.
*
- * <p>
- * To use, create a new {@link ComparableTester} and add comparable groups
- * where each group contains objects that are
- * {@link java.util.Comparator#compare(Object, Object)} == 0 to each other.
- * Groups are added in order asserting that all earlier groups have compare < 0
- * for all later groups.
+ * <p>To use, create a new {@link ComparableTester} and add comparable groups where each group
+ * contains objects that are {@link java.util.Comparator#compare(Object, Object)} == 0 to each
+ * other. Groups are added in order asserting that all earlier groups have compare < 0 for all later
+ * groups.
*
* <pre>{@code
* new ComparableTester<String>()
@@ -39,8 +36,7 @@ import java.util.List;
* .addEquivalentGroup("World", "wORLD")
* .addEquivalentGroup("ZEBRA")
* .test();
- * }
- * </pre>
+ * }</pre>
*
* @param <T> the type of objects to compare.
*/
@@ -74,8 +70,8 @@ public class ComparableTester<T extends Comparable<T>> {
assertMore(more, less, moreGroup, lessGroup);
}
- private void assertLess(int left, int right, Collection<T> leftGroup,
- Collection<T> rightGroup) {
+ private void assertLess(
+ int left, int right, Collection<T> leftGroup, Collection<T> rightGroup) {
int leftSub = 0;
for (T leftItem : leftGroup) {
int rightSub = 0;
@@ -83,14 +79,22 @@ public class ComparableTester<T extends Comparable<T>> {
for (T rightItem : rightGroup) {
String rightName = "Item[" + right + "," + (rightSub++) + "]";
Assert.assertEquals(
- leftName + " " + leftItem + " compareTo " + rightName + " " + rightItem
- + " is <0", true, leftItem.compareTo(rightItem) < 0);
+ leftName
+ + " "
+ + leftItem
+ + " compareTo "
+ + rightName
+ + " "
+ + rightItem
+ + " is <0",
+ true,
+ leftItem.compareTo(rightItem) < 0);
}
}
}
- private void assertMore(int left, int right, Collection<T> leftGroup,
- Collection<T> rightGroup) {
+ private void assertMore(
+ int left, int right, Collection<T> leftGroup, Collection<T> rightGroup) {
int leftSub = 0;
for (T leftItem : leftGroup) {
int rightSub = 0;
@@ -98,8 +102,16 @@ public class ComparableTester<T extends Comparable<T>> {
for (T rightItem : rightGroup) {
String rightName = "Item[" + right + "," + (rightSub++) + "]";
Assert.assertEquals(
- leftName + " " + leftItem + " compareTo " + rightName + " " + rightItem
- + " is >0", true, leftItem.compareTo(rightItem) > 0);
+ leftName
+ + " "
+ + leftItem
+ + " compareTo "
+ + rightName
+ + " "
+ + rightItem
+ + " is >0",
+ true,
+ leftItem.compareTo(rightItem) > 0);
}
}
}
diff --git a/tests/common/src/com/android/tv/testing/ComparatorTester.java b/tests/common/src/com/android/tv/testing/ComparatorTester.java
index 3774532f..6ebd8b4e 100644
--- a/tests/common/src/com/android/tv/testing/ComparatorTester.java
+++ b/tests/common/src/com/android/tv/testing/ComparatorTester.java
@@ -27,12 +27,9 @@ import java.util.List;
/**
* Tester for {@link Comparator} relationships between groups of T.
*
- * <p>
- * To use, create a new {@link ComparatorTester} and add comparable groups
- * where each group contains objects that are
- * {@link Comparator#compare(Object, Object)} == 0 to each other.
- * Groups are added in order asserting that all earlier groups have compare < 0
- * for all later groups.
+ * <p>To use, create a new {@link ComparatorTester} and add comparable groups where each group
+ * contains objects that are {@link Comparator#compare(Object, Object)} == 0 to each other. Groups
+ * are added in order asserting that all earlier groups have compare < 0 for all later groups.
*
* <pre>{@code
* ComparatorTester
@@ -41,8 +38,7 @@ import java.util.List;
* .addComparableGroup("World", "wORLD")
* .addComparableGroup("ZEBRA")
* .test();
- * }
- * </pre>
+ * }</pre>
*
* @param <T> the type of objects to compare.
*/
@@ -52,7 +48,6 @@ public class ComparatorTester<T> {
private final Comparator<T> comparator;
-
public static <T> ComparatorTester<T> withoutEqualsTest(Comparator<T> comparator) {
return new ComparatorTester<>(comparator);
}
@@ -80,7 +75,7 @@ public class ComparatorTester<T> {
assertOrder(i, j, currentGroup, rhs);
}
}
- //TODO: also test equals
+ // TODO: also test equals
}
private void assertOrder(int less, int more, List<T> lessGroup, List<T> moreGroup) {
@@ -88,30 +83,48 @@ public class ComparatorTester<T> {
assertMore(more, less, moreGroup, lessGroup);
}
- private void assertLess(int left, int right, Collection<T> leftGroup,
- Collection<T> rightGroup) {
+ private void assertLess(
+ int left, int right, Collection<T> leftGroup, Collection<T> rightGroup) {
int leftSub = 0;
for (T leftItem : leftGroup) {
int rightSub = 0;
for (T rightItem : rightGroup) {
String leftName = "Item[" + left + "," + (leftSub++) + "]";
String rName = "Item[" + right + "," + (rightSub++) + "]";
- assertEquals(leftName + " " + leftItem + " compareTo " + rName + " " + rightItem
- + " is <0", true, comparator.compare(leftItem, rightItem) < 0);
+ assertEquals(
+ leftName
+ + " "
+ + leftItem
+ + " compareTo "
+ + rName
+ + " "
+ + rightItem
+ + " is <0",
+ true,
+ comparator.compare(leftItem, rightItem) < 0);
}
}
}
- private void assertMore(int left, int right, Collection<T> leftGroup,
- Collection<T> rightGroup) {
+ private void assertMore(
+ int left, int right, Collection<T> leftGroup, Collection<T> rightGroup) {
int leftSub = 0;
for (T leftItem : leftGroup) {
int rightSub = 0;
for (T rightItem : rightGroup) {
String leftName = "Item[" + left + "," + (leftSub++) + "]";
String rName = "Item[" + right + "," + (rightSub++) + "]";
- assertEquals(leftName + " " + leftItem + " compareTo " + rName + " " + rightItem
- + " is >0", true, comparator.compare(leftItem, rightItem) > 0);
+ assertEquals(
+ leftName
+ + " "
+ + leftItem
+ + " compareTo "
+ + rName
+ + " "
+ + rightItem
+ + " is >0",
+ true,
+ comparator.compare(leftItem, rightItem) > 0);
}
}
}
@@ -120,9 +133,11 @@ public class ComparatorTester<T> {
// Test everything against everything in both directions, including against itself.
for (T leftItem : group) {
for (T rightItem : group) {
- assertEquals(leftItem + " compareTo " + rightItem, 0,
+ assertEquals(
+ leftItem + " compareTo " + rightItem,
+ 0,
comparator.compare(leftItem, rightItem));
}
}
}
-} \ No newline at end of file
+}
diff --git a/tests/common/src/com/android/tv/testing/Constants.java b/tests/common/src/com/android/tv/testing/Constants.java
deleted file mode 100644
index 4c9cb5fb..00000000
--- a/tests/common/src/com/android/tv/testing/Constants.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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.testing;
-
-import android.media.tv.TvTrackInfo;
-
-/**
- * Constants for testing.
- */
-public final class Constants {
- public static final int FUNC_TEST_CHANNEL_COUNT = 100;
- public static final int UNIT_TEST_CHANNEL_COUNT = 4;
- public static final int JANK_TEST_CHANNEL_COUNT = 500; // TODO: increase to 1000 see b/23526997
-
- public static final TvTrackInfo EN_STEREO_AUDIO_TRACK = new TvTrackInfo.Builder(
- TvTrackInfo.TYPE_AUDIO, "English Stereo Audio").setLanguage("en")
- .setAudioChannelCount(2).build();
- public static final TvTrackInfo GENERIC_AUDIO_TRACK = new TvTrackInfo.Builder(
- TvTrackInfo.TYPE_AUDIO, "Generic Audio").build();
-
- public static final TvTrackInfo FHD1080P50_VIDEO_TRACK = new TvTrackInfo.Builder(
- TvTrackInfo.TYPE_VIDEO, "FHD Video").setVideoHeight(1080).setVideoWidth(1920)
- .setVideoFrameRate(50).build();
- public static final TvTrackInfo SVGA_VIDEO_TRACK = new TvTrackInfo.Builder(
- TvTrackInfo.TYPE_VIDEO, "SVGA Video").setVideoHeight(600).setVideoWidth(800).build();
-
- private Constants() {
- }
-}
diff --git a/tests/common/src/com/android/tv/testing/DbTestingUtils.java b/tests/common/src/com/android/tv/testing/DbTestingUtils.java
new file mode 100644
index 00000000..53e26ca7
--- /dev/null
+++ b/tests/common/src/com/android/tv/testing/DbTestingUtils.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2017 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.testing;
+
+import android.database.Cursor;
+import java.util.ArrayList;
+import java.util.List;
+
+/** Static utilities for testing using databases. */
+public final class DbTestingUtils {
+
+ public static List<List<String>> toList(Cursor cursor) {
+ ArrayList<List<String>> result = new ArrayList<>();
+ int colCount = cursor.getColumnCount();
+ while (cursor.moveToNext()) {
+ List<String> row = new ArrayList<>(colCount);
+ for (int i = 0; i < colCount; i++) {
+ row.add(cursor.getString(i));
+ }
+ result.add(row);
+ }
+ return result;
+ }
+
+ private DbTestingUtils() {}
+}
diff --git a/tests/common/src/com/android/tv/testing/EpgTestData.java b/tests/common/src/com/android/tv/testing/EpgTestData.java
new file mode 100644
index 00000000..49a92181
--- /dev/null
+++ b/tests/common/src/com/android/tv/testing/EpgTestData.java
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2017 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.testing;
+
+import com.android.tv.data.ChannelImpl;
+import com.android.tv.data.Lineup;
+import com.android.tv.data.Program;
+import com.android.tv.data.api.Channel;
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableListMultimap;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.ListMultimap;
+import java.util.concurrent.TimeUnit;
+
+/** EPG data for use in tests. */
+public abstract class EpgTestData {
+
+ public static final android.support.media.tv.Channel CHANNEL_10 =
+ new android.support.media.tv.Channel.Builder()
+ .setDisplayName("Channel TEN")
+ .setDisplayNumber("10")
+ .build();
+ public static final android.support.media.tv.Channel CHANNEL_11 =
+ new android.support.media.tv.Channel.Builder()
+ .setDisplayName("Channel Eleven")
+ .setDisplayNumber("11")
+ .build();
+ public static final android.support.media.tv.Channel CHANNEL_90_2 =
+ new android.support.media.tv.Channel.Builder()
+ .setDisplayName("Channel Ninety dot Two")
+ .setDisplayNumber("90.2")
+ .build();
+
+ public static final Lineup LINEUP_1 =
+ new Lineup(
+ "lineup1",
+ Lineup.LINEUP_SATELLITE,
+ "Lineup one",
+ "Location one",
+ ImmutableList.of("1", "2.2"));
+ public static final Lineup LINEUP_2 =
+ new Lineup(
+ "lineup2",
+ Lineup.LINEUP_SATELLITE,
+ "Lineup two",
+ "Location two",
+ ImmutableList.of("1", "2.3"));
+
+ public static final Lineup LINEUP_90210 =
+ new Lineup(
+ "test90210",
+ Lineup.LINEUP_BROADCAST_DIGITAL,
+ "Test 90210",
+ "Beverly Hills",
+ ImmutableList.of("90.2", "10"));
+
+ // Programs start and end times are set relative to 0.
+ // Then when loaded they are offset by the {@link #getStartTimeMs}.
+ // Start and end time may be negative meaning they happen before "now".
+
+ public static final Program PROGRAM_1 =
+ new Program.Builder()
+ .setTitle("Program 1")
+ .setStartTimeUtcMillis(0)
+ .setEndTimeUtcMillis(TimeUnit.MINUTES.toMillis(30))
+ .build();
+
+ public static final Program PROGRAM_2 =
+ new Program.Builder()
+ .setTitle("Program 2")
+ .setStartTimeUtcMillis(TimeUnit.MINUTES.toMillis(30))
+ .setEndTimeUtcMillis(TimeUnit.MINUTES.toMillis(60))
+ .build();
+
+ public static final EpgTestData DATA_90210 =
+ new EpgTestData() {
+
+ // Thursday, June 1, 2017 4:00:00 PM GMT-07:00
+ private final long testStartTimeMs = 1496358000000L;
+
+ @Override
+ public ListMultimap<String, Lineup> getLineups() {
+ ImmutableListMultimap.Builder<String, Lineup> builder =
+ ImmutableListMultimap.builder();
+ return builder.putAll("90210", LINEUP_1, LINEUP_2, LINEUP_90210).build();
+ }
+
+ @Override
+ public ListMultimap<String, Channel> getLineupChannels() {
+ ImmutableListMultimap.Builder<String, Channel> builder =
+ ImmutableListMultimap.builder();
+ return builder.putAll(
+ LINEUP_90210.getId(), toTvChannels(CHANNEL_90_2, CHANNEL_10))
+ .putAll(LINEUP_1.getId(), toTvChannels(CHANNEL_10, CHANNEL_11))
+ .build();
+ }
+
+ @Override
+ public ListMultimap<String, Program> getEpgPrograms() {
+ ImmutableListMultimap.Builder<String, Program> builder =
+ ImmutableListMultimap.builder();
+ return builder.putAll(
+ CHANNEL_10.getDisplayNumber(),
+ EpgTestData.updateTime(getStartTimeMs(), PROGRAM_1))
+ .putAll(
+ CHANNEL_11.getDisplayNumber(),
+ EpgTestData.updateTime(getStartTimeMs(), PROGRAM_2))
+ .build();
+ }
+
+ @Override
+ public long getStartTimeMs() {
+ return testStartTimeMs;
+ }
+ };
+
+ public abstract ListMultimap<String, Lineup> getLineups();
+
+ public abstract ListMultimap<String, Channel> getLineupChannels();
+
+ public abstract ListMultimap<String, Program> getEpgPrograms();
+
+ /** The starting time for this test data */
+ public abstract long getStartTimeMs();
+
+ /**
+ * Loads test data
+ *
+ * <p>
+ *
+ * <ul>
+ * <li>Sets clock to {@link #getStartTimeMs()} and boot time to 12 hours before that
+ * <li>Loads lineups
+ * <li>Loads lineupChannels
+ * <li>Loads epgPrograms
+ * </ul>
+ */
+ public final void loadData(FakeClock clock, FakeEpgReader epgReader) {
+ clock.setBootTimeMillis(getStartTimeMs() + TimeUnit.HOURS.toMillis(-12));
+ clock.setCurrentTimeMillis(getStartTimeMs());
+ epgReader.zip2lineups.putAll(getLineups());
+ epgReader.lineup2Channels.putAll(getLineupChannels());
+ epgReader.epgChannelId2Programs.putAll(getEpgPrograms());
+ }
+
+ public final void loadData(TestSingletonApp testSingletonApp) {
+ loadData(testSingletonApp.fakeClock, testSingletonApp.epgReader);
+ }
+
+ private static Iterable<Channel> toTvChannels(android.support.media.tv.Channel... channels) {
+ return Iterables.transform(
+ ImmutableList.copyOf(channels),
+ new Function<android.support.media.tv.Channel, Channel>() {
+ @Override
+ public Channel apply(android.support.media.tv.Channel original) {
+ return toTvChannel(original);
+ }
+ });
+ }
+
+ public static Channel toTvChannel(android.support.media.tv.Channel original) {
+ return new ChannelImpl.Builder()
+ .setDisplayName(original.getDisplayName())
+ .setDisplayNumber(original.getDisplayNumber())
+ // TODO implement the reset
+ .build();
+ }
+
+ /** Add time to the startTime and stopTime of each program */
+ private static Iterable<Program> updateTime(long time, Program... programs) {
+ return Iterables.transform(
+ ImmutableList.copyOf(programs),
+ new Function<Program, Program>() {
+ @Override
+ public Program apply(Program p) {
+ return new Program.Builder(p)
+ .setStartTimeUtcMillis(p.getStartTimeUtcMillis() + time)
+ .setEndTimeUtcMillis(p.getEndTimeUtcMillis() + time)
+ .build();
+ }
+ });
+ }
+}
diff --git a/tests/common/src/com/android/tv/testing/FakeClock.java b/tests/common/src/com/android/tv/testing/FakeClock.java
index d88e53a8..f5941939 100644
--- a/tests/common/src/com/android/tv/testing/FakeClock.java
+++ b/tests/common/src/com/android/tv/testing/FakeClock.java
@@ -16,8 +16,7 @@
package com.android.tv.testing;
-import com.android.tv.util.Clock;
-
+import com.android.tv.common.util.Clock;
import java.util.concurrent.TimeUnit;
/**
@@ -27,21 +26,20 @@ import java.util.concurrent.TimeUnit;
* {@link #sleep(long)} is called.
*/
public class FakeClock implements Clock {
- /**
- * Creates a fake clock with the time set to now and the boot time set to now - 100,000.
- */
+ /** Creates a fake clock with the time set to now and the boot time set to now - 100,000. */
public static FakeClock createWithCurrentTime() {
long now = System.currentTimeMillis();
return new FakeClock(now, now - 100_000);
}
- /**
- * Creates a fake clock with the time set to zero.
- */
+ /** Creates a fake clock with the time set to zero. */
public static FakeClock createWithTimeOne() {
return new FakeClock(1L, 0L);
}
-
+ /** Creates a fake clock with the time set to {@code time}. */
+ public static FakeClock createWithTime(long time) {
+ return new FakeClock(time, 0L);
+ }
private long mCurrentTimeMillis;
@@ -95,9 +93,12 @@ public class FakeClock implements Clock {
return mCurrentTimeMillis - mBootTimeMillis;
}
- /**
- * Sleep does not block it just updates the current time.
- */
+ @Override
+ public long uptimeMillis() {
+ return elapsedRealtime();
+ }
+
+ /** Sleep does not block it just updates the current time. */
@Override
public void sleep(long ms) {
// TODO: implement blocking if needed.
diff --git a/tests/common/src/com/android/tv/testing/FakeEpgFetcher.java b/tests/common/src/com/android/tv/testing/FakeEpgFetcher.java
new file mode 100644
index 00000000..d1018a5c
--- /dev/null
+++ b/tests/common/src/com/android/tv/testing/FakeEpgFetcher.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2017 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.testing;
+
+import android.app.job.JobParameters;
+import android.app.job.JobService;
+import com.android.tv.data.epg.EpgFetcher;
+
+/** Fake {@link EpgFetcher} for testing. */
+public class FakeEpgFetcher implements EpgFetcher {
+ public boolean fetchStarted = false;
+
+ @Override
+ public void startRoutineService() {}
+
+ @Override
+ public void fetchImmediatelyIfNeeded() {}
+
+ @Override
+ public void fetchImmediately() {
+ fetchStarted = true;
+ }
+
+ @Override
+ public void onChannelScanStarted() {}
+
+ @Override
+ public void onChannelScanFinished() {}
+
+ @Override
+ public boolean executeFetchTaskIfPossible(JobService jobService, JobParameters params) {
+ return false;
+ }
+
+ @Override
+ public void stopFetchingJob() {
+ fetchStarted = false;
+ }
+
+ public void reset() {
+ fetchStarted = false;
+ }
+}
diff --git a/tests/common/src/com/android/tv/testing/FakeEpgReader.java b/tests/common/src/com/android/tv/testing/FakeEpgReader.java
new file mode 100644
index 00000000..710ada55
--- /dev/null
+++ b/tests/common/src/com/android/tv/testing/FakeEpgReader.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2017 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.testing;
+
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.util.Range;
+import com.android.tv.data.ChannelImpl;
+import com.android.tv.data.ChannelNumber;
+import com.android.tv.data.Lineup;
+import com.android.tv.data.Program;
+import com.android.tv.data.api.Channel;
+import com.android.tv.data.epg.EpgReader;
+import com.android.tv.dvr.data.SeriesInfo;
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.LinkedListMultimap;
+import com.google.common.collect.ListMultimap;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/** Fake {@link EpgReader} for testing. */
+public final class FakeEpgReader implements EpgReader {
+ public final ListMultimap<String, Lineup> zip2lineups = LinkedListMultimap.create(2);
+ public final ListMultimap<String, Channel> lineup2Channels = LinkedListMultimap.create(2);
+ public final ListMultimap<String, Program> epgChannelId2Programs = LinkedListMultimap.create(2);
+ public final FakeClock fakeClock;
+
+ public FakeEpgReader(FakeClock fakeClock) {
+ this.fakeClock = fakeClock;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return true;
+ }
+
+ @Override
+ public long getEpgTimestamp() {
+ return fakeClock.currentTimeMillis();
+ }
+
+ @Override
+ public void setRegionCode(String regionCode) {}
+
+ @Override
+ public List<Lineup> getLineups(@NonNull String postalCode) {
+ return zip2lineups.get(postalCode);
+ }
+
+ @Override
+ public List<String> getChannelNumbers(@NonNull String lineupId) {
+ return null;
+ }
+
+ @Override
+ public Set<EpgChannel> getChannels(Set<Channel> inputChannels, @NonNull String lineupId) {
+ Set<EpgChannel> result = new HashSet<>();
+ List<Channel> lineupChannels = lineup2Channels.get(lineupId);
+ for (Channel channel : lineupChannels) {
+ Channel match =
+ Iterables.find(
+ inputChannels,
+ new Predicate<Channel>() {
+ @Override
+ public boolean apply(@Nullable Channel inputChannel) {
+ return ChannelNumber.equivalent(
+ inputChannel.getDisplayNumber(),
+ channel.getDisplayNumber());
+ }
+ },
+ null);
+ if (match != null) {
+ ChannelImpl updatedChannel = new ChannelImpl.Builder(match).build();
+ updatedChannel.setLogoUri(channel.getLogoUri());
+ result.add(EpgChannel.createEpgChannel(updatedChannel, channel.getDisplayNumber()));
+ }
+ }
+ return result;
+ }
+
+ @Override
+ public void preloadChannels(@NonNull String lineupId) {}
+
+ @Override
+ public void clearCachedChannels(@NonNull String lineupId) {}
+
+ @Override
+ public List<Program> getPrograms(EpgChannel epgChannel) {
+ return ImmutableList.copyOf(
+ Iterables.transform(
+ epgChannelId2Programs.get(epgChannel.getEpgChannelId()),
+ updateWith(epgChannel)));
+ }
+
+ @Override
+ public Map<EpgChannel, Collection<Program>> getPrograms(
+ @NonNull Set<EpgChannel> epgChannels, long duration) {
+ Range<Long> validRange =
+ Range.create(
+ fakeClock.currentTimeMillis(), fakeClock.currentTimeMillis() + duration);
+ ImmutableMap.Builder<EpgChannel, Collection<Program>> mapBuilder = ImmutableMap.builder();
+ for (EpgChannel epgChannel : epgChannels) {
+ Iterable<Program> programs = getPrograms(epgChannel);
+
+ mapBuilder.put(
+ epgChannel,
+ ImmutableList.copyOf(Iterables.filter(programs, isProgramDuring(validRange))));
+ }
+ return mapBuilder.build();
+ }
+
+ protected Function<Program, Program> updateWith(final EpgChannel channel) {
+ return new Function<Program, Program>() {
+ @Nullable
+ @Override
+ public Program apply(@Nullable Program program) {
+ return new Program.Builder(program)
+ .setChannelId(channel.getChannel().getId())
+ .setPackageName(channel.getChannel().getPackageName())
+ .build();
+ }
+ };
+ }
+
+ /**
+ * True if the start time or the end time is {@link Range#contains contained (inclusive)} in the
+ * range
+ */
+ protected Predicate<Program> isProgramDuring(final Range<Long> validRange) {
+ return new Predicate<Program>() {
+ @Override
+ public boolean apply(@Nullable Program program) {
+ return validRange.contains(program.getStartTimeUtcMillis())
+ || validRange.contains(program.getEndTimeUtcMillis());
+ }
+ };
+ }
+
+ @Override
+ public SeriesInfo getSeriesInfo(@NonNull String seriesId) {
+ return null;
+ }
+}
diff --git a/tests/common/src/com/android/tv/testing/FakeRemoteConfig.java b/tests/common/src/com/android/tv/testing/FakeRemoteConfig.java
new file mode 100644
index 00000000..89e6a0a2
--- /dev/null
+++ b/tests/common/src/com/android/tv/testing/FakeRemoteConfig.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2017 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.testing;
+
+import android.text.TextUtils;
+import com.android.tv.common.config.api.RemoteConfig;
+import java.util.HashMap;
+import java.util.Map;
+
+/** Fake {@link RemoteConfig} suitable for testing. */
+public class FakeRemoteConfig implements RemoteConfig {
+ public final Map<String, String> values = new HashMap();
+
+ @Override
+ public void fetch(OnRemoteConfigUpdatedListener listener) {}
+
+ @Override
+ public String getString(String key) {
+ return values.get(key);
+ }
+
+ @Override
+ public boolean getBoolean(String key) {
+ String value = values.get(key);
+ return TextUtils.isEmpty(value) ? false : Boolean.valueOf(key);
+ }
+
+ @Override
+ public long getLong(String key) {
+ return getLong(key, 0);
+ }
+
+ @Override
+ public long getLong(String key, long defaultValue) {
+ if (values.containsKey(key)) {
+ String value = values.get(key);
+ return TextUtils.isEmpty(value) ? defaultValue : Long.valueOf(value);
+ }
+ return defaultValue;
+ }
+}
diff --git a/tests/common/src/com/android/tv/testing/FakeTvInputManager.java b/tests/common/src/com/android/tv/testing/FakeTvInputManager.java
new file mode 100644
index 00000000..397b4052
--- /dev/null
+++ b/tests/common/src/com/android/tv/testing/FakeTvInputManager.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2017 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.testing;
+
+import android.media.tv.TvContentRatingSystemInfo;
+import android.media.tv.TvInputInfo;
+import android.media.tv.TvInputManager;
+import android.os.Handler;
+import com.android.tv.util.TvInputManagerHelper;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/** Fake implementation for testing. */
+public class FakeTvInputManager implements TvInputManagerHelper.TvInputManagerInterface {
+
+ private final Map<String, Integer> mInputStateMap = new HashMap<>();
+ private final Map<String, TvInputInfo> mInputMap = new HashMap<>();
+ private final Map<TvInputManager.TvInputCallback, Handler> mCallbacks = new HashMap<>();
+
+ public void add(TvInputInfo inputInfo, int state) {
+ final String inputId = inputInfo.getId();
+ if (mInputStateMap.containsKey(inputId)) {
+ throw new IllegalArgumentException("inputId " + inputId);
+ }
+ mInputMap.put(inputId, inputInfo);
+ mInputStateMap.put(inputId, state);
+ for (final Map.Entry<TvInputManager.TvInputCallback, Handler> e : mCallbacks.entrySet()) {
+ e.getValue()
+ .post(
+ new Runnable() {
+ @Override
+ public void run() {
+ e.getKey().onInputAdded(inputId);
+ }
+ });
+ }
+ }
+
+ public void setInputState(final String inputId, final int state) {
+ if (!mInputStateMap.containsKey(inputId)) {
+ throw new IllegalArgumentException("inputId " + inputId);
+ }
+ mInputStateMap.put(inputId, state);
+ for (final Map.Entry<TvInputManager.TvInputCallback, Handler> e : mCallbacks.entrySet()) {
+ e.getValue()
+ .post(
+ new Runnable() {
+ @Override
+ public void run() {
+ e.getKey().onInputStateChanged(inputId, state);
+ }
+ });
+ }
+ }
+
+ public void remove(final String inputId) {
+ mInputMap.remove(inputId);
+ mInputStateMap.remove(inputId);
+ for (final Map.Entry<TvInputManager.TvInputCallback, Handler> e : mCallbacks.entrySet()) {
+ e.getValue()
+ .post(
+ new Runnable() {
+ @Override
+ public void run() {
+ e.getKey().onInputRemoved(inputId);
+ }
+ });
+ }
+ }
+
+ @Override
+ public TvInputInfo getTvInputInfo(String inputId) {
+ return mInputMap.get(inputId);
+ }
+
+ @Override
+ public Integer getInputState(String inputId) {
+ return mInputStateMap.get(inputId);
+ }
+
+ @Override
+ public void registerCallback(TvInputManager.TvInputCallback internalCallback, Handler handler) {
+ mCallbacks.put(internalCallback, handler);
+ }
+
+ @Override
+ public void unregisterCallback(TvInputManager.TvInputCallback internalCallback) {
+ mCallbacks.remove(internalCallback);
+ }
+
+ @Override
+ public List<TvInputInfo> getTvInputList() {
+ return new ArrayList(mInputMap.values());
+ }
+
+ @Override
+ public List<TvContentRatingSystemInfo> getTvContentRatingSystemList() {
+ // TODO implement
+ return new ArrayList<>();
+ }
+}
diff --git a/tests/common/src/com/android/tv/testing/FakeTvInputManagerHelper.java b/tests/common/src/com/android/tv/testing/FakeTvInputManagerHelper.java
new file mode 100644
index 00000000..85bdcf04
--- /dev/null
+++ b/tests/common/src/com/android/tv/testing/FakeTvInputManagerHelper.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2017 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.testing;
+
+import android.content.Context;
+import com.android.tv.util.TvInputManagerHelper;
+
+/** Fake TvInputManagerHelper. */
+public class FakeTvInputManagerHelper extends TvInputManagerHelper {
+
+ public FakeTvInputManagerHelper(Context context) {
+ super(context, new FakeTvInputManager());
+ }
+
+ public FakeTvInputManager getFakeTvInputManager() {
+ return (FakeTvInputManager) mTvInputManager;
+ }
+}
diff --git a/tests/common/src/com/android/tv/testing/FakeTvProvider.java b/tests/common/src/com/android/tv/testing/FakeTvProvider.java
new file mode 100644
index 00000000..24c26f39
--- /dev/null
+++ b/tests/common/src/com/android/tv/testing/FakeTvProvider.java
@@ -0,0 +1,2605 @@
+/*
+ * Copyright (C) 2017 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.testing;
+
+import android.annotation.SuppressLint;
+import android.content.ContentProvider;
+import android.content.ContentProviderOperation;
+import android.content.ContentProviderResult;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.OperationApplicationException;
+import android.content.SharedPreferences;
+import android.content.UriMatcher;
+import android.content.pm.PackageManager;
+import android.database.Cursor;
+import android.database.DatabaseUtils;
+import android.database.SQLException;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.database.sqlite.SQLiteQueryBuilder;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.media.tv.TvContract;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.os.ParcelFileDescriptor;
+import android.os.ParcelFileDescriptor.AutoCloseInputStream;
+import android.preference.PreferenceManager;
+import android.provider.BaseColumns;
+import android.support.annotation.VisibleForTesting;
+import android.support.media.tv.TvContractCompat;
+import android.support.media.tv.TvContractCompat.BaseTvColumns;
+import android.support.media.tv.TvContractCompat.Channels;
+import android.support.media.tv.TvContractCompat.PreviewPrograms;
+import android.support.media.tv.TvContractCompat.Programs;
+import android.support.media.tv.TvContractCompat.Programs.Genres;
+import android.support.media.tv.TvContractCompat.RecordedPrograms;
+import android.support.media.tv.TvContractCompat.WatchNextPrograms;
+import android.text.TextUtils;
+import android.util.Log;
+import com.android.tv.util.SqlParams;
+import java.io.ByteArrayOutputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Fake TV content provider suitable for unit tests. The contract between this provider and
+ * applications is defined in {@link TvContractCompat}.
+ */
+// TODO(b/62143348): remove when error prone check fixed
+@SuppressWarnings({"AndroidApiChecker", "TryWithResources"})
+public class FakeTvProvider extends ContentProvider {
+ // TODO either make this a shadow or move it to the support library
+
+ private static final boolean DEBUG = false;
+ private static final String TAG = "TvProvider";
+
+ static final int DATABASE_VERSION = 34;
+ static final String SHARED_PREF_BLOCKED_PACKAGES_KEY = "blocked_packages";
+ static final String CHANNELS_TABLE = "channels";
+ static final String PROGRAMS_TABLE = "programs";
+ static final String RECORDED_PROGRAMS_TABLE = "recorded_programs";
+ static final String PREVIEW_PROGRAMS_TABLE = "preview_programs";
+ static final String WATCH_NEXT_PROGRAMS_TABLE = "watch_next_programs";
+ static final String WATCHED_PROGRAMS_TABLE = "watched_programs";
+ static final String PROGRAMS_TABLE_PACKAGE_NAME_INDEX = "programs_package_name_index";
+ static final String PROGRAMS_TABLE_CHANNEL_ID_INDEX = "programs_channel_id_index";
+ static final String PROGRAMS_TABLE_START_TIME_INDEX = "programs_start_time_index";
+ static final String PROGRAMS_TABLE_END_TIME_INDEX = "programs_end_time_index";
+ static final String WATCHED_PROGRAMS_TABLE_CHANNEL_ID_INDEX =
+ "watched_programs_channel_id_index";
+ // The internal column in the watched programs table to indicate whether the current log entry
+ // is consolidated or not. Unconsolidated entries may have columns with missing data.
+ static final String WATCHED_PROGRAMS_COLUMN_CONSOLIDATED = "consolidated";
+ static final String CHANNELS_COLUMN_LOGO = "logo";
+ private static final String DATABASE_NAME = "tv.db";
+ private static final String DELETED_CHANNELS_TABLE = "deleted_channels"; // Deprecated
+ private static final String DEFAULT_PROGRAMS_SORT_ORDER =
+ Programs.COLUMN_START_TIME_UTC_MILLIS + " ASC";
+ private static final String DEFAULT_WATCHED_PROGRAMS_SORT_ORDER =
+ WatchedPrograms.COLUMN_WATCH_START_TIME_UTC_MILLIS + " DESC";
+ private static final String CHANNELS_TABLE_INNER_JOIN_PROGRAMS_TABLE =
+ CHANNELS_TABLE
+ + " INNER JOIN "
+ + PROGRAMS_TABLE
+ + " ON ("
+ + CHANNELS_TABLE
+ + "."
+ + Channels._ID
+ + "="
+ + PROGRAMS_TABLE
+ + "."
+ + Programs.COLUMN_CHANNEL_ID
+ + ")";
+
+ // Operation names for createSqlParams().
+ private static final String OP_QUERY = "query";
+ private static final String OP_UPDATE = "update";
+ private static final String OP_DELETE = "delete";
+
+ private static final UriMatcher sUriMatcher;
+ private static final int MATCH_CHANNEL = 1;
+ private static final int MATCH_CHANNEL_ID = 2;
+ private static final int MATCH_CHANNEL_ID_LOGO = 3;
+ private static final int MATCH_PASSTHROUGH_ID = 4;
+ private static final int MATCH_PROGRAM = 5;
+ private static final int MATCH_PROGRAM_ID = 6;
+ private static final int MATCH_WATCHED_PROGRAM = 7;
+ private static final int MATCH_WATCHED_PROGRAM_ID = 8;
+ private static final int MATCH_RECORDED_PROGRAM = 9;
+ private static final int MATCH_RECORDED_PROGRAM_ID = 10;
+ private static final int MATCH_PREVIEW_PROGRAM = 11;
+ private static final int MATCH_PREVIEW_PROGRAM_ID = 12;
+ private static final int MATCH_WATCH_NEXT_PROGRAM = 13;
+ private static final int MATCH_WATCH_NEXT_PROGRAM_ID = 14;
+
+ private static final int MAX_LOGO_IMAGE_SIZE = 256;
+
+ private static final String EMPTY_STRING = "";
+
+ private static final Map<String, String> sChannelProjectionMap;
+ private static final Map<String, String> sProgramProjectionMap;
+ private static final Map<String, String> sWatchedProgramProjectionMap;
+ private static final Map<String, String> sRecordedProgramProjectionMap;
+ private static final Map<String, String> sPreviewProgramProjectionMap;
+ private static final Map<String, String> sWatchNextProgramProjectionMap;
+
+ // TvContract hidden
+ private static final String PARAM_PACKAGE = "package";
+ private static final String PARAM_PREVIEW = "preview";
+
+ private static boolean sInitialized;
+
+ static {
+ sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
+ sUriMatcher.addURI(TvContractCompat.AUTHORITY, "channel", MATCH_CHANNEL);
+ sUriMatcher.addURI(TvContractCompat.AUTHORITY, "channel/#", MATCH_CHANNEL_ID);
+ sUriMatcher.addURI(TvContractCompat.AUTHORITY, "channel/#/logo", MATCH_CHANNEL_ID_LOGO);
+ sUriMatcher.addURI(TvContractCompat.AUTHORITY, "passthrough/*", MATCH_PASSTHROUGH_ID);
+ sUriMatcher.addURI(TvContractCompat.AUTHORITY, "program", MATCH_PROGRAM);
+ sUriMatcher.addURI(TvContractCompat.AUTHORITY, "program/#", MATCH_PROGRAM_ID);
+ sUriMatcher.addURI(TvContractCompat.AUTHORITY, "watched_program", MATCH_WATCHED_PROGRAM);
+ sUriMatcher.addURI(
+ TvContractCompat.AUTHORITY, "watched_program/#", MATCH_WATCHED_PROGRAM_ID);
+ sUriMatcher.addURI(TvContractCompat.AUTHORITY, "recorded_program", MATCH_RECORDED_PROGRAM);
+ sUriMatcher.addURI(
+ TvContractCompat.AUTHORITY, "recorded_program/#", MATCH_RECORDED_PROGRAM_ID);
+ sUriMatcher.addURI(TvContractCompat.AUTHORITY, "preview_program", MATCH_PREVIEW_PROGRAM);
+ sUriMatcher.addURI(
+ TvContractCompat.AUTHORITY, "preview_program/#", MATCH_PREVIEW_PROGRAM_ID);
+ sUriMatcher.addURI(
+ TvContractCompat.AUTHORITY, "watch_next_program", MATCH_WATCH_NEXT_PROGRAM);
+ sUriMatcher.addURI(
+ TvContractCompat.AUTHORITY, "watch_next_program/#", MATCH_WATCH_NEXT_PROGRAM_ID);
+
+ sChannelProjectionMap = new HashMap<>();
+ sChannelProjectionMap.put(Channels._ID, CHANNELS_TABLE + "." + Channels._ID);
+ sChannelProjectionMap.put(
+ Channels.COLUMN_PACKAGE_NAME, CHANNELS_TABLE + "." + Channels.COLUMN_PACKAGE_NAME);
+ sChannelProjectionMap.put(
+ Channels.COLUMN_INPUT_ID, CHANNELS_TABLE + "." + Channels.COLUMN_INPUT_ID);
+ sChannelProjectionMap.put(
+ Channels.COLUMN_TYPE, CHANNELS_TABLE + "." + Channels.COLUMN_TYPE);
+ sChannelProjectionMap.put(
+ Channels.COLUMN_SERVICE_TYPE, CHANNELS_TABLE + "." + Channels.COLUMN_SERVICE_TYPE);
+ sChannelProjectionMap.put(
+ Channels.COLUMN_ORIGINAL_NETWORK_ID,
+ CHANNELS_TABLE + "." + Channels.COLUMN_ORIGINAL_NETWORK_ID);
+ sChannelProjectionMap.put(
+ Channels.COLUMN_TRANSPORT_STREAM_ID,
+ CHANNELS_TABLE + "." + Channels.COLUMN_TRANSPORT_STREAM_ID);
+ sChannelProjectionMap.put(
+ Channels.COLUMN_SERVICE_ID, CHANNELS_TABLE + "." + Channels.COLUMN_SERVICE_ID);
+ sChannelProjectionMap.put(
+ Channels.COLUMN_DISPLAY_NUMBER,
+ CHANNELS_TABLE + "." + Channels.COLUMN_DISPLAY_NUMBER);
+ sChannelProjectionMap.put(
+ Channels.COLUMN_DISPLAY_NAME, CHANNELS_TABLE + "." + Channels.COLUMN_DISPLAY_NAME);
+ sChannelProjectionMap.put(
+ Channels.COLUMN_NETWORK_AFFILIATION,
+ CHANNELS_TABLE + "." + Channels.COLUMN_NETWORK_AFFILIATION);
+ sChannelProjectionMap.put(
+ Channels.COLUMN_DESCRIPTION, CHANNELS_TABLE + "." + Channels.COLUMN_DESCRIPTION);
+ sChannelProjectionMap.put(
+ Channels.COLUMN_VIDEO_FORMAT, CHANNELS_TABLE + "." + Channels.COLUMN_VIDEO_FORMAT);
+ sChannelProjectionMap.put(
+ Channels.COLUMN_BROWSABLE, CHANNELS_TABLE + "." + Channels.COLUMN_BROWSABLE);
+ sChannelProjectionMap.put(
+ Channels.COLUMN_SEARCHABLE, CHANNELS_TABLE + "." + Channels.COLUMN_SEARCHABLE);
+ sChannelProjectionMap.put(
+ Channels.COLUMN_LOCKED, CHANNELS_TABLE + "." + Channels.COLUMN_LOCKED);
+ sChannelProjectionMap.put(
+ Channels.COLUMN_APP_LINK_ICON_URI,
+ CHANNELS_TABLE + "." + Channels.COLUMN_APP_LINK_ICON_URI);
+ sChannelProjectionMap.put(
+ Channels.COLUMN_APP_LINK_POSTER_ART_URI,
+ CHANNELS_TABLE + "." + Channels.COLUMN_APP_LINK_POSTER_ART_URI);
+ sChannelProjectionMap.put(
+ Channels.COLUMN_APP_LINK_TEXT,
+ CHANNELS_TABLE + "." + Channels.COLUMN_APP_LINK_TEXT);
+ sChannelProjectionMap.put(
+ Channels.COLUMN_APP_LINK_COLOR,
+ CHANNELS_TABLE + "." + Channels.COLUMN_APP_LINK_COLOR);
+ sChannelProjectionMap.put(
+ Channels.COLUMN_APP_LINK_INTENT_URI,
+ CHANNELS_TABLE + "." + Channels.COLUMN_APP_LINK_INTENT_URI);
+ sChannelProjectionMap.put(
+ Channels.COLUMN_INTERNAL_PROVIDER_DATA,
+ CHANNELS_TABLE + "." + Channels.COLUMN_INTERNAL_PROVIDER_DATA);
+ sChannelProjectionMap.put(
+ Channels.COLUMN_INTERNAL_PROVIDER_FLAG1,
+ CHANNELS_TABLE + "." + Channels.COLUMN_INTERNAL_PROVIDER_FLAG1);
+ sChannelProjectionMap.put(
+ Channels.COLUMN_INTERNAL_PROVIDER_FLAG2,
+ CHANNELS_TABLE + "." + Channels.COLUMN_INTERNAL_PROVIDER_FLAG2);
+ sChannelProjectionMap.put(
+ Channels.COLUMN_INTERNAL_PROVIDER_FLAG3,
+ CHANNELS_TABLE + "." + Channels.COLUMN_INTERNAL_PROVIDER_FLAG3);
+ sChannelProjectionMap.put(
+ Channels.COLUMN_INTERNAL_PROVIDER_FLAG4,
+ CHANNELS_TABLE + "." + Channels.COLUMN_INTERNAL_PROVIDER_FLAG4);
+ sChannelProjectionMap.put(
+ Channels.COLUMN_VERSION_NUMBER,
+ CHANNELS_TABLE + "." + Channels.COLUMN_VERSION_NUMBER);
+ sChannelProjectionMap.put(
+ Channels.COLUMN_TRANSIENT, CHANNELS_TABLE + "." + Channels.COLUMN_TRANSIENT);
+ sChannelProjectionMap.put(
+ Channels.COLUMN_INTERNAL_PROVIDER_ID,
+ CHANNELS_TABLE + "." + Channels.COLUMN_INTERNAL_PROVIDER_ID);
+
+ sProgramProjectionMap = new HashMap<>();
+ sProgramProjectionMap.put(Programs._ID, Programs._ID);
+ sProgramProjectionMap.put(Programs.COLUMN_PACKAGE_NAME, Programs.COLUMN_PACKAGE_NAME);
+ sProgramProjectionMap.put(Programs.COLUMN_CHANNEL_ID, Programs.COLUMN_CHANNEL_ID);
+ sProgramProjectionMap.put(Programs.COLUMN_TITLE, Programs.COLUMN_TITLE);
+ // COLUMN_SEASON_NUMBER is deprecated. Return COLUMN_SEASON_DISPLAY_NUMBER instead.
+ sProgramProjectionMap.put(
+ Programs.COLUMN_SEASON_NUMBER,
+ Programs.COLUMN_SEASON_DISPLAY_NUMBER + " AS " + Programs.COLUMN_SEASON_NUMBER);
+ sProgramProjectionMap.put(
+ Programs.COLUMN_SEASON_DISPLAY_NUMBER, Programs.COLUMN_SEASON_DISPLAY_NUMBER);
+ sProgramProjectionMap.put(Programs.COLUMN_SEASON_TITLE, Programs.COLUMN_SEASON_TITLE);
+ // COLUMN_EPISODE_NUMBER is deprecated. Return COLUMN_EPISODE_DISPLAY_NUMBER instead.
+ sProgramProjectionMap.put(
+ Programs.COLUMN_EPISODE_NUMBER,
+ Programs.COLUMN_EPISODE_DISPLAY_NUMBER + " AS " + Programs.COLUMN_EPISODE_NUMBER);
+ sProgramProjectionMap.put(
+ Programs.COLUMN_EPISODE_DISPLAY_NUMBER, Programs.COLUMN_EPISODE_DISPLAY_NUMBER);
+ sProgramProjectionMap.put(Programs.COLUMN_EPISODE_TITLE, Programs.COLUMN_EPISODE_TITLE);
+ sProgramProjectionMap.put(
+ Programs.COLUMN_START_TIME_UTC_MILLIS, Programs.COLUMN_START_TIME_UTC_MILLIS);
+ sProgramProjectionMap.put(
+ Programs.COLUMN_END_TIME_UTC_MILLIS, Programs.COLUMN_END_TIME_UTC_MILLIS);
+ sProgramProjectionMap.put(Programs.COLUMN_BROADCAST_GENRE, Programs.COLUMN_BROADCAST_GENRE);
+ sProgramProjectionMap.put(Programs.COLUMN_CANONICAL_GENRE, Programs.COLUMN_CANONICAL_GENRE);
+ sProgramProjectionMap.put(
+ Programs.COLUMN_SHORT_DESCRIPTION, Programs.COLUMN_SHORT_DESCRIPTION);
+ sProgramProjectionMap.put(
+ Programs.COLUMN_LONG_DESCRIPTION, Programs.COLUMN_LONG_DESCRIPTION);
+ sProgramProjectionMap.put(Programs.COLUMN_VIDEO_WIDTH, Programs.COLUMN_VIDEO_WIDTH);
+ sProgramProjectionMap.put(Programs.COLUMN_VIDEO_HEIGHT, Programs.COLUMN_VIDEO_HEIGHT);
+ sProgramProjectionMap.put(Programs.COLUMN_AUDIO_LANGUAGE, Programs.COLUMN_AUDIO_LANGUAGE);
+ sProgramProjectionMap.put(Programs.COLUMN_CONTENT_RATING, Programs.COLUMN_CONTENT_RATING);
+ sProgramProjectionMap.put(Programs.COLUMN_POSTER_ART_URI, Programs.COLUMN_POSTER_ART_URI);
+ sProgramProjectionMap.put(Programs.COLUMN_THUMBNAIL_URI, Programs.COLUMN_THUMBNAIL_URI);
+ sProgramProjectionMap.put(Programs.COLUMN_SEARCHABLE, Programs.COLUMN_SEARCHABLE);
+ sProgramProjectionMap.put(
+ Programs.COLUMN_RECORDING_PROHIBITED, Programs.COLUMN_RECORDING_PROHIBITED);
+ sProgramProjectionMap.put(
+ Programs.COLUMN_INTERNAL_PROVIDER_DATA, Programs.COLUMN_INTERNAL_PROVIDER_DATA);
+ sProgramProjectionMap.put(
+ Programs.COLUMN_INTERNAL_PROVIDER_FLAG1, Programs.COLUMN_INTERNAL_PROVIDER_FLAG1);
+ sProgramProjectionMap.put(
+ Programs.COLUMN_INTERNAL_PROVIDER_FLAG2, Programs.COLUMN_INTERNAL_PROVIDER_FLAG2);
+ sProgramProjectionMap.put(
+ Programs.COLUMN_INTERNAL_PROVIDER_FLAG3, Programs.COLUMN_INTERNAL_PROVIDER_FLAG3);
+ sProgramProjectionMap.put(
+ Programs.COLUMN_INTERNAL_PROVIDER_FLAG4, Programs.COLUMN_INTERNAL_PROVIDER_FLAG4);
+ sProgramProjectionMap.put(Programs.COLUMN_VERSION_NUMBER, Programs.COLUMN_VERSION_NUMBER);
+ sProgramProjectionMap.put(
+ Programs.COLUMN_REVIEW_RATING_STYLE, Programs.COLUMN_REVIEW_RATING_STYLE);
+ sProgramProjectionMap.put(Programs.COLUMN_REVIEW_RATING, Programs.COLUMN_REVIEW_RATING);
+
+ sWatchedProgramProjectionMap = new HashMap<>();
+ sWatchedProgramProjectionMap.put(WatchedPrograms._ID, WatchedPrograms._ID);
+ sWatchedProgramProjectionMap.put(
+ WatchedPrograms.COLUMN_WATCH_START_TIME_UTC_MILLIS,
+ WatchedPrograms.COLUMN_WATCH_START_TIME_UTC_MILLIS);
+ sWatchedProgramProjectionMap.put(
+ WatchedPrograms.COLUMN_WATCH_END_TIME_UTC_MILLIS,
+ WatchedPrograms.COLUMN_WATCH_END_TIME_UTC_MILLIS);
+ sWatchedProgramProjectionMap.put(
+ WatchedPrograms.COLUMN_CHANNEL_ID, WatchedPrograms.COLUMN_CHANNEL_ID);
+ sWatchedProgramProjectionMap.put(
+ WatchedPrograms.COLUMN_TITLE, WatchedPrograms.COLUMN_TITLE);
+ sWatchedProgramProjectionMap.put(
+ WatchedPrograms.COLUMN_START_TIME_UTC_MILLIS,
+ WatchedPrograms.COLUMN_START_TIME_UTC_MILLIS);
+ sWatchedProgramProjectionMap.put(
+ WatchedPrograms.COLUMN_END_TIME_UTC_MILLIS,
+ WatchedPrograms.COLUMN_END_TIME_UTC_MILLIS);
+ sWatchedProgramProjectionMap.put(
+ WatchedPrograms.COLUMN_DESCRIPTION, WatchedPrograms.COLUMN_DESCRIPTION);
+ sWatchedProgramProjectionMap.put(
+ WatchedPrograms.COLUMN_INTERNAL_TUNE_PARAMS,
+ WatchedPrograms.COLUMN_INTERNAL_TUNE_PARAMS);
+ sWatchedProgramProjectionMap.put(
+ WatchedPrograms.COLUMN_INTERNAL_SESSION_TOKEN,
+ WatchedPrograms.COLUMN_INTERNAL_SESSION_TOKEN);
+ sWatchedProgramProjectionMap.put(
+ WATCHED_PROGRAMS_COLUMN_CONSOLIDATED, WATCHED_PROGRAMS_COLUMN_CONSOLIDATED);
+
+ sRecordedProgramProjectionMap = new HashMap<>();
+ sRecordedProgramProjectionMap.put(RecordedPrograms._ID, RecordedPrograms._ID);
+ sRecordedProgramProjectionMap.put(
+ RecordedPrograms.COLUMN_PACKAGE_NAME, RecordedPrograms.COLUMN_PACKAGE_NAME);
+ sRecordedProgramProjectionMap.put(
+ RecordedPrograms.COLUMN_INPUT_ID, RecordedPrograms.COLUMN_INPUT_ID);
+ sRecordedProgramProjectionMap.put(
+ RecordedPrograms.COLUMN_CHANNEL_ID, RecordedPrograms.COLUMN_CHANNEL_ID);
+ sRecordedProgramProjectionMap.put(
+ RecordedPrograms.COLUMN_TITLE, RecordedPrograms.COLUMN_TITLE);
+ sRecordedProgramProjectionMap.put(
+ RecordedPrograms.COLUMN_SEASON_DISPLAY_NUMBER,
+ RecordedPrograms.COLUMN_SEASON_DISPLAY_NUMBER);
+ sRecordedProgramProjectionMap.put(
+ RecordedPrograms.COLUMN_SEASON_TITLE, RecordedPrograms.COLUMN_SEASON_TITLE);
+ sRecordedProgramProjectionMap.put(
+ RecordedPrograms.COLUMN_EPISODE_DISPLAY_NUMBER,
+ RecordedPrograms.COLUMN_EPISODE_DISPLAY_NUMBER);
+ sRecordedProgramProjectionMap.put(
+ RecordedPrograms.COLUMN_EPISODE_TITLE, RecordedPrograms.COLUMN_EPISODE_TITLE);
+ sRecordedProgramProjectionMap.put(
+ RecordedPrograms.COLUMN_START_TIME_UTC_MILLIS,
+ RecordedPrograms.COLUMN_START_TIME_UTC_MILLIS);
+ sRecordedProgramProjectionMap.put(
+ RecordedPrograms.COLUMN_END_TIME_UTC_MILLIS,
+ RecordedPrograms.COLUMN_END_TIME_UTC_MILLIS);
+ sRecordedProgramProjectionMap.put(
+ RecordedPrograms.COLUMN_BROADCAST_GENRE, RecordedPrograms.COLUMN_BROADCAST_GENRE);
+ sRecordedProgramProjectionMap.put(
+ RecordedPrograms.COLUMN_CANONICAL_GENRE, RecordedPrograms.COLUMN_CANONICAL_GENRE);
+ sRecordedProgramProjectionMap.put(
+ RecordedPrograms.COLUMN_SHORT_DESCRIPTION,
+ RecordedPrograms.COLUMN_SHORT_DESCRIPTION);
+ sRecordedProgramProjectionMap.put(
+ RecordedPrograms.COLUMN_LONG_DESCRIPTION, RecordedPrograms.COLUMN_LONG_DESCRIPTION);
+ sRecordedProgramProjectionMap.put(
+ RecordedPrograms.COLUMN_VIDEO_WIDTH, RecordedPrograms.COLUMN_VIDEO_WIDTH);
+ sRecordedProgramProjectionMap.put(
+ RecordedPrograms.COLUMN_VIDEO_HEIGHT, RecordedPrograms.COLUMN_VIDEO_HEIGHT);
+ sRecordedProgramProjectionMap.put(
+ RecordedPrograms.COLUMN_AUDIO_LANGUAGE, RecordedPrograms.COLUMN_AUDIO_LANGUAGE);
+ sRecordedProgramProjectionMap.put(
+ RecordedPrograms.COLUMN_CONTENT_RATING, RecordedPrograms.COLUMN_CONTENT_RATING);
+ sRecordedProgramProjectionMap.put(
+ RecordedPrograms.COLUMN_POSTER_ART_URI, RecordedPrograms.COLUMN_POSTER_ART_URI);
+ sRecordedProgramProjectionMap.put(
+ RecordedPrograms.COLUMN_THUMBNAIL_URI, RecordedPrograms.COLUMN_THUMBNAIL_URI);
+ sRecordedProgramProjectionMap.put(
+ RecordedPrograms.COLUMN_SEARCHABLE, RecordedPrograms.COLUMN_SEARCHABLE);
+ sRecordedProgramProjectionMap.put(
+ RecordedPrograms.COLUMN_RECORDING_DATA_URI,
+ RecordedPrograms.COLUMN_RECORDING_DATA_URI);
+ sRecordedProgramProjectionMap.put(
+ RecordedPrograms.COLUMN_RECORDING_DATA_BYTES,
+ RecordedPrograms.COLUMN_RECORDING_DATA_BYTES);
+ sRecordedProgramProjectionMap.put(
+ RecordedPrograms.COLUMN_RECORDING_DURATION_MILLIS,
+ RecordedPrograms.COLUMN_RECORDING_DURATION_MILLIS);
+ sRecordedProgramProjectionMap.put(
+ RecordedPrograms.COLUMN_RECORDING_EXPIRE_TIME_UTC_MILLIS,
+ RecordedPrograms.COLUMN_RECORDING_EXPIRE_TIME_UTC_MILLIS);
+ sRecordedProgramProjectionMap.put(
+ RecordedPrograms.COLUMN_INTERNAL_PROVIDER_DATA,
+ RecordedPrograms.COLUMN_INTERNAL_PROVIDER_DATA);
+ sRecordedProgramProjectionMap.put(
+ RecordedPrograms.COLUMN_INTERNAL_PROVIDER_FLAG1,
+ RecordedPrograms.COLUMN_INTERNAL_PROVIDER_FLAG1);
+ sRecordedProgramProjectionMap.put(
+ RecordedPrograms.COLUMN_INTERNAL_PROVIDER_FLAG2,
+ RecordedPrograms.COLUMN_INTERNAL_PROVIDER_FLAG2);
+ sRecordedProgramProjectionMap.put(
+ RecordedPrograms.COLUMN_INTERNAL_PROVIDER_FLAG3,
+ RecordedPrograms.COLUMN_INTERNAL_PROVIDER_FLAG3);
+ sRecordedProgramProjectionMap.put(
+ RecordedPrograms.COLUMN_INTERNAL_PROVIDER_FLAG4,
+ RecordedPrograms.COLUMN_INTERNAL_PROVIDER_FLAG4);
+ sRecordedProgramProjectionMap.put(
+ RecordedPrograms.COLUMN_VERSION_NUMBER, RecordedPrograms.COLUMN_VERSION_NUMBER);
+ sRecordedProgramProjectionMap.put(
+ RecordedPrograms.COLUMN_REVIEW_RATING_STYLE,
+ RecordedPrograms.COLUMN_REVIEW_RATING_STYLE);
+ sRecordedProgramProjectionMap.put(
+ RecordedPrograms.COLUMN_REVIEW_RATING, RecordedPrograms.COLUMN_REVIEW_RATING);
+
+ sPreviewProgramProjectionMap = new HashMap<>();
+ sPreviewProgramProjectionMap.put(PreviewPrograms._ID, PreviewPrograms._ID);
+ sPreviewProgramProjectionMap.put(
+ PreviewPrograms.COLUMN_PACKAGE_NAME, PreviewPrograms.COLUMN_PACKAGE_NAME);
+ sPreviewProgramProjectionMap.put(
+ PreviewPrograms.COLUMN_CHANNEL_ID, PreviewPrograms.COLUMN_CHANNEL_ID);
+ sPreviewProgramProjectionMap.put(
+ PreviewPrograms.COLUMN_TITLE, PreviewPrograms.COLUMN_TITLE);
+ sPreviewProgramProjectionMap.put(
+ PreviewPrograms.COLUMN_SEASON_DISPLAY_NUMBER,
+ PreviewPrograms.COLUMN_SEASON_DISPLAY_NUMBER);
+ sPreviewProgramProjectionMap.put(
+ PreviewPrograms.COLUMN_SEASON_TITLE, PreviewPrograms.COLUMN_SEASON_TITLE);
+ sPreviewProgramProjectionMap.put(
+ PreviewPrograms.COLUMN_EPISODE_DISPLAY_NUMBER,
+ PreviewPrograms.COLUMN_EPISODE_DISPLAY_NUMBER);
+ sPreviewProgramProjectionMap.put(
+ PreviewPrograms.COLUMN_EPISODE_TITLE, PreviewPrograms.COLUMN_EPISODE_TITLE);
+ sPreviewProgramProjectionMap.put(
+ PreviewPrograms.COLUMN_CANONICAL_GENRE, PreviewPrograms.COLUMN_CANONICAL_GENRE);
+ sPreviewProgramProjectionMap.put(
+ PreviewPrograms.COLUMN_SHORT_DESCRIPTION, PreviewPrograms.COLUMN_SHORT_DESCRIPTION);
+ sPreviewProgramProjectionMap.put(
+ PreviewPrograms.COLUMN_LONG_DESCRIPTION, PreviewPrograms.COLUMN_LONG_DESCRIPTION);
+ sPreviewProgramProjectionMap.put(
+ PreviewPrograms.COLUMN_VIDEO_WIDTH, PreviewPrograms.COLUMN_VIDEO_WIDTH);
+ sPreviewProgramProjectionMap.put(
+ PreviewPrograms.COLUMN_VIDEO_HEIGHT, PreviewPrograms.COLUMN_VIDEO_HEIGHT);
+ sPreviewProgramProjectionMap.put(
+ PreviewPrograms.COLUMN_AUDIO_LANGUAGE, PreviewPrograms.COLUMN_AUDIO_LANGUAGE);
+ sPreviewProgramProjectionMap.put(
+ PreviewPrograms.COLUMN_CONTENT_RATING, PreviewPrograms.COLUMN_CONTENT_RATING);
+ sPreviewProgramProjectionMap.put(
+ PreviewPrograms.COLUMN_POSTER_ART_URI, PreviewPrograms.COLUMN_POSTER_ART_URI);
+ sPreviewProgramProjectionMap.put(
+ PreviewPrograms.COLUMN_THUMBNAIL_URI, PreviewPrograms.COLUMN_THUMBNAIL_URI);
+ sPreviewProgramProjectionMap.put(
+ PreviewPrograms.COLUMN_SEARCHABLE, PreviewPrograms.COLUMN_SEARCHABLE);
+ sPreviewProgramProjectionMap.put(
+ PreviewPrograms.COLUMN_INTERNAL_PROVIDER_DATA,
+ PreviewPrograms.COLUMN_INTERNAL_PROVIDER_DATA);
+ sPreviewProgramProjectionMap.put(
+ PreviewPrograms.COLUMN_INTERNAL_PROVIDER_FLAG1,
+ PreviewPrograms.COLUMN_INTERNAL_PROVIDER_FLAG1);
+ sPreviewProgramProjectionMap.put(
+ PreviewPrograms.COLUMN_INTERNAL_PROVIDER_FLAG2,
+ PreviewPrograms.COLUMN_INTERNAL_PROVIDER_FLAG2);
+ sPreviewProgramProjectionMap.put(
+ PreviewPrograms.COLUMN_INTERNAL_PROVIDER_FLAG3,
+ PreviewPrograms.COLUMN_INTERNAL_PROVIDER_FLAG3);
+ sPreviewProgramProjectionMap.put(
+ PreviewPrograms.COLUMN_INTERNAL_PROVIDER_FLAG4,
+ PreviewPrograms.COLUMN_INTERNAL_PROVIDER_FLAG4);
+ sPreviewProgramProjectionMap.put(
+ PreviewPrograms.COLUMN_VERSION_NUMBER, PreviewPrograms.COLUMN_VERSION_NUMBER);
+ sPreviewProgramProjectionMap.put(
+ PreviewPrograms.COLUMN_INTERNAL_PROVIDER_ID,
+ PreviewPrograms.COLUMN_INTERNAL_PROVIDER_ID);
+ sPreviewProgramProjectionMap.put(
+ PreviewPrograms.COLUMN_PREVIEW_VIDEO_URI, PreviewPrograms.COLUMN_PREVIEW_VIDEO_URI);
+ sPreviewProgramProjectionMap.put(
+ PreviewPrograms.COLUMN_LAST_PLAYBACK_POSITION_MILLIS,
+ PreviewPrograms.COLUMN_LAST_PLAYBACK_POSITION_MILLIS);
+ sPreviewProgramProjectionMap.put(
+ PreviewPrograms.COLUMN_DURATION_MILLIS, PreviewPrograms.COLUMN_DURATION_MILLIS);
+ sPreviewProgramProjectionMap.put(
+ PreviewPrograms.COLUMN_INTENT_URI, PreviewPrograms.COLUMN_INTENT_URI);
+ sPreviewProgramProjectionMap.put(
+ PreviewPrograms.COLUMN_WEIGHT, PreviewPrograms.COLUMN_WEIGHT);
+ sPreviewProgramProjectionMap.put(
+ PreviewPrograms.COLUMN_TRANSIENT, PreviewPrograms.COLUMN_TRANSIENT);
+ sPreviewProgramProjectionMap.put(PreviewPrograms.COLUMN_TYPE, PreviewPrograms.COLUMN_TYPE);
+ sPreviewProgramProjectionMap.put(
+ PreviewPrograms.COLUMN_POSTER_ART_ASPECT_RATIO,
+ PreviewPrograms.COLUMN_POSTER_ART_ASPECT_RATIO);
+ sPreviewProgramProjectionMap.put(
+ PreviewPrograms.COLUMN_THUMBNAIL_ASPECT_RATIO,
+ PreviewPrograms.COLUMN_THUMBNAIL_ASPECT_RATIO);
+ sPreviewProgramProjectionMap.put(
+ PreviewPrograms.COLUMN_LOGO_URI, PreviewPrograms.COLUMN_LOGO_URI);
+ sPreviewProgramProjectionMap.put(
+ PreviewPrograms.COLUMN_AVAILABILITY, PreviewPrograms.COLUMN_AVAILABILITY);
+ sPreviewProgramProjectionMap.put(
+ PreviewPrograms.COLUMN_STARTING_PRICE, PreviewPrograms.COLUMN_STARTING_PRICE);
+ sPreviewProgramProjectionMap.put(
+ PreviewPrograms.COLUMN_OFFER_PRICE, PreviewPrograms.COLUMN_OFFER_PRICE);
+ sPreviewProgramProjectionMap.put(
+ PreviewPrograms.COLUMN_RELEASE_DATE, PreviewPrograms.COLUMN_RELEASE_DATE);
+ sPreviewProgramProjectionMap.put(
+ PreviewPrograms.COLUMN_ITEM_COUNT, PreviewPrograms.COLUMN_ITEM_COUNT);
+ sPreviewProgramProjectionMap.put(PreviewPrograms.COLUMN_LIVE, PreviewPrograms.COLUMN_LIVE);
+ sPreviewProgramProjectionMap.put(
+ PreviewPrograms.COLUMN_INTERACTION_TYPE, PreviewPrograms.COLUMN_INTERACTION_TYPE);
+ sPreviewProgramProjectionMap.put(
+ PreviewPrograms.COLUMN_INTERACTION_COUNT, PreviewPrograms.COLUMN_INTERACTION_COUNT);
+ sPreviewProgramProjectionMap.put(
+ PreviewPrograms.COLUMN_AUTHOR, PreviewPrograms.COLUMN_AUTHOR);
+ sPreviewProgramProjectionMap.put(
+ PreviewPrograms.COLUMN_REVIEW_RATING_STYLE,
+ PreviewPrograms.COLUMN_REVIEW_RATING_STYLE);
+ sPreviewProgramProjectionMap.put(
+ PreviewPrograms.COLUMN_REVIEW_RATING, PreviewPrograms.COLUMN_REVIEW_RATING);
+ sPreviewProgramProjectionMap.put(
+ PreviewPrograms.COLUMN_BROWSABLE, PreviewPrograms.COLUMN_BROWSABLE);
+ sPreviewProgramProjectionMap.put(
+ PreviewPrograms.COLUMN_CONTENT_ID, PreviewPrograms.COLUMN_CONTENT_ID);
+
+ sWatchNextProgramProjectionMap = new HashMap<>();
+ sWatchNextProgramProjectionMap.put(WatchNextPrograms._ID, WatchNextPrograms._ID);
+ sWatchNextProgramProjectionMap.put(
+ WatchNextPrograms.COLUMN_PACKAGE_NAME, WatchNextPrograms.COLUMN_PACKAGE_NAME);
+ sWatchNextProgramProjectionMap.put(
+ WatchNextPrograms.COLUMN_TITLE, WatchNextPrograms.COLUMN_TITLE);
+ sWatchNextProgramProjectionMap.put(
+ WatchNextPrograms.COLUMN_SEASON_DISPLAY_NUMBER,
+ WatchNextPrograms.COLUMN_SEASON_DISPLAY_NUMBER);
+ sWatchNextProgramProjectionMap.put(
+ WatchNextPrograms.COLUMN_SEASON_TITLE, WatchNextPrograms.COLUMN_SEASON_TITLE);
+ sWatchNextProgramProjectionMap.put(
+ WatchNextPrograms.COLUMN_EPISODE_DISPLAY_NUMBER,
+ WatchNextPrograms.COLUMN_EPISODE_DISPLAY_NUMBER);
+ sWatchNextProgramProjectionMap.put(
+ WatchNextPrograms.COLUMN_EPISODE_TITLE, WatchNextPrograms.COLUMN_EPISODE_TITLE);
+ sWatchNextProgramProjectionMap.put(
+ WatchNextPrograms.COLUMN_CANONICAL_GENRE, WatchNextPrograms.COLUMN_CANONICAL_GENRE);
+ sWatchNextProgramProjectionMap.put(
+ WatchNextPrograms.COLUMN_SHORT_DESCRIPTION,
+ WatchNextPrograms.COLUMN_SHORT_DESCRIPTION);
+ sWatchNextProgramProjectionMap.put(
+ WatchNextPrograms.COLUMN_LONG_DESCRIPTION,
+ WatchNextPrograms.COLUMN_LONG_DESCRIPTION);
+ sWatchNextProgramProjectionMap.put(
+ WatchNextPrograms.COLUMN_VIDEO_WIDTH, WatchNextPrograms.COLUMN_VIDEO_WIDTH);
+ sWatchNextProgramProjectionMap.put(
+ WatchNextPrograms.COLUMN_VIDEO_HEIGHT, WatchNextPrograms.COLUMN_VIDEO_HEIGHT);
+ sWatchNextProgramProjectionMap.put(
+ WatchNextPrograms.COLUMN_AUDIO_LANGUAGE, WatchNextPrograms.COLUMN_AUDIO_LANGUAGE);
+ sWatchNextProgramProjectionMap.put(
+ WatchNextPrograms.COLUMN_CONTENT_RATING, WatchNextPrograms.COLUMN_CONTENT_RATING);
+ sWatchNextProgramProjectionMap.put(
+ WatchNextPrograms.COLUMN_POSTER_ART_URI, WatchNextPrograms.COLUMN_POSTER_ART_URI);
+ sWatchNextProgramProjectionMap.put(
+ WatchNextPrograms.COLUMN_THUMBNAIL_URI, WatchNextPrograms.COLUMN_THUMBNAIL_URI);
+ sWatchNextProgramProjectionMap.put(
+ WatchNextPrograms.COLUMN_SEARCHABLE, WatchNextPrograms.COLUMN_SEARCHABLE);
+ sWatchNextProgramProjectionMap.put(
+ WatchNextPrograms.COLUMN_INTERNAL_PROVIDER_DATA,
+ WatchNextPrograms.COLUMN_INTERNAL_PROVIDER_DATA);
+ sWatchNextProgramProjectionMap.put(
+ WatchNextPrograms.COLUMN_INTERNAL_PROVIDER_FLAG1,
+ WatchNextPrograms.COLUMN_INTERNAL_PROVIDER_FLAG1);
+ sWatchNextProgramProjectionMap.put(
+ WatchNextPrograms.COLUMN_INTERNAL_PROVIDER_FLAG2,
+ WatchNextPrograms.COLUMN_INTERNAL_PROVIDER_FLAG2);
+ sWatchNextProgramProjectionMap.put(
+ WatchNextPrograms.COLUMN_INTERNAL_PROVIDER_FLAG3,
+ WatchNextPrograms.COLUMN_INTERNAL_PROVIDER_FLAG3);
+ sWatchNextProgramProjectionMap.put(
+ WatchNextPrograms.COLUMN_INTERNAL_PROVIDER_FLAG4,
+ WatchNextPrograms.COLUMN_INTERNAL_PROVIDER_FLAG4);
+ sWatchNextProgramProjectionMap.put(
+ WatchNextPrograms.COLUMN_VERSION_NUMBER, WatchNextPrograms.COLUMN_VERSION_NUMBER);
+ sWatchNextProgramProjectionMap.put(
+ WatchNextPrograms.COLUMN_INTERNAL_PROVIDER_ID,
+ WatchNextPrograms.COLUMN_INTERNAL_PROVIDER_ID);
+ sWatchNextProgramProjectionMap.put(
+ WatchNextPrograms.COLUMN_PREVIEW_VIDEO_URI,
+ WatchNextPrograms.COLUMN_PREVIEW_VIDEO_URI);
+ sWatchNextProgramProjectionMap.put(
+ WatchNextPrograms.COLUMN_LAST_PLAYBACK_POSITION_MILLIS,
+ WatchNextPrograms.COLUMN_LAST_PLAYBACK_POSITION_MILLIS);
+ sWatchNextProgramProjectionMap.put(
+ WatchNextPrograms.COLUMN_DURATION_MILLIS, WatchNextPrograms.COLUMN_DURATION_MILLIS);
+ sWatchNextProgramProjectionMap.put(
+ WatchNextPrograms.COLUMN_INTENT_URI, WatchNextPrograms.COLUMN_INTENT_URI);
+ sWatchNextProgramProjectionMap.put(
+ WatchNextPrograms.COLUMN_TRANSIENT, WatchNextPrograms.COLUMN_TRANSIENT);
+ sWatchNextProgramProjectionMap.put(
+ WatchNextPrograms.COLUMN_TYPE, WatchNextPrograms.COLUMN_TYPE);
+ sWatchNextProgramProjectionMap.put(
+ WatchNextPrograms.COLUMN_WATCH_NEXT_TYPE, WatchNextPrograms.COLUMN_WATCH_NEXT_TYPE);
+ sWatchNextProgramProjectionMap.put(
+ WatchNextPrograms.COLUMN_POSTER_ART_ASPECT_RATIO,
+ WatchNextPrograms.COLUMN_POSTER_ART_ASPECT_RATIO);
+ sWatchNextProgramProjectionMap.put(
+ WatchNextPrograms.COLUMN_THUMBNAIL_ASPECT_RATIO,
+ WatchNextPrograms.COLUMN_THUMBNAIL_ASPECT_RATIO);
+ sWatchNextProgramProjectionMap.put(
+ WatchNextPrograms.COLUMN_LOGO_URI, WatchNextPrograms.COLUMN_LOGO_URI);
+ sWatchNextProgramProjectionMap.put(
+ WatchNextPrograms.COLUMN_AVAILABILITY, WatchNextPrograms.COLUMN_AVAILABILITY);
+ sWatchNextProgramProjectionMap.put(
+ WatchNextPrograms.COLUMN_STARTING_PRICE, WatchNextPrograms.COLUMN_STARTING_PRICE);
+ sWatchNextProgramProjectionMap.put(
+ WatchNextPrograms.COLUMN_OFFER_PRICE, WatchNextPrograms.COLUMN_OFFER_PRICE);
+ sWatchNextProgramProjectionMap.put(
+ WatchNextPrograms.COLUMN_RELEASE_DATE, WatchNextPrograms.COLUMN_RELEASE_DATE);
+ sWatchNextProgramProjectionMap.put(
+ WatchNextPrograms.COLUMN_ITEM_COUNT, WatchNextPrograms.COLUMN_ITEM_COUNT);
+ sWatchNextProgramProjectionMap.put(
+ WatchNextPrograms.COLUMN_LIVE, WatchNextPrograms.COLUMN_LIVE);
+ sWatchNextProgramProjectionMap.put(
+ WatchNextPrograms.COLUMN_INTERACTION_TYPE,
+ WatchNextPrograms.COLUMN_INTERACTION_TYPE);
+ sWatchNextProgramProjectionMap.put(
+ WatchNextPrograms.COLUMN_INTERACTION_COUNT,
+ WatchNextPrograms.COLUMN_INTERACTION_COUNT);
+ sWatchNextProgramProjectionMap.put(
+ WatchNextPrograms.COLUMN_AUTHOR, WatchNextPrograms.COLUMN_AUTHOR);
+ sWatchNextProgramProjectionMap.put(
+ WatchNextPrograms.COLUMN_REVIEW_RATING_STYLE,
+ WatchNextPrograms.COLUMN_REVIEW_RATING_STYLE);
+ sWatchNextProgramProjectionMap.put(
+ WatchNextPrograms.COLUMN_REVIEW_RATING, WatchNextPrograms.COLUMN_REVIEW_RATING);
+ sWatchNextProgramProjectionMap.put(
+ WatchNextPrograms.COLUMN_BROWSABLE, WatchNextPrograms.COLUMN_BROWSABLE);
+ sWatchNextProgramProjectionMap.put(
+ WatchNextPrograms.COLUMN_CONTENT_ID, WatchNextPrograms.COLUMN_CONTENT_ID);
+ sWatchNextProgramProjectionMap.put(
+ WatchNextPrograms.COLUMN_LAST_ENGAGEMENT_TIME_UTC_MILLIS,
+ WatchNextPrograms.COLUMN_LAST_ENGAGEMENT_TIME_UTC_MILLIS);
+ }
+
+ // Mapping from broadcast genre to canonical genre.
+ private static Map<String, String> sGenreMap;
+
+ private static final String PERMISSION_READ_TV_LISTINGS = "android.permission.READ_TV_LISTINGS";
+
+ private static final String PERMISSION_ACCESS_ALL_EPG_DATA =
+ "com.android.providers.tv.permission.ACCESS_ALL_EPG_DATA";
+
+ private static final String PERMISSION_ACCESS_WATCHED_PROGRAMS =
+ "com.android.providers.tv.permission.ACCESS_WATCHED_PROGRAMS";
+
+ private static final String CREATE_RECORDED_PROGRAMS_TABLE_SQL =
+ "CREATE TABLE "
+ + RECORDED_PROGRAMS_TABLE
+ + " ("
+ + RecordedPrograms._ID
+ + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ + RecordedPrograms.COLUMN_PACKAGE_NAME
+ + " TEXT NOT NULL,"
+ + RecordedPrograms.COLUMN_INPUT_ID
+ + " TEXT NOT NULL,"
+ + RecordedPrograms.COLUMN_CHANNEL_ID
+ + " INTEGER,"
+ + RecordedPrograms.COLUMN_TITLE
+ + " TEXT,"
+ + RecordedPrograms.COLUMN_SEASON_DISPLAY_NUMBER
+ + " TEXT,"
+ + RecordedPrograms.COLUMN_SEASON_TITLE
+ + " TEXT,"
+ + RecordedPrograms.COLUMN_EPISODE_DISPLAY_NUMBER
+ + " TEXT,"
+ + RecordedPrograms.COLUMN_EPISODE_TITLE
+ + " TEXT,"
+ + RecordedPrograms.COLUMN_START_TIME_UTC_MILLIS
+ + " INTEGER,"
+ + RecordedPrograms.COLUMN_END_TIME_UTC_MILLIS
+ + " INTEGER,"
+ + RecordedPrograms.COLUMN_BROADCAST_GENRE
+ + " TEXT,"
+ + RecordedPrograms.COLUMN_CANONICAL_GENRE
+ + " TEXT,"
+ + RecordedPrograms.COLUMN_SHORT_DESCRIPTION
+ + " TEXT,"
+ + RecordedPrograms.COLUMN_LONG_DESCRIPTION
+ + " TEXT,"
+ + RecordedPrograms.COLUMN_VIDEO_WIDTH
+ + " INTEGER,"
+ + RecordedPrograms.COLUMN_VIDEO_HEIGHT
+ + " INTEGER,"
+ + RecordedPrograms.COLUMN_AUDIO_LANGUAGE
+ + " TEXT,"
+ + RecordedPrograms.COLUMN_CONTENT_RATING
+ + " TEXT,"
+ + RecordedPrograms.COLUMN_POSTER_ART_URI
+ + " TEXT,"
+ + RecordedPrograms.COLUMN_THUMBNAIL_URI
+ + " TEXT,"
+ + RecordedPrograms.COLUMN_SEARCHABLE
+ + " INTEGER NOT NULL DEFAULT 1,"
+ + RecordedPrograms.COLUMN_RECORDING_DATA_URI
+ + " TEXT,"
+ + RecordedPrograms.COLUMN_RECORDING_DATA_BYTES
+ + " INTEGER,"
+ + RecordedPrograms.COLUMN_RECORDING_DURATION_MILLIS
+ + " INTEGER,"
+ + RecordedPrograms.COLUMN_RECORDING_EXPIRE_TIME_UTC_MILLIS
+ + " INTEGER,"
+ + RecordedPrograms.COLUMN_INTERNAL_PROVIDER_DATA
+ + " BLOB,"
+ + RecordedPrograms.COLUMN_INTERNAL_PROVIDER_FLAG1
+ + " INTEGER,"
+ + RecordedPrograms.COLUMN_INTERNAL_PROVIDER_FLAG2
+ + " INTEGER,"
+ + RecordedPrograms.COLUMN_INTERNAL_PROVIDER_FLAG3
+ + " INTEGER,"
+ + RecordedPrograms.COLUMN_INTERNAL_PROVIDER_FLAG4
+ + " INTEGER,"
+ + RecordedPrograms.COLUMN_VERSION_NUMBER
+ + " INTEGER,"
+ + RecordedPrograms.COLUMN_REVIEW_RATING_STYLE
+ + " INTEGER,"
+ + RecordedPrograms.COLUMN_REVIEW_RATING
+ + " TEXT,"
+ + "FOREIGN KEY("
+ + RecordedPrograms.COLUMN_CHANNEL_ID
+ + ") "
+ + "REFERENCES "
+ + CHANNELS_TABLE
+ + "("
+ + Channels._ID
+ + ") "
+ + "ON UPDATE CASCADE ON DELETE SET NULL);";
+
+ private static final String CREATE_PREVIEW_PROGRAMS_TABLE_SQL =
+ "CREATE TABLE "
+ + PREVIEW_PROGRAMS_TABLE
+ + " ("
+ + PreviewPrograms._ID
+ + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ + PreviewPrograms.COLUMN_PACKAGE_NAME
+ + " TEXT NOT NULL,"
+ + PreviewPrograms.COLUMN_CHANNEL_ID
+ + " INTEGER,"
+ + PreviewPrograms.COLUMN_TITLE
+ + " TEXT,"
+ + PreviewPrograms.COLUMN_SEASON_DISPLAY_NUMBER
+ + " TEXT,"
+ + PreviewPrograms.COLUMN_SEASON_TITLE
+ + " TEXT,"
+ + PreviewPrograms.COLUMN_EPISODE_DISPLAY_NUMBER
+ + " TEXT,"
+ + PreviewPrograms.COLUMN_EPISODE_TITLE
+ + " TEXT,"
+ + PreviewPrograms.COLUMN_CANONICAL_GENRE
+ + " TEXT,"
+ + PreviewPrograms.COLUMN_SHORT_DESCRIPTION
+ + " TEXT,"
+ + PreviewPrograms.COLUMN_LONG_DESCRIPTION
+ + " TEXT,"
+ + PreviewPrograms.COLUMN_VIDEO_WIDTH
+ + " INTEGER,"
+ + PreviewPrograms.COLUMN_VIDEO_HEIGHT
+ + " INTEGER,"
+ + PreviewPrograms.COLUMN_AUDIO_LANGUAGE
+ + " TEXT,"
+ + PreviewPrograms.COLUMN_CONTENT_RATING
+ + " TEXT,"
+ + PreviewPrograms.COLUMN_POSTER_ART_URI
+ + " TEXT,"
+ + PreviewPrograms.COLUMN_THUMBNAIL_URI
+ + " TEXT,"
+ + PreviewPrograms.COLUMN_SEARCHABLE
+ + " INTEGER NOT NULL DEFAULT 1,"
+ + PreviewPrograms.COLUMN_INTERNAL_PROVIDER_DATA
+ + " BLOB,"
+ + PreviewPrograms.COLUMN_INTERNAL_PROVIDER_FLAG1
+ + " INTEGER,"
+ + PreviewPrograms.COLUMN_INTERNAL_PROVIDER_FLAG2
+ + " INTEGER,"
+ + PreviewPrograms.COLUMN_INTERNAL_PROVIDER_FLAG3
+ + " INTEGER,"
+ + PreviewPrograms.COLUMN_INTERNAL_PROVIDER_FLAG4
+ + " INTEGER,"
+ + PreviewPrograms.COLUMN_VERSION_NUMBER
+ + " INTEGER,"
+ + PreviewPrograms.COLUMN_INTERNAL_PROVIDER_ID
+ + " TEXT,"
+ + PreviewPrograms.COLUMN_PREVIEW_VIDEO_URI
+ + " TEXT,"
+ + PreviewPrograms.COLUMN_LAST_PLAYBACK_POSITION_MILLIS
+ + " INTEGER,"
+ + PreviewPrograms.COLUMN_DURATION_MILLIS
+ + " INTEGER,"
+ + PreviewPrograms.COLUMN_INTENT_URI
+ + " TEXT,"
+ + PreviewPrograms.COLUMN_WEIGHT
+ + " INTEGER,"
+ + PreviewPrograms.COLUMN_TRANSIENT
+ + " INTEGER NOT NULL DEFAULT 0,"
+ + PreviewPrograms.COLUMN_TYPE
+ + " INTEGER NOT NULL,"
+ + PreviewPrograms.COLUMN_POSTER_ART_ASPECT_RATIO
+ + " INTEGER,"
+ + PreviewPrograms.COLUMN_THUMBNAIL_ASPECT_RATIO
+ + " INTEGER,"
+ + PreviewPrograms.COLUMN_LOGO_URI
+ + " TEXT,"
+ + PreviewPrograms.COLUMN_AVAILABILITY
+ + " INTERGER,"
+ + PreviewPrograms.COLUMN_STARTING_PRICE
+ + " TEXT,"
+ + PreviewPrograms.COLUMN_OFFER_PRICE
+ + " TEXT,"
+ + PreviewPrograms.COLUMN_RELEASE_DATE
+ + " TEXT,"
+ + PreviewPrograms.COLUMN_ITEM_COUNT
+ + " INTEGER,"
+ + PreviewPrograms.COLUMN_LIVE
+ + " INTEGER NOT NULL DEFAULT 0,"
+ + PreviewPrograms.COLUMN_INTERACTION_TYPE
+ + " INTEGER,"
+ + PreviewPrograms.COLUMN_INTERACTION_COUNT
+ + " INTEGER,"
+ + PreviewPrograms.COLUMN_AUTHOR
+ + " TEXT,"
+ + PreviewPrograms.COLUMN_REVIEW_RATING_STYLE
+ + " INTEGER,"
+ + PreviewPrograms.COLUMN_REVIEW_RATING
+ + " TEXT,"
+ + PreviewPrograms.COLUMN_BROWSABLE
+ + " INTEGER NOT NULL DEFAULT 1,"
+ + PreviewPrograms.COLUMN_CONTENT_ID
+ + " TEXT,"
+ + "FOREIGN KEY("
+ + PreviewPrograms.COLUMN_CHANNEL_ID
+ + ","
+ + PreviewPrograms.COLUMN_PACKAGE_NAME
+ + ") REFERENCES "
+ + CHANNELS_TABLE
+ + "("
+ + Channels._ID
+ + ","
+ + Channels.COLUMN_PACKAGE_NAME
+ + ") ON UPDATE CASCADE ON DELETE CASCADE"
+ + ");";
+ private static final String CREATE_PREVIEW_PROGRAMS_PACKAGE_NAME_INDEX_SQL =
+ "CREATE INDEX preview_programs_package_name_index ON "
+ + PREVIEW_PROGRAMS_TABLE
+ + "("
+ + PreviewPrograms.COLUMN_PACKAGE_NAME
+ + ");";
+ private static final String CREATE_PREVIEW_PROGRAMS_CHANNEL_ID_INDEX_SQL =
+ "CREATE INDEX preview_programs_id_index ON "
+ + PREVIEW_PROGRAMS_TABLE
+ + "("
+ + PreviewPrograms.COLUMN_CHANNEL_ID
+ + ");";
+ private static final String CREATE_WATCH_NEXT_PROGRAMS_TABLE_SQL =
+ "CREATE TABLE "
+ + WATCH_NEXT_PROGRAMS_TABLE
+ + " ("
+ + WatchNextPrograms._ID
+ + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ + WatchNextPrograms.COLUMN_PACKAGE_NAME
+ + " TEXT NOT NULL,"
+ + WatchNextPrograms.COLUMN_TITLE
+ + " TEXT,"
+ + WatchNextPrograms.COLUMN_SEASON_DISPLAY_NUMBER
+ + " TEXT,"
+ + WatchNextPrograms.COLUMN_SEASON_TITLE
+ + " TEXT,"
+ + WatchNextPrograms.COLUMN_EPISODE_DISPLAY_NUMBER
+ + " TEXT,"
+ + WatchNextPrograms.COLUMN_EPISODE_TITLE
+ + " TEXT,"
+ + WatchNextPrograms.COLUMN_CANONICAL_GENRE
+ + " TEXT,"
+ + WatchNextPrograms.COLUMN_SHORT_DESCRIPTION
+ + " TEXT,"
+ + WatchNextPrograms.COLUMN_LONG_DESCRIPTION
+ + " TEXT,"
+ + WatchNextPrograms.COLUMN_VIDEO_WIDTH
+ + " INTEGER,"
+ + WatchNextPrograms.COLUMN_VIDEO_HEIGHT
+ + " INTEGER,"
+ + WatchNextPrograms.COLUMN_AUDIO_LANGUAGE
+ + " TEXT,"
+ + WatchNextPrograms.COLUMN_CONTENT_RATING
+ + " TEXT,"
+ + WatchNextPrograms.COLUMN_POSTER_ART_URI
+ + " TEXT,"
+ + WatchNextPrograms.COLUMN_THUMBNAIL_URI
+ + " TEXT,"
+ + WatchNextPrograms.COLUMN_SEARCHABLE
+ + " INTEGER NOT NULL DEFAULT 1,"
+ + WatchNextPrograms.COLUMN_INTERNAL_PROVIDER_DATA
+ + " BLOB,"
+ + WatchNextPrograms.COLUMN_INTERNAL_PROVIDER_FLAG1
+ + " INTEGER,"
+ + WatchNextPrograms.COLUMN_INTERNAL_PROVIDER_FLAG2
+ + " INTEGER,"
+ + WatchNextPrograms.COLUMN_INTERNAL_PROVIDER_FLAG3
+ + " INTEGER,"
+ + WatchNextPrograms.COLUMN_INTERNAL_PROVIDER_FLAG4
+ + " INTEGER,"
+ + WatchNextPrograms.COLUMN_VERSION_NUMBER
+ + " INTEGER,"
+ + WatchNextPrograms.COLUMN_INTERNAL_PROVIDER_ID
+ + " TEXT,"
+ + WatchNextPrograms.COLUMN_PREVIEW_VIDEO_URI
+ + " TEXT,"
+ + WatchNextPrograms.COLUMN_LAST_PLAYBACK_POSITION_MILLIS
+ + " INTEGER,"
+ + WatchNextPrograms.COLUMN_DURATION_MILLIS
+ + " INTEGER,"
+ + WatchNextPrograms.COLUMN_INTENT_URI
+ + " TEXT,"
+ + WatchNextPrograms.COLUMN_TRANSIENT
+ + " INTEGER NOT NULL DEFAULT 0,"
+ + WatchNextPrograms.COLUMN_TYPE
+ + " INTEGER NOT NULL,"
+ + WatchNextPrograms.COLUMN_WATCH_NEXT_TYPE
+ + " INTEGER,"
+ + WatchNextPrograms.COLUMN_POSTER_ART_ASPECT_RATIO
+ + " INTEGER,"
+ + WatchNextPrograms.COLUMN_THUMBNAIL_ASPECT_RATIO
+ + " INTEGER,"
+ + WatchNextPrograms.COLUMN_LOGO_URI
+ + " TEXT,"
+ + WatchNextPrograms.COLUMN_AVAILABILITY
+ + " INTEGER,"
+ + WatchNextPrograms.COLUMN_STARTING_PRICE
+ + " TEXT,"
+ + WatchNextPrograms.COLUMN_OFFER_PRICE
+ + " TEXT,"
+ + WatchNextPrograms.COLUMN_RELEASE_DATE
+ + " TEXT,"
+ + WatchNextPrograms.COLUMN_ITEM_COUNT
+ + " INTEGER,"
+ + WatchNextPrograms.COLUMN_LIVE
+ + " INTEGER NOT NULL DEFAULT 0,"
+ + WatchNextPrograms.COLUMN_INTERACTION_TYPE
+ + " INTEGER,"
+ + WatchNextPrograms.COLUMN_INTERACTION_COUNT
+ + " INTEGER,"
+ + WatchNextPrograms.COLUMN_AUTHOR
+ + " TEXT,"
+ + WatchNextPrograms.COLUMN_REVIEW_RATING_STYLE
+ + " INTEGER,"
+ + WatchNextPrograms.COLUMN_REVIEW_RATING
+ + " TEXT,"
+ + WatchNextPrograms.COLUMN_BROWSABLE
+ + " INTEGER NOT NULL DEFAULT 1,"
+ + WatchNextPrograms.COLUMN_CONTENT_ID
+ + " TEXT,"
+ + WatchNextPrograms.COLUMN_LAST_ENGAGEMENT_TIME_UTC_MILLIS
+ + " INTEGER"
+ + ");";
+ private static final String CREATE_WATCH_NEXT_PROGRAMS_PACKAGE_NAME_INDEX_SQL =
+ "CREATE INDEX watch_next_programs_package_name_index ON "
+ + WATCH_NEXT_PROGRAMS_TABLE
+ + "("
+ + WatchNextPrograms.COLUMN_PACKAGE_NAME
+ + ");";
+
+ private String mCallingPackage = "com.android.tv";
+
+ static class DatabaseHelper extends SQLiteOpenHelper {
+ private Context mContext;
+
+ public static synchronized DatabaseHelper createInstance(Context context) {
+ return new DatabaseHelper(context);
+ }
+
+ private DatabaseHelper(Context context) {
+ this(context, DATABASE_NAME, DATABASE_VERSION);
+ }
+
+ @VisibleForTesting
+ DatabaseHelper(Context context, String databaseName, int databaseVersion) {
+ super(context, databaseName, null, databaseVersion);
+ mContext = context;
+ }
+
+ @Override
+ public void onConfigure(SQLiteDatabase db) {
+ db.setForeignKeyConstraintsEnabled(true);
+ }
+
+ @Override
+ public void onCreate(SQLiteDatabase db) {
+ if (DEBUG) {
+ Log.d(TAG, "Creating database");
+ }
+ // Set up the database schema.
+ db.execSQL(
+ "CREATE TABLE "
+ + CHANNELS_TABLE
+ + " ("
+ + Channels._ID
+ + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ + Channels.COLUMN_PACKAGE_NAME
+ + " TEXT NOT NULL,"
+ + Channels.COLUMN_INPUT_ID
+ + " TEXT NOT NULL,"
+ + Channels.COLUMN_TYPE
+ + " TEXT NOT NULL DEFAULT '"
+ + Channels.TYPE_OTHER
+ + "',"
+ + Channels.COLUMN_SERVICE_TYPE
+ + " TEXT NOT NULL DEFAULT '"
+ + Channels.SERVICE_TYPE_AUDIO_VIDEO
+ + "',"
+ + Channels.COLUMN_ORIGINAL_NETWORK_ID
+ + " INTEGER NOT NULL DEFAULT 0,"
+ + Channels.COLUMN_TRANSPORT_STREAM_ID
+ + " INTEGER NOT NULL DEFAULT 0,"
+ + Channels.COLUMN_SERVICE_ID
+ + " INTEGER NOT NULL DEFAULT 0,"
+ + Channels.COLUMN_DISPLAY_NUMBER
+ + " TEXT,"
+ + Channels.COLUMN_DISPLAY_NAME
+ + " TEXT,"
+ + Channels.COLUMN_NETWORK_AFFILIATION
+ + " TEXT,"
+ + Channels.COLUMN_DESCRIPTION
+ + " TEXT,"
+ + Channels.COLUMN_VIDEO_FORMAT
+ + " TEXT,"
+ + Channels.COLUMN_BROWSABLE
+ + " INTEGER NOT NULL DEFAULT 0,"
+ + Channels.COLUMN_SEARCHABLE
+ + " INTEGER NOT NULL DEFAULT 1,"
+ + Channels.COLUMN_LOCKED
+ + " INTEGER NOT NULL DEFAULT 0,"
+ + Channels.COLUMN_APP_LINK_ICON_URI
+ + " TEXT,"
+ + Channels.COLUMN_APP_LINK_POSTER_ART_URI
+ + " TEXT,"
+ + Channels.COLUMN_APP_LINK_TEXT
+ + " TEXT,"
+ + Channels.COLUMN_APP_LINK_COLOR
+ + " INTEGER,"
+ + Channels.COLUMN_APP_LINK_INTENT_URI
+ + " TEXT,"
+ + Channels.COLUMN_INTERNAL_PROVIDER_DATA
+ + " BLOB,"
+ + Channels.COLUMN_INTERNAL_PROVIDER_FLAG1
+ + " INTEGER,"
+ + Channels.COLUMN_INTERNAL_PROVIDER_FLAG2
+ + " INTEGER,"
+ + Channels.COLUMN_INTERNAL_PROVIDER_FLAG3
+ + " INTEGER,"
+ + Channels.COLUMN_INTERNAL_PROVIDER_FLAG4
+ + " INTEGER,"
+ + CHANNELS_COLUMN_LOGO
+ + " BLOB,"
+ + Channels.COLUMN_VERSION_NUMBER
+ + " INTEGER,"
+ + Channels.COLUMN_TRANSIENT
+ + " INTEGER NOT NULL DEFAULT 0,"
+ + Channels.COLUMN_INTERNAL_PROVIDER_ID
+ + " TEXT,"
+ // Needed for foreign keys in other tables.
+ + "UNIQUE("
+ + Channels._ID
+ + ","
+ + Channels.COLUMN_PACKAGE_NAME
+ + ")"
+ + ");");
+ db.execSQL(
+ "CREATE TABLE "
+ + PROGRAMS_TABLE
+ + " ("
+ + Programs._ID
+ + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ + Programs.COLUMN_PACKAGE_NAME
+ + " TEXT NOT NULL,"
+ + Programs.COLUMN_CHANNEL_ID
+ + " INTEGER,"
+ + Programs.COLUMN_TITLE
+ + " TEXT,"
+ + Programs.COLUMN_SEASON_DISPLAY_NUMBER
+ + " TEXT,"
+ + Programs.COLUMN_SEASON_TITLE
+ + " TEXT,"
+ + Programs.COLUMN_EPISODE_DISPLAY_NUMBER
+ + " TEXT,"
+ + Programs.COLUMN_EPISODE_TITLE
+ + " TEXT,"
+ + Programs.COLUMN_START_TIME_UTC_MILLIS
+ + " INTEGER,"
+ + Programs.COLUMN_END_TIME_UTC_MILLIS
+ + " INTEGER,"
+ + Programs.COLUMN_BROADCAST_GENRE
+ + " TEXT,"
+ + Programs.COLUMN_CANONICAL_GENRE
+ + " TEXT,"
+ + Programs.COLUMN_SHORT_DESCRIPTION
+ + " TEXT,"
+ + Programs.COLUMN_LONG_DESCRIPTION
+ + " TEXT,"
+ + Programs.COLUMN_VIDEO_WIDTH
+ + " INTEGER,"
+ + Programs.COLUMN_VIDEO_HEIGHT
+ + " INTEGER,"
+ + Programs.COLUMN_AUDIO_LANGUAGE
+ + " TEXT,"
+ + Programs.COLUMN_CONTENT_RATING
+ + " TEXT,"
+ + Programs.COLUMN_POSTER_ART_URI
+ + " TEXT,"
+ + Programs.COLUMN_THUMBNAIL_URI
+ + " TEXT,"
+ + Programs.COLUMN_SEARCHABLE
+ + " INTEGER NOT NULL DEFAULT 1,"
+ + Programs.COLUMN_RECORDING_PROHIBITED
+ + " INTEGER NOT NULL DEFAULT 0,"
+ + Programs.COLUMN_INTERNAL_PROVIDER_DATA
+ + " BLOB,"
+ + Programs.COLUMN_INTERNAL_PROVIDER_FLAG1
+ + " INTEGER,"
+ + Programs.COLUMN_INTERNAL_PROVIDER_FLAG2
+ + " INTEGER,"
+ + Programs.COLUMN_INTERNAL_PROVIDER_FLAG3
+ + " INTEGER,"
+ + Programs.COLUMN_INTERNAL_PROVIDER_FLAG4
+ + " INTEGER,"
+ + Programs.COLUMN_REVIEW_RATING_STYLE
+ + " INTEGER,"
+ + Programs.COLUMN_REVIEW_RATING
+ + " TEXT,"
+ + Programs.COLUMN_VERSION_NUMBER
+ + " INTEGER,"
+ + "FOREIGN KEY("
+ + Programs.COLUMN_CHANNEL_ID
+ + ","
+ + Programs.COLUMN_PACKAGE_NAME
+ + ") REFERENCES "
+ + CHANNELS_TABLE
+ + "("
+ + Channels._ID
+ + ","
+ + Channels.COLUMN_PACKAGE_NAME
+ + ") ON UPDATE CASCADE ON DELETE CASCADE"
+ + ");");
+ db.execSQL(
+ "CREATE INDEX "
+ + PROGRAMS_TABLE_PACKAGE_NAME_INDEX
+ + " ON "
+ + PROGRAMS_TABLE
+ + "("
+ + Programs.COLUMN_PACKAGE_NAME
+ + ");");
+ db.execSQL(
+ "CREATE INDEX "
+ + PROGRAMS_TABLE_CHANNEL_ID_INDEX
+ + " ON "
+ + PROGRAMS_TABLE
+ + "("
+ + Programs.COLUMN_CHANNEL_ID
+ + ");");
+ db.execSQL(
+ "CREATE INDEX "
+ + PROGRAMS_TABLE_START_TIME_INDEX
+ + " ON "
+ + PROGRAMS_TABLE
+ + "("
+ + Programs.COLUMN_START_TIME_UTC_MILLIS
+ + ");");
+ db.execSQL(
+ "CREATE INDEX "
+ + PROGRAMS_TABLE_END_TIME_INDEX
+ + " ON "
+ + PROGRAMS_TABLE
+ + "("
+ + Programs.COLUMN_END_TIME_UTC_MILLIS
+ + ");");
+ db.execSQL(
+ "CREATE TABLE "
+ + WATCHED_PROGRAMS_TABLE
+ + " ("
+ + WatchedPrograms._ID
+ + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ + WatchedPrograms.COLUMN_PACKAGE_NAME
+ + " TEXT NOT NULL,"
+ + WatchedPrograms.COLUMN_WATCH_START_TIME_UTC_MILLIS
+ + " INTEGER NOT NULL DEFAULT 0,"
+ + WatchedPrograms.COLUMN_WATCH_END_TIME_UTC_MILLIS
+ + " INTEGER NOT NULL DEFAULT 0,"
+ + WatchedPrograms.COLUMN_CHANNEL_ID
+ + " INTEGER,"
+ + WatchedPrograms.COLUMN_TITLE
+ + " TEXT,"
+ + WatchedPrograms.COLUMN_START_TIME_UTC_MILLIS
+ + " INTEGER,"
+ + WatchedPrograms.COLUMN_END_TIME_UTC_MILLIS
+ + " INTEGER,"
+ + WatchedPrograms.COLUMN_DESCRIPTION
+ + " TEXT,"
+ + WatchedPrograms.COLUMN_INTERNAL_TUNE_PARAMS
+ + " TEXT,"
+ + WatchedPrograms.COLUMN_INTERNAL_SESSION_TOKEN
+ + " TEXT NOT NULL,"
+ + WATCHED_PROGRAMS_COLUMN_CONSOLIDATED
+ + " INTEGER NOT NULL DEFAULT 0,"
+ + "FOREIGN KEY("
+ + WatchedPrograms.COLUMN_CHANNEL_ID
+ + ","
+ + WatchedPrograms.COLUMN_PACKAGE_NAME
+ + ") REFERENCES "
+ + CHANNELS_TABLE
+ + "("
+ + Channels._ID
+ + ","
+ + Channels.COLUMN_PACKAGE_NAME
+ + ") ON UPDATE CASCADE ON DELETE CASCADE"
+ + ");");
+ db.execSQL(
+ "CREATE INDEX "
+ + WATCHED_PROGRAMS_TABLE_CHANNEL_ID_INDEX
+ + " ON "
+ + WATCHED_PROGRAMS_TABLE
+ + "("
+ + WatchedPrograms.COLUMN_CHANNEL_ID
+ + ");");
+ db.execSQL(CREATE_RECORDED_PROGRAMS_TABLE_SQL);
+ db.execSQL(CREATE_PREVIEW_PROGRAMS_TABLE_SQL);
+ db.execSQL(CREATE_PREVIEW_PROGRAMS_PACKAGE_NAME_INDEX_SQL);
+ db.execSQL(CREATE_PREVIEW_PROGRAMS_CHANNEL_ID_INDEX_SQL);
+ db.execSQL(CREATE_WATCH_NEXT_PROGRAMS_TABLE_SQL);
+ db.execSQL(CREATE_WATCH_NEXT_PROGRAMS_PACKAGE_NAME_INDEX_SQL);
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ if (oldVersion < 23) {
+ Log.i(
+ TAG,
+ "Upgrading from version "
+ + oldVersion
+ + " to "
+ + newVersion
+ + ", data will be lost!");
+ db.execSQL("DROP TABLE IF EXISTS " + DELETED_CHANNELS_TABLE);
+ db.execSQL("DROP TABLE IF EXISTS " + WATCHED_PROGRAMS_TABLE);
+ db.execSQL("DROP TABLE IF EXISTS " + PROGRAMS_TABLE);
+ db.execSQL("DROP TABLE IF EXISTS " + CHANNELS_TABLE);
+
+ onCreate(db);
+ return;
+ }
+
+ Log.i(TAG, "Upgrading from version " + oldVersion + " to " + newVersion + ".");
+ if (oldVersion <= 23) {
+ db.execSQL(
+ "ALTER TABLE "
+ + CHANNELS_TABLE
+ + " ADD "
+ + Channels.COLUMN_INTERNAL_PROVIDER_FLAG1
+ + " INTEGER;");
+ db.execSQL(
+ "ALTER TABLE "
+ + CHANNELS_TABLE
+ + " ADD "
+ + Channels.COLUMN_INTERNAL_PROVIDER_FLAG2
+ + " INTEGER;");
+ db.execSQL(
+ "ALTER TABLE "
+ + CHANNELS_TABLE
+ + " ADD "
+ + Channels.COLUMN_INTERNAL_PROVIDER_FLAG3
+ + " INTEGER;");
+ db.execSQL(
+ "ALTER TABLE "
+ + CHANNELS_TABLE
+ + " ADD "
+ + Channels.COLUMN_INTERNAL_PROVIDER_FLAG4
+ + " INTEGER;");
+ }
+ if (oldVersion <= 24) {
+ db.execSQL(
+ "ALTER TABLE "
+ + PROGRAMS_TABLE
+ + " ADD "
+ + Programs.COLUMN_INTERNAL_PROVIDER_FLAG1
+ + " INTEGER;");
+ db.execSQL(
+ "ALTER TABLE "
+ + PROGRAMS_TABLE
+ + " ADD "
+ + Programs.COLUMN_INTERNAL_PROVIDER_FLAG2
+ + " INTEGER;");
+ db.execSQL(
+ "ALTER TABLE "
+ + PROGRAMS_TABLE
+ + " ADD "
+ + Programs.COLUMN_INTERNAL_PROVIDER_FLAG3
+ + " INTEGER;");
+ db.execSQL(
+ "ALTER TABLE "
+ + PROGRAMS_TABLE
+ + " ADD "
+ + Programs.COLUMN_INTERNAL_PROVIDER_FLAG4
+ + " INTEGER;");
+ }
+ if (oldVersion <= 25) {
+ db.execSQL(
+ "ALTER TABLE "
+ + CHANNELS_TABLE
+ + " ADD "
+ + Channels.COLUMN_APP_LINK_ICON_URI
+ + " TEXT;");
+ db.execSQL(
+ "ALTER TABLE "
+ + CHANNELS_TABLE
+ + " ADD "
+ + Channels.COLUMN_APP_LINK_POSTER_ART_URI
+ + " TEXT;");
+ db.execSQL(
+ "ALTER TABLE "
+ + CHANNELS_TABLE
+ + " ADD "
+ + Channels.COLUMN_APP_LINK_TEXT
+ + " TEXT;");
+ db.execSQL(
+ "ALTER TABLE "
+ + CHANNELS_TABLE
+ + " ADD "
+ + Channels.COLUMN_APP_LINK_COLOR
+ + " INTEGER;");
+ db.execSQL(
+ "ALTER TABLE "
+ + CHANNELS_TABLE
+ + " ADD "
+ + Channels.COLUMN_APP_LINK_INTENT_URI
+ + " TEXT;");
+ db.execSQL(
+ "ALTER TABLE "
+ + PROGRAMS_TABLE
+ + " ADD "
+ + Programs.COLUMN_SEARCHABLE
+ + " INTEGER NOT NULL DEFAULT 1;");
+ }
+ if (oldVersion <= 28) {
+ db.execSQL(
+ "ALTER TABLE "
+ + PROGRAMS_TABLE
+ + " ADD "
+ + Programs.COLUMN_SEASON_TITLE
+ + " TEXT;");
+ migrateIntegerColumnToTextColumn(
+ db,
+ PROGRAMS_TABLE,
+ Programs.COLUMN_SEASON_NUMBER,
+ Programs.COLUMN_SEASON_DISPLAY_NUMBER);
+ migrateIntegerColumnToTextColumn(
+ db,
+ PROGRAMS_TABLE,
+ Programs.COLUMN_EPISODE_NUMBER,
+ Programs.COLUMN_EPISODE_DISPLAY_NUMBER);
+ }
+ if (oldVersion <= 29) {
+ db.execSQL("DROP TABLE IF EXISTS " + RECORDED_PROGRAMS_TABLE);
+ db.execSQL(CREATE_RECORDED_PROGRAMS_TABLE_SQL);
+ }
+ if (oldVersion <= 30) {
+ db.execSQL(
+ "ALTER TABLE "
+ + PROGRAMS_TABLE
+ + " ADD "
+ + Programs.COLUMN_RECORDING_PROHIBITED
+ + " INTEGER NOT NULL DEFAULT 0;");
+ }
+ if (oldVersion <= 32) {
+ db.execSQL(
+ "ALTER TABLE "
+ + CHANNELS_TABLE
+ + " ADD "
+ + Channels.COLUMN_TRANSIENT
+ + " INTEGER NOT NULL DEFAULT 0;");
+ db.execSQL(
+ "ALTER TABLE "
+ + CHANNELS_TABLE
+ + " ADD "
+ + Channels.COLUMN_INTERNAL_PROVIDER_ID
+ + " TEXT;");
+ db.execSQL(
+ "ALTER TABLE "
+ + PROGRAMS_TABLE
+ + " ADD "
+ + Programs.COLUMN_REVIEW_RATING_STYLE
+ + " INTEGER;");
+ db.execSQL(
+ "ALTER TABLE "
+ + PROGRAMS_TABLE
+ + " ADD "
+ + Programs.COLUMN_REVIEW_RATING
+ + " TEXT;");
+ if (oldVersion > 29) {
+ db.execSQL(
+ "ALTER TABLE "
+ + RECORDED_PROGRAMS_TABLE
+ + " ADD "
+ + RecordedPrograms.COLUMN_REVIEW_RATING_STYLE
+ + " INTEGER;");
+ db.execSQL(
+ "ALTER TABLE "
+ + RECORDED_PROGRAMS_TABLE
+ + " ADD "
+ + RecordedPrograms.COLUMN_REVIEW_RATING
+ + " TEXT;");
+ }
+ }
+ if (oldVersion <= 33) {
+ db.execSQL("DROP TABLE IF EXISTS " + PREVIEW_PROGRAMS_TABLE);
+ db.execSQL("DROP TABLE IF EXISTS " + WATCH_NEXT_PROGRAMS_TABLE);
+ db.execSQL(CREATE_PREVIEW_PROGRAMS_TABLE_SQL);
+ db.execSQL(CREATE_PREVIEW_PROGRAMS_PACKAGE_NAME_INDEX_SQL);
+ db.execSQL(CREATE_PREVIEW_PROGRAMS_CHANNEL_ID_INDEX_SQL);
+ db.execSQL(CREATE_WATCH_NEXT_PROGRAMS_TABLE_SQL);
+ db.execSQL(CREATE_WATCH_NEXT_PROGRAMS_PACKAGE_NAME_INDEX_SQL);
+ }
+ Log.i(TAG, "Upgrading from version " + oldVersion + " to " + newVersion + " is done.");
+ }
+
+ @Override
+ public void onOpen(SQLiteDatabase db) {
+ // Call a static method on the TvProvider because changes to sInitialized must
+ // be guarded by a lock on the class.
+ initOnOpenIfNeeded(mContext, db);
+ }
+
+ private static void migrateIntegerColumnToTextColumn(
+ SQLiteDatabase db, String table, String integerColumn, String textColumn) {
+ db.execSQL("ALTER TABLE " + table + " ADD " + textColumn + " TEXT;");
+ db.execSQL(
+ "UPDATE "
+ + table
+ + " SET "
+ + textColumn
+ + " = CAST("
+ + integerColumn
+ + " AS TEXT);");
+ }
+ }
+
+ private DatabaseHelper mOpenHelper;
+ private static SharedPreferences sBlockedPackagesSharedPreference;
+ private static Map<String, Boolean> sBlockedPackages;
+
+ @Override
+ public boolean onCreate() {
+ if (DEBUG) {
+ Log.d(TAG, "Creating TvProvider");
+ }
+ mOpenHelper = DatabaseHelper.createInstance(getContext());
+ return true;
+ }
+
+ @VisibleForTesting
+ String getCallingPackage_() {
+ return mCallingPackage;
+ }
+
+ public void setCallingPackage(String packageName) {
+ mCallingPackage = packageName;
+ }
+
+ void setOpenHelper(DatabaseHelper helper) {
+ mOpenHelper = helper;
+ }
+
+ @Override
+ public String getType(Uri uri) {
+ switch (sUriMatcher.match(uri)) {
+ case MATCH_CHANNEL:
+ return Channels.CONTENT_TYPE;
+ case MATCH_CHANNEL_ID:
+ return Channels.CONTENT_ITEM_TYPE;
+ case MATCH_CHANNEL_ID_LOGO:
+ return "image/png";
+ case MATCH_PASSTHROUGH_ID:
+ return Channels.CONTENT_ITEM_TYPE;
+ case MATCH_PROGRAM:
+ return Programs.CONTENT_TYPE;
+ case MATCH_PROGRAM_ID:
+ return Programs.CONTENT_ITEM_TYPE;
+ case MATCH_WATCHED_PROGRAM:
+ return WatchedPrograms.CONTENT_TYPE;
+ case MATCH_WATCHED_PROGRAM_ID:
+ return WatchedPrograms.CONTENT_ITEM_TYPE;
+ case MATCH_RECORDED_PROGRAM:
+ return RecordedPrograms.CONTENT_TYPE;
+ case MATCH_RECORDED_PROGRAM_ID:
+ return RecordedPrograms.CONTENT_ITEM_TYPE;
+ case MATCH_PREVIEW_PROGRAM:
+ return PreviewPrograms.CONTENT_TYPE;
+ case MATCH_PREVIEW_PROGRAM_ID:
+ return PreviewPrograms.CONTENT_ITEM_TYPE;
+ case MATCH_WATCH_NEXT_PROGRAM:
+ return WatchNextPrograms.CONTENT_TYPE;
+ case MATCH_WATCH_NEXT_PROGRAM_ID:
+ return WatchNextPrograms.CONTENT_ITEM_TYPE;
+ default:
+ throw new IllegalArgumentException("Unknown URI " + uri);
+ }
+ }
+
+ @Override
+ public Bundle call(String method, String arg, Bundle extras) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Cursor query(
+ Uri uri,
+ String[] projection,
+ String selection,
+ String[] selectionArgs,
+ String sortOrder) {
+ ensureInitialized();
+ boolean needsToValidateSortOrder = !callerHasAccessAllEpgDataPermission();
+ SqlParams params = createSqlParams(OP_QUERY, uri, selection, selectionArgs);
+
+ SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
+ queryBuilder.setStrict(needsToValidateSortOrder);
+ queryBuilder.setTables(params.getTables());
+ String orderBy = null;
+ Map<String, String> projectionMap;
+ switch (params.getTables()) {
+ case PROGRAMS_TABLE:
+ projectionMap = sProgramProjectionMap;
+ orderBy = DEFAULT_PROGRAMS_SORT_ORDER;
+ break;
+ case WATCHED_PROGRAMS_TABLE:
+ projectionMap = sWatchedProgramProjectionMap;
+ orderBy = DEFAULT_WATCHED_PROGRAMS_SORT_ORDER;
+ break;
+ case RECORDED_PROGRAMS_TABLE:
+ projectionMap = sRecordedProgramProjectionMap;
+ break;
+ case PREVIEW_PROGRAMS_TABLE:
+ projectionMap = sPreviewProgramProjectionMap;
+ break;
+ case WATCH_NEXT_PROGRAMS_TABLE:
+ projectionMap = sWatchNextProgramProjectionMap;
+ break;
+ default:
+ projectionMap = sChannelProjectionMap;
+ break;
+ }
+ queryBuilder.setProjectionMap(createProjectionMapForQuery(projection, projectionMap));
+ if (needsToValidateSortOrder) {
+ validateSortOrder(sortOrder, projectionMap.keySet());
+ }
+
+ // Use the default sort order only if no sort order is specified.
+ if (!TextUtils.isEmpty(sortOrder)) {
+ orderBy = sortOrder;
+ }
+
+ // Get the database and run the query.
+ SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+ Cursor c =
+ queryBuilder.query(
+ db,
+ projection,
+ params.getSelection(),
+ params.getSelectionArgs(),
+ null,
+ null,
+ orderBy);
+
+ // Tell the cursor what URI to watch, so it knows when its source data changes.
+ c.setNotificationUri(getContext().getContentResolver(), uri);
+ return c;
+ }
+
+ @Override
+ public Uri insert(Uri uri, ContentValues values) {
+ ensureInitialized();
+ switch (sUriMatcher.match(uri)) {
+ case MATCH_CHANNEL:
+ // Preview channels are not necessarily associated with TV input service.
+ // Therefore, we fill a fake ID to meet not null restriction for preview channels.
+ if (values.get(Channels.COLUMN_INPUT_ID) == null
+ && TvContractCompat.PARAM_CHANNEL.equals(
+ values.get(Channels.COLUMN_TYPE))) {
+ values.put(Channels.COLUMN_INPUT_ID, EMPTY_STRING);
+ }
+ filterContentValues(values, sChannelProjectionMap);
+ return insertChannel(uri, values);
+ case MATCH_PROGRAM:
+ filterContentValues(values, sProgramProjectionMap);
+ return insertProgram(uri, values);
+ case MATCH_WATCHED_PROGRAM:
+ return insertWatchedProgram(uri, values);
+ case MATCH_RECORDED_PROGRAM:
+ filterContentValues(values, sRecordedProgramProjectionMap);
+ return insertRecordedProgram(uri, values);
+ case MATCH_PREVIEW_PROGRAM:
+ filterContentValues(values, sPreviewProgramProjectionMap);
+ return insertPreviewProgram(uri, values);
+ case MATCH_WATCH_NEXT_PROGRAM:
+ filterContentValues(values, sWatchNextProgramProjectionMap);
+ return insertWatchNextProgram(uri, values);
+ case MATCH_CHANNEL_ID:
+ case MATCH_CHANNEL_ID_LOGO:
+ case MATCH_PASSTHROUGH_ID:
+ case MATCH_PROGRAM_ID:
+ case MATCH_WATCHED_PROGRAM_ID:
+ case MATCH_RECORDED_PROGRAM_ID:
+ case MATCH_PREVIEW_PROGRAM_ID:
+ throw new UnsupportedOperationException("Cannot insert into that URI: " + uri);
+ default:
+ throw new IllegalArgumentException("Unknown URI " + uri);
+ }
+ }
+
+ private Uri insertChannel(Uri uri, ContentValues values) {
+ if (TextUtils.equals(
+ values.getAsString(Channels.COLUMN_TYPE), TvContractCompat.Channels.TYPE_PREVIEW)) {
+ blockIllegalAccessFromBlockedPackage();
+ }
+ // Mark the owner package of this channel.
+ values.put(Channels.COLUMN_PACKAGE_NAME, getCallingPackage_());
+ blockIllegalAccessToChannelsSystemColumns(values);
+
+ SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+ long rowId = db.insert(CHANNELS_TABLE, null, values);
+ if (rowId > 0) {
+ Uri channelUri = TvContractCompat.buildChannelUri(rowId);
+ notifyChange(channelUri);
+ return channelUri;
+ }
+
+ throw new SQLException("Failed to insert row into " + uri);
+ }
+
+ private Uri insertProgram(Uri uri, ContentValues values) {
+ if (!callerHasAccessAllEpgDataPermission()
+ || !values.containsKey(Programs.COLUMN_PACKAGE_NAME)) {
+ // Mark the owner package of this program. System app with a proper permission may
+ // change the owner of the program.
+ values.put(Programs.COLUMN_PACKAGE_NAME, getCallingPackage_());
+ }
+
+ checkAndConvertGenre(values);
+ checkAndConvertDeprecatedColumns(values);
+
+ SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+ long rowId = db.insert(PROGRAMS_TABLE, null, values);
+ if (rowId > 0) {
+ Uri programUri = TvContractCompat.buildProgramUri(rowId);
+ notifyChange(programUri);
+ return programUri;
+ }
+
+ throw new SQLException("Failed to insert row into " + uri);
+ }
+
+ private Uri insertWatchedProgram(Uri uri, ContentValues values) {
+ if (DEBUG) {
+ Log.d(TAG, "insertWatchedProgram(uri=" + uri + ", values={" + values + "})");
+ }
+ Long watchStartTime = values.getAsLong(WatchedPrograms.COLUMN_WATCH_START_TIME_UTC_MILLIS);
+ Long watchEndTime = values.getAsLong(WatchedPrograms.COLUMN_WATCH_END_TIME_UTC_MILLIS);
+ // The system sends only two kinds of watch events:
+ // 1. The user tunes to a new channel. (COLUMN_WATCH_START_TIME_UTC_MILLIS)
+ // 2. The user stops watching. (COLUMN_WATCH_END_TIME_UTC_MILLIS)
+ if (watchStartTime != null && watchEndTime == null) {
+ SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+ long rowId = db.insert(WATCHED_PROGRAMS_TABLE, null, values);
+ if (rowId > 0) {
+ return ContentUris.withAppendedId(WatchedPrograms.CONTENT_URI, rowId);
+ }
+ Log.w(TAG, "Failed to insert row for " + values + ". Channel does not exist.");
+ return null;
+ } else if (watchStartTime == null && watchEndTime != null) {
+ return null;
+ }
+ // All the other cases are invalid.
+ throw new IllegalArgumentException(
+ "Only one of COLUMN_WATCH_START_TIME_UTC_MILLIS and"
+ + " COLUMN_WATCH_END_TIME_UTC_MILLIS should be specified");
+ }
+
+ private Uri insertRecordedProgram(Uri uri, ContentValues values) {
+ // Mark the owner package of this program.
+ values.put(Programs.COLUMN_PACKAGE_NAME, getCallingPackage_());
+
+ checkAndConvertGenre(values);
+
+ SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+ long rowId = db.insert(RECORDED_PROGRAMS_TABLE, null, values);
+ if (rowId > 0) {
+ Uri recordedProgramUri = TvContractCompat.buildRecordedProgramUri(rowId);
+ notifyChange(recordedProgramUri);
+ return recordedProgramUri;
+ }
+
+ throw new SQLException("Failed to insert row into " + uri);
+ }
+
+ private Uri insertPreviewProgram(Uri uri, ContentValues values) {
+ if (!values.containsKey(PreviewPrograms.COLUMN_TYPE)) {
+ throw new IllegalArgumentException(
+ "Missing the required column: " + PreviewPrograms.COLUMN_TYPE);
+ }
+ blockIllegalAccessFromBlockedPackage();
+ // Mark the owner package of this program.
+ values.put(Programs.COLUMN_PACKAGE_NAME, getCallingPackage_());
+ blockIllegalAccessToPreviewProgramsSystemColumns(values);
+
+ SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+ long rowId = db.insert(PREVIEW_PROGRAMS_TABLE, null, values);
+ if (rowId > 0) {
+ Uri previewProgramUri = TvContractCompat.buildPreviewProgramUri(rowId);
+ notifyChange(previewProgramUri);
+ return previewProgramUri;
+ }
+
+ throw new SQLException("Failed to insert row into " + uri);
+ }
+
+ private Uri insertWatchNextProgram(Uri uri, ContentValues values) {
+ if (!values.containsKey(WatchNextPrograms.COLUMN_TYPE)) {
+ throw new IllegalArgumentException(
+ "Missing the required column: " + WatchNextPrograms.COLUMN_TYPE);
+ }
+ blockIllegalAccessFromBlockedPackage();
+ if (!callerHasAccessAllEpgDataPermission()
+ || !values.containsKey(Programs.COLUMN_PACKAGE_NAME)) {
+ // Mark the owner package of this program. System app with a proper permission may
+ // change the owner of the program.
+ values.put(Programs.COLUMN_PACKAGE_NAME, getCallingPackage_());
+ }
+ blockIllegalAccessToPreviewProgramsSystemColumns(values);
+
+ SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+ long rowId = db.insert(WATCH_NEXT_PROGRAMS_TABLE, null, values);
+ if (rowId > 0) {
+ Uri watchNextProgramUri = TvContractCompat.buildWatchNextProgramUri(rowId);
+ notifyChange(watchNextProgramUri);
+ return watchNextProgramUri;
+ }
+
+ throw new SQLException("Failed to insert row into " + uri);
+ }
+
+ @Override
+ public int delete(Uri uri, String selection, String[] selectionArgs) {
+ SqlParams params = createSqlParams(OP_DELETE, uri, selection, selectionArgs);
+ SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+ int count;
+ switch (sUriMatcher.match(uri)) {
+ case MATCH_CHANNEL_ID_LOGO:
+ ContentValues values = new ContentValues();
+ values.putNull(CHANNELS_COLUMN_LOGO);
+ count =
+ db.update(
+ params.getTables(),
+ values,
+ params.getSelection(),
+ params.getSelectionArgs());
+ break;
+ case MATCH_CHANNEL:
+ case MATCH_PROGRAM:
+ case MATCH_WATCHED_PROGRAM:
+ case MATCH_RECORDED_PROGRAM:
+ case MATCH_PREVIEW_PROGRAM:
+ case MATCH_WATCH_NEXT_PROGRAM:
+ case MATCH_CHANNEL_ID:
+ case MATCH_PASSTHROUGH_ID:
+ case MATCH_PROGRAM_ID:
+ case MATCH_WATCHED_PROGRAM_ID:
+ case MATCH_RECORDED_PROGRAM_ID:
+ case MATCH_PREVIEW_PROGRAM_ID:
+ case MATCH_WATCH_NEXT_PROGRAM_ID:
+ count =
+ db.delete(
+ params.getTables(),
+ params.getSelection(),
+ params.getSelectionArgs());
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown URI " + uri);
+ }
+ if (count > 0) {
+ notifyChange(uri);
+ }
+ return count;
+ }
+
+ @Override
+ public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+ SqlParams params = createSqlParams(OP_UPDATE, uri, selection, selectionArgs);
+ blockIllegalAccessToIdAndPackageName(uri, values);
+ boolean containImmutableColumn = false;
+ if (params.getTables().equals(CHANNELS_TABLE)) {
+ filterContentValues(values, sChannelProjectionMap);
+ containImmutableColumn = disallowModifyChannelType(values, params);
+ if (containImmutableColumn && sUriMatcher.match(uri) != MATCH_CHANNEL_ID) {
+ Log.i(TAG, "Updating failed. Attempt to change immutable column for channels.");
+ return 0;
+ }
+ blockIllegalAccessToChannelsSystemColumns(values);
+ } else if (params.getTables().equals(PROGRAMS_TABLE)) {
+ filterContentValues(values, sProgramProjectionMap);
+ checkAndConvertGenre(values);
+ checkAndConvertDeprecatedColumns(values);
+ } else if (params.getTables().equals(RECORDED_PROGRAMS_TABLE)) {
+ filterContentValues(values, sRecordedProgramProjectionMap);
+ checkAndConvertGenre(values);
+ } else if (params.getTables().equals(PREVIEW_PROGRAMS_TABLE)) {
+ filterContentValues(values, sPreviewProgramProjectionMap);
+ containImmutableColumn = disallowModifyChannelId(values, params);
+ if (containImmutableColumn && PreviewPrograms.CONTENT_URI.equals(uri)) {
+ Log.i(
+ TAG,
+ "Updating failed. Attempt to change unmodifiable column for "
+ + "preview programs.");
+ return 0;
+ }
+ blockIllegalAccessToPreviewProgramsSystemColumns(values);
+ } else if (params.getTables().equals(WATCH_NEXT_PROGRAMS_TABLE)) {
+ filterContentValues(values, sWatchNextProgramProjectionMap);
+ blockIllegalAccessToPreviewProgramsSystemColumns(values);
+ }
+ if (values.size() == 0) {
+ // All values may be filtered out, no need to update
+ return 0;
+ }
+ SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+ int count =
+ db.update(
+ params.getTables(),
+ values,
+ params.getSelection(),
+ params.getSelectionArgs());
+ if (count > 0) {
+ notifyChange(uri);
+ } else if (containImmutableColumn) {
+ Log.i(
+ TAG,
+ "Updating failed. The item may not exist or attempt to change "
+ + "immutable column.");
+ }
+ return count;
+ }
+
+ private synchronized void ensureInitialized() {
+ if (!sInitialized) {
+ // Database is not accessed before and the projection maps and the blocked package list
+ // are not updated yet. Gets database here to make it initialized.
+ mOpenHelper.getReadableDatabase();
+ }
+ }
+
+ private static synchronized void initOnOpenIfNeeded(Context context, SQLiteDatabase db) {
+ if (!sInitialized) {
+ updateProjectionMap(db, CHANNELS_TABLE, sChannelProjectionMap);
+ updateProjectionMap(db, PROGRAMS_TABLE, sProgramProjectionMap);
+ updateProjectionMap(db, WATCHED_PROGRAMS_TABLE, sWatchedProgramProjectionMap);
+ updateProjectionMap(db, RECORDED_PROGRAMS_TABLE, sRecordedProgramProjectionMap);
+ updateProjectionMap(db, PREVIEW_PROGRAMS_TABLE, sPreviewProgramProjectionMap);
+ updateProjectionMap(db, WATCH_NEXT_PROGRAMS_TABLE, sWatchNextProgramProjectionMap);
+ sBlockedPackagesSharedPreference =
+ PreferenceManager.getDefaultSharedPreferences(context);
+ sBlockedPackages = new ConcurrentHashMap<>();
+ for (String packageName :
+ sBlockedPackagesSharedPreference.getStringSet(
+ SHARED_PREF_BLOCKED_PACKAGES_KEY, new HashSet<>())) {
+ sBlockedPackages.put(packageName, true);
+ }
+ sInitialized = true;
+ }
+ }
+
+ private static void updateProjectionMap(
+ SQLiteDatabase db, String tableName, Map<String, String> projectionMap) {
+ try (Cursor cursor = db.rawQuery("SELECT * FROM " + tableName + " LIMIT 0", null)) {
+ for (String columnName : cursor.getColumnNames()) {
+ if (!projectionMap.containsKey(columnName)) {
+ projectionMap.put(columnName, tableName + '.' + columnName);
+ }
+ }
+ }
+ }
+
+ private Map<String, String> createProjectionMapForQuery(
+ String[] projection, Map<String, String> projectionMap) {
+ if (projection == null) {
+ return projectionMap;
+ }
+ Map<String, String> columnProjectionMap = new HashMap<>();
+ for (String columnName : projection) {
+ // Value NULL will be provided if the requested column does not exist in the database.
+ columnProjectionMap.put(
+ columnName, projectionMap.getOrDefault(columnName, "NULL as " + columnName));
+ }
+ return columnProjectionMap;
+ }
+
+ private void filterContentValues(ContentValues values, Map<String, String> projectionMap) {
+ Iterator<String> iter = values.keySet().iterator();
+ while (iter.hasNext()) {
+ String columnName = iter.next();
+ if (!projectionMap.containsKey(columnName)) {
+ iter.remove();
+ }
+ }
+ }
+
+ private SqlParams createSqlParams(
+ String operation, Uri uri, String selection, String[] selectionArgs) {
+ int match = sUriMatcher.match(uri);
+ SqlParams params = new SqlParams(null, selection, selectionArgs);
+
+ // Control access to EPG data (excluding watched programs) when the caller doesn't have all
+ // access.
+ String prefix = match == MATCH_CHANNEL ? CHANNELS_TABLE + "." : "";
+ if (!callerHasAccessAllEpgDataPermission()
+ && match != MATCH_WATCHED_PROGRAM
+ && match != MATCH_WATCHED_PROGRAM_ID) {
+ if (!TextUtils.isEmpty(selection)) {
+ throw new SecurityException("Selection not allowed for " + uri);
+ }
+ // Limit the operation only to the data that the calling package owns except for when
+ // the caller tries to read TV listings and has the appropriate permission.
+ if (operation.equals(OP_QUERY) && callerHasReadTvListingsPermission()) {
+ params.setWhere(
+ prefix
+ + BaseTvColumns.COLUMN_PACKAGE_NAME
+ + "=? OR "
+ + Channels.COLUMN_SEARCHABLE
+ + "=?",
+ getCallingPackage_(),
+ "1");
+ } else {
+ params.setWhere(
+ prefix + BaseTvColumns.COLUMN_PACKAGE_NAME + "=?", getCallingPackage_());
+ }
+ }
+ String packageName = uri.getQueryParameter(PARAM_PACKAGE);
+ if (packageName != null) {
+ params.appendWhere(prefix + BaseTvColumns.COLUMN_PACKAGE_NAME + "=?", packageName);
+ }
+
+ switch (match) {
+ case MATCH_CHANNEL:
+ String genre = uri.getQueryParameter(TvContractCompat.PARAM_CANONICAL_GENRE);
+ if (genre == null) {
+ params.setTables(CHANNELS_TABLE);
+ } else {
+ if (!operation.equals(OP_QUERY)) {
+ throw new SecurityException(
+ capitalize(operation) + " not allowed for " + uri);
+ }
+ if (!Genres.isCanonical(genre)) {
+ throw new IllegalArgumentException("Not a canonical genre : " + genre);
+ }
+ params.setTables(CHANNELS_TABLE_INNER_JOIN_PROGRAMS_TABLE);
+ String curTime = String.valueOf(System.currentTimeMillis());
+ params.appendWhere(
+ "LIKE(?, "
+ + Programs.COLUMN_CANONICAL_GENRE
+ + ") AND "
+ + Programs.COLUMN_START_TIME_UTC_MILLIS
+ + "<=? AND "
+ + Programs.COLUMN_END_TIME_UTC_MILLIS
+ + ">=?",
+ "%" + genre + "%",
+ curTime,
+ curTime);
+ }
+ String inputId = uri.getQueryParameter(TvContractCompat.PARAM_INPUT);
+ if (inputId != null) {
+ params.appendWhere(Channels.COLUMN_INPUT_ID + "=?", inputId);
+ }
+ boolean browsableOnly =
+ uri.getBooleanQueryParameter(TvContractCompat.PARAM_BROWSABLE_ONLY, false);
+ if (browsableOnly) {
+ params.appendWhere(Channels.COLUMN_BROWSABLE + "=1");
+ }
+ String preview = uri.getQueryParameter(PARAM_PREVIEW);
+ if (preview != null) {
+ String previewSelection =
+ Channels.COLUMN_TYPE
+ + (preview.equals(String.valueOf(true)) ? "=?" : "!=?");
+ params.appendWhere(previewSelection, Channels.TYPE_PREVIEW);
+ }
+ break;
+ case MATCH_CHANNEL_ID:
+ params.setTables(CHANNELS_TABLE);
+ params.appendWhere(Channels._ID + "=?", uri.getLastPathSegment());
+ break;
+ case MATCH_PROGRAM:
+ params.setTables(PROGRAMS_TABLE);
+ String paramChannelId = uri.getQueryParameter(TvContractCompat.PARAM_CHANNEL);
+ if (paramChannelId != null) {
+ String channelId = String.valueOf(Long.parseLong(paramChannelId));
+ params.appendWhere(Programs.COLUMN_CHANNEL_ID + "=?", channelId);
+ }
+ String paramStartTime = uri.getQueryParameter(TvContractCompat.PARAM_START_TIME);
+ String paramEndTime = uri.getQueryParameter(TvContractCompat.PARAM_END_TIME);
+ if (paramStartTime != null && paramEndTime != null) {
+ String startTime = String.valueOf(Long.parseLong(paramStartTime));
+ String endTime = String.valueOf(Long.parseLong(paramEndTime));
+ params.appendWhere(
+ Programs.COLUMN_START_TIME_UTC_MILLIS
+ + "<=? AND "
+ + Programs.COLUMN_END_TIME_UTC_MILLIS
+ + ">=? AND ?<=?",
+ endTime,
+ startTime,
+ startTime,
+ endTime);
+ }
+ break;
+ case MATCH_PROGRAM_ID:
+ params.setTables(PROGRAMS_TABLE);
+ params.appendWhere(Programs._ID + "=?", uri.getLastPathSegment());
+ break;
+ case MATCH_WATCHED_PROGRAM:
+ if (!callerHasAccessWatchedProgramsPermission()) {
+ throw new SecurityException("Access not allowed for " + uri);
+ }
+ params.setTables(WATCHED_PROGRAMS_TABLE);
+ params.appendWhere(WATCHED_PROGRAMS_COLUMN_CONSOLIDATED + "=?", "1");
+ break;
+ case MATCH_WATCHED_PROGRAM_ID:
+ if (!callerHasAccessWatchedProgramsPermission()) {
+ throw new SecurityException("Access not allowed for " + uri);
+ }
+ params.setTables(WATCHED_PROGRAMS_TABLE);
+ params.appendWhere(WatchedPrograms._ID + "=?", uri.getLastPathSegment());
+ params.appendWhere(WATCHED_PROGRAMS_COLUMN_CONSOLIDATED + "=?", "1");
+ break;
+ case MATCH_RECORDED_PROGRAM_ID:
+ params.appendWhere(RecordedPrograms._ID + "=?", uri.getLastPathSegment());
+ // fall-through
+ case MATCH_RECORDED_PROGRAM:
+ params.setTables(RECORDED_PROGRAMS_TABLE);
+ paramChannelId = uri.getQueryParameter(TvContractCompat.PARAM_CHANNEL);
+ if (paramChannelId != null) {
+ String channelId = String.valueOf(Long.parseLong(paramChannelId));
+ params.appendWhere(Programs.COLUMN_CHANNEL_ID + "=?", channelId);
+ }
+ break;
+ case MATCH_PREVIEW_PROGRAM_ID:
+ params.appendWhere(PreviewPrograms._ID + "=?", uri.getLastPathSegment());
+ // fall-through
+ case MATCH_PREVIEW_PROGRAM:
+ params.setTables(PREVIEW_PROGRAMS_TABLE);
+ paramChannelId = uri.getQueryParameter(TvContractCompat.PARAM_CHANNEL);
+ if (paramChannelId != null) {
+ String channelId = String.valueOf(Long.parseLong(paramChannelId));
+ params.appendWhere(PreviewPrograms.COLUMN_CHANNEL_ID + "=?", channelId);
+ }
+ break;
+ case MATCH_WATCH_NEXT_PROGRAM_ID:
+ params.appendWhere(WatchNextPrograms._ID + "=?", uri.getLastPathSegment());
+ // fall-through
+ case MATCH_WATCH_NEXT_PROGRAM:
+ params.setTables(WATCH_NEXT_PROGRAMS_TABLE);
+ break;
+ case MATCH_CHANNEL_ID_LOGO:
+ if (operation.equals(OP_DELETE)) {
+ params.setTables(CHANNELS_TABLE);
+ params.appendWhere(Channels._ID + "=?", uri.getPathSegments().get(1));
+ break;
+ }
+ // fall-through
+ case MATCH_PASSTHROUGH_ID:
+ throw new UnsupportedOperationException(operation + " not permmitted on " + uri);
+ default:
+ throw new IllegalArgumentException("Unknown URI " + uri);
+ }
+ return params;
+ }
+
+ private static String capitalize(String str) {
+ return Character.toUpperCase(str.charAt(0)) + str.substring(1);
+ }
+
+ @SuppressLint("DefaultLocale")
+ private void checkAndConvertGenre(ContentValues values) {
+ String canonicalGenres = values.getAsString(Programs.COLUMN_CANONICAL_GENRE);
+
+ if (!TextUtils.isEmpty(canonicalGenres)) {
+ // Check if the canonical genres are valid. If not, clear them.
+ String[] genres = Genres.decode(canonicalGenres);
+ for (String genre : genres) {
+ if (!Genres.isCanonical(genre)) {
+ values.putNull(Programs.COLUMN_CANONICAL_GENRE);
+ canonicalGenres = null;
+ break;
+ }
+ }
+ }
+
+ if (TextUtils.isEmpty(canonicalGenres)) {
+ // If the canonical genre is not set, try to map the broadcast genre to the canonical
+ // genre.
+ String broadcastGenres = values.getAsString(Programs.COLUMN_BROADCAST_GENRE);
+ if (!TextUtils.isEmpty(broadcastGenres)) {
+ Set<String> genreSet = new HashSet<>();
+ String[] genres = Genres.decode(broadcastGenres);
+ for (String genre : genres) {
+ String canonicalGenre = sGenreMap.get(genre.toUpperCase());
+ if (Genres.isCanonical(canonicalGenre)) {
+ genreSet.add(canonicalGenre);
+ }
+ }
+ if (genreSet.size() > 0) {
+ values.put(
+ Programs.COLUMN_CANONICAL_GENRE,
+ Genres.encode(genreSet.toArray(new String[genreSet.size()])));
+ }
+ }
+ }
+ }
+
+ private void checkAndConvertDeprecatedColumns(ContentValues values) {
+ if (values.containsKey(Programs.COLUMN_SEASON_NUMBER)) {
+ if (!values.containsKey(Programs.COLUMN_SEASON_DISPLAY_NUMBER)) {
+ values.put(
+ Programs.COLUMN_SEASON_DISPLAY_NUMBER,
+ values.getAsInteger(Programs.COLUMN_SEASON_NUMBER));
+ }
+ values.remove(Programs.COLUMN_SEASON_NUMBER);
+ }
+ if (values.containsKey(Programs.COLUMN_EPISODE_NUMBER)) {
+ if (!values.containsKey(Programs.COLUMN_EPISODE_DISPLAY_NUMBER)) {
+ values.put(
+ Programs.COLUMN_EPISODE_DISPLAY_NUMBER,
+ values.getAsInteger(Programs.COLUMN_EPISODE_NUMBER));
+ }
+ values.remove(Programs.COLUMN_EPISODE_NUMBER);
+ }
+ }
+
+ // We might have more than one thread trying to make its way through applyBatch() so the
+ // notification coalescing needs to be thread-local to work correctly.
+ private final ThreadLocal<Set<Uri>> mTLBatchNotifications = new ThreadLocal<>();
+
+ private Set<Uri> getBatchNotificationsSet() {
+ return mTLBatchNotifications.get();
+ }
+
+ private void setBatchNotificationsSet(Set<Uri> batchNotifications) {
+ mTLBatchNotifications.set(batchNotifications);
+ }
+
+ @Override
+ public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations)
+ throws OperationApplicationException {
+ setBatchNotificationsSet(new HashSet<Uri>());
+ Context context = getContext();
+ SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+ db.beginTransaction();
+ try {
+ ContentProviderResult[] results = super.applyBatch(operations);
+ db.setTransactionSuccessful();
+ return results;
+ } finally {
+ db.endTransaction();
+ final Set<Uri> notifications = getBatchNotificationsSet();
+ setBatchNotificationsSet(null);
+ for (final Uri uri : notifications) {
+ context.getContentResolver().notifyChange(uri, null);
+ }
+ }
+ }
+
+ @Override
+ public int bulkInsert(Uri uri, ContentValues[] values) {
+ setBatchNotificationsSet(new HashSet<Uri>());
+ Context context = getContext();
+ SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+ db.beginTransaction();
+ try {
+ int result = super.bulkInsert(uri, values);
+ db.setTransactionSuccessful();
+ return result;
+ } finally {
+ db.endTransaction();
+ final Set<Uri> notifications = getBatchNotificationsSet();
+ setBatchNotificationsSet(null);
+ for (final Uri notificationUri : notifications) {
+ context.getContentResolver().notifyChange(notificationUri, null);
+ }
+ }
+ }
+
+ private void notifyChange(Uri uri) {
+ final Set<Uri> batchNotifications = getBatchNotificationsSet();
+ if (batchNotifications != null) {
+ batchNotifications.add(uri);
+ } else {
+ getContext().getContentResolver().notifyChange(uri, null);
+ }
+ }
+
+ private boolean callerHasReadTvListingsPermission() {
+ return getContext().checkCallingOrSelfPermission(PERMISSION_READ_TV_LISTINGS)
+ == PackageManager.PERMISSION_GRANTED;
+ }
+
+ private boolean callerHasAccessAllEpgDataPermission() {
+ return getContext().checkCallingOrSelfPermission(PERMISSION_ACCESS_ALL_EPG_DATA)
+ == PackageManager.PERMISSION_GRANTED;
+ }
+
+ private boolean callerHasAccessWatchedProgramsPermission() {
+ return getContext().checkCallingOrSelfPermission(PERMISSION_ACCESS_WATCHED_PROGRAMS)
+ == PackageManager.PERMISSION_GRANTED;
+ }
+
+ private boolean callerHasModifyParentalControlsPermission() {
+ return getContext()
+ .checkCallingOrSelfPermission(
+ android.Manifest.permission.MODIFY_PARENTAL_CONTROLS)
+ == PackageManager.PERMISSION_GRANTED;
+ }
+
+ private void blockIllegalAccessToIdAndPackageName(Uri uri, ContentValues values) {
+ if (values.containsKey(BaseColumns._ID)) {
+ int match = sUriMatcher.match(uri);
+ switch (match) {
+ case MATCH_CHANNEL_ID:
+ case MATCH_PROGRAM_ID:
+ case MATCH_PREVIEW_PROGRAM_ID:
+ case MATCH_RECORDED_PROGRAM_ID:
+ case MATCH_WATCH_NEXT_PROGRAM_ID:
+ case MATCH_WATCHED_PROGRAM_ID:
+ if (TextUtils.equals(
+ values.getAsString(BaseColumns._ID), uri.getLastPathSegment())) {
+ break;
+ }
+ // fall through
+ default:
+ throw new IllegalArgumentException("Not allowed to change ID.");
+ }
+ }
+ if (values.containsKey(BaseTvColumns.COLUMN_PACKAGE_NAME)
+ && !callerHasAccessAllEpgDataPermission()
+ && !TextUtils.equals(
+ values.getAsString(BaseTvColumns.COLUMN_PACKAGE_NAME),
+ getCallingPackage_())) {
+ throw new SecurityException("Not allowed to change package name.");
+ }
+ }
+
+ private void blockIllegalAccessToChannelsSystemColumns(ContentValues values) {
+ if (values.containsKey(Channels.COLUMN_LOCKED)
+ && !callerHasModifyParentalControlsPermission()) {
+ throw new SecurityException("Not allowed to access Channels.COLUMN_LOCKED");
+ }
+ Boolean hasAccessAllEpgDataPermission = null;
+ if (values.containsKey(Channels.COLUMN_BROWSABLE)) {
+ hasAccessAllEpgDataPermission = callerHasAccessAllEpgDataPermission();
+ if (!hasAccessAllEpgDataPermission) {
+ throw new SecurityException("Not allowed to access Channels.COLUMN_BROWSABLE");
+ }
+ }
+ }
+
+ private void blockIllegalAccessToPreviewProgramsSystemColumns(ContentValues values) {
+ if (values.containsKey(PreviewPrograms.COLUMN_BROWSABLE)
+ && !callerHasAccessAllEpgDataPermission()) {
+ throw new SecurityException("Not allowed to access Programs.COLUMN_BROWSABLE");
+ }
+ }
+
+ private void blockIllegalAccessFromBlockedPackage() {
+ String callingPackageName = getCallingPackage_();
+ if (sBlockedPackages.containsKey(callingPackageName)) {
+ throw new SecurityException(
+ "Not allowed to access "
+ + TvContractCompat.AUTHORITY
+ + ", "
+ + callingPackageName
+ + " is blocked");
+ }
+ }
+
+ private boolean disallowModifyChannelType(ContentValues values, SqlParams params) {
+ if (values.containsKey(Channels.COLUMN_TYPE)) {
+ params.appendWhere(
+ Channels.COLUMN_TYPE + "=?", values.getAsString(Channels.COLUMN_TYPE));
+ return true;
+ }
+ return false;
+ }
+
+ private boolean disallowModifyChannelId(ContentValues values, SqlParams params) {
+ if (values.containsKey(PreviewPrograms.COLUMN_CHANNEL_ID)) {
+ params.appendWhere(
+ PreviewPrograms.COLUMN_CHANNEL_ID + "=?",
+ values.getAsString(PreviewPrograms.COLUMN_CHANNEL_ID));
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
+ switch (sUriMatcher.match(uri)) {
+ case MATCH_CHANNEL_ID_LOGO:
+ return openLogoFile(uri, mode);
+ default:
+ throw new FileNotFoundException(uri.toString());
+ }
+ }
+
+ private ParcelFileDescriptor openLogoFile(Uri uri, String mode) throws FileNotFoundException {
+ long channelId = Long.parseLong(uri.getPathSegments().get(1));
+
+ SqlParams params =
+ new SqlParams(CHANNELS_TABLE, Channels._ID + "=?", String.valueOf(channelId));
+ if (!callerHasAccessAllEpgDataPermission()) {
+ if (callerHasReadTvListingsPermission()) {
+ params.appendWhere(
+ Channels.COLUMN_PACKAGE_NAME + "=? OR " + Channels.COLUMN_SEARCHABLE + "=?",
+ getCallingPackage_(),
+ "1");
+ } else {
+ params.appendWhere(Channels.COLUMN_PACKAGE_NAME + "=?", getCallingPackage_());
+ }
+ }
+
+ SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
+ queryBuilder.setTables(params.getTables());
+
+ // We don't write the database here.
+ SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+ if (mode.equals("r")) {
+ String sql =
+ queryBuilder.buildQuery(
+ new String[] {CHANNELS_COLUMN_LOGO},
+ params.getSelection(),
+ null,
+ null,
+ null,
+ null);
+ ParcelFileDescriptor fd =
+ DatabaseUtils.blobFileDescriptorForQuery(db, sql, params.getSelectionArgs());
+ if (fd == null) {
+ throw new FileNotFoundException(uri.toString());
+ }
+ return fd;
+ } else {
+ try (Cursor cursor =
+ queryBuilder.query(
+ db,
+ new String[] {Channels._ID},
+ params.getSelection(),
+ params.getSelectionArgs(),
+ null,
+ null,
+ null)) {
+ if (cursor.getCount() < 1) {
+ // Fails early if corresponding channel does not exist.
+ // PipeMonitor may still fail to update DB later.
+ throw new FileNotFoundException(uri.toString());
+ }
+ }
+
+ try {
+ ParcelFileDescriptor[] pipeFds = ParcelFileDescriptor.createPipe();
+ PipeMonitor pipeMonitor = new PipeMonitor(pipeFds[0], channelId, params);
+ pipeMonitor.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ return pipeFds[1];
+ } catch (IOException ioe) {
+ FileNotFoundException fne = new FileNotFoundException(uri.toString());
+ fne.initCause(ioe);
+ throw fne;
+ }
+ }
+ }
+
+ /**
+ * Validates the sort order based on the given field set.
+ *
+ * @throws IllegalArgumentException if there is any unknown field.
+ */
+ @SuppressLint("DefaultLocale")
+ private static void validateSortOrder(String sortOrder, Set<String> possibleFields) {
+ if (TextUtils.isEmpty(sortOrder) || possibleFields.isEmpty()) {
+ return;
+ }
+ String[] orders = sortOrder.split(",");
+ for (String order : orders) {
+ String field =
+ order.replaceAll("\\s+", " ")
+ .trim()
+ .toLowerCase()
+ .replace(" asc", "")
+ .replace(" desc", "");
+ if (!possibleFields.contains(field)) {
+ throw new IllegalArgumentException("Illegal field in sort order " + order);
+ }
+ }
+ }
+
+ private class PipeMonitor extends AsyncTask<Void, Void, Void> {
+ private final ParcelFileDescriptor mPfd;
+ private final long mChannelId;
+ private final SqlParams mParams;
+
+ private PipeMonitor(ParcelFileDescriptor pfd, long channelId, SqlParams params) {
+ mPfd = pfd;
+ mChannelId = channelId;
+ mParams = params;
+ }
+
+ @Override
+ protected Void doInBackground(Void... params) {
+ int count = 0;
+ try (AutoCloseInputStream is = new AutoCloseInputStream(mPfd);
+ ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
+ Bitmap bitmap = BitmapFactory.decodeStream(is);
+ if (bitmap == null) {
+ Log.e(TAG, "Failed to decode logo image for channel ID " + mChannelId);
+ return null;
+ }
+
+ float scaleFactor =
+ Math.min(
+ 1f,
+ ((float) MAX_LOGO_IMAGE_SIZE)
+ / Math.max(bitmap.getWidth(), bitmap.getHeight()));
+ if (scaleFactor < 1f) {
+ bitmap =
+ Bitmap.createScaledBitmap(
+ bitmap,
+ (int) (bitmap.getWidth() * scaleFactor),
+ (int) (bitmap.getHeight() * scaleFactor),
+ false);
+ }
+ bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
+ byte[] bytes = baos.toByteArray();
+
+ ContentValues values = new ContentValues();
+ values.put(CHANNELS_COLUMN_LOGO, bytes);
+ SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+ count =
+ db.update(
+ mParams.getTables(),
+ values,
+ mParams.getSelection(),
+ mParams.getSelectionArgs());
+ if (count > 0) {
+ Uri uri = TvContractCompat.buildChannelLogoUri(mChannelId);
+ notifyChange(uri);
+ }
+ } catch (IOException e) {
+ Log.e(TAG, "Failed to write logo for channel ID " + mChannelId, e);
+
+ } finally {
+ if (count == 0) {
+ try {
+ mPfd.closeWithError("Failed to write logo for channel ID " + mChannelId);
+ } catch (IOException ioe) {
+ Log.e(TAG, "Failed to close pipe", ioe);
+ }
+ }
+ }
+ return null;
+ }
+ }
+
+ /**
+ * Column definitions for the TV programs that the user watched. Applications do not have access
+ * to this table.
+ *
+ * <p>
+ *
+ * <p>By default, the query results will be sorted by {@link
+ * WatchedPrograms#COLUMN_WATCH_START_TIME_UTC_MILLIS} in descending order.
+ *
+ * @hide
+ */
+ public static final class WatchedPrograms implements BaseTvColumns {
+
+ /** The content:// style URI for this table. */
+ public static final Uri CONTENT_URI =
+ Uri.parse("content://" + TvContract.AUTHORITY + "/watched_program");
+
+ /** The MIME type of a directory of watched programs. */
+ public static final String CONTENT_TYPE = "vnd.android.cursor.dir/watched_program";
+
+ /** The MIME type of a single item in this table. */
+ public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/watched_program";
+
+ /**
+ * The UTC time that the user started watching this TV program, in milliseconds since the
+ * epoch.
+ *
+ * <p>
+ *
+ * <p>Type: INTEGER (long)
+ */
+ public static final String COLUMN_WATCH_START_TIME_UTC_MILLIS =
+ "watch_start_time_utc_millis";
+
+ /**
+ * The UTC time that the user stopped watching this TV program, in milliseconds since the
+ * epoch.
+ *
+ * <p>
+ *
+ * <p>Type: INTEGER (long)
+ */
+ public static final String COLUMN_WATCH_END_TIME_UTC_MILLIS = "watch_end_time_utc_millis";
+
+ /**
+ * The ID of the TV channel that provides this TV program.
+ *
+ * <p>
+ *
+ * <p>This is a required field.
+ *
+ * <p>
+ *
+ * <p>Type: INTEGER (long)
+ */
+ public static final String COLUMN_CHANNEL_ID = "channel_id";
+
+ /**
+ * The title of this TV program.
+ *
+ * <p>
+ *
+ * <p>Type: TEXT
+ */
+ public static final String COLUMN_TITLE = "title";
+
+ /**
+ * The start time of this TV program, in milliseconds since the epoch.
+ *
+ * <p>
+ *
+ * <p>Type: INTEGER (long)
+ */
+ public static final String COLUMN_START_TIME_UTC_MILLIS = "start_time_utc_millis";
+
+ /**
+ * The end time of this TV program, in milliseconds since the epoch.
+ *
+ * <p>
+ *
+ * <p>Type: INTEGER (long)
+ */
+ public static final String COLUMN_END_TIME_UTC_MILLIS = "end_time_utc_millis";
+
+ /**
+ * The description of this TV program.
+ *
+ * <p>
+ *
+ * <p>Type: TEXT
+ */
+ public static final String COLUMN_DESCRIPTION = "description";
+
+ /**
+ * Extra parameters given to {@link TvInputService.Session#tune(Uri, android.os.Bundle)
+ * TvInputService.Session.tune(Uri, android.os.Bundle)} when tuning to the channel that
+ * provides this TV program. (Used internally.)
+ *
+ * <p>
+ *
+ * <p>This column contains an encoded string that represents comma-separated key-value pairs
+ * of the tune parameters. (Ex. "[key1]=[value1], [key2]=[value2]"). '%' is used as an
+ * escape character for '%', '=', and ','.
+ *
+ * <p>
+ *
+ * <p>Type: TEXT
+ */
+ public static final String COLUMN_INTERNAL_TUNE_PARAMS = "tune_params";
+
+ /**
+ * The session token of this TV program. (Used internally.)
+ *
+ * <p>
+ *
+ * <p>This contains a String representation of {@link IBinder} for {@link
+ * TvInputService.Session} that provides the current TV program. It is used internally to
+ * distinguish watched programs entries from different TV input sessions.
+ *
+ * <p>
+ *
+ * <p>Type: TEXT
+ */
+ public static final String COLUMN_INTERNAL_SESSION_TOKEN = "session_token";
+
+ private WatchedPrograms() {}
+ }
+}
diff --git a/tests/common/src/com/android/tv/testing/SingletonProvider.java b/tests/common/src/com/android/tv/testing/SingletonProvider.java
new file mode 100644
index 00000000..d9c2d409
--- /dev/null
+++ b/tests/common/src/com/android/tv/testing/SingletonProvider.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2017 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.testing;
+
+import javax.inject.Provider;
+
+/** A Provider that always returns the same instance. */
+public class SingletonProvider<T> implements Provider<T> {
+ private final T t;
+
+ private SingletonProvider(T t) {
+ this.t = t;
+ }
+
+ @Override
+ public T get() {
+ return t;
+ }
+
+ public static <S, T extends S> Provider<S> create(T t) {
+ return new SingletonProvider<S>(t);
+ }
+}
diff --git a/tests/common/src/com/android/tv/testing/TestSingletonApp.java b/tests/common/src/com/android/tv/testing/TestSingletonApp.java
new file mode 100644
index 00000000..f55ed8d4
--- /dev/null
+++ b/tests/common/src/com/android/tv/testing/TestSingletonApp.java
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) 2017 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.testing;
+
+import android.app.Application;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.media.tv.TvInputManager;
+import android.os.AsyncTask;
+import com.android.tv.InputSessionManager;
+import com.android.tv.MainActivityWrapper;
+import com.android.tv.TvSingletons;
+import com.android.tv.analytics.Analytics;
+import com.android.tv.analytics.Tracker;
+import com.android.tv.common.BaseApplication;
+import com.android.tv.common.config.api.RemoteConfig;
+import com.android.tv.common.experiments.ExperimentLoader;
+import com.android.tv.common.recording.RecordingStorageStatusManager;
+import com.android.tv.common.util.Clock;
+import com.android.tv.data.ChannelDataManager;
+import com.android.tv.data.PreviewDataManager;
+import com.android.tv.data.ProgramDataManager;
+import com.android.tv.data.epg.EpgFetcher;
+import com.android.tv.data.epg.EpgReader;
+import com.android.tv.dvr.DvrDataManager;
+import com.android.tv.dvr.DvrManager;
+import com.android.tv.dvr.DvrScheduleManager;
+import com.android.tv.dvr.DvrWatchedPositionManager;
+import com.android.tv.dvr.recorder.RecordingScheduler;
+import com.android.tv.perf.PerformanceMonitor;
+import com.android.tv.perf.StubPerformanceMonitor;
+import com.android.tv.testing.dvr.DvrDataManagerInMemoryImpl;
+import com.android.tv.testing.testdata.TestData;
+import com.android.tv.tuner.TunerInputController;
+import com.android.tv.util.SetupUtils;
+import com.android.tv.util.TvInputManagerHelper;
+import com.android.tv.util.account.AccountHelper;
+import java.util.concurrent.Executor;
+import javax.inject.Provider;
+
+/** Test application for Live TV. */
+public class TestSingletonApp extends Application implements TvSingletons {
+ public final FakeClock fakeClock = FakeClock.createWithCurrentTime();
+ public final FakeEpgReader epgReader = new FakeEpgReader(fakeClock);
+ public final FakeRemoteConfig remoteConfig = new FakeRemoteConfig();
+ public final FakeEpgFetcher epgFetcher = new FakeEpgFetcher();
+
+ public FakeTvInputManagerHelper tvInputManagerHelper;
+ public SetupUtils setupUtils;
+ public DvrManager dvrManager;
+ public DvrDataManager mDvrDataManager;
+
+ private final Provider<EpgReader> mEpgReaderProvider = SingletonProvider.create(epgReader);
+ private TunerInputController mTunerInputController;
+ private PerformanceMonitor mPerformanceMonitor;
+ private ChannelDataManager mChannelDataManager;
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ mTunerInputController =
+ new TunerInputController(
+ ComponentName.unflattenFromString(getEmbeddedTunerInputId()));
+
+ tvInputManagerHelper = new FakeTvInputManagerHelper(this);
+ setupUtils = SetupUtils.createForTvSingletons(this);
+ tvInputManagerHelper.start();
+ mChannelDataManager = new ChannelDataManager(this, tvInputManagerHelper);
+ mChannelDataManager.start();
+ mDvrDataManager = new DvrDataManagerInMemoryImpl(this, fakeClock);
+ // HACK reset the singleton for tests
+ BaseApplication.sSingletons = this;
+ }
+
+ public void loadTestData(TestData testData, long durationMs) {
+ tvInputManagerHelper
+ .getFakeTvInputManager()
+ .add(testData.getTvInputInfo(), TvInputManager.INPUT_STATE_CONNECTED);
+ testData.init(this, fakeClock, durationMs);
+ }
+
+ @Override
+ public Analytics getAnalytics() {
+ return null;
+ }
+
+ @Override
+ public void handleInputCountChanged() {}
+
+ @Override
+ public ChannelDataManager getChannelDataManager() {
+ return mChannelDataManager;
+ }
+
+ @Override
+ public boolean isChannelDataManagerLoadFinished() {
+ return false;
+ }
+
+ @Override
+ public ProgramDataManager getProgramDataManager() {
+ return null;
+ }
+
+ @Override
+ public boolean isProgramDataManagerCurrentProgramsLoadFinished() {
+ return false;
+ }
+
+ @Override
+ public PreviewDataManager getPreviewDataManager() {
+ return null;
+ }
+
+ @Override
+ public DvrDataManager getDvrDataManager() {
+ return mDvrDataManager;
+ }
+
+ @Override
+ public DvrScheduleManager getDvrScheduleManager() {
+ return null;
+ }
+
+ @Override
+ public DvrManager getDvrManager() {
+ return dvrManager;
+ }
+
+ @Override
+ public RecordingScheduler getRecordingScheduler() {
+ return null;
+ }
+
+ @Override
+ public DvrWatchedPositionManager getDvrWatchedPositionManager() {
+ return null;
+ }
+
+ @Override
+ public InputSessionManager getInputSessionManager() {
+ return null;
+ }
+
+ @Override
+ public Tracker getTracker() {
+ return null;
+ }
+
+ @Override
+ public TvInputManagerHelper getTvInputManagerHelper() {
+ return tvInputManagerHelper;
+ }
+
+ @Override
+ public Provider<EpgReader> providesEpgReader() {
+ return mEpgReaderProvider;
+ }
+
+ @Override
+ public EpgFetcher getEpgFetcher() {
+ return epgFetcher;
+ }
+
+ @Override
+ public SetupUtils getSetupUtils() {
+ return setupUtils;
+ }
+
+ @Override
+ public TunerInputController getTunerInputController() {
+ return mTunerInputController;
+ }
+
+ @Override
+ public ExperimentLoader getExperimentLoader() {
+ return new ExperimentLoader();
+ }
+
+ @Override
+ public MainActivityWrapper getMainActivityWrapper() {
+ return null;
+ }
+
+ @Override
+ public AccountHelper getAccountHelper() {
+ return null;
+ }
+
+ @Override
+ public Clock getClock() {
+ return fakeClock;
+ }
+
+ @Override
+ public RecordingStorageStatusManager getRecordingStorageStatusManager() {
+ return null;
+ }
+
+ @Override
+ public RemoteConfig getRemoteConfig() {
+ return remoteConfig;
+ }
+
+ @Override
+ public Intent getTunerSetupIntent(Context context) {
+ return null;
+ }
+
+ @Override
+ public boolean isRunningInMainProcess() {
+ return false;
+ }
+
+ @Override
+ public PerformanceMonitor getPerformanceMonitor() {
+ if (mPerformanceMonitor == null) {
+ mPerformanceMonitor = new StubPerformanceMonitor();
+ }
+ return mPerformanceMonitor;
+ }
+
+ @Override
+ public String getEmbeddedTunerInputId() {
+ return "com.android.tv/.tuner.tvinput.TunerTvInputService";
+ }
+
+ @Override
+ public Executor getDbExecutor() {
+ return AsyncTask.SERIAL_EXECUTOR;
+ }
+}
diff --git a/tests/unit/src/com/android/tv/BaseMainActivityTestCase.java b/tests/common/src/com/android/tv/testing/activities/BaseMainActivityTestCase.java
index e6f1af7e..666f8181 100644
--- a/tests/unit/src/com/android/tv/BaseMainActivityTestCase.java
+++ b/tests/common/src/com/android/tv/testing/activities/BaseMainActivityTestCase.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.tv;
+package com.android.tv.testing.activities;
import static android.support.test.InstrumentationRegistry.getInstrumentation;
@@ -21,23 +21,19 @@ import android.content.Context;
import android.os.SystemClock;
import android.support.test.rule.ActivityTestRule;
import android.text.TextUtils;
-
-import com.android.tv.data.Channel;
+import com.android.tv.MainActivity;
import com.android.tv.data.ChannelDataManager;
-import com.android.tv.testing.ChannelInfo;
+import com.android.tv.data.api.Channel;
+import com.android.tv.testing.data.ChannelInfo;
import com.android.tv.testing.testinput.ChannelStateData;
import com.android.tv.testing.testinput.TestInputControlConnection;
import com.android.tv.testing.testinput.TestInputControlUtils;
import com.android.tv.testing.testinput.TvTestInputConstants;
-
+import java.util.List;
import org.junit.Before;
import org.junit.Rule;
-import java.util.List;
-
-/**
- * Base TestCase for tests that need a {@link MainActivity}.
- */
+/** Base TestCase for tests that need a {@link MainActivity}. */
public abstract class BaseMainActivityTestCase {
private static final String TAG = "BaseMainActivityTest";
private static final int CHANNEL_LOADING_CHECK_INTERVAL_MS = 10;
@@ -54,8 +50,11 @@ public abstract class BaseMainActivityTestCase {
public void setUp() {
mActivity = mActivityTestRule.getActivity();
// TODO: ensure the SampleInputs are setup.
- getInstrumentation().getTargetContext()
- .bindService(TestInputControlUtils.createIntent(), mConnection,
+ getInstrumentation()
+ .getTargetContext()
+ .bindService(
+ TestInputControlUtils.createIntent(),
+ mConnection,
Context.BIND_AUTO_CREATE);
}
@@ -73,17 +72,17 @@ public abstract class BaseMainActivityTestCase {
*/
protected void tuneToChannel(final Channel channel) {
// Run on UI thread so views can be modified
- getInstrumentation().runOnMainSync(new Runnable() {
- @Override
- public void run() {
- mActivity.tuneToChannel(channel);
- }
- });
+ getInstrumentation()
+ .runOnMainSync(
+ new Runnable() {
+ @Override
+ public void run() {
+ mActivity.tuneToChannel(channel);
+ }
+ });
}
- /**
- * Sleep until @{@link ChannelDataManager#isDbLoadFinished()} is true.
- */
+ /** Sleep until @{@link ChannelDataManager#isDbLoadFinished()} is true. */
protected void waitUntilChannelLoadingFinish() {
ChannelDataManager channelDataManager = mActivity.getChannelDataManager();
while (!channelDataManager.isDbLoadFinished()) {
@@ -102,9 +101,7 @@ public abstract class BaseMainActivityTestCase {
tuneToChannel(c);
}
- /**
- * Tune to channel.
- */
+ /** Tune to channel. */
protected void tuneToChannel(ChannelInfo channel) {
tuneToChannel(channel.name);
}
@@ -112,13 +109,14 @@ public abstract class BaseMainActivityTestCase {
/**
* Update the channel state to {@code data} then tune to that channel.
*
- * @param data the state to update the channel with.
+ * @param data the state to update the channel with.
* @param channel the channel to tune to
*/
protected void updateThenTune(ChannelStateData data, ChannelInfo channel) {
if (channel.equals(TvTestInputConstants.CH_1_DEFAULT_DONT_MODIFY)) {
throw new IllegalArgumentException(
- "By convention " + TvTestInputConstants.CH_1_DEFAULT_DONT_MODIFY.name
+ "By convention "
+ + TvTestInputConstants.CH_1_DEFAULT_DONT_MODIFY.name
+ " should not be modified.");
}
mConnection.updateChannelState(channel, data);
@@ -128,7 +126,7 @@ public abstract class BaseMainActivityTestCase {
private Channel findChannelWithName(String displayName) {
waitUntilChannelLoadingFinish();
Channel channel = null;
- List <Channel> channelList = mActivity.getChannelDataManager().getChannelList();
+ List<Channel> channelList = mActivity.getChannelDataManager().getChannelList();
for (Channel c : channelList) {
if (TextUtils.equals(c.getDisplayName(), displayName)) {
channel = c;
diff --git a/tests/common/src/com/android/tv/testing/constants/ConfigConstants.java b/tests/common/src/com/android/tv/testing/constants/ConfigConstants.java
new file mode 100644
index 00000000..890c51e0
--- /dev/null
+++ b/tests/common/src/com/android/tv/testing/constants/ConfigConstants.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2017 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.testing.constants;
+
+import android.os.Build;
+
+/** Constants for Robolectic Config. */
+public final class ConfigConstants {
+
+ public static final String MANIFEST = "vendor/unbundled_google/packages/TV/AndroidManifest.xml";
+ public static final int SDK = Build.VERSION_CODES.M;
+
+ private ConfigConstants() {}
+}
diff --git a/tests/common/src/com/android/tv/testing/constants/Constants.java b/tests/common/src/com/android/tv/testing/constants/Constants.java
new file mode 100644
index 00000000..09e1ada1
--- /dev/null
+++ b/tests/common/src/com/android/tv/testing/constants/Constants.java
@@ -0,0 +1,47 @@
+/*
+ * 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.testing.constants;
+
+import android.media.tv.TvTrackInfo;
+
+/** Constants for testing. */
+public final class Constants {
+ public static final int FUNC_TEST_CHANNEL_COUNT = 100;
+ public static final int UNIT_TEST_CHANNEL_COUNT = 4;
+ public static final int JANK_TEST_CHANNEL_COUNT = 500; // TODO: increase to 1000 see b/23526997
+
+ public static final TvTrackInfo EN_STEREO_AUDIO_TRACK =
+ new TvTrackInfo.Builder(TvTrackInfo.TYPE_AUDIO, "English Stereo Audio")
+ .setLanguage("en")
+ .setAudioChannelCount(2)
+ .build();
+ public static final TvTrackInfo GENERIC_AUDIO_TRACK =
+ new TvTrackInfo.Builder(TvTrackInfo.TYPE_AUDIO, "Generic Audio").build();
+
+ public static final TvTrackInfo FHD1080P50_VIDEO_TRACK =
+ new TvTrackInfo.Builder(TvTrackInfo.TYPE_VIDEO, "FHD Video")
+ .setVideoHeight(1080)
+ .setVideoWidth(1920)
+ .setVideoFrameRate(50)
+ .build();
+ public static final TvTrackInfo SVGA_VIDEO_TRACK =
+ new TvTrackInfo.Builder(TvTrackInfo.TYPE_VIDEO, "SVGA Video")
+ .setVideoHeight(600)
+ .setVideoWidth(800)
+ .build();
+
+ private Constants() {}
+}
diff --git a/tests/common/src/com/android/tv/testing/TvContentRatingConstants.java b/tests/common/src/com/android/tv/testing/constants/TvContentRatingConstants.java
index c4c96fed..e1a3d906 100644
--- a/tests/common/src/com/android/tv/testing/TvContentRatingConstants.java
+++ b/tests/common/src/com/android/tv/testing/constants/TvContentRatingConstants.java
@@ -14,20 +14,21 @@
* limitations under the License.
*/
-package com.android.tv.testing;
+package com.android.tv.testing.constants;
import android.media.tv.TvContentRating;
-/**
- * Constants for the content rating strings.
- */
+/** Constants for the content rating strings. */
public final class TvContentRatingConstants {
/**
* A content rating object.
*
* <p>Domain: com.android.tv
+ *
* <p>Rating system: US_TV
+ *
* <p>Rating: US_TV_Y7
+ *
* <p>Sub ratings: US_TV_FV
*/
public static final TvContentRating CONTENT_RATING_US_TV_Y7_US_TV_FV =
@@ -39,7 +40,9 @@ public final class TvContentRatingConstants {
* A content rating object.
*
* <p>Domain: com.android.tv
+ *
* <p>Rating system: US_TV
+ *
* <p>Rating: US_TV_MA
*/
public static final TvContentRating CONTENT_RATING_US_TV_MA =
@@ -51,11 +54,14 @@ public final class TvContentRatingConstants {
* A content rating object.
*
* <p>Domain: com.android.tv
+ *
* <p>Rating system: US_TV
+ *
* <p>Rating: US_TV_PG
+ *
* <p>Sub ratings: US_TV_L, US_TV_S
*/
public static final TvContentRating CONTENT_RATING_US_TV_PG_US_TV_L_US_TV_S =
- TvContentRating.createRating("com.android.tv", "US_TV", "US_TV_PG", "US_TV_L",
- "US_TV_S");
+ TvContentRating.createRating(
+ "com.android.tv", "US_TV", "US_TV_PG", "US_TV_L", "US_TV_S");
}
diff --git a/tests/common/src/com/android/tv/testing/ChannelInfo.java b/tests/common/src/com/android/tv/testing/data/ChannelInfo.java
index 946c0b55..e39c057d 100644
--- a/tests/common/src/com/android/tv/testing/ChannelInfo.java
+++ b/tests/common/src/com/android/tv/testing/data/ChannelInfo.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.tv.testing;
+package com.android.tv.testing.data;
import android.content.ContentResolver;
import android.content.Context;
@@ -23,14 +23,12 @@ import android.media.tv.TvContract;
import android.net.Uri;
import android.support.annotation.Nullable;
import android.util.SparseArray;
-
import java.util.Objects;
-/**
- * Channel Information.
- */
+/** Channel Information. */
public final class ChannelInfo {
private static final SparseArray<String> VIDEO_HEIGHT_TO_FORMAT_MAP = new SparseArray<>();
+
static {
VIDEO_HEIGHT_TO_FORMAT_MAP.put(480, TvContract.Channels.VIDEO_FORMAT_480P);
VIDEO_HEIGHT_TO_FORMAT_MAP.put(576, TvContract.Channels.VIDEO_FORMAT_576P);
@@ -41,9 +39,9 @@ public final class ChannelInfo {
}
public static final String[] PROJECTION = {
- TvContract.Channels.COLUMN_DISPLAY_NUMBER,
- TvContract.Channels.COLUMN_DISPLAY_NAME,
- TvContract.Channels.COLUMN_ORIGINAL_NETWORK_ID,
+ TvContract.Channels.COLUMN_DISPLAY_NUMBER,
+ TvContract.Channels.COLUMN_DISPLAY_NAME,
+ TvContract.Channels.COLUMN_ORIGINAL_NETWORK_ID,
};
public final String number;
@@ -67,14 +65,15 @@ public final class ChannelInfo {
* Create a channel info for TVTestInput.
*
* @param context a context to insert logo. It can be null if logo isn't needed.
- * @param channelNumber a channel number to be use as an identifier.
- * {@link #originalNetworkId} will be assigned the same value, too.
+ * @param channelNumber a channel number to be use as an identifier. {@link #originalNetworkId}
+ * will be assigned the same value, too.
*/
public static ChannelInfo create(@Nullable Context context, int channelNumber) {
- Builder builder = new Builder()
- .setNumber(String.valueOf(channelNumber))
- .setName("Channel " + channelNumber)
- .setOriginalNetworkId(channelNumber);
+ Builder builder =
+ new Builder()
+ .setNumber(String.valueOf(channelNumber))
+ .setName("Channel " + channelNumber)
+ .setOriginalNetworkId(channelNumber);
if (context != null) {
// tests/input/tools/get_test_logos.sh only stores 1000 logos.
builder.setLogoUrl(getUriStringForChannelLogo(context, channelNumber));
@@ -88,7 +87,9 @@ public final class ChannelInfo {
.scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
.authority(context.getPackageName())
.path("drawable")
- .appendPath("ch_" + index + "_logo").build().toString();
+ .appendPath("ch_" + index + "_logo")
+ .build()
+ .toString();
}
public static ChannelInfo fromCursor(Cursor c) {
@@ -109,10 +110,22 @@ public final class ChannelInfo {
return builder.build();
}
- private ChannelInfo(String number, String name, String logoUrl, int originalNetworkId,
- int videoWidth, int videoHeight, float videoPixelAspectRatio, int audioChannel,
- int audioLanguageCount, boolean hasClosedCaption, ProgramInfo program,
- String appLinkText, int appLinkColor, String appLinkIconUri, String appLinkPosterArtUri,
+ private ChannelInfo(
+ String number,
+ String name,
+ String logoUrl,
+ int originalNetworkId,
+ int videoWidth,
+ int videoHeight,
+ float videoPixelAspectRatio,
+ int audioChannel,
+ int audioLanguageCount,
+ boolean hasClosedCaption,
+ ProgramInfo program,
+ String appLinkText,
+ int appLinkColor,
+ String appLinkIconUri,
+ String appLinkPosterArtUri,
String appLinkIntentUri) {
this.number = number;
this.name = name;
@@ -139,20 +152,35 @@ public final class ChannelInfo {
@Override
public String toString() {
return "Channel{"
- + "number=" + number
- + ", name=" + name
- + ", logoUri=" + logoUrl
- + ", originalNetworkId=" + originalNetworkId
- + ", videoWidth=" + videoWidth
- + ", videoHeight=" + videoHeight
- + ", audioChannel=" + audioChannel
- + ", audioLanguageCount=" + audioLanguageCount
- + ", hasClosedCaption=" + hasClosedCaption
- + ", appLinkText=" + appLinkText
- + ", appLinkColor=" + appLinkColor
- + ", appLinkIconUri=" + appLinkIconUri
- + ", appLinkPosterArtUri=" + appLinkPosterArtUri
- + ", appLinkIntentUri=" + appLinkIntentUri + "}";
+ + "number="
+ + number
+ + ", name="
+ + name
+ + ", logoUri="
+ + logoUrl
+ + ", originalNetworkId="
+ + originalNetworkId
+ + ", videoWidth="
+ + videoWidth
+ + ", videoHeight="
+ + videoHeight
+ + ", audioChannel="
+ + audioChannel
+ + ", audioLanguageCount="
+ + audioLanguageCount
+ + ", hasClosedCaption="
+ + hasClosedCaption
+ + ", appLinkText="
+ + appLinkText
+ + ", appLinkColor="
+ + appLinkColor
+ + ", appLinkIconUri="
+ + appLinkIconUri
+ + ", appLinkPosterArtUri="
+ + appLinkPosterArtUri
+ + ", appLinkIntentUri="
+ + appLinkIntentUri
+ + "}";
}
@Override
@@ -164,21 +192,21 @@ public final class ChannelInfo {
return false;
}
ChannelInfo that = (ChannelInfo) o;
- return Objects.equals(originalNetworkId, that.originalNetworkId) &&
- Objects.equals(videoWidth, that.videoWidth) &&
- Objects.equals(videoHeight, that.videoHeight) &&
- Objects.equals(audioChannel, that.audioChannel) &&
- Objects.equals(audioLanguageCount, that.audioLanguageCount) &&
- Objects.equals(hasClosedCaption, that.hasClosedCaption) &&
- Objects.equals(appLinkColor, that.appLinkColor) &&
- Objects.equals(number, that.number) &&
- Objects.equals(name, that.name) &&
- Objects.equals(logoUrl, that.logoUrl) &&
- Objects.equals(program, that.program) &&
- Objects.equals(appLinkText, that.appLinkText) &&
- Objects.equals(appLinkIconUri, that.appLinkIconUri) &&
- Objects.equals(appLinkPosterArtUri, that.appLinkPosterArtUri) &&
- Objects.equals(appLinkIntentUri, that.appLinkIntentUri);
+ return Objects.equals(originalNetworkId, that.originalNetworkId)
+ && Objects.equals(videoWidth, that.videoWidth)
+ && Objects.equals(videoHeight, that.videoHeight)
+ && Objects.equals(audioChannel, that.audioChannel)
+ && Objects.equals(audioLanguageCount, that.audioLanguageCount)
+ && Objects.equals(hasClosedCaption, that.hasClosedCaption)
+ && Objects.equals(appLinkColor, that.appLinkColor)
+ && Objects.equals(number, that.number)
+ && Objects.equals(name, that.name)
+ && Objects.equals(logoUrl, that.logoUrl)
+ && Objects.equals(program, that.program)
+ && Objects.equals(appLinkText, that.appLinkText)
+ && Objects.equals(appLinkIconUri, that.appLinkIconUri)
+ && Objects.equals(appLinkPosterArtUri, that.appLinkPosterArtUri)
+ && Objects.equals(appLinkIntentUri, that.appLinkIntentUri);
}
@Override
@@ -186,17 +214,15 @@ public final class ChannelInfo {
return Objects.hash(number, name, originalNetworkId);
}
- /**
- * Builder class for {@code ChannelInfo}.
- */
+ /** Builder class for {@code ChannelInfo}. */
public static class Builder {
private String mNumber;
private String mName;
private String mLogoUrl = null;
private int mOriginalNetworkId;
- private int mVideoWidth = 1920; // Width for HD video.
- private int mVideoHeight = 1080; // Height for HD video.
- private float mVideoPixelAspectRatio = 1.0f; //default value
+ private int mVideoWidth = 1920; // Width for HD video.
+ private int mVideoHeight = 1080; // Height for HD video.
+ private float mVideoPixelAspectRatio = 1.0f; // default value
private int mAudioChannel;
private int mAudioLanguageCount;
private boolean mHasClosedCaption;
@@ -207,8 +233,7 @@ public final class ChannelInfo {
private String mAppLinkPosterArtUri;
private String mAppLinkIntentUri;
- public Builder() {
- }
+ public Builder() {}
public Builder(ChannelInfo other) {
mNumber = other.number;
@@ -305,11 +330,23 @@ public final class ChannelInfo {
}
public ChannelInfo build() {
- return new ChannelInfo(mNumber, mName, mLogoUrl, mOriginalNetworkId,
- mVideoWidth, mVideoHeight, mVideoPixelAspectRatio, mAudioChannel,
- mAudioLanguageCount, mHasClosedCaption, mProgram, mAppLinkText, mAppLinkColor,
- mAppLinkIconUri, mAppLinkPosterArtUri, mAppLinkIntentUri);
-
+ return new ChannelInfo(
+ mNumber,
+ mName,
+ mLogoUrl,
+ mOriginalNetworkId,
+ mVideoWidth,
+ mVideoHeight,
+ mVideoPixelAspectRatio,
+ mAudioChannel,
+ mAudioLanguageCount,
+ mHasClosedCaption,
+ mProgram,
+ mAppLinkText,
+ mAppLinkColor,
+ mAppLinkIconUri,
+ mAppLinkPosterArtUri,
+ mAppLinkIntentUri);
}
}
}
diff --git a/tests/common/src/com/android/tv/testing/ChannelUtils.java b/tests/common/src/com/android/tv/testing/data/ChannelUtils.java
index bfb766d6..920c7087 100644
--- a/tests/common/src/com/android/tv/testing/ChannelUtils.java
+++ b/tests/common/src/com/android/tv/testing/data/ChannelUtils.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.tv.testing;
+package com.android.tv.testing.data;
import android.content.ContentResolver;
import android.content.ContentValues;
@@ -27,24 +27,22 @@ import android.support.annotation.WorkerThread;
import android.text.TextUtils;
import android.util.Log;
import android.util.SparseArray;
-
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-/**
- * Static helper methods for working with {@link android.media.tv.TvContract}.
- */
+/** Static helper methods for working with {@link android.media.tv.TvContract}. */
public class ChannelUtils {
private static final String TAG = "ChannelUtils";
private static final boolean DEBUG = false;
/**
- * Query and return the map of (channel_id, ChannelInfo).
- * See: {@link ChannelInfo#fromCursor(Cursor)}.
+ * Query and return the map of (channel_id, ChannelInfo). See: {@link
+ * com.android.tv.testing.data.ChannelInfo#fromCursor(Cursor)}.
*/
@WorkerThread
public static Map<Long, ChannelInfo> queryChannelInfoMapForTvInput(
@@ -55,8 +53,8 @@ public class ChannelUtils {
String[] projections = new String[ChannelInfo.PROJECTION.length + 1];
projections[0] = Channels._ID;
System.arraycopy(ChannelInfo.PROJECTION, 0, projections, 1, ChannelInfo.PROJECTION.length);
- try (Cursor cursor = context.getContentResolver()
- .query(uri, projections, null, null, null)) {
+ try (Cursor cursor =
+ context.getContentResolver().query(uri, projections, null, null, null)) {
if (cursor != null) {
while (cursor.moveToNext()) {
map.put(cursor.getLong(0), ChannelInfo.fromCursor(cursor));
@@ -113,10 +111,14 @@ public class ChannelUtils {
Long rowId = existingChannelsMap.get(channel.originalNetworkId);
Uri uri;
if (rowId == null) {
- if (DEBUG) Log.d(TAG, "Inserting "+ channel);
+ if (DEBUG) {
+ Log.d(TAG, "Inserting " + channel);
+ }
uri = resolver.insert(TvContract.Channels.CONTENT_URI, values);
} else {
- if (DEBUG) Log.d(TAG, "Updating "+ channel);
+ if (DEBUG) {
+ Log.d(TAG, "Updating " + channel);
+ }
uri = TvContract.buildChannelUri(rowId);
resolver.update(uri, values, null, null);
existingChannelsMap.remove(channel.originalNetworkId);
@@ -149,6 +151,14 @@ public class ChannelUtils {
// Prevent instantiation.
}
+ public static List<ChannelInfo> createChannelInfos(Context context, int channelCount) {
+ List<ChannelInfo> channels = new ArrayList<>();
+ for (int i = 1; i <= channelCount; i++) {
+ channels.add(ChannelInfo.create(context, i));
+ }
+ return channels;
+ }
+
public static class InsertLogosTask extends AsyncTask<Map<Uri, String>, Void, Void> {
private final Context mContext;
diff --git a/tests/common/src/com/android/tv/testing/ProgramInfo.java b/tests/common/src/com/android/tv/testing/data/ProgramInfo.java
index b1aaea6b..6d801425 100644
--- a/tests/common/src/com/android/tv/testing/ProgramInfo.java
+++ b/tests/common/src/com/android/tv/testing/data/ProgramInfo.java
@@ -14,80 +14,83 @@
* limitations under the License.
*/
-package com.android.tv.testing;
+package com.android.tv.testing.data;
import android.content.Context;
import android.database.Cursor;
import android.media.tv.TvContentRating;
import android.media.tv.TvContract;
-
+import com.android.tv.testing.R;
+import com.android.tv.testing.utils.Utils;
+import java.util.Arrays;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
public final class ProgramInfo {
- /**
- * If this is specify for title, it will be generated by adding index.
- */
+ /** If this is specify for title, it will be generated by adding index. */
public static final String GEN_TITLE = "";
/**
- * If this is specify for episode title, it will be generated by adding index.
- * Also, season and episode numbers would be generated, too.
- * see: {@link #build} for detail.
+ * If this is specify for episode title, it will be generated by adding index. Also, season and
+ * episode numbers would be generated, too. see: {@link #build} for detail.
*/
public static final String GEN_EPISODE = "";
+
private static final int SEASON_MAX = 10;
private static final int EPISODE_MAX = 12;
/**
- * If this is specify for poster art,
- * it will be selected one of {@link #POSTER_ARTS_RES} in order.
+ * If this is specify for poster art, it will be selected one of {@link #POSTER_ARTS_RES} in
+ * order.
*/
public static final String GEN_POSTER = "GEN";
+
private static final int[] POSTER_ARTS_RES = {
- 0,
- R.drawable.blue,
- R.drawable.red_large,
- R.drawable.green,
- R.drawable.red,
- R.drawable.green_large,
- R.drawable.blue_small};
+ 0,
+ R.drawable.blue,
+ R.drawable.red_large,
+ R.drawable.green,
+ R.drawable.red,
+ R.drawable.green_large,
+ R.drawable.blue_small
+ };
/**
- * If this is specified for duration,
- * it will be selected one of {@link #DURATIONS_MS} in order.
+ * If this is specified for duration, it will be selected one of {@link #DURATIONS_MS} in order.
*/
public static final int GEN_DURATION = -1;
+
private static final long[] DURATIONS_MS = {
- TimeUnit.MINUTES.toMillis(15),
- TimeUnit.MINUTES.toMillis(45),
- TimeUnit.MINUTES.toMillis(90),
- TimeUnit.MINUTES.toMillis(60),
- TimeUnit.MINUTES.toMillis(30),
- TimeUnit.MINUTES.toMillis(45),
- TimeUnit.MINUTES.toMillis(60),
- TimeUnit.MINUTES.toMillis(90),
- TimeUnit.HOURS.toMillis(5)};
- private static long DURATIONS_SUM_MS;
+ TimeUnit.MINUTES.toMillis(15),
+ TimeUnit.MINUTES.toMillis(45),
+ TimeUnit.MINUTES.toMillis(90),
+ TimeUnit.MINUTES.toMillis(60),
+ TimeUnit.MINUTES.toMillis(30),
+ TimeUnit.MINUTES.toMillis(45),
+ TimeUnit.MINUTES.toMillis(60),
+ TimeUnit.MINUTES.toMillis(90),
+ TimeUnit.HOURS.toMillis(5)
+ };
+ private static long durationsSumMs;
+
static {
- DURATIONS_SUM_MS = 0;
+ durationsSumMs = 0;
for (long duration : DURATIONS_MS) {
- DURATIONS_SUM_MS += duration;
+ durationsSumMs += duration;
}
}
- /**
- * If this is specified for genre,
- * it will be selected one of {@link #GENRES} in order.
- */
+ /** If this is specified for genre, it will be selected one of {@link #GENRES} in order. */
public static final String GEN_GENRE = "GEN";
+
private static final String[] GENRES = {
- "",
- TvContract.Programs.Genres.SPORTS,
- TvContract.Programs.Genres.NEWS,
- TvContract.Programs.Genres.SHOPPING,
- TvContract.Programs.Genres.DRAMA,
- TvContract.Programs.Genres.ENTERTAINMENT};
+ "",
+ TvContract.Programs.Genres.SPORTS,
+ TvContract.Programs.Genres.NEWS,
+ TvContract.Programs.Genres.SHOPPING,
+ TvContract.Programs.Genres.DRAMA,
+ TvContract.Programs.Genres.ENTERTAINMENT
+ };
public final String title;
public final String episode;
@@ -118,9 +121,17 @@ public final class ProgramInfo {
return builder.build();
}
- public ProgramInfo(String title, String episode, int seasonNumber, int episodeNumber,
- String posterArtUri, String description, long durationMs,
- TvContentRating[] contentRatings, String genre, String resourceUri) {
+ public ProgramInfo(
+ String title,
+ String episode,
+ int seasonNumber,
+ int episodeNumber,
+ String posterArtUri,
+ String description,
+ long durationMs,
+ TvContentRating[] contentRatings,
+ String genre,
+ String resourceUri) {
this.title = title;
this.episode = episode;
this.seasonNumber = seasonNumber;
@@ -141,8 +152,9 @@ public final class ProgramInfo {
}
/**
- * Get index of the program whose start time equals or less than {@code timeMs} and
- * end time more than {@code timeMs}.
+ * Get index of the program whose start time equals or less than {@code timeMs} and end time
+ * more than {@code timeMs}.
+ *
* @param timeMs target time in millis to find a program.
* @param channelId used to add complexity to the index between two consequence channels.
*/
@@ -151,8 +163,8 @@ public final class ProgramInfo {
return Math.max((int) (timeMs / durationMs), 0);
}
long startTimeMs = channelId * DURATIONS_MS[((int) (channelId % DURATIONS_MS.length))];
- int index = (int) ((timeMs - startTimeMs) / DURATIONS_SUM_MS) * DURATIONS_MS.length;
- startTimeMs += (index / DURATIONS_MS.length) * DURATIONS_SUM_MS;
+ int index = (int) ((timeMs - startTimeMs) / durationsSumMs) * DURATIONS_MS.length;
+ startTimeMs += (index / DURATIONS_MS.length) * durationsSumMs;
while (startTimeMs + DURATIONS_MS[index % DURATIONS_MS.length] < timeMs) {
startTimeMs += DURATIONS_MS[index % DURATIONS_MS.length];
index++;
@@ -162,14 +174,16 @@ public final class ProgramInfo {
/**
* Returns the start time for the program with the position.
+ *
* @param index index returned by {@link #getIndex}
*/
public long getStartTimeMs(int index, long channelId) {
if (durationMs != GEN_DURATION) {
return index * durationMs;
}
- long startTimeMs = channelId * DURATIONS_MS[((int) (channelId % DURATIONS_MS.length))]
- + (index / DURATIONS_MS.length) * DURATIONS_SUM_MS;
+ long startTimeMs =
+ channelId * DURATIONS_MS[((int) (channelId % DURATIONS_MS.length))]
+ + (index / DURATIONS_MS.length) * durationsSumMs;
for (int i = 0; i < index % DURATIONS_MS.length; i++) {
startTimeMs += DURATIONS_MS[i];
}
@@ -177,9 +191,9 @@ public final class ProgramInfo {
}
/**
- * Return complete {@link ProgramInfo} with the generated value.
- * See: {@link #GEN_TITLE}, {@link #GEN_EPISODE}, {@link #GEN_POSTER}, {@link #GEN_DURATION},
- * {@link #GEN_GENRE}.
+ * Return complete {@link ProgramInfo} with the generated value. See: {@link #GEN_TITLE}, {@link
+ * #GEN_EPISODE}, {@link #GEN_POSTER}, {@link #GEN_DURATION}, {@link #GEN_GENRE}.
+ *
* @param index index returned by {@link #getIndex}
*/
public ProgramInfo build(Context context, int index) {
@@ -196,8 +210,8 @@ public final class ProgramInfo {
episode != null ? (index % SEASON_MAX + 1) : seasonNumber,
episode != null ? (index % EPISODE_MAX + 1) : episodeNumber,
GEN_POSTER.equals(posterArtUri)
- ? Utils.getUriStringForResource(context,
- POSTER_ARTS_RES[index % POSTER_ARTS_RES.length])
+ ? Utils.getUriStringForResource(
+ context, POSTER_ARTS_RES[index % POSTER_ARTS_RES.length])
: posterArtUri,
description,
durationMs == GEN_DURATION ? DURATIONS_MS[index % DURATIONS_MS.length] : durationMs,
@@ -208,9 +222,13 @@ public final class ProgramInfo {
@Override
public String toString() {
- return "ProgramInfo{title=" + title
- + ", episode=" + episode
- + ", durationMs=" + durationMs + "}";
+ return "ProgramInfo{title="
+ + title
+ + ", episode="
+ + episode
+ + ", durationMs="
+ + durationMs
+ + "}";
}
@Override
@@ -222,16 +240,16 @@ public final class ProgramInfo {
return false;
}
ProgramInfo that = (ProgramInfo) o;
- return Objects.equals(seasonNumber, that.seasonNumber) &&
- Objects.equals(episodeNumber, that.episodeNumber) &&
- Objects.equals(durationMs, that.durationMs) &&
- Objects.equals(title, that.title) &&
- Objects.equals(episode, that.episode) &&
- Objects.equals(posterArtUri, that.posterArtUri) &&
- Objects.equals(description, that.description) &&
- Objects.equals(genre, that.genre) &&
- Objects.equals(contentRatings, that.contentRatings) &&
- Objects.equals(resourceUri, that.resourceUri);
+ return Objects.equals(seasonNumber, that.seasonNumber)
+ && Objects.equals(episodeNumber, that.episodeNumber)
+ && Objects.equals(durationMs, that.durationMs)
+ && Objects.equals(title, that.title)
+ && Objects.equals(episode, that.episode)
+ && Objects.equals(posterArtUri, that.posterArtUri)
+ && Objects.equals(description, that.description)
+ && Objects.equals(genre, that.genre)
+ && Arrays.equals(contentRatings, that.contentRatings)
+ && Objects.equals(resourceUri, that.resourceUri);
}
@Override
@@ -302,8 +320,17 @@ public final class ProgramInfo {
}
public ProgramInfo build() {
- return new ProgramInfo(mTitle, mEpisode, mSeasonNumber, mEpisodeNumber, mPosterArtUri,
- mDescription, mDurationMs, mContentRatings, mGenre, mResourceUri);
+ return new ProgramInfo(
+ mTitle,
+ mEpisode,
+ mSeasonNumber,
+ mEpisodeNumber,
+ mPosterArtUri,
+ mDescription,
+ mDurationMs,
+ mContentRatings,
+ mGenre,
+ mResourceUri);
}
}
}
diff --git a/tests/common/src/com/android/tv/testing/ProgramUtils.java b/tests/common/src/com/android/tv/testing/data/ProgramUtils.java
index 08c6a033..21647719 100644
--- a/tests/common/src/com/android/tv/testing/ProgramUtils.java
+++ b/tests/common/src/com/android/tv/testing/data/ProgramUtils.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.tv.testing;
+package com.android.tv.testing.data;
import android.content.ContentUris;
import android.content.ContentValues;
@@ -25,36 +25,57 @@ import android.media.tv.TvContract;
import android.media.tv.TvContract.Programs;
import android.net.Uri;
import android.util.Log;
-
import com.android.tv.common.TvContentRatingCache;
-
+import com.android.tv.common.util.Clock;
import java.util.ArrayList;
+import java.util.Map;
import java.util.concurrent.TimeUnit;
-public class ProgramUtils {
+/** Static utilities for using Programs in tests */
+public final class ProgramUtils {
private static final String TAG = "ProgramUtils";
private static final boolean DEBUG = false;
- // Populate program data for a week.
- private static final long PROGRAM_INSERT_DURATION_MS = TimeUnit.DAYS.toMillis(7);
+ /** Populate program data for a week */
+ public static final long PROGRAM_INSERT_DURATION_MS = TimeUnit.DAYS.toMillis(7);
+
private static final int MAX_DB_INSERT_COUNT_AT_ONCE = 500;
/**
- * Populate programs by repeating given program information.
- * This method will populate programs without any gap nor overlapping
- * starting from the current time.
+ * Populate programs by repeating given program information. This method will populate programs
+ * without any gap nor overlapping starting from the current time.
*/
- public static void populatePrograms(Context context, Uri channelUri, ProgramInfo program) {
+ public static void populatePrograms(
+ Context context, Uri channelUri, ProgramInfo program, Clock clock) {
+ populatePrograms(context, channelUri, program, clock, PROGRAM_INSERT_DURATION_MS);
+ }
+
+ public static void populatePrograms(
+ Context context,
+ Uri channelUri,
+ ProgramInfo program,
+ Clock clock,
+ long programInsertDurationMs) {
+ long currentTimeMs = clock.currentTimeMillis();
+ long targetEndTimeMs = currentTimeMs + programInsertDurationMs;
+ populatePrograms(context, channelUri, program, currentTimeMs, targetEndTimeMs);
+ }
+
+ public static void populatePrograms(
+ Context context,
+ Uri channelUri,
+ ProgramInfo program,
+ long currentTimeMs,
+ long targetEndTimeMs) {
ContentValues values = new ContentValues();
long channelId = ContentUris.parseId(channelUri);
values.put(Programs.COLUMN_CHANNEL_ID, channelId);
values.put(Programs.COLUMN_SHORT_DESCRIPTION, program.description);
- values.put(Programs.COLUMN_CONTENT_RATING,
+ values.put(
+ Programs.COLUMN_CONTENT_RATING,
TvContentRatingCache.contentRatingsToString(program.contentRatings));
- long currentTimeMs = System.currentTimeMillis();
- long targetEndTimeMs = currentTimeMs + PROGRAM_INSERT_DURATION_MS;
long timeMs = getLastProgramEndTimeMs(context, channelUri, currentTimeMs, targetEndTimeMs);
if (timeMs <= 0) {
timeMs = currentTimeMs;
@@ -81,11 +102,12 @@ public class ProgramUtils {
list.add(new ContentValues(values));
timeMs += programAt.durationMs;
- if (list.size() >= MAX_DB_INSERT_COUNT_AT_ONCE
- || timeMs >= targetEndTimeMs) {
+ if (list.size() >= MAX_DB_INSERT_COUNT_AT_ONCE || timeMs >= targetEndTimeMs) {
try {
- context.getContentResolver().bulkInsert(Programs.CONTENT_URI,
- list.toArray(new ContentValues[list.size()]));
+ context.getContentResolver()
+ .bulkInsert(
+ Programs.CONTENT_URI,
+ list.toArray(new ContentValues[list.size()]));
} catch (SQLiteException e) {
Log.e(TAG, "Can't insert EPG.", e);
return;
@@ -110,4 +132,16 @@ public class ProgramUtils {
}
private ProgramUtils() {}
+
+ public static void updateProgramForAllChannelsOf(
+ Context context, String inputId, Clock clock, long durationMs) {
+ // Reload channels so we have the ids.
+ Map<Long, ChannelInfo> channelIdToInfoMap =
+ ChannelUtils.queryChannelInfoMapForTvInput(context, inputId);
+ for (Long channelId : channelIdToInfoMap.keySet()) {
+ ProgramInfo programInfo = ProgramInfo.create();
+ populatePrograms(
+ context, TvContract.buildChannelUri(channelId), programInfo, clock, durationMs);
+ }
+ }
}
diff --git a/tests/unit/src/com/android/tv/dvr/DvrDataManagerInMemoryImpl.java b/tests/common/src/com/android/tv/testing/dvr/DvrDataManagerInMemoryImpl.java
index 0a7ab46c..b8a055c7 100644
--- a/tests/unit/src/com/android/tv/dvr/DvrDataManagerInMemoryImpl.java
+++ b/tests/common/src/com/android/tv/testing/dvr/DvrDataManagerInMemoryImpl.java
@@ -14,24 +14,22 @@
* limitations under the License
*/
-package com.android.tv.dvr;
+package com.android.tv.testing.dvr;
import android.content.Context;
-import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
-import android.support.test.filters.SdkSuppress;
import android.text.TextUtils;
import android.util.Log;
import android.util.Range;
-
import com.android.tv.common.SoftPreconditions;
+import com.android.tv.common.util.Clock;
+import com.android.tv.dvr.BaseDvrDataManager;
+import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.data.RecordedProgram;
import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.dvr.data.ScheduledRecording.RecordingState;
import com.android.tv.dvr.data.SeriesRecording;
-import com.android.tv.util.Clock;
-
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -40,9 +38,8 @@ import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;
/** A DVR Data manager that stores values in memory suitable for testing. */
-@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
public final class DvrDataManagerInMemoryImpl extends BaseDvrDataManager {
- private final static String TAG = "DvrDataManagerInMemory";
+ private static final String TAG = "DvrDataManagerInMemory";
private final AtomicLong mNextId = new AtomicLong(1);
private final Map<Long, ScheduledRecording> mScheduledRecordings = new HashMap<>();
private final Map<Long, RecordedProgram> mRecordedPrograms = new HashMap<>();
@@ -81,6 +78,7 @@ public final class DvrDataManagerInMemoryImpl extends BaseDvrDataManager {
return new ArrayList<>(mScheduledRecordings.values());
}
+ @Override
public List<SeriesRecording> getSeriesRecordings() {
return new ArrayList<>(mSeriesRecordings.values());
}
@@ -99,7 +97,7 @@ public final class DvrDataManagerInMemoryImpl extends BaseDvrDataManager {
@Override
public long getNextScheduledStartTimeAfter(long startTime) {
- List<ScheduledRecording> temp = getNonStartedScheduledRecordings();
+ List<ScheduledRecording> temp = getNonStartedScheduledRecordings();
Collections.sort(temp, ScheduledRecording.START_TIME_COMPARATOR);
for (ScheduledRecording r : temp) {
if (r.getStartTimeMs() > startTime) {
@@ -110,8 +108,8 @@ public final class DvrDataManagerInMemoryImpl extends BaseDvrDataManager {
}
@Override
- public List<ScheduledRecording> getScheduledRecordings(Range<Long> period,
- @RecordingState int state) {
+ public List<ScheduledRecording> getScheduledRecordings(
+ Range<Long> period, @RecordingState int state) {
List<ScheduledRecording> temp = getScheduledRecordingsPrograms();
List<ScheduledRecording> result = new ArrayList<>();
for (ScheduledRecording r : temp) {
@@ -144,19 +142,20 @@ public final class DvrDataManagerInMemoryImpl extends BaseDvrDataManager {
return result;
}
- /**
- * Add a new scheduled recording.
- */
+ /** Add a new scheduled recording. */
@Override
public void addScheduledRecording(ScheduledRecording... scheduledRecordings) {
+ addScheduledRecording(false, scheduledRecordings);
+ }
+
+ public void addScheduledRecording(boolean keepIds, ScheduledRecording... scheduledRecordings) {
for (ScheduledRecording r : scheduledRecordings) {
- addScheduledRecordingInternal(r);
+ addScheduledRecordingInternal(r, keepIds);
}
}
-
public void addRecordedProgram(RecordedProgram recordedProgram) {
- addRecordedProgramInternal(recordedProgram);
+ addRecordedProgramInternal(recordedProgram, false);
}
public void updateRecordedProgram(RecordedProgram r) {
@@ -174,26 +173,43 @@ public final class DvrDataManagerInMemoryImpl extends BaseDvrDataManager {
notifyRecordedProgramsRemoved(scheduledRecording);
}
-
public ScheduledRecording addScheduledRecordingInternal(ScheduledRecording scheduledRecording) {
- SoftPreconditions
- .checkState(scheduledRecording.getId() == ScheduledRecording.ID_NOT_SET, TAG,
- "expected id of " + ScheduledRecording.ID_NOT_SET + " but was "
- + scheduledRecording);
- scheduledRecording = ScheduledRecording.buildFrom(scheduledRecording)
- .setId(mNextId.incrementAndGet())
- .build();
+ return addScheduledRecordingInternal(scheduledRecording, false);
+ }
+
+ public ScheduledRecording addScheduledRecordingInternal(
+ ScheduledRecording scheduledRecording, boolean keepId) {
+ if (!keepId) {
+ SoftPreconditions.checkState(
+ scheduledRecording.getId() == ScheduledRecording.ID_NOT_SET,
+ TAG,
+ "expected id of "
+ + ScheduledRecording.ID_NOT_SET
+ + " but was "
+ + scheduledRecording);
+ scheduledRecording =
+ ScheduledRecording.buildFrom(scheduledRecording)
+ .setId(mNextId.incrementAndGet())
+ .build();
+ }
mScheduledRecordings.put(scheduledRecording.getId(), scheduledRecording);
notifyScheduledRecordingAdded(scheduledRecording);
return scheduledRecording;
}
- public RecordedProgram addRecordedProgramInternal(RecordedProgram recordedProgram) {
- SoftPreconditions.checkState(recordedProgram.getId() == RecordedProgram.ID_NOT_SET, TAG,
- "expected id of " + RecordedProgram.ID_NOT_SET + " but was " + recordedProgram);
- recordedProgram = RecordedProgram.buildFrom(recordedProgram)
- .setId(mNextId.incrementAndGet())
- .build();
+ public RecordedProgram addRecordedProgramInternal(
+ RecordedProgram recordedProgram, boolean keepId) {
+ if (!keepId) {
+ SoftPreconditions.checkState(
+ recordedProgram.getId() == RecordedProgram.ID_NOT_SET,
+ TAG,
+ "expected id of " + RecordedProgram.ID_NOT_SET + " but was " + recordedProgram);
+ recordedProgram =
+ RecordedProgram
+ .buildFrom(recordedProgram)
+ .setId(mNextId.incrementAndGet())
+ .build();
+ }
mRecordedPrograms.put(recordedProgram.getId(), recordedProgram);
notifyRecordedProgramsAdded(recordedProgram);
return recordedProgram;
@@ -265,7 +281,7 @@ public final class DvrDataManagerInMemoryImpl extends BaseDvrDataManager {
public ScheduledRecording getScheduledRecordingForProgramId(long programId) {
for (ScheduledRecording r : mScheduledRecordings.values()) {
if (r.getProgramId() == programId) {
- return r;
+ return r;
}
}
return null;
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 a9bfa97a..72bac8fc 100644
--- a/tests/common/src/com/android/tv/testing/dvr/RecordingTestUtils.java
+++ b/tests/common/src/com/android/tv/testing/dvr/RecordingTestUtils.java
@@ -17,40 +17,37 @@
package com.android.tv.testing.dvr;
import com.android.tv.dvr.data.ScheduledRecording;
-
import junit.framework.Assert;
-/**
- * Static utils for using {@link ScheduledRecording} in tests.
- */
+/** Static utils for using {@link ScheduledRecording} in tests. */
public final class RecordingTestUtils {
private static final String INPUT_ID = "input_id";
private static final int CHANNEL_ID = 273;
- public static ScheduledRecording createTestRecordingWithIdAndPeriod(long id, String inputId,
- long channelId, long startTime, long endTime) {
+ public static ScheduledRecording createTestRecordingWithIdAndPeriod(
+ long id, String inputId, long channelId, long startTime, long endTime) {
return ScheduledRecording.builder(inputId, channelId, startTime, endTime)
.setId(id)
.setChannelId(channelId)
.build();
}
- public static ScheduledRecording createTestRecordingWithPeriod(String inputId,
- long channelId, long startTime, long endTime) {
- return createTestRecordingWithIdAndPeriod(ScheduledRecording.ID_NOT_SET, inputId, channelId,
- startTime, endTime);
+ public static ScheduledRecording createTestRecordingWithPeriod(
+ String inputId, long channelId, long startTime, long endTime) {
+ return createTestRecordingWithIdAndPeriod(
+ ScheduledRecording.ID_NOT_SET, inputId, channelId, startTime, endTime);
}
- public static ScheduledRecording createTestRecordingWithPriorityAndPeriod(long channelId,
- long priority, long startTime, long endTime) {
+ public static ScheduledRecording createTestRecordingWithPriorityAndPeriod(
+ long channelId, long priority, long startTime, long endTime) {
return ScheduledRecording.builder(INPUT_ID, CHANNEL_ID, startTime, endTime)
.setChannelId(channelId)
.setPriority(priority)
.build();
}
- public static ScheduledRecording createTestRecordingWithIdAndPriorityAndPeriod(long id,
- long channelId, long priority, long startTime, long endTime) {
+ public static ScheduledRecording createTestRecordingWithIdAndPriorityAndPeriod(
+ long id, long channelId, long priority, long startTime, long endTime) {
return ScheduledRecording.builder(INPUT_ID, CHANNEL_ID, startTime, endTime)
.setId(id)
.setChannelId(channelId)
@@ -58,11 +55,12 @@ public final class RecordingTestUtils {
.build();
}
- public static ScheduledRecording normalizePriority(ScheduledRecording orig){
+ public static ScheduledRecording normalizePriority(ScheduledRecording orig) {
return ScheduledRecording.buildFrom(orig).setPriority(orig.getId()).build();
}
- public static void assertRecordingEquals(ScheduledRecording expected, ScheduledRecording actual) {
+ public static void assertRecordingEquals(
+ ScheduledRecording expected, ScheduledRecording actual) {
Assert.assertEquals("id", expected.getId(), actual.getId());
Assert.assertEquals("channel", expected.getChannelId(), actual.getChannelId());
Assert.assertEquals("programId", expected.getProgramId(), actual.getProgramId());
@@ -70,9 +68,11 @@ public final class RecordingTestUtils {
Assert.assertEquals("start time", expected.getStartTimeMs(), actual.getStartTimeMs());
Assert.assertEquals("end time", expected.getEndTimeMs(), actual.getEndTimeMs());
Assert.assertEquals("state", expected.getState(), actual.getState());
- Assert.assertEquals("parent series recording", expected.getSeriesRecordingId(),
+ Assert.assertEquals(
+ "parent series recording",
+ expected.getSeriesRecordingId(),
actual.getSeriesRecordingId());
}
- private RecordingTestUtils() { }
+ private RecordingTestUtils() {}
}
diff --git a/tests/common/src/com/android/tv/testing/robo/ContentProviders.java b/tests/common/src/com/android/tv/testing/robo/ContentProviders.java
new file mode 100644
index 00000000..aaaa11df
--- /dev/null
+++ b/tests/common/src/com/android/tv/testing/robo/ContentProviders.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2018 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.testing.robo;
+
+import android.content.ContentProvider;
+import android.content.pm.ProviderInfo;
+import org.robolectric.Robolectric;
+import org.robolectric.android.controller.ContentProviderController;
+import org.robolectric.shadows.ShadowContentResolver;
+
+/** Static utilities for using content providers in tests. */
+public final class ContentProviders {
+
+ /** Builds creates and register a ContentProvider with the given authority. */
+ public static <T extends ContentProvider> T register(Class<T> providerClass, String authority) {
+ ProviderInfo info = new ProviderInfo();
+ info.authority = authority;
+ ContentProviderController<T> contentProviderController =
+ Robolectric.buildContentProvider(providerClass);
+ T provider = contentProviderController.create(info).get();
+ provider.onCreate();
+ ShadowContentResolver.registerProviderInternal(authority, provider);
+ return provider;
+ }
+
+ private ContentProviders() {}
+}
diff --git a/tests/common/src/com/android/tv/testing/robo/RobotTestAppHelper.java b/tests/common/src/com/android/tv/testing/robo/RobotTestAppHelper.java
new file mode 100644
index 00000000..9eb79298
--- /dev/null
+++ b/tests/common/src/com/android/tv/testing/robo/RobotTestAppHelper.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2018 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.testing.robo;
+
+import android.media.tv.TvContract;
+import com.android.tv.testing.FakeTvProvider;
+import com.android.tv.testing.TestSingletonApp;
+import com.android.tv.testing.testdata.TestData;
+import java.util.concurrent.TimeUnit;
+import org.robolectric.Robolectric;
+
+/** Static utilities for using {@link TestSingletonApp} in roboletric tests. */
+public final class RobotTestAppHelper {
+
+ public static void loadTestData(TestSingletonApp app, TestData testData) {
+ ContentProviders.register(FakeTvProvider.class, TvContract.AUTHORITY);
+ app.loadTestData(testData, TimeUnit.DAYS.toMillis(1));
+ Robolectric.flushBackgroundThreadScheduler();
+ Robolectric.flushForegroundThreadScheduler();
+ }
+
+ private RobotTestAppHelper() {}
+}
diff --git a/tests/common/src/com/android/tv/testing/shadows/ShadowMediaSession.java b/tests/common/src/com/android/tv/testing/shadows/ShadowMediaSession.java
new file mode 100644
index 00000000..5a2c41e6
--- /dev/null
+++ b/tests/common/src/com/android/tv/testing/shadows/ShadowMediaSession.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2017 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.testing.shadows;
+
+import android.app.PendingIntent;
+import android.content.Context;
+import android.media.MediaMetadata;
+import android.media.session.MediaSession;
+import android.media.session.PlaybackState;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+
+/** Shadow {@link MediaSession}. */
+@Implements(MediaSession.class)
+public class ShadowMediaSession {
+
+ public MediaSession.Callback mCallback;
+ public PendingIntent mMediaButtonReceiver;
+ public PendingIntent mSessionActivity;
+ public PlaybackState mPlaybackState;
+ public MediaMetadata mMediaMetadata;
+ public int mFlags;
+ public boolean mActive;
+ public boolean mReleased;
+
+ /** Stand-in for the MediaSession constructor with the same parameters. */
+ public void __constructor__(Context context, String tag, int userID) {
+ // This empty method prevents the real MediaSession constructor from being called.
+ }
+
+ @Implementation
+ public void setCallback(MediaSession.Callback callback) {
+ mCallback = callback;
+ }
+
+ @Implementation
+ public void setMediaButtonReceiver(PendingIntent mbr) {
+ mMediaButtonReceiver = mbr;
+ }
+
+ @Implementation
+ public void setSessionActivity(PendingIntent activity) {
+ mSessionActivity = activity;
+ }
+
+ @Implementation
+ public void setPlaybackState(PlaybackState state) {
+ mPlaybackState = state;
+ }
+
+ @Implementation
+ public void setMetadata(MediaMetadata metadata) {
+ mMediaMetadata = metadata;
+ }
+
+ @Implementation
+ public void setFlags(int flags) {
+ mFlags = flags;
+ }
+
+ @Implementation
+ public boolean isActive() {
+ return mActive;
+ }
+
+ @Implementation
+ public void setActive(boolean active) {
+ mActive = active;
+ }
+
+ @Implementation
+ public void release() {
+ mReleased = true;
+ }
+}
diff --git a/tests/common/src/com/android/tv/testing/testdata/TestData.java b/tests/common/src/com/android/tv/testing/testdata/TestData.java
new file mode 100644
index 00000000..e7e52348
--- /dev/null
+++ b/tests/common/src/com/android/tv/testing/testdata/TestData.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2018 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.testing.testdata;
+
+import android.content.Context;
+import android.media.tv.TvInputInfo;
+import com.android.tv.common.util.Clock;
+import com.android.tv.testing.data.ChannelInfo;
+import com.android.tv.testing.data.ChannelUtils;
+import com.android.tv.testing.data.ProgramUtils;
+import com.android.tv.testing.utils.TestUtils;
+import java.util.List;
+
+/**
+ * A set of test data.
+ *
+ * <p>contains:
+ *
+ * <ul>
+ * <li>InputID
+ * <li>Channel List
+ * </ul>
+ *
+ * Call {@link #init(Context)}, to update the TvProvider data base with the given values.
+ */
+public abstract class TestData {
+ private List<ChannelInfo> channelList;
+
+ protected abstract List<ChannelInfo> createChannels(Context context);
+
+ public void init(Context context, Clock clock, long durationMs) {
+ channelList = createChannels(context);
+ ChannelUtils.updateChannels(context, getInputId(), channelList);
+ ProgramUtils.updateProgramForAllChannelsOf(context, getInputId(), clock, durationMs);
+ }
+
+ public abstract TvInputInfo getTvInputInfo();
+
+ public final String getInputId() {
+ return getTvInputInfo().getId();
+ }
+
+ public static final TestData DEFAULT_10_CHANNELS =
+ new TestData() {
+ private TvInputInfo mTvInputInfo = createTvInputInfo();
+
+ private TvInputInfo createTvInputInfo() {
+ try {
+ return TestUtils.createTvInputInfo(
+ TestUtils.createResolveInfo(
+ "com.android.tv.testing.testdata",
+ "com.android.tv.testing.testdata.Default10Channels"),
+ "com.android.tv.testing.testdata/.Default10Channels",
+ null,
+ TvInputInfo.TYPE_TUNER,
+ true);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ protected List<ChannelInfo> createChannels(Context context) {
+ return ChannelUtils.createChannelInfos(context, 10);
+ }
+
+ @Override
+ public TvInputInfo getTvInputInfo() {
+ return mTvInputInfo;
+ }
+ };
+}
diff --git a/tests/common/src/com/android/tv/testing/testinput/ChannelState.java b/tests/common/src/com/android/tv/testing/testinput/ChannelState.java
index 1b8f63cd..3e8bab33 100644
--- a/tests/common/src/com/android/tv/testing/testinput/ChannelState.java
+++ b/tests/common/src/com/android/tv/testing/testinput/ChannelState.java
@@ -16,24 +16,16 @@
package com.android.tv.testing.testinput;
import android.media.tv.TvTrackInfo;
-
-import com.android.tv.testing.Constants;
-
+import com.android.tv.testing.constants.Constants;
import java.util.Collections;
import java.util.List;
-/**
- * Versioned state information for a channel.
- */
+/** Versioned state information for a channel. */
public class ChannelState {
- /**
- * The video track a channel has by default.
- */
+ /** The video track a channel has by default. */
public static final TvTrackInfo DEFAULT_VIDEO_TRACK = Constants.FHD1080P50_VIDEO_TRACK;
- /**
- * The video track a channel has by default.
- */
+ /** The video track a channel has by default. */
public static final TvTrackInfo DEFAULT_AUDIO_TRACK = Constants.EN_STEREO_AUDIO_TRACK;
/**
* The channel is "tuned" and video available.
@@ -47,27 +39,23 @@ public class ChannelState {
* Default ChannelState with version @{value #CHANNEL_VERSION_DEFAULT} and default {@link
* ChannelStateData}.
*/
- public static final ChannelState DEFAULT = new ChannelState(CHANNEL_VERSION_DEFAULT,
- new ChannelStateData());
+ public static final ChannelState DEFAULT =
+ new ChannelState(CHANNEL_VERSION_DEFAULT, new ChannelStateData());
+
private final int mVersion;
private final ChannelStateData mData;
-
private ChannelState(int version, ChannelStateData channelStateData) {
mVersion = version;
mData = channelStateData;
}
- /**
- * Returns the id of the selected audio track, or null if none is selected.
- */
+ /** Returns the id of the selected audio track, or null if none is selected. */
public String getSelectedAudioTrackId() {
return mData.mSelectedAudioTrackId;
}
- /**
- * Returns the id of the selected audio track, or null if none is selected.
- */
+ /** Returns the id of the selected audio track, or null if none is selected. */
public String getSelectedVideoTrackId() {
return mData.mSelectedVideoTrackId;
}
@@ -82,9 +70,8 @@ public class ChannelState {
}
/**
- * Tune status is either {@link #TUNE_STATUS_VIDEO_AVAILABLE} or a {@link
- * android.media.tv.TvInputService.Session#notifyVideoUnavailable(int) video unavailable
- * reason}
+ * Tune status is either {@link #TUNE_STATUS_VIDEO_AVAILABLE} or a {@link
+ * android.media.tv.TvInputService.Session#notifyVideoUnavailable(int) video unavailable reason}
*/
public int getTuneStatus() {
return mData.mTuneStatus;
diff --git a/tests/common/src/com/android/tv/testing/testinput/ChannelStateData.java b/tests/common/src/com/android/tv/testing/testinput/ChannelStateData.java
index 9bac9d12..cdeb1f5c 100644
--- a/tests/common/src/com/android/tv/testing/testinput/ChannelStateData.java
+++ b/tests/common/src/com/android/tv/testing/testinput/ChannelStateData.java
@@ -19,25 +19,23 @@ package com.android.tv.testing.testinput;
import android.media.tv.TvTrackInfo;
import android.os.Parcel;
import android.os.Parcelable;
-
import java.util.ArrayList;
import java.util.List;
-/**
- * Mutable unversioned channel state.
- */
+/** Mutable unversioned channel state. */
public final class ChannelStateData implements Parcelable {
- public static final Creator<ChannelStateData> CREATOR = new Creator<ChannelStateData>() {
- @Override
- public ChannelStateData createFromParcel(Parcel in) {
- return new ChannelStateData(in);
- }
+ public static final Creator<ChannelStateData> CREATOR =
+ new Creator<ChannelStateData>() {
+ @Override
+ public ChannelStateData createFromParcel(Parcel in) {
+ return new ChannelStateData(in);
+ }
- @Override
- public ChannelStateData[] newArray(int size) {
- return new ChannelStateData[size];
- }
- };
+ @Override
+ public ChannelStateData[] newArray(int size) {
+ return new ChannelStateData[size];
+ }
+ };
public final List<TvTrackInfo> mTvTrackInfos = new ArrayList<>();
public int mTuneStatus = ChannelState.TUNE_STATUS_VIDEO_AVAILABLE;
@@ -71,9 +69,6 @@ public final class ChannelStateData implements Parcelable {
@Override
public String toString() {
- return "{"
- + "tune=" + mTuneStatus
- + ", tracks=" + mTvTrackInfos
- + "}";
+ return "{" + "tune=" + mTuneStatus + ", tracks=" + mTvTrackInfos + "}";
}
}
diff --git a/tests/common/src/com/android/tv/testing/testinput/TestInputControlConnection.java b/tests/common/src/com/android/tv/testing/testinput/TestInputControlConnection.java
index 9b3f8835..071b1d3c 100644
--- a/tests/common/src/com/android/tv/testing/testinput/TestInputControlConnection.java
+++ b/tests/common/src/com/android/tv/testing/testinput/TestInputControlConnection.java
@@ -21,8 +21,7 @@ import android.os.IBinder;
import android.os.RemoteException;
import android.os.SystemClock;
import android.util.Log;
-
-import com.android.tv.testing.ChannelInfo;
+import com.android.tv.testing.data.ChannelInfo;
/**
* Connection for controlling the Test TV Input Service.
@@ -47,9 +46,7 @@ public class TestInputControlConnection implements ServiceConnection {
mControl = null;
}
- /**
- * Is the service currently connected.
- */
+ /** Is the service currently connected. */
public boolean isBound() {
return mControl != null;
}
@@ -58,7 +55,7 @@ public class TestInputControlConnection implements ServiceConnection {
* Update the state of the channel.
*
* @param channel the channel to update.
- * @param data the new state for the channel.
+ * @param data the new state for the channel.
*/
public void updateChannelState(ChannelInfo channel, ChannelStateData data) {
waitUntilBound();
@@ -69,9 +66,7 @@ public class TestInputControlConnection implements ServiceConnection {
}
}
- /**
- * Sleep until {@link #isBound()} is true;
- */
+ /** Sleep until {@link #isBound()} is true; */
public void waitUntilBound() {
while (!isBound()) {
SystemClock.sleep(BOUND_CHECK_INTERVAL_MS);
diff --git a/tests/common/src/com/android/tv/testing/testinput/TestInputControlUtils.java b/tests/common/src/com/android/tv/testing/testinput/TestInputControlUtils.java
index 54aacf20..330afa9b 100644
--- a/tests/common/src/com/android/tv/testing/testinput/TestInputControlUtils.java
+++ b/tests/common/src/com/android/tv/testing/testinput/TestInputControlUtils.java
@@ -18,16 +18,16 @@ package com.android.tv.testing.testinput;
import android.content.ComponentName;
import android.content.Intent;
-/**
- * Static utils for {@link ITestInputControl}.
- */
+/** Static utils for {@link ITestInputControl}. */
public final class TestInputControlUtils {
public static Intent createIntent() {
- return new Intent().setComponent(new ComponentName("com.android.tv.testinput",
- "com.android.tv.testinput.TestInputControlService"));
+ return new Intent()
+ .setComponent(
+ new ComponentName(
+ "com.android.tv.testinput",
+ "com.android.tv.testinput.TestInputControlService"));
}
- private TestInputControlUtils() {
- }
+ private TestInputControlUtils() {}
}
diff --git a/tests/common/src/com/android/tv/testing/testinput/TvTestInputConstants.java b/tests/common/src/com/android/tv/testing/testinput/TvTestInputConstants.java
index 498addfd..27d3036c 100644
--- a/tests/common/src/com/android/tv/testing/testinput/TvTestInputConstants.java
+++ b/tests/common/src/com/android/tv/testing/testinput/TvTestInputConstants.java
@@ -15,25 +15,22 @@
*/
package com.android.tv.testing.testinput;
-import com.android.tv.testing.ChannelInfo;
+import com.android.tv.testing.data.ChannelInfo;
-/**
- * Constants for interacting with TvTestInput.
- */
+/** Constants for interacting with TvTestInput. */
public final class TvTestInputConstants {
/**
* Channel 1.
*
- * <p> By convention Channel 1 should not be changed. Test often start by tuning to this
- * channel.
+ * <p>By convention Channel 1 should not be changed. Test often start by tuning to this channel.
*/
public static final ChannelInfo CH_1_DEFAULT_DONT_MODIFY = ChannelInfo.create(null, 1);
/**
* Channel 2.
*
- * <p> By convention the state of Channel 2 is changed by tests. Testcases should explicitly
- * set the state of this channel before using it in tests.
+ * <p>By convention the state of Channel 2 is changed by tests. Testcases should explicitly set
+ * the state of this channel before using it in tests.
*/
public static final ChannelInfo CH_2 = ChannelInfo.create(null, 2);
}
diff --git a/tests/common/src/com/android/tv/testing/uihelper/BaseUiDeviceHelper.java b/tests/common/src/com/android/tv/testing/uihelper/BaseUiDeviceHelper.java
index 3a2f5509..21b05d67 100644
--- a/tests/common/src/com/android/tv/testing/uihelper/BaseUiDeviceHelper.java
+++ b/tests/common/src/com/android/tv/testing/uihelper/BaseUiDeviceHelper.java
@@ -18,9 +18,7 @@ package com.android.tv.testing.uihelper;
import android.content.res.Resources;
import android.support.test.uiautomator.UiDevice;
-/**
- * Base class for building UiAutomator Helper classes.
- */
+/** Base class for building UiAutomator Helper classes. */
public abstract class BaseUiDeviceHelper {
protected final UiDevice mUiDevice;
protected final Resources mTargetResources;
diff --git a/tests/common/src/com/android/tv/testing/uihelper/ByResource.java b/tests/common/src/com/android/tv/testing/uihelper/ByResource.java
index a76ee1d3..47b8d9f9 100644
--- a/tests/common/src/com/android/tv/testing/uihelper/ByResource.java
+++ b/tests/common/src/com/android/tv/testing/uihelper/ByResource.java
@@ -19,9 +19,7 @@ import android.content.res.Resources;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.BySelector;
-/**
- * Convenience methods for creating {@link BySelector}s using resource ids.
- */
+/** Convenience methods for creating {@link BySelector}s using resource ids. */
public final class ByResource {
/**
@@ -44,6 +42,5 @@ public final class ByResource {
return By.text(text);
}
- private ByResource() {
- }
+ private ByResource() {}
}
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 8dd8e14a..4b522914 100644
--- a/tests/common/src/com/android/tv/testing/uihelper/Constants.java
+++ b/tests/common/src/com/android/tv/testing/uihelper/Constants.java
@@ -17,6 +17,7 @@ package com.android.tv.testing.uihelper;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.BySelector;
+import com.android.tv.common.CommonConstants;
public final class Constants {
@@ -24,7 +25,7 @@ public final class Constants {
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 String TV_APP_PACKAGE = CommonConstants.BASE_PACKAGE;
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");
public static final BySelector KEYPAD_CHANNEL_SWITCH = By.res(TV_APP_PACKAGE, "channel_number");
@@ -35,6 +36,5 @@ public final class Constants {
public static final BySelector DVR_SCHEDULES = By.res(TV_APP_PACKAGE, "dvr_schedules");
public static final BySelector FOCUSED_VIEW = By.focused(true);
- private Constants() {
- }
+ private Constants() {}
}
diff --git a/tests/common/src/com/android/tv/testing/uihelper/DialogHelper.java b/tests/common/src/com/android/tv/testing/uihelper/DialogHelper.java
index 9e4040a8..2ac4b648 100644
--- a/tests/common/src/com/android/tv/testing/uihelper/DialogHelper.java
+++ b/tests/common/src/com/android/tv/testing/uihelper/DialogHelper.java
@@ -24,12 +24,9 @@ import android.content.res.Resources;
import android.support.test.uiautomator.BySelector;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.Until;
-
import com.android.tv.R;
-/**
- * Helper for testing {@link DialogFragment}s.
- */
+/** Helper for testing {@link DialogFragment}s. */
public class DialogHelper extends BaseUiDeviceHelper {
private final BySelector byPinDialog;
@@ -39,7 +36,9 @@ public class DialogHelper extends BaseUiDeviceHelper {
}
public void assertWaitForPinDialogOpen() {
- assertWaitForCondition(mUiDevice, Until.hasObject(byPinDialog),
+ assertWaitForCondition(
+ mUiDevice,
+ Until.hasObject(byPinDialog),
Constants.MAX_SHOW_DELAY_MILLIS
+ mTargetResources.getInteger(R.integer.pin_dialog_anim_duration));
}
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 1dc0f020..4b7c1f89 100644
--- a/tests/common/src/com/android/tv/testing/uihelper/LiveChannelsUiDeviceHelper.java
+++ b/tests/common/src/com/android/tv/testing/uihelper/LiveChannelsUiDeviceHelper.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright (C) 2017 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.testing.uihelper;
import static com.android.tv.testing.uihelper.UiDeviceAsserts.waitForCondition;
@@ -11,31 +26,28 @@ import android.support.test.uiautomator.BySelector;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.Until;
import android.util.Log;
-
-import com.android.tv.testing.Utils;
-
+import com.android.tv.common.CommonConstants;
+import com.android.tv.testing.utils.Utils;
import junit.framework.Assert;
-/**
- * Helper for testing the Live TV Application.
- */
+/** Helper for testing the Live TV Application. */
public class LiveChannelsUiDeviceHelper extends BaseUiDeviceHelper {
private static final String TAG = "LiveChannelsUiDevice";
private static final int APPLICATION_START_TIMEOUT_MSEC = 5000;
private final Context mContext;
- public LiveChannelsUiDeviceHelper(UiDevice uiDevice, Resources targetResources,
- Context context) {
+ public LiveChannelsUiDeviceHelper(
+ UiDevice uiDevice, Resources targetResources, Context context) {
super(uiDevice, targetResources);
mContext = context;
}
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
+ Intent intent =
+ mContext.getPackageManager().getLaunchIntentForPackage(Constants.TV_APP_PACKAGE);
+ intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); // Clear out any previous instances
mContext.startActivity(intent);
// Wait for idle state before checking the channel banner because waitForCondition() has
// timeout.
@@ -43,8 +55,10 @@ public class LiveChannelsUiDeviceHelper extends BaseUiDeviceHelper {
// Make sure that the activity is resumed.
waitForCondition(mUiDevice, Until.hasObject(Constants.TV_VIEW));
- Assert.assertTrue(Constants.TV_APP_PACKAGE + " did not start", mUiDevice
- .wait(Until.hasObject(By.pkg(Constants.TV_APP_PACKAGE).depth(0)),
+ Assert.assertTrue(
+ Constants.TV_APP_PACKAGE + " did not start",
+ mUiDevice.wait(
+ Until.hasObject(By.pkg(Constants.TV_APP_PACKAGE).depth(0)),
APPLICATION_START_TIMEOUT_MSEC));
BySelector welcome = ByResource.id(mTargetResources, com.android.tv.R.id.intro);
if (mUiDevice.hasObject(welcome)) {
@@ -54,9 +68,9 @@ public class LiveChannelsUiDeviceHelper extends BaseUiDeviceHelper {
}
public void assertAppStopped() {
- while(mUiDevice.hasObject(By.pkg(Constants.TV_APP_PACKAGE).depth(0))) {
+ while (mUiDevice.hasObject(By.pkg(CommonConstants.BASE_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 80d53242..c8ea85ac 100644
--- a/tests/common/src/com/android/tv/testing/uihelper/MenuHelper.java
+++ b/tests/common/src/com/android/tv/testing/uihelper/MenuHelper.java
@@ -25,33 +25,30 @@ import android.support.test.uiautomator.Direction;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject2;
import android.support.test.uiautomator.Until;
-
import com.android.tv.R;
-
import junit.framework.Assert;
-/**
- * Helper for testing {@link com.android.tv.menu.Menu}.
- */
+/** Helper for testing {@link com.android.tv.menu.Menu}. */
public class MenuHelper extends BaseUiDeviceHelper {
private final BySelector byChannels;
public MenuHelper(UiDevice uiDevice, Resources targetResources) {
super(uiDevice, targetResources);
- byChannels = ByResource.id(mTargetResources, R.id.item_list)
- .hasDescendant(ByResource.text(mTargetResources, R.string.menu_title_channels));
+ byChannels =
+ ByResource.id(mTargetResources, R.id.item_list)
+ .hasDescendant(
+ ByResource.text(mTargetResources, R.string.menu_title_channels));
}
public BySelector getByChannels() {
return byChannels;
}
-
/**
- * Navigate to the menu item with the text {@code itemTextResId} in the row with text
- * {@code rowTitleResId}.
- * <p>
- * Fails if the menu item can not be navigated to.
+ * Navigate to the menu item with the text {@code itemTextResId} in the row with text {@code
+ * rowTitleResId}.
+ *
+ * <p>Fails if the menu item can not be navigated to.
*
* @param rowTitleResId the resource id of the string in the desired row title.
* @param itemTextResId the resource id of the string in the desired item.
@@ -62,17 +59,20 @@ public class MenuHelper extends BaseUiDeviceHelper {
BySelector byListView = ByResource.id(mTargetResources, R.id.list_view);
UiObject2 listView = row.findObject(byListView);
Assert.assertNotNull(
- "Menu row '" + mTargetResources.getString(rowTitleResId) + "' does not have a "
- + byListView, listView);
+ "Menu row '"
+ + mTargetResources.getString(rowTitleResId)
+ + "' does not have a "
+ + byListView,
+ listView);
return assertNavigateToRowItem(listView, itemTextResId);
}
/**
* Navigate to the menu row with the text title {@code rowTitleResId}.
- * <p>
- * Fails if the menu row can not be navigated to.
- * We can't navigate to the Play controls row with this method, because the row doesn't have the
- * title when it is selected. Use {@link #assertNavigateToPlayControlsRow} for the row instead.
+ *
+ * <p>Fails if the menu row can not be navigated to. We can't navigate to the Play controls row
+ * with this method, because the row doesn't have the title when it is selected. Use {@link
+ * #assertNavigateToPlayControlsRow} for the row instead.
*
* @param rowTitleResId the resource id of the string in the desired row title.
* @return the row navigated to.
@@ -82,14 +82,17 @@ public class MenuHelper extends BaseUiDeviceHelper {
UiObject2 menu = mUiDevice.findObject(MENU);
// TODO: handle play controls. They have a different dom structure and navigation sometimes
// can get stuck on that row.
- return UiDeviceAsserts.assertNavigateTo(mUiDevice, menu,
- By.hasDescendant(ByResource.text(mTargetResources, rowTitleResId)), Direction.DOWN);
+ return UiDeviceAsserts.assertNavigateTo(
+ mUiDevice,
+ menu,
+ By.hasDescendant(ByResource.text(mTargetResources, rowTitleResId)),
+ Direction.DOWN);
}
/**
* Navigate to the Play controls row.
- * <p>
- * Fails if the row can not be navigated to.
+ *
+ * <p>Fails if the row can not be navigated to.
*
* @see #assertNavigateToRow
*/
@@ -103,27 +106,28 @@ public class MenuHelper extends BaseUiDeviceHelper {
/**
* Navigate to the menu item in the given {@code row} with the text {@code itemTextResId} .
- * <p>
- * Fails if the menu item can not be navigated to.
*
- * @param row the container to look for menu items in.
+ * <p>Fails if the menu item can not be navigated to.
+ *
+ * @param row the container to look for menu items in.
* @param itemTextResId the resource id of the string in the desired item.
* @return the item navigated to.
*/
public UiObject2 assertNavigateToRowItem(UiObject2 row, int itemTextResId) {
- return UiDeviceAsserts.assertNavigateTo(mUiDevice, row,
+ return UiDeviceAsserts.assertNavigateTo(
+ mUiDevice,
+ row,
By.hasDescendant(ByResource.text(mTargetResources, itemTextResId)),
Direction.RIGHT);
}
public UiObject2 assertPressOptionsSettings() {
- return assertPressMenuItem(R.string.menu_title_options,
- R.string.options_item_settings);
+ return assertPressMenuItem(R.string.menu_title_options, R.string.options_item_settings);
}
public UiObject2 assertPressOptionsClosedCaptions() {
- return assertPressMenuItem(R.string.menu_title_options,
- R.string.options_item_closed_caption);
+ return assertPressMenuItem(
+ R.string.menu_title_options, R.string.options_item_closed_caption);
}
public UiObject2 assertPressOptionsDisplayMode() {
@@ -135,20 +139,19 @@ public class MenuHelper extends BaseUiDeviceHelper {
}
public UiObject2 assertPressProgramGuide() {
- return assertPressMenuItem(R.string.menu_title_channels,
- R.string.channels_item_program_guide);
+ return assertPressMenuItem(
+ R.string.menu_title_channels, R.string.channels_item_program_guide);
}
public UiObject2 assertPressDvrLibrary() {
- return assertPressMenuItem(R.string.menu_title_channels,
- R.string.channels_item_dvr);
+ 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}.
- * <p>
- * Fails if the menu item can not be navigated to.
+ * Navigate to the menu item with the text {@code itemTextResId} in the row with text {@code
+ * rowTitleResId}.
+ *
+ * <p>Fails if the menu item can not be navigated to.
*
* @param rowTitleResId the resource id of the string in the desired row title.
* @param itemTextResId the resource id of the string in the desired item.
@@ -161,17 +164,15 @@ public class MenuHelper extends BaseUiDeviceHelper {
return item;
}
- /**
- * Waits until the menu is visible.
- */
+ /** Waits until the menu is visible. */
public void assertWaitForMenu() {
UiDeviceAsserts.assertWaitForCondition(mUiDevice, Until.hasObject(MENU));
}
/**
- * Show the menu.
- * <p>
- * Fails if the menu does not appear in {@link Constants#MAX_SHOW_DELAY_MILLIS}.
+ * Show the menu.
+ *
+ * <p>Fails if the menu does not appear in {@link Constants#MAX_SHOW_DELAY_MILLIS}.
*/
public void showMenu() {
if (!mUiDevice.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 98a19a41..ba015260 100644
--- a/tests/common/src/com/android/tv/testing/uihelper/SidePanelHelper.java
+++ b/tests/common/src/com/android/tv/testing/uihelper/SidePanelHelper.java
@@ -22,15 +22,11 @@ import android.support.test.uiautomator.BySelector;
import android.support.test.uiautomator.Direction;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject2;
-
import com.android.tv.R;
import com.android.tv.ui.sidepanel.SideFragment;
-
import junit.framework.Assert;
-/**
- * Helper for testing {@link SideFragment}s.
- */
+/** Helper for testing {@link SideFragment}s. */
public class SidePanelHelper extends BaseUiDeviceHelper {
public SidePanelHelper(UiDevice uiDevice, Resources targetResources) {
@@ -54,6 +50,7 @@ public class SidePanelHelper extends BaseUiDeviceHelper {
String title = mTargetResources.getString(resId);
return assertNavigateToItem(title, direction);
}
+
public UiObject2 assertNavigateToItem(String title) {
return assertNavigateToItem(title, Direction.DOWN);
}
@@ -63,7 +60,7 @@ public class SidePanelHelper extends BaseUiDeviceHelper {
UiObject2 sidePanelList = mUiDevice.findObject(sidePanelSelector);
Assert.assertNotNull(sidePanelSelector + " not found", sidePanelList);
- return UiDeviceAsserts.assertNavigateTo(mUiDevice, sidePanelList,
- By.hasDescendant(By.text(title)), direction);
+ 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 c096d7d2..28ea163e 100644
--- a/tests/common/src/com/android/tv/testing/uihelper/UiDeviceAsserts.java
+++ b/tests/common/src/com/android/tv/testing/uihelper/UiDeviceAsserts.java
@@ -27,12 +27,9 @@ import android.support.test.uiautomator.SearchCondition;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject2;
import android.support.test.uiautomator.Until;
-
import junit.framework.Assert;
-/**
- * Asserts for {@link UiDevice}s.
- */
+/** Asserts for {@link UiDevice}s. */
public final class UiDeviceAsserts {
public static void assertHas(UiDevice uiDevice, BySelector bySelector, boolean expected) {
@@ -46,25 +43,25 @@ public final class UiDeviceAsserts {
}
/**
- * Assert that {@code searchCondition} becomes true within
- * {@value Constants#MAX_SHOW_DELAY_MILLIS} milliseconds.
+ * Assert that {@code searchCondition} becomes true within {@value
+ * Constants#MAX_SHOW_DELAY_MILLIS} milliseconds.
*
- * @param uiDevice the device under test.
+ * @param uiDevice the device under test.
* @param searchCondition the condition to wait for.
*/
- public static void assertWaitForCondition(UiDevice uiDevice,
- SearchCondition<Boolean> searchCondition) {
+ public static void assertWaitForCondition(
+ UiDevice uiDevice, SearchCondition<Boolean> searchCondition) {
assertWaitForCondition(uiDevice, searchCondition, Constants.MAX_SHOW_DELAY_MILLIS);
}
/**
* Assert that {@code searchCondition} becomes true within {@code timeout} milliseconds.
*
- * @param uiDevice the device under test.
+ * @param uiDevice the device under test.
* @param searchCondition the condition to wait for.
*/
- public static void assertWaitForCondition(UiDevice uiDevice,
- SearchCondition<Boolean> searchCondition, long timeout) {
+ public static void assertWaitForCondition(
+ UiDevice uiDevice, SearchCondition<Boolean> searchCondition, long timeout) {
boolean result = waitForCondition(uiDevice, searchCondition, timeout);
assertTrue(searchCondition + " not true after " + timeout / 1000.0 + " seconds.", result);
}
@@ -72,52 +69,55 @@ public final class UiDeviceAsserts {
/**
* Wait until {@code searchCondition} becomes true.
*
- * @param uiDevice The device under test.
+ * @param uiDevice The device under test.
* @param searchCondition The condition to wait for.
* @return {@code true} if the condition is met, otherwise {@code false}.
*/
- public static boolean waitForCondition(UiDevice uiDevice,
- SearchCondition<Boolean> searchCondition) {
+ public static boolean waitForCondition(
+ UiDevice uiDevice, SearchCondition<Boolean> searchCondition) {
return waitForCondition(uiDevice, searchCondition, Constants.MAX_SHOW_DELAY_MILLIS);
}
- private static boolean waitForCondition(UiDevice uiDevice,
- SearchCondition<Boolean> searchCondition, long timeout) {
- long adjustedTimeout = timeout + Math.max(Constants.MIN_EXTRA_TIMEOUT,
- (long) (timeout * Constants.EXTRA_TIMEOUT_PERCENT));
+ private static boolean waitForCondition(
+ UiDevice uiDevice, SearchCondition<Boolean> searchCondition, long timeout) {
+ long adjustedTimeout =
+ timeout
+ + Math.max(
+ Constants.MIN_EXTRA_TIMEOUT,
+ (long) (timeout * Constants.EXTRA_TIMEOUT_PERCENT));
return uiDevice.wait(searchCondition, adjustedTimeout);
}
/**
* Navigates through the focus items in a container returning the container child that has a
* descendant matching the {@code selector}.
- * <p>
- * The navigation starts in the {@code direction} specified and
- * {@link Direction#reverse(Direction) reverses} once if needed. Fails if there is not a
- * focused
- * descendant, or if after completing both directions no focused child has a descendant
- * matching
+ *
+ * <p>The navigation starts in the {@code direction} specified and {@link
+ * Direction#reverse(Direction) reverses} once if needed. Fails if there is not a focused
+ * descendant, or if after completing both directions no focused child has a descendant matching
* {@code selector}.
- * <p>
- * Fails if the menu item can not be navigated to.
*
- * @param uiDevice the device under test.
+ * <p>Fails if the menu item can not be navigated to.
+ *
+ * @param uiDevice the device under test.
* @param container contains children to navigate over.
- * @param selector the selector for the object to navigate to.
+ * @param selector the selector for the object to navigate to.
* @param direction the direction to start navigating.
* @return the object navigated to.
*/
- public static UiObject2 assertNavigateTo(UiDevice uiDevice, UiObject2 container,
- BySelector selector, Direction direction) {
+ public static UiObject2 assertNavigateTo(
+ UiDevice uiDevice, UiObject2 container, BySelector selector, Direction direction) {
int count = 0;
while (count < 2) {
BySelector hasFocusedDescendant = By.hasDescendant(FOCUSED_VIEW);
UiObject2 focusedChild = null;
- SearchCondition<Boolean> untilHasFocusedDescendant = Until
- .hasObject(hasFocusedDescendant);
+ SearchCondition<Boolean> untilHasFocusedDescendant =
+ Until.hasObject(hasFocusedDescendant);
- boolean result = container.wait(untilHasFocusedDescendant,
- UiObject2Asserts.getAdjustedTimeout(Constants.MAX_SHOW_DELAY_MILLIS));
+ boolean result =
+ container.wait(
+ untilHasFocusedDescendant,
+ UiObject2Asserts.getAdjustedTimeout(Constants.MAX_SHOW_DELAY_MILLIS));
if (!result) {
// HACK: Try direction anyways because play control does not always have a
// focused item.
@@ -147,6 +147,5 @@ public final class UiDeviceAsserts {
return null;
}
- private UiDeviceAsserts() {
- }
+ private UiDeviceAsserts() {}
}
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 98eff906..d5545023 100644
--- a/tests/common/src/com/android/tv/testing/uihelper/UiDeviceUtils.java
+++ b/tests/common/src/com/android/tv/testing/uihelper/UiDeviceUtils.java
@@ -15,21 +15,11 @@
*/
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;
-/**
- * Static utility methods for {@link UiDevice}.
- */
+/** Static utility methods for {@link UiDevice}. */
public final class UiDeviceUtils {
public static void pressDpad(UiDevice uiDevice, Direction direction) {
@@ -51,7 +41,6 @@ public final class UiDeviceUtils {
}
}
-
public static void pressKeys(UiDevice uiDevice, int... keyCodes) {
for (int k : keyCodes) {
uiDevice.pressKeyCode(k);
@@ -60,8 +49,8 @@ public final class UiDeviceUtils {
/**
* Parses the string and sends the corresponding individual key presses.
- * <p>
- * <b>Note:</b> only handles 0-9, '.', and '-'.
+ *
+ * <p><b>Note:</b> only handles 0-9, '.', and '-'.
*/
public static void pressKeys(UiDevice uiDevice, String keys) {
for (char c : keys.toCharArray()) {
@@ -77,59 +66,5 @@ 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() {
- }
+ private UiDeviceUtils() {}
}
diff --git a/tests/common/src/com/android/tv/testing/uihelper/UiObject2Asserts.java b/tests/common/src/com/android/tv/testing/uihelper/UiObject2Asserts.java
index aba29f0e..ee02d7f7 100644
--- a/tests/common/src/com/android/tv/testing/uihelper/UiObject2Asserts.java
+++ b/tests/common/src/com/android/tv/testing/uihelper/UiObject2Asserts.java
@@ -20,41 +20,40 @@ import static junit.framework.Assert.assertTrue;
import android.support.test.uiautomator.SearchCondition;
import android.support.test.uiautomator.UiObject2;
-/**
- * Asserts for {@link UiObject2}s.
- */
+/** Asserts for {@link UiObject2}s. */
public final class UiObject2Asserts {
/**
- * Assert that {@code searchCondition} becomes true within
- * {@value Constants#MAX_SHOW_DELAY_MILLIS} milliseconds.
+ * Assert that {@code searchCondition} becomes true within {@value
+ * Constants#MAX_SHOW_DELAY_MILLIS} milliseconds.
*
- * @param uiObject the device under test.
+ * @param uiObject the device under test.
* @param searchCondition the condition to wait for.
*/
- public static void assertWaitForCondition(UiObject2 uiObject,
- SearchCondition<Boolean> searchCondition) {
+ public static void assertWaitForCondition(
+ UiObject2 uiObject, SearchCondition<Boolean> searchCondition) {
assertWaitForCondition(uiObject, searchCondition, Constants.MAX_SHOW_DELAY_MILLIS);
}
/**
* Assert that {@code searchCondition} becomes true within {@code timeout} milliseconds.
*
- * @param uiObject the device under test.
+ * @param uiObject the device under test.
* @param searchCondition the condition to wait for.
*/
- public static void assertWaitForCondition(UiObject2 uiObject,
- SearchCondition<Boolean> searchCondition, long timeout) {
+ public static void assertWaitForCondition(
+ UiObject2 uiObject, SearchCondition<Boolean> searchCondition, long timeout) {
long adjustedTimeout = getAdjustedTimeout(timeout);
boolean result = uiObject.wait(searchCondition, adjustedTimeout);
assertTrue(searchCondition + " not true after " + timeout / 1000.0 + " seconds.", result);
}
public static long getAdjustedTimeout(long timeout) {
- return timeout + Math.max(
- Constants.MIN_EXTRA_TIMEOUT, (long) (timeout * Constants.EXTRA_TIMEOUT_PERCENT));
+ return timeout
+ + Math.max(
+ Constants.MIN_EXTRA_TIMEOUT,
+ (long) (timeout * Constants.EXTRA_TIMEOUT_PERCENT));
}
- private UiObject2Asserts() {
- }
+ private UiObject2Asserts() {}
}
diff --git a/tests/common/src/com/android/tv/testing/uihelper/UiObject2Utils.java b/tests/common/src/com/android/tv/testing/uihelper/UiObject2Utils.java
index 2a997a67..2f3779c5 100644
--- a/tests/common/src/com/android/tv/testing/uihelper/UiObject2Utils.java
+++ b/tests/common/src/com/android/tv/testing/uihelper/UiObject2Utils.java
@@ -19,9 +19,7 @@ import android.graphics.Point;
import android.support.test.uiautomator.Direction;
import android.support.test.uiautomator.UiObject2;
-/**
- * Static utility methods for {@link UiObject2}s.
- */
+/** Static utility methods for {@link UiObject2}s. */
public class UiObject2Utils {
public static boolean hasSiblingInDirection(UiObject2 theUiObject, Direction direction) {
@@ -56,6 +54,5 @@ public class UiObject2Utils {
return false;
}
- private UiObject2Utils() {
- }
+ private UiObject2Utils() {}
}
diff --git a/tests/common/src/com/android/tv/testing/utils/TestUtils.java b/tests/common/src/com/android/tv/testing/utils/TestUtils.java
new file mode 100644
index 00000000..6604c9ad
--- /dev/null
+++ b/tests/common/src/com/android/tv/testing/utils/TestUtils.java
@@ -0,0 +1,193 @@
+/*
+ * 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.testing.utils;
+
+import android.content.pm.ApplicationInfo;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.graphics.drawable.Icon;
+import android.hardware.hdmi.HdmiDeviceInfo;
+import android.media.tv.TvInputInfo;
+import android.os.Build;
+import android.os.Bundle;
+import java.lang.reflect.Constructor;
+
+/** A class that includes convenience methods for testing. */
+public class TestUtils {
+ /** Creates a {@link TvInputInfo}. */
+ public static TvInputInfo createTvInputInfo(
+ ResolveInfo service, String id, String parentId, int type, boolean isHardwareInput)
+ throws Exception {
+ return createTvInputInfo(service, id, parentId, type, isHardwareInput, false, 0);
+ }
+
+ /**
+ * Creates a {@link TvInputInfo}.
+ *
+ * <p>If this is called on MNC, {@code canRecord} and {@code tunerCount} are ignored.
+ */
+ public static TvInputInfo createTvInputInfo(
+ ResolveInfo service,
+ String id,
+ String parentId,
+ int type,
+ boolean isHardwareInput,
+ boolean canRecord,
+ int tunerCount)
+ throws Exception {
+ // Create a mock TvInputInfo by using private constructor
+ // Note that mockito doesn't support mock/spy on final object.
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ return createTvInputInfoForO(
+ service, id, parentId, type, isHardwareInput, canRecord, tunerCount);
+
+ } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ return createTvInputInfoForNyc(
+ service, id, parentId, type, isHardwareInput, canRecord, tunerCount);
+ }
+ return createTvInputInfoForMnc(service, id, parentId, type, isHardwareInput);
+ }
+
+ /**
+ * private TvInputInfo(ResolveInfo service, String id, int type, boolean isHardwareInput,
+ * CharSequence label, int labelResId, Icon icon, Icon iconStandby, Icon iconDisconnected,
+ * String setupActivity, boolean canRecord, int tunerCount, HdmiDeviceInfo hdmiDeviceInfo,
+ * boolean isConnectedToHdmiSwitch, String parentId, Bundle extras) {
+ */
+ private static TvInputInfo createTvInputInfoForO(
+ ResolveInfo service,
+ String id,
+ String parentId,
+ int type,
+ boolean isHardwareInput,
+ boolean canRecord,
+ int tunerCount)
+ throws Exception {
+ Constructor<TvInputInfo> constructor =
+ TvInputInfo.class.getDeclaredConstructor(
+ ResolveInfo.class,
+ String.class,
+ int.class,
+ boolean.class,
+ CharSequence.class,
+ int.class,
+ Icon.class,
+ Icon.class,
+ Icon.class,
+ String.class,
+ boolean.class,
+ int.class,
+ HdmiDeviceInfo.class,
+ boolean.class,
+ String.class,
+ Bundle.class);
+ constructor.setAccessible(true);
+ return constructor.newInstance(
+ service,
+ id,
+ type,
+ isHardwareInput,
+ null,
+ 0,
+ null,
+ null,
+ null,
+ null,
+ canRecord,
+ tunerCount,
+ null,
+ false,
+ parentId,
+ null);
+ }
+
+ /**
+ * private TvInputInfo(ResolveInfo service, String id, int type, boolean isHardwareInput,
+ * CharSequence label, int labelResId, Icon icon, Icon iconStandby, Icon iconDisconnected,
+ * String setupActivity, String settingsActivity, boolean canRecord, int tunerCount,
+ * HdmiDeviceInfo hdmiDeviceInfo, boolean isConnectedToHdmiSwitch, String parentId, Bundle
+ * extras) {
+ */
+ private static TvInputInfo createTvInputInfoForNyc(
+ ResolveInfo service,
+ String id,
+ String parentId,
+ int type,
+ boolean isHardwareInput,
+ boolean canRecord,
+ int tunerCount)
+ throws Exception {
+ Constructor<TvInputInfo> constructor =
+ TvInputInfo.class.getDeclaredConstructor(
+ ResolveInfo.class,
+ String.class,
+ int.class,
+ boolean.class,
+ CharSequence.class,
+ int.class,
+ Icon.class,
+ Icon.class,
+ Icon.class,
+ String.class,
+ String.class,
+ boolean.class,
+ int.class,
+ HdmiDeviceInfo.class,
+ boolean.class,
+ String.class,
+ Bundle.class);
+ constructor.setAccessible(true);
+ return constructor.newInstance(
+ service,
+ id,
+ type,
+ isHardwareInput,
+ null,
+ 0,
+ null,
+ null,
+ null,
+ null,
+ null,
+ canRecord,
+ tunerCount,
+ null,
+ false,
+ parentId,
+ null);
+ }
+
+ private static TvInputInfo createTvInputInfoForMnc(
+ ResolveInfo service, String id, String parentId, int type, boolean isHardwareInput)
+ throws Exception {
+ Constructor<TvInputInfo> constructor =
+ TvInputInfo.class.getDeclaredConstructor(
+ ResolveInfo.class, String.class, String.class, int.class, boolean.class);
+ constructor.setAccessible(true);
+ return constructor.newInstance(service, id, parentId, type, isHardwareInput);
+ }
+
+ public static ResolveInfo createResolveInfo(String packageName, String name) {
+ ResolveInfo resolveInfo = new ResolveInfo();
+ resolveInfo.serviceInfo = new ServiceInfo();
+ resolveInfo.serviceInfo.packageName = packageName;
+ resolveInfo.serviceInfo.name = name;
+ resolveInfo.serviceInfo.metaData = new Bundle();
+ resolveInfo.serviceInfo.applicationInfo = new ApplicationInfo();
+ return resolveInfo;
+ }
+}
diff --git a/tests/common/src/com/android/tv/testing/Utils.java b/tests/common/src/com/android/tv/testing/utils/Utils.java
index b2b4036e..a116db0b 100644
--- a/tests/common/src/com/android/tv/testing/Utils.java
+++ b/tests/common/src/com/android/tv/testing/utils/Utils.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.tv.testing;
+package com.android.tv.testing.utils;
import android.content.ComponentName;
import android.content.ContentResolver;
@@ -26,9 +26,8 @@ import android.media.tv.TvInputInfo;
import android.media.tv.TvInputManager;
import android.net.Uri;
import android.util.Log;
-
-import com.android.tv.common.TvCommonUtils;
-
+import com.android.tv.common.CommonConstants;
+import com.android.tv.common.util.CommonUtils;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@@ -40,12 +39,10 @@ import java.util.Random;
/**
* An utility class for testing.
*
- * <p>This class is also used to check whether TV app is running in tests or not.
- *
- * @see TvCommonUtils#isRunningInTest
+ * @see CommonUtils#isRunningInTest
*/
public final class Utils {
- private static final String TAG ="Utils";
+ private static final String TAG = "Utils";
private static final long DEFAULT_RANDOM_SEED = getSeed();
@@ -55,10 +52,12 @@ public final class Utils {
}
Resources res = context.getResources();
return new Uri.Builder()
- .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
- .authority(res.getResourcePackageName(resId))
- .path(res.getResourceTypeName(resId))
- .appendPath(res.getResourceEntryName(resId)).build().toString();
+ .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
+ .authority(res.getResourcePackageName(resId))
+ .path(res.getResourceTypeName(resId))
+ .appendPath(res.getResourceEntryName(resId))
+ .build()
+ .toString();
}
public static void copy(InputStream is, OutputStream os) throws IOException {
@@ -91,8 +90,8 @@ public final class Utils {
}
/**
- * Return the Random class which is needed to make random data for testing.
- * Default seed of the random is today's date.
+ * Return the Random class which is needed to make random data for testing. Default seed of the
+ * random is today's date.
*/
public static Random createTestRandom() {
return new Random(DEFAULT_RANDOM_SEED);
@@ -106,17 +105,15 @@ public final class Utils {
return Long.valueOf(today);
}
- private Utils() {}
-
- /**
- * Checks whether TvActivity is enabled or not.
- */
+ /** 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");
+ ComponentName name =
+ new ComponentName(CommonConstants.BASE_PACKAGE, "com.android.tv.TvActivity");
int enabled = pm.getComponentEnabledSetting(name);
return enabled == PackageManager.COMPONENT_ENABLED_STATE_ENABLED
|| enabled == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
}
+
+ private Utils() {}
}
diff --git a/tests/func/Android.mk b/tests/func/Android.mk
index e89ba25b..855e8ebf 100644
--- a/tests/func/Android.mk
+++ b/tests/func/Android.mk
@@ -14,9 +14,11 @@ LOCAL_STATIC_JAVA_LIBRARIES := \
tv-test-common \
ub-uiautomator \
+LOCAL_JAVA_LIBRARIES := android.test.base.stubs
+
LOCAL_INSTRUMENTATION_FOR := LiveTv
-LOCAL_SDK_VERSION := current
-LOCAL_MIN_SDK_VERSION := 23 # M
+LOCAL_SDK_VERSION := system_current
+LOCAL_PROGUARD_ENABLED := disabled
include $(BUILD_PACKAGE)
diff --git a/tests/func/AndroidManifest.xml b/tests/func/AndroidManifest.xml
index 29b018e1..708dc220 100644
--- a/tests/func/AndroidManifest.xml
+++ b/tests/func/AndroidManifest.xml
@@ -18,7 +18,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.tv.tests.ui" >
- <uses-sdk android:targetSdkVersion="23" android:minSdkVersion="21" />
+ <uses-sdk android:targetSdkVersion="26" android:minSdkVersion="21" />
<instrumentation
android:name="android.support.test.runner.AndroidJUnitRunner"
diff --git a/tests/func/src/com/android/tv/tests/ui/ChannelBannerViewTest.java b/tests/func/src/com/android/tv/tests/ui/ChannelBannerViewTest.java
index d8a4aec1..600b52b6 100644
--- a/tests/func/src/com/android/tv/tests/ui/ChannelBannerViewTest.java
+++ b/tests/func/src/com/android/tv/tests/ui/ChannelBannerViewTest.java
@@ -16,37 +16,48 @@
package com.android.tv.tests.ui;
-import static com.android.tv.testing.uihelper.UiDeviceAsserts.assertWaitForCondition;
-
-import android.support.test.filters.SmallTest;
+import android.support.test.filters.MediumTest;
import android.support.test.uiautomator.Until;
-
import com.android.tv.R;
import com.android.tv.testing.uihelper.Constants;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** Tests for {@link com.android.tv.ui.ChannelBannerView} */
+@MediumTest
+@RunWith(JUnit4.class)
+public class ChannelBannerViewTest {
+ @Rule public final LiveChannelsTestController controller = new LiveChannelsTestController();
-@SmallTest
-public class ChannelBannerViewTest extends LiveChannelsTestCase {
// Channel banner show duration with the grace period.
private long mShowDurationMillis;
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- mLiveChannelsHelper.assertAppStarted();
- mShowDurationMillis = mTargetResources.getInteger(R.integer.channel_banner_show_duration)
- + Constants.MAX_SHOW_DELAY_MILLIS;
+ @Before
+ public void setUp() throws Exception {
+ controller.liveChannelsHelper.assertAppStarted();
+ mShowDurationMillis =
+ controller.getTargetResources().getInteger(R.integer.channel_banner_show_duration)
+ + Constants.MAX_SHOW_DELAY_MILLIS;
}
+ @Ignore("b/73727914")
+ @Test
public void testChannelBannerAppearDisappear() {
- mDevice.pressDPadCenter();
- assertWaitForCondition(mDevice, Until.hasObject(Constants.CHANNEL_BANNER));
- assertWaitForCondition(mDevice, Until.gone(Constants.CHANNEL_BANNER), mShowDurationMillis);
+ controller.pressDPadCenter();
+ controller.assertWaitForCondition(Until.hasObject(Constants.CHANNEL_BANNER));
+ controller.assertWaitForCondition(
+ Until.gone(Constants.CHANNEL_BANNER), mShowDurationMillis);
}
+ @Test
public void testChannelBannerShownWhenTune() {
- mDevice.pressDPadDown();
- assertWaitForCondition(mDevice, Until.hasObject(Constants.CHANNEL_BANNER));
- mDevice.pressDPadUp();
- assertWaitForCondition(mDevice, Until.hasObject(Constants.CHANNEL_BANNER));
+ controller.pressDPadDown();
+ controller.assertWaitForCondition(Until.hasObject(Constants.CHANNEL_BANNER));
+ controller.pressDPadUp();
+ controller.assertWaitForCondition(Until.hasObject(Constants.CHANNEL_BANNER));
}
}
diff --git a/tests/func/src/com/android/tv/tests/ui/ChannelSourcesTest.java b/tests/func/src/com/android/tv/tests/ui/ChannelSourcesTest.java
index cfa5eda7..53e27f1b 100644
--- a/tests/func/src/com/android/tv/tests/ui/ChannelSourcesTest.java
+++ b/tests/func/src/com/android/tv/tests/ui/ChannelSourcesTest.java
@@ -15,56 +15,64 @@
*/
package com.android.tv.tests.ui;
-import static com.android.tv.testing.uihelper.UiDeviceAsserts.assertWaitForCondition;
-
-import android.support.test.filters.LargeTest;
+import android.support.test.filters.MediumTest;
import android.support.test.uiautomator.BySelector;
import android.support.test.uiautomator.Until;
-
import com.android.tv.R;
import com.android.tv.testing.uihelper.ByResource;
-import com.android.tv.testing.uihelper.UiDeviceUtils;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
-/**
- * Tests for channel sources.
- */
-@LargeTest
-public class ChannelSourcesTest extends LiveChannelsTestCase {
+/** Tests for channel sources. */
+@MediumTest
+@RunWith(JUnit4.class)
+public class ChannelSourcesTest {
+ @Rule public final LiveChannelsTestController controller = new LiveChannelsTestController();
private BySelector mBySettingsSidePanel;
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- mBySettingsSidePanel = mSidePanelHelper.bySidePanelTitled(
- R.string.side_panel_title_settings);
+ @Before
+ public void before() throws Exception {
+ mBySettingsSidePanel =
+ controller.sidePanelHelper.bySidePanelTitled(R.string.side_panel_title_settings);
}
- //TODO: create a cancelable test channel setup.
+ // TODO: create a cancelable test channel setup.
+ @Test
public void testSetup_cancel() {
- mLiveChannelsHelper.assertAppStarted();
- mMenuHelper.assertPressOptionsSettings();
- assertWaitForCondition(mDevice, Until.hasObject(mBySettingsSidePanel));
+ controller.liveChannelsHelper.assertAppStarted();
+ controller.menuHelper.assertPressOptionsSettings();
+ controller.assertWaitForCondition(Until.hasObject(mBySettingsSidePanel));
- mSidePanelHelper.assertNavigateToItem(R.string.settings_channel_source_item_setup);
- mDevice.pressDPadCenter();
+ controller.sidePanelHelper.assertNavigateToItem(
+ R.string.settings_channel_source_item_setup);
+ controller.pressDPadCenter();
- assertWaitForCondition(mDevice,
- Until.hasObject(ByResource.text(mTargetResources, R.string.setup_sources_text)));
- mDevice.pressBack();
+ controller.assertWaitForCondition(
+ Until.hasObject(
+ ByResource.text(
+ controller.getTargetResources(), R.string.setup_sources_text)));
+ controller.pressBack();
}
// SetupSourcesFragment should have no errors if side fragment item is clicked multiple times.
+ @Test
public void testSetupTwice_cancel() {
- mLiveChannelsHelper.assertAppStarted();
- mMenuHelper.assertPressOptionsSettings();
- assertWaitForCondition(mDevice, Until.hasObject(mBySettingsSidePanel));
+ controller.liveChannelsHelper.assertAppStarted();
+ controller.menuHelper.assertPressOptionsSettings();
+ controller.assertWaitForCondition(Until.hasObject(mBySettingsSidePanel));
- mSidePanelHelper.assertNavigateToItem(R.string.settings_channel_source_item_setup);
- UiDeviceUtils.pressDPadCenter(getInstrumentation(), 2);
+ controller.sidePanelHelper.assertNavigateToItem(
+ R.string.settings_channel_source_item_setup);
+ controller.pressDPadCenter(2);
- assertWaitForCondition(mDevice,
- Until.hasObject(ByResource.text(mTargetResources, R.string.setup_sources_text)));
- mDevice.pressBack();
+ controller.assertWaitForCondition(
+ Until.hasObject(
+ ByResource.text(
+ controller.getTargetResources(), R.string.setup_sources_text)));
+ controller.pressBack();
}
}
diff --git a/tests/func/src/com/android/tv/tests/ui/LiveChannelsAppTest.java b/tests/func/src/com/android/tv/tests/ui/LiveChannelsAppTest.java
index 48224123..1a5ceb45 100644
--- a/tests/func/src/com/android/tv/tests/ui/LiveChannelsAppTest.java
+++ b/tests/func/src/com/android/tv/tests/ui/LiveChannelsAppTest.java
@@ -16,103 +16,116 @@
package com.android.tv.tests.ui;
-import static com.android.tv.testing.uihelper.UiDeviceAsserts.assertHas;
-import static com.android.tv.testing.uihelper.UiDeviceAsserts.assertWaitForCondition;
-
-import android.support.test.filters.LargeTest;
+import android.support.test.filters.MediumTest;
import android.support.test.uiautomator.BySelector;
import android.support.test.uiautomator.Until;
-
import com.android.tv.R;
import com.android.tv.testing.testinput.ChannelStateData;
import com.android.tv.testing.testinput.TvTestInputConstants;
import com.android.tv.testing.uihelper.Constants;
import com.android.tv.testing.uihelper.DialogHelper;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** Basic tests for the LiveChannels app. */
+@MediumTest
+@RunWith(JUnit4.class)
+public class LiveChannelsAppTest {
+ @Rule public final LiveChannelsTestController controller = new LiveChannelsTestController();
-/**
- * Basic tests for the LiveChannels app.
- */
-@LargeTest
-public class LiveChannelsAppTest extends LiveChannelsTestCase {
private BySelector mBySettingsSidePanel;
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- mLiveChannelsHelper.assertAppStarted();
- pressKeysForChannel(TvTestInputConstants.CH_1_DEFAULT_DONT_MODIFY);
- getInstrumentation().waitForIdleSync();
- mBySettingsSidePanel = mSidePanelHelper.bySidePanelTitled(
- R.string.side_panel_title_settings);
+ @Before
+ public void setUp() throws Exception {
+ controller.liveChannelsHelper.assertAppStarted();
+ controller.pressKeysForChannel(TvTestInputConstants.CH_1_DEFAULT_DONT_MODIFY);
+ controller.waitForIdleSync();
+ mBySettingsSidePanel =
+ controller.sidePanelHelper.bySidePanelTitled(R.string.side_panel_title_settings);
}
+ @Test
public void testSettingsCancel() {
- mMenuHelper.assertPressOptionsSettings();
- BySelector byChannelSourcesSidePanel = mSidePanelHelper
- .bySidePanelTitled(R.string.settings_channel_source_item_customize_channels);
- assertWaitForCondition(mDevice, Until.hasObject(byChannelSourcesSidePanel));
- mDevice.pressBack();
- assertWaitForCondition(mDevice, Until.gone(byChannelSourcesSidePanel));
- assertHas(mDevice, Constants.MENU, false);
+ controller.menuHelper.assertPressOptionsSettings();
+ BySelector byChannelSourcesSidePanel =
+ controller.sidePanelHelper.bySidePanelTitled(
+ R.string.settings_channel_source_item_customize_channels);
+ controller.assertWaitForCondition(Until.hasObject(byChannelSourcesSidePanel));
+ controller.pressBack();
+ controller.assertWaitForCondition(Until.gone(byChannelSourcesSidePanel));
+ controller.assertHas(Constants.MENU, false);
}
+ @Test
public void testClosedCaptionsCancel() {
- mMenuHelper.assertPressOptionsClosedCaptions();
- BySelector byClosedCaptionSidePanel = mSidePanelHelper
- .bySidePanelTitled(R.string.side_panel_title_closed_caption);
- assertWaitForCondition(mDevice, Until.hasObject(byClosedCaptionSidePanel));
- mDevice.pressBack();
- assertWaitForCondition(mDevice, Until.gone(byClosedCaptionSidePanel));
- assertHas(mDevice, Constants.MENU, false);
+ controller.menuHelper.assertPressOptionsClosedCaptions();
+ BySelector byClosedCaptionSidePanel =
+ controller.sidePanelHelper.bySidePanelTitled(
+ R.string.side_panel_title_closed_caption);
+ controller.assertWaitForCondition(Until.hasObject(byClosedCaptionSidePanel));
+ controller.pressBack();
+ controller.assertWaitForCondition(Until.gone(byClosedCaptionSidePanel));
+ controller.assertHas(Constants.MENU, false);
}
+ @Test
public void testDisplayModeCancel() {
ChannelStateData data = new ChannelStateData();
- data.mTvTrackInfos.add(com.android.tv.testing.Constants.SVGA_VIDEO_TRACK);
- data.mSelectedVideoTrackId = com.android.tv.testing.Constants.SVGA_VIDEO_TRACK
- .getId();
- updateThenTune(data, TvTestInputConstants.CH_2);
+ data.mTvTrackInfos.add(com.android.tv.testing.constants.Constants.SVGA_VIDEO_TRACK);
+ data.mSelectedVideoTrackId =
+ com.android.tv.testing.constants.Constants.SVGA_VIDEO_TRACK.getId();
+ controller.updateThenTune(data, TvTestInputConstants.CH_2);
- mMenuHelper.assertPressOptionsDisplayMode();
- BySelector byDisplayModeSidePanel = mSidePanelHelper
- .bySidePanelTitled(R.string.side_panel_title_display_mode);
- assertWaitForCondition(mDevice, Until.hasObject(byDisplayModeSidePanel));
- mDevice.pressBack();
- assertWaitForCondition(mDevice, Until.gone(byDisplayModeSidePanel));
- assertHas(mDevice, Constants.MENU, false);
+ controller.menuHelper.assertPressOptionsDisplayMode();
+ BySelector byDisplayModeSidePanel =
+ controller.sidePanelHelper.bySidePanelTitled(
+ R.string.side_panel_title_display_mode);
+ controller.assertWaitForCondition(Until.hasObject(byDisplayModeSidePanel));
+ controller.pressBack();
+ controller.assertWaitForCondition(Until.gone(byDisplayModeSidePanel));
+ controller.assertHas(Constants.MENU, false);
}
+ @Test
public void testMenu() {
- mDevice.pressMenu();
+ controller.pressMenu();
- assertWaitForCondition(mDevice, Until.hasObject(Constants.MENU));
- assertHas(mDevice, mMenuHelper.getByChannels(), true);
+ controller.assertWaitForCondition(Until.hasObject(Constants.MENU));
+ controller.assertHas(controller.menuHelper.getByChannels(), true);
}
+ @Test
public void testMultiAudioCancel() {
ChannelStateData data = new ChannelStateData();
- data.mTvTrackInfos.add(com.android.tv.testing.Constants.GENERIC_AUDIO_TRACK);
- updateThenTune(data, TvTestInputConstants.CH_2);
+ data.mTvTrackInfos.add(com.android.tv.testing.constants.Constants.GENERIC_AUDIO_TRACK);
+ controller.updateThenTune(data, TvTestInputConstants.CH_2);
- mMenuHelper.assertPressOptionsMultiAudio();
- BySelector byMultiAudioSidePanel = mSidePanelHelper
- .bySidePanelTitled(R.string.side_panel_title_multi_audio);
- assertWaitForCondition(mDevice, Until.hasObject(byMultiAudioSidePanel));
- mDevice.pressBack();
- assertWaitForCondition(mDevice, Until.gone(byMultiAudioSidePanel));
- assertHas(mDevice, Constants.MENU, false);
+ controller.menuHelper.assertPressOptionsMultiAudio();
+ BySelector byMultiAudioSidePanel =
+ controller.sidePanelHelper.bySidePanelTitled(R.string.side_panel_title_multi_audio);
+ controller.assertWaitForCondition(Until.hasObject(byMultiAudioSidePanel));
+ controller.pressBack();
+ controller.assertWaitForCondition(Until.gone(byMultiAudioSidePanel));
+ controller.assertHas(Constants.MENU, false);
}
+ @Ignore("b/72156196")
+ @Test
public void testPinCancel() {
- mMenuHelper.showMenu();
- mMenuHelper.assertPressOptionsSettings();
- assertWaitForCondition(mDevice, Until.hasObject(mBySettingsSidePanel));
- mSidePanelHelper.assertNavigateToItem(R.string.settings_parental_controls);
- mDevice.pressDPadCenter();
- DialogHelper dialogHelper = new DialogHelper(mDevice, mTargetResources);
+ controller.menuHelper.showMenu();
+ controller.menuHelper.assertPressOptionsSettings();
+ controller.assertWaitForCondition(Until.hasObject(mBySettingsSidePanel));
+ controller.sidePanelHelper.assertNavigateToItem(R.string.settings_parental_controls);
+ controller.pressDPadCenter();
+ DialogHelper dialogHelper =
+ new DialogHelper(controller.getUiDevice(), controller.getTargetResources());
dialogHelper.assertWaitForPinDialogOpen();
- mDevice.pressBack();
+ controller.pressBack();
dialogHelper.assertWaitForPinDialogClose();
- assertHas(mDevice, Constants.MENU, false);
+ controller.assertHas(Constants.MENU, false);
}
}
diff --git a/tests/func/src/com/android/tv/tests/ui/LiveChannelsTestCase.java b/tests/func/src/com/android/tv/tests/ui/LiveChannelsTestCase.java
deleted file mode 100644
index e306e6c6..00000000
--- a/tests/func/src/com/android/tv/tests/ui/LiveChannelsTestCase.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * 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.ui;
-
-import static com.android.tv.testing.uihelper.UiDeviceAsserts.assertWaitForCondition;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.support.test.uiautomator.UiDevice;
-import android.support.test.uiautomator.Until;
-import android.test.InstrumentationTestCase;
-
-import com.android.tv.testing.ChannelInfo;
-import com.android.tv.testing.testinput.ChannelStateData;
-import com.android.tv.testing.testinput.TestInputControlConnection;
-import com.android.tv.testing.testinput.TestInputControlUtils;
-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.SidePanelHelper;
-import com.android.tv.testing.uihelper.UiDeviceUtils;
-
-/**
- * Base test case for LiveChannel UI tests.
- */
-public abstract class LiveChannelsTestCase extends InstrumentationTestCase {
- protected final TestInputControlConnection mConnection = new TestInputControlConnection();
-
- protected UiDevice mDevice;
- protected Resources mTargetResources;
- protected MenuHelper mMenuHelper;
- protected SidePanelHelper mSidePanelHelper;
- protected LiveChannelsUiDeviceHelper mLiveChannelsHelper;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- Context context = getInstrumentation().getContext();
- context.bindService(TestInputControlUtils.createIntent(), mConnection,
- Context.BIND_AUTO_CREATE);
- mDevice = UiDevice.getInstance(getInstrumentation());
- mTargetResources = getInstrumentation().getTargetContext().getResources();
- mMenuHelper = new MenuHelper(mDevice, mTargetResources);
- mSidePanelHelper = new SidePanelHelper(mDevice, mTargetResources);
- mLiveChannelsHelper = new LiveChannelsUiDeviceHelper(mDevice, mTargetResources, context);
- }
-
- @Override
- protected void tearDown() throws Exception {
- if (mConnection.isBound()) {
- getInstrumentation().getContext().unbindService(mConnection);
- }
-
- // TODO: robustly handle left over pops from failed tests.
- // Clear any side panel, menu, ...
- // Scene container should not be checked here because pressing the BACK key in some scenes
- // might launch the home screen.
- if (mDevice.hasObject(Constants.SIDE_PANEL) || mDevice.hasObject(Constants.MENU) || mDevice
- .hasObject(Constants.PROGRAM_GUIDE)) {
- mDevice.pressBack();
- }
- // To destroy the activity to make sure next test case's activity launch check works well.
- mDevice.pressBack();
- super.tearDown();
- }
-
- /**
- * Send the keys for the channel number of {@code channel} and press the DPAD
- * center.
- *
- * <p>Usually this will tune to the given channel.
- */
- protected void pressKeysForChannel(ChannelInfo channel) {
- UiDeviceUtils.pressKeys(mDevice, channel.number);
- assertWaitForCondition(mDevice, Until.hasObject(Constants.KEYPAD_CHANNEL_SWITCH));
- mDevice.pressDPadCenter();
- }
-
- /**
- * Update the channel state to {@code data} then tune to that channel.
- *
- * @param data the state to update the channel with.
- * @param channel the channel to tune to
- */
- protected void updateThenTune(ChannelStateData data, ChannelInfo channel) {
- mConnection.updateChannelState(channel, data);
- pressKeysForChannel(channel);
- }
-}
diff --git a/tests/func/src/com/android/tv/tests/ui/LiveChannelsTestController.java b/tests/func/src/com/android/tv/tests/ui/LiveChannelsTestController.java
new file mode 100644
index 00000000..03d30ca4
--- /dev/null
+++ b/tests/func/src/com/android/tv/tests/ui/LiveChannelsTestController.java
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2018 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.ui;
+
+import static junit.framework.Assert.assertTrue;
+
+import android.app.Instrumentation;
+import android.app.UiAutomation;
+import android.content.Context;
+import android.content.res.Resources;
+import android.os.Build;
+import android.os.SystemClock;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.uiautomator.BySelector;
+import android.support.test.uiautomator.Configurator;
+import android.support.test.uiautomator.SearchCondition;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.Until;
+import android.view.InputDevice;
+import android.view.KeyEvent;
+import com.android.tv.testing.data.ChannelInfo;
+import com.android.tv.testing.testinput.ChannelStateData;
+import com.android.tv.testing.testinput.TestInputControlConnection;
+import com.android.tv.testing.testinput.TestInputControlUtils;
+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.SidePanelHelper;
+import com.android.tv.testing.uihelper.UiDeviceAsserts;
+import com.android.tv.testing.uihelper.UiDeviceUtils;
+import org.junit.rules.ExternalResource;
+
+/** UIHelpers and TestInputController for LiveChannels. */
+public class LiveChannelsTestController extends ExternalResource {
+
+ private final TestInputControlConnection mConnection = new TestInputControlConnection();
+
+ public MenuHelper menuHelper;
+ public SidePanelHelper sidePanelHelper;
+ public LiveChannelsUiDeviceHelper liveChannelsHelper;
+
+ private UiDevice mDevice;
+ private Resources mTargetResources;
+ private Instrumentation mInstrumentation;
+
+ private void assertPressKeyUp(int keyCode, boolean sync) {
+ assertPressKey(KeyEvent.ACTION_UP, keyCode, sync);
+ }
+
+ private void assertPressKey(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(event, sync));
+ }
+
+ private UiAutomation getUiAutomation() {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ int flags = Configurator.getInstance().getUiAutomationFlags();
+ return mInstrumentation.getUiAutomation(flags);
+ } else {
+ return mInstrumentation.getUiAutomation();
+ }
+ }
+
+ @Override
+ protected void before() throws Exception {
+ mInstrumentation = InstrumentationRegistry.getInstrumentation();
+ Context context = mInstrumentation.getContext();
+ context.bindService(
+ TestInputControlUtils.createIntent(), mConnection, Context.BIND_AUTO_CREATE);
+ mDevice = UiDevice.getInstance(mInstrumentation);
+ mTargetResources = mInstrumentation.getTargetContext().getResources();
+ menuHelper = new MenuHelper(mDevice, mTargetResources);
+ sidePanelHelper = new SidePanelHelper(mDevice, mTargetResources);
+ liveChannelsHelper = new LiveChannelsUiDeviceHelper(mDevice, mTargetResources, context);
+ }
+
+ @Override
+ protected void after() {
+ if (mConnection.isBound()) {
+ mInstrumentation.getContext().unbindService(mConnection);
+ }
+
+ // TODO: robustly handle left over pops from failed tests.
+ // Clear any side panel, menu, ...
+ // Scene container should not be checked here because pressing the BACK key in some scenes
+ // might launch the home screen.
+ if (mDevice.hasObject(Constants.SIDE_PANEL)
+ || mDevice.hasObject(Constants.MENU)
+ || mDevice.hasObject(Constants.PROGRAM_GUIDE)) {
+ mDevice.pressBack();
+ }
+ // To destroy the activity to make sure next test case's activity launch check works well.
+ mDevice.pressBack();
+ }
+
+ /**
+ * Update the channel state to {@code data} then tune to that channel.
+ *
+ * @param data the state to update the channel with.
+ * @param channel the channel to tune to
+ */
+ protected void updateThenTune(ChannelStateData data, ChannelInfo channel) {
+ mConnection.updateChannelState(channel, data);
+ pressKeysForChannel(channel);
+ }
+
+ /**
+ * Send the keys for the channel number of {@code channel} and press the DPAD center.
+ *
+ * <p>Usually this will tune to the given channel.
+ */
+ public void pressKeysForChannel(ChannelInfo channel) {
+ UiDeviceUtils.pressKeys(mDevice, channel.number);
+ UiDeviceAsserts.assertWaitForCondition(
+ mDevice, Until.hasObject(Constants.KEYPAD_CHANNEL_SWITCH));
+ mDevice.pressDPadCenter();
+ }
+
+ public void assertHas(BySelector bySelector, boolean expected) {
+ UiDeviceAsserts.assertHas(mDevice, bySelector, expected);
+ }
+
+ public void assertWaitForCondition(SearchCondition<Boolean> booleanSearchCondition) {
+ UiDeviceAsserts.assertWaitForCondition(mDevice, booleanSearchCondition);
+ }
+
+ public void assertWaitForCondition(SearchCondition<Boolean> gone, long timeout) {
+ UiDeviceAsserts.assertWaitForCondition(mDevice, gone, timeout);
+ }
+
+ public void assertWaitUntilFocused(BySelector bySelector) {
+ UiDeviceAsserts.assertWaitUntilFocused(mDevice, bySelector);
+ }
+
+ public Resources getTargetResources() {
+ return mTargetResources;
+ }
+
+ public UiDevice getUiDevice() {
+ return mDevice;
+ }
+
+ public boolean injectEvent(KeyEvent event, boolean sync) {
+ return getUiAutomation().injectInputEvent(event, sync);
+ }
+
+ public void pressBack() {
+ mDevice.pressBack();
+ }
+
+ public void pressDPadCenter() {
+ pressDPadCenter(1);
+ }
+
+ public void pressDPadCenter(int repeat) {
+ UiDevice.getInstance(mInstrumentation).waitForIdle();
+ for (int i = 0; i < repeat; ++i) {
+ assertPressKey(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_CENTER, false);
+ if (i < repeat - 1) {
+ assertPressKeyUp(KeyEvent.KEYCODE_DPAD_CENTER, false);
+ }
+ }
+ // Send last key event synchronously.
+ assertPressKeyUp(KeyEvent.KEYCODE_DPAD_CENTER, true);
+ }
+
+ public void pressDPadDown() {
+ mDevice.pressDPadDown();
+ }
+
+ public void pressDPadLeft() {
+ mDevice.pressDPadLeft();
+ }
+
+ public void pressDPadRight() {
+ mDevice.pressDPadRight();
+ }
+
+ public void pressDPadUp() {
+ mDevice.pressDPadUp();
+ }
+
+ public void pressEnter() {
+ mDevice.pressEnter();
+ }
+
+ public void pressHome() {
+ mDevice.pressHome();
+ }
+
+ public void pressKeyCode(int keyCode) {
+ mDevice.pressKeyCode(keyCode);
+ }
+
+ public void pressMenu() {
+ mDevice.pressMenu();
+ }
+
+ public void waitForIdle() {
+ mDevice.waitForIdle();
+ }
+
+ public void waitForIdleSync() {
+ mInstrumentation.waitForIdleSync();
+ }
+}
diff --git a/tests/func/src/com/android/tv/tests/ui/ParentalControlsTest.java b/tests/func/src/com/android/tv/tests/ui/ParentalControlsTest.java
index 93d14bde..ee039d7c 100644
--- a/tests/func/src/com/android/tv/tests/ui/ParentalControlsTest.java
+++ b/tests/func/src/com/android/tv/tests/ui/ParentalControlsTest.java
@@ -16,139 +16,169 @@
package com.android.tv.tests.ui;
-import static com.android.tv.testing.uihelper.UiDeviceAsserts.assertWaitForCondition;
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertTrue;
-import android.support.test.filters.SmallTest;
+import android.support.test.filters.MediumTest;
import android.support.test.uiautomator.BySelector;
import android.support.test.uiautomator.UiObject2;
import android.support.test.uiautomator.Until;
-
import com.android.tv.R;
import com.android.tv.testing.uihelper.ByResource;
import com.android.tv.testing.uihelper.DialogHelper;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
-@SmallTest
-public class ParentalControlsTest extends LiveChannelsTestCase {
-
+/** Tests for {@link com.android.tv.ui.sidepanel.parentalcontrols.ParentalControlsFragment} */
+@MediumTest
+@RunWith(JUnit4.class)
+public class ParentalControlsTest {
+ @Rule public final LiveChannelsTestController controller = new LiveChannelsTestController();
private BySelector mBySettingsSidePanel;
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- mLiveChannelsHelper.assertAppStarted();
- mBySettingsSidePanel = mSidePanelHelper.bySidePanelTitled(
- R.string.side_panel_title_settings);
- prepareParentalControl();
+ @Before
+ public void setUp() throws Exception {
+
+ controller.liveChannelsHelper.assertAppStarted();
+ mBySettingsSidePanel =
+ controller.sidePanelHelper.bySidePanelTitled(R.string.side_panel_title_settings);
+ // TODO(b/72154681): prepareParentalControl();
}
- @Override
- protected void tearDown() throws Exception {
+ @After
+ public void tearDown() throws Exception {
switchParentalControl(R.string.option_toggle_parental_controls_on);
- super.tearDown();
}
+ @Test
+ public void placeHolder() {
+ // there must be at least one test.
+ }
+
+ @Ignore("b/72154681")
+ @Test
public void testRatingDependentSelect() {
// Show ratings fragment.
- BySelector bySidePanel = mSidePanelHelper.bySidePanelTitled(
- R.string.option_program_restrictions);
- assertWaitForCondition(mDevice, Until.hasObject(bySidePanel));
- mSidePanelHelper.assertNavigateToItem(R.string.option_ratings);
- mDevice.pressDPadCenter();
+ BySelector bySidePanel =
+ controller.sidePanelHelper.bySidePanelTitled(R.string.option_program_restrictions);
+ controller.assertWaitForCondition(Until.hasObject(bySidePanel));
+ controller.sidePanelHelper.assertNavigateToItem(R.string.option_ratings);
+ controller.pressDPadCenter();
// Block rating 6 and rating 12. Check if dependent select works well.
- bySidePanel = mSidePanelHelper.bySidePanelTitled(R.string.option_ratings);
- assertWaitForCondition(mDevice, Until.hasObject(bySidePanel));
+ bySidePanel = controller.sidePanelHelper.bySidePanelTitled(R.string.option_ratings);
+ controller.assertWaitForCondition(Until.hasObject(bySidePanel));
// Test on blocking and unblocking Japanese rating.
int blockAge = 6;
int unBlockAge = 12;
int maxAge = 20;
int minAge = 4;
for (int age = minAge; age <= maxAge; age++) {
- UiObject2 ratingCheckBox = mSidePanelHelper.assertNavigateToItem(String.valueOf(age))
- .findObject(ByResource.id(mTargetResources, R.id.check_box));
+ UiObject2 ratingCheckBox =
+ controller
+ .sidePanelHelper
+ .assertNavigateToItem(String.valueOf(age))
+ .findObject(
+ ByResource.id(controller.getTargetResources(), R.id.check_box));
if (ratingCheckBox.isChecked()) {
- mDevice.pressDPadCenter();
+ controller.pressDPadCenter();
}
}
- mSidePanelHelper.assertNavigateToItem(String.valueOf(blockAge));
- mDevice.pressDPadCenter();
+ controller.sidePanelHelper.assertNavigateToItem(String.valueOf(blockAge));
+ controller.pressDPadCenter();
assertRatingViewIsChecked(minAge, maxAge, blockAge, true);
- mSidePanelHelper.assertNavigateToItem(String.valueOf(unBlockAge));
- mDevice.pressDPadCenter();
+ controller.sidePanelHelper.assertNavigateToItem(String.valueOf(unBlockAge));
+ controller.pressDPadCenter();
assertRatingViewIsChecked(minAge, maxAge, unBlockAge, false);
- mDevice.pressBack();
- mDevice.pressBack();
- getInstrumentation().waitForIdleSync();
+ controller.pressBack();
+ controller.pressBack();
+ controller.waitForIdleSync();
}
- private void assertRatingViewIsChecked(int minAge, int maxAge, int selectedAge,
- boolean expectedValue) {
+ private void assertRatingViewIsChecked(
+ int minAge, int maxAge, int selectedAge, boolean expectedValue) {
for (int age = minAge; age <= maxAge; age++) {
- UiObject2 ratingCheckBox = mSidePanelHelper.assertNavigateToItem(String.valueOf(age))
- .findObject(ByResource.id(mTargetResources, R.id.check_box));
+ UiObject2 ratingCheckBox =
+ controller
+ .sidePanelHelper
+ .assertNavigateToItem(String.valueOf(age))
+ .findObject(
+ ByResource.id(controller.getTargetResources(), R.id.check_box));
if (age < selectedAge) {
assertTrue("The lower rating age should be unblocked", !ratingCheckBox.isChecked());
} else if (age > selectedAge) {
assertTrue("The higher rating age should be blocked", ratingCheckBox.isChecked());
} else {
- assertEquals("The rating for age " + selectedAge + " isBlocked ", expectedValue,
+ assertEquals(
+ "The rating for age " + selectedAge + " isBlocked ",
+ expectedValue,
ratingCheckBox.isChecked());
}
}
}
/**
- * Prepare the need for testRatingDependentSelect.
- * 1. Turn on parental control if it's off.
- * 2. Make sure Japan rating system is selected.
+ * Prepare the need for testRatingDependentSelect. 1. Turn on parental control if it's off. 2.
+ * Make sure Japan rating system is selected.
*/
private void prepareParentalControl() {
showParentalControl();
switchParentalControl(R.string.option_toggle_parental_controls_off);
// Show all rating systems.
- mSidePanelHelper.assertNavigateToItem(R.string.option_program_restrictions);
- mDevice.pressDPadCenter();
- BySelector bySidePanel = mSidePanelHelper.bySidePanelTitled(
- R.string.option_program_restrictions);
- assertWaitForCondition(mDevice, Until.hasObject(bySidePanel));
- mSidePanelHelper.assertNavigateToItem(R.string.option_country_rating_systems);
- mDevice.pressDPadCenter();
- bySidePanel = mSidePanelHelper.bySidePanelTitled(R.string.option_country_rating_systems);
- assertWaitForCondition(mDevice,Until.hasObject(bySidePanel));
- mSidePanelHelper.assertNavigateToItem(R.string.option_see_all_rating_systems);
- mDevice.pressDPadCenter();
+ controller.sidePanelHelper.assertNavigateToItem(R.string.option_program_restrictions);
+ controller.pressDPadCenter();
+ BySelector bySidePanel =
+ controller.sidePanelHelper.bySidePanelTitled(R.string.option_program_restrictions);
+ controller.assertWaitForCondition(Until.hasObject(bySidePanel));
+ controller.sidePanelHelper.assertNavigateToItem(R.string.option_country_rating_systems);
+ controller.pressDPadCenter();
+ bySidePanel =
+ controller.sidePanelHelper.bySidePanelTitled(
+ R.string.option_country_rating_systems);
+ controller.assertWaitForCondition(Until.hasObject(bySidePanel));
+ controller.sidePanelHelper.assertNavigateToItem(R.string.option_see_all_rating_systems);
+ controller.pressDPadCenter();
// Make sure Japan rating system is selected.
- UiObject2 ratingSystemCheckBox = mSidePanelHelper.assertNavigateToItem("Japan")
- .findObject(ByResource.id(mTargetResources, R.id.check_box));
+ UiObject2 ratingSystemCheckBox =
+ controller
+ .sidePanelHelper
+ .assertNavigateToItem("Japan")
+ .findObject(ByResource.id(controller.getTargetResources(), R.id.check_box));
if (!ratingSystemCheckBox.isChecked()) {
- mDevice.pressDPadCenter();
- getInstrumentation().waitForIdleSync();
+ controller.pressDPadCenter();
+ controller.waitForIdleSync();
}
- mDevice.pressBack();
+ controller.pressBack();
}
private void switchParentalControl(int oppositeStateResId) {
- BySelector bySidePanel = mSidePanelHelper.byViewText(oppositeStateResId);
- if (mDevice.hasObject(bySidePanel)) {
- mSidePanelHelper.assertNavigateToItem(oppositeStateResId);
- mDevice.pressDPadCenter();
- getInstrumentation().waitForIdleSync();
+ BySelector bySidePanel = controller.sidePanelHelper.byViewText(oppositeStateResId);
+ if (controller.getUiDevice().hasObject(bySidePanel)) {
+ controller.sidePanelHelper.assertNavigateToItem(oppositeStateResId);
+ controller.pressDPadCenter();
+ controller.waitForIdleSync();
}
}
private void showParentalControl() {
// Show menu and select parental controls.
- mMenuHelper.showMenu();
- mMenuHelper.assertPressOptionsSettings();
- assertWaitForCondition(mDevice, Until.hasObject(mBySettingsSidePanel));
- mSidePanelHelper.assertNavigateToItem(R.string.settings_parental_controls);
- mDevice.pressDPadCenter();
+ controller.menuHelper.showMenu();
+ controller.menuHelper.assertPressOptionsSettings();
+ controller.assertWaitForCondition(Until.hasObject(mBySettingsSidePanel));
+ controller.sidePanelHelper.assertNavigateToItem(R.string.settings_parental_controls);
+ controller.pressDPadCenter();
// Enter pin code.
- DialogHelper dialogHelper = new DialogHelper(mDevice, mTargetResources);
+ DialogHelper dialogHelper =
+ new DialogHelper(controller.getUiDevice(), controller.getTargetResources());
dialogHelper.assertWaitForPinDialogOpen();
dialogHelper.enterPinCodes();
dialogHelper.assertWaitForPinDialogClose();
- BySelector bySidePanel = mSidePanelHelper.bySidePanelTitled(
- R.string.menu_parental_controls);
- assertWaitForCondition(mDevice, Until.hasObject(bySidePanel));
+ BySelector bySidePanel =
+ controller.sidePanelHelper.bySidePanelTitled(R.string.menu_parental_controls);
+ controller.assertWaitForCondition(Until.hasObject(bySidePanel));
}
}
diff --git a/tests/func/src/com/android/tv/tests/ui/PlayControlsRowViewTest.java b/tests/func/src/com/android/tv/tests/ui/PlayControlsRowViewTest.java
index 82c6a810..7c982782 100644
--- a/tests/func/src/com/android/tv/tests/ui/PlayControlsRowViewTest.java
+++ b/tests/func/src/com/android/tv/tests/ui/PlayControlsRowViewTest.java
@@ -19,121 +19,136 @@ package com.android.tv.tests.ui;
import static com.android.tv.testing.uihelper.Constants.CHANNEL_BANNER;
import static com.android.tv.testing.uihelper.Constants.FOCUSED_VIEW;
import static com.android.tv.testing.uihelper.Constants.MENU;
-import static com.android.tv.testing.uihelper.UiDeviceAsserts.assertWaitForCondition;
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotNull;
import android.support.test.filters.SmallTest;
import android.support.test.uiautomator.BySelector;
import android.support.test.uiautomator.UiObject2;
import android.support.test.uiautomator.Until;
import android.view.KeyEvent;
-
import com.android.tv.R;
import com.android.tv.testing.testinput.TvTestInputConstants;
+import com.android.tv.testing.uihelper.Constants;
import com.android.tv.testing.uihelper.DialogHelper;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
@SmallTest
-public class PlayControlsRowViewTest extends LiveChannelsTestCase {
- private static final String BUTTON_ID_PLAY_PAUSE = "com.android.tv:id/play_pause";
+@RunWith(JUnit4.class)
+public class PlayControlsRowViewTest {
+ private static final String BUTTON_ID_PLAY_PAUSE = Constants.TV_APP_PACKAGE + ":id/play_pause";
+ @Rule public final LiveChannelsTestController controller = new LiveChannelsTestController();
private BySelector mBySettingsSidePanel;
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- mLiveChannelsHelper.assertAppStarted();
- pressKeysForChannel(TvTestInputConstants.CH_2);
+ @Before
+ public void setUp() throws Exception {
+
+ controller.liveChannelsHelper.assertAppStarted();
+ controller.pressKeysForChannel(TvTestInputConstants.CH_2);
// Wait until KeypadChannelSwitchView closes.
- assertWaitForCondition(mDevice, Until.hasObject(CHANNEL_BANNER));
+ controller.assertWaitForCondition(Until.hasObject(CHANNEL_BANNER));
// Tune to a new channel to ensure that the channel is changed.
- mDevice.pressDPadUp();
- getInstrumentation().waitForIdleSync();
- mBySettingsSidePanel = mSidePanelHelper.bySidePanelTitled(
- R.string.side_panel_title_settings);
+ controller.pressDPadUp();
+ controller.waitForIdleSync();
+ mBySettingsSidePanel =
+ controller.sidePanelHelper.bySidePanelTitled(R.string.side_panel_title_settings);
}
- /**
- * Test the normal case. The play/pause button should have focus initially.
- */
+ /** Test the normal case. The play/pause button should have focus initially. */
+ @Ignore("b/72154153")
+ @Test
public void testFocusedViewInNormalCase() {
- mMenuHelper.showMenu();
- mMenuHelper.assertNavigateToPlayControlsRow();
+ controller.menuHelper.showMenu();
+ controller.menuHelper.assertNavigateToPlayControlsRow();
assertButtonHasFocus(BUTTON_ID_PLAY_PAUSE);
- mDevice.pressBack();
+ controller.pressBack();
}
/**
- * Tests the case when the forwarding action is disabled.
- * In this case, the button corresponding to the action is disabled, so play/pause button should
- * have the focus.
+ * Tests the case when the forwarding action is disabled. In this case, the button corresponding
+ * to the action is disabled, so play/pause button should have the focus.
*/
+ @Test
public void testFocusedViewWithDisabledActionForward() {
// Fast forward button
- mDevice.pressKeyCode(KeyEvent.KEYCODE_MEDIA_FAST_FORWARD);
- mMenuHelper.assertWaitForMenu();
+ controller.pressKeyCode(KeyEvent.KEYCODE_MEDIA_FAST_FORWARD);
+ controller.menuHelper.assertWaitForMenu();
assertButtonHasFocus(BUTTON_ID_PLAY_PAUSE);
- mDevice.pressBack();
+ controller.pressBack();
// Next button
- mDevice.pressKeyCode(KeyEvent.KEYCODE_MEDIA_NEXT);
- mMenuHelper.assertWaitForMenu();
+ controller.pressKeyCode(KeyEvent.KEYCODE_MEDIA_NEXT);
+ controller.menuHelper.assertWaitForMenu();
assertButtonHasFocus(BUTTON_ID_PLAY_PAUSE);
- mDevice.pressBack();
+ controller.pressBack();
}
+ @Test
public void testFocusedViewInMenu() {
- mMenuHelper.showMenu();
- mDevice.pressKeyCode(KeyEvent.KEYCODE_MEDIA_PLAY);
+ controller.menuHelper.showMenu();
+ controller.pressKeyCode(KeyEvent.KEYCODE_MEDIA_PLAY);
assertButtonHasFocus(BUTTON_ID_PLAY_PAUSE);
- mMenuHelper.assertNavigateToRow(R.string.menu_title_channels);
- mDevice.pressKeyCode(KeyEvent.KEYCODE_MEDIA_NEXT);
+ controller.menuHelper.assertNavigateToRow(R.string.menu_title_channels);
+ controller.pressKeyCode(KeyEvent.KEYCODE_MEDIA_NEXT);
assertButtonHasFocus(BUTTON_ID_PLAY_PAUSE);
}
+ @Ignore("b/72154153")
+ @Test
public void testKeepPausedWhileParentalControlChange() {
// Pause the playback.
- mDevice.pressKeyCode(KeyEvent.KEYCODE_MEDIA_PAUSE);
- mMenuHelper.assertWaitForMenu();
+ controller.pressKeyCode(KeyEvent.KEYCODE_MEDIA_PAUSE);
+ controller.menuHelper.assertWaitForMenu();
assertButtonHasFocus(BUTTON_ID_PLAY_PAUSE);
// Show parental controls fragment.
- mMenuHelper.assertPressOptionsSettings();
- assertWaitForCondition(mDevice, Until.hasObject(mBySettingsSidePanel));
- mSidePanelHelper.assertNavigateToItem(R.string.settings_parental_controls);
- mDevice.pressDPadCenter();
- DialogHelper dialogHelper = new DialogHelper(mDevice, mTargetResources);
+ controller.menuHelper.assertPressOptionsSettings();
+ controller.assertWaitForCondition(Until.hasObject(mBySettingsSidePanel));
+ controller.sidePanelHelper.assertNavigateToItem(R.string.settings_parental_controls);
+ controller.pressDPadCenter();
+ DialogHelper dialogHelper =
+ new DialogHelper(controller.getUiDevice(), controller.getTargetResources());
dialogHelper.assertWaitForPinDialogOpen();
dialogHelper.enterPinCodes();
dialogHelper.assertWaitForPinDialogClose();
- BySelector bySidePanel = mSidePanelHelper.bySidePanelTitled(
- R.string.menu_parental_controls);
- assertWaitForCondition(mDevice, Until.hasObject(bySidePanel));
- mDevice.pressEnter();
- mDevice.pressEnter();
- mDevice.pressBack();
- mDevice.pressBack();
+ BySelector bySidePanel =
+ controller.sidePanelHelper.bySidePanelTitled(R.string.menu_parental_controls);
+ controller.assertWaitForCondition(Until.hasObject(bySidePanel));
+ controller.pressEnter();
+ controller.pressEnter();
+ controller.pressBack();
+ controller.pressBack();
// Return to the main menu.
- mMenuHelper.assertWaitForMenu();
+ controller.menuHelper.assertWaitForMenu();
assertButtonHasFocus(BUTTON_ID_PLAY_PAUSE);
}
+ // TODO("b/70727167"): fix tests
+ @Test
public void testKeepPausedAfterVisitingHome() {
// Pause the playback.
- mDevice.pressKeyCode(KeyEvent.KEYCODE_MEDIA_PAUSE);
- mMenuHelper.assertWaitForMenu();
+ controller.pressKeyCode(KeyEvent.KEYCODE_MEDIA_PAUSE);
+ controller.menuHelper.assertWaitForMenu();
assertButtonHasFocus(BUTTON_ID_PLAY_PAUSE);
// Press HOME twice to visit the home screen and return to Live TV.
- mDevice.pressHome();
+ controller.pressHome();
// Wait until home screen is shown.
- mDevice.waitForIdle();
- mDevice.pressHome();
+ controller.waitForIdle();
+ controller.pressHome();
// Wait until TV is resumed.
- mDevice.waitForIdle();
+ controller.waitForIdle();
// Return to the main menu.
- mMenuHelper.assertWaitForMenu();
+ controller.menuHelper.assertWaitForMenu();
assertButtonHasFocus(BUTTON_ID_PLAY_PAUSE);
}
private void assertButtonHasFocus(String buttonId) {
- UiObject2 menu = mDevice.findObject(MENU);
+ UiObject2 menu = controller.getUiDevice().findObject(MENU);
UiObject2 focusedView = menu.findObject(FOCUSED_VIEW);
assertNotNull("Play controls row doesn't have a focused child.", focusedView);
UiObject2 focusedButtonGroup = focusedView.getParent();
diff --git a/tests/func/src/com/android/tv/tests/ui/ProgramGuideTest.java b/tests/func/src/com/android/tv/tests/ui/ProgramGuideTest.java
index 06c76b3b..4adf448a 100644
--- a/tests/func/src/com/android/tv/tests/ui/ProgramGuideTest.java
+++ b/tests/func/src/com/android/tv/tests/ui/ProgramGuideTest.java
@@ -15,28 +15,28 @@
*/
package com.android.tv.tests.ui;
-import static com.android.tv.testing.uihelper.UiDeviceAsserts.assertHas;
-import static com.android.tv.testing.uihelper.UiDeviceAsserts.assertWaitForCondition;
-
-import android.support.test.filters.LargeTest;
+import android.support.test.filters.MediumTest;
import android.support.test.uiautomator.Until;
-
import com.android.tv.guide.ProgramGuide;
import com.android.tv.testing.uihelper.Constants;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
-/**
- * Tests for {@link ProgramGuide}.
- */
-@LargeTest
-public class ProgramGuideTest extends LiveChannelsTestCase {
+/** Tests for {@link ProgramGuide}. */
+@MediumTest
+@RunWith(JUnit4.class)
+public class ProgramGuideTest {
+ @Rule public final LiveChannelsTestController controller = new LiveChannelsTestController();
+ @Test
public void testCancel() {
- mLiveChannelsHelper.assertAppStarted();
- mMenuHelper.assertPressProgramGuide();
- assertWaitForCondition(mDevice,
- Until.hasObject(Constants.PROGRAM_GUIDE));
- mDevice.pressBack();
- assertWaitForCondition(mDevice, Until.gone(Constants.PROGRAM_GUIDE));
- assertHas(mDevice, Constants.MENU, false);
+ controller.liveChannelsHelper.assertAppStarted();
+ controller.menuHelper.assertPressProgramGuide();
+ controller.assertWaitForCondition(Until.hasObject(Constants.PROGRAM_GUIDE));
+ controller.pressBack();
+ controller.assertWaitForCondition(Until.gone(Constants.PROGRAM_GUIDE));
+ controller.assertHas(Constants.MENU, false);
}
}
diff --git a/tests/func/src/com/android/tv/tests/ui/TimeoutTest.java b/tests/func/src/com/android/tv/tests/ui/TimeoutTest.java
index 9bf2ac50..4b6befe4 100644
--- a/tests/func/src/com/android/tv/tests/ui/TimeoutTest.java
+++ b/tests/func/src/com/android/tv/tests/ui/TimeoutTest.java
@@ -15,40 +15,54 @@
*/
package com.android.tv.tests.ui;
-import static com.android.tv.testing.uihelper.UiDeviceAsserts.assertHas;
-import static com.android.tv.testing.uihelper.UiDeviceAsserts.assertWaitForCondition;
-
import android.support.test.filters.LargeTest;
import android.support.test.uiautomator.Until;
-
import com.android.tv.R;
import com.android.tv.testing.uihelper.Constants;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
/**
* Test timeout events like the menu despairing after no input.
- * <p>
- * <b>WARNING</b> some of these timeouts are 60 seconds. These tests will take a long time
+ *
+ * <p><b>WARNING</b> some of these timeouts are 60 seconds. These tests will take a long time
* complete.
*/
@LargeTest
-public class TimeoutTest extends LiveChannelsTestCase {
+@RunWith(JUnit4.class)
+public class TimeoutTest {
+
+ @Rule public final LiveChannelsTestController controller = new LiveChannelsTestController();
+
+ @Test
+ public void placeholder() {
+ // There must be at least one test
+ }
+ @Ignore("b/73727914")
+ @Test
public void testMenu() {
- mLiveChannelsHelper.assertAppStarted();
- mDevice.pressMenu();
+ controller.liveChannelsHelper.assertAppStarted();
+ controller.pressMenu();
- assertWaitForCondition(mDevice, Until.hasObject(Constants.MENU));
- assertWaitForCondition(mDevice, Until.gone(Constants.MENU),
- mTargetResources.getInteger(R.integer.menu_show_duration));
+ controller.assertWaitForCondition(Until.hasObject(Constants.MENU));
+ controller.assertWaitForCondition(
+ Until.gone(Constants.MENU),
+ controller.getTargetResources().getInteger(R.integer.menu_show_duration));
}
+ @Ignore("b/73727914")
+ @Test
public void testProgramGuide() {
- mLiveChannelsHelper.assertAppStarted();
- mMenuHelper.assertPressProgramGuide();
- assertWaitForCondition(mDevice,
- Until.hasObject(Constants.PROGRAM_GUIDE));
- assertWaitForCondition(mDevice, Until.gone(Constants.PROGRAM_GUIDE),
- mTargetResources.getInteger(R.integer.program_guide_show_duration));
- assertHas(mDevice, Constants.MENU, false);
+ controller.liveChannelsHelper.assertAppStarted();
+ controller.menuHelper.assertPressProgramGuide();
+ controller.assertWaitForCondition(Until.hasObject(Constants.PROGRAM_GUIDE));
+ controller.assertWaitForCondition(
+ Until.gone(Constants.PROGRAM_GUIDE),
+ controller.getTargetResources().getInteger(R.integer.program_guide_show_duration));
+ controller.assertHas(Constants.MENU, false);
}
}
diff --git a/tests/func/src/com/android/tv/tests/ui/dvr/DvrLibraryTest.java b/tests/func/src/com/android/tv/tests/ui/dvr/DvrLibraryTest.java
index d88e67ad..d0ebed91 100644
--- a/tests/func/src/com/android/tv/tests/ui/dvr/DvrLibraryTest.java
+++ b/tests/func/src/com/android/tv/tests/ui/dvr/DvrLibraryTest.java
@@ -16,8 +16,6 @@
package com.android.tv.tests.ui.dvr;
-import static com.android.tv.testing.uihelper.UiDeviceAsserts.assertHas;
-import static com.android.tv.testing.uihelper.UiDeviceAsserts.assertWaitForCondition;
import static com.android.tv.testing.uihelper.UiDeviceAsserts.assertWaitUntilFocused;
import android.os.Build;
@@ -25,195 +23,302 @@ import android.support.test.filters.MediumTest;
import android.support.test.filters.SdkSuppress;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.BySelector;
-import android.support.test.uiautomator.UiObject2;
import android.support.test.uiautomator.Until;
-
import com.android.tv.R;
import com.android.tv.testing.uihelper.ByResource;
import com.android.tv.testing.uihelper.Constants;
-import com.android.tv.tests.ui.LiveChannelsTestCase;
-
+import com.android.tv.tests.ui.LiveChannelsTestController;
import java.util.regex.Pattern;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+/** Test the DVR library UI */
@MediumTest
+@RunWith(JUnit4.class)
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
-public class DvrLibraryTest extends LiveChannelsTestCase {
+public class DvrLibraryTest {
private static final String PROGRAM_NAME_PREFIX = "Title(";
+ @Rule public final LiveChannelsTestController controller = new LiveChannelsTestController();
+
private BySelector mRecentRow;
private BySelector mScheduledRow;
private BySelector mSeriesRow;
private BySelector mFullScheduleCard;
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- mRecentRow = By.hasDescendant(ByResource.text(mTargetResources, R.string.dvr_main_recent));
- mScheduledRow = By.hasDescendant(
- ByResource.text(mTargetResources, R.string.dvr_main_scheduled));
- mSeriesRow = By.hasDescendant(ByResource.text(mTargetResources, R.string.dvr_main_series));
- mFullScheduleCard = By.focusable(true).hasDescendant(
- ByResource.text(mTargetResources, R.string.dvr_full_schedule_card_view_title));
- mLiveChannelsHelper.assertAppStarted();
+ @Before
+ public void setUp() throws Exception {
+
+ mRecentRow =
+ By.hasDescendant(
+ ByResource.text(controller.getTargetResources(), R.string.dvr_main_recent));
+ mScheduledRow =
+ By.hasDescendant(
+ ByResource.text(
+ controller.getTargetResources(), R.string.dvr_main_scheduled));
+ mSeriesRow =
+ By.hasDescendant(
+ ByResource.text(controller.getTargetResources(), R.string.dvr_main_series));
+ mFullScheduleCard =
+ By.focusable(true)
+ .hasDescendant(
+ ByResource.text(
+ controller.getTargetResources(),
+ R.string.dvr_full_schedule_card_view_title));
+ controller.liveChannelsHelper.assertAppStarted();
}
+ @Test
+ public void placeholder() {
+ // TODO(b/72153742): three must be at least one test
+ }
+
+ @Ignore("b/72153742")
+ @Test
public void testCancel() {
- mMenuHelper.assertPressDvrLibrary();
- assertWaitForCondition(mDevice, Until.hasObject(Constants.DVR_LIBRARY));
- mDevice.pressBack();
- assertWaitForCondition(mDevice, Until.gone(Constants.DVR_LIBRARY));
- assertHas(mDevice, Constants.MENU, false);
+ controller.menuHelper.assertPressDvrLibrary();
+ controller.assertWaitForCondition(Until.hasObject(Constants.DVR_LIBRARY));
+ controller.pressBack();
+ controller.assertWaitForCondition(Until.gone(Constants.DVR_LIBRARY));
+ controller.assertHas(Constants.MENU, false);
}
+ @Ignore("b/72153742")
+ @Test
public void testEmptyLibrary() {
- mMenuHelper.assertPressDvrLibrary();
- assertWaitForCondition(mDevice, Until.hasObject(Constants.DVR_LIBRARY));
+ controller.menuHelper.assertPressDvrLibrary();
+ controller.assertWaitForCondition(Until.hasObject(Constants.DVR_LIBRARY));
// DVR Library is empty, only Scheduled row and Full schedule card should be displayed.
- assertHas(mDevice, mRecentRow, false);
- assertHas(mDevice, mScheduledRow, true);
- assertHas(mDevice, mSeriesRow, false);
+ controller.assertHas(mRecentRow, false);
+ controller.assertHas(mScheduledRow, true);
+ controller.assertHas(mSeriesRow, false);
- mDevice.pressDPadCenter();
- assertWaitUntilFocused(mDevice, mFullScheduleCard);
- mDevice.pressDPadCenter();
- assertWaitForCondition(mDevice, Until.gone(Constants.DVR_LIBRARY));
+ controller.pressDPadCenter();
+ assertWaitUntilFocused(controller.getUiDevice(), mFullScheduleCard);
+ controller.pressDPadCenter();
+ controller.assertWaitForCondition(Until.gone(Constants.DVR_LIBRARY));
// Empty schedules screen should be shown.
- assertHas(mDevice, Constants.DVR_SCHEDULES, true);
- assertHas(mDevice, ByResource.text(mTargetResources, R.string.dvr_schedules_empty_state),
+ controller.assertHas(Constants.DVR_SCHEDULES, true);
+ controller.assertHas(
+ ByResource.text(
+ controller.getTargetResources(), R.string.dvr_schedules_empty_state),
true);
// Close the DVR library.
- mDevice.pressBack();
- assertWaitForCondition(mDevice, Until.hasObject(Constants.DVR_LIBRARY));
- mDevice.pressBack();
- assertWaitForCondition(mDevice, Until.gone(Constants.DVR_LIBRARY));
+ controller.pressBack();
+ controller.assertWaitForCondition(Until.hasObject(Constants.DVR_LIBRARY));
+ controller.pressBack();
+ controller.assertWaitForCondition(Until.gone(Constants.DVR_LIBRARY));
}
+ @Ignore("b/72153742")
+ @Test
public void testScheduleRecordings() {
- BySelector newScheduleCard = By.focusable(true).hasDescendant(
- By.textStartsWith(PROGRAM_NAME_PREFIX)).hasDescendant(By.textEndsWith("today"));
- BySelector seriesCardWithOneSchedule = By.focusable(true).hasDescendant(
- By.textStartsWith(PROGRAM_NAME_PREFIX)).hasDescendant(By.text(mTargetResources
- .getQuantityString(R.plurals.dvr_count_scheduled_recordings, 1, 1)));
- BySelector seriesCardWithOneRecordedProgram = By.focusable(true).hasDescendant(
- By.textStartsWith(PROGRAM_NAME_PREFIX)).hasDescendant(By.text(mTargetResources
- .getQuantityString(R.plurals.dvr_count_new_recordings, 1, 1)));
- Pattern watchButton = Pattern.compile("^" + mTargetResources
- .getString(R.string.dvr_detail_watch).toUpperCase() + "\n.*$");
-
- mMenuHelper.showMenu();
- mMenuHelper.assertNavigateToPlayControlsRow();
- mDevice.pressDPadRight();
- mDevice.pressDPadCenter();
- assertWaitForCondition(mDevice, Until.hasObject(
- ByResource.text(mTargetResources, R.string.dvr_action_record_episode)));
- mDevice.pressDPadCenter();
- assertWaitForCondition(mDevice, Until.gone(
- ByResource.text(mTargetResources, R.string.dvr_action_record_episode)));
-
- mMenuHelper.assertPressDvrLibrary();
- assertWaitForCondition(mDevice, Until.hasObject(Constants.DVR_LIBRARY));
+ BySelector newScheduleCard =
+ By.focusable(true)
+ .hasDescendant(By.textStartsWith(PROGRAM_NAME_PREFIX))
+ .hasDescendant(By.textEndsWith("today"));
+ BySelector seriesCardWithOneSchedule =
+ By.focusable(true)
+ .hasDescendant(By.textStartsWith(PROGRAM_NAME_PREFIX))
+ .hasDescendant(
+ By.text(
+ controller
+ .getTargetResources()
+ .getQuantityString(
+ R.plurals.dvr_count_scheduled_recordings,
+ 1,
+ 1)));
+ BySelector seriesCardWithOneRecordedProgram =
+ By.focusable(true)
+ .hasDescendant(By.textStartsWith(PROGRAM_NAME_PREFIX))
+ .hasDescendant(
+ By.text(
+ controller
+ .getTargetResources()
+ .getQuantityString(
+ R.plurals.dvr_count_new_recordings, 1, 1)));
+ Pattern watchButton =
+ Pattern.compile(
+ "^"
+ + controller
+ .getTargetResources()
+ .getString(R.string.dvr_detail_watch)
+ .toUpperCase()
+ + "\n.*$");
+
+ controller.menuHelper.showMenu();
+ controller.menuHelper.assertNavigateToPlayControlsRow();
+ controller.pressDPadRight();
+ controller.pressDPadCenter();
+ controller.assertWaitForCondition(
+ Until.hasObject(
+ ByResource.text(
+ controller.getTargetResources(),
+ R.string.dvr_action_record_episode)));
+ controller.pressDPadCenter();
+ controller.assertWaitForCondition(
+ Until.gone(
+ ByResource.text(
+ controller.getTargetResources(),
+ R.string.dvr_action_record_episode)));
+
+ controller.menuHelper.assertPressDvrLibrary();
+ controller.assertWaitForCondition(Until.hasObject(Constants.DVR_LIBRARY));
// Schedule should be automatically added to the series.
- assertHas(mDevice, mRecentRow, false);
- assertHas(mDevice, mScheduledRow, true);
- assertHas(mDevice, mSeriesRow, true);
- String programName = mDevice.findObject(By.textStartsWith(PROGRAM_NAME_PREFIX)).getText();
+ controller.assertHas(mRecentRow, false);
+ controller.assertHas(mScheduledRow, true);
+ controller.assertHas(mSeriesRow, true);
+ String programName =
+ controller
+ .getUiDevice()
+ .findObject(By.textStartsWith(PROGRAM_NAME_PREFIX))
+ .getText();
// Move to scheduled row, there should be one new schedule and one full schedule card.
- mDevice.pressDPadRight();
- assertWaitUntilFocused(mDevice, newScheduleCard);
- mDevice.pressDPadRight();
- assertWaitUntilFocused(mDevice, mFullScheduleCard);
+ controller.pressDPadRight();
+ controller.assertWaitUntilFocused(newScheduleCard);
+ controller.pressDPadRight();
+ controller.assertWaitUntilFocused(mFullScheduleCard);
// Enters the full schedule, there should be one schedule in the full schedule.
- mDevice.pressDPadCenter();
- assertWaitForCondition(mDevice, Until.gone(Constants.DVR_LIBRARY));
- assertHas(mDevice, Constants.DVR_SCHEDULES, true);
- assertHas(mDevice, ByResource.text(mTargetResources, R.string.dvr_schedules_empty_state),
+ controller.pressDPadCenter();
+ controller.assertWaitForCondition(Until.gone(Constants.DVR_LIBRARY));
+ controller.assertHas(Constants.DVR_SCHEDULES, true);
+ controller.assertHas(
+ ByResource.text(
+ controller.getTargetResources(), R.string.dvr_schedules_empty_state),
false);
- assertHas(mDevice, By.textStartsWith(programName), true);
+ controller.assertHas(By.textStartsWith(programName), true);
// Moves to the series card, clicks it, the detail page should be shown with "View schedule"
// button.
- mDevice.pressBack();
- assertWaitForCondition(mDevice, Until.hasObject(Constants.DVR_LIBRARY));
- mDevice.pressDPadLeft();
- assertWaitUntilFocused(mDevice, newScheduleCard);
- mDevice.pressDPadDown();
- assertWaitUntilFocused(mDevice, seriesCardWithOneSchedule);
- mDevice.pressDPadCenter();
- assertWaitForCondition(mDevice, Until.gone(Constants.DVR_LIBRARY));
- assertHas(mDevice, By.text(mTargetResources
- .getString(R.string.dvr_detail_view_schedule).toUpperCase()), true);
- assertHas(mDevice, By.text(watchButton), false);
- assertHas(mDevice, By.text(mTargetResources
- .getString(R.string.dvr_detail_series_delete).toUpperCase()), false);
+ controller.pressBack();
+ controller.assertWaitForCondition(Until.hasObject(Constants.DVR_LIBRARY));
+ controller.pressDPadLeft();
+ controller.assertWaitUntilFocused(newScheduleCard);
+ controller.pressDPadDown();
+ controller.assertWaitUntilFocused(seriesCardWithOneSchedule);
+ controller.pressDPadCenter();
+ controller.assertWaitForCondition(Until.gone(Constants.DVR_LIBRARY));
+ controller.assertHas(
+ By.text(
+ controller
+ .getTargetResources()
+ .getString(R.string.dvr_detail_view_schedule)
+ .toUpperCase()),
+ true);
+ controller.assertHas(By.text(watchButton), false);
+ controller.assertHas(
+ By.text(
+ controller
+ .getTargetResources()
+ .getString(R.string.dvr_detail_series_delete)
+ .toUpperCase()),
+ false);
// Clicks the new schedule, the detail page should be shown with "Stop recording" button.
- mDevice.pressBack();
- assertWaitForCondition(mDevice, Until.hasObject(Constants.DVR_LIBRARY));
- assertWaitUntilFocused(mDevice, seriesCardWithOneSchedule);
- mDevice.pressDPadUp();
- assertWaitUntilFocused(mDevice, newScheduleCard);
- mDevice.pressDPadCenter();
- assertWaitForCondition(mDevice, Until.gone(Constants.DVR_LIBRARY));
- assertHas(mDevice, By.text(mTargetResources
- .getString(R.string.dvr_detail_stop_recording).toUpperCase()), true);
+ controller.pressBack();
+ controller.assertWaitForCondition(Until.hasObject(Constants.DVR_LIBRARY));
+ controller.assertWaitUntilFocused(seriesCardWithOneSchedule);
+ controller.pressDPadUp();
+ controller.assertWaitUntilFocused(newScheduleCard);
+ controller.pressDPadCenter();
+ controller.assertWaitForCondition(Until.gone(Constants.DVR_LIBRARY));
+ controller.assertHas(
+ By.text(
+ controller
+ .getTargetResources()
+ .getString(R.string.dvr_detail_stop_recording)
+ .toUpperCase()),
+ true);
// Stops the recording
- mDevice.pressDPadCenter();
- assertWaitForCondition(mDevice, Until.hasObject(
- ByResource.text(mTargetResources, R.string.dvr_action_stop)));
- mDevice.pressDPadCenter();
- assertWaitForCondition(mDevice, Until.gone(
- ByResource.text(mTargetResources, R.string.dvr_action_stop)));
- assertWaitForCondition(mDevice, Until.hasObject(Constants.DVR_LIBRARY));
- assertWaitUntilFocused(mDevice, mFullScheduleCard);
+ controller.pressDPadCenter();
+ controller.assertWaitForCondition(
+ Until.hasObject(
+ ByResource.text(
+ controller.getTargetResources(), R.string.dvr_action_stop)));
+ controller.pressDPadCenter();
+ controller.assertWaitForCondition(
+ Until.gone(
+ ByResource.text(
+ controller.getTargetResources(), R.string.dvr_action_stop)));
+ controller.assertWaitForCondition(Until.hasObject(Constants.DVR_LIBRARY));
+ controller.assertWaitUntilFocused(mFullScheduleCard);
// Moves to series' detail page again, now it should have two more buttons
- mDevice.pressDPadDown();
- assertWaitUntilFocused(mDevice, seriesCardWithOneRecordedProgram);
- mDevice.pressDPadCenter();
- assertWaitForCondition(mDevice, Until.gone(Constants.DVR_LIBRARY));
- assertHas(mDevice, By.text(watchButton), true);
- assertHas(mDevice, By.text(mTargetResources
- .getString(R.string.dvr_detail_view_schedule).toUpperCase()), true);
- assertHas(mDevice, By.text(mTargetResources
- .getString(R.string.dvr_detail_series_delete).toUpperCase()), true);
+ controller.pressDPadDown();
+ controller.assertWaitUntilFocused(seriesCardWithOneRecordedProgram);
+ controller.pressDPadCenter();
+ controller.assertWaitForCondition(Until.gone(Constants.DVR_LIBRARY));
+ controller.assertHas(By.text(watchButton), true);
+ controller.assertHas(
+ By.text(
+ controller
+ .getTargetResources()
+ .getString(R.string.dvr_detail_view_schedule)
+ .toUpperCase()),
+ true);
+ controller.assertHas(
+ By.text(
+ controller
+ .getTargetResources()
+ .getString(R.string.dvr_detail_series_delete)
+ .toUpperCase()),
+ true);
// Moves to the recent row and clicks the recent recorded program.
- mDevice.pressBack();
- assertWaitForCondition(mDevice, Until.hasObject(Constants.DVR_LIBRARY));
- assertWaitUntilFocused(mDevice, seriesCardWithOneRecordedProgram);
- mDevice.pressDPadUp();
- assertWaitUntilFocused(mDevice, mFullScheduleCard);
- mDevice.pressDPadUp();
- assertWaitUntilFocused(mDevice, By.focusable(true).hasDescendant(By.text(programName)));
- mDevice.pressDPadCenter();
- assertWaitForCondition(mDevice, Until.gone(Constants.DVR_LIBRARY));
- assertHas(mDevice, By.text(mTargetResources
- .getString(R.string.dvr_detail_watch).toUpperCase()), true);
- assertHas(mDevice, By.text(mTargetResources
- .getString(R.string.dvr_detail_delete).toUpperCase()), true);
+ controller.pressBack();
+ controller.assertWaitForCondition(Until.hasObject(Constants.DVR_LIBRARY));
+ controller.assertWaitUntilFocused(seriesCardWithOneRecordedProgram);
+ controller.pressDPadUp();
+ controller.assertWaitUntilFocused(mFullScheduleCard);
+ controller.pressDPadUp();
+ controller.assertWaitUntilFocused(By.focusable(true).hasDescendant(By.text(programName)));
+ controller.pressDPadCenter();
+ controller.assertWaitForCondition(Until.gone(Constants.DVR_LIBRARY));
+ controller.assertHas(
+ By.text(
+ controller
+ .getTargetResources()
+ .getString(R.string.dvr_detail_watch)
+ .toUpperCase()),
+ true);
+ controller.assertHas(
+ By.text(
+ controller
+ .getTargetResources()
+ .getString(R.string.dvr_detail_delete)
+ .toUpperCase()),
+ true);
// Moves to the delete button and clicks to remove the recorded program.
- mDevice.pressDPadRight();
- assertWaitUntilFocused(mDevice, By.text(mTargetResources
- .getString(R.string.dvr_detail_delete).toUpperCase()));
- mDevice.pressDPadCenter();
- assertWaitForCondition(mDevice, Until.hasObject(Constants.DVR_LIBRARY));
- assertWaitUntilFocused(mDevice, mFullScheduleCard);
+ controller.pressDPadRight();
+ controller.assertWaitUntilFocused(
+ By.text(
+ controller
+ .getTargetResources()
+ .getString(R.string.dvr_detail_delete)
+ .toUpperCase()));
+ controller.pressDPadCenter();
+ controller.assertWaitForCondition(Until.hasObject(Constants.DVR_LIBRARY));
+ controller.assertWaitUntilFocused(mFullScheduleCard);
// DVR Library should be empty now.
- assertHas(mDevice, mRecentRow, false);
- assertHas(mDevice, mScheduledRow, true);
- assertHas(mDevice, mSeriesRow, false);
+ controller.assertHas(mRecentRow, false);
+ controller.assertHas(mScheduledRow, true);
+ controller.assertHas(mSeriesRow, false);
// Close the DVR library.
- mDevice.pressBack();
- assertWaitForCondition(mDevice, Until.gone(Constants.DVR_LIBRARY));
+ controller.pressBack();
+ controller.assertWaitForCondition(Until.gone(Constants.DVR_LIBRARY));
}
}
diff --git a/tests/func/src/com/android/tv/tests/ui/sidepanel/CustomizeChannelListFragmentTest.java b/tests/func/src/com/android/tv/tests/ui/sidepanel/CustomizeChannelListFragmentTest.java
index deeb9bfd..09b855e2 100644
--- a/tests/func/src/com/android/tv/tests/ui/sidepanel/CustomizeChannelListFragmentTest.java
+++ b/tests/func/src/com/android/tv/tests/ui/sidepanel/CustomizeChannelListFragmentTest.java
@@ -16,37 +16,48 @@
package com.android.tv.tests.ui.sidepanel;
-import static com.android.tv.testing.uihelper.UiDeviceAsserts.assertWaitForCondition;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertTrue;
import android.graphics.Point;
-import android.support.test.filters.LargeTest;
+import android.support.test.filters.MediumTest;
import android.support.test.uiautomator.BySelector;
import android.support.test.uiautomator.Direction;
import android.support.test.uiautomator.UiObject2;
import android.support.test.uiautomator.Until;
-
import com.android.tv.R;
import com.android.tv.testing.uihelper.Constants;
-import com.android.tv.tests.ui.LiveChannelsTestCase;
+import com.android.tv.tests.ui.LiveChannelsTestController;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** Tests for @{link {@link com.android.tv.ui.sidepanel.CustomizeChannelListFragment} */
+@MediumTest
+@RunWith(JUnit4.class)
+public class CustomizeChannelListFragmentTest {
-@LargeTest
-public class CustomizeChannelListFragmentTest extends LiveChannelsTestCase {
+ @Rule public final LiveChannelsTestController controller = new LiveChannelsTestController();
private BySelector mBySettingsSidePanel;
private UiObject2 mTvView;
private Point mNormalTvViewCenter;
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- mLiveChannelsHelper.assertAppStarted();
- mTvView = mDevice.findObject(Constants.TV_VIEW);
+ @Before
+ public void setUp() throws Exception {
+
+ controller.liveChannelsHelper.assertAppStarted();
+ mTvView = controller.getUiDevice().findObject(Constants.TV_VIEW);
mNormalTvViewCenter = mTvView.getVisibleCenter();
assertNotNull(mNormalTvViewCenter);
- pressKeysForChannel(com.android.tv.testing.testinput.TvTestInputConstants.CH_2);
+ controller.pressKeysForChannel(com.android.tv.testing.testinput.TvTestInputConstants.CH_2);
// Wait until KeypadChannelSwitchView closes.
- assertWaitForCondition(mDevice, Until.hasObject(Constants.CHANNEL_BANNER));
- mBySettingsSidePanel = mSidePanelHelper.bySidePanelTitled(
- R.string.side_panel_title_settings);
+ controller.assertWaitForCondition(Until.hasObject(Constants.CHANNEL_BANNER));
+ mBySettingsSidePanel =
+ controller.sidePanelHelper.bySidePanelTitled(R.string.side_panel_title_settings);
}
private void assertShrunkenTvView(boolean shrunkenExpected) {
@@ -58,60 +69,71 @@ public class CustomizeChannelListFragmentTest extends LiveChannelsTestCase {
}
}
+ @Test
public void testCustomizeChannelList_noraml() {
// Show customize channel list fragment
- mMenuHelper.assertPressOptionsSettings();
- assertWaitForCondition(mDevice, Until.hasObject(mBySettingsSidePanel));
- mSidePanelHelper.assertNavigateToItem(
+ controller.menuHelper.assertPressOptionsSettings();
+ controller.assertWaitForCondition(Until.hasObject(mBySettingsSidePanel));
+ controller.sidePanelHelper.assertNavigateToItem(
R.string.settings_channel_source_item_customize_channels);
- mDevice.pressDPadCenter();
- BySelector bySidePanel = mSidePanelHelper.bySidePanelTitled(
- R.string.side_panel_title_edit_channels_for_an_input);
- assertWaitForCondition(mDevice, Until.hasObject(bySidePanel));
+ controller.pressDPadCenter();
+ BySelector bySidePanel =
+ controller.sidePanelHelper.bySidePanelTitled(
+ R.string.side_panel_title_edit_channels_for_an_input);
+ controller.assertWaitForCondition(Until.hasObject(bySidePanel));
assertShrunkenTvView(true);
// Show group by fragment
- mSidePanelHelper.assertNavigateToItem(R.string.edit_channels_item_group_by, Direction.UP);
- mDevice.pressDPadCenter();
- bySidePanel = mSidePanelHelper.bySidePanelTitled(R.string.side_panel_title_group_by);
- assertWaitForCondition(mDevice, Until.hasObject(bySidePanel));
+ controller.sidePanelHelper.assertNavigateToItem(
+ R.string.edit_channels_item_group_by, Direction.UP);
+ controller.pressDPadCenter();
+ bySidePanel =
+ controller.sidePanelHelper.bySidePanelTitled(R.string.side_panel_title_group_by);
+ controller.assertWaitForCondition(Until.hasObject(bySidePanel));
assertShrunkenTvView(true);
// Back to customize channel list fragment
- mDevice.pressBack();
- bySidePanel = mSidePanelHelper.bySidePanelTitled(
- R.string.side_panel_title_edit_channels_for_an_input);
- assertWaitForCondition(mDevice, Until.hasObject(bySidePanel));
+ controller.pressBack();
+ bySidePanel =
+ controller.sidePanelHelper.bySidePanelTitled(
+ R.string.side_panel_title_edit_channels_for_an_input);
+ controller.assertWaitForCondition(Until.hasObject(bySidePanel));
assertShrunkenTvView(true);
// Return to the main menu.
- mDevice.pressBack();
- assertWaitForCondition(mDevice, Until.hasObject(mBySettingsSidePanel));
+ controller.pressBack();
+ controller.assertWaitForCondition(Until.hasObject(mBySettingsSidePanel));
assertShrunkenTvView(false);
}
+ @Ignore("b/73727914")
+ @Test
public void testCustomizeChannelList_timeout() {
// Show customize channel list fragment
- mMenuHelper.assertPressOptionsSettings();
- assertWaitForCondition(mDevice, Until.hasObject(mBySettingsSidePanel));
- mSidePanelHelper.assertNavigateToItem(
+ controller.menuHelper.assertPressOptionsSettings();
+ controller.assertWaitForCondition(Until.hasObject(mBySettingsSidePanel));
+ controller.sidePanelHelper.assertNavigateToItem(
R.string.settings_channel_source_item_customize_channels);
- mDevice.pressDPadCenter();
- BySelector bySidePanel = mSidePanelHelper.bySidePanelTitled(
- R.string.side_panel_title_edit_channels_for_an_input);
- assertWaitForCondition(mDevice, Until.hasObject(bySidePanel));
+ controller.pressDPadCenter();
+ BySelector bySidePanel =
+ controller.sidePanelHelper.bySidePanelTitled(
+ R.string.side_panel_title_edit_channels_for_an_input);
+ controller.assertWaitForCondition(Until.hasObject(bySidePanel));
assertShrunkenTvView(true);
// Show group by fragment
- mSidePanelHelper.assertNavigateToItem(R.string.edit_channels_item_group_by, Direction.UP);
- mDevice.pressDPadCenter();
- bySidePanel = mSidePanelHelper.bySidePanelTitled(R.string.side_panel_title_group_by);
- assertWaitForCondition(mDevice, Until.hasObject(bySidePanel));
+ controller.sidePanelHelper.assertNavigateToItem(
+ R.string.edit_channels_item_group_by, Direction.UP);
+ controller.pressDPadCenter();
+ bySidePanel =
+ controller.sidePanelHelper.bySidePanelTitled(R.string.side_panel_title_group_by);
+ controller.assertWaitForCondition(Until.hasObject(bySidePanel));
assertShrunkenTvView(true);
// Wait for time-out to return to the main menu.
- assertWaitForCondition(mDevice, Until.gone(bySidePanel),
- mTargetResources.getInteger(R.integer.side_panel_show_duration));
+ controller.assertWaitForCondition(
+ Until.gone(bySidePanel),
+ controller.getTargetResources().getInteger(R.integer.side_panel_show_duration));
assertShrunkenTvView(false);
}
}
diff --git a/tests/input/Android.mk b/tests/input/Android.mk
index 2efd32b9..46b5621c 100644
--- a/tests/input/Android.mk
+++ b/tests/input/Android.mk
@@ -8,7 +8,7 @@ LOCAL_MODULE_TAGS := optional
LOCAL_PROGUARD_ENABLED := disabled
# Overlay view related functionality requires system APIs.
LOCAL_SDK_VERSION := system_current
-LOCAL_MIN_SDK_VERSION := 23 # M
+LOCAL_PROGUARD_ENABLED := disabled
LOCAL_STATIC_JAVA_LIBRARIES := \
tv-test-common \
diff --git a/tests/input/AndroidManifest.xml b/tests/input/AndroidManifest.xml
index 14491449..9b5df2ff 100644
--- a/tests/input/AndroidManifest.xml
+++ b/tests/input/AndroidManifest.xml
@@ -18,7 +18,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.tv.testinput">
- <uses-sdk android:targetSdkVersion="23" android:minSdkVersion="23"/>
+ <uses-sdk android:targetSdkVersion="26" android:minSdkVersion="23"/>
<!-- Required to update or read existing channel and program information in TvProvider. -->
<uses-permission android:name="com.android.providers.tv.permission.READ_EPG_DATA" />
diff --git a/tests/input/func.sh b/tests/input/func.sh
new file mode 100644
index 00000000..3b2af4da
--- /dev/null
+++ b/tests/input/func.sh
@@ -0,0 +1,24 @@
+#!/system/bin/sh
+#
+# Copyright (C) 2017 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.
+
+# text fixture setup for unit tests
+
+
+echo "text fixture setup for func tests"
+
+am instrument \
+ -e testSetupMode func \
+ -w com.android.tv.testinput/.instrument.TestSetupInstrumentation \ No newline at end of file
diff --git a/tests/input/jank.sh b/tests/input/jank.sh
new file mode 100644
index 00000000..c6311a4d
--- /dev/null
+++ b/tests/input/jank.sh
@@ -0,0 +1,24 @@
+#!/system/bin/sh
+#
+# Copyright (C) 2017 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.
+
+# text fixture setup for unit tests
+
+
+echo "text fixture setup for func tests"
+
+am instrument \
+ -e testSetupMode jank \
+ -w com.android.tv.testinput/.instrument.TestSetupInstrumentation \ No newline at end of file
diff --git a/tests/input/src/com/android/tv/testinput/TestInputControl.java b/tests/input/src/com/android/tv/testinput/TestInputControl.java
index cd85c86e..5e5ec32a 100644
--- a/tests/input/src/com/android/tv/testinput/TestInputControl.java
+++ b/tests/input/src/com/android/tv/testinput/TestInputControl.java
@@ -21,28 +21,26 @@ import android.net.Uri;
import android.os.RemoteException;
import android.util.Log;
import android.util.LongSparseArray;
-
-import com.android.tv.testing.ChannelInfo;
-import com.android.tv.testing.ChannelUtils;
+import com.android.tv.testing.data.ChannelInfo;
+import com.android.tv.testing.data.ChannelUtils;
import com.android.tv.testing.testinput.ChannelState;
import com.android.tv.testing.testinput.ChannelStateData;
import com.android.tv.testing.testinput.ITestInputControl;
-
import java.util.Map;
/**
* Maintains state for the {@link TestTvInputService}.
*
- * <p>Maintains the current state for every channel. A default is sent if the state is not
+ * <p>Maintains the current state for every channel. A default is sent if the state is not
* explicitly set. The state is versioned so TestTvInputService can tell if onNotifyXXX events need
* to be sent.
*
- * <p> Test update the state using @{link ITestInputControl} via {@link TestInputControlService}.
+ * <p>Test update the state using @{link ITestInputControl} via {@link TestInputControlService}.
*/
class TestInputControl extends ITestInputControl.Stub {
- private final static String TAG = "TestInputControl";
- private final static TestInputControl INSTANCE = new TestInputControl();
+ private static final String TAG = "TestInputControl";
+ private static final TestInputControl INSTANCE = new TestInputControl();
private final LongSparseArray<ChannelInfo> mId2ChannelInfoMap = new LongSparseArray<>();
private final LongSparseArray<ChannelState> mOrigId2StateMap = new LongSparseArray<>();
@@ -50,8 +48,7 @@ class TestInputControl extends ITestInputControl.Stub {
private java.lang.String mInputId;
private boolean initialized;
- private TestInputControl() {
- }
+ private TestInputControl() {}
public static TestInputControl getInstance() {
return INSTANCE;
@@ -73,8 +70,13 @@ class TestInputControl extends ITestInputControl.Stub {
for (Long channelId : channelIdToInfoMap.keySet()) {
mId2ChannelInfoMap.put(channelId, channelIdToInfoMap.get(channelId));
}
- Log.i(TAG, "Initialized channel map for " + mInputId + " with " + mId2ChannelInfoMap.size()
- + " channels");
+ Log.i(
+ TAG,
+ "Initialized channel map for "
+ + mInputId
+ + " with "
+ + mId2ChannelInfoMap.size()
+ + " channels");
}
public ChannelInfo getChannelInfo(Uri channelUri) {
diff --git a/tests/input/src/com/android/tv/testinput/TestInputControlService.java b/tests/input/src/com/android/tv/testinput/TestInputControlService.java
index 4a5668cc..4a1306ed 100644
--- a/tests/input/src/com/android/tv/testinput/TestInputControlService.java
+++ b/tests/input/src/com/android/tv/testinput/TestInputControlService.java
@@ -20,8 +20,8 @@ import android.content.Intent;
import android.os.IBinder;
/**
- * Testcases communicate to the {@link TestInputControl} via
- * {@link com.android.tv.testing.testinput.ITestInputControl}.
+ * Testcases communicate to the {@link TestInputControl} via {@link
+ * com.android.tv.testing.testinput.ITestInputControl}.
*/
public class TestInputControlService extends Service {
diff --git a/tests/input/src/com/android/tv/testinput/TestTvInputService.java b/tests/input/src/com/android/tv/testinput/TestTvInputService.java
index 621ceacb..840587c9 100644
--- a/tests/input/src/com/android/tv/testinput/TestTvInputService.java
+++ b/tests/input/src/com/android/tv/testinput/TestTvInputService.java
@@ -41,17 +41,13 @@ import android.os.Message;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Surface;
-
import com.android.tv.input.TunerHelper;
-import com.android.tv.testing.ChannelInfo;
+import com.android.tv.testing.data.ChannelInfo;
import com.android.tv.testing.testinput.ChannelState;
-
import java.util.Date;
import java.util.concurrent.TimeUnit;
-/**
- * Simple TV input service which provides test channels.
- */
+/** Simple TV input service which provides test channels. */
public class TestTvInputService extends TvInputService {
private static final String TAG = "TestTvInputService";
private static final int REFRESH_DELAY_MS = 1000 / 5;
@@ -93,9 +89,7 @@ public class TestTvInputService extends TvInputService {
return new SimpleRecordingSessionImpl(this, inputId);
}
- /**
- * Simple session implementation that just display some text.
- */
+ /** Simple session implementation that just display some text. */
private class SimpleSessionImpl extends Session {
private static final int MSG_SEEK = 1000;
private static final int SEEK_DELAY_MS = 300;
@@ -118,28 +112,36 @@ public class TestTvInputService extends TvInputService {
// The current playback speed rate.
private float mSpeed;
- private final Handler mHandler = new Handler(Looper.myLooper()) {
- @Override
- public void handleMessage(Message msg) {
- if (msg.what == MSG_SEEK) {
- // Actually, this input doesn't play any videos, it just shows the image.
- // So we should simulate the playback here by changing the current playback
- // position periodically in order to test the time shift.
- // If the playback is paused, the current playback position doesn't need to be
- // changed.
- if (mPausedTimeMs == 0) {
- long currentTimeMs = System.currentTimeMillis();
- mCurrentPositionMs += (long) ((currentTimeMs
- - mLastCurrentPositionUpdateTimeMs) * mSpeed);
- mCurrentPositionMs = Math.max(mRecordStartTimeMs,
- Math.min(mCurrentPositionMs, currentTimeMs));
- mLastCurrentPositionUpdateTimeMs = currentTimeMs;
+ private final Handler mHandler =
+ new Handler(Looper.myLooper()) {
+ @Override
+ public void handleMessage(Message msg) {
+ if (msg.what == MSG_SEEK) {
+ // Actually, this input doesn't play any videos, it just shows the
+ // image.
+ // So we should simulate the playback here by changing the current
+ // playback
+ // position periodically in order to test the time shift.
+ // If the playback is paused, the current playback position doesn't need
+ // to be
+ // changed.
+ if (mPausedTimeMs == 0) {
+ long currentTimeMs = System.currentTimeMillis();
+ mCurrentPositionMs +=
+ (long)
+ ((currentTimeMs - mLastCurrentPositionUpdateTimeMs)
+ * mSpeed);
+ mCurrentPositionMs =
+ Math.max(
+ mRecordStartTimeMs,
+ Math.min(mCurrentPositionMs, currentTimeMs));
+ mLastCurrentPositionUpdateTimeMs = currentTimeMs;
+ }
+ sendEmptyMessageDelayed(MSG_SEEK, SEEK_DELAY_MS);
+ }
+ super.handleMessage(msg);
}
- sendEmptyMessageDelayed(MSG_SEEK, SEEK_DELAY_MS);
- }
- super.handleMessage(msg);
- }
- };
+ };
SimpleSessionImpl(Context context) {
super(context);
@@ -213,7 +215,8 @@ public class TestTvInputService extends TvInputService {
mChannelUri = channelUri;
ChannelInfo info = mBackend.getChannelInfo(channelUri);
synchronized (mDrawRunnable) {
- if (info == null || mChannel == null
+ if (info == null
+ || mChannel == null
|| mChannel.originalNetworkId != info.originalNetworkId) {
mCurrentState = null;
}
@@ -231,8 +234,9 @@ public class TestTvInputService extends TvInputService {
Log.i(TAG, "Tuning to " + mChannel);
}
notifyTimeShiftStatusChanged(TvInputManager.TIME_SHIFT_STATUS_AVAILABLE);
- mRecordStartTimeMs = mCurrentPositionMs = mLastCurrentPositionUpdateTimeMs
- = System.currentTimeMillis();
+ mRecordStartTimeMs =
+ mCurrentPositionMs =
+ mLastCurrentPositionUpdateTimeMs = System.currentTimeMillis();
mPausedTimeMs = 0;
mHandler.sendEmptyMessageDelayed(MSG_SEEK, SEEK_DELAY_MS);
mSpeed = 1;
@@ -269,8 +273,8 @@ public class TestTvInputService extends TvInputService {
@Override
public void onTimeShiftPause() {
- mCurrentPositionMs = mPausedTimeMs = mLastCurrentPositionUpdateTimeMs
- = System.currentTimeMillis();
+ mCurrentPositionMs =
+ mPausedTimeMs = mLastCurrentPositionUpdateTimeMs = System.currentTimeMillis();
}
@Override
@@ -283,8 +287,9 @@ public class TestTvInputService extends TvInputService {
@Override
public void onTimeShiftSeekTo(long timeMs) {
mLastCurrentPositionUpdateTimeMs = System.currentTimeMillis();
- mCurrentPositionMs = Math.max(mRecordStartTimeMs,
- Math.min(timeMs, mLastCurrentPositionUpdateTimeMs));
+ mCurrentPositionMs =
+ Math.max(
+ mRecordStartTimeMs, Math.min(timeMs, mLastCurrentPositionUpdateTimeMs));
}
@Override
@@ -354,14 +359,14 @@ public class TestTvInputService extends TvInputService {
}
}
- private void update(ChannelState oldState, ChannelState newState,
- ChannelInfo currentChannel) {
+ private void update(
+ ChannelState oldState, ChannelState newState, ChannelInfo currentChannel) {
Log.i(TAG, "Updating channel " + currentChannel.number + " state to " + newState);
notifyTracksChanged(newState.getTrackInfoList());
if (oldState == null || oldState.getTuneStatus() != newState.getTuneStatus()) {
if (newState.getTuneStatus() == ChannelState.TUNE_STATUS_VIDEO_AVAILABLE) {
notifyVideoAvailable();
- //TODO handle parental controls.
+ // TODO handle parental controls.
notifyContentAllowed();
setAudioTrack(newState.getSelectedAudioTrackId());
setVideoTrack(newState.getSelectedVideoTrackId());
@@ -379,20 +384,20 @@ public class TestTvInputService extends TvInputService {
private class SimpleRecordingSessionImpl extends RecordingSession {
private final String[] PROGRAM_PROJECTION = {
- Programs.COLUMN_TITLE,
- Programs.COLUMN_EPISODE_TITLE,
- Programs.COLUMN_SHORT_DESCRIPTION,
- Programs.COLUMN_POSTER_ART_URI,
- Programs.COLUMN_THUMBNAIL_URI,
- Programs.COLUMN_CANONICAL_GENRE,
- Programs.COLUMN_CONTENT_RATING,
- Programs.COLUMN_START_TIME_UTC_MILLIS,
- Programs.COLUMN_END_TIME_UTC_MILLIS,
- Programs.COLUMN_VIDEO_WIDTH,
- Programs.COLUMN_VIDEO_HEIGHT,
- Programs.COLUMN_SEASON_DISPLAY_NUMBER,
- Programs.COLUMN_SEASON_TITLE,
- Programs.COLUMN_EPISODE_DISPLAY_NUMBER,
+ Programs.COLUMN_TITLE,
+ Programs.COLUMN_EPISODE_TITLE,
+ Programs.COLUMN_SHORT_DESCRIPTION,
+ Programs.COLUMN_POSTER_ART_URI,
+ Programs.COLUMN_THUMBNAIL_URI,
+ Programs.COLUMN_CANONICAL_GENRE,
+ Programs.COLUMN_CONTENT_RATING,
+ Programs.COLUMN_START_TIME_UTC_MILLIS,
+ Programs.COLUMN_END_TIME_UTC_MILLIS,
+ Programs.COLUMN_VIDEO_WIDTH,
+ Programs.COLUMN_VIDEO_HEIGHT,
+ Programs.COLUMN_SEASON_DISPLAY_NUMBER,
+ Programs.COLUMN_SEASON_TITLE,
+ Programs.COLUMN_EPISODE_DISPLAY_NUMBER,
};
private final String mInputId;
@@ -442,8 +447,14 @@ public class TestTvInputService extends TvInputService {
long time = System.currentTimeMillis();
if (programHintUri != null) {
// Retrieves program info from mProgramHintUri
- try (Cursor c = getContentResolver().query(programHintUri,
- PROGRAM_PROJECTION, null, null, null)) {
+ try (Cursor c =
+ getContentResolver()
+ .query(
+ programHintUri,
+ PROGRAM_PROJECTION,
+ null,
+ null,
+ null)) {
if (c != null && c.getCount() > 0) {
storeRecordedProgram(c, startTime, endTime);
return null;
@@ -453,11 +464,19 @@ public class TestTvInputService extends TvInputService {
}
}
// Retrieves the current program
- try (Cursor c = getContentResolver().query(
- TvContract.buildProgramsUriForChannel(channelUri, startTime,
- endTime - startTime < MAX_COMMAND_DELAY ? startTime :
- endTime - MAX_COMMAND_DELAY),
- PROGRAM_PROJECTION, null, null, null)) {
+ try (Cursor c =
+ getContentResolver()
+ .query(
+ TvContract.buildProgramsUriForChannel(
+ channelUri,
+ startTime,
+ endTime - startTime < MAX_COMMAND_DELAY
+ ? startTime
+ : endTime - MAX_COMMAND_DELAY),
+ PROGRAM_PROJECTION,
+ null,
+ null,
+ null)) {
if (c != null && c.getCount() == 1) {
storeRecordedProgram(c, startTime, endTime);
return null;
@@ -472,10 +491,9 @@ public class TestTvInputService extends TvInputService {
private void storeRecordedProgram(Cursor c, long startTime, long endTime) {
ContentValues values = new ContentValues();
values.put(RecordedPrograms.COLUMN_INPUT_ID, mInputId);
- values.put(RecordedPrograms.COLUMN_CHANNEL_ID,
- ContentUris.parseId(channelUri));
- values.put(RecordedPrograms.COLUMN_RECORDING_DURATION_MILLIS,
- endTime - startTime);
+ values.put(RecordedPrograms.COLUMN_CHANNEL_ID, ContentUris.parseId(channelUri));
+ values.put(
+ RecordedPrograms.COLUMN_RECORDING_DURATION_MILLIS, endTime - startTime);
if (c != null) {
int index = 0;
c.moveToNext();
@@ -492,15 +510,15 @@ public class TestTvInputService extends TvInputService {
values.put(Programs.COLUMN_VIDEO_HEIGHT, c.getLong(index++));
values.put(Programs.COLUMN_SEASON_DISPLAY_NUMBER, c.getString(index++));
values.put(Programs.COLUMN_SEASON_TITLE, c.getString(index++));
- values.put(Programs.COLUMN_EPISODE_DISPLAY_NUMBER,
- c.getString(index++));
+ values.put(Programs.COLUMN_EPISODE_DISPLAY_NUMBER, c.getString(index++));
} else {
values.put(RecordedPrograms.COLUMN_TITLE, "No program info");
values.put(RecordedPrograms.COLUMN_START_TIME_UTC_MILLIS, startTime);
values.put(RecordedPrograms.COLUMN_END_TIME_UTC_MILLIS, endTime);
}
- Uri uri = getContentResolver()
- .insert(TvContract.RecordedPrograms.CONTENT_URI, values);
+ Uri uri =
+ getContentResolver()
+ .insert(TvContract.RecordedPrograms.CONTENT_URI, values);
notifyRecordingStopped(uri);
}
}.execute();
diff --git a/tests/input/src/com/android/tv/testinput/TestTvInputSetupActivity.java b/tests/input/src/com/android/tv/testinput/TestTvInputSetupActivity.java
index a793ac71..c9153d1c 100644
--- a/tests/input/src/com/android/tv/testinput/TestTvInputSetupActivity.java
+++ b/tests/input/src/com/android/tv/testinput/TestTvInputSetupActivity.java
@@ -22,24 +22,17 @@ import android.app.Dialog;
import android.app.DialogFragment;
import android.content.Context;
import android.content.DialogInterface;
-import android.media.tv.TvContract;
import android.media.tv.TvInputInfo;
import android.os.Bundle;
import android.util.Log;
-
-import com.android.tv.testing.ChannelInfo;
-import com.android.tv.testing.ChannelUtils;
-import com.android.tv.testing.Constants;
-import com.android.tv.testing.ProgramInfo;
-import com.android.tv.testing.ProgramUtils;
-
-import java.util.ArrayList;
+import com.android.tv.common.util.Clock;
+import com.android.tv.testing.constants.Constants;
+import com.android.tv.testing.data.ChannelInfo;
+import com.android.tv.testing.data.ChannelUtils;
+import com.android.tv.testing.data.ProgramUtils;
import java.util.List;
-import java.util.Map;
-/**
- * The setup activity for {@link TestTvInputService}.
- */
+/** The setup activity for {@link TestTvInputService}. */
public class TestTvInputSetupActivity extends Activity {
private static final String TAG = "TestTvInputSetup";
private String mInputId;
@@ -60,45 +53,41 @@ public class TestTvInputSetupActivity extends Activity {
public static void registerChannels(Context context, String inputId, int channelCount) {
Log.i(TAG, "Registering " + channelCount + " channels");
- List<ChannelInfo> channels = new ArrayList<>();
- for (int i = 1; i <= channelCount; i++) {
- channels.add(ChannelInfo.create(context, i));
- }
+ List<ChannelInfo> channels = ChannelUtils.createChannelInfos(context, channelCount);
ChannelUtils.updateChannels(context, inputId, channels);
-
- // Reload channels so we have the ids.
- Map<Long, ChannelInfo> channelIdToInfoMap =
- ChannelUtils.queryChannelInfoMapForTvInput(context, inputId);
- for (Long channelId : channelIdToInfoMap.keySet()) {
- ProgramInfo programInfo = ProgramInfo.create();
- ProgramUtils.populatePrograms(context, TvContract.buildChannelUri(channelId),
- programInfo);
- }
+ ProgramUtils.updateProgramForAllChannelsOf(
+ context, inputId, Clock.SYSTEM, ProgramUtils.PROGRAM_INSERT_DURATION_MS);
}
public static class MyAlertDialogFragment extends DialogFragment {
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
- return new AlertDialog.Builder(getActivity()).setTitle(R.string.simple_setup_title)
+ return new AlertDialog.Builder(getActivity())
+ .setTitle(R.string.simple_setup_title)
.setMessage(R.string.simple_setup_message)
- .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int whichButton) {
- // TODO: add UI to ask how many channels
- ((TestTvInputSetupActivity) getActivity())
- .registerChannels(Constants.UNIT_TEST_CHANNEL_COUNT);
- // Sets the results so that the application can process the
- // registered channels properly.
- getActivity().setResult(Activity.RESULT_OK);
- getActivity().finish();
- }
- }).setNegativeButton(android.R.string.cancel,
+ .setPositiveButton(
+ android.R.string.ok,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int whichButton) {
+ // TODO: add UI to ask how many channels
+ ((TestTvInputSetupActivity) getActivity())
+ .registerChannels(Constants.UNIT_TEST_CHANNEL_COUNT);
+ // Sets the results so that the application can process the
+ // registered channels properly.
+ getActivity().setResult(Activity.RESULT_OK);
+ getActivity().finish();
+ }
+ })
+ .setNegativeButton(
+ android.R.string.cancel,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int whichButton) {
getActivity().finish();
}
- }).create();
+ })
+ .create();
}
}
}
diff --git a/tests/input/src/com/android/tv/testinput/instrument/TestSetupInstrumentation.java b/tests/input/src/com/android/tv/testinput/instrument/TestSetupInstrumentation.java
index 48e485c5..a4bd45c0 100644
--- a/tests/input/src/com/android/tv/testinput/instrument/TestSetupInstrumentation.java
+++ b/tests/input/src/com/android/tv/testinput/instrument/TestSetupInstrumentation.java
@@ -21,22 +21,24 @@ import android.app.Instrumentation;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
-
-import com.android.tv.testing.Constants;
+import com.android.tv.testing.constants.Constants;
import com.android.tv.testinput.TestTvInputService;
import com.android.tv.testinput.TestTvInputSetupActivity;
/**
- * An instrumentation utility to set up the needed inputs, channels, programs and other settings
- * for automated unit tests.
+ * An instrumentation utility to set up the needed inputs, channels, programs and other settings for
+ * automated unit tests.
+ *
+ * <p>
*
- * <p><pre>{@code
+ * <pre>{@code
* adb shell am instrument \
* -e testSetupMode {func,jank,unit} \
* -w com.android.tv.testinput/.instrument.TestSetupInstrumentation
* }</pre>
*
* <p>Optional arguments are:
+ *
* <pre>
* -e channelCount number
* </pre>
@@ -82,23 +84,26 @@ public class TestSetupInstrumentation extends Instrumentation {
private void setup() throws TestSetupException {
final String testSetupMode = mArguments.getString(TEST_SETUP_MODE_ARG);
if (TextUtils.isEmpty(testSetupMode)) {
- Log.i(TAG, "Performing no setup actions because " + TEST_SETUP_MODE_ARG
- + " was not passed as an argument");
+ Log.i(
+ TAG,
+ "Performing no setup actions because "
+ + TEST_SETUP_MODE_ARG
+ + " was not passed as an argument");
} else {
Log.i(TAG, "Running setup for " + testSetupMode + " tests.");
int channelCount;
switch (testSetupMode) {
case "func":
- channelCount = getArgumentAsInt(CHANNEL_COUNT_ARG,
- Constants.FUNC_TEST_CHANNEL_COUNT);
+ channelCount =
+ getArgumentAsInt(CHANNEL_COUNT_ARG, Constants.FUNC_TEST_CHANNEL_COUNT);
break;
case "jank":
- channelCount = getArgumentAsInt(CHANNEL_COUNT_ARG,
- Constants.JANK_TEST_CHANNEL_COUNT);
+ channelCount =
+ getArgumentAsInt(CHANNEL_COUNT_ARG, Constants.JANK_TEST_CHANNEL_COUNT);
break;
case "unit":
- channelCount = getArgumentAsInt(CHANNEL_COUNT_ARG,
- Constants.UNIT_TEST_CHANNEL_COUNT);
+ channelCount =
+ getArgumentAsInt(CHANNEL_COUNT_ARG, Constants.UNIT_TEST_CHANNEL_COUNT);
break;
default:
throw new TestSetupException(
@@ -114,8 +119,14 @@ public class TestSetupInstrumentation extends Instrumentation {
try {
return Integer.parseInt(stringValue);
} catch (NumberFormatException e) {
- Log.w(TAG, "Unable to parse arg " + arg + " with value " + stringValue
- + " to a integer.", e);
+ Log.w(
+ TAG,
+ "Unable to parse arg "
+ + arg
+ + " with value "
+ + stringValue
+ + " to a integer.",
+ e);
}
}
return defaultValue;
diff --git a/tests/input/tools/get_test_logos.sh b/tests/input/tools/get_test_logos.sh
new file mode 100755
index 00000000..4dd87a3a
--- /dev/null
+++ b/tests/input/tools/get_test_logos.sh
@@ -0,0 +1,57 @@
+#!/bin/bash
+#
+# Copyright (C) 2017 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.
+
+BASE="http://www.google.com/chart?chs=32&chst=d_simple_text_icon_above"
+
+# From http://developers.google.com/chart/image/docs/gallery/dynamic_icons#basic-icons
+icons=(
+ academy activities airport amusement aquarium
+ art-gallery atm baby bank-dollar bank-euro
+ bank-intl bank-pound bank-yen bar barber
+ beach beer bicycle books bowling
+ bus cafe camping car-dealer car-rental
+ car-repair casino caution cemetery-grave cemetery-tomb
+ cinema civic-building computer corporate courthouse
+ fire flag floral helicopter home
+ info landslide legal location locomotive
+ medical mobile motorcycle music parking
+ pet petrol phone picnic postal
+ repair restaurant sail school scissors
+ ship shoppingbag shoppingcart ski snack
+ snow sport star swim taxi train
+ truck wc-female wc-male wc
+ wheelchair
+ )
+
+# The 500s from https://spec.googleplex.com/quantumpalette#
+colors=(
+ DB4437 E91E63 9C27B0 673AB7 3F51B5
+ 4285F4 03A9F4 00BCD4 009688 0F9D58
+ 8BC34A CDDC39 FFEB3B F4B400 FF9800
+ FF5722 795548 9E9E9E 607D8B
+)
+
+
+# See https://developers.google.com/chart/image/docs/gallery/dynamic_icons
+for n in `seq 1 80`;
+do
+ i=n%76
+ c=$(($RANDOM%19))
+ # <font_size>|<font_fill_color>|<icon_name>|<icon_size>|<icon_fill_color>|<icon_and_text_border_color>
+ url=${BASE}"&chld=Ch+"${n}"|7|00F|${icons[${i}]}|24|${colors[${c}]}|FFF"
+ echo ${url}
+ curl ${url} -o tests/input/res/drawable-xhdpi/ch_${n}_logo.png
+done; \ No newline at end of file
diff --git a/tests/input/unit.sh b/tests/input/unit.sh
new file mode 100644
index 00000000..a14d3292
--- /dev/null
+++ b/tests/input/unit.sh
@@ -0,0 +1,24 @@
+#!/system/bin/sh
+#
+# Copyright (C) 2017 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.
+
+# text fixture setup for unit tests
+
+
+echo "text fixture setup for unit tests"
+
+am instrument \
+ -e testSetupMode unit \
+ -w com.android.tv.testinput/.instrument.TestSetupInstrumentation \ No newline at end of file
diff --git a/tests/jank/Android.mk b/tests/jank/Android.mk
index b71ea1b7..1b67ac3f 100644
--- a/tests/jank/Android.mk
+++ b/tests/jank/Android.mk
@@ -15,9 +15,11 @@ LOCAL_STATIC_JAVA_LIBRARIES := \
ub-janktesthelper \
ub-uiautomator \
+LOCAL_JAVA_LIBRARIES := android.test.base.stubs
+
LOCAL_INSTRUMENTATION_FOR := LiveTv
-LOCAL_SDK_VERSION := current
-LOCAL_MIN_SDK_VERSION := 23 # M
+LOCAL_SDK_VERSION := system_current
+LOCAL_PROGUARD_ENABLED := disabled
include $(BUILD_PACKAGE)
diff --git a/tests/jank/AndroidManifest.xml b/tests/jank/AndroidManifest.xml
index fa09917d..5ea72b44 100644
--- a/tests/jank/AndroidManifest.xml
+++ b/tests/jank/AndroidManifest.xml
@@ -18,7 +18,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.tv.tests.jank" >
- <uses-sdk android:targetSdkVersion="23" android:minSdkVersion="21" />
+ <uses-sdk android:targetSdkVersion="26" android:minSdkVersion="21" />
<instrumentation
android:name="android.support.test.runner.AndroidJUnitRunner"
diff --git a/tests/jank/src/com/android/tv/tests/jank/ChannelZappingJankTest.java b/tests/jank/src/com/android/tv/tests/jank/ChannelZappingJankTest.java
index ef936e32..eee2328b 100644
--- a/tests/jank/src/com/android/tv/tests/jank/ChannelZappingJankTest.java
+++ b/tests/jank/src/com/android/tv/tests/jank/ChannelZappingJankTest.java
@@ -19,9 +19,7 @@ import android.support.test.filters.MediumTest;
import android.support.test.jank.GfxMonitor;
import android.support.test.jank.JankTest;
-/**
- * Jank tests for channel zapping.
- */
+/** Jank tests for channel zapping. */
@MediumTest
public class ChannelZappingJankTest extends LiveChannelsTestCase {
private static final String TAG = "ChannelZappingJankTest";
@@ -29,15 +27,17 @@ public class ChannelZappingJankTest extends LiveChannelsTestCase {
private static final String STARTING_CHANNEL = "13";
/**
- * The minimum number of frames expected during each jank test.
- * If there is less the test will fail. To be safe we loop the action in each test to create
- * twice this many frames under normal conditions.
- * <p>At least 100 frams should be chosen so there will be enough frame
- * for the 90th, 95th, and 98th percentile measurements are significant.
+ * The minimum number of frames expected during each jank test. If there is less the test will
+ * fail. To be safe we loop the action in each test to create twice this many frames under
+ * normal conditions.
+ *
+ * <p>At least 100 frams should be chosen so there will be enough frame for the 90th, 95th, and
+ * 98th percentile measurements are significant.
*
* @see <a href="http://go/janktesthelper-best-practices">Jank Test Helper Best Practices</a>
*/
private static final int EXPECTED_FRAMES = 100;
+
private static final int WARM_UP_CHANNEL_ZAPPING_COUNT = 2;
@Override
@@ -46,11 +46,10 @@ public class ChannelZappingJankTest extends LiveChannelsTestCase {
Utils.pressKeysForChannelNumber(STARTING_CHANNEL, mDevice);
}
- @JankTest(expectedFrames = EXPECTED_FRAMES,
- beforeTest = "warmChannelZapping")
+ @JankTest(expectedFrames = EXPECTED_FRAMES, beforeTest = "warmChannelZapping")
@GfxMonitor(processName = Utils.LIVE_CHANNELS_PROCESS_NAME)
public void testChannelZapping() {
- int frameCountForOneChannelZapping = 40; // measured by hand
+ int frameCountForOneChannelZapping = 40; // measured by hand
int repeat = EXPECTED_FRAMES * 2 / frameCountForOneChannelZapping;
for (int i = 0; i < repeat; i++) {
mDevice.pressDPadUp();
diff --git a/tests/jank/src/com/android/tv/tests/jank/LiveChannelsTestCase.java b/tests/jank/src/com/android/tv/tests/jank/LiveChannelsTestCase.java
index 6de01036..507e9dd5 100644
--- a/tests/jank/src/com/android/tv/tests/jank/LiveChannelsTestCase.java
+++ b/tests/jank/src/com/android/tv/tests/jank/LiveChannelsTestCase.java
@@ -18,12 +18,9 @@ package com.android.tv.tests.jank;
import android.content.res.Resources;
import android.support.test.jank.JankTestBase;
import android.support.test.uiautomator.UiDevice;
-
import com.android.tv.testing.uihelper.LiveChannelsUiDeviceHelper;
-/**
- * Base test case for LiveChannel jank tests.
- */
+/** Base test case for LiveChannel jank tests. */
abstract class LiveChannelsTestCase extends JankTestBase {
protected UiDevice mDevice;
protected Resources mTargetResources;
@@ -34,8 +31,9 @@ abstract class LiveChannelsTestCase extends JankTestBase {
super.setUp();
mDevice = UiDevice.getInstance(getInstrumentation());
mTargetResources = getInstrumentation().getTargetContext().getResources();
- mLiveChannelsHelper = new LiveChannelsUiDeviceHelper(mDevice, mTargetResources,
- getInstrumentation().getContext());
+ mLiveChannelsHelper =
+ new LiveChannelsUiDeviceHelper(
+ mDevice, mTargetResources, getInstrumentation().getContext());
mLiveChannelsHelper.assertAppStarted();
}
diff --git a/tests/jank/src/com/android/tv/tests/jank/MenuJankTest.java b/tests/jank/src/com/android/tv/tests/jank/MenuJankTest.java
index 411a0bb9..ea80eb3d 100644
--- a/tests/jank/src/com/android/tv/tests/jank/MenuJankTest.java
+++ b/tests/jank/src/com/android/tv/tests/jank/MenuJankTest.java
@@ -18,26 +18,25 @@ package com.android.tv.tests.jank;
import android.support.test.filters.MediumTest;
import android.support.test.jank.GfxMonitor;
import android.support.test.jank.JankTest;
-
import com.android.tv.testing.uihelper.MenuHelper;
-/**
- * Jank tests for the program guide.
- */
+/** Jank tests for the program guide. */
@MediumTest
public class MenuJankTest extends LiveChannelsTestCase {
private static final String STARTING_CHANNEL = "1";
/**
- * The minimum number of frames expected during each jank test.
- * If there is less the test will fail. To be safe we loop the action in each test to create
- * twice this many frames under normal conditions.
+ * The minimum number of frames expected during each jank test. If there is less the test will
+ * fail. To be safe we loop the action in each test to create twice this many frames under
+ * normal conditions.
+ *
* <p>200 is chosen so there will be enough frame for the 90th, 95th, and 98th percentile
* measurements are significant.
*
* @see <a href="http://go/janktesthelper-best-practices">Jank Test Helper Best Practices</a>
*/
private static final int EXPECTED_FRAMES = 200;
+
protected MenuHelper mMenuHelper;
@Override
@@ -47,8 +46,7 @@ public class MenuJankTest extends LiveChannelsTestCase {
Utils.pressKeysForChannelNumber(STARTING_CHANNEL, mDevice);
}
- @JankTest(expectedFrames = EXPECTED_FRAMES,
- beforeTest = "fillTheMenuRowWithPreviousChannels")
+ @JankTest(expectedFrames = EXPECTED_FRAMES, beforeTest = "fillTheMenuRowWithPreviousChannels")
@GfxMonitor(processName = Utils.LIVE_CHANNELS_PROCESS_NAME)
public void testShowMenu() {
int frames = 40; // measured by hand.
diff --git a/tests/jank/src/com/android/tv/tests/jank/ProgramGuideJankTest.java b/tests/jank/src/com/android/tv/tests/jank/ProgramGuideJankTest.java
index d8860dd7..57d38ba9 100644
--- a/tests/jank/src/com/android/tv/tests/jank/ProgramGuideJankTest.java
+++ b/tests/jank/src/com/android/tv/tests/jank/ProgramGuideJankTest.java
@@ -21,23 +21,21 @@ import android.support.test.filters.MediumTest;
import android.support.test.jank.GfxMonitor;
import android.support.test.jank.JankTest;
import android.support.test.uiautomator.Until;
-
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.MenuHelper;
-/**
- * Jank tests for the program guide.
- */
+/** Jank tests for the program guide. */
@MediumTest
public class ProgramGuideJankTest extends LiveChannelsTestCase {
private static final String STARTING_CHANNEL = "13";
/**
- * The minimum number of frames expected during each jank test.
- * If there is less the test will fail. To be safe we loop the action in each test to create
- * twice this many frames under normal conditions.
+ * The minimum number of frames expected during each jank test. If there is less the test will
+ * fail. To be safe we loop the action in each test to create twice this many frames under
+ * normal conditions.
+ *
* <p>200 is chosen so there will be enough frame for the 90th, 95th, and 98th percentile
* measurements are significant.
*
@@ -54,8 +52,7 @@ public class ProgramGuideJankTest extends LiveChannelsTestCase {
Utils.pressKeysForChannelNumber(STARTING_CHANNEL, mDevice);
}
- @JankTest(expectedFrames = EXPECTED_FRAMES,
- beforeTest = "warmProgramGuide")
+ @JankTest(expectedFrames = EXPECTED_FRAMES, beforeTest = "warmProgramGuide")
@GfxMonitor(processName = Utils.LIVE_CHANNELS_PROCESS_NAME)
public void testShowClearProgramGuide() {
int frames = 53; // measured by hand
@@ -66,24 +63,28 @@ public class ProgramGuideJankTest extends LiveChannelsTestCase {
}
}
- @JankTest(expectedFrames = EXPECTED_FRAMES,
- beforeLoop = "showAndFocusProgramGuide",
- afterLoop = "clearProgramGuide")
+ @JankTest(
+ expectedFrames = EXPECTED_FRAMES,
+ beforeLoop = "showAndFocusProgramGuide",
+ afterLoop = "clearProgramGuide"
+ )
@GfxMonitor(processName = Utils.LIVE_CHANNELS_PROCESS_NAME)
public void testScrollDown() {
- int frames = 20; // measured by hand
+ int frames = 20; // measured by hand
int repeat = EXPECTED_FRAMES * 2 / frames;
for (int i = 0; i < repeat; i++) {
mDevice.pressDPadDown();
}
}
- @JankTest(expectedFrames = EXPECTED_FRAMES,
- beforeLoop = "showAndFocusProgramGuide",
- afterLoop = "clearProgramGuide")
+ @JankTest(
+ expectedFrames = EXPECTED_FRAMES,
+ beforeLoop = "showAndFocusProgramGuide",
+ afterLoop = "clearProgramGuide"
+ )
@GfxMonitor(processName = Utils.LIVE_CHANNELS_PROCESS_NAME)
public void testScrollRight() {
- int frames = 30; // measured by hand
+ int frames = 30; // measured by hand
int repeat = EXPECTED_FRAMES * 2 / frames;
for (int i = 0; i < repeat; i++) {
mDevice.pressDPadRight();
@@ -92,8 +93,8 @@ public class ProgramGuideJankTest extends LiveChannelsTestCase {
private void selectProgramGuideMenuItem() {
mMenuHelper.showMenu();
- mMenuHelper.assertNavigateToMenuItem(R.string.menu_title_channels,
- R.string.channels_item_program_guide);
+ mMenuHelper.assertNavigateToMenuItem(
+ R.string.menu_title_channels, R.string.channels_item_program_guide);
mDevice.waitForIdle();
}
diff --git a/tests/jank/src/com/android/tv/tests/jank/Utils.java b/tests/jank/src/com/android/tv/tests/jank/Utils.java
index cd1f7eff..4ad0f643 100644
--- a/tests/jank/src/com/android/tv/tests/jank/Utils.java
+++ b/tests/jank/src/com/android/tv/tests/jank/Utils.java
@@ -15,19 +15,16 @@
*/
package com.android.tv.tests.jank;
-import com.android.tv.testing.uihelper.UiDeviceUtils;
-
import android.support.test.uiautomator.UiDevice;
+import com.android.tv.testing.uihelper.UiDeviceUtils;
public final class Utils {
/** Live TV process name */
public static final String LIVE_CHANNELS_PROCESS_NAME = "com.android.tv";
- private Utils() { }
+ private Utils() {}
- /**
- * Presses channel number to tune to {@code channel}.
- */
+ /** Presses channel number to tune to {@code channel}. */
public static void pressKeysForChannelNumber(String channel, UiDevice uiDevice) {
UiDeviceUtils.pressKeys(uiDevice, channel);
uiDevice.pressDPadCenter();
diff --git a/tests/tunerscripts/measure-tuning-time.awk b/tests/tunerscripts/measure-tuning-time.awk
new file mode 100644
index 00000000..e7febcf1
--- /dev/null
+++ b/tests/tunerscripts/measure-tuning-time.awk
@@ -0,0 +1,32 @@
+# Awk script to measure tuning time statistics from logcat dump
+
+BEGIN {
+ n = 0;
+ sum = 0;
+}
+
+# Collect tuning time with "Video available in <time> ms" message
+/Video available in/ {
+ n++;
+ tune_time = $11;
+ sum += tune_time;
+ if (n == 1) {
+ min = tune_time;
+ max = tune_time;
+ } else {
+ if (tune_time < min) {
+ min = tune_time
+ }
+ if (tune_time > max) {
+ max = tune_time
+ }
+ }
+}
+
+END {
+ average = sum / n;
+ print "Average tune time", average, "ms";
+ print "Minimum tune time", min, "ms";
+ print "Maximum tune time", max, "ms";
+}
+
diff --git a/tests/tunerscripts/usbtuner-test.sh b/tests/tunerscripts/usbtuner-test.sh
new file mode 100755
index 00000000..b8c15841
--- /dev/null
+++ b/tests/tunerscripts/usbtuner-test.sh
@@ -0,0 +1,159 @@
+#!/bin/bash
+#
+# Copyright (C) 2017 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.
+#
+# usage: usbtuner-test.sh <test_case> [channel]
+#
+# To test repeated channel change, run:
+#
+# ./usbtuner-test.sh <1 or 3>
+#
+# To test watching a fixed channel, run:
+#
+# ./usbtuner-test.sh 2
+#
+# Case 2 uses the last-viewed channel by TV app. Give a channel number
+# as a 2nd parameter if you want to use the channel for testing, like below:
+#
+# ./usbtuner-test.sh 2 6-1
+#
+# The script assumes that:
+# 1) Browsing by keydown event circulates among the USB input channels only
+# 2) When started, TV app should tune to one of the channels provided by the USB input
+#
+# The test result is logged in the doc: https://goo.gl/MsPBf7
+
+function start_tv {
+ disable_analytics_report
+ adb shell am force-stop com.android.tv
+ adb shell am start -n com.android.tv/.MainActivity > /dev/null
+ sleep 5
+}
+
+function log_begin {
+ adb shell dumpsys meminfo -d --package com.android.tv.tuner > meminfo-begin.txt
+}
+
+function tune {
+ adb shell input text $1
+ adb shell input keyevent KEYCODE_DPAD_CENTER
+ sleep 5 # Wait enough for tuning
+}
+
+function browse {
+ for i in {1..50}; do
+ adb shell input keyevent DPAD_DOWN
+ sleep 10 # Tune and watch the channel for a while
+ done;
+}
+
+function browse_heavily {
+ for i in {1..60}; do
+ echo "$(date '+%x %X') ======== Test #$i of 60 ========"
+ clear_logcat
+ for j in {1..60}; do
+ adb shell input keyevent DPAD_DOWN
+ sleep $(( $RANDOM % 3 )) # Sleep for 0 - 2 seconds
+ done;
+ measure_tuning_time
+ done;
+}
+
+function clear_logcat {
+ adb logcat -c
+}
+
+function measure_tuning_time {
+ timeout 1 adb logcat -s TvInputSessionImpl | awk -f $(dirname $0)/measure-tuning-time.awk
+}
+
+function log_end {
+ adb shell dumpsys meminfo -d --package com.android.tv.tuner > meminfo-end.txt
+}
+
+function stop_tv {
+ # Stop TV by running other app (Settings)
+ adb shell am start com.android.tv.settings/com.android.tv.settings.MainSettings
+ restore_analytics_setting
+}
+
+function output {
+ echo "Cut and paste this"
+ sed -n 33,46p meminfo-begin.txt | cut -f 2 -d ":" -s | awk '{print $1}'
+ sed -n 33,46p meminfo-end.txt | cut -f 2 -d ":" -s | awk '{print $1}'
+}
+
+function disable_analytics_report {
+ tracker=$(adb shell getprop tv_use_tracker | tr -d '[[:space:]]')
+ adb shell setprop tv_use_tracker false
+}
+
+function restore_analytics_setting {
+ if [ "${tracker}" == "" ]; then
+ adb shell setprop tv_use_tracker ""
+ else
+ adb shell setprop tv_use_tracker ${tracker}
+ fi
+}
+
+function control_c {
+ restore_analytics_setting
+ echo "Exiting..."
+ exit 1
+}
+
+# Entry point
+
+trap control_c SIGINT
+
+case "$1" in
+ 1)
+ echo "Runing test 1"
+ start_tv
+ log_begin
+ clear_logcat
+ browse # Repeat channel change for about 10 minutes
+ measure_tuning_time
+ log_end
+ stop_tv
+ output
+ ;;
+ 2)
+ echo "Runing test 2"
+ start_tv
+ log_begin
+ if [ "$2" != "" ]; then
+ tune $2
+ fi
+ sleep 600 # 10 minutes
+ log_end
+ stop_tv
+ output
+ ;;
+ 3)
+ echo "Runing test 3"
+ start_tv
+ log_begin
+ browse_heavily # Repeat channel change for about 3 hours
+ log_end
+ stop_tv
+ output
+ ;;
+ *)
+ echo "usage: usbtuner-test.sh <1|2|3> [channel]"
+ exit 1
+ ;;
+esac
+
diff --git a/tests/unit/Android.mk b/tests/unit/Android.mk
index 3632fe94..a425bcfe 100644
--- a/tests/unit/Android.mk
+++ b/tests/unit/Android.mk
@@ -12,6 +12,11 @@ LOCAL_STATIC_JAVA_LIBRARIES := \
mockito-target \
tv-test-common \
+LOCAL_JAVA_LIBRARIES := \
+ android.test.runner.stubs \
+ android.test.base.stubs \
+ android.test.mock.stubs \
+
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/../common/res
@@ -20,7 +25,7 @@ LOCAL_PACKAGE_NAME := TVUnitTests
LOCAL_INSTRUMENTATION_FOR := LiveTv
LOCAL_SDK_VERSION := system_current
-LOCAL_MIN_SDK_VERSION := 23 # M
+LOCAL_PROGUARD_ENABLED := disabled
include $(BUILD_PACKAGE)
diff --git a/tests/unit/AndroidManifest.xml b/tests/unit/AndroidManifest.xml
index d073f8ac..9134a1c1 100644
--- a/tests/unit/AndroidManifest.xml
+++ b/tests/unit/AndroidManifest.xml
@@ -18,7 +18,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.tv.tests" >
- <uses-sdk android:targetSdkVersion="23" android:minSdkVersion="23" />
+ <uses-sdk android:targetSdkVersion="26" android:minSdkVersion="23" />
<instrumentation
android:name="android.support.test.runner.AndroidJUnitRunner"
diff --git a/tests/unit/src/com/android/tv/CurrentPositionMediatorTest.java b/tests/unit/src/com/android/tv/CurrentPositionMediatorTest.java
index f2917181..abadde31 100644
--- a/tests/unit/src/com/android/tv/CurrentPositionMediatorTest.java
+++ b/tests/unit/src/com/android/tv/CurrentPositionMediatorTest.java
@@ -18,16 +18,18 @@ package com.android.tv;
import static com.android.tv.TimeShiftManager.INVALID_TIME;
import static com.android.tv.TimeShiftManager.REQUEST_TIMEOUT_MS;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotSame;
+import static com.google.common.truth.Truth.assertWithMessage;
import android.support.test.annotation.UiThreadTest;
import android.support.test.filters.MediumTest;
-
+import android.support.test.runner.AndroidJUnit4;
+import com.android.tv.testing.activities.BaseMainActivityTestCase;
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
@MediumTest
+@RunWith(AndroidJUnit4.class)
public class CurrentPositionMediatorTest extends BaseMainActivityTestCase {
private TimeShiftManager.CurrentPositionMediator mMediator;
@@ -51,8 +53,12 @@ public class CurrentPositionMediatorTest extends BaseMainActivityTestCase {
public void testOnSeekRequested() {
long seekToTimeMs = System.currentTimeMillis() - REQUEST_TIMEOUT_MS * 3;
mMediator.onSeekRequested(seekToTimeMs);
- assertNotSame("Seek request time", INVALID_TIME, mMediator.mSeekRequestTimeMs);
- assertEquals("Current position", seekToTimeMs, mMediator.mCurrentPositionMs);
+ assertWithMessage("Seek request time")
+ .that(mMediator.mSeekRequestTimeMs)
+ .isNotSameAs(INVALID_TIME);
+ assertWithMessage("Current position")
+ .that(mMediator.mCurrentPositionMs)
+ .isEqualTo(seekToTimeMs);
}
@UiThreadTest
@@ -62,9 +68,15 @@ public class CurrentPositionMediatorTest extends BaseMainActivityTestCase {
long newCurrentTimeMs = seekToTimeMs + REQUEST_TIMEOUT_MS;
mMediator.onSeekRequested(seekToTimeMs);
mMediator.onCurrentPositionChanged(newCurrentTimeMs);
- assertNotSame("Seek request time", INVALID_TIME, mMediator.mSeekRequestTimeMs);
- assertNotSame("Current position", seekToTimeMs, mMediator.mCurrentPositionMs);
- assertNotSame("Current position", newCurrentTimeMs, mMediator.mCurrentPositionMs);
+ assertWithMessage("Seek request time")
+ .that(mMediator.mSeekRequestTimeMs)
+ .isNotSameAs(INVALID_TIME);
+ assertWithMessage("Current position")
+ .that(mMediator.mCurrentPositionMs)
+ .isNotSameAs(seekToTimeMs);
+ assertWithMessage("Current position")
+ .that(mMediator.mCurrentPositionMs)
+ .isNotSameAs(newCurrentTimeMs);
}
@UiThreadTest
@@ -77,9 +89,13 @@ public class CurrentPositionMediatorTest extends BaseMainActivityTestCase {
assertCurrentPositionMediator(INVALID_TIME, newCurrentTimeMs);
}
- private void assertCurrentPositionMediator(long expectedSeekRequestTimeMs,
- long expectedCurrentPositionMs) {
- assertEquals("Seek request time", expectedSeekRequestTimeMs, mMediator.mSeekRequestTimeMs);
- assertEquals("Current position", expectedCurrentPositionMs, mMediator.mCurrentPositionMs);
+ private void assertCurrentPositionMediator(
+ long expectedSeekRequestTimeMs, long expectedCurrentPositionMs) {
+ assertWithMessage("Seek request time")
+ .that(mMediator.mSeekRequestTimeMs)
+ .isEqualTo(expectedSeekRequestTimeMs);
+ assertWithMessage("Current position")
+ .that(mMediator.mCurrentPositionMs)
+ .isEqualTo(expectedCurrentPositionMs);
}
}
diff --git a/tests/unit/src/com/android/tv/FeaturesTest.java b/tests/unit/src/com/android/tv/FeaturesTest.java
index 9d61e757..e19f4b7c 100644
--- a/tests/unit/src/com/android/tv/FeaturesTest.java
+++ b/tests/unit/src/com/android/tv/FeaturesTest.java
@@ -16,21 +16,21 @@
package com.android.tv;
-import static org.junit.Assert.assertFalse;
+import static com.google.common.truth.Truth.assertThat;
import android.support.test.filters.SmallTest;
-
+import android.support.test.runner.AndroidJUnit4;
import org.junit.Test;
+import org.junit.runner.RunWith;
-/**
- * Test for features.
- */
+/** Test for features. */
@SmallTest
+@RunWith(AndroidJUnit4.class)
public class FeaturesTest {
@Test
public void testPropertyFeatureKeyLength() {
// This forces the class to be loaded and verifies all PropertyFeature key lengths.
// If any keys are too long the test will fail to load.
- assertFalse(Features.TEST_FEATURE.isEnabled(null));
+ assertThat(TvFeatures.TEST_FEATURE.isEnabled(null)).isFalse();
}
}
diff --git a/tests/unit/src/com/android/tv/MainActivityTest.java b/tests/unit/src/com/android/tv/MainActivityTest.java
index 15805032..c5df21a9 100644
--- a/tests/unit/src/com/android/tv/MainActivityTest.java
+++ b/tests/unit/src/com/android/tv/MainActivityTest.java
@@ -16,31 +16,30 @@
package com.android.tv;
import static android.support.test.InstrumentationRegistry.getInstrumentation;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
import android.view.View;
import android.widget.TextView;
-
-import com.android.tv.data.Channel;
+import com.android.tv.data.api.Channel;
+import com.android.tv.testing.activities.BaseMainActivityTestCase;
import com.android.tv.testing.testinput.TvTestInputConstants;
import com.android.tv.ui.ChannelBannerView;
-
-import org.junit.Test;
-
import java.util.List;
+import org.junit.Test;
+import org.junit.runner.RunWith;
-/**
- * Tests for {@link MainActivity}.
- */
+/** Tests for {@link MainActivity}. */
@MediumTest
+@RunWith(AndroidJUnit4.class)
public class MainActivityTest extends BaseMainActivityTestCase {
@Test
public void testInitialConditions() {
waitUntilChannelLoadingFinish();
List<Channel> channelList = mActivity.getChannelDataManager().getChannelList();
- assertTrue("Expected at least one channel", channelList.size() > 0);
+ assertWithMessage("Expected at least one channel").that(channelList.size() > 0).isTrue();
}
@Test
@@ -61,17 +60,19 @@ public class MainActivityTest extends BaseMainActivityTestCase {
private void showProgramGuide() {
// Run on UI thread so views can be modified
- getInstrumentation().runOnMainSync(new Runnable() {
- @Override
- public void run() {
- mActivity.getOverlayManager().showProgramGuide();
- }
- });
+ getInstrumentation()
+ .runOnMainSync(
+ new Runnable() {
+ @Override
+ public void run() {
+ mActivity.getOverlayManager().showProgramGuide();
+ }
+ });
}
private void assertChannelName(String displayName) {
TextView channelNameView = (TextView) mActivity.findViewById(R.id.channel_name);
- assertEquals("Channel Name", displayName, channelNameView.getText());
+ assertWithMessage("Channel Name").that(channelNameView.getText()).isEqualTo(displayName);
}
private void assertProgramGuide(boolean isShown) {
@@ -83,12 +84,13 @@ public class MainActivityTest extends BaseMainActivityTestCase {
return (ChannelBannerView) v;
}
- private View assertExpectedBannerSceneClassShown(Class<ChannelBannerView> expectedClass,
- boolean expectedShown) {
- View v = assertViewIsShown(expectedClass.getSimpleName(), R.id.scene_transition_common,
- expectedShown);
+ private View assertExpectedBannerSceneClassShown(
+ Class<ChannelBannerView> expectedClass, boolean expectedShown) {
+ View v =
+ assertViewIsShown(
+ expectedClass.getSimpleName(), R.id.scene_transition_common, expectedShown);
if (v != null) {
- assertEquals(expectedClass, v.getClass());
+ assertThat(v.getClass()).isEqualTo(expectedClass);
}
return v;
}
@@ -102,7 +104,7 @@ public class MainActivityTest extends BaseMainActivityTestCase {
return null;
}
}
- assertEquals(viewName + " shown", expected, view.isShown());
+ assertWithMessage(viewName + " shown").that(view.isShown()).isEqualTo(expected);
return view;
}
}
diff --git a/tests/unit/src/com/android/tv/TimeShiftManagerTest.java b/tests/unit/src/com/android/tv/TimeShiftManagerTest.java
index 052b5d19..cb523045 100644
--- a/tests/unit/src/com/android/tv/TimeShiftManagerTest.java
+++ b/tests/unit/src/com/android/tv/TimeShiftManagerTest.java
@@ -22,14 +22,17 @@ import static com.android.tv.TimeShiftManager.TIME_SHIFT_ACTION_ID_JUMP_TO_PREVI
import static com.android.tv.TimeShiftManager.TIME_SHIFT_ACTION_ID_PAUSE;
import static com.android.tv.TimeShiftManager.TIME_SHIFT_ACTION_ID_PLAY;
import static com.android.tv.TimeShiftManager.TIME_SHIFT_ACTION_ID_REWIND;
-import static org.junit.Assert.assertEquals;
+import static com.google.common.truth.Truth.assertWithMessage;
import android.support.test.filters.MediumTest;
-
+import android.support.test.runner.AndroidJUnit4;
+import com.android.tv.testing.activities.BaseMainActivityTestCase;
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
@MediumTest
+@RunWith(AndroidJUnit4.class)
public class TimeShiftManagerTest extends BaseMainActivityTestCase {
private TimeShiftManager mTimeShiftManager;
@@ -85,19 +88,30 @@ public class TimeShiftManagerTest extends BaseMainActivityTestCase {
mTimeShiftManager.enableAction(TIME_SHIFT_ACTION_ID_JUMP_TO_NEXT, enabled);
}
- private void assertActionState(boolean playEnabled, boolean pauseEnabled, boolean rewindEnabled,
- boolean fastForwardEnabled, boolean jumpToPreviousEnabled, boolean jumpToNextEnabled) {
- assertEquals("Play Action", playEnabled,
- mTimeShiftManager.isActionEnabled(TIME_SHIFT_ACTION_ID_PLAY));
- assertEquals("Pause Action", pauseEnabled,
- mTimeShiftManager.isActionEnabled(TIME_SHIFT_ACTION_ID_PAUSE));
- assertEquals("Rewind Action", rewindEnabled,
- mTimeShiftManager.isActionEnabled(TIME_SHIFT_ACTION_ID_REWIND));
- assertEquals("Fast Forward Action", fastForwardEnabled,
- mTimeShiftManager.isActionEnabled(TIME_SHIFT_ACTION_ID_FAST_FORWARD));
- assertEquals("Jump To Previous Action", jumpToPreviousEnabled,
- mTimeShiftManager.isActionEnabled(TIME_SHIFT_ACTION_ID_JUMP_TO_PREVIOUS));
- assertEquals("Jump To Next Action", jumpToNextEnabled,
- mTimeShiftManager.isActionEnabled(TIME_SHIFT_ACTION_ID_JUMP_TO_NEXT));
+ private void assertActionState(
+ boolean playEnabled,
+ boolean pauseEnabled,
+ boolean rewindEnabled,
+ boolean fastForwardEnabled,
+ boolean jumpToPreviousEnabled,
+ boolean jumpToNextEnabled) {
+ assertWithMessage("Play Action")
+ .that(mTimeShiftManager.isActionEnabled(TIME_SHIFT_ACTION_ID_PLAY))
+ .isEqualTo(playEnabled);
+ assertWithMessage("Pause Action")
+ .that(mTimeShiftManager.isActionEnabled(TIME_SHIFT_ACTION_ID_PAUSE))
+ .isEqualTo(pauseEnabled);
+ assertWithMessage("Rewind Action")
+ .that(mTimeShiftManager.isActionEnabled(TIME_SHIFT_ACTION_ID_REWIND))
+ .isEqualTo(rewindEnabled);
+ assertWithMessage("Fast Forward Action")
+ .that(mTimeShiftManager.isActionEnabled(TIME_SHIFT_ACTION_ID_FAST_FORWARD))
+ .isEqualTo(fastForwardEnabled);
+ assertWithMessage("Jump To Previous Action")
+ .that(mTimeShiftManager.isActionEnabled(TIME_SHIFT_ACTION_ID_JUMP_TO_PREVIOUS))
+ .isEqualTo(jumpToPreviousEnabled);
+ assertWithMessage("Jump To Next Action")
+ .that(mTimeShiftManager.isActionEnabled(TIME_SHIFT_ACTION_ID_JUMP_TO_NEXT))
+ .isEqualTo(jumpToNextEnabled);
}
}
diff --git a/tests/unit/src/com/android/tv/data/ChannelDataManagerTest.java b/tests/unit/src/com/android/tv/data/ChannelDataManagerTest.java
index 7a4a4982..96c1f7a1 100644
--- a/tests/unit/src/com/android/tv/data/ChannelDataManagerTest.java
+++ b/tests/unit/src/com/android/tv/data/ChannelDataManagerTest.java
@@ -18,9 +18,8 @@ package com.android.tv.data;
import static android.support.test.InstrumentationRegistry.getInstrumentation;
import static android.support.test.InstrumentationRegistry.getTargetContext;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
import android.content.ContentProvider;
import android.content.ContentUris;
@@ -31,7 +30,9 @@ import android.database.Cursor;
import android.media.tv.TvContract;
import android.media.tv.TvContract.Channels;
import android.net.Uri;
+import android.os.AsyncTask;
import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
import android.test.MoreAsserts;
import android.test.mock.MockContentProvider;
import android.test.mock.MockContentResolver;
@@ -39,30 +40,30 @@ import android.test.mock.MockCursor;
import android.text.TextUtils;
import android.util.Log;
import android.util.SparseArray;
-
-import com.android.tv.testing.ChannelInfo;
-import com.android.tv.testing.Constants;
+import com.android.tv.data.api.Channel;
+import com.android.tv.testing.constants.Constants;
+import com.android.tv.testing.data.ChannelInfo;
import com.android.tv.util.TvInputManagerHelper;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Matchers;
-import org.mockito.Mockito;
-
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Matchers;
+import org.mockito.Mockito;
/**
* Test for {@link ChannelDataManager}
*
- * A test method may include tests for multiple methods to minimize the DB access.
- * Note that all the methods of {@link ChannelDataManager} should be called from the UI thread.
+ * <p>A test method may include tests for multiple methods to minimize the DB access. Note that all
+ * the methods of {@link ChannelDataManager} should be called from the UI thread.
*/
@SmallTest
+@RunWith(AndroidJUnit4.class)
public class ChannelDataManagerTest {
private static final boolean DEBUG = false;
private static final String TAG = "ChannelDataManagerTest";
@@ -80,73 +81,89 @@ public class ChannelDataManagerTest {
@Before
public void setUp() {
- assertTrue("More than 2 channels to test", Constants.UNIT_TEST_CHANNEL_COUNT > 2);
+ assertWithMessage("More than 2 channels to test")
+ .that(Constants.UNIT_TEST_CHANNEL_COUNT > 2)
+ .isTrue();
mContentProvider = new FakeContentProvider(getTargetContext());
mContentResolver = new FakeContentResolver();
mContentResolver.addProvider(TvContract.AUTHORITY, mContentProvider);
mListener = new TestChannelDataManagerListener();
- getInstrumentation().runOnMainSync(new Runnable() {
- @Override
- public void run() {
- TvInputManagerHelper mockHelper = Mockito.mock(TvInputManagerHelper.class);
- Mockito.when(mockHelper.hasTvInputInfo(Matchers.anyString())).thenReturn(true);
- mChannelDataManager = new ChannelDataManager(getTargetContext(), mockHelper,
- mContentResolver);
- mChannelDataManager.addListener(mListener);
- }
- });
+ getInstrumentation()
+ .runOnMainSync(
+ new Runnable() {
+ @Override
+ public void run() {
+ TvInputManagerHelper mockHelper =
+ Mockito.mock(TvInputManagerHelper.class);
+ Mockito.when(mockHelper.hasTvInputInfo(Matchers.anyString()))
+ .thenReturn(true);
+ mChannelDataManager =
+ new ChannelDataManager(
+ getTargetContext(),
+ mockHelper,
+ AsyncTask.SERIAL_EXECUTOR,
+ mContentResolver);
+ mChannelDataManager.addListener(mListener);
+ }
+ });
}
@After
public void tearDown() {
- getInstrumentation().runOnMainSync(new Runnable() {
- @Override
- public void run() {
- mChannelDataManager.stop();
- }
- });
+ getInstrumentation()
+ .runOnMainSync(
+ new Runnable() {
+ @Override
+ public void run() {
+ mChannelDataManager.stop();
+ }
+ });
}
private void startAndWaitForComplete() throws InterruptedException {
- getInstrumentation().runOnMainSync(new Runnable() {
- @Override
- public void run() {
- mChannelDataManager.start();
- }
- });
- assertTrue(mListener.loadFinishedLatch.await(WAIT_TIME_OUT_MS, TimeUnit.MILLISECONDS));
+ getInstrumentation()
+ .runOnMainSync(
+ new Runnable() {
+ @Override
+ public void run() {
+ mChannelDataManager.start();
+ }
+ });
+ assertThat(mListener.loadFinishedLatch.await(WAIT_TIME_OUT_MS, TimeUnit.MILLISECONDS))
+ .isTrue();
}
private void restart() throws InterruptedException {
- getInstrumentation().runOnMainSync(new Runnable() {
- @Override
- public void run() {
- mChannelDataManager.stop();
- mListener.reset();
- }
- });
+ getInstrumentation()
+ .runOnMainSync(
+ new Runnable() {
+ @Override
+ public void run() {
+ mChannelDataManager.stop();
+ mListener.reset();
+ }
+ });
startAndWaitForComplete();
}
@Test
public void testIsDbLoadFinished() throws InterruptedException {
startAndWaitForComplete();
- assertTrue(mChannelDataManager.isDbLoadFinished());
+ assertThat(mChannelDataManager.isDbLoadFinished()).isTrue();
}
/**
- * Test for following methods
- * - {@link ChannelDataManager#getChannelCount}
- * - {@link ChannelDataManager#getChannelList}
- * - {@link ChannelDataManager#getChannel}
+ * Test for following methods - {@link ChannelDataManager#getChannelCount} - {@link
+ * ChannelDataManager#getChannelList} - {@link ChannelDataManager#getChannel}
*/
@Test
public void testGetChannels() throws InterruptedException {
startAndWaitForComplete();
// Test {@link ChannelDataManager#getChannelCount}
- assertEquals(Constants.UNIT_TEST_CHANNEL_COUNT, mChannelDataManager.getChannelCount());
+ assertThat(mChannelDataManager.getChannelCount())
+ .isEqualTo(Constants.UNIT_TEST_CHANNEL_COUNT);
// Test {@link ChannelDataManager#getChannelList}
List<ChannelInfo> channelInfoList = new ArrayList<>();
@@ -157,36 +174,32 @@ public class ChannelDataManagerTest {
for (Channel channel : channelList) {
boolean found = false;
for (ChannelInfo channelInfo : channelInfoList) {
- if (TextUtils.equals(channelInfo.name, channel.getDisplayName())
- && TextUtils.equals(channelInfo.name, channel.getDisplayName())) {
+ if (TextUtils.equals(channelInfo.name, channel.getDisplayName())) {
found = true;
channelInfoList.remove(channelInfo);
break;
}
}
- assertTrue("Cannot find (" + channel + ")", found);
+ assertWithMessage("Cannot find (" + channel + ")").that(found).isTrue();
}
// Test {@link ChannelDataManager#getChannelIndex()}
for (Channel channel : channelList) {
- assertEquals(channel, mChannelDataManager.getChannel(channel.getId()));
+ assertThat(mChannelDataManager.getChannel(channel.getId())).isEqualTo(channel);
}
}
- /**
- * Test for {@link ChannelDataManager#getChannelCount} when no channel is available.
- */
+ /** Test for {@link ChannelDataManager#getChannelCount} when no channel is available. */
@Test
public void testGetChannels_noChannels() throws InterruptedException {
mContentProvider.clear();
startAndWaitForComplete();
- assertEquals(0, mChannelDataManager.getChannelCount());
+ assertThat(mChannelDataManager.getChannelCount()).isEqualTo(0);
}
/**
- * Test for following methods and channel listener with notifying change.
- * - {@link ChannelDataManager#updateBrowsable}
- * - {@link ChannelDataManager#applyUpdatedValuesToDb}
+ * Test for following methods and channel listener with notifying change. - {@link
+ * ChannelDataManager#updateBrowsable} - {@link ChannelDataManager#applyUpdatedValuesToDb}
*/
@Test
public void testBrowsable() throws InterruptedException {
@@ -197,9 +210,9 @@ public class ChannelDataManagerTest {
List<Channel> browsableChannelList = mChannelDataManager.getBrowsableChannelList();
for (Channel browsableChannel : browsableChannelList) {
boolean found = channelList.remove(browsableChannel);
- assertTrue("Cannot find (" + browsableChannel + ")", found);
+ assertWithMessage("Cannot find (" + browsableChannel + ")").that(found).isTrue();
}
- assertEquals(0, channelList.size());
+ assertThat(channelList).isEmpty();
// Prepare for next tests.
channelList = mChannelDataManager.getChannelList();
@@ -210,8 +223,8 @@ public class ChannelDataManagerTest {
// Test {@link ChannelDataManager#updateBrowsable} & notification.
mChannelDataManager.updateBrowsable(channel1.getId(), false, false);
- assertTrue(mListener.channelBrowsableChangedCalled);
- assertFalse(mChannelDataManager.getBrowsableChannelList().contains(channel1));
+ assertThat(mListener.channelBrowsableChangedCalled).isTrue();
+ assertThat(mChannelDataManager.getBrowsableChannelList()).doesNotContain(channel1);
MoreAsserts.assertContentsInAnyOrder(channelListener.updatedChannels, channel1);
channelListener.reset();
@@ -221,14 +234,13 @@ public class ChannelDataManagerTest {
mChannelDataManager.applyUpdatedValuesToDb();
restart();
browsableChannelList = mChannelDataManager.getBrowsableChannelList();
- assertEquals(Constants.UNIT_TEST_CHANNEL_COUNT - 1, browsableChannelList.size());
- assertFalse(browsableChannelList.contains(channel1));
+ assertThat(browsableChannelList).hasSize(Constants.UNIT_TEST_CHANNEL_COUNT - 1);
+ assertThat(browsableChannelList).doesNotContain(channel1);
}
/**
- * Test for following methods and channel listener without notifying change.
- * - {@link ChannelDataManager#updateBrowsable}
- * - {@link ChannelDataManager#applyUpdatedValuesToDb}
+ * Test for following methods and channel listener without notifying change. - {@link
+ * ChannelDataManager#updateBrowsable} - {@link ChannelDataManager#applyUpdatedValuesToDb}
*/
@Test
public void testBrowsable_skipNotification() throws InterruptedException {
@@ -247,10 +259,10 @@ public class ChannelDataManagerTest {
mChannelDataManager.updateBrowsable(channel1.getId(), false, true);
mChannelDataManager.updateBrowsable(channel2.getId(), false, true);
mChannelDataManager.updateBrowsable(channel1.getId(), true, true);
- assertFalse(mListener.channelBrowsableChangedCalled);
+ assertThat(mListener.channelBrowsableChangedCalled).isFalse();
List<Channel> browsableChannelList = mChannelDataManager.getBrowsableChannelList();
- assertTrue(browsableChannelList.contains(channel1));
- assertFalse(browsableChannelList.contains(channel2));
+ assertThat(browsableChannelList).contains(channel1);
+ assertThat(browsableChannelList).doesNotContain(channel2);
// Test {@link ChannelDataManager#applyUpdatedValuesToDb}
// Disable the update notification to avoid the unwanted call of "onLoadFinished".
@@ -258,14 +270,13 @@ public class ChannelDataManagerTest {
mChannelDataManager.applyUpdatedValuesToDb();
restart();
browsableChannelList = mChannelDataManager.getBrowsableChannelList();
- assertEquals(Constants.UNIT_TEST_CHANNEL_COUNT - 1, browsableChannelList.size());
- assertFalse(browsableChannelList.contains(channel2));
+ assertThat(browsableChannelList).hasSize(Constants.UNIT_TEST_CHANNEL_COUNT - 1);
+ assertThat(browsableChannelList).doesNotContain(channel2);
}
/**
- * Test for following methods and channel listener.
- * - {@link ChannelDataManager#updateLocked}
- * - {@link ChannelDataManager#applyUpdatedValuesToDb}
+ * Test for following methods and channel listener. - {@link ChannelDataManager#updateLocked} -
+ * {@link ChannelDataManager#applyUpdatedValuesToDb}
*/
@Test
public void testLocked() throws InterruptedException {
@@ -274,7 +285,7 @@ public class ChannelDataManagerTest {
// Test if all channels aren't locked at the first time.
List<Channel> channelList = mChannelDataManager.getChannelList();
for (Channel channel : channelList) {
- assertFalse(channel + " is locked", channel.isLocked());
+ assertWithMessage(channel + " is locked").that(channel.isLocked()).isFalse();
}
// Prepare for next tests.
@@ -282,22 +293,20 @@ public class ChannelDataManagerTest {
// Test {@link ChannelDataManager#updateLocked}
mChannelDataManager.updateLocked(channel.getId(), true);
- assertTrue(mChannelDataManager.getChannel(channel.getId()).isLocked());
+ assertThat(mChannelDataManager.getChannel(channel.getId()).isLocked()).isTrue();
// Test {@link ChannelDataManager#applyUpdatedValuesToDb}.
// Disable the update notification to avoid the unwanted call of "onLoadFinished".
mContentResolver.mNotifyDisabled = true;
mChannelDataManager.applyUpdatedValuesToDb();
restart();
- assertTrue(mChannelDataManager.getChannel(channel.getId()).isLocked());
+ assertThat(mChannelDataManager.getChannel(channel.getId()).isLocked()).isTrue();
// Cleanup
mChannelDataManager.updateLocked(channel.getId(), false);
}
- /**
- * Test ChannelDataManager when channels in TvContract are updated, removed, or added.
- */
+ /** Test ChannelDataManager when channels in TvContract are updated, removed, or added. */
@Test
public void testChannelListChanged() throws InterruptedException {
startAndWaitForComplete();
@@ -308,9 +317,10 @@ public class ChannelDataManagerTest {
ChannelInfo testChannelInfo = ChannelInfo.create(getTargetContext(), (int) testChannelId);
testChannelId = Constants.UNIT_TEST_CHANNEL_COUNT + 1;
mContentProvider.simulateInsert(testChannelInfo);
- assertTrue(
- mListener.channelListUpdatedLatch.await(WAIT_TIME_OUT_MS, TimeUnit.MILLISECONDS));
- assertEquals(Constants.UNIT_TEST_CHANNEL_COUNT + 1, mChannelDataManager.getChannelCount());
+ assertThat(mListener.channelListUpdatedLatch.await(WAIT_TIME_OUT_MS, TimeUnit.MILLISECONDS))
+ .isTrue();
+ assertThat(mChannelDataManager.getChannelCount())
+ .isEqualTo(Constants.UNIT_TEST_CHANNEL_COUNT + 1);
// Test channel update
mListener.reset();
@@ -319,39 +329,45 @@ public class ChannelDataManagerTest {
mChannelDataManager.addChannelListener(testChannelId, channelListener);
String newName = testChannelInfo.name + "_test";
mContentProvider.simulateUpdate(testChannelId, newName);
- assertTrue(
- mListener.channelListUpdatedLatch.await(WAIT_TIME_OUT_MS, TimeUnit.MILLISECONDS));
- assertTrue(
- channelListener.channelChangedLatch.await(WAIT_TIME_OUT_MS, TimeUnit.MILLISECONDS));
- assertEquals(0, channelListener.removedChannels.size());
- assertEquals(1, channelListener.updatedChannels.size());
+ assertThat(mListener.channelListUpdatedLatch.await(WAIT_TIME_OUT_MS, TimeUnit.MILLISECONDS))
+ .isTrue();
+ assertThat(
+ channelListener.channelChangedLatch.await(
+ WAIT_TIME_OUT_MS, TimeUnit.MILLISECONDS))
+ .isTrue();
+ assertThat(channelListener.removedChannels).isEmpty();
+ assertThat(channelListener.updatedChannels).hasSize(1);
Channel updatedChannel = channelListener.updatedChannels.get(0);
- assertEquals(testChannelId, updatedChannel.getId());
- assertEquals(testChannelInfo.number, updatedChannel.getDisplayNumber());
- assertEquals(newName, updatedChannel.getDisplayName());
- assertEquals(Constants.UNIT_TEST_CHANNEL_COUNT + 1,
- mChannelDataManager.getChannelCount());
+ assertThat(updatedChannel.getId()).isEqualTo(testChannelId);
+ assertThat(updatedChannel.getDisplayNumber()).isEqualTo(testChannelInfo.number);
+ assertThat(updatedChannel.getDisplayName()).isEqualTo(newName);
+ assertThat(mChannelDataManager.getChannelCount())
+ .isEqualTo(Constants.UNIT_TEST_CHANNEL_COUNT + 1);
// Test channel remove.
mListener.reset();
channelListener.reset();
mContentProvider.simulateDelete(testChannelId);
- assertTrue(
- mListener.channelListUpdatedLatch.await(WAIT_TIME_OUT_MS, TimeUnit.MILLISECONDS));
- assertTrue(
- channelListener.channelChangedLatch.await(WAIT_TIME_OUT_MS, TimeUnit.MILLISECONDS));
- assertEquals(1, channelListener.removedChannels.size());
- assertEquals(0, channelListener.updatedChannels.size());
+ assertThat(mListener.channelListUpdatedLatch.await(WAIT_TIME_OUT_MS, TimeUnit.MILLISECONDS))
+ .isTrue();
+ assertThat(
+ channelListener.channelChangedLatch.await(
+ WAIT_TIME_OUT_MS, TimeUnit.MILLISECONDS))
+ .isTrue();
+ assertThat(channelListener.removedChannels).hasSize(1);
+ assertThat(channelListener.updatedChannels).isEmpty();
Channel removedChannel = channelListener.removedChannels.get(0);
- assertEquals(newName, removedChannel.getDisplayName());
- assertEquals(testChannelInfo.number, removedChannel.getDisplayNumber());
- assertEquals(Constants.UNIT_TEST_CHANNEL_COUNT, mChannelDataManager.getChannelCount());
+ assertThat(removedChannel.getDisplayName()).isEqualTo(newName);
+ assertThat(removedChannel.getDisplayNumber()).isEqualTo(testChannelInfo.number);
+ assertThat(mChannelDataManager.getChannelCount())
+ .isEqualTo(Constants.UNIT_TEST_CHANNEL_COUNT);
}
- private class ChannelInfoWrapper {
+ private static class ChannelInfoWrapper {
public ChannelInfo channelInfo;
public boolean browsable;
public boolean locked;
+
public ChannelInfoWrapper(ChannelInfo channelInfo) {
this.channelInfo = channelInfo;
browsable = true;
@@ -366,8 +382,14 @@ public class ChannelDataManagerTest {
public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork) {
super.notifyChange(uri, observer, syncToNetwork);
if (DEBUG) {
- Log.d(TAG, "onChanged(uri=" + uri + ", observer=" + observer + ") - Notification "
- + (mNotifyDisabled ? "disabled" : "enabled"));
+ Log.d(
+ TAG,
+ "onChanged(uri="
+ + uri
+ + ", observer="
+ + observer
+ + ") - Notification "
+ + (mNotifyDisabled ? "disabled" : "enabled"));
}
if (mNotifyDisabled) {
return;
@@ -390,19 +412,23 @@ public class ChannelDataManagerTest {
public FakeContentProvider(Context context) {
super(context);
for (int i = 1; i <= Constants.UNIT_TEST_CHANNEL_COUNT; i++) {
- mChannelInfoList.put(i,
- new ChannelInfoWrapper(ChannelInfo.create(getTargetContext(), i)));
+ mChannelInfoList.put(
+ i, new ChannelInfoWrapper(ChannelInfo.create(getTargetContext(), i)));
}
}
/**
- * Implementation of {@link ContentProvider#query}.
- * This assumes that {@link ChannelDataManager} queries channels
- * with empty {@code selection}. (i.e. channels are always queries for all)
+ * Implementation of {@link ContentProvider#query}. This assumes that {@link
+ * ChannelDataManager} queries channels with empty {@code selection}. (i.e. channels are
+ * always queries for all)
*/
@Override
- public Cursor query(Uri uri, String[] projection, String selection, String[]
- selectionArgs, String sortOrder) {
+ public Cursor query(
+ Uri uri,
+ String[] projection,
+ String selection,
+ String[] selectionArgs,
+ String sortOrder) {
if (DEBUG) {
Log.d(TAG, "dump query");
Log.d(TAG, " uri=" + uri);
@@ -414,9 +440,8 @@ public class ChannelDataManagerTest {
}
/**
- * Implementation of {@link ContentProvider#update}.
- * This assumes that {@link ChannelDataManager} update channels
- * only for changing browsable and locked.
+ * Implementation of {@link ContentProvider#update}. This assumes that {@link
+ * ChannelDataManager} update channels only for changing browsable and locked.
*/
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
@@ -434,8 +459,9 @@ public class ChannelDataManagerTest {
}
} else {
// See {@link Utils#buildSelectionForIds} for the syntax.
- String selectionForId = selection.substring(
- selection.indexOf("(") + 1, selection.lastIndexOf(")"));
+ String selectionForId =
+ selection.substring(
+ selection.indexOf("(") + 1, selection.lastIndexOf(")"));
String[] ids = selectionForId.split(", ");
if (ids != null) {
for (String id : ids) {
@@ -476,27 +502,25 @@ public class ChannelDataManagerTest {
}
/**
- * Simulates channel data insert.
- * This assigns original network ID (the same with channel number) to channel ID.
+ * Simulates channel data insert. This assigns original network ID (the same with channel
+ * number) to channel ID.
*/
public void simulateInsert(ChannelInfo testChannelInfo) {
long channelId = testChannelInfo.originalNetworkId;
- mChannelInfoList.put((int) channelId, new ChannelInfoWrapper(
- ChannelInfo.create(getTargetContext(), (int) channelId)));
+ mChannelInfoList.put(
+ (int) channelId,
+ new ChannelInfoWrapper(
+ ChannelInfo.create(getTargetContext(), (int) channelId)));
mContentResolver.notifyChange(TvContract.buildChannelUri(channelId), null);
}
- /**
- * Simulates channel data delete.
- */
+ /** Simulates channel data delete. */
public void simulateDelete(long channelId) {
mChannelInfoList.remove((int) channelId);
mContentResolver.notifyChange(TvContract.buildChannelUri(channelId), null);
}
- /**
- * Simulates channel data update.
- */
+ /** Simulates channel data update. */
public void simulateUpdate(long channelId, String newName) {
ChannelInfoWrapper channel = mChannelInfoList.get((int) channelId);
ChannelInfo.Builder builder = new ChannelInfo.Builder(channel.channelInfo);
@@ -506,8 +530,9 @@ public class ChannelDataManagerTest {
}
private void assertChannelUri(Uri uri) {
- assertTrue("Uri(" + uri + ") isn't channel uri",
- uri.toString().startsWith(Channels.CONTENT_URI.toString()));
+ assertWithMessage("Uri(" + uri + ") isn't channel uri")
+ .that(uri.toString().startsWith(Channels.CONTENT_URI.toString()))
+ .isTrue();
}
public void clear() {
@@ -528,20 +553,21 @@ public class ChannelDataManagerTest {
}
private class FakeCursor extends MockCursor {
- private final String[] ALL_COLUMNS = {
- Channels._ID,
- Channels.COLUMN_DISPLAY_NAME,
- Channels.COLUMN_DISPLAY_NUMBER,
- Channels.COLUMN_INPUT_ID,
- Channels.COLUMN_VIDEO_FORMAT,
- Channels.COLUMN_ORIGINAL_NETWORK_ID,
- COLUMN_BROWSABLE,
- COLUMN_LOCKED};
+ private final String[] allColumns = {
+ Channels._ID,
+ Channels.COLUMN_DISPLAY_NAME,
+ Channels.COLUMN_DISPLAY_NUMBER,
+ Channels.COLUMN_INPUT_ID,
+ Channels.COLUMN_VIDEO_FORMAT,
+ Channels.COLUMN_ORIGINAL_NETWORK_ID,
+ COLUMN_BROWSABLE,
+ COLUMN_LOCKED
+ };
private final String[] mColumns;
private int mPosition;
public FakeCursor(String[] columns) {
- mColumns = (columns == null) ? ALL_COLUMNS : columns;
+ mColumns = (columns == null) ? allColumns : columns;
mPosition = -1;
}
@@ -566,6 +592,7 @@ public class ChannelDataManagerTest {
switch (columnName) {
case Channels._ID:
return mContentProvider.keyAt(mPosition);
+ default: // fall out
}
if (DEBUG) {
Log.d(TAG, "Column (" + columnName + ") is ignored in getLong()");
@@ -586,6 +613,7 @@ public class ChannelDataManagerTest {
return DUMMY_INPUT_ID;
case Channels.COLUMN_VIDEO_FORMAT:
return channel.channelInfo.getVideoFormat();
+ default: // fall out
}
if (DEBUG) {
Log.d(TAG, "Column (" + columnName + ") is ignored in getString()");
@@ -604,6 +632,7 @@ public class ChannelDataManagerTest {
return channel.browsable ? 1 : 0;
case COLUMN_LOCKED:
return channel.locked ? 1 : 0;
+ default: // fall out
}
if (DEBUG) {
Log.d(TAG, "Column (" + columnName + ") is ignored in getInt()");
@@ -627,7 +656,7 @@ public class ChannelDataManagerTest {
}
}
- private class TestChannelDataManagerListener implements ChannelDataManager.Listener {
+ private static class TestChannelDataManagerListener implements ChannelDataManager.Listener {
public CountDownLatch loadFinishedLatch = new CountDownLatch(1);
public CountDownLatch channelListUpdatedLatch = new CountDownLatch(1);
public boolean channelBrowsableChangedCalled;
@@ -654,7 +683,7 @@ public class ChannelDataManagerTest {
}
}
- private class TestChannelDataManagerChannelListener
+ private static class TestChannelDataManagerChannelListener
implements ChannelDataManager.ChannelListener {
public CountDownLatch channelChangedLatch = new CountDownLatch(1);
public final List<Channel> removedChannels = new ArrayList<>();
diff --git a/tests/unit/src/com/android/tv/data/ChannelImplTest.java b/tests/unit/src/com/android/tv/data/ChannelImplTest.java
new file mode 100644
index 00000000..b791a7e4
--- /dev/null
+++ b/tests/unit/src/com/android/tv/data/ChannelImplTest.java
@@ -0,0 +1,381 @@
+/*
+ * 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.data;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import com.android.tv.data.api.Channel;
+import com.android.tv.testing.ComparatorTester;
+import com.android.tv.util.TvInputManagerHelper;
+import java.util.Comparator;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Matchers;
+import org.mockito.Mockito;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+/** Tests for {@link ChannelImpl}. */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class ChannelImplTest {
+ // Used for testing TV inputs with invalid input package. This could happen when a TV input is
+ // uninstalled while drawing an app link card.
+ private static final String INVALID_TV_INPUT_PACKAGE_NAME = "com.android.tv.invalid_tv_input";
+ // Used for testing TV inputs defined inside of Live TV.
+ private static final String LIVE_CHANNELS_PACKAGE_NAME = "com.android.tv";
+ // Used for testing a TV input which doesn't have its leanback launcher activity.
+ private static final String NONE_LEANBACK_TV_INPUT_PACKAGE_NAME =
+ "com.android.tv.none_leanback_tv_input";
+ // Used for testing a TV input which has its leanback launcher activity.
+ private static final String LEANBACK_TV_INPUT_PACKAGE_NAME = "com.android.tv.leanback_tv_input";
+ private static final String TEST_APP_LINK_TEXT = "test_app_link_text";
+ private static final String PARTNER_INPUT_ID = "partner";
+ private static final ActivityInfo TEST_ACTIVITY_INFO = new ActivityInfo();
+
+ private Context mMockContext;
+ private Intent mInvalidIntent;
+ private Intent mValidIntent;
+
+ @Before
+ public void setUp() throws NameNotFoundException {
+ mInvalidIntent = new Intent(Intent.ACTION_VIEW);
+ mInvalidIntent.setComponent(new ComponentName(INVALID_TV_INPUT_PACKAGE_NAME, ".test"));
+ mValidIntent = new Intent(Intent.ACTION_VIEW);
+ mValidIntent.setComponent(new ComponentName(LEANBACK_TV_INPUT_PACKAGE_NAME, ".test"));
+ Intent liveChannelsIntent = new Intent(Intent.ACTION_VIEW);
+ liveChannelsIntent.setComponent(
+ new ComponentName(LIVE_CHANNELS_PACKAGE_NAME, ".MainActivity"));
+ Intent leanbackTvInputIntent = new Intent(Intent.ACTION_VIEW);
+ leanbackTvInputIntent.setComponent(
+ new ComponentName(LEANBACK_TV_INPUT_PACKAGE_NAME, ".test"));
+
+ PackageManager mockPackageManager = Mockito.mock(PackageManager.class);
+ Mockito.when(
+ mockPackageManager.getLeanbackLaunchIntentForPackage(
+ INVALID_TV_INPUT_PACKAGE_NAME))
+ .thenReturn(null);
+ Mockito.when(
+ mockPackageManager.getLeanbackLaunchIntentForPackage(
+ LIVE_CHANNELS_PACKAGE_NAME))
+ .thenReturn(liveChannelsIntent);
+ Mockito.when(
+ mockPackageManager.getLeanbackLaunchIntentForPackage(
+ NONE_LEANBACK_TV_INPUT_PACKAGE_NAME))
+ .thenReturn(null);
+ Mockito.when(
+ mockPackageManager.getLeanbackLaunchIntentForPackage(
+ LEANBACK_TV_INPUT_PACKAGE_NAME))
+ .thenReturn(leanbackTvInputIntent);
+
+ // Channel.getAppLinkIntent() calls initAppLinkTypeAndIntent() which calls
+ // Intent.resolveActivityInfo() which calls PackageManager.getActivityInfo().
+ Mockito.doAnswer(
+ new Answer<ActivityInfo>() {
+ @Override
+ public ActivityInfo answer(InvocationOnMock invocation) {
+ // We only check the package name, since the class name can be
+ // changed
+ // when an intent is changed to an uri and created from the uri.
+ // (ex, ".className" -> "packageName.className")
+ return mValidIntent
+ .getComponent()
+ .getPackageName()
+ .equals(
+ ((ComponentName)
+ invocation
+ .getArguments()[0])
+ .getPackageName())
+ ? TEST_ACTIVITY_INFO
+ : null;
+ }
+ })
+ .when(mockPackageManager)
+ .getActivityInfo(Mockito.<ComponentName>any(), Mockito.anyInt());
+
+ mMockContext = Mockito.mock(Context.class);
+ Mockito.when(mMockContext.getApplicationContext()).thenReturn(mMockContext);
+ Mockito.when(mMockContext.getPackageName()).thenReturn(LIVE_CHANNELS_PACKAGE_NAME);
+ Mockito.when(mMockContext.getPackageManager()).thenReturn(mockPackageManager);
+ }
+
+ @Test
+ public void testGetAppLinkType_NoText_NoIntent() {
+ assertAppLinkType(Channel.APP_LINK_TYPE_NONE, INVALID_TV_INPUT_PACKAGE_NAME, null, null);
+ assertAppLinkType(Channel.APP_LINK_TYPE_NONE, LIVE_CHANNELS_PACKAGE_NAME, null, null);
+ assertAppLinkType(
+ Channel.APP_LINK_TYPE_NONE, NONE_LEANBACK_TV_INPUT_PACKAGE_NAME, null, null);
+ assertAppLinkType(Channel.APP_LINK_TYPE_APP, LEANBACK_TV_INPUT_PACKAGE_NAME, null, null);
+ }
+
+ @Test
+ public void testGetAppLinkType_NoText_InvalidIntent() {
+ assertAppLinkType(
+ Channel.APP_LINK_TYPE_NONE, INVALID_TV_INPUT_PACKAGE_NAME, null, mInvalidIntent);
+ assertAppLinkType(
+ Channel.APP_LINK_TYPE_NONE, LIVE_CHANNELS_PACKAGE_NAME, null, mInvalidIntent);
+ assertAppLinkType(
+ Channel.APP_LINK_TYPE_NONE,
+ NONE_LEANBACK_TV_INPUT_PACKAGE_NAME,
+ null,
+ mInvalidIntent);
+ assertAppLinkType(
+ Channel.APP_LINK_TYPE_APP, LEANBACK_TV_INPUT_PACKAGE_NAME, null, mInvalidIntent);
+ }
+
+ @Test
+ public void testGetAppLinkType_NoText_ValidIntent() {
+ assertAppLinkType(
+ Channel.APP_LINK_TYPE_NONE, INVALID_TV_INPUT_PACKAGE_NAME, null, mValidIntent);
+ assertAppLinkType(
+ Channel.APP_LINK_TYPE_NONE, LIVE_CHANNELS_PACKAGE_NAME, null, mValidIntent);
+ assertAppLinkType(
+ Channel.APP_LINK_TYPE_NONE,
+ NONE_LEANBACK_TV_INPUT_PACKAGE_NAME,
+ null,
+ mValidIntent);
+ assertAppLinkType(
+ Channel.APP_LINK_TYPE_APP, LEANBACK_TV_INPUT_PACKAGE_NAME, null, mValidIntent);
+ }
+
+ @Test
+ public void testGetAppLinkType_HasText_NoIntent() {
+ assertAppLinkType(
+ Channel.APP_LINK_TYPE_NONE,
+ INVALID_TV_INPUT_PACKAGE_NAME,
+ TEST_APP_LINK_TEXT,
+ null);
+ assertAppLinkType(
+ Channel.APP_LINK_TYPE_NONE, LIVE_CHANNELS_PACKAGE_NAME, TEST_APP_LINK_TEXT, null);
+ assertAppLinkType(
+ Channel.APP_LINK_TYPE_NONE,
+ NONE_LEANBACK_TV_INPUT_PACKAGE_NAME,
+ TEST_APP_LINK_TEXT,
+ null);
+ assertAppLinkType(
+ Channel.APP_LINK_TYPE_APP,
+ LEANBACK_TV_INPUT_PACKAGE_NAME,
+ TEST_APP_LINK_TEXT,
+ null);
+ }
+
+ @Test
+ public void testGetAppLinkType_HasText_InvalidIntent() {
+ assertAppLinkType(
+ Channel.APP_LINK_TYPE_NONE,
+ INVALID_TV_INPUT_PACKAGE_NAME,
+ TEST_APP_LINK_TEXT,
+ mInvalidIntent);
+ assertAppLinkType(
+ Channel.APP_LINK_TYPE_NONE,
+ LIVE_CHANNELS_PACKAGE_NAME,
+ TEST_APP_LINK_TEXT,
+ mInvalidIntent);
+ assertAppLinkType(
+ Channel.APP_LINK_TYPE_NONE,
+ NONE_LEANBACK_TV_INPUT_PACKAGE_NAME,
+ TEST_APP_LINK_TEXT,
+ mInvalidIntent);
+ assertAppLinkType(
+ Channel.APP_LINK_TYPE_APP,
+ LEANBACK_TV_INPUT_PACKAGE_NAME,
+ TEST_APP_LINK_TEXT,
+ mInvalidIntent);
+ }
+
+ @Test
+ public void testGetAppLinkType_HasText_ValidIntent() {
+ assertAppLinkType(
+ Channel.APP_LINK_TYPE_CHANNEL,
+ INVALID_TV_INPUT_PACKAGE_NAME,
+ TEST_APP_LINK_TEXT,
+ mValidIntent);
+ assertAppLinkType(
+ Channel.APP_LINK_TYPE_CHANNEL,
+ LIVE_CHANNELS_PACKAGE_NAME,
+ TEST_APP_LINK_TEXT,
+ mValidIntent);
+ assertAppLinkType(
+ Channel.APP_LINK_TYPE_CHANNEL,
+ NONE_LEANBACK_TV_INPUT_PACKAGE_NAME,
+ TEST_APP_LINK_TEXT,
+ mValidIntent);
+ assertAppLinkType(
+ Channel.APP_LINK_TYPE_CHANNEL,
+ LEANBACK_TV_INPUT_PACKAGE_NAME,
+ TEST_APP_LINK_TEXT,
+ mValidIntent);
+ }
+
+ private void assertAppLinkType(
+ int expectedType, String inputPackageName, String appLinkText, Intent appLinkIntent) {
+ // In ChannelImpl, Intent.URI_INTENT_SCHEME is used to parse the URI. So the same flag
+ // should be
+ // used when the URI is created.
+ ChannelImpl testChannel =
+ new ChannelImpl.Builder()
+ .setPackageName(inputPackageName)
+ .setAppLinkText(appLinkText)
+ .setAppLinkIntentUri(
+ appLinkIntent == null
+ ? null
+ : appLinkIntent.toUri(Intent.URI_INTENT_SCHEME))
+ .build();
+ assertWithMessage("Unexpected app-link type for for " + testChannel)
+ .that(testChannel.getAppLinkType(mMockContext))
+ .isEqualTo(expectedType);
+ }
+
+ @Test
+ public void testComparator() {
+ TvInputManagerHelper manager = Mockito.mock(TvInputManagerHelper.class);
+ Mockito.when(manager.isPartnerInput(Matchers.anyString()))
+ .thenAnswer(
+ new Answer<Boolean>() {
+ @Override
+ public Boolean answer(InvocationOnMock invocation) throws Throwable {
+ String inputId = (String) invocation.getArguments()[0];
+ return PARTNER_INPUT_ID.equals(inputId);
+ }
+ });
+ Comparator<Channel> comparator = new TestChannelComparator(manager);
+ ComparatorTester<Channel> comparatorTester = ComparatorTester.withoutEqualsTest(comparator);
+ comparatorTester.addComparableGroup(
+ new ChannelImpl.Builder().setInputId(PARTNER_INPUT_ID).build());
+ comparatorTester.addComparableGroup(new ChannelImpl.Builder().setInputId("1").build());
+ comparatorTester.addComparableGroup(
+ new ChannelImpl.Builder().setInputId("1").setDisplayNumber("2").build());
+ comparatorTester.addComparableGroup(
+ new ChannelImpl.Builder().setInputId("2").setDisplayNumber("1.0").build());
+
+ // display name does not affect comparator
+ comparatorTester.addComparableGroup(
+ new ChannelImpl.Builder()
+ .setInputId("2")
+ .setDisplayNumber("1.62")
+ .setDisplayName("test1")
+ .build(),
+ new ChannelImpl.Builder()
+ .setInputId("2")
+ .setDisplayNumber("1.62")
+ .setDisplayName("test2")
+ .build(),
+ new ChannelImpl.Builder()
+ .setInputId("2")
+ .setDisplayNumber("1.62")
+ .setDisplayName("test3")
+ .build());
+ comparatorTester.addComparableGroup(
+ new ChannelImpl.Builder().setInputId("2").setDisplayNumber("2.0").build());
+ // Numeric display number sorting
+ comparatorTester.addComparableGroup(
+ new ChannelImpl.Builder().setInputId("2").setDisplayNumber("12.2").build());
+ comparatorTester.test();
+ }
+
+ /**
+ * Test Input Label handled by {@link ChannelImpl.DefaultComparator}.
+ *
+ * <p>Sort partner inputs first, then sort by input label, then by input id. See <a
+ * href="http://b/23031603">b/23031603</a>.
+ */
+ @Test
+ public void testComparatorLabel() {
+ TvInputManagerHelper manager = Mockito.mock(TvInputManagerHelper.class);
+ Mockito.when(manager.isPartnerInput(Matchers.anyString()))
+ .thenAnswer(
+ new Answer<Boolean>() {
+ @Override
+ public Boolean answer(InvocationOnMock invocation) throws Throwable {
+ String inputId = (String) invocation.getArguments()[0];
+ return PARTNER_INPUT_ID.equals(inputId);
+ }
+ });
+ Comparator<Channel> comparator = new ChannelComparatorWithDescriptionAsLabel(manager);
+ ComparatorTester<Channel> comparatorTester = ComparatorTester.withoutEqualsTest(comparator);
+
+ comparatorTester.addComparableGroup(
+ new ChannelImpl.Builder().setInputId(PARTNER_INPUT_ID).setDescription("A").build());
+
+ // The description is used as a label for this test.
+ comparatorTester.addComparableGroup(
+ new ChannelImpl.Builder().setDescription("A").setInputId("1").build());
+ comparatorTester.addComparableGroup(
+ new ChannelImpl.Builder().setDescription("A").setInputId("2").build());
+ comparatorTester.addComparableGroup(
+ new ChannelImpl.Builder().setDescription("B").setInputId("1").build());
+
+ comparatorTester.test();
+ }
+
+ @Test
+ public void testNormalizeChannelNumber() {
+ assertNormalizedDisplayNumber(null, null);
+ assertNormalizedDisplayNumber("", "");
+ assertNormalizedDisplayNumber("1", "1");
+ assertNormalizedDisplayNumber("abcde", "abcde");
+ assertNormalizedDisplayNumber("1-1", "1-1");
+ assertNormalizedDisplayNumber("1.1", "1-1");
+ assertNormalizedDisplayNumber("1 1", "1-1");
+ assertNormalizedDisplayNumber("1\u058a1", "1-1");
+ assertNormalizedDisplayNumber("1\u05be1", "1-1");
+ assertNormalizedDisplayNumber("1\u14001", "1-1");
+ assertNormalizedDisplayNumber("1\u18061", "1-1");
+ assertNormalizedDisplayNumber("1\u20101", "1-1");
+ assertNormalizedDisplayNumber("1\u20111", "1-1");
+ assertNormalizedDisplayNumber("1\u20121", "1-1");
+ assertNormalizedDisplayNumber("1\u20131", "1-1");
+ assertNormalizedDisplayNumber("1\u20141", "1-1");
+ }
+
+ private void assertNormalizedDisplayNumber(String displayNumber, String normalized) {
+ assertThat(ChannelImpl.normalizeDisplayNumber(displayNumber)).isEqualTo(normalized);
+ }
+
+ private static final class TestChannelComparator extends ChannelImpl.DefaultComparator {
+ public TestChannelComparator(TvInputManagerHelper manager) {
+ super(null, manager);
+ }
+
+ @Override
+ public String getInputLabelForChannel(Channel channel) {
+ return channel.getInputId();
+ }
+ }
+
+ private static final class ChannelComparatorWithDescriptionAsLabel
+ extends ChannelImpl.DefaultComparator {
+ public ChannelComparatorWithDescriptionAsLabel(TvInputManagerHelper manager) {
+ super(null, manager);
+ }
+
+ @Override
+ public String getInputLabelForChannel(Channel channel) {
+ return channel.getDescription();
+ }
+ }
+}
diff --git a/tests/unit/src/com/android/tv/data/ChannelNumberTest.java b/tests/unit/src/com/android/tv/data/ChannelNumberTest.java
deleted file mode 100644
index 827dcdbd..00000000
--- a/tests/unit/src/com/android/tv/data/ChannelNumberTest.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * 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.data;
-
-import static com.android.tv.data.ChannelNumber.parseChannelNumber;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-
-import android.support.test.filters.SmallTest;
-
-import com.android.tv.testing.ComparableTester;
-
-import org.junit.Test;
-
-/**
- * Tests for {@link ChannelNumber}.
- */
-@SmallTest
-public class ChannelNumberTest {
- /**
- * Test method for {@link ChannelNumber#ChannelNumber()}.
- */
- @Test
- public void testChannelNumber() {
- assertChannelEquals(new ChannelNumber(), "", false, "");
- }
-
- /**
- * Test method for
- * {@link com.android.tv.data.ChannelNumber#parseChannelNumber(java.lang.String)}.
- */
- @Test
- public void testParseChannelNumber() {
- assertNull(parseChannelNumber(""));
- assertNull(parseChannelNumber("-"));
- assertNull(parseChannelNumber("abcd12"));
- assertNull(parseChannelNumber("12abcd"));
- assertNull(parseChannelNumber("-12"));
- assertChannelEquals(parseChannelNumber("1"), "1", false, "");
- assertChannelEquals(parseChannelNumber("1234-4321"), "1234", true, "4321");
- assertChannelEquals(parseChannelNumber("3-4"), "3", true, "4");
- assertChannelEquals(parseChannelNumber("5-6"), "5", true, "6");
- }
-
- /**
- * Test method for {@link ChannelNumber#compareTo(com.android.tv.data.ChannelNumber)}.
- */
- @Test
- public void testCompareTo() {
- new ComparableTester<ChannelNumber>()
- .addEquivalentGroup(parseChannelNumber("1"), parseChannelNumber("1"))
- .addEquivalentGroup(parseChannelNumber("2"))
- .addEquivalentGroup(parseChannelNumber("2-1"))
- .addEquivalentGroup(parseChannelNumber("2-2"))
- .addEquivalentGroup(parseChannelNumber("2-10"))
- .addEquivalentGroup(parseChannelNumber("3"))
- .addEquivalentGroup(parseChannelNumber("4"), parseChannelNumber("4-0"))
- .addEquivalentGroup(parseChannelNumber("10"))
- .addEquivalentGroup(parseChannelNumber("100"))
- .test();
- }
-
- /**
- * Test method for {@link ChannelNumber#compare(java.lang.String, java.lang.String)}.
- */
- @Test
- public void testCompare() {
- // Only need to test nulls, the reset is tested by testCompareTo
- assertEquals("compareTo(null,null)", 0, ChannelNumber.compare(null, null));
- assertEquals("compareTo(1,1)", 0, ChannelNumber.compare("1", "1"));
- assertEquals("compareTo(null,1)<0", true, ChannelNumber.compare(null, "1") < 0);
- assertEquals("compareTo(mal-formatted,1)<0", true, ChannelNumber.compare("abcd", "1") < 0);
- assertEquals("compareTo(mal-formatted,1)<0", true, ChannelNumber.compare(".4", "1") < 0);
- assertEquals("compareTo(1,null)>0", true, ChannelNumber.compare("1", null) > 0);
- }
-
- private void assertChannelEquals(ChannelNumber actual, String expectedMajor,
- boolean expectedHasDelimiter, String expectedMinor) {
- assertEquals(actual + " major", actual.majorNumber, expectedMajor);
- assertEquals(actual + " hasDelimiter", actual.hasDelimiter, expectedHasDelimiter);
- assertEquals(actual + " minor", actual.minorNumber, expectedMinor);
- }
-
-}
diff --git a/tests/unit/src/com/android/tv/data/ChannelTest.java b/tests/unit/src/com/android/tv/data/ChannelTest.java
deleted file mode 100644
index 69fcb858..00000000
--- a/tests/unit/src/com/android/tv/data/ChannelTest.java
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
- * 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.data;
-
-import static org.junit.Assert.assertEquals;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ActivityInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.support.test.filters.SmallTest;
-
-import com.android.tv.testing.ComparatorTester;
-import com.android.tv.util.TvInputManagerHelper;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Matchers;
-import org.mockito.Mockito;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-
-import java.util.Comparator;
-
-/**
- * Tests for {@link Channel}.
- */
-@SmallTest
-public class ChannelTest {
- // Used for testing TV inputs with invalid input package. This could happen when a TV input is
- // uninstalled while drawing an app link card.
- private static final String INVALID_TV_INPUT_PACKAGE_NAME =
- "com.android.tv.invalid_tv_input";
- // Used for testing TV inputs defined inside of Live TV.
- private static final String LIVE_CHANNELS_PACKAGE_NAME = "com.android.tv";
- // Used for testing a TV input which doesn't have its leanback launcher activity.
- private static final String NONE_LEANBACK_TV_INPUT_PACKAGE_NAME =
- "com.android.tv.none_leanback_tv_input";
- // Used for testing a TV input which has its leanback launcher activity.
- private static final String LEANBACK_TV_INPUT_PACKAGE_NAME =
- "com.android.tv.leanback_tv_input";
- private static final String TEST_APP_LINK_TEXT = "test_app_link_text";
- private static final String PARTNER_INPUT_ID = "partner";
- private static final ActivityInfo TEST_ACTIVITY_INFO = new ActivityInfo();
-
- private Context mMockContext;
- private Intent mInvalidIntent;
- private Intent mValidIntent;
-
- @Before
- public void setUp() throws NameNotFoundException {
- mInvalidIntent = new Intent(Intent.ACTION_VIEW);
- mInvalidIntent.setComponent(new ComponentName(INVALID_TV_INPUT_PACKAGE_NAME, ".test"));
- mValidIntent = new Intent(Intent.ACTION_VIEW);
- mValidIntent.setComponent(new ComponentName(LEANBACK_TV_INPUT_PACKAGE_NAME, ".test"));
- Intent liveChannelsIntent = new Intent(Intent.ACTION_VIEW);
- liveChannelsIntent.setComponent(
- new ComponentName(LIVE_CHANNELS_PACKAGE_NAME, ".MainActivity"));
- Intent leanbackTvInputIntent = new Intent(Intent.ACTION_VIEW);
- leanbackTvInputIntent.setComponent(
- new ComponentName(LEANBACK_TV_INPUT_PACKAGE_NAME, ".test"));
-
- PackageManager mockPackageManager = Mockito.mock(PackageManager.class);
- Mockito.when(mockPackageManager.getLeanbackLaunchIntentForPackage(
- INVALID_TV_INPUT_PACKAGE_NAME)).thenReturn(null);
- Mockito.when(mockPackageManager.getLeanbackLaunchIntentForPackage(
- LIVE_CHANNELS_PACKAGE_NAME)).thenReturn(liveChannelsIntent);
- Mockito.when(mockPackageManager.getLeanbackLaunchIntentForPackage(
- NONE_LEANBACK_TV_INPUT_PACKAGE_NAME)).thenReturn(null);
- Mockito.when(mockPackageManager.getLeanbackLaunchIntentForPackage(
- LEANBACK_TV_INPUT_PACKAGE_NAME)).thenReturn(leanbackTvInputIntent);
-
- // Channel.getAppLinkIntent() calls initAppLinkTypeAndIntent() which calls
- // Intent.resolveActivityInfo() which calls PackageManager.getActivityInfo().
- Mockito.doAnswer(new Answer<ActivityInfo>() {
- @Override
- public ActivityInfo answer(InvocationOnMock invocation) {
- // We only check the package name, since the class name can be changed
- // when an intent is changed to an uri and created from the uri.
- // (ex, ".className" -> "packageName.className")
- return mValidIntent.getComponent().getPackageName().equals(
- ((ComponentName)invocation.getArguments()[0]).getPackageName())
- ? TEST_ACTIVITY_INFO : null;
- }
- }).when(mockPackageManager).getActivityInfo(Mockito.<ComponentName>any(), Mockito.anyInt());
-
- mMockContext = Mockito.mock(Context.class);
- Mockito.when(mMockContext.getApplicationContext()).thenReturn(mMockContext);
- Mockito.when(mMockContext.getPackageName()).thenReturn(LIVE_CHANNELS_PACKAGE_NAME);
- Mockito.when(mMockContext.getPackageManager()).thenReturn(mockPackageManager);
- }
-
- @Test
- public void testGetAppLinkType_NoText_NoIntent() {
- assertAppLinkType(Channel.APP_LINK_TYPE_NONE, INVALID_TV_INPUT_PACKAGE_NAME, null, null);
- assertAppLinkType(Channel.APP_LINK_TYPE_NONE, LIVE_CHANNELS_PACKAGE_NAME, null, null);
- assertAppLinkType(Channel.APP_LINK_TYPE_NONE, NONE_LEANBACK_TV_INPUT_PACKAGE_NAME, null,
- null);
- assertAppLinkType(Channel.APP_LINK_TYPE_APP, LEANBACK_TV_INPUT_PACKAGE_NAME, null, null);
- }
-
- @Test
- public void testGetAppLinkType_NoText_InvalidIntent() {
- assertAppLinkType(Channel.APP_LINK_TYPE_NONE, INVALID_TV_INPUT_PACKAGE_NAME, null,
- mInvalidIntent);
- assertAppLinkType(Channel.APP_LINK_TYPE_NONE, LIVE_CHANNELS_PACKAGE_NAME, null,
- mInvalidIntent);
- assertAppLinkType(Channel.APP_LINK_TYPE_NONE, NONE_LEANBACK_TV_INPUT_PACKAGE_NAME, null,
- mInvalidIntent);
- assertAppLinkType(Channel.APP_LINK_TYPE_APP, LEANBACK_TV_INPUT_PACKAGE_NAME, null,
- mInvalidIntent);
- }
-
- @Test
- public void testGetAppLinkType_NoText_ValidIntent() {
- assertAppLinkType(Channel.APP_LINK_TYPE_NONE, INVALID_TV_INPUT_PACKAGE_NAME, null,
- mValidIntent);
- assertAppLinkType(Channel.APP_LINK_TYPE_NONE, LIVE_CHANNELS_PACKAGE_NAME, null,
- mValidIntent);
- assertAppLinkType(Channel.APP_LINK_TYPE_NONE, NONE_LEANBACK_TV_INPUT_PACKAGE_NAME, null,
- mValidIntent);
- assertAppLinkType(Channel.APP_LINK_TYPE_APP, LEANBACK_TV_INPUT_PACKAGE_NAME, null,
- mValidIntent);
- }
-
- @Test
- public void testGetAppLinkType_HasText_NoIntent() {
- assertAppLinkType(Channel.APP_LINK_TYPE_NONE, INVALID_TV_INPUT_PACKAGE_NAME,
- TEST_APP_LINK_TEXT, null);
- assertAppLinkType(Channel.APP_LINK_TYPE_NONE, LIVE_CHANNELS_PACKAGE_NAME,
- TEST_APP_LINK_TEXT, null);
- assertAppLinkType(Channel.APP_LINK_TYPE_NONE, NONE_LEANBACK_TV_INPUT_PACKAGE_NAME,
- TEST_APP_LINK_TEXT, null);
- assertAppLinkType(Channel.APP_LINK_TYPE_APP, LEANBACK_TV_INPUT_PACKAGE_NAME,
- TEST_APP_LINK_TEXT, null);
- }
-
- @Test
- public void testGetAppLinkType_HasText_InvalidIntent() {
- assertAppLinkType(Channel.APP_LINK_TYPE_NONE, INVALID_TV_INPUT_PACKAGE_NAME,
- TEST_APP_LINK_TEXT, mInvalidIntent);
- assertAppLinkType(Channel.APP_LINK_TYPE_NONE, LIVE_CHANNELS_PACKAGE_NAME,
- TEST_APP_LINK_TEXT, mInvalidIntent);
- assertAppLinkType(Channel.APP_LINK_TYPE_NONE, NONE_LEANBACK_TV_INPUT_PACKAGE_NAME,
- TEST_APP_LINK_TEXT, mInvalidIntent);
- assertAppLinkType(Channel.APP_LINK_TYPE_APP, LEANBACK_TV_INPUT_PACKAGE_NAME,
- TEST_APP_LINK_TEXT, mInvalidIntent);
- }
-
- @Test
- public void testGetAppLinkType_HasText_ValidIntent() {
- assertAppLinkType(Channel.APP_LINK_TYPE_CHANNEL, INVALID_TV_INPUT_PACKAGE_NAME,
- TEST_APP_LINK_TEXT, mValidIntent);
- assertAppLinkType(Channel.APP_LINK_TYPE_CHANNEL, LIVE_CHANNELS_PACKAGE_NAME,
- TEST_APP_LINK_TEXT, mValidIntent);
- assertAppLinkType(Channel.APP_LINK_TYPE_CHANNEL, NONE_LEANBACK_TV_INPUT_PACKAGE_NAME,
- TEST_APP_LINK_TEXT, mValidIntent);
- assertAppLinkType(Channel.APP_LINK_TYPE_CHANNEL, LEANBACK_TV_INPUT_PACKAGE_NAME,
- TEST_APP_LINK_TEXT, mValidIntent);
- }
-
- private void assertAppLinkType(int expectedType, String inputPackageName, String appLinkText,
- Intent appLinkIntent) {
- // In Channel, Intent.URI_INTENT_SCHEME is used to parse the URI. So the same flag should be
- // used when the URI is created.
- Channel testChannel = new Channel.Builder()
- .setPackageName(inputPackageName)
- .setAppLinkText(appLinkText)
- .setAppLinkIntentUri(appLinkIntent == null ? null : appLinkIntent.toUri(
- Intent.URI_INTENT_SCHEME))
- .build();
- assertEquals("Unexpected app-link type for for " + testChannel,
- expectedType, testChannel.getAppLinkType(mMockContext));
- }
-
- @Test
- public void testComparator() {
-
- TvInputManagerHelper manager = Mockito.mock(TvInputManagerHelper.class);
- Mockito.when(manager.isPartnerInput(Matchers.anyString())).thenAnswer(
- new Answer<Boolean>() {
- @Override
- public Boolean answer(InvocationOnMock invocation) throws Throwable {
- String inputId = (String) invocation.getArguments()[0];
- return PARTNER_INPUT_ID.equals(inputId);
- }
- });
- Comparator<Channel> comparator = new TestChannelComparator(manager);
- ComparatorTester<Channel> comparatorTester =
- ComparatorTester.withoutEqualsTest(comparator);
- comparatorTester.addComparableGroup(
- new Channel.Builder().setInputId(PARTNER_INPUT_ID).build());
- comparatorTester.addComparableGroup(
- new Channel.Builder().setInputId("1").build());
- comparatorTester.addComparableGroup(
- new Channel.Builder().setInputId("1").setDisplayNumber("2").build());
- comparatorTester.addComparableGroup(
- new Channel.Builder().setInputId("2").setDisplayNumber("1.0").build());
-
- // display name does not affect comparator
- comparatorTester.addComparableGroup(
- new Channel.Builder().setInputId("2").setDisplayNumber("1.62")
- .setDisplayName("test1").build(),
- new Channel.Builder().setInputId("2").setDisplayNumber("1.62")
- .setDisplayName("test2").build(),
- new Channel.Builder().setInputId("2").setDisplayNumber("1.62")
- .setDisplayName("test3").build());
- comparatorTester.addComparableGroup(
- new Channel.Builder().setInputId("2").setDisplayNumber("2.0").build());
- // Numeric display number sorting
- comparatorTester.addComparableGroup(
- new Channel.Builder().setInputId("2").setDisplayNumber("12.2").build());
- comparatorTester.test();
- }
-
- /**
- * Test Input Label handled by {@link com.android.tv.data.Channel.DefaultComparator}.
- *
- * <p>Sort partner inputs first, then sort by input label, then by input id.
- * See <a href="http://b/23031603">b/23031603</a>.
- */
- @Test
- public void testComparatorLabel() {
- TvInputManagerHelper manager = Mockito.mock(TvInputManagerHelper.class);
- Mockito.when(manager.isPartnerInput(Matchers.anyString())).thenAnswer(
- new Answer<Boolean>() {
- @Override
- public Boolean answer(InvocationOnMock invocation) throws Throwable {
- String inputId = (String) invocation.getArguments()[0];
- return PARTNER_INPUT_ID.equals(inputId);
- }
- });
- Comparator<Channel> comparator = new ChannelComparatorWithDescriptionAsLabel(manager);
- ComparatorTester<Channel> comparatorTester =
- ComparatorTester.withoutEqualsTest(comparator);
-
- comparatorTester.addComparableGroup(
- new Channel.Builder().setInputId(PARTNER_INPUT_ID).setDescription("A").build());
-
- // The description is used as a label for this test.
- comparatorTester.addComparableGroup(
- new Channel.Builder().setDescription("A").setInputId("1").build());
- comparatorTester.addComparableGroup(
- new Channel.Builder().setDescription("A").setInputId("2").build());
- comparatorTester.addComparableGroup(
- new Channel.Builder().setDescription("B").setInputId("1").build());
-
- comparatorTester.test();
- }
-
- @Test
- public void testNormalizeChannelNumber() {
- assertNormalizedDisplayNumber(null, null);
- assertNormalizedDisplayNumber("", "");
- assertNormalizedDisplayNumber("1", "1");
- assertNormalizedDisplayNumber("abcde", "abcde");
- assertNormalizedDisplayNumber("1-1", "1-1");
- assertNormalizedDisplayNumber("1.1", "1-1");
- assertNormalizedDisplayNumber("1 1", "1-1");
- assertNormalizedDisplayNumber("1\u058a1", "1-1");
- assertNormalizedDisplayNumber("1\u05be1", "1-1");
- assertNormalizedDisplayNumber("1\u14001", "1-1");
- assertNormalizedDisplayNumber("1\u18061", "1-1");
- assertNormalizedDisplayNumber("1\u20101", "1-1");
- assertNormalizedDisplayNumber("1\u20111", "1-1");
- assertNormalizedDisplayNumber("1\u20121", "1-1");
- assertNormalizedDisplayNumber("1\u20131", "1-1");
- assertNormalizedDisplayNumber("1\u20141", "1-1");
- }
-
- private void assertNormalizedDisplayNumber(String displayNumber, String normalized) {
- assertEquals(normalized, Channel.normalizeDisplayNumber(displayNumber));
- }
-
- private class TestChannelComparator extends Channel.DefaultComparator {
- public TestChannelComparator(TvInputManagerHelper manager) {
- super(null, manager);
- }
-
- @Override
- public String getInputLabelForChannel(Channel channel) {
- return channel.getInputId();
- }
- }
-
- private static class ChannelComparatorWithDescriptionAsLabel extends Channel.DefaultComparator {
- public ChannelComparatorWithDescriptionAsLabel(TvInputManagerHelper manager) {
- super(null, manager);
- }
-
- @Override
- public String getInputLabelForChannel(Channel channel) {
- return channel.getDescription();
- }
- }
-}
diff --git a/tests/unit/src/com/android/tv/data/GenreItemTest.java b/tests/unit/src/com/android/tv/data/GenreItemTest.java
deleted file mode 100644
index fdbcb599..00000000
--- a/tests/unit/src/com/android/tv/data/GenreItemTest.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * 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.data;
-
-import static android.support.test.InstrumentationRegistry.getTargetContext;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import android.media.tv.TvContract.Programs.Genres;
-import android.os.Build;
-import android.support.test.filters.SmallTest;
-
-import org.junit.Test;
-
-/**
- * Tests for {@link Channel}.
- */
-@SmallTest
-public class GenreItemTest {
- private static final String INVALID_GENRE = "INVALID GENRE";
-
- @Test
- public void testGetLabels() {
- // Checks if no exception is thrown.
- GenreItems.getLabels(getTargetContext());
- }
-
- @Test
- public void testGetCanonicalGenre() {
- int count = GenreItems.getGenreCount();
- assertNull(GenreItems.getCanonicalGenre(GenreItems.ID_ALL_CHANNELS));
- for (int i = 1; i < count; ++i) {
- assertNotNull(GenreItems.getCanonicalGenre(i));
- }
- }
-
- @Test
- public void testGetId_base() {
- int count = GenreItems.getGenreCount();
- assertEquals(GenreItems.ID_ALL_CHANNELS, GenreItems.getId(null));
- assertEquals(GenreItems.ID_ALL_CHANNELS, GenreItems.getId(INVALID_GENRE));
- assertInRange(GenreItems.getId(Genres.FAMILY_KIDS), 1, count - 1);
- assertInRange(GenreItems.getId(Genres.SPORTS), 1, count - 1);
- assertInRange(GenreItems.getId(Genres.SHOPPING), 1, count - 1);
- assertInRange(GenreItems.getId(Genres.MOVIES), 1, count - 1);
- assertInRange(GenreItems.getId(Genres.COMEDY), 1, count - 1);
- assertInRange(GenreItems.getId(Genres.TRAVEL), 1, count - 1);
- assertInRange(GenreItems.getId(Genres.DRAMA), 1, count - 1);
- assertInRange(GenreItems.getId(Genres.EDUCATION), 1, count - 1);
- assertInRange(GenreItems.getId(Genres.ANIMAL_WILDLIFE), 1, count - 1);
- assertInRange(GenreItems.getId(Genres.NEWS), 1, count - 1);
- assertInRange(GenreItems.getId(Genres.GAMING), 1, count - 1);
- }
-
- @Test
- public void testGetId_lmp_mr1() {
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP_MR1) {
- assertEquals(GenreItems.ID_ALL_CHANNELS, GenreItems.getId(Genres.ARTS));
- assertEquals(GenreItems.ID_ALL_CHANNELS, GenreItems.getId(Genres.ENTERTAINMENT));
- assertEquals(GenreItems.ID_ALL_CHANNELS, GenreItems.getId(Genres.LIFE_STYLE));
- assertEquals(GenreItems.ID_ALL_CHANNELS, GenreItems.getId(Genres.MUSIC));
- assertEquals(GenreItems.ID_ALL_CHANNELS, GenreItems.getId(Genres.PREMIER));
- assertEquals(GenreItems.ID_ALL_CHANNELS, GenreItems.getId(Genres.TECH_SCIENCE));
- } else {
- int count = GenreItems.getGenreCount();
- assertInRange(GenreItems.getId(Genres.ARTS), 1, count - 1);
- assertInRange(GenreItems.getId(Genres.ENTERTAINMENT), 1, count - 1);
- assertInRange(GenreItems.getId(Genres.LIFE_STYLE), 1, count - 1);
- assertInRange(GenreItems.getId(Genres.MUSIC), 1, count - 1);
- assertInRange(GenreItems.getId(Genres.PREMIER), 1, count - 1);
- assertInRange(GenreItems.getId(Genres.TECH_SCIENCE), 1, count - 1);
- }
- }
-
- private void assertInRange(int value, int lower, int upper) {
- assertTrue(value >= lower && value <= upper);
- }
-}
diff --git a/tests/unit/src/com/android/tv/data/ProgramDataManagerTest.java b/tests/unit/src/com/android/tv/data/ProgramDataManagerTest.java
deleted file mode 100644
index 5457051f..00000000
--- a/tests/unit/src/com/android/tv/data/ProgramDataManagerTest.java
+++ /dev/null
@@ -1,542 +0,0 @@
-/*
- * 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.data;
-
-import static android.support.test.InstrumentationRegistry.getTargetContext;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import android.content.Context;
-import android.database.ContentObserver;
-import android.database.Cursor;
-import android.media.tv.TvContract;
-import android.net.Uri;
-import android.os.HandlerThread;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.SmallTest;
-import android.test.mock.MockContentProvider;
-import android.test.mock.MockContentResolver;
-import android.test.mock.MockCursor;
-import android.util.Log;
-import android.util.SparseArray;
-
-import com.android.tv.testing.Constants;
-import com.android.tv.testing.FakeClock;
-import com.android.tv.testing.ProgramInfo;
-import com.android.tv.util.Utils;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Test for {@link com.android.tv.data.ProgramDataManager}
- */
-@SmallTest
-public class ProgramDataManagerTest {
- private static final boolean DEBUG = false;
- private static final String TAG = "ProgramDataManagerTest";
-
- // Wait time for expected success.
- private static final long WAIT_TIME_OUT_MS = 1000L;
- // Wait time for expected failure.
- private static final long FAILURE_TIME_OUT_MS = 300L;
-
- // TODO: Use TvContract constants, once they become public.
- private static final String PARAM_CHANNEL = "channel";
- private static final String PARAM_START_TIME = "start_time";
- private static final String PARAM_END_TIME = "end_time";
-
- private ProgramDataManager mProgramDataManager;
- private FakeClock mClock;
- private HandlerThread mHandlerThread;
- private TestProgramDataManagerListener mListener;
- private FakeContentResolver mContentResolver;
- private FakeContentProvider mContentProvider;
-
- @Before
- public void setUp() {
- mClock = FakeClock.createWithCurrentTime();
- mListener = new TestProgramDataManagerListener();
- mContentProvider = new FakeContentProvider(getTargetContext());
- mContentResolver = new FakeContentResolver();
- mContentResolver.addProvider(TvContract.AUTHORITY, mContentProvider);
- mHandlerThread = new HandlerThread(TAG);
- mHandlerThread.start();
- mProgramDataManager = new ProgramDataManager(
- mContentResolver, mClock, mHandlerThread.getLooper());
- mProgramDataManager.setPrefetchEnabled(true);
- mProgramDataManager.addListener(mListener);
- }
-
- @After
- public void tearDown() {
- mHandlerThread.quitSafely();
- mProgramDataManager.stop();
- }
-
- private void startAndWaitForComplete() throws InterruptedException {
- mProgramDataManager.start();
- assertTrue(mListener.programUpdatedLatch.await(WAIT_TIME_OUT_MS, TimeUnit.MILLISECONDS));
- }
-
- /**
- * Test for {@link ProgramInfo#getIndex} and {@link ProgramInfo#getStartTimeMs}.
- */
- @Test
- public void testProgramUtils() {
- ProgramInfo stub = ProgramInfo.create();
- for (long channelId = 1; channelId < Constants.UNIT_TEST_CHANNEL_COUNT; channelId++) {
- int index = stub.getIndex(mClock.currentTimeMillis(), channelId);
- long startTimeMs = stub.getStartTimeMs(index, channelId);
- ProgramInfo programAt = stub.build(InstrumentationRegistry.getContext(), index);
- assertTrue(startTimeMs <= mClock.currentTimeMillis());
- assertTrue(mClock.currentTimeMillis() < startTimeMs + programAt.durationMs);
- }
- }
-
- /**
- * Test for following methods.
- *
- * <p>
- * {@link ProgramDataManager#getCurrentProgram(long)},
- * {@link ProgramDataManager#getPrograms(long, long)},
- * {@link ProgramDataManager#setPrefetchTimeRange(long)}.
- * </p>
- */
- @Test
- public void testGetPrograms() throws InterruptedException {
- // Initial setup to test {@link ProgramDataManager#setPrefetchTimeRange(long)}.
- long preventSnapDelayMs = ProgramDataManager.PROGRAM_GUIDE_SNAP_TIME_MS * 2;
- long prefetchTimeRangeStartMs = System.currentTimeMillis() + preventSnapDelayMs;
- mClock.setCurrentTimeMillis(prefetchTimeRangeStartMs + preventSnapDelayMs);
- mProgramDataManager.setPrefetchTimeRange(prefetchTimeRangeStartMs);
-
- startAndWaitForComplete();
-
- for (long channelId = 1; channelId <= Constants.UNIT_TEST_CHANNEL_COUNT; channelId++) {
- Program currentProgram = mProgramDataManager.getCurrentProgram(channelId);
- // Test {@link ProgramDataManager#getCurrentProgram(long)}.
- assertTrue(currentProgram.getStartTimeUtcMillis() <= mClock.currentTimeMillis()
- && mClock.currentTimeMillis() <= currentProgram.getEndTimeUtcMillis());
-
- // Test {@link ProgramDataManager#getPrograms(long)}.
- // Case #1: Normal case
- List<Program> programs =
- mProgramDataManager.getPrograms(channelId, mClock.currentTimeMillis());
- ProgramInfo stub = ProgramInfo.create();
- int index = stub.getIndex(mClock.currentTimeMillis(), channelId);
- for (Program program : programs) {
- ProgramInfo programInfoAt = stub.build(InstrumentationRegistry.getContext(), index);
- long startTimeMs = stub.getStartTimeMs(index, channelId);
- assertProgramEquals(startTimeMs, programInfoAt, program);
- index++;
- }
- // Case #2: Corner cases where there's a program that starts at the start of the range.
- long startTimeMs = programs.get(0).getStartTimeUtcMillis();
- programs = mProgramDataManager.getPrograms(channelId, startTimeMs);
- assertEquals(startTimeMs, programs.get(0).getStartTimeUtcMillis());
-
- // Test {@link ProgramDataManager#setPrefetchTimeRange(long)}.
- programs = mProgramDataManager.getPrograms(channelId,
- prefetchTimeRangeStartMs - TimeUnit.HOURS.toMillis(1));
- for (Program program : programs) {
- assertTrue(program.getEndTimeUtcMillis() >= prefetchTimeRangeStartMs);
- }
- }
- }
-
- /**
- * Test for following methods.
- *
- * <p>
- * {@link ProgramDataManager#addOnCurrentProgramUpdatedListener},
- * {@link ProgramDataManager#removeOnCurrentProgramUpdatedListener}.
- * </p>
- */
- @Test
- public void testCurrentProgramListener() throws InterruptedException {
- final long testChannelId = 1;
- ProgramInfo stub = ProgramInfo.create();
- int index = stub.getIndex(mClock.currentTimeMillis(), testChannelId);
- // Set current time to few seconds before the current program ends,
- // so we can see if callback is called as expected.
- long nextProgramStartTimeMs = stub.getStartTimeMs(index + 1, testChannelId);
- ProgramInfo nextProgramInfo = stub.build(InstrumentationRegistry.getContext(), index + 1);
- mClock.setCurrentTimeMillis(nextProgramStartTimeMs - (WAIT_TIME_OUT_MS / 2));
-
- startAndWaitForComplete();
- // Note that changing current time doesn't affect the current program
- // because current program is updated after waiting for the program's duration.
- // See {@link ProgramDataManager#updateCurrentProgram}.
- mClock.setCurrentTimeMillis(mClock.currentTimeMillis() + WAIT_TIME_OUT_MS);
- TestProgramDataManagerOnCurrentProgramUpdatedListener listener =
- new TestProgramDataManagerOnCurrentProgramUpdatedListener();
- mProgramDataManager.addOnCurrentProgramUpdatedListener(testChannelId, listener);
- assertTrue(
- listener.currentProgramUpdatedLatch.await(WAIT_TIME_OUT_MS, TimeUnit.MILLISECONDS));
- assertEquals(testChannelId, listener.updatedChannelId);
- Program currentProgram = mProgramDataManager.getCurrentProgram(testChannelId);
- assertProgramEquals(nextProgramStartTimeMs, nextProgramInfo, currentProgram);
- assertEquals(listener.updatedProgram, currentProgram);
- }
-
- /**
- * Test if program data is refreshed after the program insertion.
- */
- @Test
- public void testContentProviderUpdate() throws InterruptedException {
- final long testChannelId = 1;
- startAndWaitForComplete();
- // Force program data manager to update program data whenever it's changes.
- mProgramDataManager.setProgramPrefetchUpdateWait(0);
- mListener.reset();
- List<Program> programList =
- mProgramDataManager.getPrograms(testChannelId, mClock.currentTimeMillis());
- assertNotNull(programList);
- long lastProgramEndTime = programList.get(programList.size() - 1).getEndTimeUtcMillis();
- // Make change in content provider
- mContentProvider.simulateAppend(testChannelId);
- assertTrue(mListener.programUpdatedLatch.await(WAIT_TIME_OUT_MS, TimeUnit.MILLISECONDS));
- programList = mProgramDataManager.getPrograms(testChannelId, mClock.currentTimeMillis());
- assertTrue(
- lastProgramEndTime < programList.get(programList.size() - 1).getEndTimeUtcMillis());
- }
-
- /**
- * Test for {@link ProgramDataManager#setPauseProgramUpdate(boolean)}.
- */
- @Test
- public void testSetPauseProgramUpdate() throws InterruptedException {
- final long testChannelId = 1;
- startAndWaitForComplete();
- // Force program data manager to update program data whenever it's changes.
- mProgramDataManager.setProgramPrefetchUpdateWait(0);
- mListener.reset();
- mProgramDataManager.setPauseProgramUpdate(true);
- mContentProvider.simulateAppend(testChannelId);
- assertFalse(mListener.programUpdatedLatch.await(FAILURE_TIME_OUT_MS,
- TimeUnit.MILLISECONDS));
- }
-
- public static void assertProgramEquals(long expectedStartTime, ProgramInfo expectedInfo,
- Program actualProgram) {
- assertEquals("title", expectedInfo.title, actualProgram.getTitle());
- assertEquals("episode", expectedInfo.episode, actualProgram.getEpisodeTitle());
- assertEquals("description", expectedInfo.description, actualProgram.getDescription());
- assertEquals("startTime", expectedStartTime, actualProgram.getStartTimeUtcMillis());
- assertEquals("endTime", expectedStartTime + expectedInfo.durationMs,
- actualProgram.getEndTimeUtcMillis());
- }
-
- private class FakeContentResolver extends MockContentResolver {
- @Override
- public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork) {
- super.notifyChange(uri, observer, syncToNetwork);
- if (DEBUG) {
- Log.d(TAG, "onChanged(uri=" + uri + ")");
- }
- if (observer != null) {
- observer.dispatchChange(false, uri);
- } else {
- mProgramDataManager.getContentObserver().dispatchChange(false, uri);
- }
- }
- }
-
- private static class ProgramInfoWrapper {
- private final int index;
- private final long startTimeMs;
- private final ProgramInfo programInfo;
-
- public ProgramInfoWrapper(int index, long startTimeMs, ProgramInfo programInfo) {
- this.index = index;
- this.startTimeMs = startTimeMs;
- this.programInfo = programInfo;
- }
- }
-
- // This implements the minimal methods in content resolver
- // and detailed assumptions are written in each method.
- private class FakeContentProvider extends MockContentProvider {
- private final SparseArray<List<ProgramInfoWrapper>> mProgramInfoList = new SparseArray<>();
-
- /**
- * Constructor for FakeContentProvider
- * <p>
- * This initializes program info assuming that
- * channel IDs are 1, 2, 3, ... {@link Constants#UNIT_TEST_CHANNEL_COUNT}.
- * </p>
- */
- public FakeContentProvider(Context context) {
- super(context);
- long startTimeMs = Utils.floorTime(
- mClock.currentTimeMillis() - ProgramDataManager.PROGRAM_GUIDE_SNAP_TIME_MS,
- ProgramDataManager.PROGRAM_GUIDE_SNAP_TIME_MS);
- long endTimeMs = startTimeMs + (ProgramDataManager.PROGRAM_GUIDE_MAX_TIME_RANGE / 2);
- for (int i = 1; i <= Constants.UNIT_TEST_CHANNEL_COUNT; i++) {
- List<ProgramInfoWrapper> programInfoList = new ArrayList<>();
- ProgramInfo stub = ProgramInfo.create();
- int index = stub.getIndex(startTimeMs, i);
- long programStartTimeMs = stub.getStartTimeMs(index, i);
- while (programStartTimeMs < endTimeMs) {
- ProgramInfo programAt = stub.build(InstrumentationRegistry.getContext(), index);
- programInfoList.add(
- new ProgramInfoWrapper(index, programStartTimeMs, programAt));
- index++;
- programStartTimeMs += programAt.durationMs;
- }
- mProgramInfoList.put(i, programInfoList);
- }
- }
-
- @Override
- public Cursor query(Uri uri, String[] projection, String selection,
- String[] selectionArgs, String sortOrder) {
- if (DEBUG) {
- Log.d(TAG, "dump query");
- Log.d(TAG, " uri=" + uri);
- Log.d(TAG, " projection=" + Arrays.toString(projection));
- Log.d(TAG, " selection=" + selection);
- }
- long startTimeMs = Long.parseLong(uri.getQueryParameter(PARAM_START_TIME));
- long endTimeMs = Long.parseLong(uri.getQueryParameter(PARAM_END_TIME));
- if (startTimeMs == 0 || endTimeMs == 0) {
- throw new UnsupportedOperationException();
- }
- assertProgramUri(uri);
- long channelId;
- try {
- channelId = Long.parseLong(uri.getQueryParameter(PARAM_CHANNEL));
- } catch (NumberFormatException e) {
- channelId = -1;
- }
- return new FakeCursor(projection, channelId, startTimeMs, endTimeMs);
- }
-
- /**
- * Simulate program data appends at the end of the existing programs.
- * This appends programs until the maximum program query range
- * ({@link ProgramDataManager#PROGRAM_GUIDE_MAX_TIME_RANGE})
- * where we started with the inserting half of it.
- */
- public void simulateAppend(long channelId) {
- long endTimeMs =
- mClock.currentTimeMillis() + ProgramDataManager.PROGRAM_GUIDE_MAX_TIME_RANGE;
- List<ProgramInfoWrapper> programList = mProgramInfoList.get((int) channelId);
- if (mProgramInfoList == null) {
- return;
- }
- ProgramInfo stub = ProgramInfo.create();
- ProgramInfoWrapper last = programList.get(programList.size() - 1);
- while (last.startTimeMs < endTimeMs) {
- ProgramInfo nextProgramInfo = stub.build(InstrumentationRegistry.getContext(),
- last.index + 1);
- ProgramInfoWrapper next = new ProgramInfoWrapper(last.index + 1,
- last.startTimeMs + last.programInfo.durationMs, nextProgramInfo);
- programList.add(next);
- last = next;
- }
- mContentResolver.notifyChange(TvContract.Programs.CONTENT_URI, null);
- }
-
- private void assertProgramUri(Uri uri) {
- assertTrue("Uri(" + uri + ") isn't channel uri",
- uri.toString().startsWith(TvContract.Programs.CONTENT_URI.toString()));
- }
-
- public ProgramInfoWrapper get(long channelId, int position) {
- List<ProgramInfoWrapper> programList = mProgramInfoList.get((int) channelId);
- if (programList == null || position >= programList.size()) {
- return null;
- }
- return programList.get(position);
- }
- }
-
- private class FakeCursor extends MockCursor {
- private final String[] ALL_COLUMNS = {
- TvContract.Programs.COLUMN_CHANNEL_ID,
- TvContract.Programs.COLUMN_TITLE,
- TvContract.Programs.COLUMN_SHORT_DESCRIPTION,
- TvContract.Programs.COLUMN_EPISODE_TITLE,
- TvContract.Programs.COLUMN_START_TIME_UTC_MILLIS,
- TvContract.Programs.COLUMN_END_TIME_UTC_MILLIS};
- private final String[] mColumns;
- private final boolean mIsQueryForSingleChannel;
- private final long mStartTimeMs;
- private final long mEndTimeMs;
- private final int mCount;
- private long mChannelId;
- private int mProgramPosition;
- private ProgramInfoWrapper mCurrentProgram;
-
- /**
- * Constructor
- * @param columns the same as projection passed from {@link FakeContentProvider#query}.
- * Can be null for query all.
- * @param channelId channel ID to query programs belongs to the specified channel.
- * Can be negative to indicate all channels.
- * @param startTimeMs start of the time range to query programs.
- * @param endTimeMs end of the time range to query programs.
- */
- public FakeCursor(String[] columns, long channelId, long startTimeMs, long endTimeMs) {
- mColumns = (columns == null) ? ALL_COLUMNS : columns;
- mIsQueryForSingleChannel = (channelId > 0);
- mChannelId = channelId;
- mProgramPosition = -1;
- mStartTimeMs = startTimeMs;
- mEndTimeMs = endTimeMs;
- int count = 0;
- while (moveToNext()) {
- count++;
- }
- mCount = count;
- // Rewind channel Id and program index.
- mChannelId = channelId;
- mProgramPosition = -1;
- if (DEBUG) {
- Log.d(TAG, "FakeCursor(columns=" + Arrays.toString(columns)
- + ", channelId=" + channelId + ", startTimeMs=" + startTimeMs
- + ", endTimeMs=" + endTimeMs + ") has mCount=" + mCount);
- }
- }
-
- @Override
- public String getColumnName(int columnIndex) {
- return mColumns[columnIndex];
- }
-
- @Override
- public int getColumnIndex(String columnName) {
- for (int i = 0; i < mColumns.length; i++) {
- if (mColumns[i].equalsIgnoreCase(columnName)) {
- return i;
- }
- }
- return -1;
- }
-
- @Override
- public int getInt(int columnIndex) {
- if (DEBUG) {
- Log.d(TAG, "Column (" + getColumnName(columnIndex) + ") is ignored in getInt()");
- }
- return 0;
- }
-
- @Override
- public long getLong(int columnIndex) {
- String columnName = getColumnName(columnIndex);
- switch (columnName) {
- case TvContract.Programs.COLUMN_CHANNEL_ID:
- return mChannelId;
- case TvContract.Programs.COLUMN_START_TIME_UTC_MILLIS:
- return mCurrentProgram.startTimeMs;
- case TvContract.Programs.COLUMN_END_TIME_UTC_MILLIS:
- return mCurrentProgram.startTimeMs + mCurrentProgram.programInfo.durationMs;
- }
- if (DEBUG) {
- Log.d(TAG, "Column (" + columnName + ") is ignored in getLong()");
- }
- return 0;
- }
-
- @Override
- public String getString(int columnIndex) {
- String columnName = getColumnName(columnIndex);
- switch (columnName) {
- case TvContract.Programs.COLUMN_TITLE:
- return mCurrentProgram.programInfo.title;
- case TvContract.Programs.COLUMN_SHORT_DESCRIPTION:
- return mCurrentProgram.programInfo.description;
- case TvContract.Programs.COLUMN_EPISODE_TITLE:
- return mCurrentProgram.programInfo.episode;
- }
- if (DEBUG) {
- Log.d(TAG, "Column (" + columnName + ") is ignored in getString()");
- }
- return null;
- }
-
- @Override
- public int getCount() {
- return mCount;
- }
-
- @Override
- public boolean moveToNext() {
- while (true) {
- ProgramInfoWrapper program = mContentProvider.get(mChannelId, ++mProgramPosition);
- if (program == null || program.startTimeMs >= mEndTimeMs) {
- if (mIsQueryForSingleChannel) {
- return false;
- } else {
- if (++mChannelId > Constants.UNIT_TEST_CHANNEL_COUNT) {
- return false;
- }
- mProgramPosition = -1;
- }
- } else if (program.startTimeMs + program.programInfo.durationMs >= mStartTimeMs) {
- mCurrentProgram = program;
- break;
- }
- }
- return true;
- }
-
- @Override
- public void close() {
- // No-op.
- }
- }
-
- private class TestProgramDataManagerListener implements ProgramDataManager.Listener {
- public CountDownLatch programUpdatedLatch = new CountDownLatch(1);
-
- @Override
- public void onProgramUpdated() {
- programUpdatedLatch.countDown();
- }
-
- public void reset() {
- programUpdatedLatch = new CountDownLatch(1);
- }
- }
-
- private class TestProgramDataManagerOnCurrentProgramUpdatedListener implements
- OnCurrentProgramUpdatedListener {
- public final CountDownLatch currentProgramUpdatedLatch = new CountDownLatch(1);
- public long updatedChannelId = -1;
- public Program updatedProgram = null;
-
- @Override
- public void onCurrentProgramUpdated(long channelId, Program program) {
- updatedChannelId = channelId;
- updatedProgram = program;
- currentProgramUpdatedLatch.countDown();
- }
- }
-}
diff --git a/tests/unit/src/com/android/tv/data/ProgramTest.java b/tests/unit/src/com/android/tv/data/ProgramTest.java
deleted file mode 100644
index 1d1f6c10..00000000
--- a/tests/unit/src/com/android/tv/data/ProgramTest.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * 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.data;
-
-import static android.media.tv.TvContract.Programs.Genres.COMEDY;
-import static android.media.tv.TvContract.Programs.Genres.FAMILY_KIDS;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-
-import android.media.tv.TvContentRating;
-import android.media.tv.TvContract.Programs.Genres;
-import android.os.Parcel;
-import android.support.test.filters.SmallTest;
-
-import com.android.tv.data.Program.CriticScore;
-
-import org.junit.Test;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Tests for {@link Program}.
- */
-@SmallTest
-public class ProgramTest {
- private static final int NOT_FOUND_GENRE = 987;
-
- private static final int FAMILY_GENRE_ID = GenreItems.getId(FAMILY_KIDS);
-
- private static final int COMEDY_GENRE_ID = GenreItems.getId(COMEDY);
-
- @Test
- public void testBuild() {
- Program program = new Program.Builder().build();
- assertEquals("isValid", false, program.isValid());
- }
-
- @Test
- public void testNoGenres() {
- Program program = new Program.Builder()
- .setCanonicalGenres("")
- .build();
- assertNullCanonicalGenres(program);
- assertHasGenre(program, NOT_FOUND_GENRE, false);
- assertHasGenre(program, FAMILY_GENRE_ID, false);
- assertHasGenre(program, COMEDY_GENRE_ID, false);
- assertHasGenre(program, GenreItems.ID_ALL_CHANNELS, true);
- }
-
- @Test
- public void testFamilyGenre() {
- Program program = new Program.Builder()
- .setCanonicalGenres(FAMILY_KIDS)
- .build();
- assertCanonicalGenres(program, FAMILY_KIDS);
- assertHasGenre(program, NOT_FOUND_GENRE, false);
- assertHasGenre(program, FAMILY_GENRE_ID, true);
- assertHasGenre(program, COMEDY_GENRE_ID, false);
- assertHasGenre(program, GenreItems.ID_ALL_CHANNELS, true);
- }
-
- @Test
- public void testFamilyComedyGenre() {
- Program program = new Program.Builder()
- .setCanonicalGenres(FAMILY_KIDS + ", " + COMEDY)
- .build();
- assertCanonicalGenres(program, FAMILY_KIDS, COMEDY);
- assertHasGenre(program, NOT_FOUND_GENRE, false);
- assertHasGenre(program, FAMILY_GENRE_ID, true);
- assertHasGenre(program, COMEDY_GENRE_ID, true);
- assertHasGenre(program, GenreItems.ID_ALL_CHANNELS, true);
- }
-
- @Test
- public void testOtherGenre() {
- Program program = new Program.Builder()
- .setCanonicalGenres("other")
- .build();
- assertCanonicalGenres(program);
- assertHasGenre(program, NOT_FOUND_GENRE, false);
- assertHasGenre(program, FAMILY_GENRE_ID, false);
- assertHasGenre(program, COMEDY_GENRE_ID, false);
- assertHasGenre(program, GenreItems.ID_ALL_CHANNELS, true);
- }
-
- @Test
- public void testParcelable() {
- List<CriticScore> criticScores = new ArrayList<>();
- criticScores.add(new CriticScore("1", "2", "3"));
- criticScores.add(new CriticScore("4", "5", "6"));
- TvContentRating[] ratings = new TvContentRating[2];
- ratings[0] = TvContentRating.unflattenFromString("1/2/3");
- ratings[1] = TvContentRating.unflattenFromString("4/5/6");
- Program p = new Program.Builder()
- .setId(1)
- .setPackageName("2")
- .setChannelId(3)
- .setTitle("4")
- .setSeriesId("5")
- .setEpisodeTitle("6")
- .setSeasonNumber("7")
- .setSeasonTitle("8")
- .setEpisodeNumber("9")
- .setStartTimeUtcMillis(10)
- .setEndTimeUtcMillis(11)
- .setDescription("12")
- .setLongDescription("12-long")
- .setVideoWidth(13)
- .setVideoHeight(14)
- .setCriticScores(criticScores)
- .setPosterArtUri("15")
- .setThumbnailUri("16")
- .setCanonicalGenres(Genres.encode(Genres.SPORTS, Genres.SHOPPING))
- .setContentRatings(ratings)
- .setRecordingProhibited(true)
- .build();
- Parcel p1 = Parcel.obtain();
- Parcel p2 = Parcel.obtain();
- try {
- p.writeToParcel(p1, 0);
- byte[] bytes = p1.marshall();
- p2.unmarshall(bytes, 0, bytes.length);
- p2.setDataPosition(0);
- Program r2 = Program.fromParcel(p2);
- assertEquals(p, r2);
- } finally {
- p1.recycle();
- p2.recycle();
- }
- }
-
- @Test
- public void testParcelableWithCriticScore() {
- Program program = new Program.Builder()
- .setTitle("MyTitle")
- .addCriticScore(new CriticScore(
- "default source",
- "5/10",
- "https://testurl/testimage.jpg"))
- .build();
- Parcel parcel = Parcel.obtain();
- program.writeToParcel(parcel, 0);
- parcel.setDataPosition(0);
- Program programFromParcel = Program.CREATOR.createFromParcel(parcel);
-
- assertNotNull(programFromParcel.getCriticScores());
- assertEquals(programFromParcel.getCriticScores().get(0).source, "default source");
- assertEquals(programFromParcel.getCriticScores().get(0).score, "5/10");
- assertEquals(programFromParcel.getCriticScores().get(0).logoUrl,
- "https://testurl/testimage.jpg");
- }
-
- private static void assertNullCanonicalGenres(Program program) {
- String[] actual = program.getCanonicalGenres();
- assertNull("Expected null canonical genres but was " + Arrays.toString(actual), actual);
- }
-
- private static void assertCanonicalGenres(Program program, String... expected) {
- assertEquals("canonical genres", Arrays.asList(expected),
- Arrays.asList(program.getCanonicalGenres()));
- }
-
- private static void assertHasGenre(Program program, int genreId, boolean expected) {
- assertEquals("hasGenre(" + genreId + ")", expected, program.hasGenre(genreId));
- }
-}
diff --git a/tests/unit/src/com/android/tv/data/TvInputNewComparatorTest.java b/tests/unit/src/com/android/tv/data/TvInputNewComparatorTest.java
index b4682dd9..8e892cce 100644
--- a/tests/unit/src/com/android/tv/data/TvInputNewComparatorTest.java
+++ b/tests/unit/src/com/android/tv/data/TvInputNewComparatorTest.java
@@ -19,26 +19,24 @@ package com.android.tv.data;
import android.content.pm.ResolveInfo;
import android.media.tv.TvInputInfo;
import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
import android.util.Pair;
-
import com.android.tv.testing.ComparatorTester;
+import com.android.tv.testing.utils.TestUtils;
import com.android.tv.util.SetupUtils;
-import com.android.tv.util.TestUtils;
import com.android.tv.util.TvInputManagerHelper;
-
+import java.util.Comparator;
+import java.util.LinkedHashMap;
import org.junit.Test;
+import org.junit.runner.RunWith;
import org.mockito.Matchers;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
-import java.util.Comparator;
-import java.util.LinkedHashMap;
-
-/**
- * Test for {@link TvInputNewComparator}
- */
+/** Test for {@link TvInputNewComparator} */
@SmallTest
+@RunWith(AndroidJUnit4.class)
public class TvInputNewComparatorTest {
@Test
public void testComparator() throws Exception {
@@ -51,45 +49,48 @@ public class TvInputNewComparatorTest {
inputIdToNewInput.put("3_old_input", new Pair<>(false, true));
SetupUtils setupUtils = Mockito.mock(SetupUtils.class);
- Mockito.when(setupUtils.isNewInput(Matchers.anyString())).thenAnswer(
- new Answer<Boolean>() {
- @Override
- public Boolean answer(InvocationOnMock invocation) throws Throwable {
- String inputId = (String) invocation.getArguments()[0];
- return inputIdToNewInput.get(inputId).first;
- }
- }
- );
- Mockito.when(setupUtils.isSetupDone(Matchers.anyString())).thenAnswer(
- new Answer<Boolean>() {
- @Override
- public Boolean answer(InvocationOnMock invocation) throws Throwable {
- String inputId = (String) invocation.getArguments()[0];
- return inputIdToNewInput.get(inputId).second;
- }
- }
- );
+ Mockito.when(setupUtils.isNewInput(Matchers.anyString()))
+ .thenAnswer(
+ new Answer<Boolean>() {
+ @Override
+ public Boolean answer(InvocationOnMock invocation) throws Throwable {
+ String inputId = (String) invocation.getArguments()[0];
+ return inputIdToNewInput.get(inputId).first;
+ }
+ });
+ Mockito.when(setupUtils.isSetupDone(Matchers.anyString()))
+ .thenAnswer(
+ new Answer<Boolean>() {
+ @Override
+ public Boolean answer(InvocationOnMock invocation) throws Throwable {
+ String inputId = (String) invocation.getArguments()[0];
+ return inputIdToNewInput.get(inputId).second;
+ }
+ });
TvInputManagerHelper inputManager = Mockito.mock(TvInputManagerHelper.class);
- Mockito.when(inputManager.getDefaultTvInputInfoComparator()).thenReturn(
- new Comparator<TvInputInfo>() {
- @Override
- public int compare(TvInputInfo lhs, TvInputInfo rhs) {
- return lhs.getId().compareTo(rhs.getId());
- }
- }
- );
+ Mockito.when(inputManager.getDefaultTvInputInfoComparator())
+ .thenReturn(
+ new Comparator<TvInputInfo>() {
+ @Override
+ public int compare(TvInputInfo lhs, TvInputInfo rhs) {
+ return lhs.getId().compareTo(rhs.getId());
+ }
+ });
TvInputNewComparator comparator = new TvInputNewComparator(setupUtils, inputManager);
ComparatorTester<TvInputInfo> comparatorTester =
ComparatorTester.withoutEqualsTest(comparator);
ResolveInfo resolveInfo = TestUtils.createResolveInfo("test", "test");
for (String id : inputIdToNewInput.keySet()) {
// Put mock resolveInfo to prevent NPE in {@link TvInputInfo#toString}
- TvInputInfo info1 = TestUtils.createTvInputInfo(
- resolveInfo, id, "test1", TvInputInfo.TYPE_TUNER, false);
- TvInputInfo info2 = TestUtils.createTvInputInfo(
- resolveInfo, id, "test2", TvInputInfo.TYPE_DISPLAY_PORT, true);
- TvInputInfo info3 = TestUtils.createTvInputInfo(
- resolveInfo, id, "test", TvInputInfo.TYPE_HDMI, true);
+ TvInputInfo info1 =
+ TestUtils.createTvInputInfo(
+ resolveInfo, id, "test1", TvInputInfo.TYPE_TUNER, false);
+ TvInputInfo info2 =
+ TestUtils.createTvInputInfo(
+ resolveInfo, id, "test2", TvInputInfo.TYPE_DISPLAY_PORT, true);
+ TvInputInfo info3 =
+ TestUtils.createTvInputInfo(
+ resolveInfo, id, "test", TvInputInfo.TYPE_HDMI, true);
comparatorTester.addComparableGroup(info1, info2, info3);
}
comparatorTester.test();
diff --git a/tests/unit/src/com/android/tv/data/WatchedHistoryManagerTest.java b/tests/unit/src/com/android/tv/data/WatchedHistoryManagerTest.java
index 7eea1be7..43bfde09 100644
--- a/tests/unit/src/com/android/tv/data/WatchedHistoryManagerTest.java
+++ b/tests/unit/src/com/android/tv/data/WatchedHistoryManagerTest.java
@@ -17,26 +17,24 @@
package com.android.tv.data;
import static android.support.test.InstrumentationRegistry.getTargetContext;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
+import static com.google.common.truth.Truth.assertThat;
import android.os.Looper;
import android.support.test.filters.MediumTest;
-
+import android.support.test.runner.AndroidJUnit4;
import com.android.tv.data.WatchedHistoryManager.WatchedRecord;
-
+import java.util.concurrent.TimeUnit;
import org.junit.Before;
import org.junit.Test;
-
-import java.util.concurrent.TimeUnit;
+import org.junit.runner.RunWith;
/**
* Test for {@link com.android.tv.data.WatchedHistoryManagerTest}
- * <p>
- * This is a medium test because it load files which accessing SharedPreferences.
+ *
+ * <p>This is a medium test because it load files which accessing SharedPreferences.
*/
@MediumTest
+@RunWith(AndroidJUnit4.class)
public class WatchedHistoryManagerTest {
// Wait time for expected success.
private static final int MAX_HISTORY_SIZE = 100;
@@ -56,13 +54,13 @@ public class WatchedHistoryManagerTest {
private void startAndWaitForComplete() throws InterruptedException {
mWatchedHistoryManager.start();
- assertTrue(mListener.mLoadFinished);
+ assertThat(mListener.mLoadFinished).isTrue();
}
@Test
public void testIsLoaded() throws InterruptedException {
startAndWaitForComplete();
- assertTrue(mWatchedHistoryManager.isLoaded());
+ assertThat(mWatchedHistoryManager.isLoaded()).isTrue();
}
@Test
@@ -71,16 +69,16 @@ public class WatchedHistoryManagerTest {
long fakeId = 100000000;
long time = System.currentTimeMillis();
long duration = TimeUnit.MINUTES.toMillis(10);
- Channel channel = new Channel.Builder().setId(fakeId).build();
+ ChannelImpl channel = new ChannelImpl.Builder().setId(fakeId).build();
mWatchedHistoryManager.logChannelViewStop(channel, time, duration);
WatchedRecord record = mWatchedHistoryManager.getRecord(0);
WatchedRecord recordFromSharedPreferences =
mWatchedHistoryManager.getRecordFromSharedPreferences(0);
- assertEquals(record.channelId, fakeId);
- assertEquals(record.watchedStartTime, time - duration);
- assertEquals(record.duration, duration);
- assertEquals(record, recordFromSharedPreferences);
+ assertThat(fakeId).isEqualTo(record.channelId);
+ assertThat(time - duration).isEqualTo(record.watchedStartTime);
+ assertThat(duration).isEqualTo(record.duration);
+ assertThat(recordFromSharedPreferences).isEqualTo(record);
}
@Test
@@ -92,28 +90,28 @@ public class WatchedHistoryManagerTest {
int size = MAX_HISTORY_SIZE * 2;
for (int i = 0; i < size; ++i) {
- Channel channel = new Channel.Builder().setId(startChannelId + i).build();
+ ChannelImpl channel = new ChannelImpl.Builder().setId(startChannelId + i).build();
mWatchedHistoryManager.logChannelViewStop(channel, time + duration * i, duration);
}
for (int i = 0; i < MAX_HISTORY_SIZE; ++i) {
WatchedRecord record = mWatchedHistoryManager.getRecord(i);
WatchedRecord recordFromSharedPreferences =
mWatchedHistoryManager.getRecordFromSharedPreferences(i);
- assertEquals(record, recordFromSharedPreferences);
- assertEquals(record.channelId, startChannelId + size - 1 - i);
+ assertThat(recordFromSharedPreferences).isEqualTo(record);
+ assertThat(startChannelId + size - 1 - i).isEqualTo(record.channelId);
}
// Since the WatchedHistory is a circular queue, the value for 0 and maxHistorySize
// are same.
- assertEquals(mWatchedHistoryManager.getRecordFromSharedPreferences(0),
- mWatchedHistoryManager.getRecordFromSharedPreferences(MAX_HISTORY_SIZE));
+ assertThat(mWatchedHistoryManager.getRecordFromSharedPreferences(MAX_HISTORY_SIZE))
+ .isEqualTo(mWatchedHistoryManager.getRecordFromSharedPreferences(0));
}
@Test
public void testWatchedRecordEquals() {
- assertTrue(new WatchedRecord(1, 2, 3).equals(new WatchedRecord(1, 2, 3)));
- assertFalse(new WatchedRecord(1, 2, 3).equals(new WatchedRecord(1, 2, 4)));
- assertFalse(new WatchedRecord(1, 2, 3).equals(new WatchedRecord(1, 4, 3)));
- assertFalse(new WatchedRecord(1, 2, 3).equals(new WatchedRecord(4, 2, 3)));
+ assertThat(new WatchedRecord(1, 2, 3).equals(new WatchedRecord(1, 2, 3))).isTrue();
+ assertThat(new WatchedRecord(1, 2, 3).equals(new WatchedRecord(1, 2, 4))).isFalse();
+ assertThat(new WatchedRecord(1, 2, 3).equals(new WatchedRecord(1, 4, 3))).isFalse();
+ assertThat(new WatchedRecord(1, 2, 3).equals(new WatchedRecord(4, 2, 3))).isFalse();
}
@Test
@@ -122,12 +120,13 @@ public class WatchedHistoryManagerTest {
long time = System.currentTimeMillis();
long duration = TimeUnit.MINUTES.toMillis(10);
WatchedRecord record = new WatchedRecord(fakeId, time, duration);
- WatchedRecord sameRecord = mWatchedHistoryManager.decode(
- mWatchedHistoryManager.encode(record));
- assertEquals(record, sameRecord);
+ WatchedRecord sameRecord =
+ mWatchedHistoryManager.decode(mWatchedHistoryManager.encode(record));
+ assertThat(sameRecord).isEqualTo(record);
}
- private class TestWatchedHistoryManagerListener implements WatchedHistoryManager.Listener {
+ private static final class TestWatchedHistoryManagerListener
+ implements WatchedHistoryManager.Listener {
boolean mLoadFinished;
@Override
@@ -136,6 +135,6 @@ public class WatchedHistoryManagerTest {
}
@Override
- public void onNewRecordAdded(WatchedRecord watchedRecord) { }
+ public void onNewRecordAdded(WatchedRecord watchedRecord) {}
}
}
diff --git a/tests/unit/src/com/android/tv/dvr/BaseDvrDataManagerTest.java b/tests/unit/src/com/android/tv/dvr/BaseDvrDataManagerTest.java
deleted file mode 100644
index 5f0ae15c..00000000
--- a/tests/unit/src/com/android/tv/dvr/BaseDvrDataManagerTest.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2016 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.dvr;
-
-import static android.support.test.InstrumentationRegistry.getContext;
-
-import android.os.Build;
-import android.support.annotation.NonNull;
-import android.support.test.filters.SdkSuppress;
-import android.support.test.filters.SmallTest;
-import android.test.MoreAsserts;
-
-import com.android.tv.common.feature.CommonFeatures;
-import com.android.tv.common.feature.TestableFeature;
-import com.android.tv.dvr.data.ScheduledRecording;
-import com.android.tv.testing.FakeClock;
-import com.android.tv.testing.dvr.RecordingTestUtils;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-
-/** Tests for {@link BaseDvrDataManager} using {@link DvrDataManagerInMemoryImpl}. */
-@SmallTest
-@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
-public class BaseDvrDataManagerTest {
- private static final String INPUT_ID = "input_id";
- private static final int CHANNEL_ID = 273;
-
- private final TestableFeature mDvrFeature = CommonFeatures.DVR;
- private DvrDataManagerInMemoryImpl mDvrDataManager;
- private FakeClock mFakeClock;
-
- @Before
- public void setUp() {
- mDvrFeature.enableForTest();
- mFakeClock = FakeClock.createWithCurrentTime();
- mDvrDataManager = new DvrDataManagerInMemoryImpl(getContext(), mFakeClock);
- }
-
- @After
- public void tearDown() {
- mDvrFeature.resetForTests();
- }
-
- @Test
- public void testGetNonStartedScheduledRecordings() {
- ScheduledRecording recording = mDvrDataManager
- .addScheduledRecordingInternal(createNewScheduledRecordingStartingNow());
- List<ScheduledRecording> result = mDvrDataManager.getNonStartedScheduledRecordings();
- MoreAsserts.assertContentsInAnyOrder(result, recording);
- }
-
- @Test
- public void testGetNonStartedScheduledRecordings_past() {
- mDvrDataManager.addScheduledRecordingInternal(createNewScheduledRecordingStartingNow());
- mFakeClock.increment(TimeUnit.MINUTES, 6);
- List<ScheduledRecording> result = mDvrDataManager.getNonStartedScheduledRecordings();
- MoreAsserts.assertContentsInAnyOrder(result);
- }
-
- @NonNull
- private ScheduledRecording createNewScheduledRecordingStartingNow() {
- return ScheduledRecording.buildFrom(RecordingTestUtils
- .createTestRecordingWithIdAndPeriod(
- ScheduledRecording.ID_NOT_SET,
- INPUT_ID, CHANNEL_ID,
- mFakeClock.currentTimeMillis(),
- mFakeClock.currentTimeMillis() + TimeUnit.MINUTES.toMillis(5)))
- .setState(ScheduledRecording.STATE_RECORDING_NOT_STARTED)
- .build();
- }
-}
diff --git a/tests/unit/src/com/android/tv/dvr/DvrDataManagerImplTest.java b/tests/unit/src/com/android/tv/dvr/DvrDataManagerImplTest.java
deleted file mode 100644
index 9771a2e5..00000000
--- a/tests/unit/src/com/android/tv/dvr/DvrDataManagerImplTest.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * 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.dvr;
-
-import static org.junit.Assert.assertEquals;
-
-import android.os.Build;
-import android.support.test.filters.SdkSuppress;
-import android.support.test.filters.SmallTest;
-
-import com.android.tv.dvr.data.ScheduledRecording;
-import com.android.tv.testing.dvr.RecordingTestUtils;
-
-import org.junit.Test;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/** Tests for {@link DvrDataManagerImpl} */
-@SmallTest
-@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
-public class DvrDataManagerImplTest {
- private static final String INPUT_ID = "input_id";
- private static final int CHANNEL_ID = 273;
-
- @Test
- public void testGetNextScheduledStartTimeAfter() {
- long id = 1;
- List<ScheduledRecording> scheduledRecordings = new ArrayList<>();
- assertNextStartTime(scheduledRecordings, 0L, DvrDataManager.NEXT_START_TIME_NOT_FOUND);
- scheduledRecordings.add(RecordingTestUtils
- .createTestRecordingWithIdAndPeriod(id++, INPUT_ID, CHANNEL_ID, 10L, 20L));
- assertNextStartTime(scheduledRecordings, 9L, 10L);
- assertNextStartTime(scheduledRecordings, 10L, DvrDataManager.NEXT_START_TIME_NOT_FOUND);
- scheduledRecordings.add(RecordingTestUtils
- .createTestRecordingWithIdAndPeriod(id++, INPUT_ID, CHANNEL_ID, 20L, 30L));
- assertNextStartTime(scheduledRecordings, 9L, 10L);
- assertNextStartTime(scheduledRecordings, 10L, 20L);
- assertNextStartTime(scheduledRecordings, 20L, DvrDataManager.NEXT_START_TIME_NOT_FOUND);
- scheduledRecordings.add(RecordingTestUtils
- .createTestRecordingWithIdAndPeriod(id++, INPUT_ID, CHANNEL_ID, 30L, 40L));
- assertNextStartTime(scheduledRecordings, 9L, 10L);
- assertNextStartTime(scheduledRecordings, 10L, 20L);
- assertNextStartTime(scheduledRecordings, 20L, 30L);
- assertNextStartTime(scheduledRecordings, 30L, DvrDataManager.NEXT_START_TIME_NOT_FOUND);
- scheduledRecordings.clear();
- scheduledRecordings.add(RecordingTestUtils
- .createTestRecordingWithIdAndPeriod(id++, INPUT_ID, CHANNEL_ID, 10L, 20L));
- scheduledRecordings.add(RecordingTestUtils
- .createTestRecordingWithIdAndPeriod(id++, INPUT_ID, CHANNEL_ID, 10L, 20L));
- scheduledRecordings.add(RecordingTestUtils
- .createTestRecordingWithIdAndPeriod(id++, INPUT_ID, CHANNEL_ID, 10L, 20L));
- assertNextStartTime(scheduledRecordings, 9L, 10L);
- assertNextStartTime(scheduledRecordings, 10L, DvrDataManager.NEXT_START_TIME_NOT_FOUND);
- }
-
- private void assertNextStartTime(List<ScheduledRecording> scheduledRecordings, long startTime,
- long expected) {
- assertEquals("getNextScheduledStartTimeAfter()", expected,
- DvrDataManagerImpl.getNextStartTimeAfter(scheduledRecordings, startTime));
- }
-} \ No newline at end of file
diff --git a/tests/unit/src/com/android/tv/dvr/DvrScheduleManagerTest.java b/tests/unit/src/com/android/tv/dvr/DvrScheduleManagerTest.java
deleted file mode 100644
index 1c77aa0e..00000000
--- a/tests/unit/src/com/android/tv/dvr/DvrScheduleManagerTest.java
+++ /dev/null
@@ -1,693 +0,0 @@
-/*
- * Copyright (C) 2016 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.dvr;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-
-import android.os.Build;
-import android.support.test.filters.SdkSuppress;
-import android.support.test.filters.SmallTest;
-import android.test.MoreAsserts;
-import android.util.Range;
-
-import com.android.tv.dvr.DvrScheduleManager.ConflictInfo;
-import com.android.tv.dvr.data.ScheduledRecording;
-import com.android.tv.testing.dvr.RecordingTestUtils;
-
-import org.junit.Test;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-/** Tests for {@link DvrScheduleManager} */
-@SmallTest
-@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
-public class DvrScheduleManagerTest {
- private static final String INPUT_ID = "input_id";
-
- @Test
- public void testGetConflictingSchedules_emptySchedule() {
- List<ScheduledRecording> schedules = new ArrayList<>();
- MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 1));
- }
-
- @Test
- public void testGetConflictingSchedules_noConflict() {
- long priority = 0;
- long channelId = 0;
- List<ScheduledRecording> schedules = new ArrayList<>();
-
- schedules.add(RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(++channelId,
- ++priority, 0L, 200L));
- MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 1));
-
- schedules.add(RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(++channelId,
- ++priority, 0L, 100L));
- MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 2));
-
- schedules.add(RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(++channelId,
- ++priority, 100L, 200L));
- MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 2));
-
- schedules.add(RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(++channelId,
- ++priority, 0L, 100L));
- MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 3));
-
- schedules.add(RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(++channelId,
- ++priority, 100L, 200L));
- MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 3));
- }
-
- @Test
- public void testGetConflictingSchedules_noTuner() {
- long priority = 0;
- long channelId = 0;
- List<ScheduledRecording> schedules = new ArrayList<>();
- MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 0));
-
- schedules.add(RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(++channelId,
- ++priority, 0L, 200L));
- assertEquals(schedules, DvrScheduleManager.getConflictingSchedules(schedules, 0));
- schedules.add(0, RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(++channelId,
- ++priority, 0L, 100L));
- assertEquals(schedules, DvrScheduleManager.getConflictingSchedules(schedules, 0));
- }
-
- @Test
- public void testGetConflictingSchedules_conflict() {
- long priority = 0;
- long channelId = 0;
- List<ScheduledRecording> schedules = new ArrayList<>();
-
- ScheduledRecording r1 = RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 200L);
- schedules.add(r1);
- MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 1));
-
- ScheduledRecording r2 = RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 100L);
- schedules.add(r2);
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedules(schedules, 1),
- r1);
- MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 2));
-
- ScheduledRecording r3 = RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 100L, 200L);
- schedules.add(r3);
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedules(schedules, 1),
- r1);
- MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 2));
-
- ScheduledRecording r4 = RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 100L);
- schedules.add(r4);
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedules(schedules, 1),
- r2, r1);
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedules(schedules, 2),
- r1);
- MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 3));
-
- ScheduledRecording r5 = RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 100L, 200L);
- schedules.add(r5);
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedules(schedules, 1),
- r3, r2, r1);
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedules(schedules, 2),
- r1);
- MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 3));
-
- ScheduledRecording r6 = RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 10L, 90L);
- schedules.add(r6);
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedules(schedules, 1),
- r4, r3, r2, r1);
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedules(schedules, 2),
- r2, r1);
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedules(schedules, 3),
- r1);
- MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 4));
-
- ScheduledRecording r7 = RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 110L, 190L);
- schedules.add(r7);
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedules(schedules, 1),
- r5, r4, r3, r2, r1);
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedules(schedules, 2),
- r3, r2, r1);
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedules(schedules, 3),
- r1);
- MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 4));
-
- ScheduledRecording r8 = RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 50L, 150L);
- schedules.add(r8);
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedules(schedules, 1),
- r7, r6, r5, r4, r3, r2, r1);
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedules(schedules, 2),
- r5, r4, r3, r2, r1);
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedules(schedules, 3),
- r3, r2, r1);
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedules(schedules, 4),
- r1);
- MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 5));
- }
-
- @Test
- public void testGetConflictingSchedules_conflict2() {
- // The case when there is a long schedule.
- long priority = 0;
- long channelId = 0;
- List<ScheduledRecording> schedules = new ArrayList<>();
-
- ScheduledRecording r1 = RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 1000L);
- schedules.add(r1);
- MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 1));
-
- ScheduledRecording r2 = RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 100L);
- schedules.add(r2);
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedules(schedules, 1),
- r1);
- MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 2));
-
- ScheduledRecording r3 = RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 100L, 200L);
- schedules.add(r3);
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedules(schedules, 1),
- r1);
- MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 2));
- }
-
- @Test
- public void testGetConflictingSchedules_reverseOrder() {
- long priority = 0;
- long channelId = 0;
- List<ScheduledRecording> schedules = new ArrayList<>();
-
- ScheduledRecording r1 = RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 200L);
- schedules.add(0, r1);
- MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 1));
-
- ScheduledRecording r2 = RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 100L);
- schedules.add(0, r2);
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedules(schedules, 1),
- r1);
- MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 2));
-
- ScheduledRecording r3 = RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 100L, 200L);
- schedules.add(0, r3);
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedules(schedules, 1),
- r1);
- MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 2));
-
- ScheduledRecording r4 = RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 100L);
- schedules.add(0, r4);
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedules(schedules, 1),
- r2, r1);
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedules(schedules, 2),
- r1);
- MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 3));
-
- ScheduledRecording r5 = RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 100L, 200L);
- schedules.add(0, r5);
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedules(schedules, 1),
- r3, r2, r1);
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedules(schedules, 2),
- r1);
- MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 3));
-
- ScheduledRecording r6 = RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 10L, 90L);
- schedules.add(0, r6);
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedules(schedules, 1),
- r4, r3, r2, r1);
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedules(schedules, 2),
- r2, r1);
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedules(schedules, 3),
- r1);
- MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 4));
-
- ScheduledRecording r7 = RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 110L, 190L);
- schedules.add(0, r7);
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedules(schedules, 1),
- r5, r4, r3, r2, r1);
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedules(schedules, 2),
- r3, r2, r1);
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedules(schedules, 3),
- r1);
- MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 4));
-
- ScheduledRecording r8 = RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 50L, 150L);
- schedules.add(0, r8);
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedules(schedules, 1),
- r7, r6, r5, r4, r3, r2, r1);
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedules(schedules, 2),
- r5, r4, r3, r2, r1);
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedules(schedules, 3),
- r3, r2, r1);
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedules(schedules, 4),
- r1);
- MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 5));
- }
-
- @Test
- public void testGetConflictingSchedules_period1() {
- long priority = 0;
- long channelId = 0;
- List<ScheduledRecording> schedules = new ArrayList<>();
-
- ScheduledRecording r1 = RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 200L);
- schedules.add(r1);
- ScheduledRecording r2 = RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 100L);
- schedules.add(r2);
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedules(schedules, 1,
- Collections.singletonList(new Range<>(10L, 20L))), r1);
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedules(schedules, 1,
- Collections.singletonList(new Range<>(110L, 120L))), r1);
- }
-
- @Test
- public void testGetConflictingSchedules_period2() {
- long priority = 0;
- long channelId = 0;
- List<ScheduledRecording> schedules = new ArrayList<>();
-
- ScheduledRecording r1 = RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 200L);
- schedules.add(r1);
- ScheduledRecording r2 = RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 100L, 200L);
- schedules.add(r2);
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedules(schedules, 1,
- Collections.singletonList(new Range<>(10L, 20L))), r1);
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedules(schedules, 1,
- Collections.singletonList(new Range<>(110L, 120L))), r1);
- }
-
- @Test
- public void testGetConflictingSchedules_period3() {
- long priority = 0;
- long channelId = 0;
- List<ScheduledRecording> schedules = new ArrayList<>();
-
- ScheduledRecording r1 = RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 100L);
- schedules.add(r1);
- ScheduledRecording r2 = RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 100L, 200L);
- schedules.add(r2);
- ScheduledRecording r3 = RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 100L);
- schedules.add(r3);
- ScheduledRecording r4 = RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 100L, 200L);
- schedules.add(r4);
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedules(schedules, 1,
- Collections.singletonList(new Range<>(10L, 20L))), r1);
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedules(schedules, 1,
- Collections.singletonList(new Range<>(110L, 120L))), r2);
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedules(schedules, 1,
- Collections.singletonList(new Range<>(50L, 150L))), r2, r1);
- List<Range<Long>> ranges = new ArrayList<>();
- ranges.add(new Range<>(10L, 20L));
- ranges.add(new Range<>(110L, 120L));
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedules(schedules, 1,
- ranges), r2, r1);
- }
-
- @Test
- public void testGetConflictingSchedules_addSchedules1() {
- long priority = 0;
- long channelId = 0;
- List<ScheduledRecording> schedules = new ArrayList<>();
-
- ScheduledRecording r1 = RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 200L);
- schedules.add(r1);
- ScheduledRecording r2 = RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 100L);
- schedules.add(r2);
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedules(
- Collections.singletonList(
- ScheduledRecording.builder(INPUT_ID, ++channelId, 10L, 20L)
- .setPriority(++priority).build()),
- schedules, 1), r2, r1);
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedules(
- Collections.singletonList(
- ScheduledRecording.builder(INPUT_ID, ++channelId, 110L, 120L)
- .setPriority(++priority).build()),
- schedules, 1), r1);
- }
-
- @Test
- public void testGetConflictingSchedules_addSchedules2() {
- long priority = 0;
- long channelId = 0;
- List<ScheduledRecording> schedules = new ArrayList<>();
-
- ScheduledRecording r1 = RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 200L);
- schedules.add(r1);
- ScheduledRecording r2 = RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 100L, 200L);
- schedules.add(r2);
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedules(
- Collections.singletonList(
- ScheduledRecording.builder(INPUT_ID, ++channelId, 10L, 20L)
- .setPriority(++priority).build()),
- schedules, 1), r1);
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedules(
- Collections.singletonList(
- ScheduledRecording.builder(INPUT_ID, ++channelId, 110L, 120L)
- .setPriority(++priority).build()),
- schedules, 1), r2, r1);
- }
-
- @Test
- public void testGetConflictingSchedules_addLowestPriority() {
- long priority = 0;
- long channelId = 0;
- List<ScheduledRecording> schedules = new ArrayList<>();
-
- ScheduledRecording r1 = RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 400L);
- schedules.add(r1);
- ScheduledRecording r2 = RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 100L, 200L);
- schedules.add(r2);
- // Returning r1 even though r1 has the higher priority than the new one. That's because r1
- // starts at 0 and stops at 100, and the new one will be recorded successfully.
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedules(
- Collections.singletonList(
- ScheduledRecording.builder(INPUT_ID, ++channelId, 200L, 300L)
- .setPriority(0).build()),
- schedules, 1), r1);
- }
-
- @Test
- public void testGetConflictingSchedules_sameChannel() {
- long priority = 0;
- long channelId = 1;
- List<ScheduledRecording> schedules = new ArrayList<>();
- schedules.add(RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(channelId,
- ++priority, 0L, 200L));
- schedules.add(RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(channelId,
- ++priority, 0L, 200L));
- MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 3));
- }
-
- @Test
- public void testGetConflictingSchedule_startEarlyAndFail() {
- long priority = 0;
- long channelId = 0;
- List<ScheduledRecording> schedules = new ArrayList<>();
- ScheduledRecording r1 = RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 200L, 300L);
- schedules.add(r1);
- ScheduledRecording r2 = RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 400L);
- schedules.add(r2);
- ScheduledRecording r3 = RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 100L, 200L);
- schedules.add(r3);
- // r2 starts recording and fails when r3 starts. r1 is recorded successfully.
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedules(schedules, 1),
- r2);
- }
-
- @Test
- public void testGetConflictingSchedule_startLate() {
- long priority = 0;
- long channelId = 0;
- List<ScheduledRecording> schedules = new ArrayList<>();
- ScheduledRecording r1 = RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 200L, 400L);
- schedules.add(r1);
- ScheduledRecording r2 = RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 100L, 300L);
- schedules.add(r2);
- ScheduledRecording r3 = RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 200L);
- schedules.add(r3);
- // r2 and r1 are clipped.
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedules(schedules, 1),
- r2, r1);
- }
-
- @Test
- public void testGetConflictingSchedulesForTune_canTune() {
- // Can tune to the recorded channel if tuner count is 1.
- long priority = 0;
- long channelId = 1;
- List<ScheduledRecording> schedules = new ArrayList<>();
- schedules.add(RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(channelId,
- ++priority, 0L, 200L));
- MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedulesForTune(INPUT_ID,
- channelId, 0L, priority + 1, schedules, 1));
- }
-
- @Test
- public void testGetConflictingSchedulesForTune_cannotTune() {
- // Can't tune to a channel if other channel is recording and tuner count is 1.
- long priority = 0;
- long channelId = 1;
- List<ScheduledRecording> schedules = new ArrayList<>();
- schedules.add(RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(channelId,
- ++priority, 0L, 200L));
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedulesForTune(
- INPUT_ID, channelId + 1, 0L, priority + 1, schedules, 1), schedules.get(0));
- }
-
- @Test
- public void testGetConflictingSchedulesForWatching_otherChannels() {
- // The other channels are to be recorded.
- long priority = 0;
- long channelToWatch = 1;
- long channelId = 1;
- List<ScheduledRecording> schedules = new ArrayList<>();
- ScheduledRecording r1 = RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 200L);
- schedules.add(r1);
- ScheduledRecording r2 = RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 200L);
- schedules.add(r2);
- MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedulesForWatching(
- INPUT_ID, channelToWatch, 0L, ++priority, schedules, 3));
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedulesForWatching(
- INPUT_ID, channelToWatch, 0L, ++priority, schedules, 2), r1);
- }
-
- @Test
- public void testGetConflictingSchedulesForWatching_sameChannel1() {
- long priority = 0;
- long channelToWatch = 1;
- long channelId = 1;
- List<ScheduledRecording> schedules = new ArrayList<>();
- ScheduledRecording r1 = RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- channelToWatch, ++priority, 0L, 200L);
- schedules.add(r1);
- ScheduledRecording r2 = RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 200L);
- schedules.add(r2);
- MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedulesForWatching(
- INPUT_ID, channelToWatch, 0L, ++priority, schedules, 2));
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedulesForWatching(
- INPUT_ID, channelToWatch, 0L, ++priority, schedules, 1), r2);
- }
-
- @Test
- public void testGetConflictingSchedulesForWatching_sameChannel2() {
- long priority = 0;
- long channelToWatch = 1;
- long channelId = 1;
- List<ScheduledRecording> schedules = new ArrayList<>();
- ScheduledRecording r1 = RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 200L);
- schedules.add(r1);
- ScheduledRecording r2 = RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- channelToWatch, ++priority, 0L, 200L);
- schedules.add(r2);
- MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedulesForWatching(
- INPUT_ID, channelToWatch, 0L, ++priority, schedules, 2));
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedulesForWatching(
- INPUT_ID, channelToWatch, 0L, ++priority, schedules, 1), r1);
- }
-
- @Test
- public void testGetConflictingSchedulesForWatching_sameChannelConflict1() {
- long priority = 0;
- long channelToWatch = 1;
- long channelId = 1;
- List<ScheduledRecording> schedules = new ArrayList<>();
- ScheduledRecording r1 = RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 200L);
- schedules.add(r1);
- ScheduledRecording r2 = RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- channelToWatch, ++priority, 0L, 200L);
- schedules.add(r2);
- ScheduledRecording r3 = RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- channelToWatch, ++priority, 0L, 200L);
- schedules.add(r3);
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedulesForWatching(
- INPUT_ID, channelToWatch, 0L, ++priority, schedules, 3), r2);
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedulesForWatching(
- INPUT_ID, channelToWatch, 0L, ++priority, schedules, 2), r2);
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedulesForWatching(
- INPUT_ID, channelToWatch, 0L, ++priority, schedules, 1), r2, r1);
- }
-
- @Test
- public void testGetConflictingSchedulesForWatching_sameChannelConflict2() {
- long priority = 0;
- long channelToWatch = 1;
- long channelId = 1;
- List<ScheduledRecording> schedules = new ArrayList<>();
- ScheduledRecording r1 = RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- channelToWatch, ++priority, 0L, 200L);
- schedules.add(r1);
- ScheduledRecording r2 = RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- channelToWatch, ++priority, 0L, 200L);
- schedules.add(r2);
- ScheduledRecording r3 = RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(
- ++channelId, ++priority, 0L, 200L);
- schedules.add(r3);
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedulesForWatching(
- INPUT_ID, channelToWatch, 0L, ++priority, schedules, 3), r1);
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedulesForWatching(
- INPUT_ID, channelToWatch, 0L, ++priority, schedules, 2), r1);
- MoreAsserts.assertContentsInOrder(DvrScheduleManager.getConflictingSchedulesForWatching(
- INPUT_ID, channelToWatch, 0L, ++priority, schedules, 1), r3, r1);
- }
-
- @Test
- public void testPartiallyConflictingSchedules() {
- long priority = 100;
- long channelId = 0;
- List<ScheduledRecording> schedules = new ArrayList<>(Arrays.asList(
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(++channelId,
- --priority, 0L, 400L),
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(++channelId,
- --priority, 0L, 200L),
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(++channelId,
- --priority, 200L, 500L),
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(++channelId,
- --priority, 400L, 600L),
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(++channelId,
- --priority, 700L, 800L),
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(++channelId,
- --priority, 600L, 900L),
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(++channelId,
- --priority, 800L, 900L),
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(++channelId,
- --priority, 800L, 900L),
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(++channelId,
- --priority, 750L, 850L),
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(++channelId,
- --priority, 300L, 450L),
- RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(++channelId,
- --priority, 50L, 900L)
- ));
- List<ConflictInfo> conflicts = DvrScheduleManager.getConflictingSchedulesInfo(schedules, 1);
-
- assertNotInList(schedules.get(0), conflicts);
- assertFullConflict(schedules.get(1), conflicts);
- assertPartialConflict(schedules.get(2), conflicts);
- assertPartialConflict(schedules.get(3), conflicts);
- assertNotInList(schedules.get(4), conflicts);
- assertPartialConflict(schedules.get(5), conflicts);
- assertNotInList(schedules.get(6), conflicts);
- assertFullConflict(schedules.get(7), conflicts);
- assertFullConflict(schedules.get(8), conflicts);
- assertFullConflict(schedules.get(9), conflicts);
- assertFullConflict(schedules.get(10), conflicts);
-
- conflicts = DvrScheduleManager.getConflictingSchedulesInfo(schedules, 2);
-
- assertNotInList(schedules.get(0), conflicts);
- assertNotInList(schedules.get(1), conflicts);
- assertNotInList(schedules.get(2), conflicts);
- assertNotInList(schedules.get(3), conflicts);
- assertNotInList(schedules.get(4), conflicts);
- assertNotInList(schedules.get(5), conflicts);
- assertNotInList(schedules.get(6), conflicts);
- assertFullConflict(schedules.get(7), conflicts);
- assertFullConflict(schedules.get(8), conflicts);
- assertFullConflict(schedules.get(9), conflicts);
- assertPartialConflict(schedules.get(10), conflicts);
-
- conflicts = DvrScheduleManager.getConflictingSchedulesInfo(schedules, 3);
-
- assertNotInList(schedules.get(0), conflicts);
- assertNotInList(schedules.get(1), conflicts);
- assertNotInList(schedules.get(2), conflicts);
- assertNotInList(schedules.get(3), conflicts);
- assertNotInList(schedules.get(4), conflicts);
- assertNotInList(schedules.get(5), conflicts);
- assertNotInList(schedules.get(6), conflicts);
- assertNotInList(schedules.get(7), conflicts);
- assertPartialConflict(schedules.get(8), conflicts);
- assertNotInList(schedules.get(9), conflicts);
- assertPartialConflict(schedules.get(10), conflicts);
- }
-
- private void assertNotInList(ScheduledRecording schedule, List<ConflictInfo> conflicts) {
- for (ConflictInfo conflictInfo : conflicts) {
- if (conflictInfo.schedule.equals(schedule)) {
- fail(schedule + " conflicts with others.");
- }
- }
- }
-
- private void assertPartialConflict(ScheduledRecording schedule, List<ConflictInfo> conflicts) {
- for (ConflictInfo conflictInfo : conflicts) {
- if (conflictInfo.schedule.equals(schedule)) {
- if (conflictInfo.partialConflict) {
- return;
- } else {
- fail(schedule + " fully conflicts with others.");
- }
- }
- }
- fail(schedule + " doesn't conflict");
- }
-
- private void assertFullConflict(ScheduledRecording schedule, List<ConflictInfo> conflicts) {
- for (ConflictInfo conflictInfo : conflicts) {
- if (conflictInfo.schedule.equals(schedule)) {
- if (!conflictInfo.partialConflict) {
- return;
- } else {
- fail(schedule + " partially conflicts with others.");
- }
- }
- }
- fail(schedule + " doesn't conflict");
- }
-} \ No newline at end of file
diff --git a/tests/unit/src/com/android/tv/dvr/ScheduledRecordingTest.java b/tests/unit/src/com/android/tv/dvr/ScheduledRecordingTest.java
deleted file mode 100644
index b98af603..00000000
--- a/tests/unit/src/com/android/tv/dvr/ScheduledRecordingTest.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * 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.dvr;
-
-import static com.android.tv.testing.dvr.RecordingTestUtils.createTestRecordingWithIdAndPeriod;
-import static com.android.tv.testing.dvr.RecordingTestUtils.normalizePriority;
-import static junit.framework.TestCase.assertEquals;
-
-import android.os.Build;
-import android.support.test.filters.SdkSuppress;
-import android.support.test.filters.SmallTest;
-import android.test.MoreAsserts;
-import android.util.Range;
-
-import com.android.tv.data.Channel;
-import com.android.tv.data.Program;
-import com.android.tv.dvr.data.ScheduledRecording;
-import com.android.tv.testing.dvr.RecordingTestUtils;
-
-import org.junit.Test;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-/** Tests for {@link ScheduledRecordingTest} */
-@SmallTest
-@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
-public class ScheduledRecordingTest {
- private static final String INPUT_ID = "input_id";
- private static final int CHANNEL_ID = 273;
-
- @Test
- public void testIsOverLapping() {
- ScheduledRecording r = createTestRecordingWithIdAndPeriod(1, INPUT_ID, CHANNEL_ID,
- 10L, 20L);
- assertOverLapping(false, 1L, 9L, r);
-
- assertOverLapping(true, 1L, 20L, r);
- assertOverLapping(false, 1L, 10L, r);
- assertOverLapping(true, 10L, 19L, r);
- assertOverLapping(true, 10L, 20L, r);
- assertOverLapping(true, 11L, 20L, r);
- assertOverLapping(true, 11L, 21L, r);
- assertOverLapping(false, 20L, 21L, r);
-
- assertOverLapping(false, 21L, 29L, r);
- }
-
- @Test
- public void testBuildProgram() {
- Channel c = new Channel.Builder().build();
- Program p = new Program.Builder().build();
- ScheduledRecording actual = ScheduledRecording.builder(INPUT_ID, p)
- .setChannelId(c.getId()).build();
- assertEquals("type", ScheduledRecording.TYPE_PROGRAM, actual.getType());
- }
-
- @Test
- public void testBuildTime() {
- ScheduledRecording actual = createTestRecordingWithIdAndPeriod(1, INPUT_ID, CHANNEL_ID,
- 10L, 20L);
- assertEquals("type", ScheduledRecording.TYPE_TIMED, actual.getType());
- }
-
- @Test
- public void testBuildFrom() {
- ScheduledRecording expected = createTestRecordingWithIdAndPeriod(1, INPUT_ID, CHANNEL_ID,
- 10L, 20L);
- ScheduledRecording actual = ScheduledRecording.buildFrom(expected).build();
- RecordingTestUtils.assertRecordingEquals(expected, actual);
- }
-
- @Test
- public void testBuild_priority() {
- ScheduledRecording a = normalizePriority(
- createTestRecordingWithIdAndPeriod(1, INPUT_ID, CHANNEL_ID, 10L, 20L));
- ScheduledRecording b = normalizePriority(
- createTestRecordingWithIdAndPeriod(2, INPUT_ID, CHANNEL_ID, 10L, 20L));
- ScheduledRecording c = normalizePriority(
- createTestRecordingWithIdAndPeriod(3, INPUT_ID, CHANNEL_ID, 10L, 20L));
-
- // default priority
- MoreAsserts.assertContentsInOrder(sortByPriority(c, b, a), a, b, c);
-
- // make A preferred over B
- a = ScheduledRecording.buildFrom(a).setPriority(b.getPriority() + 2).build();
- MoreAsserts.assertContentsInOrder(sortByPriority(a, b, c), b, c, a);
- }
-
- public Collection<ScheduledRecording> sortByPriority(ScheduledRecording a, ScheduledRecording b,
- ScheduledRecording c) {
- List<ScheduledRecording> list = Arrays.asList(a, b, c);
- Collections.sort(list, ScheduledRecording.PRIORITY_COMPARATOR);
- return list;
- }
-
- private void assertOverLapping(boolean expected, long lower, long upper, ScheduledRecording r) {
- assertEquals("isOverlapping(Range(" + lower + "," + upper + "), recording " + r, expected,
- r.isOverLapping(new Range<>(lower, upper)));
- }
-}
diff --git a/tests/unit/src/com/android/tv/dvr/data/SeriesRecordingTest.java b/tests/unit/src/com/android/tv/dvr/data/SeriesRecordingTest.java
deleted file mode 100644
index 790b2ee8..00000000
--- a/tests/unit/src/com/android/tv/dvr/data/SeriesRecordingTest.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (C) 2016 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.dvr.data;
-
-import static org.junit.Assert.assertEquals;
-
-import android.os.Build;
-import android.os.Parcel;
-import android.support.test.filters.SdkSuppress;
-import android.support.test.filters.SmallTest;
-
-import com.android.tv.data.Program;
-
-import org.junit.Test;
-
-/**
- * Tests for {@link SeriesRecording}.
- */
-@SmallTest
-@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
-public class SeriesRecordingTest {
- private static final String PROGRAM_TITLE = "MyProgram";
- private static final long CHANNEL_ID = 123;
- private static final long OTHER_CHANNEL_ID = 321;
- private static final String SERIES_ID = "SERIES_ID";
- private static final String OTHER_SERIES_ID = "OTHER_SERIES_ID";
-
- private final SeriesRecording mBaseSeriesRecording = new SeriesRecording.Builder()
- .setTitle(PROGRAM_TITLE).setChannelId(CHANNEL_ID).setSeriesId(SERIES_ID).build();
- private final SeriesRecording mSeriesRecordingSeason2 = SeriesRecording
- .buildFrom(mBaseSeriesRecording).setStartFromSeason(2).build();
- private final SeriesRecording mSeriesRecordingSeason2Episode5 = SeriesRecording
- .buildFrom(mSeriesRecordingSeason2).setStartFromEpisode(5).build();
- private final Program mBaseProgram = new Program.Builder().setTitle(PROGRAM_TITLE)
- .setChannelId(CHANNEL_ID).setSeriesId(SERIES_ID).build();
-
- @Test
- public void testParcelable() {
- SeriesRecording r1 = new SeriesRecording.Builder()
- .setId(1)
- .setChannelId(2)
- .setPriority(3)
- .setTitle("4")
- .setDescription("5")
- .setLongDescription("5-long")
- .setSeriesId("6")
- .setStartFromEpisode(7)
- .setStartFromSeason(8)
- .setChannelOption(SeriesRecording.OPTION_CHANNEL_ALL)
- .setCanonicalGenreIds(new int[] {9, 10})
- .setPosterUri("11")
- .setPhotoUri("12")
- .build();
- Parcel p1 = Parcel.obtain();
- Parcel p2 = Parcel.obtain();
- try {
- r1.writeToParcel(p1, 0);
- byte[] bytes = p1.marshall();
- p2.unmarshall(bytes, 0, bytes.length);
- p2.setDataPosition(0);
- SeriesRecording r2 = SeriesRecording.fromParcel(p2);
- assertEquals(r1, r2);
- } finally {
- p1.recycle();
- p2.recycle();
- }
- }
-
- @Test
- public void testDoesProgramMatch_simpleMatch() {
- assertDoesProgramMatch(mBaseProgram, mBaseSeriesRecording, true);
- }
-
- @Test
- public void testDoesProgramMatch_differentSeriesId() {
- Program program = new Program.Builder(mBaseProgram).setSeriesId(OTHER_SERIES_ID).build();
- assertDoesProgramMatch(program, mBaseSeriesRecording, false);
- }
-
- @Test
- public void testDoesProgramMatch_differentChannel() {
- Program program = new Program.Builder(mBaseProgram).setChannelId(OTHER_CHANNEL_ID).build();
- assertDoesProgramMatch(program, mBaseSeriesRecording, false);
- }
-
- @Test
- public void testDoesProgramMatch_startFromSeason2() {
- Program program = mBaseProgram;
- assertDoesProgramMatch(program, mSeriesRecordingSeason2, true);
- program = new Program.Builder(program).setSeasonNumber("1").build();
- assertDoesProgramMatch(program, mSeriesRecordingSeason2, false);
- program = new Program.Builder(program).setSeasonNumber("2").build();
- assertDoesProgramMatch(program, mSeriesRecordingSeason2, true);
- program = new Program.Builder(program).setSeasonNumber("3").build();
- assertDoesProgramMatch(program, mSeriesRecordingSeason2, true);
- }
-
- @Test
- public void testDoesProgramMatch_startFromSeason2episode5() {
- Program program = mBaseProgram;
- assertDoesProgramMatch(program, mSeriesRecordingSeason2Episode5, true);
- program = new Program.Builder(program).setSeasonNumber("2").build();
- assertDoesProgramMatch(program, mSeriesRecordingSeason2Episode5, true);
- program = new Program.Builder(program).setEpisodeNumber("4").build();
- assertDoesProgramMatch(program, mSeriesRecordingSeason2Episode5, false);
- program = new Program.Builder(program).setEpisodeNumber("5").build();
- assertDoesProgramMatch(program, mSeriesRecordingSeason2Episode5, true);
- program = new Program.Builder(program).setEpisodeNumber("6").build();
- assertDoesProgramMatch(program, mSeriesRecordingSeason2Episode5, true);
- program = new Program.Builder(program).setSeasonNumber("3").setEpisodeNumber("1").build();
- assertDoesProgramMatch(program, mSeriesRecordingSeason2Episode5, true);
- }
-
- private void assertDoesProgramMatch(Program p, SeriesRecording seriesRecording,
- boolean expected) {
- assertEquals(seriesRecording + " doesProgramMatch " + p, expected,
- seriesRecording.matchProgram(p));
- }
-}
diff --git a/tests/unit/src/com/android/tv/dvr/provider/DvrDbSyncTest.java b/tests/unit/src/com/android/tv/dvr/provider/DvrDbSyncTest.java
deleted file mode 100644
index 94f88a51..00000000
--- a/tests/unit/src/com/android/tv/dvr/provider/DvrDbSyncTest.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2016 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.dvr.provider;
-
-import static android.support.test.InstrumentationRegistry.getContext;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyObject;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.os.Build;
-import android.support.test.filters.SdkSuppress;
-import android.support.test.filters.SmallTest;
-
-import com.android.tv.data.ChannelDataManager;
-import com.android.tv.data.Program;
-import com.android.tv.dvr.DvrDataManagerImpl;
-import com.android.tv.dvr.DvrManager;
-import com.android.tv.dvr.data.ScheduledRecording;
-import com.android.tv.dvr.data.SeriesRecording;
-import com.android.tv.dvr.recorder.SeriesRecordingScheduler;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-/**
- * Tests for {@link com.android.tv.dvr.DvrScheduleManager}
- */
-@SmallTest
-@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
-public class DvrDbSyncTest {
- private static final String INPUT_ID = "input_id";
- private static final long BASE_PROGRAM_ID = 1;
- private static final long BASE_START_TIME_MS = 0;
- private static final long BASE_END_TIME_MS = 1;
- private static final String BASE_SEASON_NUMBER = "2";
- private static final String BASE_EPISODE_NUMBER = "3";
- private static final Program BASE_PROGRAM = new Program.Builder().setId(BASE_PROGRAM_ID)
- .setStartTimeUtcMillis(BASE_START_TIME_MS).setEndTimeUtcMillis(BASE_END_TIME_MS)
- .build();
- private static final Program BASE_SERIES_PROGRAM = new Program.Builder().setId(BASE_PROGRAM_ID)
- .setStartTimeUtcMillis(BASE_START_TIME_MS).setEndTimeUtcMillis(BASE_END_TIME_MS)
- .setSeasonNumber(BASE_SEASON_NUMBER).setEpisodeNumber(BASE_EPISODE_NUMBER).build();
- private static final ScheduledRecording BASE_SCHEDULE =
- ScheduledRecording.builder(INPUT_ID, BASE_PROGRAM).build();
- private static final ScheduledRecording BASE_SERIES_SCHEDULE =
- ScheduledRecording.builder(INPUT_ID, BASE_SERIES_PROGRAM).build();
-
- private DvrDbSync mDbSync;
- @Mock private DvrManager mDvrManager;
- @Mock private DvrDataManagerImpl mDataManager;
- @Mock private ChannelDataManager mChannelDataManager;
- @Mock private SeriesRecordingScheduler mSeriesRecordingScheduler;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- when(mChannelDataManager.isDbLoadFinished()).thenReturn(true);
- when(mDvrManager.addSeriesRecording(anyObject(), anyObject(), anyInt()))
- .thenReturn(SeriesRecording.builder(INPUT_ID, BASE_PROGRAM).build());
- mDbSync = new DvrDbSync(getContext(), mDataManager, mChannelDataManager,
- mDvrManager, mSeriesRecordingScheduler);
- }
-
- @Test
- public void testHandleUpdateProgram_null() {
- addSchedule(BASE_PROGRAM_ID, BASE_SCHEDULE);
- mDbSync.handleUpdateProgram(null, BASE_PROGRAM_ID);
- verify(mDataManager).removeScheduledRecording(BASE_SCHEDULE);
- }
-
- @Test
- public void testHandleUpdateProgram_changeTimeNotStarted() {
- addSchedule(BASE_PROGRAM_ID, BASE_SCHEDULE);
- long startTimeMs = BASE_START_TIME_MS + 1;
- long endTimeMs = BASE_END_TIME_MS + 1;
- Program program = new Program.Builder(BASE_PROGRAM).setStartTimeUtcMillis(startTimeMs)
- .setEndTimeUtcMillis(endTimeMs).build();
- mDbSync.handleUpdateProgram(program, BASE_PROGRAM_ID);
- assertUpdateScheduleCalled(program);
- }
-
- @Test
- public void testHandleUpdateProgram_changeTimeInProgressNotCalled() {
- addSchedule(BASE_PROGRAM_ID, ScheduledRecording.buildFrom(BASE_SCHEDULE)
- .setState(ScheduledRecording.STATE_RECORDING_IN_PROGRESS).build());
- long startTimeMs = BASE_START_TIME_MS + 1;
- Program program = new Program.Builder(BASE_PROGRAM).setStartTimeUtcMillis(startTimeMs)
- .build();
- mDbSync.handleUpdateProgram(program, BASE_PROGRAM_ID);
- verify(mDataManager, never()).updateScheduledRecording(anyObject());
- }
-
- @Test
- public void testHandleUpdateProgram_changeSeason() {
- addSchedule(BASE_PROGRAM_ID, BASE_SERIES_SCHEDULE);
- String seasonNumber = BASE_SEASON_NUMBER + "1";
- String episodeNumber = BASE_EPISODE_NUMBER + "1";
- Program program = new Program.Builder(BASE_SERIES_PROGRAM).setSeasonNumber(seasonNumber)
- .setEpisodeNumber(episodeNumber).build();
- mDbSync.handleUpdateProgram(program, BASE_PROGRAM_ID);
- assertUpdateScheduleCalled(program);
- }
-
- @Test
- public void testHandleUpdateProgram_finished() {
- addSchedule(BASE_PROGRAM_ID, ScheduledRecording.buildFrom(BASE_SERIES_SCHEDULE)
- .setState(ScheduledRecording.STATE_RECORDING_FINISHED).build());
- String seasonNumber = BASE_SEASON_NUMBER + "1";
- String episodeNumber = BASE_EPISODE_NUMBER + "1";
- Program program = new Program.Builder(BASE_SERIES_PROGRAM).setSeasonNumber(seasonNumber)
- .setEpisodeNumber(episodeNumber).build();
- mDbSync.handleUpdateProgram(program, BASE_PROGRAM_ID);
- verify(mDataManager, never()).updateScheduledRecording(anyObject());
- }
-
- private void addSchedule(long programId, ScheduledRecording schedule) {
- when(mDataManager.getScheduledRecordingForProgramId(programId)).thenReturn(schedule);
- }
-
- private void assertUpdateScheduleCalled(Program program) {
- verify(mDataManager).updateScheduledRecording(
- eq(ScheduledRecording.builder(INPUT_ID, program).build()));
- }
-}
diff --git a/tests/unit/src/com/android/tv/dvr/provider/EpisodicProgramLoadTaskTest.java b/tests/unit/src/com/android/tv/dvr/provider/EpisodicProgramLoadTaskTest.java
deleted file mode 100644
index 216d4d5b..00000000
--- a/tests/unit/src/com/android/tv/dvr/provider/EpisodicProgramLoadTaskTest.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2016 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.dvr.provider;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import android.os.Build;
-import android.support.test.filters.SdkSuppress;
-import android.support.test.filters.SmallTest;
-
-import com.android.tv.dvr.data.SeasonEpisodeNumber;
-
-import org.junit.Test;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Tests for {@link EpisodicProgramLoadTask}
- */
-@SmallTest
-@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
-public class EpisodicProgramLoadTaskTest {
- private static final long SERIES_RECORDING_ID1 = 1;
- private static final long SERIES_RECORDING_ID2 = 2;
- private static final String SEASON_NUMBER1 = "SEASON NUMBER1";
- private static final String SEASON_NUMBER2 = "SEASON NUMBER2";
- private static final String EPISODE_NUMBER1 = "EPISODE NUMBER1";
- private static final String EPISODE_NUMBER2 = "EPISODE NUMBER2";
-
- @Test
- public void testEpisodeAlreadyScheduled_true() {
- List<SeasonEpisodeNumber> seasonEpisodeNumbers = new ArrayList<>();
- SeasonEpisodeNumber seasonEpisodeNumber = new SeasonEpisodeNumber(
- SERIES_RECORDING_ID1, SEASON_NUMBER1, EPISODE_NUMBER1);
- seasonEpisodeNumbers.add(seasonEpisodeNumber);
- assertTrue(seasonEpisodeNumbers.contains(
- new SeasonEpisodeNumber(SERIES_RECORDING_ID1, SEASON_NUMBER1, EPISODE_NUMBER1)));
- }
-
- @Test
- public void testEpisodeAlreadyScheduled_false() {
- List<SeasonEpisodeNumber> seasonEpisodeNumbers = new ArrayList<>();
- SeasonEpisodeNumber seasonEpisodeNumber = new SeasonEpisodeNumber(
- SERIES_RECORDING_ID1, SEASON_NUMBER1, EPISODE_NUMBER1);
- seasonEpisodeNumbers.add(seasonEpisodeNumber);
- assertFalse(seasonEpisodeNumbers.contains(
- new SeasonEpisodeNumber(SERIES_RECORDING_ID2, SEASON_NUMBER1, EPISODE_NUMBER1)));
- assertFalse(seasonEpisodeNumbers.contains(
- new SeasonEpisodeNumber(SERIES_RECORDING_ID1, SEASON_NUMBER2, EPISODE_NUMBER1)));
- assertFalse(seasonEpisodeNumbers.contains(
- new SeasonEpisodeNumber(SERIES_RECORDING_ID1, SEASON_NUMBER1, EPISODE_NUMBER2)));
- }
-
- @Test
- public void testEpisodeAlreadyScheduled_null() {
- List<SeasonEpisodeNumber> seasonEpisodeNumbers = new ArrayList<>();
- SeasonEpisodeNumber seasonEpisodeNumber = new SeasonEpisodeNumber(
- SERIES_RECORDING_ID1, SEASON_NUMBER1, EPISODE_NUMBER1);
- seasonEpisodeNumbers.add(seasonEpisodeNumber);
- assertFalse(seasonEpisodeNumbers.contains(
- new SeasonEpisodeNumber(SERIES_RECORDING_ID1, null, EPISODE_NUMBER1)));
- assertFalse(seasonEpisodeNumbers.contains(
- new SeasonEpisodeNumber(SERIES_RECORDING_ID1, SEASON_NUMBER1, null)));
- assertFalse(seasonEpisodeNumbers.contains(
- new SeasonEpisodeNumber(SERIES_RECORDING_ID1, null, null)));
- }
-} \ No newline at end of file
diff --git a/tests/unit/src/com/android/tv/dvr/recorder/DvrRecordingServiceTest.java b/tests/unit/src/com/android/tv/dvr/recorder/DvrRecordingServiceTest.java
index 8f7dcaf2..d510da32 100644
--- a/tests/unit/src/com/android/tv/dvr/recorder/DvrRecordingServiceTest.java
+++ b/tests/unit/src/com/android/tv/dvr/recorder/DvrRecordingServiceTest.java
@@ -16,24 +16,18 @@
package com.android.tv.dvr.recorder;
-import static org.mockito.Mockito.verify;
+import static com.google.common.truth.Truth.assertThat;
import android.content.Intent;
import android.os.Build;
import android.support.test.filters.SdkSuppress;
import android.support.test.filters.SmallTest;
import android.test.ServiceTestCase;
-
import com.android.tv.common.feature.CommonFeatures;
import com.android.tv.common.feature.TestableFeature;
-
-import org.mockito.Mock;
-import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
-/**
- * Tests for {@link DvrRecordingService}.
- */
+/** Tests for {@link DvrRecordingService}. */
@SmallTest
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
public class DvrRecordingServiceTest
@@ -61,13 +55,13 @@ public class DvrRecordingServiceTest
public void testStartService_null() throws Exception {
// Not recording
startService(null);
- assertFalse(getService().mInForeground);
+ assertThat(getService().mInForeground).isFalse();
// Recording
getService().startRecording();
startService(null);
- assertTrue(getService().mInForeground);
- assertTrue(getService().mIsRecording);
+ assertThat(getService().mInForeground).isTrue();
+ assertThat(getService().mIsRecording).isTrue();
getService().reset();
}
@@ -77,38 +71,38 @@ public class DvrRecordingServiceTest
// Not recording
startService(intent);
- assertTrue(getService().mInForeground);
- assertFalse(getService().mForegroundForUpcomingRecording);
+ assertThat(getService().mInForeground).isTrue();
+ assertThat(getService().mForegroundForUpcomingRecording).isFalse();
getService().stopForegroundIfNotRecordingInternal();
- assertFalse(getService().mInForeground);
+ assertThat(getService().mInForeground).isFalse();
// Recording, ended quickly
getService().startRecording();
startService(intent);
- assertTrue(getService().mInForeground);
- assertTrue(getService().mForegroundForUpcomingRecording);
- assertTrue(getService().mIsRecording);
+ assertThat(getService().mInForeground).isTrue();
+ assertThat(getService().mForegroundForUpcomingRecording).isTrue();
+ assertThat(getService().mIsRecording).isTrue();
getService().stopRecording();
- assertFalse(getService().mInForeground);
- assertFalse(getService().mIsRecording);
+ assertThat(getService().mInForeground).isFalse();
+ assertThat(getService().mIsRecording).isFalse();
getService().stopForegroundIfNotRecordingInternal();
- assertFalse(getService().mInForeground);
- assertFalse(getService().mIsRecording);
+ assertThat(getService().mInForeground).isFalse();
+ assertThat(getService().mIsRecording).isFalse();
getService().reset();
// Recording, ended later
getService().startRecording();
startService(intent);
- assertTrue(getService().mInForeground);
- assertTrue(getService().mForegroundForUpcomingRecording);
- assertTrue(getService().mIsRecording);
+ assertThat(getService().mInForeground).isTrue();
+ assertThat(getService().mForegroundForUpcomingRecording).isTrue();
+ assertThat(getService().mIsRecording).isTrue();
getService().stopForegroundIfNotRecordingInternal();
- assertTrue(getService().mInForeground);
- assertTrue(getService().mForegroundForUpcomingRecording);
- assertTrue(getService().mIsRecording);
+ assertThat(getService().mInForeground).isTrue();
+ assertThat(getService().mForegroundForUpcomingRecording).isTrue();
+ assertThat(getService().mIsRecording).isTrue();
getService().stopRecording();
- assertFalse(getService().mInForeground);
- assertFalse(getService().mIsRecording);
+ assertThat(getService().mInForeground).isFalse();
+ assertThat(getService().mIsRecording).isFalse();
getService().reset();
}
@@ -118,38 +112,39 @@ public class DvrRecordingServiceTest
// Not recording
startService(intent);
- assertTrue(getService().mInForeground);
- assertTrue(getService().mForegroundForUpcomingRecording);
- assertFalse(getService().mIsRecording);
+ assertThat(getService().mInForeground).isTrue();
+ assertThat(getService().mForegroundForUpcomingRecording).isTrue();
+ assertThat(getService().mIsRecording).isFalse();
getService().startRecording();
- assertTrue(getService().mInForeground);
- assertTrue(getService().mForegroundForUpcomingRecording);
- assertTrue(getService().mIsRecording);
+ assertThat(getService().mInForeground).isTrue();
+ assertThat(getService().mForegroundForUpcomingRecording).isTrue();
+ assertThat(getService().mIsRecording).isTrue();
getService().stopRecording();
- assertFalse(getService().mInForeground);
- assertFalse(getService().mIsRecording);
+ assertThat(getService().mInForeground).isFalse();
+ assertThat(getService().mIsRecording).isFalse();
getService().reset();
// Recording
getService().startRecording();
startService(intent);
- assertTrue(getService().mInForeground);
- assertTrue(getService().mForegroundForUpcomingRecording);
- assertTrue(getService().mIsRecording);
+ assertThat(getService().mInForeground).isTrue();
+ assertThat(getService().mForegroundForUpcomingRecording).isTrue();
+ assertThat(getService().mIsRecording).isTrue();
getService().startRecording();
- assertTrue(getService().mInForeground);
- assertTrue(getService().mForegroundForUpcomingRecording);
- assertTrue(getService().mIsRecording);
+ assertThat(getService().mInForeground).isTrue();
+ assertThat(getService().mForegroundForUpcomingRecording).isTrue();
+ assertThat(getService().mIsRecording).isTrue();
getService().stopRecording();
- assertTrue(getService().mInForeground);
- assertTrue(getService().mForegroundForUpcomingRecording);
- assertTrue(getService().mIsRecording);
+ assertThat(getService().mInForeground).isTrue();
+ assertThat(getService().mForegroundForUpcomingRecording).isTrue();
+ assertThat(getService().mIsRecording).isTrue();
getService().stopRecording();
- assertFalse(getService().mInForeground);
- assertFalse(getService().mIsRecording);
+ assertThat(getService().mInForeground).isFalse();
+ assertThat(getService().mIsRecording).isFalse();
getService().reset();
}
+ /** Mock {@link DvrRecordingService}. */
public static class MockDvrRecordingService extends DvrRecordingService {
private int mRecordingCount = 0;
private boolean mInForeground;
@@ -180,4 +175,4 @@ public class DvrRecordingServiceTest
mIsRecording = false;
}
}
-} \ No newline at end of file
+}
diff --git a/tests/unit/src/com/android/tv/dvr/recorder/InputTaskSchedulerTest.java b/tests/unit/src/com/android/tv/dvr/recorder/InputTaskSchedulerTest.java
deleted file mode 100644
index e5c27e2c..00000000
--- a/tests/unit/src/com/android/tv/dvr/recorder/InputTaskSchedulerTest.java
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * Copyright (C) 2016 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.dvr.recorder;
-
-import static android.support.test.InstrumentationRegistry.getContext;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyLong;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.timeout;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.AlarmManager;
-import android.media.tv.TvInputInfo;
-import android.os.Build;
-import android.os.Looper;
-import android.os.SystemClock;
-import android.support.test.filters.SdkSuppress;
-import android.support.test.filters.SmallTest;
-
-import com.android.tv.InputSessionManager;
-import com.android.tv.data.Channel;
-import com.android.tv.data.ChannelDataManager;
-import com.android.tv.dvr.DvrManager;
-import com.android.tv.dvr.WritableDvrDataManager;
-import com.android.tv.dvr.data.ScheduledRecording;
-import com.android.tv.dvr.recorder.InputTaskScheduler.RecordingTaskFactory;
-import com.android.tv.testing.FakeClock;
-import com.android.tv.testing.dvr.RecordingTestUtils;
-import com.android.tv.util.Clock;
-import com.android.tv.util.TestUtils;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Tests for {@link InputTaskScheduler}.
- */
-@SmallTest
-@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
-public class InputTaskSchedulerTest {
- private static final String INPUT_ID = "input_id";
- private static final int CHANNEL_ID = 1;
- private static final long LISTENER_TIMEOUT_MS = TimeUnit.SECONDS.toMillis(1);
- private static final int TUNER_COUNT_ONE = 1;
- private static final int TUNER_COUNT_TWO = 2;
- private static final long LOW_PRIORITY = 1;
- private static final long HIGH_PRIORITY = 2;
-
- private FakeClock mFakeClock;
- private InputTaskScheduler mScheduler;
- @Mock private DvrManager mDvrManager;
- @Mock private WritableDvrDataManager mDataManager;
- @Mock private InputSessionManager mSessionManager;
- @Mock private AlarmManager mMockAlarmManager;
- @Mock private ChannelDataManager mChannelDataManager;
- private List<RecordingTask> mRecordingTasks;
-
- @Before
- public void setUp() throws Exception {
- if (Looper.myLooper() == null) {
- Looper.prepare();
- }
- mRecordingTasks = new ArrayList();
- MockitoAnnotations.initMocks(this);
- mFakeClock = FakeClock.createWithCurrentTime();
- TvInputInfo input = createTvInputInfo(TUNER_COUNT_ONE);
- mScheduler = new InputTaskScheduler(getContext(), input, Looper.myLooper(),
- mChannelDataManager, mDvrManager, mDataManager, mSessionManager, mFakeClock,
- new RecordingTaskFactory() {
- @Override
- public RecordingTask createRecordingTask(ScheduledRecording scheduledRecording,
- Channel channel, DvrManager dvrManager,
- InputSessionManager sessionManager, WritableDvrDataManager dataManager,
- Clock clock) {
- RecordingTask task = mock(RecordingTask.class);
- when(task.getPriority()).thenReturn(scheduledRecording.getPriority());
- when(task.getEndTimeMs()).thenReturn(scheduledRecording.getEndTimeMs());
- mRecordingTasks.add(task);
- return task;
- }
- });
- }
-
- @Test
- public void testAddSchedule_past() {
- ScheduledRecording r = RecordingTestUtils.createTestRecordingWithPeriod(INPUT_ID,
- CHANNEL_ID, 0L, 1L);
- when(mDataManager.getScheduledRecording(anyLong())).thenReturn(r);
- mScheduler.handleAddSchedule(r);
- mScheduler.handleBuildSchedule();
- verify(mDataManager, timeout((int) LISTENER_TIMEOUT_MS).times(1))
- .changeState(any(ScheduledRecording.class),
- eq(ScheduledRecording.STATE_RECORDING_FAILED));
- }
-
- @Test
- public void testAddSchedule_start() {
- mScheduler.handleAddSchedule(RecordingTestUtils.createTestRecordingWithPeriod(INPUT_ID,
- CHANNEL_ID, mFakeClock.currentTimeMillis(),
- mFakeClock.currentTimeMillis() + TimeUnit.HOURS.toMillis(1)));
- mScheduler.handleBuildSchedule();
- verify(mRecordingTasks.get(0), timeout((int) LISTENER_TIMEOUT_MS).times(1)).start();
- }
-
- @Test
- public void testAddSchedule_consecutiveNoStop() {
- long startTimeMs = mFakeClock.currentTimeMillis();
- long endTimeMs = startTimeMs + TimeUnit.SECONDS.toMillis(1);
- long id = 0;
- mScheduler.handleAddSchedule(
- RecordingTestUtils.createTestRecordingWithIdAndPriorityAndPeriod(++id, CHANNEL_ID,
- LOW_PRIORITY, startTimeMs, endTimeMs));
- mScheduler.handleBuildSchedule();
- startTimeMs = endTimeMs;
- endTimeMs = startTimeMs + TimeUnit.SECONDS.toMillis(1);
- mScheduler.handleAddSchedule(
- RecordingTestUtils.createTestRecordingWithIdAndPriorityAndPeriod(++id, CHANNEL_ID,
- HIGH_PRIORITY, startTimeMs, endTimeMs));
- mScheduler.handleBuildSchedule();
- verify(mRecordingTasks.get(0), timeout((int) LISTENER_TIMEOUT_MS).times(1)).start();
- // The first schedule should not be stopped because the second one should wait for the end
- // of the first schedule.
- SystemClock.sleep(LISTENER_TIMEOUT_MS);
- verify(mRecordingTasks.get(0), never()).stop();
- }
-
- @Test
- public void testAddSchedule_consecutiveNoFail() {
- long startTimeMs = mFakeClock.currentTimeMillis();
- long endTimeMs = startTimeMs + TimeUnit.SECONDS.toMillis(1);
- long id = 0;
- when(mDataManager.getScheduledRecording(anyLong())).thenReturn(ScheduledRecording
- .builder(INPUT_ID, CHANNEL_ID, 0L, 0L).build());
- mScheduler.handleAddSchedule(
- RecordingTestUtils.createTestRecordingWithIdAndPriorityAndPeriod(++id, CHANNEL_ID,
- HIGH_PRIORITY, startTimeMs, endTimeMs));
- mScheduler.handleBuildSchedule();
- startTimeMs = endTimeMs;
- endTimeMs = startTimeMs + TimeUnit.SECONDS.toMillis(1);
- mScheduler.handleAddSchedule(
- RecordingTestUtils.createTestRecordingWithIdAndPriorityAndPeriod(++id, CHANNEL_ID,
- LOW_PRIORITY, startTimeMs, endTimeMs));
- mScheduler.handleBuildSchedule();
- verify(mRecordingTasks.get(0), timeout((int) LISTENER_TIMEOUT_MS).times(1)).start();
- SystemClock.sleep(LISTENER_TIMEOUT_MS);
- verify(mRecordingTasks.get(0), never()).stop();
- // The second schedule should not fail because it can starts after the first one finishes.
- SystemClock.sleep(LISTENER_TIMEOUT_MS);
- verify(mDataManager, never())
- .changeState(any(ScheduledRecording.class),
- eq(ScheduledRecording.STATE_RECORDING_FAILED));
- }
-
- @Test
- public void testAddSchedule_consecutiveUseLessSession() throws Exception {
- TvInputInfo input = createTvInputInfo(TUNER_COUNT_TWO);
- mScheduler.updateTvInputInfo(input);
- long startTimeMs = mFakeClock.currentTimeMillis();
- long endTimeMs = startTimeMs + TimeUnit.SECONDS.toMillis(1);
- long id = 0;
- mScheduler.handleAddSchedule(
- RecordingTestUtils.createTestRecordingWithIdAndPriorityAndPeriod(++id, CHANNEL_ID,
- LOW_PRIORITY, startTimeMs, endTimeMs));
- mScheduler.handleBuildSchedule();
- startTimeMs = endTimeMs;
- endTimeMs = startTimeMs + TimeUnit.SECONDS.toMillis(1);
- mScheduler.handleAddSchedule(
- RecordingTestUtils.createTestRecordingWithIdAndPriorityAndPeriod(++id, CHANNEL_ID,
- HIGH_PRIORITY, startTimeMs, endTimeMs));
- mScheduler.handleBuildSchedule();
- verify(mRecordingTasks.get(0), timeout((int) LISTENER_TIMEOUT_MS).times(1)).start();
- SystemClock.sleep(LISTENER_TIMEOUT_MS);
- verify(mRecordingTasks.get(0), never()).stop();
- // The second schedule should wait until the first one finishes rather than creating a new
- // session even though there are available tuners.
- assertTrue(mRecordingTasks.size() == 1);
- }
-
- @Test
- public void testUpdateSchedule_noCancel() {
- ScheduledRecording r = RecordingTestUtils.createTestRecordingWithPeriod(INPUT_ID,
- CHANNEL_ID, mFakeClock.currentTimeMillis(),
- mFakeClock.currentTimeMillis() + TimeUnit.HOURS.toMillis(1));
- mScheduler.handleAddSchedule(r);
- mScheduler.handleBuildSchedule();
- mScheduler.handleUpdateSchedule(r);
- SystemClock.sleep(LISTENER_TIMEOUT_MS);
- verify(mRecordingTasks.get(0), never()).cancel();
- }
-
- @Test
- public void testUpdateSchedule_cancel() {
- ScheduledRecording r = RecordingTestUtils.createTestRecordingWithPeriod(INPUT_ID,
- CHANNEL_ID, mFakeClock.currentTimeMillis(),
- mFakeClock.currentTimeMillis() + TimeUnit.HOURS.toMillis(2));
- mScheduler.handleAddSchedule(r);
- mScheduler.handleBuildSchedule();
- mScheduler.handleUpdateSchedule(ScheduledRecording.buildFrom(r)
- .setStartTimeMs(mFakeClock.currentTimeMillis() + TimeUnit.HOURS.toMillis(1))
- .build());
- verify(mRecordingTasks.get(0), timeout((int) LISTENER_TIMEOUT_MS).times(1)).cancel();
- }
-
- private TvInputInfo createTvInputInfo(int tunerCount) throws Exception {
- return TestUtils.createTvInputInfo(null, null, null, 0, false, true, tunerCount);
- }
-}
diff --git a/tests/unit/src/com/android/tv/dvr/recorder/RecordingTaskTest.java b/tests/unit/src/com/android/tv/dvr/recorder/RecordingTaskTest.java
deleted file mode 100644
index 37561a42..00000000
--- a/tests/unit/src/com/android/tv/dvr/recorder/RecordingTaskTest.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * 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.dvr.recorder;
-
-import static android.support.test.InstrumentationRegistry.getContext;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.anyLong;
-import static org.mockito.Matchers.anyObject;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import android.os.Build;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.support.test.filters.SdkSuppress;
-import android.support.test.filters.SmallTest;
-
-import com.android.tv.InputSessionManager;
-import com.android.tv.InputSessionManager.RecordingSession;
-import com.android.tv.common.feature.CommonFeatures;
-import com.android.tv.common.feature.TestableFeature;
-import com.android.tv.data.Channel;
-import com.android.tv.dvr.DvrDataManagerInMemoryImpl;
-import com.android.tv.dvr.DvrManager;
-import com.android.tv.dvr.data.ScheduledRecording;
-import com.android.tv.dvr.recorder.RecordingTask.State;
-import com.android.tv.testing.FakeClock;
-import com.android.tv.testing.dvr.RecordingTestUtils;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.concurrent.TimeUnit;
-
-/**
- * Tests for {@link RecordingTask}.
- */
-@SmallTest
-@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
-public class RecordingTaskTest {
- private static final long DURATION = TimeUnit.MINUTES.toMillis(30);
- private static final long START_OFFSET_MS = RecordingScheduler.MS_TO_WAKE_BEFORE_START;
- private static final String INPUT_ID = "input_id";
- private static final int CHANNEL_ID = 273;
-
- private FakeClock mFakeClock;
- private DvrDataManagerInMemoryImpl mDataManager;
- @Mock Handler mMockHandler;
- @Mock DvrManager mDvrManager;
- @Mock InputSessionManager mMockSessionManager;
- @Mock RecordingSession mMockRecordingSession;
- private final TestableFeature mDvrFeature = CommonFeatures.DVR;
-
- @Before
- public void setUp() {
- mDvrFeature.enableForTest();
- if (Looper.myLooper() == null) {
- Looper.prepare();
- }
- MockitoAnnotations.initMocks(this);
- mFakeClock = FakeClock.createWithCurrentTime();
- mDataManager = new DvrDataManagerInMemoryImpl(getContext(), mFakeClock);
- }
-
- @After
- public void tearDown() {
- mDvrFeature.resetForTests();
- }
-
- @Test
- public void testHandle_init() {
- Channel channel = createTestChannel();
- ScheduledRecording r = createRecording(channel);
- RecordingTask task = createRecordingTask(r, channel);
- String inputId = channel.getInputId();
- when(mMockSessionManager.createRecordingSession(eq(inputId), anyString(), eq(task),
- eq(mMockHandler), anyLong())).thenReturn(mMockRecordingSession);
- when(mMockHandler.sendMessageAtTime(anyObject(), anyLong())).thenReturn(true);
- assertTrue(task.handleMessage(createMessage(RecordingTask.MSG_INITIALIZE)));
- assertEquals(State.CONNECTION_PENDING, task.getState());
- verify(mMockSessionManager).createRecordingSession(eq(inputId), anyString(), eq(task),
- eq(mMockHandler), anyLong());
- verify(mMockRecordingSession).tune(eq(inputId), eq(channel.getUri()));
- verifyNoMoreInteractions(mMockHandler, mMockRecordingSession, mMockSessionManager);
- }
-
- private static Channel createTestChannel() {
- return new Channel.Builder().setInputId(INPUT_ID).setId(CHANNEL_ID)
- .setDisplayName("Test Ch " + CHANNEL_ID).build();
- }
-
- @Test
- public void testOnConnected() {
- Channel channel = createTestChannel();
- ScheduledRecording r = createRecording(channel);
- mDataManager.addScheduledRecording(r);
- RecordingTask task = createRecordingTask(r, channel);
- String inputId = channel.getInputId();
- when(mMockSessionManager.createRecordingSession(eq(inputId), anyString(), eq(task),
- eq(mMockHandler), anyLong())).thenReturn(mMockRecordingSession);
- when(mMockHandler.sendMessageAtTime(anyObject(), anyLong())).thenReturn(true);
- task.handleMessage(createMessage(RecordingTask.MSG_INITIALIZE));
- task.onTuned(channel.getUri());
- assertEquals(State.CONNECTED, task.getState());
- }
-
- private ScheduledRecording createRecording(Channel c) {
- long startTime = mFakeClock.currentTimeMillis() + START_OFFSET_MS;
- long endTime = startTime + DURATION;
- return RecordingTestUtils.createTestRecordingWithPeriod(c.getInputId(), c.getId(),
- startTime, endTime);
- }
-
- private RecordingTask createRecordingTask(ScheduledRecording r, Channel channel) {
- RecordingTask recordingTask = new RecordingTask(getContext(), r, channel, mDvrManager,
- mMockSessionManager, mDataManager, mFakeClock);
- recordingTask.setHandler(mMockHandler);
- return recordingTask;
- }
-
- private Message createMessage(int what) {
- Message msg = new Message();
- msg.setTarget(mMockHandler);
- msg.what = what;
- return msg;
- }
-} \ No newline at end of file
diff --git a/tests/unit/src/com/android/tv/dvr/recorder/ScheduledProgramReaperTest.java b/tests/unit/src/com/android/tv/dvr/recorder/ScheduledProgramReaperTest.java
deleted file mode 100644
index ca72e13f..00000000
--- a/tests/unit/src/com/android/tv/dvr/recorder/ScheduledProgramReaperTest.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2016 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.dvr.recorder;
-
-import static android.support.test.InstrumentationRegistry.getContext;
-import static org.junit.Assert.assertTrue;
-
-import android.os.Build;
-import android.support.test.filters.SdkSuppress;
-import android.support.test.filters.SmallTest;
-import android.test.MoreAsserts;
-
-import com.android.tv.common.feature.CommonFeatures;
-import com.android.tv.common.feature.TestableFeature;
-import com.android.tv.dvr.DvrDataManagerInMemoryImpl;
-import com.android.tv.dvr.DvrManager;
-import com.android.tv.dvr.data.ScheduledRecording;
-import com.android.tv.testing.FakeClock;
-import com.android.tv.testing.dvr.RecordingTestUtils;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.concurrent.TimeUnit;
-
-/**
- * Tests for {@link ScheduledProgramReaper}.
- */
-@SmallTest
-@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
-public class ScheduledProgramReaperTest {
- private static final String INPUT_ID = "input_id";
- private static final int CHANNEL_ID = 273;
- private static final long DURATION = TimeUnit.HOURS.toMillis(1);
-
- private ScheduledProgramReaper mReaper;
- private FakeClock mFakeClock;
- private DvrDataManagerInMemoryImpl mDvrDataManager;
- @Mock private DvrManager mDvrManager;
- private final TestableFeature mDvrFeature = CommonFeatures.DVR;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- mDvrFeature.enableForTest();
- mFakeClock = FakeClock.createWithTimeOne();
- mDvrDataManager = new DvrDataManagerInMemoryImpl(getContext(), mFakeClock);
- mReaper = new ScheduledProgramReaper(mDvrDataManager, mFakeClock);
- }
-
- @After
- public void tearDown() {
- mDvrFeature.resetForTests();
- }
-
- @Test
- public void testRun_noRecordings() {
- assertTrue(mDvrDataManager.getAllScheduledRecordings().isEmpty());
- mReaper.run();
- assertTrue(mDvrDataManager.getAllScheduledRecordings().isEmpty());
- }
-
- @Test
- public void testRun_oneRecordingsTomorrow() {
- ScheduledRecording recording = addNewScheduledRecordingForTomorrow();
- MoreAsserts
- .assertContentsInAnyOrder(mDvrDataManager.getAllScheduledRecordings(), recording);
- mReaper.run();
- MoreAsserts
- .assertContentsInAnyOrder(mDvrDataManager.getAllScheduledRecordings(), recording);
- }
-
- @Test
- public void testRun_oneRecordingsStarted() {
- ScheduledRecording recording = addNewScheduledRecordingForTomorrow();
- MoreAsserts
- .assertContentsInAnyOrder(mDvrDataManager.getAllScheduledRecordings(), recording);
- mFakeClock.increment(TimeUnit.DAYS);
- mReaper.run();
- MoreAsserts
- .assertContentsInAnyOrder(mDvrDataManager.getAllScheduledRecordings(), recording);
- }
-
- @Test
- public void testRun_oneRecordingsFinished() {
- ScheduledRecording recording = addNewScheduledRecordingForTomorrow();
- MoreAsserts
- .assertContentsInAnyOrder(mDvrDataManager.getAllScheduledRecordings(), recording);
- mFakeClock.increment(TimeUnit.DAYS);
- mFakeClock.increment(TimeUnit.MINUTES, 2);
- mReaper.run();
- MoreAsserts
- .assertContentsInAnyOrder(mDvrDataManager.getAllScheduledRecordings(), recording);
- }
-
- @Test
- public void testRun_oneRecordingsExpired() {
- ScheduledRecording recording = addNewScheduledRecordingForTomorrow();
- MoreAsserts
- .assertContentsInAnyOrder(mDvrDataManager.getAllScheduledRecordings(), recording);
- mFakeClock.increment(TimeUnit.DAYS, 1 + ScheduledProgramReaper.DAYS);
- mFakeClock.increment(TimeUnit.MILLISECONDS, DURATION);
- // After the cutoff and enough so we can see on the clock
- mFakeClock.increment(TimeUnit.SECONDS, 1);
-
- mReaper.run();
- assertTrue("Recordings after reaper at " + com.android.tv.util.Utils
- .toIsoDateTimeString(mFakeClock.currentTimeMillis()),
- mDvrDataManager.getAllScheduledRecordings().isEmpty());
- }
-
- private ScheduledRecording addNewScheduledRecordingForTomorrow() {
- long startTime = mFakeClock.currentTimeMillis() + TimeUnit.DAYS.toMillis(1);
- ScheduledRecording recording = RecordingTestUtils.createTestRecordingWithPeriod(INPUT_ID,
- CHANNEL_ID, startTime, startTime + DURATION);
- return mDvrDataManager.addScheduledRecordingInternal(
- ScheduledRecording.buildFrom(recording)
- .setState(ScheduledRecording.STATE_RECORDING_FINISHED).build());
- }
-}
diff --git a/tests/unit/src/com/android/tv/dvr/recorder/SchedulerTest.java b/tests/unit/src/com/android/tv/dvr/recorder/SchedulerTest.java
deleted file mode 100644
index a5154729..00000000
--- a/tests/unit/src/com/android/tv/dvr/recorder/SchedulerTest.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * 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.dvr.recorder;
-
-import static android.support.test.InstrumentationRegistry.getTargetContext;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-
-import android.app.AlarmManager;
-import android.app.PendingIntent;
-import android.os.Build;
-import android.os.Looper;
-import android.support.test.filters.SdkSuppress;
-import android.support.test.filters.SmallTest;
-
-import com.android.tv.InputSessionManager;
-import com.android.tv.common.feature.CommonFeatures;
-import com.android.tv.common.feature.TestableFeature;
-import com.android.tv.data.ChannelDataManager;
-import com.android.tv.dvr.DvrDataManagerInMemoryImpl;
-import com.android.tv.dvr.DvrManager;
-import com.android.tv.dvr.data.ScheduledRecording;
-import com.android.tv.testing.FakeClock;
-import com.android.tv.testing.dvr.RecordingTestUtils;
-import com.android.tv.util.TvInputManagerHelper;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-
-import java.util.concurrent.TimeUnit;
-
-/**
- * Tests for {@link RecordingScheduler}.
- */
-@SmallTest
-@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
-public class SchedulerTest {
- private static final String INPUT_ID = "input_id";
- private static final int CHANNEL_ID = 273;
-
- private FakeClock mFakeClock;
- private DvrDataManagerInMemoryImpl mDataManager;
- private RecordingScheduler mScheduler;
- @Mock DvrManager mDvrManager;
- @Mock InputSessionManager mSessionManager;
- @Mock AlarmManager mMockAlarmManager;
- @Mock ChannelDataManager mChannelDataManager;
- @Mock TvInputManagerHelper mInputManager;
- private final TestableFeature mDvrFeature = CommonFeatures.DVR;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- mDvrFeature.enableForTest();
- mFakeClock = FakeClock.createWithCurrentTime();
- mDataManager = new DvrDataManagerInMemoryImpl(getTargetContext(), mFakeClock);
- Mockito.when(mChannelDataManager.isDbLoadFinished()).thenReturn(true);
- mScheduler = new RecordingScheduler(Looper.myLooper(), mDvrManager, mSessionManager, mDataManager,
- mChannelDataManager, mInputManager, getTargetContext(), mFakeClock,
- mMockAlarmManager);
- }
-
- @After
- public void tearDown() {
- mDvrFeature.resetForTests();
- }
-
- @Test
- public void testUpdate_none() {
- mScheduler.updateAndStartServiceIfNeeded();
- verifyZeroInteractions(mMockAlarmManager);
- }
-
- @Test
- public void testUpdate_nextIn12Hours() {
- long now = mFakeClock.currentTimeMillis();
- long startTime = now + TimeUnit.HOURS.toMillis(12);
- ScheduledRecording r = RecordingTestUtils
- .createTestRecordingWithPeriod(INPUT_ID, CHANNEL_ID, startTime,
- startTime + TimeUnit.HOURS.toMillis(1));
- mDataManager.addScheduledRecording(r);
- verify(mMockAlarmManager).setExactAndAllowWhileIdle(
- eq(AlarmManager.RTC_WAKEUP),
- eq(startTime - RecordingScheduler.MS_TO_WAKE_BEFORE_START),
- any(PendingIntent.class));
- Mockito.reset(mMockAlarmManager);
- mScheduler.updateAndStartServiceIfNeeded();
- verify(mMockAlarmManager).setExactAndAllowWhileIdle(
- eq(AlarmManager.RTC_WAKEUP),
- eq(startTime - RecordingScheduler.MS_TO_WAKE_BEFORE_START),
- any(PendingIntent.class));
- }
-
- @Test
- public void testStartsWithin() {
- long now = mFakeClock.currentTimeMillis();
- long startTime = now + 3;
- ScheduledRecording r = RecordingTestUtils
- .createTestRecordingWithPeriod(INPUT_ID, CHANNEL_ID, startTime, startTime + 100);
- assertFalse(mScheduler.startsWithin(r, 2));
- assertTrue(mScheduler.startsWithin(r, 3));
- }
-} \ No newline at end of file
diff --git a/tests/unit/src/com/android/tv/dvr/recorder/SeriesRecordingSchedulerTest.java b/tests/unit/src/com/android/tv/dvr/recorder/SeriesRecordingSchedulerTest.java
deleted file mode 100644
index 16fa1baf..00000000
--- a/tests/unit/src/com/android/tv/dvr/recorder/SeriesRecordingSchedulerTest.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2016 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.dvr.recorder;
-
-import static android.support.test.InstrumentationRegistry.getContext;
-
-import android.os.Build;
-import android.support.test.filters.SdkSuppress;
-import android.support.test.filters.SmallTest;
-import android.test.MoreAsserts;
-import android.util.LongSparseArray;
-
-import com.android.tv.common.feature.CommonFeatures;
-import com.android.tv.common.feature.TestableFeature;
-import com.android.tv.data.Program;
-import com.android.tv.dvr.DvrDataManagerInMemoryImpl;
-import com.android.tv.dvr.data.SeriesRecording;
-import com.android.tv.testing.FakeClock;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Tests for {@link SeriesRecordingScheduler}
- */
-@SmallTest
-@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
-public class SeriesRecordingSchedulerTest {
- private static final String PROGRAM_TITLE = "MyProgram";
- private static final long CHANNEL_ID = 123;
- private static final long SERIES_RECORDING_ID1 = 1;
- private static final String SERIES_ID = "SERIES_ID";
- private static final String SEASON_NUMBER1 = "SEASON NUMBER1";
- private static final String SEASON_NUMBER2 = "SEASON NUMBER2";
- private static final String EPISODE_NUMBER1 = "EPISODE NUMBER1";
- private static final String EPISODE_NUMBER2 = "EPISODE NUMBER2";
-
- private final SeriesRecording mBaseSeriesRecording = new SeriesRecording.Builder()
- .setTitle(PROGRAM_TITLE).setChannelId(CHANNEL_ID).setSeriesId(SERIES_ID).build();
- private final Program mBaseProgram = new Program.Builder().setTitle(PROGRAM_TITLE)
- .setChannelId(CHANNEL_ID).setSeriesId(SERIES_ID).build();
- private final TestableFeature mDvrFeature = CommonFeatures.DVR;
-
- private DvrDataManagerInMemoryImpl mDataManager;
-
- @Before
- public void setUp() {
- mDvrFeature.enableForTest();
- FakeClock fakeClock = FakeClock.createWithCurrentTime();
- mDataManager = new DvrDataManagerInMemoryImpl(getContext(), fakeClock);
- }
-
- @After
- public void tearDown() {
- mDvrFeature.resetForTests();
- }
-
- @Test
- public void testPickOneProgramPerEpisode_onePerEpisode() {
- SeriesRecording seriesRecording = SeriesRecording.buildFrom(mBaseSeriesRecording)
- .setId(SERIES_RECORDING_ID1).build();
- mDataManager.addSeriesRecording(seriesRecording);
- List<Program> programs = new ArrayList<>();
- Program program1 = new Program.Builder(mBaseProgram).setSeasonNumber(SEASON_NUMBER1)
- .setEpisodeNumber(EPISODE_NUMBER1).build();
- programs.add(program1);
- Program program2 = new Program.Builder(mBaseProgram).setSeasonNumber(SEASON_NUMBER2)
- .setEpisodeNumber(EPISODE_NUMBER2).build();
- programs.add(program2);
- LongSparseArray<List<Program>> result = SeriesRecordingScheduler.pickOneProgramPerEpisode(
- mDataManager, Collections.singletonList(seriesRecording), programs);
- MoreAsserts.assertContentsInAnyOrder(result.get(SERIES_RECORDING_ID1), program1, program2);
- }
-
- @Test
- public void testPickOneProgramPerEpisode_manyPerEpisode() {
- SeriesRecording seriesRecording = SeriesRecording.buildFrom(mBaseSeriesRecording)
- .setId(SERIES_RECORDING_ID1).build();
- mDataManager.addSeriesRecording(seriesRecording);
- List<Program> programs = new ArrayList<>();
- Program program1 = new Program.Builder(mBaseProgram).setSeasonNumber(SEASON_NUMBER1)
- .setEpisodeNumber(EPISODE_NUMBER1).setStartTimeUtcMillis(0).build();
- programs.add(program1);
- Program program2 = new Program.Builder(program1).setStartTimeUtcMillis(1).build();
- programs.add(program2);
- Program program3 = new Program.Builder(mBaseProgram).setSeasonNumber(SEASON_NUMBER2)
- .setEpisodeNumber(EPISODE_NUMBER2).build();
- programs.add(program3);
- Program program4 = new Program.Builder(program1).setStartTimeUtcMillis(1).build();
- programs.add(program4);
- LongSparseArray<List<Program>> result = SeriesRecordingScheduler.pickOneProgramPerEpisode(
- mDataManager, Collections.singletonList(seriesRecording), programs);
- MoreAsserts.assertContentsInAnyOrder(result.get(SERIES_RECORDING_ID1), program1, program3);
- }
-
- @Test
- public void testPickOneProgramPerEpisode_nullEpisode() {
- SeriesRecording seriesRecording = SeriesRecording.buildFrom(mBaseSeriesRecording)
- .setId(SERIES_RECORDING_ID1).build();
- mDataManager.addSeriesRecording(seriesRecording);
- List<Program> programs = new ArrayList<>();
- Program program1 = new Program.Builder(mBaseProgram).setStartTimeUtcMillis(0).build();
- programs.add(program1);
- Program program2 = new Program.Builder(mBaseProgram).setStartTimeUtcMillis(1).build();
- programs.add(program2);
- LongSparseArray<List<Program>> result = SeriesRecordingScheduler.pickOneProgramPerEpisode(
- mDataManager, Collections.singletonList(seriesRecording), programs);
- MoreAsserts.assertContentsInAnyOrder(result.get(SERIES_RECORDING_ID1), program1, program2);
- }
-}
diff --git a/tests/unit/src/com/android/tv/dvr/ui/SortedArrayAdapterTest.java b/tests/unit/src/com/android/tv/dvr/ui/SortedArrayAdapterTest.java
deleted file mode 100644
index 5667ee6b..00000000
--- a/tests/unit/src/com/android/tv/dvr/ui/SortedArrayAdapterTest.java
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * Copyright (C) 2016 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.dvr.ui;
-
-import android.support.test.filters.SmallTest;
-import android.support.v17.leanback.widget.ClassPresenterSelector;
-import android.support.v17.leanback.widget.ObjectAdapter;
-
-import junit.framework.TestCase;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.Objects;
-
-/**
- * Tests for {@link SortedArrayAdapter}.
- */
-@SmallTest
-public class SortedArrayAdapterTest extends TestCase {
- public static final TestData P1 = TestData.create(1, "c");
- public static final TestData P2 = TestData.create(2, "b");
- public static final TestData P3 = TestData.create(3, "a");
- public static final TestData EXTRA = TestData.create(4, "k");
- private TestSortedArrayAdapter mAdapter;
-
- @Before
- public void setUp() {
- mAdapter = new TestSortedArrayAdapter(Integer.MAX_VALUE, null);
- }
-
- @Test
- public void testContents_empty() {
- assertEmpty();
- }
-
- @Test
- public void testAdd_one() {
- mAdapter.add(P1);
- assertNotEmpty();
- assertContentsInOrder(mAdapter, P1);
- }
-
- @Test
- public void testAdd_two() {
- mAdapter.add(P1);
- mAdapter.add(P2);
- assertNotEmpty();
- assertContentsInOrder(mAdapter, P2, P1);
- }
-
- @Test
- public void testSetInitialItems_two() {
- mAdapter.setInitialItems(Arrays.asList(P1, P2));
- assertNotEmpty();
- assertContentsInOrder(mAdapter, P2, P1);
- }
-
- @Test
- public void testMaxInitialCount() {
- mAdapter = new TestSortedArrayAdapter(1, null);
- mAdapter.setInitialItems(Arrays.asList(P1, P2));
- assertNotEmpty();
- assertEquals(mAdapter.size(), 1);
- assertEquals(mAdapter.get(0), P2);
- }
-
- @Test
- public void testExtraItem() {
- mAdapter = new TestSortedArrayAdapter(Integer.MAX_VALUE, EXTRA);
- mAdapter.setInitialItems(Arrays.asList(P1, P2));
- assertNotEmpty();
- assertEquals(mAdapter.size(), 3);
- assertEquals(mAdapter.get(0), P2);
- assertEquals(mAdapter.get(2), EXTRA);
- mAdapter.remove(P2);
- mAdapter.remove(P1);
- assertEquals(mAdapter.size(), 1);
- assertEquals(mAdapter.get(0), EXTRA);
- }
-
- @Test
- public void testExtraItemWithMaxCount() {
- mAdapter = new TestSortedArrayAdapter(1, EXTRA);
- mAdapter.setInitialItems(Arrays.asList(P1, P2));
- assertNotEmpty();
- assertEquals(mAdapter.size(), 2);
- assertEquals(mAdapter.get(0), P2);
- assertEquals(mAdapter.get(1), EXTRA);
- mAdapter.remove(P2);
- assertEquals(mAdapter.size(), 1);
- assertEquals(mAdapter.get(0), EXTRA);
- }
-
- @Test
- public void testRemove() {
- mAdapter.add(P1);
- mAdapter.add(P2);
- assertNotEmpty();
- assertContentsInOrder(mAdapter, P2, P1);
- mAdapter.remove(P3);
- assertContentsInOrder(mAdapter, P2, P1);
- mAdapter.remove(P2);
- assertContentsInOrder(mAdapter, P1);
- mAdapter.remove(P1);
- assertEmpty();
- mAdapter.add(P1);
- mAdapter.add(P2);
- mAdapter.add(P3);
- assertContentsInOrder(mAdapter, P3, P2, P1);
- mAdapter.removeItems(0, 2);
- assertContentsInOrder(mAdapter, P1);
- mAdapter.add(P2);
- mAdapter.add(P3);
- mAdapter.addExtraItem(EXTRA);
- assertContentsInOrder(mAdapter, P3, P2, P1, EXTRA);
- mAdapter.removeItems(1, 1);
- assertContentsInOrder(mAdapter, P3, P1, EXTRA);
- mAdapter.removeItems(1, 2);
- assertContentsInOrder(mAdapter, P3);
- mAdapter.addExtraItem(EXTRA);
- mAdapter.addExtraItem(P2);
- mAdapter.add(P1);
- assertContentsInOrder(mAdapter, P3, P1, EXTRA, P2);
- mAdapter.removeItems(1, 2);
- assertContentsInOrder(mAdapter, P3, P2);
- mAdapter.add(P1);
- assertContentsInOrder(mAdapter, P3, P1, P2);
- }
-
- @Test
- public void testReplace() {
- mAdapter.add(P1);
- mAdapter.add(P2);
- assertNotEmpty();
- assertContentsInOrder(mAdapter, P2, P1);
- mAdapter.replace(1, P3);
- assertContentsInOrder(mAdapter, P3, P2);
- mAdapter.replace(0, P1);
- assertContentsInOrder(mAdapter, P2, P1);
- mAdapter.addExtraItem(EXTRA);
- assertContentsInOrder(mAdapter, P2, P1, EXTRA);
- mAdapter.replace(2, P3);
- assertContentsInOrder(mAdapter, P2, P1, P3);
- }
-
- @Test
- public void testChange_sorting() {
- TestData p2_changed = TestData.create(2, "z changed");
- mAdapter.add(P1);
- mAdapter.add(P2);
- assertNotEmpty();
- assertContentsInOrder(mAdapter, P2, P1);
- mAdapter.change(p2_changed);
- assertContentsInOrder(mAdapter, P1, p2_changed);
- }
-
- @Test
- public void testChange_new() {
- mAdapter.change(P1);
- assertNotEmpty();
- assertContentsInOrder(mAdapter, P1);
- }
-
- private void assertEmpty() {
- assertEquals("empty", true, mAdapter.isEmpty());
- }
-
- private void assertNotEmpty() {
- assertEquals("empty", false, mAdapter.isEmpty());
- }
-
- private static void assertContentsInOrder(ObjectAdapter adapter, Object... contents) {
- int ex = contents.length;
- assertEquals("size", ex, adapter.size());
- for (int i = 0; i < ex; i++) {
- assertEquals("element " + 1, contents[i], adapter.get(i));
- }
- }
-
- private static class TestData {
- @Override
- public String toString() {
- return "TestData[" + mId + "]{" + mText + '}';
- }
-
- static TestData create(long first, String text) {
- return new TestData(first, text);
- }
-
- private final long mId;
- private final String mText;
-
- private TestData(long id, String second) {
- this.mId = id;
- this.mText = second;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (!(o instanceof TestData)) return false;
- TestData that = (TestData) o;
- return mId == that.mId && Objects.equals(mText, that.mText);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(mId, mText);
- }
- }
-
- private static class TestSortedArrayAdapter extends SortedArrayAdapter<TestData> {
-
- private static final Comparator<TestData> TEXT_COMPARATOR = new Comparator<TestData>() {
- @Override
- public int compare(TestData lhs, TestData rhs) {
- return lhs.mText.compareTo(rhs.mText);
- }
- };
-
- TestSortedArrayAdapter(int maxInitialCount, Object extra) {
- super(new ClassPresenterSelector(), TEXT_COMPARATOR, maxInitialCount);
- if (extra != null) {
- addExtraItem((TestData) extra);
- }
- }
-
- @Override
- protected long getId(TestData item) {
- return item.mId;
- }
- }
-} \ No newline at end of file
diff --git a/tests/unit/src/com/android/tv/experiments/ExperimentsTest.java b/tests/unit/src/com/android/tv/experiments/ExperimentsTest.java
deleted file mode 100644
index 3f827ce1..00000000
--- a/tests/unit/src/com/android/tv/experiments/ExperimentsTest.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2016 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.experiments;
-
-import static org.junit.Assert.assertEquals;
-
-import android.support.test.filters.SmallTest;
-
-import com.android.tv.common.BuildConfig;
-
-import junit.framework.Assert;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Tests for {@link Experiments}.
- */
-@SmallTest
-public class ExperimentsTest {
- @Before
- public void setUp() {
- ExperimentFlag.initForTest();
- }
-
-
- @Test
- public void testEngOnlyDefault() {
- assertEquals("ENABLE_DEVELOPER_FEATURES", Boolean.valueOf(BuildConfig.ENG),
- Experiments.ENABLE_DEVELOPER_FEATURES.get());
- }
-
-
-}
diff --git a/tests/unit/src/com/android/tv/menu/MenuTest.java b/tests/unit/src/com/android/tv/menu/MenuTest.java
index e8cfdbef..028a185d 100644
--- a/tests/unit/src/com/android/tv/menu/MenuTest.java
+++ b/tests/unit/src/com/android/tv/menu/MenuTest.java
@@ -16,24 +16,23 @@
package com.android.tv.menu;
import static android.support.test.InstrumentationRegistry.getTargetContext;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
+import static com.google.common.truth.Truth.assertWithMessage;
import android.support.test.filters.SmallTest;
-
+import android.support.test.runner.AndroidJUnit4;
import com.android.tv.menu.Menu.OnMenuVisibilityChangeListener;
-
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
+import org.junit.runner.RunWith;
import org.mockito.Matchers;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
-/**
- * Tests for {@link Menu}.
- */
+/** Tests for {@link Menu}. */
@SmallTest
+@RunWith(AndroidJUnit4.class)
public class MenuTest {
private Menu mMenu;
private IMenuView mMenuView;
@@ -50,26 +49,27 @@ public class MenuTest {
mMenu.disableAnimationForTest();
}
+ @Ignore("b/73727914")
@Test
public void testScheduleHide() {
mMenu.show(Menu.REASON_NONE);
setMenuVisible(true);
- assertTrue("Hide is not scheduled", mMenu.isHideScheduled());
+ assertWithMessage("Hide is not scheduled").that(mMenu.isHideScheduled()).isTrue();
mMenu.hide(false);
setMenuVisible(false);
- assertFalse("Hide is scheduled", mMenu.isHideScheduled());
+ assertWithMessage("Hide is scheduled").that(mMenu.isHideScheduled()).isFalse();
mMenu.setKeepVisible(true);
mMenu.show(Menu.REASON_NONE);
setMenuVisible(true);
- assertFalse("Hide is scheduled", mMenu.isHideScheduled());
+ assertWithMessage("Hide is scheduled").that(mMenu.isHideScheduled()).isFalse();
mMenu.setKeepVisible(false);
- assertTrue("Hide is not scheduled", mMenu.isHideScheduled());
+ assertWithMessage("Hide is not scheduled").that(mMenu.isHideScheduled()).isTrue();
mMenu.setKeepVisible(true);
- assertFalse("Hide is scheduled", mMenu.isHideScheduled());
+ assertWithMessage("Hide is scheduled").that(mMenu.isHideScheduled()).isFalse();
mMenu.hide(false);
setMenuVisible(false);
- assertFalse("Hide is scheduled", mMenu.isHideScheduled());
+ assertWithMessage("Hide is scheduled").that(mMenu.isHideScheduled()).isFalse();
}
@Test
@@ -83,8 +83,11 @@ public class MenuTest {
Mockito.verify(mVisibilityChangeListener, Mockito.never())
.onMenuVisibilityChange(Matchers.eq(false));
// IMenuView.show should be called with the same parameter.
- Mockito.verify(mMenuView).onShow(Matchers.eq(Menu.REASON_NONE),
- Matchers.isNull(String.class), Matchers.isNull(Runnable.class));
+ Mockito.verify(mMenuView)
+ .onShow(
+ Matchers.eq(Menu.REASON_NONE),
+ Matchers.isNull(String.class),
+ Matchers.isNull(Runnable.class));
mMenu.hide(true);
setMenuVisible(false);
// Listener should be called with "false" argument.
@@ -104,8 +107,11 @@ public class MenuTest {
Mockito.verify(mVisibilityChangeListener, Mockito.never())
.onMenuVisibilityChange(Matchers.eq(false));
// IMenuView.show should be called with the same parameter.
- Mockito.verify(mMenuView).onShow(Matchers.eq(Menu.REASON_GUIDE),
- Matchers.eq(ChannelsRow.ID), Matchers.isNull(Runnable.class));
+ Mockito.verify(mMenuView)
+ .onShow(
+ Matchers.eq(Menu.REASON_GUIDE),
+ Matchers.eq(ChannelsRow.ID),
+ Matchers.isNull(Runnable.class));
mMenu.hide(false);
setMenuVisible(false);
// Listener should be called with "false" argument.
@@ -125,8 +131,11 @@ public class MenuTest {
Mockito.verify(mVisibilityChangeListener, Mockito.never())
.onMenuVisibilityChange(Matchers.eq(false));
// IMenuView.show should be called with the same parameter.
- Mockito.verify(mMenuView).onShow(Matchers.eq(Menu.REASON_PLAY_CONTROLS_FAST_FORWARD),
- Matchers.eq(PlayControlsRow.ID), Matchers.isNull(Runnable.class));
+ Mockito.verify(mMenuView)
+ .onShow(
+ Matchers.eq(Menu.REASON_PLAY_CONTROLS_FAST_FORWARD),
+ Matchers.eq(PlayControlsRow.ID),
+ Matchers.isNull(Runnable.class));
mMenu.hide(false);
setMenuVisible(false);
// Listener should be called with "false" argument.
@@ -136,11 +145,13 @@ public class MenuTest {
}
private void setMenuVisible(final boolean visible) {
- Mockito.when(mMenuView.isVisible()).thenAnswer(new Answer<Boolean>() {
- @Override
- public Boolean answer(InvocationOnMock invocation) throws Throwable {
- return visible;
- }
- });
+ Mockito.when(mMenuView.isVisible())
+ .thenAnswer(
+ new Answer<Boolean>() {
+ @Override
+ public Boolean answer(InvocationOnMock invocation) throws Throwable {
+ return visible;
+ }
+ });
}
}
diff --git a/tests/unit/src/com/android/tv/menu/TvOptionsRowAdapterTest.java b/tests/unit/src/com/android/tv/menu/TvOptionsRowAdapterTest.java
index 49ba8514..0f815a7a 100644
--- a/tests/unit/src/com/android/tv/menu/TvOptionsRowAdapterTest.java
+++ b/tests/unit/src/com/android/tv/menu/TvOptionsRowAdapterTest.java
@@ -16,30 +16,28 @@
package com.android.tv.menu;
import static android.support.test.InstrumentationRegistry.getInstrumentation;
-import static org.junit.Assert.assertEquals;
+import static com.google.common.truth.Truth.assertWithMessage;
import static org.junit.Assert.fail;
import android.media.tv.TvTrackInfo;
import android.os.SystemClock;
import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
import android.text.TextUtils;
-
-import com.android.tv.BaseMainActivityTestCase;
-import com.android.tv.testing.Constants;
+import com.android.tv.testing.activities.BaseMainActivityTestCase;
+import com.android.tv.testing.constants.Constants;
import com.android.tv.testing.testinput.ChannelState;
import com.android.tv.testing.testinput.ChannelStateData;
import com.android.tv.testing.testinput.TvTestInputConstants;
-
-import org.junit.Before;
-import org.junit.Test;
-
import java.util.Collections;
import java.util.List;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
-/**
- * Tests for {@link TvOptionsRowAdapter}.
- */
+/** Tests for {@link TvOptionsRowAdapter}. */
@MediumTest
+@RunWith(AndroidJUnit4.class)
public class TvOptionsRowAdapterTest extends BaseMainActivityTestCase {
private static final int WAIT_TRACK_EVENT_TIMEOUT_MS = 300;
public static final int TRACK_CHECK_INTERVAL_MS = 10;
@@ -56,12 +54,14 @@ public class TvOptionsRowAdapterTest extends BaseMainActivityTestCase {
waitUntilAudioTracksHaveSize(1);
waitUntilAudioTrackSelected(ChannelState.DEFAULT.getSelectedAudioTrackId());
// update should be called on the main thread to avoid the multi-thread problem.
- getInstrumentation().runOnMainSync(new Runnable() {
- @Override
- public void run() {
- mTvOptionsRowAdapter.update();
- }
- });
+ getInstrumentation()
+ .runOnMainSync(
+ new Runnable() {
+ @Override
+ public void run() {
+ mTvOptionsRowAdapter.update();
+ }
+ });
}
@Test
@@ -73,9 +73,10 @@ public class TvOptionsRowAdapterTest extends BaseMainActivityTestCase {
waitUntilAudioTrackSelected(Constants.EN_STEREO_AUDIO_TRACK.getId());
boolean result = mTvOptionsRowAdapter.updateMultiAudioAction();
- assertEquals("update Action had change", true, result);
- assertEquals("Multi Audio enabled", true,
- MenuAction.SELECT_AUDIO_LANGUAGE_ACTION.isEnabled());
+ assertWithMessage("update Action had change").that(result).isTrue();
+ assertWithMessage("Multi Audio enabled")
+ .that(MenuAction.SELECT_AUDIO_LANGUAGE_ACTION.isEnabled())
+ .isTrue();
}
@Test
@@ -90,9 +91,10 @@ public class TvOptionsRowAdapterTest extends BaseMainActivityTestCase {
waitUntilAudioTrackSelected(Constants.GENERIC_AUDIO_TRACK.getId());
boolean result = mTvOptionsRowAdapter.updateMultiAudioAction();
- assertEquals("update Action had change", true, result);
- assertEquals("Multi Audio enabled", false,
- MenuAction.SELECT_AUDIO_LANGUAGE_ACTION.isEnabled());
+ assertWithMessage("update Action had change").that(result).isTrue();
+ assertWithMessage("Multi Audio enabled")
+ .that(MenuAction.SELECT_AUDIO_LANGUAGE_ACTION.isEnabled())
+ .isFalse();
}
@Test
@@ -108,9 +110,10 @@ public class TvOptionsRowAdapterTest extends BaseMainActivityTestCase {
waitUntilVideoTrackSelected(data.mSelectedVideoTrackId);
boolean result = mTvOptionsRowAdapter.updateMultiAudioAction();
- assertEquals("update Action had change", true, result);
- assertEquals("Multi Audio enabled", false,
- MenuAction.SELECT_AUDIO_LANGUAGE_ACTION.isEnabled());
+ assertWithMessage("update Action had change").that(result).isTrue();
+ assertWithMessage("Multi Audio enabled")
+ .that(MenuAction.SELECT_AUDIO_LANGUAGE_ACTION.isEnabled())
+ .isFalse();
}
private void waitUntilAudioTracksHaveSize(int expected) {
@@ -135,8 +138,13 @@ public class TvOptionsRowAdapterTest extends BaseMainActivityTestCase {
}
SystemClock.sleep(TRACK_CHECK_INTERVAL_MS);
}
- fail("Waited for " + WAIT_TRACK_EVENT_TIMEOUT_MS + " milliseconds for track size to be "
- + expected + " but was " + size);
+ fail(
+ "Waited for "
+ + WAIT_TRACK_EVENT_TIMEOUT_MS
+ + " milliseconds for track size to be "
+ + expected
+ + " but was "
+ + size);
}
private void waitUntilAudioTrackSelected(String trackId) {
@@ -158,7 +166,12 @@ public class TvOptionsRowAdapterTest extends BaseMainActivityTestCase {
}
SystemClock.sleep(TRACK_CHECK_INTERVAL_MS);
}
- fail("Waited for " + WAIT_TRACK_EVENT_TIMEOUT_MS + " milliseconds for track ID to be "
- + trackId + " but was " + selectedTrackId);
+ fail(
+ "Waited for "
+ + WAIT_TRACK_EVENT_TIMEOUT_MS
+ + " milliseconds for track ID to be "
+ + trackId
+ + " but was "
+ + selectedTrackId);
}
}
diff --git a/tests/unit/src/com/android/tv/recommendation/ChannelRecordTest.java b/tests/unit/src/com/android/tv/recommendation/ChannelRecordTest.java
index db765109..e63bdc3a 100644
--- a/tests/unit/src/com/android/tv/recommendation/ChannelRecordTest.java
+++ b/tests/unit/src/com/android/tv/recommendation/ChannelRecordTest.java
@@ -17,22 +17,20 @@
package com.android.tv.recommendation;
import static android.support.test.InstrumentationRegistry.getContext;
-import static org.junit.Assert.assertEquals;
+import static com.google.common.truth.Truth.assertThat;
import android.support.test.filters.SmallTest;
-
-import com.android.tv.testing.Utils;
-
-import org.junit.Before;
-import org.junit.Test;
-
+import android.support.test.runner.AndroidJUnit4;
+import com.android.tv.testing.utils.Utils;
import java.util.Random;
import java.util.concurrent.TimeUnit;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
-/**
- * Unit tests for {@link ChannelRecord}.
- */
+/** Unit tests for {@link ChannelRecord}. */
@SmallTest
+@RunWith(AndroidJUnit4.class)
public class ChannelRecordTest {
private static final int CHANNEL_RECORD_MAX_HISTORY_SIZE = ChannelRecord.MAX_HISTORY_SIZE;
@@ -49,14 +47,14 @@ public class ChannelRecordTest {
@Test
public void testGetLastWatchEndTime_noHistory() {
- assertEquals(0, mChannelRecord.getLastWatchEndTimeMs());
+ assertThat(mChannelRecord.getLastWatchEndTimeMs()).isEqualTo(0);
}
@Test
public void testGetLastWatchEndTime_oneHistory() {
addWatchLog();
- assertEquals(mLatestWatchEndTimeMs, mChannelRecord.getLastWatchEndTimeMs());
+ assertThat(mChannelRecord.getLastWatchEndTimeMs()).isEqualTo(mLatestWatchEndTimeMs);
}
@Test
@@ -65,7 +63,7 @@ public class ChannelRecordTest {
addWatchLog();
}
- assertEquals(mLatestWatchEndTimeMs, mChannelRecord.getLastWatchEndTimeMs());
+ assertThat(mChannelRecord.getLastWatchEndTimeMs()).isEqualTo(mLatestWatchEndTimeMs);
}
@Test
@@ -74,19 +72,19 @@ public class ChannelRecordTest {
addWatchLog();
}
- assertEquals(mLatestWatchEndTimeMs, mChannelRecord.getLastWatchEndTimeMs());
+ assertThat(mChannelRecord.getLastWatchEndTimeMs()).isEqualTo(mLatestWatchEndTimeMs);
}
@Test
public void testGetTotalWatchDuration_noHistory() {
- assertEquals(0, mChannelRecord.getTotalWatchDurationMs());
+ assertThat(mChannelRecord.getTotalWatchDurationMs()).isEqualTo(0);
}
@Test
public void testGetTotalWatchDuration_oneHistory() {
long durationMs = addWatchLog();
- assertEquals(durationMs, mChannelRecord.getTotalWatchDurationMs());
+ assertThat(mChannelRecord.getTotalWatchDurationMs()).isEqualTo(durationMs);
}
@Test
@@ -97,7 +95,7 @@ public class ChannelRecordTest {
totalWatchTimeMs += durationMs;
}
- assertEquals(totalWatchTimeMs, mChannelRecord.getTotalWatchDurationMs());
+ assertThat(mChannelRecord.getTotalWatchDurationMs()).isEqualTo(totalWatchTimeMs);
}
@Test
@@ -112,8 +110,9 @@ public class ChannelRecordTest {
}
}
- // Only latest CHANNEL_RECORD_MAX_HISTORY_SIZE logs are remained.
- assertEquals(totalWatchTimeMs - firstDurationMs, mChannelRecord.getTotalWatchDurationMs());
+ // Only latest CHANNEL_RECORD_MAX_HISTORY_SIZE logs are remained.
+ assertThat(mChannelRecord.getTotalWatchDurationMs())
+ .isEqualTo(totalWatchTimeMs - firstDurationMs);
}
/**
@@ -126,8 +125,9 @@ public class ChannelRecordTest {
mLatestWatchEndTimeMs += TimeUnit.SECONDS.toMillis(mRandom.nextInt(60) + 1);
long durationMs = TimeUnit.SECONDS.toMillis(mRandom.nextInt(60) + 1);
- mChannelRecord.logWatchHistory(new WatchedProgram(null,
- mLatestWatchEndTimeMs, mLatestWatchEndTimeMs + durationMs));
+ mChannelRecord.logWatchHistory(
+ new WatchedProgram(
+ null, mLatestWatchEndTimeMs, mLatestWatchEndTimeMs + durationMs));
mLatestWatchEndTimeMs += durationMs;
return durationMs;
diff --git a/tests/unit/src/com/android/tv/recommendation/EvaluatorTestCase.java b/tests/unit/src/com/android/tv/recommendation/EvaluatorTestCase.java
index 853fb245..f62a5e05 100644
--- a/tests/unit/src/com/android/tv/recommendation/EvaluatorTestCase.java
+++ b/tests/unit/src/com/android/tv/recommendation/EvaluatorTestCase.java
@@ -20,19 +20,15 @@ import static android.support.test.InstrumentationRegistry.getContext;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
-import com.android.tv.data.Channel;
+import com.android.tv.data.api.Channel;
import com.android.tv.recommendation.RecommendationUtils.ChannelRecordSortedMapHelper;
import com.android.tv.recommendation.Recommender.Evaluator;
-import com.android.tv.testing.Utils;
-
-import org.junit.Before;
-
+import com.android.tv.testing.utils.Utils;
import java.util.ArrayList;
import java.util.List;
+import org.junit.Before;
-/**
- * Base test case for Recommendation Evaluator Unit tests.
- */
+/** Base test case for Recommendation Evaluator Unit tests. */
public abstract class EvaluatorTestCase<T extends Evaluator> {
private static final long INVALID_CHANNEL_ID = -1;
@@ -46,8 +42,8 @@ public abstract class EvaluatorTestCase<T extends Evaluator> {
@Before
public void setUp() {
mChannelRecordSortedMap = new ChannelRecordSortedMapHelper(getContext());
- mDataManager = RecommendationUtils
- .createMockRecommendationDataManager(mChannelRecordSortedMap);
+ mDataManager =
+ RecommendationUtils.createMockRecommendationDataManager(mChannelRecordSortedMap);
Recommender mRecommender = new FakeRecommender();
mEvaluator = createEvaluator();
mEvaluator.setRecommender(mRecommender);
@@ -55,9 +51,7 @@ public abstract class EvaluatorTestCase<T extends Evaluator> {
mChannelRecordSortedMap.resetRandom(Utils.createTestRandom());
}
- /**
- * Each evaluator test has to create Evaluator in {@code mEvaluator}.
- */
+ /** Each evaluator test has to create Evaluator in {@code mEvaluator}. */
public abstract T createEvaluator();
public void addChannels(int numberOfChannels) {
@@ -68,15 +62,16 @@ public abstract class EvaluatorTestCase<T extends Evaluator> {
return mChannelRecordSortedMap.addChannel();
}
- public void addRandomWatchLogs(long watchStartTimeMs, long watchEndTimeMs,
- long maxWatchDurationMs) {
- assertTrue(mChannelRecordSortedMap.addRandomWatchLogs(watchStartTimeMs, watchEndTimeMs,
- maxWatchDurationMs));
+ public void addRandomWatchLogs(
+ long watchStartTimeMs, long watchEndTimeMs, long maxWatchDurationMs) {
+ assertTrue(
+ mChannelRecordSortedMap.addRandomWatchLogs(
+ watchStartTimeMs, watchEndTimeMs, maxWatchDurationMs));
}
public void addWatchLog(long channelId, long watchStartTimeMs, long durationTimeMs) {
- assertTrue(mChannelRecordSortedMap.addWatchLog(channelId, watchStartTimeMs,
- durationTimeMs));
+ assertTrue(
+ mChannelRecordSortedMap.addWatchLog(channelId, watchStartTimeMs, durationTimeMs));
}
public List<Long> getChannelIdListSorted() {
@@ -86,31 +81,29 @@ public abstract class EvaluatorTestCase<T extends Evaluator> {
public long getLatestWatchEndTimeMs() {
long latestWatchEndTimeMs = 0;
for (ChannelRecord channelRecord : mChannelRecordSortedMap.values()) {
- latestWatchEndTimeMs = Math.max(latestWatchEndTimeMs,
- channelRecord.getLastWatchEndTimeMs());
+ latestWatchEndTimeMs =
+ Math.max(latestWatchEndTimeMs, channelRecord.getLastWatchEndTimeMs());
}
return latestWatchEndTimeMs;
}
- /**
- * Check whether scores of each channels are valid.
- */
+ /** Check whether scores of each channels are valid. */
protected void assertChannelScoresValid() {
- assertEqualScores(Evaluator.NOT_RECOMMENDED,
- mEvaluator.evaluateChannel(INVALID_CHANNEL_ID));
- assertEqualScores(Evaluator.NOT_RECOMMENDED,
+ assertEqualScores(
+ Evaluator.NOT_RECOMMENDED, mEvaluator.evaluateChannel(INVALID_CHANNEL_ID));
+ assertEqualScores(
+ Evaluator.NOT_RECOMMENDED,
mEvaluator.evaluateChannel(mChannelRecordSortedMap.size()));
for (long channelId : mChannelRecordSortedMap.keySet()) {
double score = mEvaluator.evaluateChannel(channelId);
- assertTrue("Channel " + channelId + " score of " + score + "is not valid",
+ assertTrue(
+ "Channel " + channelId + " score of " + score + "is not valid",
score == Evaluator.NOT_RECOMMENDED || (0.0 <= score && score <= 1.0));
}
}
- /**
- * Notify that loading channels and watch logs are finished.
- */
+ /** Notify that loading channels and watch logs are finished. */
protected void notifyChannelAndWatchLogLoaded() {
mEvaluator.onChannelRecordListChanged(new ArrayList<>(mChannelRecordSortedMap.values()));
}
@@ -125,15 +118,16 @@ public abstract class EvaluatorTestCase<T extends Evaluator> {
private class FakeRecommender extends Recommender {
public FakeRecommender() {
- super(new Recommender.Listener() {
- @Override
- public void onRecommenderReady() {
- }
-
- @Override
- public void onRecommendationChanged() {
- }
- }, true, mDataManager);
+ super(
+ new Recommender.Listener() {
+ @Override
+ public void onRecommenderReady() {}
+
+ @Override
+ public void onRecommendationChanged() {}
+ },
+ true,
+ mDataManager);
}
@Override
diff --git a/tests/unit/src/com/android/tv/recommendation/FavoriteChannelEvaluatorTest.java b/tests/unit/src/com/android/tv/recommendation/FavoriteChannelEvaluatorTest.java
index ac701af9..e14320f0 100644
--- a/tests/unit/src/com/android/tv/recommendation/FavoriteChannelEvaluatorTest.java
+++ b/tests/unit/src/com/android/tv/recommendation/FavoriteChannelEvaluatorTest.java
@@ -16,19 +16,18 @@
package com.android.tv.recommendation;
-import static org.junit.Assert.assertTrue;
+import static com.google.common.truth.Truth.assertThat;
import android.support.test.filters.SmallTest;
-
-import org.junit.Test;
-
+import android.support.test.runner.AndroidJUnit4;
import java.util.List;
import java.util.concurrent.TimeUnit;
+import org.junit.Test;
+import org.junit.runner.RunWith;
-/**
- * Unit tests for {@link FavoriteChannelEvaluator}.
- */
+/** Unit tests for {@link FavoriteChannelEvaluator}. */
@SmallTest
+@RunWith(AndroidJUnit4.class)
public class FavoriteChannelEvaluatorTest extends EvaluatorTestCase<FavoriteChannelEvaluator> {
private static final int DEFAULT_NUMBER_OF_CHANNELS = 4;
private static final long DEFAULT_WATCH_START_TIME_MS =
@@ -47,14 +46,16 @@ public class FavoriteChannelEvaluatorTest extends EvaluatorTestCase<FavoriteChan
long channelId = addChannel().getId();
notifyChannelAndWatchLogLoaded();
- assertEqualScores(Recommender.Evaluator.NOT_RECOMMENDED,
- mEvaluator.evaluateChannel(channelId));
+ assertEqualScores(
+ Recommender.Evaluator.NOT_RECOMMENDED, mEvaluator.evaluateChannel(channelId));
}
@Test
public void testOneChannelWithRandomWatchLogs() {
addChannel();
- addRandomWatchLogs(DEFAULT_WATCH_START_TIME_MS, DEFAULT_WATCH_END_TIME_MS,
+ addRandomWatchLogs(
+ DEFAULT_WATCH_START_TIME_MS,
+ DEFAULT_WATCH_END_TIME_MS,
DEFAULT_MAX_WATCH_DURATION_MS);
notifyChannelAndWatchLogLoaded();
@@ -68,15 +69,17 @@ public class FavoriteChannelEvaluatorTest extends EvaluatorTestCase<FavoriteChan
List<Long> channelIdList = getChannelIdListSorted();
for (long channelId : channelIdList) {
- assertEqualScores(Recommender.Evaluator.NOT_RECOMMENDED,
- mEvaluator.evaluateChannel(channelId));
+ assertEqualScores(
+ Recommender.Evaluator.NOT_RECOMMENDED, mEvaluator.evaluateChannel(channelId));
}
}
@Test
public void testMultiChannelsWithRandomWatchLogs() {
addChannels(DEFAULT_NUMBER_OF_CHANNELS);
- addRandomWatchLogs(DEFAULT_WATCH_START_TIME_MS, DEFAULT_WATCH_END_TIME_MS,
+ addRandomWatchLogs(
+ DEFAULT_WATCH_START_TIME_MS,
+ DEFAULT_WATCH_END_TIME_MS,
DEFAULT_MAX_WATCH_DURATION_MS);
notifyChannelAndWatchLogLoaded();
@@ -103,7 +106,7 @@ public class FavoriteChannelEvaluatorTest extends EvaluatorTestCase<FavoriteChan
double previousScore = Recommender.Evaluator.NOT_RECOMMENDED;
for (long channelId : channelIdList) {
double score = mEvaluator.evaluateChannel(channelId);
- assertTrue(previousScore <= score);
+ assertThat(previousScore).isAtMost(score);
previousScore = score;
}
}
@@ -112,40 +115,54 @@ public class FavoriteChannelEvaluatorTest extends EvaluatorTestCase<FavoriteChan
public void testTwoChannelsWithSameWatchDuration() {
long channelOne = addChannel().getId();
long channelTwo = addChannel().getId();
- addWatchLog(channelOne, System.currentTimeMillis() - TimeUnit.HOURS.toMillis(1),
+ addWatchLog(
+ channelOne,
+ System.currentTimeMillis() - TimeUnit.HOURS.toMillis(1),
TimeUnit.MINUTES.toMillis(30));
- addWatchLog(channelTwo, System.currentTimeMillis() - TimeUnit.MINUTES.toMillis(30),
+ addWatchLog(
+ channelTwo,
+ System.currentTimeMillis() - TimeUnit.MINUTES.toMillis(30),
TimeUnit.MINUTES.toMillis(30));
notifyChannelAndWatchLogLoaded();
- assertTrue(mEvaluator.evaluateChannel(channelOne) ==
- mEvaluator.evaluateChannel(channelTwo));
+ assertThat(mEvaluator.evaluateChannel(channelOne) == mEvaluator.evaluateChannel(channelTwo))
+ .isTrue();
}
@Test
public void testTwoChannelsWithDifferentWatchDuration() {
long channelOne = addChannel().getId();
long channelTwo = addChannel().getId();
- addWatchLog(channelOne, System.currentTimeMillis() - TimeUnit.HOURS.toMillis(3),
+ addWatchLog(
+ channelOne,
+ System.currentTimeMillis() - TimeUnit.HOURS.toMillis(3),
TimeUnit.MINUTES.toMillis(30));
- addWatchLog(channelTwo, System.currentTimeMillis() - TimeUnit.HOURS.toMillis(2),
+ addWatchLog(
+ channelTwo,
+ System.currentTimeMillis() - TimeUnit.HOURS.toMillis(2),
TimeUnit.HOURS.toMillis(1));
notifyChannelAndWatchLogLoaded();
- // Channel two was watched longer than channel one, so it's score is bigger.
- assertTrue(mEvaluator.evaluateChannel(channelOne) < mEvaluator.evaluateChannel(channelTwo));
+ // Channel two was watched longer than channel one, so it's score is bigger.
+ assertThat(mEvaluator.evaluateChannel(channelOne))
+ .isLessThan(mEvaluator.evaluateChannel(channelTwo));
- addWatchLog(channelOne, System.currentTimeMillis() - TimeUnit.HOURS.toMillis(1),
+ addWatchLog(
+ channelOne,
+ System.currentTimeMillis() - TimeUnit.HOURS.toMillis(1),
TimeUnit.HOURS.toMillis(1));
- // Now, channel one was watched longer than channel two, so it's score is bigger.
- assertTrue(mEvaluator.evaluateChannel(channelOne) > mEvaluator.evaluateChannel(channelTwo));
+ // Now, channel one was watched longer than channel two, so it's score is bigger.
+ assertThat(mEvaluator.evaluateChannel(channelOne))
+ .isGreaterThan(mEvaluator.evaluateChannel(channelTwo));
}
@Test
public void testScoreIncreasesWithNewWatchLog() {
long channelId = addChannel().getId();
- addRandomWatchLogs(DEFAULT_WATCH_START_TIME_MS, DEFAULT_WATCH_END_TIME_MS,
+ addRandomWatchLogs(
+ DEFAULT_WATCH_START_TIME_MS,
+ DEFAULT_WATCH_END_TIME_MS,
DEFAULT_MAX_WATCH_DURATION_MS);
notifyChannelAndWatchLogLoaded();
@@ -154,7 +171,7 @@ public class FavoriteChannelEvaluatorTest extends EvaluatorTestCase<FavoriteChan
addWatchLog(channelId, latestWatchEndTimeMs, TimeUnit.MINUTES.toMillis(10));
- // Score must be increased because total watch duration of the channel increases.
- assertTrue(previousScore <= mEvaluator.evaluateChannel(channelId));
+ // Score must be increased because total watch duration of the channel increases.
+ assertThat(previousScore).isAtMost(mEvaluator.evaluateChannel(channelId));
}
}
diff --git a/tests/unit/src/com/android/tv/recommendation/RecentChannelEvaluatorTest.java b/tests/unit/src/com/android/tv/recommendation/RecentChannelEvaluatorTest.java
index 8f092238..f8d6b220 100644
--- a/tests/unit/src/com/android/tv/recommendation/RecentChannelEvaluatorTest.java
+++ b/tests/unit/src/com/android/tv/recommendation/RecentChannelEvaluatorTest.java
@@ -16,21 +16,20 @@
package com.android.tv.recommendation;
-import static org.junit.Assert.assertTrue;
+import static com.google.common.truth.Truth.assertThat;
import android.support.test.filters.SmallTest;
-
-import org.junit.Test;
-
+import android.support.test.runner.AndroidJUnit4;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
+import org.junit.Test;
+import org.junit.runner.RunWith;
-/**
- * Unit tests for {@link RecentChannelEvaluator}.
- */
+/** Unit tests for {@link RecentChannelEvaluator}. */
@SmallTest
+@RunWith(AndroidJUnit4.class)
public class RecentChannelEvaluatorTest extends EvaluatorTestCase<RecentChannelEvaluator> {
private static final int DEFAULT_NUMBER_OF_CHANNELS = 4;
private static final long DEFAULT_WATCH_START_TIME_MS =
@@ -49,14 +48,16 @@ public class RecentChannelEvaluatorTest extends EvaluatorTestCase<RecentChannelE
long channelId = addChannel().getId();
notifyChannelAndWatchLogLoaded();
- assertEqualScores(Recommender.Evaluator.NOT_RECOMMENDED,
- mEvaluator.evaluateChannel(channelId));
+ assertEqualScores(
+ Recommender.Evaluator.NOT_RECOMMENDED, mEvaluator.evaluateChannel(channelId));
}
@Test
public void testOneChannelWithRandomWatchLogs() {
addChannel();
- addRandomWatchLogs(DEFAULT_WATCH_START_TIME_MS, DEFAULT_WATCH_END_TIME_MS,
+ addRandomWatchLogs(
+ DEFAULT_WATCH_START_TIME_MS,
+ DEFAULT_WATCH_END_TIME_MS,
DEFAULT_MAX_WATCH_DURATION_MS);
notifyChannelAndWatchLogLoaded();
@@ -70,15 +71,17 @@ public class RecentChannelEvaluatorTest extends EvaluatorTestCase<RecentChannelE
List<Long> channelIdList = getChannelIdListSorted();
for (long channelId : channelIdList) {
- assertEqualScores(Recommender.Evaluator.NOT_RECOMMENDED,
- mEvaluator.evaluateChannel(channelId));
+ assertEqualScores(
+ Recommender.Evaluator.NOT_RECOMMENDED, mEvaluator.evaluateChannel(channelId));
}
}
@Test
public void testMultiChannelsWithRandomWatchLogs() {
addChannels(DEFAULT_NUMBER_OF_CHANNELS);
- addRandomWatchLogs(DEFAULT_WATCH_START_TIME_MS, DEFAULT_WATCH_END_TIME_MS,
+ addRandomWatchLogs(
+ DEFAULT_WATCH_START_TIME_MS,
+ DEFAULT_WATCH_END_TIME_MS,
DEFAULT_MAX_WATCH_DURATION_MS);
notifyChannelAndWatchLogLoaded();
@@ -103,7 +106,7 @@ public class RecentChannelEvaluatorTest extends EvaluatorTestCase<RecentChannelE
double previousScore = Recommender.Evaluator.NOT_RECOMMENDED;
for (long channelId : channelIdList) {
double score = mEvaluator.evaluateChannel(channelId);
- assertTrue(previousScore <= score);
+ assertThat(previousScore).isAtMost(score);
previousScore = score;
}
}
@@ -111,7 +114,9 @@ public class RecentChannelEvaluatorTest extends EvaluatorTestCase<RecentChannelE
@Test
public void testScoreIncreasesWithNewWatchLog() {
addChannels(DEFAULT_NUMBER_OF_CHANNELS);
- addRandomWatchLogs(DEFAULT_WATCH_START_TIME_MS, DEFAULT_WATCH_END_TIME_MS,
+ addRandomWatchLogs(
+ DEFAULT_WATCH_START_TIME_MS,
+ DEFAULT_WATCH_END_TIME_MS,
DEFAULT_MAX_WATCH_DURATION_MS);
notifyChannelAndWatchLogLoaded();
@@ -124,15 +129,17 @@ public class RecentChannelEvaluatorTest extends EvaluatorTestCase<RecentChannelE
addWatchLog(channelId, latestWatchEndTimeMs, durationMs);
latestWatchEndTimeMs += durationMs;
- // Score must be increased because recentness of the log increases.
- assertTrue(previousScore <= mEvaluator.evaluateChannel(channelId));
+ // Score must be increased because recentness of the log increases.
+ assertThat(previousScore).isAtMost(mEvaluator.evaluateChannel(channelId));
}
}
@Test
public void testScoreDecreasesWithIncrementOfWatchedLogUpdatedTime() {
addChannels(DEFAULT_NUMBER_OF_CHANNELS);
- addRandomWatchLogs(DEFAULT_WATCH_START_TIME_MS, DEFAULT_WATCH_END_TIME_MS,
+ addRandomWatchLogs(
+ DEFAULT_WATCH_START_TIME_MS,
+ DEFAULT_WATCH_END_TIME_MS,
DEFAULT_MAX_WATCH_DURATION_MS);
notifyChannelAndWatchLogLoaded();
@@ -148,8 +155,8 @@ public class RecentChannelEvaluatorTest extends EvaluatorTestCase<RecentChannelE
addWatchLog(newChannelId, latestWatchedEndTimeMs, TimeUnit.MINUTES.toMillis(10));
for (long channelId : channelIdList) {
- // Score must be decreased because LastWatchLogUpdateTime increases by new log.
- assertTrue(mEvaluator.evaluateChannel(channelId) <= scores.get(channelId));
+ // Score must be decreased because LastWatchLogUpdateTime increases by new log.
+ assertThat(mEvaluator.evaluateChannel(channelId)).isAtMost(scores.get(channelId));
}
}
}
diff --git a/tests/unit/src/com/android/tv/recommendation/RecommendationUtils.java b/tests/unit/src/com/android/tv/recommendation/RecommendationUtils.java
index b00ed16b..b929a0ae 100644
--- a/tests/unit/src/com/android/tv/recommendation/RecommendationUtils.java
+++ b/tests/unit/src/com/android/tv/recommendation/RecommendationUtils.java
@@ -17,50 +17,57 @@
package com.android.tv.recommendation;
import android.content.Context;
-
-import com.android.tv.data.Channel;
-import com.android.tv.testing.Utils;
-
-import org.mockito.Matchers;
-import org.mockito.Mockito;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-
+import com.android.tv.data.ChannelImpl;
+import com.android.tv.data.api.Channel;
+import com.android.tv.testing.utils.Utils;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Random;
import java.util.TreeMap;
import java.util.concurrent.TimeUnit;
+import org.mockito.Matchers;
+import org.mockito.Mockito;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
public class RecommendationUtils {
private static final long INVALID_CHANNEL_ID = -1;
- /**
- * Create a mock RecommendationDataManager backed by a {@link ChannelRecordSortedMapHelper}.
- */
+ /** Create a mock RecommendationDataManager backed by a {@link ChannelRecordSortedMapHelper}. */
public static RecommendationDataManager createMockRecommendationDataManager(
final ChannelRecordSortedMapHelper channelRecordSortedMap) {
RecommendationDataManager dataManager = Mockito.mock(RecommendationDataManager.class);
- Mockito.doAnswer(new Answer<Integer>() {
- @Override
- public Integer answer(InvocationOnMock invocation) throws Throwable {
- return channelRecordSortedMap.size();
- }
- }).when(dataManager).getChannelRecordCount();
- Mockito.doAnswer(new Answer<Collection<ChannelRecord>>() {
- @Override
- public Collection<ChannelRecord> answer(InvocationOnMock invocation) throws Throwable {
- return channelRecordSortedMap.values();
- }
- }).when(dataManager).getChannelRecords();
- Mockito.doAnswer(new Answer<ChannelRecord>() {
- @Override
- public ChannelRecord answer(InvocationOnMock invocation) throws Throwable {
- long channelId = (long) invocation.getArguments()[0];
- return channelRecordSortedMap.get(channelId);
- }
- }).when(dataManager).getChannelRecord(Matchers.anyLong());
+ Mockito.doAnswer(
+ new Answer<Integer>() {
+ @Override
+ public Integer answer(InvocationOnMock invocation) throws Throwable {
+ return channelRecordSortedMap.size();
+ }
+ })
+ .when(dataManager)
+ .getChannelRecordCount();
+ Mockito.doAnswer(
+ new Answer<Collection<ChannelRecord>>() {
+ @Override
+ public Collection<ChannelRecord> answer(InvocationOnMock invocation)
+ throws Throwable {
+ return channelRecordSortedMap.values();
+ }
+ })
+ .when(dataManager)
+ .getChannelRecords();
+ Mockito.doAnswer(
+ new Answer<ChannelRecord>() {
+ @Override
+ public ChannelRecord answer(InvocationOnMock invocation)
+ throws Throwable {
+ long channelId = (long) invocation.getArguments()[0];
+ return channelRecordSortedMap.get(channelId);
+ }
+ })
+ .when(dataManager)
+ .getChannelRecord(Matchers.anyLong());
return dataManager;
}
@@ -82,9 +89,9 @@ public class RecommendationUtils {
}
/**
- * Add new {@code numberOfChannels} channels by adding channel record to
- * {@code channelRecordMap} with no history.
- * This action corresponds to loading channels in the RecommendationDataManger.
+ * Add new {@code numberOfChannels} channels by adding channel record to {@code
+ * channelRecordMap} with no history. This action corresponds to loading channels in the
+ * RecommendationDataManger.
*/
public void addChannels(int numberOfChannels) {
for (int i = 0; i < numberOfChannels; ++i) {
@@ -100,21 +107,21 @@ public class RecommendationUtils {
*/
public Channel addChannel() {
long channelId = size();
- Channel channel = new Channel.Builder().setId(channelId).build();
+ ChannelImpl channel = new ChannelImpl.Builder().setId(channelId).build();
ChannelRecord channelRecord = new ChannelRecord(mContext, channel, false);
put(channelId, channelRecord);
return channel;
}
/**
- * Add the watch logs which its durationTime is under {@code maxWatchDurationMs}.
- * Add until latest watch end time becomes bigger than {@code watchEndTimeMs},
- * starting from {@code watchStartTimeMs}.
+ * Add the watch logs which its durationTime is under {@code maxWatchDurationMs}. Add until
+ * latest watch end time becomes bigger than {@code watchEndTimeMs}, starting from {@code
+ * watchStartTimeMs}.
*
* @return true if adding watch log success, otherwise false.
*/
- public boolean addRandomWatchLogs(long watchStartTimeMs, long watchEndTimeMs,
- long maxWatchDurationMs) {
+ public boolean addRandomWatchLogs(
+ long watchStartTimeMs, long watchEndTimeMs, long maxWatchDurationMs) {
long latestWatchEndTimeMs = watchStartTimeMs;
long previousChannelId = INVALID_CHANNEL_ID;
List<Long> channelIdList = new ArrayList<>(keySet());
@@ -143,13 +150,13 @@ public class RecommendationUtils {
*/
public boolean addWatchLog(long channelId, long watchStartTimeMs, long durationTimeMs) {
ChannelRecord channelRecord = get(channelId);
- if (channelRecord == null ||
- watchStartTimeMs + durationTimeMs > System.currentTimeMillis()) {
+ if (channelRecord == null
+ || watchStartTimeMs + durationTimeMs > System.currentTimeMillis()) {
return false;
}
- channelRecord.logWatchHistory(new WatchedProgram(null, watchStartTimeMs,
- watchStartTimeMs + durationTimeMs));
+ channelRecord.logWatchHistory(
+ new WatchedProgram(null, watchStartTimeMs, watchStartTimeMs + durationTimeMs));
if (mRecommender != null) {
mRecommender.onNewWatchLog(channelRecord);
}
diff --git a/tests/unit/src/com/android/tv/recommendation/RecommenderTest.java b/tests/unit/src/com/android/tv/recommendation/RecommenderTest.java
index 85524a82..812a3eb1 100644
--- a/tests/unit/src/com/android/tv/recommendation/RecommenderTest.java
+++ b/tests/unit/src/com/android/tv/recommendation/RecommenderTest.java
@@ -17,20 +17,14 @@
package com.android.tv.recommendation;
import static android.support.test.InstrumentationRegistry.getContext;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
+import static com.google.common.truth.Truth.assertThat;
import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
import android.test.MoreAsserts;
-
-import com.android.tv.data.Channel;
+import com.android.tv.data.api.Channel;
import com.android.tv.recommendation.RecommendationUtils.ChannelRecordSortedMapHelper;
-import com.android.tv.testing.Utils;
-
-import org.junit.Before;
-import org.junit.Test;
-
+import com.android.tv.testing.utils.Utils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -39,8 +33,12 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
@SmallTest
+@RunWith(AndroidJUnit4.class)
public class RecommenderTest {
private static final int DEFAULT_NUMBER_OF_CHANNELS = 5;
private static final long DEFAULT_WATCH_START_TIME_MS =
@@ -49,24 +47,27 @@ public class RecommenderTest {
System.currentTimeMillis() - TimeUnit.DAYS.toMillis(1);
private static final long DEFAULT_MAX_WATCH_DURATION_MS = TimeUnit.HOURS.toMillis(1);
- private final Comparator<Channel> CHANNEL_SORT_KEY_COMPARATOR = new Comparator<Channel>() {
- @Override
- public int compare(Channel lhs, Channel rhs) {
- return mRecommender.getChannelSortKey(lhs.getId())
- .compareTo(mRecommender.getChannelSortKey(rhs.getId()));
- }
- };
- private final Runnable START_DATAMANAGER_RUNNABLE_ADD_FOUR_CHANNELS = new Runnable() {
- @Override
- public void run() {
- // Add 4 channels in ChannelRecordMap for testing. Store the added channels to
- // mChannels_1 ~ mChannels_4. They are sorted by channel id in increasing order.
- mChannel_1 = mChannelRecordSortedMap.addChannel();
- mChannel_2 = mChannelRecordSortedMap.addChannel();
- mChannel_3 = mChannelRecordSortedMap.addChannel();
- mChannel_4 = mChannelRecordSortedMap.addChannel();
- }
- };
+ private final Comparator<Channel> mChannelSortKeyComparator =
+ new Comparator<Channel>() {
+ @Override
+ public int compare(Channel lhs, Channel rhs) {
+ return mRecommender
+ .getChannelSortKey(lhs.getId())
+ .compareTo(mRecommender.getChannelSortKey(rhs.getId()));
+ }
+ };
+ private final Runnable mStartDatamanagerRunnableAddFourChannels =
+ new Runnable() {
+ @Override
+ public void run() {
+ // Add 4 channels in ChannelRecordMap for testing. Store the added channels to
+ // mChannels_1 ~ mChannels_4. They are sorted by channel id in increasing order.
+ mChannel_1 = mChannelRecordSortedMap.addChannel();
+ mChannel_2 = mChannelRecordSortedMap.addChannel();
+ mChannel_3 = mChannelRecordSortedMap.addChannel();
+ mChannel_4 = mChannelRecordSortedMap.addChannel();
+ }
+ };
private RecommendationDataManager mDataManager;
private Recommender mRecommender;
@@ -82,133 +83,133 @@ public class RecommenderTest {
@Before
public void setUp() {
mChannelRecordSortedMap = new ChannelRecordSortedMapHelper(getContext());
- mDataManager = RecommendationUtils
- .createMockRecommendationDataManager(mChannelRecordSortedMap);
+ mDataManager =
+ RecommendationUtils.createMockRecommendationDataManager(mChannelRecordSortedMap);
mChannelRecordSortedMap.resetRandom(Utils.createTestRandom());
}
@Test
public void testRecommendChannels_includeRecommendedOnly_allChannelsHaveNoScore() {
- createRecommender(true, START_DATAMANAGER_RUNNABLE_ADD_FOUR_CHANNELS);
-
- // Recommender doesn't recommend any channels because all channels are not recommended.
- assertEquals(0, mRecommender.recommendChannels().size());
- assertEquals(0, mRecommender.recommendChannels(-5).size());
- assertEquals(0, mRecommender.recommendChannels(0).size());
- assertEquals(0, mRecommender.recommendChannels(3).size());
- assertEquals(0, mRecommender.recommendChannels(4).size());
- assertEquals(0, mRecommender.recommendChannels(5).size());
+ createRecommender(true, mStartDatamanagerRunnableAddFourChannels);
+
+ // Recommender doesn't recommend any channels because all channels are not recommended.
+ assertThat(mRecommender.recommendChannels()).isEmpty();
+ assertThat(mRecommender.recommendChannels(-5)).isEmpty();
+ assertThat(mRecommender.recommendChannels(0)).isEmpty();
+ assertThat(mRecommender.recommendChannels(3)).isEmpty();
+ assertThat(mRecommender.recommendChannels(4)).isEmpty();
+ assertThat(mRecommender.recommendChannels(5)).isEmpty();
}
@Test
public void testRecommendChannels_notIncludeRecommendedOnly_allChannelsHaveNoScore() {
- createRecommender(false, START_DATAMANAGER_RUNNABLE_ADD_FOUR_CHANNELS);
-
- // Recommender recommends every channel because it recommends not-recommended channels too.
- assertEquals(4, mRecommender.recommendChannels().size());
- assertEquals(0, mRecommender.recommendChannels(-5).size());
- assertEquals(0, mRecommender.recommendChannels(0).size());
- assertEquals(3, mRecommender.recommendChannels(3).size());
- assertEquals(4, mRecommender.recommendChannels(4).size());
- assertEquals(4, mRecommender.recommendChannels(5).size());
+ createRecommender(false, mStartDatamanagerRunnableAddFourChannels);
+
+ // Recommender recommends every channel because it recommends not-recommended channels too.
+ assertThat(mRecommender.recommendChannels()).hasSize(4);
+ assertThat(mRecommender.recommendChannels(-5)).isEmpty();
+ assertThat(mRecommender.recommendChannels(0)).isEmpty();
+ assertThat(mRecommender.recommendChannels(3)).hasSize(3);
+ assertThat(mRecommender.recommendChannels(4)).hasSize(4);
+ assertThat(mRecommender.recommendChannels(5)).hasSize(4);
}
@Test
public void testRecommendChannels_includeRecommendedOnly_allChannelsHaveScore() {
- createRecommender(true, START_DATAMANAGER_RUNNABLE_ADD_FOUR_CHANNELS);
+ createRecommender(true, mStartDatamanagerRunnableAddFourChannels);
setChannelScores_scoreIncreasesAsChannelIdIncreases();
// recommendChannels must be sorted by score in decreasing order.
// (i.e. sorted by channel ID in decreasing order in this case)
- MoreAsserts.assertContentsInOrder(mRecommender.recommendChannels(),
- mChannel_4, mChannel_3, mChannel_2, mChannel_1);
- assertEquals(0, mRecommender.recommendChannels(-5).size());
- assertEquals(0, mRecommender.recommendChannels(0).size());
- MoreAsserts.assertContentsInOrder(mRecommender.recommendChannels(3),
- mChannel_4, mChannel_3, mChannel_2);
- MoreAsserts.assertContentsInOrder(mRecommender.recommendChannels(4),
- mChannel_4, mChannel_3, mChannel_2, mChannel_1);
- MoreAsserts.assertContentsInOrder(mRecommender.recommendChannels(5),
- mChannel_4, mChannel_3, mChannel_2, mChannel_1);
+ MoreAsserts.assertContentsInOrder(
+ mRecommender.recommendChannels(), mChannel_4, mChannel_3, mChannel_2, mChannel_1);
+ assertThat(mRecommender.recommendChannels(-5)).isEmpty();
+ assertThat(mRecommender.recommendChannels(0)).isEmpty();
+ MoreAsserts.assertContentsInOrder(
+ mRecommender.recommendChannels(3), mChannel_4, mChannel_3, mChannel_2);
+ MoreAsserts.assertContentsInOrder(
+ mRecommender.recommendChannels(4), mChannel_4, mChannel_3, mChannel_2, mChannel_1);
+ MoreAsserts.assertContentsInOrder(
+ mRecommender.recommendChannels(5), mChannel_4, mChannel_3, mChannel_2, mChannel_1);
}
@Test
public void testRecommendChannels_notIncludeRecommendedOnly_allChannelsHaveScore() {
- createRecommender(false, START_DATAMANAGER_RUNNABLE_ADD_FOUR_CHANNELS);
+ createRecommender(false, mStartDatamanagerRunnableAddFourChannels);
setChannelScores_scoreIncreasesAsChannelIdIncreases();
// recommendChannels must be sorted by score in decreasing order.
// (i.e. sorted by channel ID in decreasing order in this case)
- MoreAsserts.assertContentsInOrder(mRecommender.recommendChannels(),
- mChannel_4, mChannel_3, mChannel_2, mChannel_1);
- assertEquals(0, mRecommender.recommendChannels(-5).size());
- assertEquals(0, mRecommender.recommendChannels(0).size());
- MoreAsserts.assertContentsInOrder(mRecommender.recommendChannels(3),
- mChannel_4, mChannel_3, mChannel_2);
- MoreAsserts.assertContentsInOrder(mRecommender.recommendChannels(4),
- mChannel_4, mChannel_3, mChannel_2, mChannel_1);
- MoreAsserts.assertContentsInOrder(mRecommender.recommendChannels(5),
- mChannel_4, mChannel_3, mChannel_2, mChannel_1);
+ MoreAsserts.assertContentsInOrder(
+ mRecommender.recommendChannels(), mChannel_4, mChannel_3, mChannel_2, mChannel_1);
+ assertThat(mRecommender.recommendChannels(-5)).isEmpty();
+ assertThat(mRecommender.recommendChannels(0)).isEmpty();
+ MoreAsserts.assertContentsInOrder(
+ mRecommender.recommendChannels(3), mChannel_4, mChannel_3, mChannel_2);
+ MoreAsserts.assertContentsInOrder(
+ mRecommender.recommendChannels(4), mChannel_4, mChannel_3, mChannel_2, mChannel_1);
+ MoreAsserts.assertContentsInOrder(
+ mRecommender.recommendChannels(5), mChannel_4, mChannel_3, mChannel_2, mChannel_1);
}
@Test
public void testRecommendChannels_includeRecommendedOnly_fewChannelsHaveScore() {
- createRecommender(true, START_DATAMANAGER_RUNNABLE_ADD_FOUR_CHANNELS);
+ createRecommender(true, mStartDatamanagerRunnableAddFourChannels);
mEvaluator.setChannelScore(mChannel_1.getId(), 1.0);
mEvaluator.setChannelScore(mChannel_2.getId(), 1.0);
// Only two channels are recommended because recommender doesn't recommend other channels.
- MoreAsserts.assertContentsInAnyOrder(mRecommender.recommendChannels(),
- mChannel_1, mChannel_2);
- assertEquals(0, mRecommender.recommendChannels(-5).size());
- assertEquals(0, mRecommender.recommendChannels(0).size());
- MoreAsserts.assertContentsInAnyOrder(mRecommender.recommendChannels(3),
- mChannel_1, mChannel_2);
- MoreAsserts.assertContentsInAnyOrder(mRecommender.recommendChannels(4),
- mChannel_1, mChannel_2);
- MoreAsserts.assertContentsInAnyOrder(mRecommender.recommendChannels(5),
- mChannel_1, mChannel_2);
+ MoreAsserts.assertContentsInAnyOrder(
+ mRecommender.recommendChannels(), mChannel_1, mChannel_2);
+ assertThat(mRecommender.recommendChannels(-5)).isEmpty();
+ assertThat(mRecommender.recommendChannels(0)).isEmpty();
+ MoreAsserts.assertContentsInAnyOrder(
+ mRecommender.recommendChannels(3), mChannel_1, mChannel_2);
+ MoreAsserts.assertContentsInAnyOrder(
+ mRecommender.recommendChannels(4), mChannel_1, mChannel_2);
+ MoreAsserts.assertContentsInAnyOrder(
+ mRecommender.recommendChannels(5), mChannel_1, mChannel_2);
}
@Test
public void testRecommendChannels_notIncludeRecommendedOnly_fewChannelsHaveScore() {
- createRecommender(false, START_DATAMANAGER_RUNNABLE_ADD_FOUR_CHANNELS);
+ createRecommender(false, mStartDatamanagerRunnableAddFourChannels);
mEvaluator.setChannelScore(mChannel_1.getId(), 1.0);
mEvaluator.setChannelScore(mChannel_2.getId(), 1.0);
- assertEquals(4, mRecommender.recommendChannels().size());
- MoreAsserts.assertContentsInAnyOrder(mRecommender.recommendChannels().subList(0, 2),
- mChannel_1, mChannel_2);
+ assertThat(mRecommender.recommendChannels()).hasSize(4);
+ MoreAsserts.assertContentsInAnyOrder(
+ mRecommender.recommendChannels().subList(0, 2), mChannel_1, mChannel_2);
- assertEquals(0, mRecommender.recommendChannels(-5).size());
- assertEquals(0, mRecommender.recommendChannels(0).size());
+ assertThat(mRecommender.recommendChannels(-5)).isEmpty();
+ assertThat(mRecommender.recommendChannels(0)).isEmpty();
- assertEquals(3, mRecommender.recommendChannels(3).size());
- MoreAsserts.assertContentsInAnyOrder(mRecommender.recommendChannels(3).subList(0, 2),
- mChannel_1, mChannel_2);
+ assertThat(mRecommender.recommendChannels(3)).hasSize(3);
+ MoreAsserts.assertContentsInAnyOrder(
+ mRecommender.recommendChannels(3).subList(0, 2), mChannel_1, mChannel_2);
- assertEquals(4, mRecommender.recommendChannels(4).size());
- MoreAsserts.assertContentsInAnyOrder(mRecommender.recommendChannels(4).subList(0, 2),
- mChannel_1, mChannel_2);
+ assertThat(mRecommender.recommendChannels(4)).hasSize(4);
+ MoreAsserts.assertContentsInAnyOrder(
+ mRecommender.recommendChannels(4).subList(0, 2), mChannel_1, mChannel_2);
- assertEquals(4, mRecommender.recommendChannels(5).size());
- MoreAsserts.assertContentsInAnyOrder(mRecommender.recommendChannels(5).subList(0, 2),
- mChannel_1, mChannel_2);
+ assertThat(mRecommender.recommendChannels(5)).hasSize(4);
+ MoreAsserts.assertContentsInAnyOrder(
+ mRecommender.recommendChannels(5).subList(0, 2), mChannel_1, mChannel_2);
}
@Test
public void testGetChannelSortKey_recommendAllChannels() {
- createRecommender(true, START_DATAMANAGER_RUNNABLE_ADD_FOUR_CHANNELS);
+ createRecommender(true, mStartDatamanagerRunnableAddFourChannels);
setChannelScores_scoreIncreasesAsChannelIdIncreases();
List<Channel> expectedChannelList = mRecommender.recommendChannels();
List<Channel> channelList = Arrays.asList(mChannel_1, mChannel_2, mChannel_3, mChannel_4);
- Collections.sort(channelList, CHANNEL_SORT_KEY_COMPARATOR);
+ Collections.sort(channelList, mChannelSortKeyComparator);
// Recommended channel list and channel list sorted by sort key must be the same.
MoreAsserts.assertContentsInOrder(channelList, expectedChannelList.toArray());
@@ -218,17 +219,17 @@ public class RecommenderTest {
@Test
public void testGetChannelSortKey_recommendFewChannels() {
// Test with recommending 3 channels.
- createRecommender(true, START_DATAMANAGER_RUNNABLE_ADD_FOUR_CHANNELS);
+ createRecommender(true, mStartDatamanagerRunnableAddFourChannels);
setChannelScores_scoreIncreasesAsChannelIdIncreases();
List<Channel> expectedChannelList = mRecommender.recommendChannels(3);
- // A channel which is not recommended by the recommender has to get an invalid sort key.
- assertEquals(Recommender.INVALID_CHANNEL_SORT_KEY,
- mRecommender.getChannelSortKey(mChannel_1.getId()));
+ // A channel which is not recommended by the recommender has to get an invalid sort key.
+ assertThat(mRecommender.getChannelSortKey(mChannel_1.getId()))
+ .isEqualTo(Recommender.INVALID_CHANNEL_SORT_KEY);
List<Channel> channelList = Arrays.asList(mChannel_2, mChannel_3, mChannel_4);
- Collections.sort(channelList, CHANNEL_SORT_KEY_COMPARATOR);
+ Collections.sort(channelList, mChannelSortKeyComparator);
MoreAsserts.assertContentsInOrder(channelList, expectedChannelList.toArray());
assertSortKeyNotInvalid(channelList);
@@ -236,10 +237,10 @@ public class RecommenderTest {
@Test
public void testListener_onRecommendationChanged() {
- createRecommender(true, START_DATAMANAGER_RUNNABLE_ADD_FOUR_CHANNELS);
- // FakeEvaluator doesn't recommend a channel with empty watch log. As every channel
- // doesn't have a watch log, nothing is recommended and recommendation isn't changed.
- assertFalse(mOnRecommendationChanged);
+ createRecommender(true, mStartDatamanagerRunnableAddFourChannels);
+ // FakeEvaluator doesn't recommend a channel with empty watch log. As every channel
+ // doesn't have a watch log, nothing is recommended and recommendation isn't changed.
+ assertThat(mOnRecommendationChanged).isFalse();
// Set lastRecommendationUpdatedTimeUtcMs to check recommendation changed because,
// recommender has a minimum recommendation update period.
@@ -248,51 +249,63 @@ public class RecommenderTest {
long latestWatchEndTimeMs = DEFAULT_WATCH_START_TIME_MS;
for (long channelId : mChannelRecordSortedMap.keySet()) {
mEvaluator.setChannelScore(channelId, 1.0);
- // Add a log to recalculate the recommendation score.
- assertTrue(mChannelRecordSortedMap.addWatchLog(channelId, latestWatchEndTimeMs,
- TimeUnit.MINUTES.toMillis(10)));
+ // Add a log to recalculate the recommendation score.
+ assertThat(
+ mChannelRecordSortedMap.addWatchLog(
+ channelId, latestWatchEndTimeMs, TimeUnit.MINUTES.toMillis(10)))
+ .isTrue();
latestWatchEndTimeMs += TimeUnit.MINUTES.toMillis(10);
}
- // onRecommendationChanged must be called, because recommend channels are not empty,
- // by setting score to each channel.
- assertTrue(mOnRecommendationChanged);
+ // onRecommendationChanged must be called, because recommend channels are not empty,
+ // by setting score to each channel.
+ assertThat(mOnRecommendationChanged).isTrue();
}
@Test
public void testListener_onRecommenderReady() {
- createRecommender(true, new Runnable() {
- @Override
- public void run() {
- mChannelRecordSortedMap.addChannels(DEFAULT_NUMBER_OF_CHANNELS);
- mChannelRecordSortedMap.addRandomWatchLogs(DEFAULT_WATCH_START_TIME_MS,
- DEFAULT_WATCH_END_TIME_MS, DEFAULT_MAX_WATCH_DURATION_MS);
- }
- });
-
- // After loading channels and watch logs are finished, recommender must be available to use.
- assertTrue(mOnRecommenderReady);
+ createRecommender(
+ true,
+ new Runnable() {
+ @Override
+ public void run() {
+ mChannelRecordSortedMap.addChannels(DEFAULT_NUMBER_OF_CHANNELS);
+ mChannelRecordSortedMap.addRandomWatchLogs(
+ DEFAULT_WATCH_START_TIME_MS,
+ DEFAULT_WATCH_END_TIME_MS,
+ DEFAULT_MAX_WATCH_DURATION_MS);
+ }
+ });
+
+ // After loading channels and watch logs are finished, recommender must be available to use.
+ assertThat(mOnRecommenderReady).isTrue();
}
private void assertSortKeyNotInvalid(List<Channel> channelList) {
for (Channel channel : channelList) {
- MoreAsserts.assertNotEqual(Recommender.INVALID_CHANNEL_SORT_KEY,
+ MoreAsserts.assertNotEqual(
+ Recommender.INVALID_CHANNEL_SORT_KEY,
mRecommender.getChannelSortKey(channel.getId()));
}
}
- private void createRecommender(boolean includeRecommendedOnly,
- Runnable startDataManagerRunnable) {
- mRecommender = new Recommender(new Recommender.Listener() {
- @Override
- public void onRecommenderReady() {
- mOnRecommenderReady = true;
- }
- @Override
- public void onRecommendationChanged() {
- mOnRecommendationChanged = true;
- }
- }, includeRecommendedOnly, mDataManager);
+ private void createRecommender(
+ boolean includeRecommendedOnly, Runnable startDataManagerRunnable) {
+ mRecommender =
+ new Recommender(
+ new Recommender.Listener() {
+ @Override
+ public void onRecommenderReady() {
+ mOnRecommenderReady = true;
+ }
+
+ @Override
+ public void onRecommendationChanged() {
+ mOnRecommendationChanged = true;
+ }
+ },
+ includeRecommendedOnly,
+ mDataManager);
mEvaluator = new FakeEvaluator();
mRecommender.registerEvaluator(mEvaluator);
diff --git a/tests/unit/src/com/android/tv/recommendation/RoutineWatchEvaluatorTest.java b/tests/unit/src/com/android/tv/recommendation/RoutineWatchEvaluatorTest.java
index 7b8e256d..39e6e9c5 100644
--- a/tests/unit/src/com/android/tv/recommendation/RoutineWatchEvaluatorTest.java
+++ b/tests/unit/src/com/android/tv/recommendation/RoutineWatchEvaluatorTest.java
@@ -16,23 +16,22 @@
package com.android.tv.recommendation;
+import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
import android.support.test.filters.SmallTest;
-import android.test.MoreAsserts;
-
+import android.support.test.runner.AndroidJUnit4;
import com.android.tv.data.Program;
import com.android.tv.recommendation.RoutineWatchEvaluator.ProgramTime;
-
-import org.junit.Test;
-
-import java.util.Arrays;
import java.util.Calendar;
import java.util.List;
-import java.util.TreeSet;
import java.util.concurrent.TimeUnit;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+/** Tests for {@link RoutineWatchEvaluator}. */
@SmallTest
+@RunWith(AndroidJUnit4.class)
public class RoutineWatchEvaluatorTest extends EvaluatorTestCase<RoutineWatchEvaluator> {
private static class ScoredItem implements Comparable<ScoredItem> {
private final String mBase;
@@ -67,13 +66,23 @@ public class RoutineWatchEvaluatorTest extends EvaluatorTestCase<RoutineWatchEva
@Test
public void testSplitTextToWords() {
- assertSplitTextToWords("");
- assertSplitTextToWords("Google", "Google");
- assertSplitTextToWords("The Big Bang Theory", "The", "Big", "Bang", "Theory");
- assertSplitTextToWords("Hello, world!", "Hello", "world");
- assertSplitTextToWords("Adam's Rib", "Adam's", "Rib");
- assertSplitTextToWords("G.I. Joe", "G.I", "Joe");
- assertSplitTextToWords("A.I.", "A.I");
+ assertThat(RoutineWatchEvaluator.splitTextToWords("")).containsExactly().inOrder();
+ assertThat(RoutineWatchEvaluator.splitTextToWords("Google"))
+ .containsExactly("Google")
+ .inOrder();
+ assertThat(RoutineWatchEvaluator.splitTextToWords("The Big Bang Theory"))
+ .containsExactly("The", "Big", "Bang", "Theory")
+ .inOrder();
+ assertThat(RoutineWatchEvaluator.splitTextToWords("Hello, world!"))
+ .containsExactly("Hello", "world")
+ .inOrder();
+ assertThat(RoutineWatchEvaluator.splitTextToWords("Adam's Rib"))
+ .containsExactly("Adam's", "Rib")
+ .inOrder();
+ assertThat(RoutineWatchEvaluator.splitTextToWords("G.I. Joe"))
+ .containsExactly("G.I", "Joe")
+ .inOrder();
+ assertThat(RoutineWatchEvaluator.splitTextToWords("A.I.")).containsExactly("A.I").inOrder();
}
@Test
@@ -102,7 +111,6 @@ public class RoutineWatchEvaluatorTest extends EvaluatorTestCase<RoutineWatchEva
assertEqualScores(0.0, RoutineWatchEvaluator.calculateTitleMatchScore(" ", "foo"));
}
-
@Test
public void testCalculateTitleMatchScore_null() {
assertEqualScores(0.0, RoutineWatchEvaluator.calculateTitleMatchScore(null, null));
@@ -113,11 +121,15 @@ public class RoutineWatchEvaluatorTest extends EvaluatorTestCase<RoutineWatchEva
@Test
public void testCalculateTitleMatchScore_longerMatchIsBetter() {
String base = "foo bar baz";
- assertInOrder(
- score(base, ""),
- score(base, "bar"),
- score(base, "foo bar"),
- score(base, "foo bar baz"));
+ assertThat(
+ new ScoredItem[] {
+ score(base, ""),
+ score(base, "bar"),
+ score(base, "foo bar"),
+ score(base, "foo bar baz")
+ })
+ .asList()
+ .isOrdered();
}
@Test
@@ -128,116 +140,154 @@ public class RoutineWatchEvaluatorTest extends EvaluatorTestCase<RoutineWatchEva
int tomorrowDayOfWeek = (todayDayOfWeek % 7) + 1;
// Today 00:00 - 01:00.
- ProgramTime programTimeToday0000_0100 = ProgramTime.createFromProgram(
- createDummyProgram(todayAtHourMin(0, 0), TimeUnit.HOURS.toMillis(1)));
- assertProgramTime(todayDayOfWeek, hourMinuteToSec(0, 0), hourMinuteToSec(1, 0),
- programTimeToday0000_0100);
+ ProgramTime programTimeToday0000to0100 =
+ ProgramTime.createFromProgram(
+ createDummyProgram(todayAtHourMin(0, 0), TimeUnit.HOURS.toMillis(1)));
+ assertProgramTime(
+ todayDayOfWeek,
+ hourMinuteToSec(0, 0),
+ hourMinuteToSec(1, 0),
+ programTimeToday0000to0100);
// Today 23:30 - 24:30.
- ProgramTime programTimeToday2330_2430 = ProgramTime.createFromProgram(
- createDummyProgram(todayAtHourMin(23, 30), TimeUnit.HOURS.toMillis(1)));
- assertProgramTime(todayDayOfWeek, hourMinuteToSec(23, 30), hourMinuteToSec(24, 30),
- programTimeToday2330_2430);
+ ProgramTime programTimeToday2330to2430 =
+ ProgramTime.createFromProgram(
+ createDummyProgram(todayAtHourMin(23, 30), TimeUnit.HOURS.toMillis(1)));
+ assertProgramTime(
+ todayDayOfWeek,
+ hourMinuteToSec(23, 30),
+ hourMinuteToSec(24, 30),
+ programTimeToday2330to2430);
// Tomorrow 00:00 - 01:00.
- ProgramTime programTimeTomorrow0000_0100 = ProgramTime.createFromProgram(
- createDummyProgram(tomorrowAtHourMin(0, 0), TimeUnit.HOURS.toMillis(1)));
- assertProgramTime(tomorrowDayOfWeek, hourMinuteToSec(0, 0), hourMinuteToSec(1, 0),
- programTimeTomorrow0000_0100);
+ ProgramTime programTimeTomorrow0000to0100 =
+ ProgramTime.createFromProgram(
+ createDummyProgram(tomorrowAtHourMin(0, 0), TimeUnit.HOURS.toMillis(1)));
+ assertProgramTime(
+ tomorrowDayOfWeek,
+ hourMinuteToSec(0, 0),
+ hourMinuteToSec(1, 0),
+ programTimeTomorrow0000to0100);
// Tomorrow 23:30 - 24:30.
- ProgramTime programTimeTomorrow2330_2430 = ProgramTime.createFromProgram(
- createDummyProgram(tomorrowAtHourMin(23, 30), TimeUnit.HOURS.toMillis(1)));
- assertProgramTime(tomorrowDayOfWeek, hourMinuteToSec(23, 30), hourMinuteToSec(24, 30),
- programTimeTomorrow2330_2430);
+ ProgramTime programTimeTomorrow2330to2430 =
+ ProgramTime.createFromProgram(
+ createDummyProgram(tomorrowAtHourMin(23, 30), TimeUnit.HOURS.toMillis(1)));
+ assertProgramTime(
+ tomorrowDayOfWeek,
+ hourMinuteToSec(23, 30),
+ hourMinuteToSec(24, 30),
+ programTimeTomorrow2330to2430);
// Today 18:00 - Tomorrow 12:00.
- ProgramTime programTimeToday1800_3600 = ProgramTime.createFromProgram(
- createDummyProgram(todayAtHourMin(18, 0), TimeUnit.HOURS.toMillis(18)));
+ ProgramTime programTimeToday1800to3600 =
+ ProgramTime.createFromProgram(
+ createDummyProgram(todayAtHourMin(18, 0), TimeUnit.HOURS.toMillis(18)));
// Maximum duration of ProgramTime is 12 hours.
// So, this program looks like it ends at Tomorrow 06:00 (30:00).
- assertProgramTime(todayDayOfWeek, hourMinuteToSec(18, 0), hourMinuteToSec(30, 0),
- programTimeToday1800_3600);
+ assertProgramTime(
+ todayDayOfWeek,
+ hourMinuteToSec(18, 0),
+ hourMinuteToSec(30, 0),
+ programTimeToday1800to3600);
}
@Test
public void testCalculateOverlappedIntervalScore() {
// Today 21:00 - 24:00.
- ProgramTime programTimeToday2100_2400 = ProgramTime.createFromProgram(
- createDummyProgram(todayAtHourMin(21, 0), TimeUnit.HOURS.toMillis(3)));
+ ProgramTime programTimeToday2100to2400 =
+ ProgramTime.createFromProgram(
+ createDummyProgram(todayAtHourMin(21, 0), TimeUnit.HOURS.toMillis(3)));
// Today 22:00 - 01:00.
- ProgramTime programTimeToday2200_0100 = ProgramTime.createFromProgram(
- createDummyProgram(todayAtHourMin(22, 0), TimeUnit.HOURS.toMillis(3)));
+ ProgramTime programTimeToday2200to0100 =
+ ProgramTime.createFromProgram(
+ createDummyProgram(todayAtHourMin(22, 0), TimeUnit.HOURS.toMillis(3)));
// Tomorrow 00:00 - 03:00.
- ProgramTime programTimeTomorrow0000_0300 = ProgramTime.createFromProgram(
- createDummyProgram(tomorrowAtHourMin(0, 0), TimeUnit.HOURS.toMillis(3)));
+ ProgramTime programTimeTomorrow0000to0300 =
+ ProgramTime.createFromProgram(
+ createDummyProgram(tomorrowAtHourMin(0, 0), TimeUnit.HOURS.toMillis(3)));
// Tomorrow 20:00 - Tomorrow 23:00.
- ProgramTime programTimeTomorrow2000_2300 = ProgramTime.createFromProgram(
- createDummyProgram(tomorrowAtHourMin(20, 0), TimeUnit.HOURS.toMillis(3)));
+ ProgramTime programTimeTomorrow2000to2300 =
+ ProgramTime.createFromProgram(
+ createDummyProgram(tomorrowAtHourMin(20, 0), TimeUnit.HOURS.toMillis(3)));
// Check intersection time and commutative law in all cases.
int oneHourInSec = hourMinuteToSec(1, 0);
- assertOverlappedIntervalScore(2 * oneHourInSec, true, programTimeToday2100_2400,
- programTimeToday2200_0100);
- assertOverlappedIntervalScore(0, false, programTimeToday2100_2400,
- programTimeTomorrow0000_0300);
- assertOverlappedIntervalScore(2 * oneHourInSec, false, programTimeToday2100_2400,
- programTimeTomorrow2000_2300);
- assertOverlappedIntervalScore(oneHourInSec, true, programTimeToday2200_0100,
- programTimeTomorrow0000_0300);
- assertOverlappedIntervalScore(oneHourInSec, false, programTimeToday2200_0100,
- programTimeTomorrow2000_2300);
- assertOverlappedIntervalScore(0, false, programTimeTomorrow0000_0300,
- programTimeTomorrow2000_2300);
+ assertOverlappedIntervalScore(
+ 2 * oneHourInSec, true, programTimeToday2100to2400, programTimeToday2200to0100);
+ assertOverlappedIntervalScore(
+ 0, false, programTimeToday2100to2400, programTimeTomorrow0000to0300);
+ assertOverlappedIntervalScore(
+ 2 * oneHourInSec, false, programTimeToday2100to2400, programTimeTomorrow2000to2300);
+ assertOverlappedIntervalScore(
+ oneHourInSec, true, programTimeToday2200to0100, programTimeTomorrow0000to0300);
+ assertOverlappedIntervalScore(
+ oneHourInSec, false, programTimeToday2200to0100, programTimeTomorrow2000to2300);
+ assertOverlappedIntervalScore(
+ 0, false, programTimeTomorrow0000to0300, programTimeTomorrow2000to2300);
}
@Test
public void testGetTimeOfDayInSec() {
// Time was set as 00:00:00. So, getTimeOfDay must returns 0 (= 0 * 60 * 60 + 0 * 60 + 0).
- assertEquals("TimeOfDayInSec", hourMinuteToSec(0, 0),
+ assertEquals(
+ "TimeOfDayInSec",
+ hourMinuteToSec(0, 0),
RoutineWatchEvaluator.getTimeOfDayInSec(todayAtHourMin(0, 0)));
// Time was set as 23:59:59. So, getTimeOfDay must returns 23 * 60 + 60 + 59 * 60 + 59.
- assertEquals("TimeOfDayInSec", hourMinuteSecondToSec(23, 59, 59),
+ assertEquals(
+ "TimeOfDayInSec",
+ hourMinuteSecondToSec(23, 59, 59),
RoutineWatchEvaluator.getTimeOfDayInSec(todayAtHourMinSec(23, 59, 59)));
}
- private void assertSplitTextToWords(String text, String... words) {
- List<String> wordList = RoutineWatchEvaluator.splitTextToWords(text);
- MoreAsserts.assertContentsInOrder(wordList, words);
- }
-
- private void assertMaximumMatchedWordSequenceLength(int expectedLength, String text1,
- String text2) {
+ private void assertMaximumMatchedWordSequenceLength(
+ int expectedLength, String text1, String text2) {
List<String> wordList1 = RoutineWatchEvaluator.splitTextToWords(text1);
List<String> wordList2 = RoutineWatchEvaluator.splitTextToWords(text2);
- assertEquals("MaximumMatchedWordSequenceLength", expectedLength,
+ assertEquals(
+ "MaximumMatchedWordSequenceLength",
+ expectedLength,
RoutineWatchEvaluator.calculateMaximumMatchedWordSequenceLength(
wordList1, wordList2));
- assertEquals("MaximumMatchedWordSequenceLength", expectedLength,
+ assertEquals(
+ "MaximumMatchedWordSequenceLength",
+ expectedLength,
RoutineWatchEvaluator.calculateMaximumMatchedWordSequenceLength(
wordList2, wordList1));
}
- private void assertProgramTime(int expectedWeekDay, int expectedStartTimeOfDayInSec,
- int expectedEndTimeOfDayInSec, ProgramTime actualProgramTime) {
+ private void assertProgramTime(
+ int expectedWeekDay,
+ int expectedStartTimeOfDayInSec,
+ int expectedEndTimeOfDayInSec,
+ ProgramTime actualProgramTime) {
assertEquals("Weekday", expectedWeekDay, actualProgramTime.weekDay);
- assertEquals("StartTimeOfDayInSec", expectedStartTimeOfDayInSec,
+ assertEquals(
+ "StartTimeOfDayInSec",
+ expectedStartTimeOfDayInSec,
actualProgramTime.startTimeOfDayInSec);
- assertEquals("EndTimeOfDayInSec", expectedEndTimeOfDayInSec,
+ assertEquals(
+ "EndTimeOfDayInSec",
+ expectedEndTimeOfDayInSec,
actualProgramTime.endTimeOfDayInSec);
}
- private void assertOverlappedIntervalScore(int expectedSeconds, boolean overlappedOnSameDay,
- ProgramTime t1, ProgramTime t2) {
+ private void assertOverlappedIntervalScore(
+ int expectedSeconds, boolean overlappedOnSameDay, ProgramTime t1, ProgramTime t2) {
double score = expectedSeconds;
if (!overlappedOnSameDay) {
score *= RoutineWatchEvaluator.MULTIPLIER_FOR_UNMATCHED_DAY_OF_WEEK;
}
// Two tests for testing commutative law.
- assertEqualScores("OverlappedIntervalScore", score,
+ assertEqualScores(
+ "OverlappedIntervalScore",
+ score,
RoutineWatchEvaluator.calculateOverlappedIntervalScore(t1, t2));
- assertEqualScores("OverlappedIntervalScore", score,
+ assertEqualScores(
+ "OverlappedIntervalScore",
+ score,
RoutineWatchEvaluator.calculateOverlappedIntervalScore(t2, t1));
}
@@ -270,12 +320,9 @@ public class RoutineWatchEvaluatorTest extends EvaluatorTestCase<RoutineWatchEva
private Program createDummyProgram(Calendar startTime, long programDurationMs) {
long startTimeMs = startTime.getTimeInMillis();
- return new Program.Builder().setStartTimeUtcMillis(startTimeMs)
- .setEndTimeUtcMillis(startTimeMs + programDurationMs).build();
- }
-
- private static <T> void assertInOrder(T... items) {
- TreeSet<T> copy = new TreeSet<>(Arrays.asList(items));
- MoreAsserts.assertContentsInOrder(copy, items);
+ return new Program.Builder()
+ .setStartTimeUtcMillis(startTimeMs)
+ .setEndTimeUtcMillis(startTimeMs + programDurationMs)
+ .build();
}
}
diff --git a/tests/unit/src/com/android/tv/search/LocalSearchProviderTest.java b/tests/unit/src/com/android/tv/search/LocalSearchProviderTest.java
deleted file mode 100644
index b0d342c6..00000000
--- a/tests/unit/src/com/android/tv/search/LocalSearchProviderTest.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright (C) 2017 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.search;
-
-import static android.support.test.InstrumentationRegistry.getTargetContext;
-import static org.mockito.Mockito.clearInvocations;
-import static org.mockito.Mockito.verify;
-
-import android.app.SearchManager;
-import android.database.Cursor;
-import android.net.Uri;
-import android.support.test.filters.SmallTest;
-import android.test.ProviderTestCase2;
-
-import com.android.tv.ApplicationSingletons;
-import com.android.tv.TvApplication;
-import com.android.tv.perf.PerformanceMonitor;
-import com.android.tv.util.MockApplicationSingletons;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-/** Unit test for {@link LocalSearchProvider}. */
-@SmallTest
-public class LocalSearchProviderTest extends ProviderTestCase2<LocalSearchProvider> {
- private static final String AUTHORITY = "com.android.tv.search";
- private static final String KEYWORD = "keyword";
- private static final Uri BASE_SEARCH_URI = Uri.parse("content://" + AUTHORITY + "/"
- + SearchManager.SUGGEST_URI_PATH_QUERY + "/" + KEYWORD);
- private static final Uri WRONG_SERACH_URI = Uri.parse("content://" + AUTHORITY + "/wrong_path/"
- + KEYWORD);
-
- private ApplicationSingletons mOldAppSingletons;
- MockApplicationSingletons mMockAppSingletons;
- @Mock PerformanceMonitor mMockPerformanceMointor;
- @Mock SearchInterface mMockSearchInterface;
-
- public LocalSearchProviderTest() {
- super(LocalSearchProvider.class, AUTHORITY);
- }
-
- @Before
- @Override
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
- setContext(getTargetContext());
- mOldAppSingletons = TvApplication.sAppSingletons;
- mMockAppSingletons = new MockApplicationSingletons(getTargetContext());
- mMockAppSingletons.setPerformanceMonitor(mMockPerformanceMointor);
- TvApplication.sAppSingletons = mMockAppSingletons;
- super.setUp();
- getProvider().setSearchInterface(mMockSearchInterface);
- }
-
- @After
- @Override
- public void tearDown() throws Exception {
- TvApplication.sAppSingletons = mOldAppSingletons;
- super.tearDown();
- }
-
- @Test
- public void testQuery_normalUri() {
- verifyQueryWithArguments(null, null);
- verifyQueryWithArguments(1, null);
- verifyQueryWithArguments(null, 1);
- verifyQueryWithArguments(1, 1);
- }
-
- @Test
- public void testQuery_invalidUri() {
- try (Cursor c = getProvider().query(WRONG_SERACH_URI, null, null, null, null)) {
- fail("Query with invalid URI should fail.");
- } catch (IllegalArgumentException e) {
- // Success.
- }
- }
-
- @Test
- public void testQuery_invalidLimit() {
- verifyQueryWithArguments(-1, null);
- }
-
- @Test
- public void testQuery_invalidAction() {
- verifyQueryWithArguments(null, SearchInterface.ACTION_TYPE_START - 1);
- verifyQueryWithArguments(null, SearchInterface.ACTION_TYPE_END + 1);
- }
-
- private void verifyQueryWithArguments(Integer limit, Integer action) {
- Uri uri = BASE_SEARCH_URI;
- if (limit != null || action != null) {
- Uri.Builder builder = uri.buildUpon();
- if (limit != null) {
- builder.appendQueryParameter(SearchManager.SUGGEST_PARAMETER_LIMIT,
- limit.toString());
- }
- if (action != null) {
- builder.appendQueryParameter(LocalSearchProvider.SUGGEST_PARAMETER_ACTION,
- action.toString());
- }
- uri = builder.build();
- }
- try (Cursor c = getProvider().query(uri, null, null, null, null)) {
- // Do nothing.
- }
- int expectedLimit = limit == null || limit <= 0 ?
- LocalSearchProvider.DEFAULT_SEARCH_LIMIT : limit;
- int expectedAction = (action == null || action < SearchInterface.ACTION_TYPE_START
- || action > SearchInterface.ACTION_TYPE_END) ?
- LocalSearchProvider.DEFAULT_SEARCH_ACTION : action;
- verify(mMockSearchInterface).search(KEYWORD, expectedLimit, expectedAction);
- clearInvocations(mMockSearchInterface);
- }
-}
diff --git a/tests/unit/src/com/android/tv/tests/TvActivityTest.java b/tests/unit/src/com/android/tv/tests/TvActivityTest.java
deleted file mode 100644
index aa33f770..00000000
--- a/tests/unit/src/com/android/tv/tests/TvActivityTest.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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;
-
-import static android.support.test.InstrumentationRegistry.getTargetContext;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import android.support.test.filters.MediumTest;
-import android.support.test.rule.ActivityTestRule;
-
-import com.android.tv.TvActivity;
-import com.android.tv.testing.Utils;
-
-import org.junit.Rule;
-import org.junit.Test;
-
-@MediumTest
-public class TvActivityTest {
- @Rule
- public ActivityTestRule<TvActivity> mActivityTestRule =
- new ActivityTestRule<>(TvActivity.class, false, false);
-
- @Test
- public void testLifeCycle() {
- assertTrue("TvActivity should be enabled.", Utils.isTvActivityEnabled(getTargetContext()));
- assertNotNull(mActivityTestRule.launchActivity(null));
- }
-}
diff --git a/tests/unit/src/com/android/tv/util/MockApplicationSingletons.java b/tests/unit/src/com/android/tv/util/MockTvSingletons.java
index 4cfc7f8a..6de1eb3e 100644
--- a/tests/unit/src/com/android/tv/util/MockApplicationSingletons.java
+++ b/tests/unit/src/com/android/tv/util/MockTvSingletons.java
@@ -17,34 +17,41 @@
package com.android.tv.util;
import android.content.Context;
-
-import com.android.tv.ApplicationSingletons;
+import android.content.Intent;
import com.android.tv.InputSessionManager;
import com.android.tv.MainActivityWrapper;
import com.android.tv.TvApplication;
+import com.android.tv.TvSingletons;
import com.android.tv.analytics.Analytics;
import com.android.tv.analytics.Tracker;
-import com.android.tv.config.RemoteConfig;
+import com.android.tv.common.config.api.RemoteConfig;
+import com.android.tv.common.experiments.ExperimentLoader;
+import com.android.tv.common.recording.RecordingStorageStatusManager;
+import com.android.tv.common.util.Clock;
import com.android.tv.data.ChannelDataManager;
import com.android.tv.data.PreviewDataManager;
import com.android.tv.data.ProgramDataManager;
+import com.android.tv.data.epg.EpgFetcher;
+import com.android.tv.data.epg.EpgReader;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.DvrManager;
import com.android.tv.dvr.DvrScheduleManager;
-import com.android.tv.dvr.DvrStorageStatusManager;
import com.android.tv.dvr.DvrWatchedPositionManager;
import com.android.tv.dvr.recorder.RecordingScheduler;
import com.android.tv.perf.PerformanceMonitor;
+import com.android.tv.testing.FakeClock;
+import com.android.tv.tuner.TunerInputController;
+import java.util.concurrent.Executor;
+import javax.inject.Provider;
-/**
- * Mock {@link ApplicationSingletons} class.
- */
-public class MockApplicationSingletons implements ApplicationSingletons {
- private final TvApplication mApp;
+/** Mock {@link TvSingletons} class. */
+public class MockTvSingletons implements TvSingletons {
+ public final FakeClock fakeClock = FakeClock.createWithCurrentTime();
+ private final TvApplication mApp;
private PerformanceMonitor mPerformanceMonitor;
- public MockApplicationSingletons(Context context) {
+ public MockTvSingletons(Context context) {
mApp = (TvApplication) context.getApplicationContext();
}
@@ -54,6 +61,9 @@ public class MockApplicationSingletons implements ApplicationSingletons {
}
@Override
+ public void handleInputCountChanged() {}
+
+ @Override
public ChannelDataManager getChannelDataManager() {
return mApp.getChannelDataManager();
}
@@ -84,8 +94,13 @@ public class MockApplicationSingletons implements ApplicationSingletons {
}
@Override
- public DvrStorageStatusManager getDvrStorageStatusManager() {
- return mApp.getDvrStorageStatusManager();
+ public Clock getClock() {
+ return fakeClock;
+ }
+
+ @Override
+ public RecordingStorageStatusManager getRecordingStorageStatusManager() {
+ return mApp.getRecordingStorageStatusManager();
}
@Override
@@ -124,12 +139,37 @@ public class MockApplicationSingletons implements ApplicationSingletons {
}
@Override
+ public Provider<EpgReader> providesEpgReader() {
+ return mApp.providesEpgReader();
+ }
+
+ @Override
+ public EpgFetcher getEpgFetcher() {
+ return mApp.getEpgFetcher();
+ }
+
+ @Override
+ public SetupUtils getSetupUtils() {
+ return mApp.getSetupUtils();
+ }
+
+ @Override
+ public TunerInputController getTunerInputController() {
+ return mApp.getTunerInputController();
+ }
+
+ @Override
+ public ExperimentLoader getExperimentLoader() {
+ return mApp.getExperimentLoader();
+ }
+
+ @Override
public MainActivityWrapper getMainActivityWrapper() {
return mApp.getMainActivityWrapper();
}
@Override
- public AccountHelper getAccountHelper() {
+ public com.android.tv.util.account.AccountHelper getAccountHelper() {
return mApp.getAccountHelper();
}
@@ -139,6 +179,11 @@ public class MockApplicationSingletons implements ApplicationSingletons {
}
@Override
+ public Intent getTunerSetupIntent(Context context) {
+ return mApp.getTunerSetupIntent(context);
+ }
+
+ @Override
public boolean isRunningInMainProcess() {
return mApp.isRunningInMainProcess();
}
@@ -151,4 +196,14 @@ public class MockApplicationSingletons implements ApplicationSingletons {
public void setPerformanceMonitor(PerformanceMonitor performanceMonitor) {
mPerformanceMonitor = performanceMonitor;
}
+
+ @Override
+ public String getEmbeddedTunerInputId() {
+ return "com.android.tv/.tuner.tvinput.LiveTvTunerTvInputService";
+ }
+
+ @Override
+ public Executor getDbExecutor() {
+ return mApp.getDbExecutor();
+ }
}
diff --git a/tests/unit/src/com/android/tv/util/MultiLongSparseArrayTest.java b/tests/unit/src/com/android/tv/util/MultiLongSparseArrayTest.java
deleted file mode 100644
index 7335f207..00000000
--- a/tests/unit/src/com/android/tv/util/MultiLongSparseArrayTest.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * 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.util;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertSame;
-
-import android.support.test.filters.SmallTest;
-import android.test.MoreAsserts;
-
-import org.junit.Test;
-
-import java.util.Collections;
-
-/**
- * Tests for {@link MultiLongSparseArray}.
- */
-@SmallTest
-public class MultiLongSparseArrayTest {
- @Test
- public void testEmpty() {
- MultiLongSparseArray<String> sparseArray = new MultiLongSparseArray<>();
- assertSame(Collections.EMPTY_SET, sparseArray.get(0));
- }
-
- @Test
- public void testOneElement() {
- MultiLongSparseArray<String> sparseArray = new MultiLongSparseArray<>();
- sparseArray.put(0, "foo");
- MoreAsserts.assertContentsInAnyOrder(sparseArray.get(0), "foo");
- }
-
- @Test
- public void testTwoElements() {
- MultiLongSparseArray<String> sparseArray = new MultiLongSparseArray<>();
- sparseArray.put(0, "foo");
- sparseArray.put(0, "bar");
- MoreAsserts.assertContentsInAnyOrder(sparseArray.get(0), "foo", "bar");
- }
-
-
- @Test
- public void testClearEmptyCache() {
- MultiLongSparseArray<String> sparseArray = new MultiLongSparseArray<>();
- sparseArray.clearEmptyCache();
- assertEquals(0, sparseArray.getEmptyCacheSize());
- sparseArray.put(0, "foo");
- sparseArray.remove(0, "foo");
- assertEquals(1, sparseArray.getEmptyCacheSize());
- sparseArray.clearEmptyCache();
- assertEquals(0, sparseArray.getEmptyCacheSize());
- }
-
- @Test
- public void testMaxEmptyCacheSize() {
- MultiLongSparseArray<String> sparseArray = new MultiLongSparseArray<>();
- sparseArray.clearEmptyCache();
- assertEquals(0, sparseArray.getEmptyCacheSize());
- for (int i = 0; i <= MultiLongSparseArray.DEFAULT_MAX_EMPTIES_KEPT + 2; i++) {
- sparseArray.put(i, "foo");
- }
- for (int i = 0; i <= MultiLongSparseArray.DEFAULT_MAX_EMPTIES_KEPT + 2; i++) {
- sparseArray.remove(i, "foo");
- }
- assertEquals(MultiLongSparseArray.DEFAULT_MAX_EMPTIES_KEPT,
- sparseArray.getEmptyCacheSize());
- sparseArray.clearEmptyCache();
- assertEquals(0, sparseArray.getEmptyCacheSize());
- }
-
- @Test
- public void testReuseEmptySets() {
- MultiLongSparseArray<String> sparseArray = new MultiLongSparseArray<>();
- sparseArray.clearEmptyCache();
- assertEquals(0, sparseArray.getEmptyCacheSize());
- // create a bunch of sets
- for (int i = 0; i <= MultiLongSparseArray.DEFAULT_MAX_EMPTIES_KEPT + 2; i++) {
- sparseArray.put(i, "foo");
- }
- // remove them so they are all put in the cache.
- for (int i = 0; i <= MultiLongSparseArray.DEFAULT_MAX_EMPTIES_KEPT + 2; i++) {
- sparseArray.remove(i, "foo");
- }
- assertEquals(MultiLongSparseArray.DEFAULT_MAX_EMPTIES_KEPT,
- sparseArray.getEmptyCacheSize());
-
- // now create elements, that use the cached empty sets.
- for (int i = 0; i < MultiLongSparseArray.DEFAULT_MAX_EMPTIES_KEPT; i++) {
- sparseArray.put(10 + i, "bar");
- assertEquals(MultiLongSparseArray.DEFAULT_MAX_EMPTIES_KEPT - i - 1,
- sparseArray.getEmptyCacheSize());
- }
- }
-}
diff --git a/tests/unit/src/com/android/tv/util/ScaledBitmapInfoTest.java b/tests/unit/src/com/android/tv/util/ScaledBitmapInfoTest.java
deleted file mode 100644
index 2714e2e9..00000000
--- a/tests/unit/src/com/android/tv/util/ScaledBitmapInfoTest.java
+++ /dev/null
@@ -1,59 +0,0 @@
-package com.android.tv.util;
-
-import static org.junit.Assert.assertEquals;
-
-import android.graphics.Bitmap;
-import android.support.test.filters.SmallTest;
-
-import com.android.tv.util.BitmapUtils.ScaledBitmapInfo;
-
-import org.junit.Test;
-
-/**
- * Tests for {@link ScaledBitmapInfo}.
- */
-@SmallTest
-public class ScaledBitmapInfoTest {
- private static final Bitmap B80x100 = Bitmap.createBitmap(80, 100, Bitmap.Config.RGB_565);
- private static final Bitmap B960x1440 = Bitmap.createBitmap(960, 1440, Bitmap.Config.RGB_565);
-
- @Test
- public void testSize_B100x100to50x50() {
- ScaledBitmapInfo actual = BitmapUtils.createScaledBitmapInfo("B80x100", B80x100, 50, 50);
- assertScaledBitmapSize(2, 40, 50, actual);
- }
-
- @Test
- public void testNeedsToReload_B100x100to50x50() {
- ScaledBitmapInfo actual = BitmapUtils.createScaledBitmapInfo("B80x100", B80x100, 50, 50);
- assertNeedsToReload(false, actual, 25, 25);
- assertNeedsToReload(false, actual, 50, 50);
- assertNeedsToReload(false, actual, 99, 99);
- assertNeedsToReload(true, actual, 100, 100);
- assertNeedsToReload(true, actual, 101, 101);
- }
-
- /**
- * Reproduces <a href="http://b/20488453">b/20488453</a>.
- */
- @Test
- public void testBug20488453() {
- ScaledBitmapInfo actual = BitmapUtils
- .createScaledBitmapInfo("B960x1440", B960x1440, 284, 160);
- assertScaledBitmapSize(8, 107, 160, actual);
- assertNeedsToReload(false, actual, 284, 160);
- }
-
- private static void assertNeedsToReload(boolean expected, ScaledBitmapInfo scaledBitmap,
- int reqWidth, int reqHeight) {
- assertEquals(scaledBitmap.id + " needToReload(" + reqWidth + "," + reqHeight + ")",
- expected, scaledBitmap.needToReload(reqWidth, reqHeight));
- }
-
- private static void assertScaledBitmapSize(int expectedInSampleSize, int expectedWidth,
- int expectedHeight, ScaledBitmapInfo actual) {
- assertEquals(actual.id + " inSampleSize", expectedInSampleSize, actual.inSampleSize);
- assertEquals(actual.id + " width", expectedWidth, actual.bitmap.getWidth());
- assertEquals(actual.id + " height", expectedHeight, actual.bitmap.getHeight());
- }
-}
diff --git a/tests/unit/src/com/android/tv/util/TestUtils.java b/tests/unit/src/com/android/tv/util/TestUtils.java
deleted file mode 100644
index d200733d..00000000
--- a/tests/unit/src/com/android/tv/util/TestUtils.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * 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.util;
-
-import android.content.pm.ResolveInfo;
-import android.content.pm.ServiceInfo;
-import android.graphics.drawable.Icon;
-import android.hardware.hdmi.HdmiDeviceInfo;
-import android.media.tv.TvInputInfo;
-import android.os.Build;
-import android.os.Bundle;
-
-import java.lang.reflect.Constructor;
-
-/**
- * A class that includes convenience methods for testing.
- */
-public class TestUtils {
- /**
- * Creates a {@link TvInputInfo}.
- */
- public static TvInputInfo createTvInputInfo(ResolveInfo service, String id, String parentId,
- int type, boolean isHardwareInput) throws Exception {
- return createTvInputInfo(service, id, parentId, type, isHardwareInput, false, 0);
- }
-
- /**
- * Creates a {@link TvInputInfo}.
- * <p>
- * If this is called on MNC, {@code canRecord} and {@code tunerCount} are ignored.
- */
- public static TvInputInfo createTvInputInfo(ResolveInfo service, String id, String parentId,
- int type, boolean isHardwareInput, boolean canRecord, int tunerCount) throws Exception {
- // Create a mock TvInputInfo by using private constructor
- // Note that mockito doesn't support mock/spy on final object.
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- return createTvInputInfoForO(service, id, parentId, type, isHardwareInput, canRecord,
- tunerCount);
-
- } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
- return createTvInputInfoForNyc(service, id, parentId, type, isHardwareInput, canRecord,
- tunerCount);
- }
- return createTvInputInfoForMnc(service, id, parentId, type, isHardwareInput);
- }
-
- /**
- * private TvInputInfo(ResolveInfo service, String id, int type, boolean isHardwareInput,
- * CharSequence label, int labelResId, Icon icon, Icon iconStandby, Icon iconDisconnected,
- * String setupActivity, boolean canRecord, int tunerCount, HdmiDeviceInfo hdmiDeviceInfo,
- * boolean isConnectedToHdmiSwitch, String parentId, Bundle extras) {
- */
- private static TvInputInfo createTvInputInfoForO(ResolveInfo service, String id,
- String parentId, int type, boolean isHardwareInput, boolean canRecord, int tunerCount)
- throws Exception {
- Constructor<TvInputInfo> constructor = TvInputInfo.class.getDeclaredConstructor(
- ResolveInfo.class, String.class, int.class, boolean.class, CharSequence.class,
- int.class, Icon.class, Icon.class, Icon.class, String.class, boolean.class,
- int.class, HdmiDeviceInfo.class, boolean.class, String.class, Bundle.class);
- constructor.setAccessible(true);
- return constructor.newInstance(service, id, type, isHardwareInput, null, 0, null, null,
- null, null, canRecord, tunerCount, null, false, parentId, null);
- }
-
- /**
- * private TvInputInfo(ResolveInfo service, String id, int type, boolean isHardwareInput,
- * CharSequence label, int labelResId, Icon icon, Icon iconStandby, Icon iconDisconnected,
- * String setupActivity, String settingsActivity, boolean canRecord, int tunerCount,
- * HdmiDeviceInfo hdmiDeviceInfo, boolean isConnectedToHdmiSwitch, String parentId,
- * Bundle extras) {
- */
- private static TvInputInfo createTvInputInfoForNyc(ResolveInfo service, String id,
- String parentId, int type, boolean isHardwareInput, boolean canRecord, int tunerCount)
- throws Exception {
- Constructor<TvInputInfo> constructor = TvInputInfo.class.getDeclaredConstructor(
- ResolveInfo.class, String.class, int.class, boolean.class, CharSequence.class,
- int.class, Icon.class, Icon.class, Icon.class, String.class, String.class,
- boolean.class, int.class, HdmiDeviceInfo.class, boolean.class, String.class,
- Bundle.class);
- constructor.setAccessible(true);
- return constructor.newInstance(service, id, type, isHardwareInput, null, 0, null, null,
- null, null, null, canRecord, tunerCount, null, false, parentId, null);
- }
-
- private static TvInputInfo createTvInputInfoForMnc(ResolveInfo service, String id,
- String parentId, int type, boolean isHardwareInput) throws Exception {
- Constructor<TvInputInfo> constructor = TvInputInfo.class.getDeclaredConstructor(
- ResolveInfo.class, String.class, String.class, int.class, boolean.class);
- constructor.setAccessible(true);
- return constructor.newInstance(service, id, parentId, type, isHardwareInput);
- }
-
- public static ResolveInfo createResolveInfo(String packageName, String name) {
- ResolveInfo resolveInfo = new ResolveInfo();
- resolveInfo.serviceInfo = new ServiceInfo();
- resolveInfo.serviceInfo.packageName = packageName;
- resolveInfo.serviceInfo.name = name;
- resolveInfo.serviceInfo.metaData = new Bundle();
- return resolveInfo;
- }
-}
diff --git a/tests/unit/src/com/android/tv/util/TvInputManagerHelperTest.java b/tests/unit/src/com/android/tv/util/TvInputManagerHelperTest.java
index 404ee5d3..6dfed64a 100644
--- a/tests/unit/src/com/android/tv/util/TvInputManagerHelperTest.java
+++ b/tests/unit/src/com/android/tv/util/TvInputManagerHelperTest.java
@@ -21,22 +21,21 @@ import static android.support.test.InstrumentationRegistry.getContext;
import android.content.pm.ResolveInfo;
import android.media.tv.TvInputInfo;
import android.support.test.filters.SmallTest;
-
+import android.support.test.runner.AndroidJUnit4;
import com.android.tv.testing.ComparatorTester;
-
+import com.android.tv.testing.utils.TestUtils;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
import org.junit.Test;
+import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-
-/**
- * Test for {@link TvInputManagerHelper}
- */
+/** Test for {@link TvInputManagerHelper} */
@SmallTest
+@RunWith(AndroidJUnit4.class)
public class TvInputManagerHelperTest {
final HashMap<String, TvInputInfoWrapper> TEST_INPUT_MAP = new HashMap<>();
@@ -45,18 +44,51 @@ public class TvInputManagerHelperTest {
ResolveInfo resolveInfo = TestUtils.createResolveInfo("test", "test");
List<TvInputInfo> inputs = new ArrayList<>();
- inputs.add(createTvInputInfo(resolveInfo, "2_partner_input", null, 0, false,
- "2_partner_input", null, true));
- inputs.add(createTvInputInfo(resolveInfo, "3_partner_input", null, 0, false,
- "3_partner_input", null, true));
- inputs.add(createTvInputInfo(resolveInfo, "1_3rd_party_input", null, 0, false,
- "1_3rd_party_input", null, false));
- inputs.add(createTvInputInfo(resolveInfo, "4_3rd_party_input", null, 0, false,
- "4_3rd_party_input", null, false));
+ inputs.add(
+ createTvInputInfo(
+ resolveInfo,
+ "2_partner_input",
+ null,
+ 0,
+ false,
+ "2_partner_input",
+ null,
+ true));
+ inputs.add(
+ createTvInputInfo(
+ resolveInfo,
+ "3_partner_input",
+ null,
+ 0,
+ false,
+ "3_partner_input",
+ null,
+ true));
+ inputs.add(
+ createTvInputInfo(
+ resolveInfo,
+ "1_3rd_party_input",
+ null,
+ 0,
+ false,
+ "1_3rd_party_input",
+ null,
+ false));
+ inputs.add(
+ createTvInputInfo(
+ resolveInfo,
+ "4_3rd_party_input",
+ null,
+ 0,
+ false,
+ "4_3rd_party_input",
+ null,
+ false));
TvInputManagerHelper manager = createMockTvInputManager();
- ComparatorTester<TvInputInfo> comparatorTester = ComparatorTester.withoutEqualsTest(
+ ComparatorTester<TvInputInfo> comparatorTester =
+ ComparatorTester.withoutEqualsTest(
new TvInputManagerHelper.InputComparatorInternal(manager));
for (TvInputInfo input : inputs) {
comparatorTester.addComparableGroup(input);
@@ -68,20 +100,54 @@ public class TvInputManagerHelperTest {
public void testHardwareInputComparatorHdmi() {
ResolveInfo resolveInfo = TestUtils.createResolveInfo("test", "test");
- TvInputInfo hdmi1 = createTvInputInfo(resolveInfo, "HDMI1", null, TvInputInfo.TYPE_HDMI,
- true, "HDMI1", null, false);
- TvInputInfo hdmi2 = createTvInputInfo(resolveInfo, "HDMI2", null, TvInputInfo.TYPE_HDMI,
- true, "HDMI2", "DVD", false);
- TvInputInfo hdmi3 = createTvInputInfo(resolveInfo, "HDMI3", null, TvInputInfo.TYPE_HDMI,
- true, "HDMI3", "Cable", false);
- TvInputInfo hdmi4 = createTvInputInfo(resolveInfo, "HDMI4", null, TvInputInfo.TYPE_HDMI,
- true, "HDMI4", null, false);
+ TvInputInfo hdmi1 =
+ createTvInputInfo(
+ resolveInfo,
+ "HDMI1",
+ null,
+ TvInputInfo.TYPE_HDMI,
+ true,
+ "HDMI1",
+ null,
+ false);
+ TvInputInfo hdmi2 =
+ createTvInputInfo(
+ resolveInfo,
+ "HDMI2",
+ null,
+ TvInputInfo.TYPE_HDMI,
+ true,
+ "HDMI2",
+ "DVD",
+ false);
+ TvInputInfo hdmi3 =
+ createTvInputInfo(
+ resolveInfo,
+ "HDMI3",
+ null,
+ TvInputInfo.TYPE_HDMI,
+ true,
+ "HDMI3",
+ "Cable",
+ false);
+ TvInputInfo hdmi4 =
+ createTvInputInfo(
+ resolveInfo,
+ "HDMI4",
+ null,
+ TvInputInfo.TYPE_HDMI,
+ true,
+ "HDMI4",
+ null,
+ false);
TvInputManagerHelper manager = createMockTvInputManager();
- ComparatorTester<TvInputInfo> comparatorTester = ComparatorTester.withoutEqualsTest(
+ ComparatorTester<TvInputInfo> comparatorTester =
+ ComparatorTester.withoutEqualsTest(
new TvInputManagerHelper.HardwareInputComparator(getContext(), manager));
- comparatorTester.addComparableGroup(hdmi3)
+ comparatorTester
+ .addComparableGroup(hdmi3)
.addComparableGroup(hdmi2)
.addComparableGroup(hdmi1)
.addComparableGroup(hdmi4)
@@ -92,61 +158,111 @@ public class TvInputManagerHelperTest {
public void testHardwareInputComparatorCec() {
ResolveInfo resolveInfo = TestUtils.createResolveInfo("test", "test");
- TvInputInfo hdmi1 = createTvInputInfo(resolveInfo, "HDMI1", null, TvInputInfo.TYPE_HDMI,
- true, "HDMI1", null, false);
- TvInputInfo hdmi2 = createTvInputInfo(resolveInfo, "HDMI2", null, TvInputInfo.TYPE_HDMI,
- true, "HDMI2", null, false);
+ TvInputInfo hdmi1 =
+ createTvInputInfo(
+ resolveInfo,
+ "HDMI1",
+ null,
+ TvInputInfo.TYPE_HDMI,
+ true,
+ "HDMI1",
+ null,
+ false);
+ TvInputInfo hdmi2 =
+ createTvInputInfo(
+ resolveInfo,
+ "HDMI2",
+ null,
+ TvInputInfo.TYPE_HDMI,
+ true,
+ "HDMI2",
+ null,
+ false);
- TvInputInfo cec1 = createTvInputInfo(resolveInfo, "2_cec", "HDMI1", TvInputInfo.TYPE_HDMI,
- true, "2_cec", null, false);
- TvInputInfo cec2 = createTvInputInfo(resolveInfo, "1_cec", "HDMI2", TvInputInfo.TYPE_HDMI,
- true, "1_cec", null, false);
+ TvInputInfo cec1 =
+ createTvInputInfo(
+ resolveInfo,
+ "2_cec",
+ "HDMI1",
+ TvInputInfo.TYPE_HDMI,
+ true,
+ "2_cec",
+ null,
+ false);
+ TvInputInfo cec2 =
+ createTvInputInfo(
+ resolveInfo,
+ "1_cec",
+ "HDMI2",
+ TvInputInfo.TYPE_HDMI,
+ true,
+ "1_cec",
+ null,
+ false);
TvInputManagerHelper manager = createMockTvInputManager();
- ComparatorTester<TvInputInfo> comparatorTester = ComparatorTester.withoutEqualsTest(
+ ComparatorTester<TvInputInfo> comparatorTester =
+ ComparatorTester.withoutEqualsTest(
new TvInputManagerHelper.HardwareInputComparator(getContext(), manager));
- comparatorTester.addComparableGroup(cec1)
- .addComparableGroup(cec2)
- .test();
+ comparatorTester.addComparableGroup(cec1).addComparableGroup(cec2).test();
}
private TvInputManagerHelper createMockTvInputManager() {
TvInputManagerHelper manager = Mockito.mock(TvInputManagerHelper.class);
- Mockito.doAnswer(new Answer<Boolean>() {
- @Override
- public Boolean answer(InvocationOnMock invocation) throws Throwable {
- TvInputInfo info = (TvInputInfo) invocation.getArguments()[0];
- return TEST_INPUT_MAP.get(info.getId()).mIsPartnerInput;
- }
- }).when(manager).isPartnerInput(Mockito.<TvInputInfo>any());
- Mockito.doAnswer(new Answer<String>() {
- @Override
- public String answer(InvocationOnMock invocation) throws Throwable {
- TvInputInfo info = (TvInputInfo) invocation.getArguments()[0];
- return TEST_INPUT_MAP.get(info.getId()).mLabel;
- }
- }).when(manager).loadLabel(Mockito.<TvInputInfo>any());
- Mockito.doAnswer(new Answer<String>() {
- @Override
- public String answer(InvocationOnMock invocation) throws Throwable {
- TvInputInfo info = (TvInputInfo) invocation.getArguments()[0];
- return TEST_INPUT_MAP.get(info.getId()).mCustomLabel;
- }
- }).when(manager).loadCustomLabel(Mockito.<TvInputInfo>any());
- Mockito.doAnswer(new Answer<TvInputInfo>() {
- @Override
- public TvInputInfo answer(InvocationOnMock invocation) throws Throwable {
- String inputId = (String) invocation.getArguments()[0];
- TvInputInfoWrapper inputWrapper = TEST_INPUT_MAP.get(inputId);
- return inputWrapper == null ? null : inputWrapper.mInput;
- }
- }).when(manager).getTvInputInfo(Mockito.<String>any());
+ Mockito.doAnswer(
+ new Answer<Boolean>() {
+ @Override
+ public Boolean answer(InvocationOnMock invocation) throws Throwable {
+ TvInputInfo info = (TvInputInfo) invocation.getArguments()[0];
+ return TEST_INPUT_MAP.get(info.getId()).mIsPartnerInput;
+ }
+ })
+ .when(manager)
+ .isPartnerInput(Mockito.<TvInputInfo>any());
+ Mockito.doAnswer(
+ new Answer<String>() {
+ @Override
+ public String answer(InvocationOnMock invocation) throws Throwable {
+ TvInputInfo info = (TvInputInfo) invocation.getArguments()[0];
+ return TEST_INPUT_MAP.get(info.getId()).mLabel;
+ }
+ })
+ .when(manager)
+ .loadLabel(Mockito.<TvInputInfo>any());
+ Mockito.doAnswer(
+ new Answer<String>() {
+ @Override
+ public String answer(InvocationOnMock invocation) throws Throwable {
+ TvInputInfo info = (TvInputInfo) invocation.getArguments()[0];
+ return TEST_INPUT_MAP.get(info.getId()).mCustomLabel;
+ }
+ })
+ .when(manager)
+ .loadCustomLabel(Mockito.<TvInputInfo>any());
+ Mockito.doAnswer(
+ new Answer<TvInputInfo>() {
+ @Override
+ public TvInputInfo answer(InvocationOnMock invocation)
+ throws Throwable {
+ String inputId = (String) invocation.getArguments()[0];
+ TvInputInfoWrapper inputWrapper = TEST_INPUT_MAP.get(inputId);
+ return inputWrapper == null ? null : inputWrapper.mInput;
+ }
+ })
+ .when(manager)
+ .getTvInputInfo(Mockito.<String>any());
return manager;
}
- private TvInputInfo createTvInputInfo(ResolveInfo service, String id,
- String parentId, int type, boolean isHardwareInput, String label, String customLabel,
+ private TvInputInfo createTvInputInfo(
+ ResolveInfo service,
+ String id,
+ String parentId,
+ int type,
+ boolean isHardwareInput,
+ String label,
+ String customLabel,
boolean isPartnerInput) {
TvInputInfoWrapper inputWrapper = new TvInputInfoWrapper();
try {
diff --git a/tests/unit/src/com/android/tv/util/TvTrackInfoUtilsTest.java b/tests/unit/src/com/android/tv/util/TvTrackInfoUtilsTest.java
index 4512bb7d..d84a90d4 100644
--- a/tests/unit/src/com/android/tv/util/TvTrackInfoUtilsTest.java
+++ b/tests/unit/src/com/android/tv/util/TvTrackInfoUtilsTest.java
@@ -16,24 +16,22 @@
package com.android.tv.util;
import static com.android.tv.util.TvTrackInfoUtils.getBestTrackInfo;
-import static org.junit.Assert.assertEquals;
+import static com.google.common.truth.Truth.assertWithMessage;
import android.media.tv.TvTrackInfo;
import android.support.test.filters.SmallTest;
-
+import android.support.test.runner.AndroidJUnit4;
import com.android.tv.testing.ComparatorTester;
-
-import org.junit.Test;
-
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
+import org.junit.Test;
+import org.junit.runner.RunWith;
-/**
- * Tests for {@link com.android.tv.util.TvTrackInfoUtils}.
- */
+/** Tests for {@link com.android.tv.util.TvTrackInfoUtils}. */
@SmallTest
+@RunWith(AndroidJUnit4.class)
public class TvTrackInfoUtilsTest {
private static final String UN_MATCHED_ID = "no matching ID";
@@ -54,57 +52,57 @@ public class TvTrackInfoUtilsTest {
.build();
}
- private static final List<TvTrackInfo> ALL = Arrays.asList(INFO_1_EN_1, INFO_2_EN_5,
- INFO_3_FR_8, INFO_4_NULL_2, INFO_5_NULL_6);
- private static final List<TvTrackInfo> NULL_LANGUAGE_TRACKS = Arrays.asList(INFO_4_NULL_2,
- INFO_5_NULL_6);
+ private static final List<TvTrackInfo> ALL =
+ Arrays.asList(INFO_1_EN_1, INFO_2_EN_5, INFO_3_FR_8, INFO_4_NULL_2, INFO_5_NULL_6);
+ private static final List<TvTrackInfo> NULL_LANGUAGE_TRACKS =
+ Arrays.asList(INFO_4_NULL_2, INFO_5_NULL_6);
@Test
public void testGetBestTrackInfo_empty() {
TvTrackInfo result = getBestTrackInfo(Collections.emptyList(), UN_MATCHED_ID, "en", 1);
- assertEquals("best track ", null, result);
+ assertWithMessage("best track ").that(result).isEqualTo(null);
}
@Test
public void testGetBestTrackInfo_exactMatch() {
TvTrackInfo result = getBestTrackInfo(ALL, "1", "en", 1);
- assertEquals("best track ", INFO_1_EN_1, result);
+ assertWithMessage("best track ").that(result).isEqualTo(INFO_1_EN_1);
}
@Test
public void testGetBestTrackInfo_langAndChannelCountMatch() {
TvTrackInfo result = getBestTrackInfo(ALL, UN_MATCHED_ID, "en", 5);
- assertEquals("best track ", INFO_2_EN_5, result);
+ assertWithMessage("best track ").that(result).isEqualTo(INFO_2_EN_5);
}
@Test
public void testGetBestTrackInfo_languageOnlyMatch() {
TvTrackInfo result = getBestTrackInfo(ALL, UN_MATCHED_ID, "fr", 1);
- assertEquals("best track ", INFO_3_FR_8, result);
+ assertWithMessage("best track ").that(result).isEqualTo(INFO_3_FR_8);
}
@Test
public void testGetBestTrackInfo_channelCountOnlyMatchWithNullLanguage() {
TvTrackInfo result = getBestTrackInfo(ALL, UN_MATCHED_ID, null, 8);
- assertEquals("best track ", INFO_3_FR_8, result);
+ assertWithMessage("best track ").that(result).isEqualTo(INFO_3_FR_8);
}
@Test
public void testGetBestTrackInfo_noMatches() {
TvTrackInfo result = getBestTrackInfo(ALL, UN_MATCHED_ID, "kr", 1);
- assertEquals("best track ", INFO_1_EN_1, result);
+ assertWithMessage("best track ").that(result).isEqualTo(INFO_1_EN_1);
}
@Test
public void testGetBestTrackInfo_noMatchesWithNullLanguage() {
TvTrackInfo result = getBestTrackInfo(ALL, UN_MATCHED_ID, null, 0);
- assertEquals("best track ", INFO_1_EN_1, result);
+ assertWithMessage("best track ").that(result).isEqualTo(INFO_1_EN_1);
}
@Test
public void testGetBestTrackInfo_channelCountAndIdMatch() {
TvTrackInfo result = getBestTrackInfo(NULL_LANGUAGE_TRACKS, "5", null, 6);
- assertEquals("best track ", INFO_5_NULL_6, result);
+ assertWithMessage("best track ").that(result).isEqualTo(INFO_5_NULL_6);
}
@Test
@@ -112,15 +110,17 @@ public class TvTrackInfoUtilsTest {
Comparator<TvTrackInfo> comparator = TvTrackInfoUtils.createComparator("1", "en", 1);
ComparatorTester.withoutEqualsTest(comparator)
// lang not match
- .addComparableGroup(create("1", "kr", 1), create("2", "kr", 2),
+ .addComparableGroup(
+ create("1", "kr", 1),
+ create("2", "kr", 2),
create("1", "ja", 1),
create("1", "ch", 1))
- // lang match not count match
- .addComparableGroup(create("2", "en", 2), create("3", "en", 3),
- create("1", "en", 2))
- // lang and count match
+ // lang match not count match
+ .addComparableGroup(
+ create("2", "en", 2), create("3", "en", 3), create("1", "en", 2))
+ // lang and count match
.addComparableGroup(create("2", "en", 1), create("3", "en", 1))
- // all match
+ // all match
.addComparableGroup(create("1", "en", 1), create("1", "en", 1))
.test();
}
diff --git a/tests/unit/src/com/android/tv/util/UtilsTest_GetDurationString.java b/tests/unit/src/com/android/tv/util/UtilsTest_GetDurationString.java
deleted file mode 100644
index e61802f5..00000000
--- a/tests/unit/src/com/android/tv/util/UtilsTest_GetDurationString.java
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * 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.util;
-
-import static android.support.test.InstrumentationRegistry.getContext;
-import static org.junit.Assert.assertEquals;
-
-import android.support.test.filters.SmallTest;
-import android.text.format.DateUtils;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import java.util.Calendar;
-import java.util.GregorianCalendar;
-import java.util.Locale;
-
-/**
- * Tests for {@link com.android.tv.util.Utils#getDurationString}.
- * <p/>
- * This test uses deprecated flags {@link DateUtils#FORMAT_12HOUR} and
- * {@link DateUtils#FORMAT_24HOUR} to run this test independent to system's 12/24h format.
- * Note that changing system setting requires permission android.permission.WRITE_SETTINGS
- * and it should be defined in TV app, not this test.
- */
-@SmallTest
-public class UtilsTest_GetDurationString {
- // TODO: Mock Context so we can specify current time and locale for test.
- private Locale mLocale;
- private static final long DATE_THIS_YEAR_2_1_MS = getFebOfThisYearInMillis(1, 0, 0);
-
- // All possible list for a parameter to test parameter independent result.
- private static final boolean[] PARAM_USE_SHORT_FORMAT = {false, true};
-
- @Before
- public void setUp() {
- // Set locale to US
- mLocale = Locale.getDefault();
- Locale.setDefault(Locale.US);
- }
-
- @After
- public void tearDown() {
- // Revive system locale.
- Locale.setDefault(mLocale);
- }
-
- /**
- * Return time in millis assuming that whose year is this year and month is Jan.
- */
- private static long getJanOfThisYearInMillis(int date, int hour, int minutes) {
- return new GregorianCalendar(getThisYear(), Calendar.JANUARY, date, hour, minutes)
- .getTimeInMillis();
- }
-
- private static long getJanOfThisYearInMillis(int date, int hour) {
- return getJanOfThisYearInMillis(date, hour, 0);
- }
-
- /**
- * Return time in millis assuming that whose year is this year and month is Feb.
- */
- private static long getFebOfThisYearInMillis(int date, int hour, int minutes) {
- return new GregorianCalendar(getThisYear(), Calendar.FEBRUARY, date, hour, minutes)
- .getTimeInMillis();
- }
-
- private static long getFebOfThisYearInMillis(int date, int hour) {
- return getFebOfThisYearInMillis(date, hour, 0);
- }
-
- private static int getThisYear() {
- return new GregorianCalendar().get(GregorianCalendar.YEAR);
- }
-
- @Test
- public void testSameDateAndTime() {
- assertEquals("3:00 AM", Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
- getFebOfThisYearInMillis(1, 3), getFebOfThisYearInMillis(1, 3), false,
- DateUtils.FORMAT_12HOUR));
- assertEquals("03:00", Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
- getFebOfThisYearInMillis(1, 3), getFebOfThisYearInMillis(1, 3), false,
- DateUtils.FORMAT_24HOUR));
- }
-
- @Test
- public void testDurationWithinToday() {
- assertEquals("12:00 – 3:00 AM",
- Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS, DATE_THIS_YEAR_2_1_MS,
- getFebOfThisYearInMillis(1, 3), false,
- DateUtils.FORMAT_12HOUR));
- assertEquals("00:00 – 03:00",
- Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS, DATE_THIS_YEAR_2_1_MS,
- getFebOfThisYearInMillis(1, 3), false,
- DateUtils.FORMAT_24HOUR));
- }
-
- @Test
- public void testDurationFromYesterdayToToday() {
- assertEquals("Jan 31, 3:00 AM – Feb 1, 4:00 AM",
- Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
- getJanOfThisYearInMillis(31, 3), getFebOfThisYearInMillis(1, 4), false,
- DateUtils.FORMAT_12HOUR));
- assertEquals("Jan 31, 03:00 – Feb 1, 04:00",
- Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
- getJanOfThisYearInMillis(31, 3), getFebOfThisYearInMillis(1, 4), false,
- DateUtils.FORMAT_24HOUR));
- assertEquals("1/31, 11:30 PM – 12:30 AM",
- Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
- getJanOfThisYearInMillis(31, 23, 30), getFebOfThisYearInMillis(1, 0, 30),
- true, DateUtils.FORMAT_12HOUR));
- assertEquals("1/31, 23:30 – 00:30",
- Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
- getJanOfThisYearInMillis(31, 23, 30), getFebOfThisYearInMillis(1, 0, 30),
- true, DateUtils.FORMAT_24HOUR));
- }
-
- @Test
- public void testDurationFromTodayToTomorrow() {
- assertEquals("Feb 1, 3:00 AM – Feb 2, 4:00 AM",
- Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
- getFebOfThisYearInMillis(1, 3), getFebOfThisYearInMillis(2, 4), false,
- DateUtils.FORMAT_12HOUR));
- assertEquals("Feb 1, 03:00 – Feb 2, 04:00",
- Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
- getFebOfThisYearInMillis(1, 3), getFebOfThisYearInMillis(2, 4), false,
- DateUtils.FORMAT_24HOUR));
- assertEquals("2/1, 3:00 AM – 2/2, 4:00 AM",
- Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
- getFebOfThisYearInMillis(1, 3), getFebOfThisYearInMillis(2, 4), true,
- DateUtils.FORMAT_12HOUR));
- assertEquals("2/1, 03:00 – 2/2, 04:00",
- Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
- getFebOfThisYearInMillis(1, 3), getFebOfThisYearInMillis(2, 4), true,
- DateUtils.FORMAT_24HOUR));
-
- assertEquals("Feb 1, 11:30 PM – Feb 2, 12:30 AM",
- Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
- getFebOfThisYearInMillis(1, 23, 30), getFebOfThisYearInMillis(2, 0, 30),
- false,
- DateUtils.FORMAT_12HOUR));
- assertEquals("Feb 1, 23:30 – Feb 2, 00:30",
- Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
- getFebOfThisYearInMillis(1, 23, 30), getFebOfThisYearInMillis(2, 0, 30),
- false,
- DateUtils.FORMAT_24HOUR));
- assertEquals("11:30 PM – 12:30 AM",
- Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
- getFebOfThisYearInMillis(1, 23, 30), getFebOfThisYearInMillis(2, 0, 30),
- true,
- DateUtils.FORMAT_12HOUR));
- assertEquals("23:30 – 00:30", Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
- getFebOfThisYearInMillis(1, 23, 30), getFebOfThisYearInMillis(2, 0, 30),
- true,
- DateUtils.FORMAT_24HOUR));
- }
-
- @Test
- public void testDurationWithinTomorrow() {
- assertEquals("Feb 2, 2:00 – 4:00 AM",
- Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
- getFebOfThisYearInMillis(2, 2), getFebOfThisYearInMillis(2, 4), false,
- DateUtils.FORMAT_12HOUR));
- assertEquals("Feb 2, 02:00 – 04:00",
- Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
- getFebOfThisYearInMillis(2, 2), getFebOfThisYearInMillis(2, 4), false,
- DateUtils.FORMAT_24HOUR));
- assertEquals("2/2, 2:00 – 4:00 AM",
- Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
- getFebOfThisYearInMillis(2, 2), getFebOfThisYearInMillis(2, 4), true,
- DateUtils.FORMAT_12HOUR));
- assertEquals("2/2, 02:00 – 04:00",
- Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
- getFebOfThisYearInMillis(2, 2), getFebOfThisYearInMillis(2, 4), true,
- DateUtils.FORMAT_24HOUR));
- }
-
- @Test
- public void testStartOfDay() {
- assertEquals("12:00 – 1:00 AM",
- Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS, DATE_THIS_YEAR_2_1_MS,
- getFebOfThisYearInMillis(1, 1), false,
- DateUtils.FORMAT_12HOUR));
- assertEquals("00:00 – 01:00",
- Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS, DATE_THIS_YEAR_2_1_MS,
- getFebOfThisYearInMillis(1, 1), false,
- DateUtils.FORMAT_24HOUR));
-
- assertEquals("Feb 2, 12:00 – 1:00 AM",
- Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
- getFebOfThisYearInMillis(2, 0), getFebOfThisYearInMillis(2, 1), false,
- DateUtils.FORMAT_12HOUR));
- assertEquals("Feb 2, 00:00 – 01:00",
- Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
- getFebOfThisYearInMillis(2, 0), getFebOfThisYearInMillis(2, 1), false,
- DateUtils.FORMAT_24HOUR));
- assertEquals("2/2, 12:00 – 1:00 AM",
- Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
- getFebOfThisYearInMillis(2, 0), getFebOfThisYearInMillis(2, 1), true,
- DateUtils.FORMAT_12HOUR));
- assertEquals("2/2, 00:00 – 01:00",
- Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
- getFebOfThisYearInMillis(2, 0), getFebOfThisYearInMillis(2, 1), true,
- DateUtils.FORMAT_24HOUR));
- }
-
- @Test
- public void testEndOfDay() {
- for (boolean useShortFormat : PARAM_USE_SHORT_FORMAT) {
- assertEquals("11:00 PM – 12:00 AM",
- Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
- getFebOfThisYearInMillis(1, 23), getFebOfThisYearInMillis(2, 0),
- useShortFormat,
- DateUtils.FORMAT_12HOUR));
- assertEquals("23:00 – 00:00",
- Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
- getFebOfThisYearInMillis(1, 23), getFebOfThisYearInMillis(2, 0),
- useShortFormat,
- DateUtils.FORMAT_24HOUR));
- }
-
- assertEquals("Feb 2, 11:00 PM – 12:00 AM",
- Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
- getFebOfThisYearInMillis(2, 23), getFebOfThisYearInMillis(3, 0), false,
- DateUtils.FORMAT_12HOUR));
- assertEquals("Feb 2, 23:00 – 00:00",
- Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
- getFebOfThisYearInMillis(2, 23), getFebOfThisYearInMillis(3, 0), false,
- DateUtils.FORMAT_24HOUR));
- assertEquals("2/2, 11:00 PM – 12:00 AM",
- Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
- getFebOfThisYearInMillis(2, 23), getFebOfThisYearInMillis(3, 0), true,
- DateUtils.FORMAT_12HOUR));
- assertEquals("2/2, 23:00 – 00:00",
- Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
- getFebOfThisYearInMillis(2, 23), getFebOfThisYearInMillis(3, 0), true,
- DateUtils.FORMAT_24HOUR));
- assertEquals("2/2, 12:00 AM – 2/3, 12:00 AM",
- Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
- getFebOfThisYearInMillis(2, 0), getFebOfThisYearInMillis(3, 0), true,
- DateUtils.FORMAT_12HOUR));
- assertEquals("2/2, 00:00 – 2/3, 00:00",
- Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
- getFebOfThisYearInMillis(2, 0), getFebOfThisYearInMillis(3, 0), true,
- DateUtils.FORMAT_24HOUR));
- }
-
- @Test
- public void testMidnight() {
- for (boolean useShortFormat : PARAM_USE_SHORT_FORMAT) {
- assertEquals("12:00 AM", Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
- DATE_THIS_YEAR_2_1_MS, DATE_THIS_YEAR_2_1_MS, useShortFormat,
- DateUtils.FORMAT_12HOUR));
- assertEquals("00:00", Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
- DATE_THIS_YEAR_2_1_MS, DATE_THIS_YEAR_2_1_MS, useShortFormat,
- DateUtils.FORMAT_24HOUR));
- }
- }
-}
diff --git a/tests/unit/src/com/android/tv/util/UtilsTest_GetMultiAudioString.java b/tests/unit/src/com/android/tv/util/UtilsTest_GetMultiAudioString.java
deleted file mode 100644
index 1e75342b..00000000
--- a/tests/unit/src/com/android/tv/util/UtilsTest_GetMultiAudioString.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * 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.util;
-
-import static android.support.test.InstrumentationRegistry.getTargetContext;
-import static org.junit.Assert.assertEquals;
-
-import android.content.Context;
-import android.media.tv.TvTrackInfo;
-import android.support.test.filters.SmallTest;
-
-import org.junit.Test;
-
-/**
- * Tests for {@link com.android.tv.util.Utils#getMultiAudioString}.
- */
-@SmallTest
-public class UtilsTest_GetMultiAudioString {
- private static final String TRACK_ID = "test_track_id";
- private static final int AUDIO_SAMPLE_RATE = 48000;
-
- @Test
- public void testAudioTrackLanguage() {
- Context context = getTargetContext();
- assertEquals("Korean",
- Utils.getMultiAudioString(context, createAudioTrackInfo("kor"), false));
- assertEquals("English",
- Utils.getMultiAudioString(context, createAudioTrackInfo("eng"), false));
- assertEquals("Unknown language",
- Utils.getMultiAudioString(context, createAudioTrackInfo(null), false));
- assertEquals("Unknown language",
- Utils.getMultiAudioString(context, createAudioTrackInfo(""), false));
- assertEquals("abc", Utils.getMultiAudioString(context, createAudioTrackInfo("abc"), false));
- }
-
- @Test
- public void testAudioTrackCount() {
- Context context = getTargetContext();
- assertEquals("English",
- Utils.getMultiAudioString(context, createAudioTrackInfo("eng", -1), false));
- assertEquals("English",
- Utils.getMultiAudioString(context, createAudioTrackInfo("eng", 0), false));
- assertEquals("English (mono)",
- Utils.getMultiAudioString(context, createAudioTrackInfo("eng", 1), false));
- assertEquals("English (stereo)",
- Utils.getMultiAudioString(context, createAudioTrackInfo("eng", 2), false));
- assertEquals("English (3 channels)",
- Utils.getMultiAudioString(context, createAudioTrackInfo("eng", 3), false));
- assertEquals("English (4 channels)",
- Utils.getMultiAudioString(context, createAudioTrackInfo("eng", 4), false));
- assertEquals("English (5 channels)",
- Utils.getMultiAudioString(context, createAudioTrackInfo("eng", 5), false));
- assertEquals("English (5.1 surround)",
- Utils.getMultiAudioString(context, createAudioTrackInfo("eng", 6), false));
- assertEquals("English (7 channels)",
- Utils.getMultiAudioString(context, createAudioTrackInfo("eng", 7), false));
- assertEquals("English (7.1 surround)",
- Utils.getMultiAudioString(context, createAudioTrackInfo("eng", 8), false));
- }
-
- @Test
- public void testShowSampleRate() {
- assertEquals("Korean (48kHz)",
- Utils.getMultiAudioString(getTargetContext(),
- createAudioTrackInfo("kor", 0), true));
- assertEquals("Korean (7.1 surround, 48kHz)",
- Utils.getMultiAudioString(getTargetContext(),
- createAudioTrackInfo("kor", 8), true));
- }
-
- private static TvTrackInfo createAudioTrackInfo(String language) {
- return createAudioTrackInfo(language, 0);
- }
-
- private static TvTrackInfo createAudioTrackInfo(String language, int channelCount) {
- return new TvTrackInfo.Builder(TvTrackInfo.TYPE_AUDIO, TRACK_ID)
- .setLanguage(language).setAudioChannelCount(channelCount)
- .setAudioSampleRate(AUDIO_SAMPLE_RATE).build();
- }
-}
diff --git a/tests/unit/src/com/android/tv/util/UtilsTest_IsInGivenDay.java b/tests/unit/src/com/android/tv/util/UtilsTest_IsInGivenDay.java
deleted file mode 100644
index 2b43abc1..00000000
--- a/tests/unit/src/com/android/tv/util/UtilsTest_IsInGivenDay.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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.util;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import android.support.test.filters.SmallTest;
-
-import org.junit.Test;
-
-import java.util.Calendar;
-import java.util.GregorianCalendar;
-import java.util.TimeZone;
-
-/**
- * Tests for {@link com.android.tv.util.Utils#isInGivenDay}.
- */
-@SmallTest
-public class UtilsTest_IsInGivenDay {
- @Test
- public void testIsInGivenDay() {
- assertTrue(Utils.isInGivenDay(
- new GregorianCalendar(2015, Calendar.JANUARY, 1).getTimeInMillis(),
- new GregorianCalendar(2015, Calendar.JANUARY, 1, 0, 30).getTimeInMillis()));
- }
-
- @Test
- public void testIsNotInGivenDay() {
- assertFalse(Utils.isInGivenDay(
- new GregorianCalendar(2015, Calendar.JANUARY, 1).getTimeInMillis(),
- new GregorianCalendar(2015, Calendar.JANUARY, 2).getTimeInMillis()));
- }
-
- @Test
- public void testIfTimeZoneApplied() {
- TimeZone timeZone = TimeZone.getDefault();
-
- TimeZone.setDefault(TimeZone.getTimeZone("Asia/Seoul"));
-
- // 2015.01.01 00:00 in KST = 2014.12.31 15:00 in UTC
- long date2015StartMs =
- new GregorianCalendar(2015, Calendar.JANUARY, 1).getTimeInMillis();
-
- // 2015.01.01 10:00 in KST = 2015.01.01 01:00 in UTC
- long date2015Start10AMMs =
- new GregorianCalendar(2015, Calendar.JANUARY, 1, 10, 0).getTimeInMillis();
-
- // Those two times aren't in the same day in UTC, but they are in KST.
- assertTrue(Utils.isInGivenDay(date2015StartMs, date2015Start10AMMs));
-
- TimeZone.setDefault(timeZone);
- }
-}
diff --git a/tests/unit/src/com/android/tv/util/ImageCacheTest.java b/tests/unit/src/com/android/tv/util/images/ImageCacheTest.java
index a76194b8..b7715c4a 100644
--- a/tests/unit/src/com/android/tv/util/ImageCacheTest.java
+++ b/tests/unit/src/com/android/tv/util/images/ImageCacheTest.java
@@ -14,23 +14,22 @@
* limitations under the License.
*/
-package com.android.tv.util;
+package com.android.tv.util.images;
-import static com.android.tv.util.BitmapUtils.createScaledBitmapInfo;
-import static org.junit.Assert.assertSame;
+import static com.android.tv.util.images.BitmapUtils.createScaledBitmapInfo;
+import static com.google.common.truth.Truth.assertWithMessage;
import android.graphics.Bitmap;
import android.support.test.filters.MediumTest;
-
-import com.android.tv.util.BitmapUtils.ScaledBitmapInfo;
-
+import android.support.test.runner.AndroidJUnit4;
+import com.android.tv.util.images.BitmapUtils.ScaledBitmapInfo;
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
-/**
- * Tests for {@link ImageCache}.
- */
+/** Tests for {@link ImageCache}. */
@MediumTest
+@RunWith(AndroidJUnit4.class)
public class ImageCacheTest {
private static final Bitmap ORIG = Bitmap.createBitmap(100, 100, Bitmap.Config.RGB_565);
@@ -47,34 +46,34 @@ public class ImageCacheTest {
mImageCache = ImageCache.newInstance(0.1f);
}
- //TODO: Empty the cache in the setup. Try using @VisibleForTesting
+ // TODO: Empty the cache in the setup. Try using @VisibleForTesting
@Test
public void testPutIfLarger_smaller() throws Exception {
- mImageCache.putIfNeeded( INFO_50);
- assertSame("before", INFO_50, mImageCache.get(KEY));
+ mImageCache.putIfNeeded(INFO_50);
+ assertWithMessage("before").that(mImageCache.get(KEY)).isSameAs(INFO_50);
- mImageCache.putIfNeeded( INFO_25);
- assertSame("after", INFO_50, mImageCache.get(KEY));
+ mImageCache.putIfNeeded(INFO_25);
+ assertWithMessage("after").that(mImageCache.get(KEY)).isSameAs(INFO_50);
}
@Test
public void testPutIfLarger_larger() throws Exception {
- mImageCache.putIfNeeded( INFO_50);
- assertSame("before", INFO_50, mImageCache.get(KEY));
+ mImageCache.putIfNeeded(INFO_50);
+ assertWithMessage("before").that(mImageCache.get(KEY)).isSameAs(INFO_50);
mImageCache.putIfNeeded(INFO_100);
- assertSame("after", INFO_100, mImageCache.get(KEY));
+ assertWithMessage("after").that(mImageCache.get(KEY)).isSameAs(INFO_100);
}
@Test
public void testPutIfLarger_alreadyMax() throws Exception {
- mImageCache.putIfNeeded( INFO_100);
- assertSame("before", INFO_100, mImageCache.get(KEY));
+ mImageCache.putIfNeeded(INFO_100);
+ assertWithMessage("before").that(mImageCache.get(KEY)).isSameAs(INFO_100);
- mImageCache.putIfNeeded( INFO_200);
- assertSame("after", INFO_100, mImageCache.get(KEY));
+ mImageCache.putIfNeeded(INFO_200);
+ assertWithMessage("after").that(mImageCache.get(KEY)).isSameAs(INFO_100);
}
-} \ No newline at end of file
+}
diff --git a/tests/unit/src/com/android/tv/util/images/ScaledBitmapInfoTest.java b/tests/unit/src/com/android/tv/util/images/ScaledBitmapInfoTest.java
new file mode 100644
index 00000000..005775b6
--- /dev/null
+++ b/tests/unit/src/com/android/tv/util/images/ScaledBitmapInfoTest.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2017 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.util.images;
+
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import android.graphics.Bitmap;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import com.android.tv.util.images.BitmapUtils.ScaledBitmapInfo;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/** Tests for {@link ScaledBitmapInfo}. */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class ScaledBitmapInfoTest {
+ private static final Bitmap B80x100 = Bitmap.createBitmap(80, 100, Bitmap.Config.RGB_565);
+ private static final Bitmap B960x1440 = Bitmap.createBitmap(960, 1440, Bitmap.Config.RGB_565);
+
+ @Test
+ public void testSize_B100x100to50x50() {
+ ScaledBitmapInfo actual = BitmapUtils.createScaledBitmapInfo("B80x100", B80x100, 50, 50);
+ assertScaledBitmapSize(2, 40, 50, actual);
+ }
+
+ @Test
+ public void testNeedsToReload_B100x100to50x50() {
+ ScaledBitmapInfo actual = BitmapUtils.createScaledBitmapInfo("B80x100", B80x100, 50, 50);
+ assertNeedsToReload(false, actual, 25, 25);
+ assertNeedsToReload(false, actual, 50, 50);
+ assertNeedsToReload(false, actual, 99, 99);
+ assertNeedsToReload(true, actual, 100, 100);
+ assertNeedsToReload(true, actual, 101, 101);
+ }
+
+ /** Reproduces <a href="http://b/20488453">b/20488453</a>. */
+ @Test
+ public void testBug20488453() {
+ ScaledBitmapInfo actual =
+ BitmapUtils.createScaledBitmapInfo("B960x1440", B960x1440, 284, 160);
+ assertScaledBitmapSize(8, 107, 160, actual);
+ assertNeedsToReload(false, actual, 284, 160);
+ }
+
+ private static void assertNeedsToReload(
+ boolean expected, ScaledBitmapInfo scaledBitmap, int reqWidth, int reqHeight) {
+ assertWithMessage(scaledBitmap.id + " needToReload(" + reqWidth + "," + reqHeight + ")")
+ .that(scaledBitmap.needToReload(reqWidth, reqHeight))
+ .isEqualTo(expected);
+ }
+
+ private static void assertScaledBitmapSize(
+ int expectedInSampleSize,
+ int expectedWidth,
+ int expectedHeight,
+ ScaledBitmapInfo actual) {
+ assertWithMessage(actual.id + " inSampleSize")
+ .that(actual.inSampleSize)
+ .isEqualTo(expectedInSampleSize);
+ assertWithMessage(actual.id + " width").that(actual.bitmap.getWidth()).isEqualTo(expectedWidth);
+ assertWithMessage(actual.id + " height")
+ .that(actual.bitmap.getHeight())
+ .isEqualTo(expectedHeight);
+ }
+}