aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2018-02-22 08:24:35 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2018-02-22 08:24:35 +0000
commitd6c5d4e09437a71508ec55cb51483c666cb902b5 (patch)
treeeb2ffc32d3631222ec1bb37a4d87f856ab055a24
parentc0729bf13b0026738e7dcec9b57d919c7bb0f2e6 (diff)
parenta75e73b3b367eecc2bdea4f7fbfd88512fcc95fe (diff)
downloadTV-d6c5d4e09437a71508ec55cb51483c666cb902b5.tar.gz
Snap for 4615953 from a75e73b3b367eecc2bdea4f7fbfd88512fcc95fe to pi-release
Change-Id: Ic71f385a5b80bb2dda0ac93f5b09ce1e33564027
-rw-r--r--common/src/com/android/tv/common/util/CommonUtils.java6
-rw-r--r--res/values/strings.xml10
-rw-r--r--src/com/android/tv/dvr/BaseDvrDataManager.java2
-rw-r--r--src/com/android/tv/dvr/ui/list/DvrHistoryFragment.java5
-rw-r--r--src/com/android/tv/dvr/ui/list/DvrHistoryRowAdapter.java27
-rw-r--r--tests/common/src/com/android/tv/testing/FakeClock.java4
-rw-r--r--tests/common/src/com/android/tv/testing/TestSingletonApp.java5
-rw-r--r--tests/common/src/com/android/tv/testing/activities/BaseMainActivityTestCase.java (renamed from tests/unit/src/com/android/tv/BaseMainActivityTestCase.java)3
-rw-r--r--tests/common/src/com/android/tv/testing/dvr/DvrDataManagerInMemoryImpl.java310
-rw-r--r--tests/common/src/com/android/tv/testing/robo/RobotTestAppHelper.java15
-rw-r--r--tests/input/jank.sh24
-rw-r--r--tests/unit/src/com/android/tv/CurrentPositionMediatorTest.java1
-rw-r--r--tests/unit/src/com/android/tv/MainActivityTest.java1
-rw-r--r--tests/unit/src/com/android/tv/TimeShiftManagerTest.java1
-rw-r--r--tests/unit/src/com/android/tv/menu/MenuTest.java3
-rw-r--r--tests/unit/src/com/android/tv/menu/TvOptionsRowAdapterTest.java5
-rw-r--r--tuner/tests/TestManifest.xml23
-rw-r--r--tuner/tests/assets/capture_kqed.ts (renamed from tuner/tests/unittests/javatests/assets/capture_kqed.ts)bin31457280 -> 31457280 bytes
-rw-r--r--tuner/tests/assets/capture_stream.ts (renamed from tuner/tests/unittests/javatests/assets/capture_stream.ts)bin73699196 -> 73699196 bytes
-rw-r--r--version.mk6
20 files changed, 424 insertions, 27 deletions
diff --git a/common/src/com/android/tv/common/util/CommonUtils.java b/common/src/com/android/tv/common/util/CommonUtils.java
index 00574586..305431d3 100644
--- a/common/src/com/android/tv/common/util/CommonUtils.java
+++ b/common/src/com/android/tv/common/util/CommonUtils.java
@@ -21,6 +21,7 @@ import android.content.Intent;
import android.media.tv.TvInputInfo;
import android.os.Build;
import android.util.ArraySet;
+import android.util.Log;
import com.android.tv.common.BuildConfig;
import com.android.tv.common.CommonConstants;
import com.android.tv.common.actions.InputSetupActionUtils;
@@ -34,6 +35,7 @@ import java.util.Set;
/** Util class for common use in TV app and inputs. */
@SuppressWarnings("AndroidApiChecker") // TODO(b/32513850) remove when error prone is updated
public final class CommonUtils {
+ private static final String TAG = "CommonUtils";
private static final ThreadLocal<SimpleDateFormat> ISO_8601 =
new ThreadLocal() {
private final SimpleDateFormat value =
@@ -94,6 +96,10 @@ public final class CommonUtils {
if (sRunningInTest == null) {
try {
Class.forName("com.android.tv.testing.utils.Utils");
+ Log.i(
+ TAG,
+ "Assumed to be running in a test because"
+ + " com.android.tv.testing.utils.Utils is found");
sRunningInTest = true;
} catch (ClassNotFoundException e) {
sRunningInTest = false;
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 182171a8..255d9663 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -572,8 +572,8 @@
<!-- Toast message that a new recording schedule of the current program has been created
from the user action. -->
<string name="dvr_msg_current_program_scheduled">Recording <xliff:g id="programName" example="Big bang theory">%1$s</xliff:g> from now to <xliff:g id="endTime" example="12:30 PM">%2$s</xliff:g></string>
- <!-- Description of a card view to show DVR history. [CHAR LIMIT=25] -->
- <string name="dvr_history_card_view_title">DVR History</string>
+ <!-- Description of a card view to show Recording (DVR) history.[CHAR LIMIT=25]-->
+ <string name="dvr_history_card_view_title">Recording History</string>
<!-- Description of a card view to show full list of scheduled recordings. [CHAR LIMIT=25] -->
<string name="dvr_full_schedule_card_view_title">Full schedule</string>
<!-- Description of how many following days the schedule list will show. [CHAR LIMIT=25] -->
@@ -752,9 +752,9 @@
sufficient space.-->
<string name="dvr_error_insufficient_space_description_three_or_more_recordings">The recordings of <xliff:g id="programName_1" example="Friends">%1$s</xliff:g>, <xliff:g id="programName_2" example="Friends">%2$s</xliff:g> and <xliff:g id="programName_3" example="Friends">%3$s</xliff:g> didn\'t complete due to insufficient storage.</string>
<!-- Dialog title which will be shown when the current storage is too small for DVR. -->
- <string name="dvr_error_small_sized_storage_title">DVR needs more storage</string>
+ <string name="dvr_error_small_sized_storage_title">More stroage needed</string>
<!-- Dialog description which will be shown when the current storage is too small for DVR. -->
- <string name="dvr_error_small_sized_storage_description">You will be able to record programs with DVR. However there is not enough storage on your device now for DVR to work. Please connect an external drive that is <xliff:g id="storage_size" example="10GB">%1$d</xliff:g>GB or larger and follow the steps to format it as device storage.</string>
+ <string name="dvr_error_small_sized_storage_description">You will be able to record programs. However there is not enough storage on your device to start recording. Please connect an external drive that is <xliff:g id="storage_size" example="10GB">%1$d</xliff:g>GB or larger and follow the steps to format it as device storage.</string>
<!-- Dialog title which will be shown when there is no free space on the current storage for DVR. -->
<string name="dvr_error_no_free_space_title">Not enough storage</string>
<!-- Dialog description which will be shown when there is no free space on the current storage for DVR. -->
@@ -762,7 +762,7 @@
<!-- Dialog title which will be shown when the current DVR storage is not accessible. -->
<string name="dvr_error_missing_storage_title">Missing storage</string>
<!-- Dialog description which will be shown when the current DVR storage is not accessible. -->
- <string name="dvr_error_missing_storage_description" translatable="false">Some of the storage used by DVR is missing. Please connect the external drive you used before to re-enable DVR. Alternately, you can forget the storage in the storage settings, if it\'s no longer available.</string>
+ <string name="dvr_error_missing_storage_description" translatable="false">Some of the storage used for recording is missing. Please connect the external drive you used before to re-enable recording. Alternately, you can forget the storage in the storage settings, if it\'s no longer available.</string>
<!-- The recording being requested to play is not existent in storage. It may be deleted. -->
<string name="dvr_toast_recording_deleted" translatable="false">The recording seems to be deleted.</string>
diff --git a/src/com/android/tv/dvr/BaseDvrDataManager.java b/src/com/android/tv/dvr/BaseDvrDataManager.java
index e890481b..4a04de4e 100644
--- a/src/com/android/tv/dvr/BaseDvrDataManager.java
+++ b/src/com/android/tv/dvr/BaseDvrDataManager.java
@@ -57,7 +57,7 @@ public abstract class BaseDvrDataManager implements WritableDvrDataManager {
private final Set<RecordedProgramListener> mRecordedProgramListeners = new ArraySet<>();
private final HashMap<Long, ScheduledRecording> mDeletedScheduleMap = new HashMap<>();
- BaseDvrDataManager(Context context, Clock clock) {
+ public BaseDvrDataManager(Context context, Clock clock) {
SoftPreconditions.checkFeatureEnabled(context, CommonFeatures.DVR, TAG);
mClock = clock;
}
diff --git a/src/com/android/tv/dvr/ui/list/DvrHistoryFragment.java b/src/com/android/tv/dvr/ui/list/DvrHistoryFragment.java
index fbf0fe53..08dc43c1 100644
--- a/src/com/android/tv/dvr/ui/list/DvrHistoryFragment.java
+++ b/src/com/android/tv/dvr/ui/list/DvrHistoryFragment.java
@@ -41,10 +41,11 @@ public class DvrHistoryFragment extends DetailsFragment {
SchedulesHeaderRow.class, new DateHeaderRowPresenter(getContext()));
presenterSelector.addClassPresenter(
ScheduleRow.class, new ScheduleRowPresenter(getContext()));
- mRowsAdapter = new DvrHistoryRowAdapter(getContext(), presenterSelector);
+ TvSingletons singletons = TvSingletons.getSingletons(getContext());
+ mRowsAdapter = new DvrHistoryRowAdapter(
+ getContext(), presenterSelector, singletons.getClock());
setAdapter(mRowsAdapter);
mRowsAdapter.start();
- TvSingletons singletons = TvSingletons.getSingletons(getContext());
mEmptyInfoScreenView = (TextView) getActivity().findViewById(R.id.empty_info_screen);
// TODO: handle show/hide message
}
diff --git a/src/com/android/tv/dvr/ui/list/DvrHistoryRowAdapter.java b/src/com/android/tv/dvr/ui/list/DvrHistoryRowAdapter.java
index 7685b7e9..ac828eb8 100644
--- a/src/com/android/tv/dvr/ui/list/DvrHistoryRowAdapter.java
+++ b/src/com/android/tv/dvr/ui/list/DvrHistoryRowAdapter.java
@@ -24,6 +24,8 @@ import android.support.v17.leanback.widget.ClassPresenterSelector;
import android.text.format.DateUtils;
import com.android.tv.R;
import com.android.tv.TvSingletons;
+import com.android.tv.common.util.Clock;
+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.recorder.ScheduledProgramReaper;
@@ -42,12 +44,17 @@ class DvrHistoryRowAdapter extends ArrayObjectAdapter {
private static final long ONE_DAY_MS = TimeUnit.DAYS.toMillis(1);
private static final int MAX_HISTORY_DAYS = ScheduledProgramReaper.DAYS;
- private Context mContext;
+ private final Context mContext;
+ private final Clock mClock;
+ private final DvrDataManager mDvrDataManager;
private final List<String> mTitles = new ArrayList<>();
- public DvrHistoryRowAdapter(Context context, ClassPresenterSelector classPresenterSelector) {
+ public DvrHistoryRowAdapter(
+ Context context, ClassPresenterSelector classPresenterSelector, Clock clock) {
super(classPresenterSelector);
mContext = context;
+ mClock = clock;
+ mDvrDataManager = TvSingletons.getSingletons(mContext).getDvrDataManager();
mTitles.add(mContext.getString(R.string.dvr_date_today));
mTitles.add(mContext.getString(R.string.dvr_date_yesterday));
}
@@ -60,20 +67,14 @@ class DvrHistoryRowAdapter extends ArrayObjectAdapter {
/** Starts row adapter. */
public void start() {
clear();
- List<ScheduledRecording> recordingList =
- TvSingletons.getSingletons(mContext)
- .getDvrDataManager()
- .getFailedScheduledRecordings();
- List<RecordedProgram> recordedProgramList =
- TvSingletons.getSingletons(mContext)
- .getDvrDataManager()
- .getRecordedPrograms();
+ List<ScheduledRecording> recordingList = mDvrDataManager.getFailedScheduledRecordings();
+ List<RecordedProgram> recordedProgramList = mDvrDataManager.getRecordedPrograms();
recordingList.addAll(
recordedProgramsToScheduledRecordings(recordedProgramList, MAX_HISTORY_DAYS));
recordingList
.sort(ScheduledRecording.START_TIME_THEN_PRIORITY_THEN_ID_COMPARATOR.reversed());
- long deadLine = Utils.getFirstMillisecondOfDay(System.currentTimeMillis());
+ long deadLine = Utils.getFirstMillisecondOfDay(mClock.currentTimeMillis());
for (int i = 0; i < recordingList.size(); ) {
ArrayList<ScheduledRecording> section = new ArrayList<>();
while (i < recordingList.size() && recordingList.get(i).getStartTimeMs() >= deadLine) {
@@ -102,7 +103,7 @@ class DvrHistoryRowAdapter extends ArrayObjectAdapter {
private String calculateHeaderDate(long timeMs) {
int titleIndex =
(int)
- ((Utils.getFirstMillisecondOfDay(System.currentTimeMillis()) - timeMs)
+ ((Utils.getFirstMillisecondOfDay(mClock.currentTimeMillis()) - timeMs)
/ ONE_DAY_MS);
String headerDate;
if (titleIndex < mTitles.size()) {
@@ -122,7 +123,7 @@ class DvrHistoryRowAdapter extends ArrayObjectAdapter {
private List<ScheduledRecording> recordedProgramsToScheduledRecordings(
List<RecordedProgram> recordedPrograms, int maxDays) {
List<ScheduledRecording> result = new ArrayList<>(recordedPrograms.size());
- long firstMillisecondToday = Utils.getFirstMillisecondOfDay(System.currentTimeMillis());
+ long firstMillisecondToday = Utils.getFirstMillisecondOfDay(mClock.currentTimeMillis());
for (RecordedProgram recordedProgram : recordedPrograms) {
if (maxDays
< Utils.computeDateDifference(
diff --git a/tests/common/src/com/android/tv/testing/FakeClock.java b/tests/common/src/com/android/tv/testing/FakeClock.java
index fc4ca6df..f5941939 100644
--- a/tests/common/src/com/android/tv/testing/FakeClock.java
+++ b/tests/common/src/com/android/tv/testing/FakeClock.java
@@ -36,6 +36,10 @@ public class FakeClock implements Clock {
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;
diff --git a/tests/common/src/com/android/tv/testing/TestSingletonApp.java b/tests/common/src/com/android/tv/testing/TestSingletonApp.java
index f1798352..f55ed8d4 100644
--- a/tests/common/src/com/android/tv/testing/TestSingletonApp.java
+++ b/tests/common/src/com/android/tv/testing/TestSingletonApp.java
@@ -44,6 +44,7 @@ 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;
@@ -62,6 +63,7 @@ public class TestSingletonApp extends Application implements TvSingletons {
public FakeTvInputManagerHelper tvInputManagerHelper;
public SetupUtils setupUtils;
public DvrManager dvrManager;
+ public DvrDataManager mDvrDataManager;
private final Provider<EpgReader> mEpgReaderProvider = SingletonProvider.create(epgReader);
private TunerInputController mTunerInputController;
@@ -80,6 +82,7 @@ public class TestSingletonApp extends Application implements TvSingletons {
tvInputManagerHelper.start();
mChannelDataManager = new ChannelDataManager(this, tvInputManagerHelper);
mChannelDataManager.start();
+ mDvrDataManager = new DvrDataManagerInMemoryImpl(this, fakeClock);
// HACK reset the singleton for tests
BaseApplication.sSingletons = this;
}
@@ -126,7 +129,7 @@ public class TestSingletonApp extends Application implements TvSingletons {
@Override
public DvrDataManager getDvrDataManager() {
- return null;
+ return mDvrDataManager;
}
@Override
diff --git a/tests/unit/src/com/android/tv/BaseMainActivityTestCase.java b/tests/common/src/com/android/tv/testing/activities/BaseMainActivityTestCase.java
index 795f6370..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,6 +21,7 @@ import android.content.Context;
import android.os.SystemClock;
import android.support.test.rule.ActivityTestRule;
import android.text.TextUtils;
+import com.android.tv.MainActivity;
import com.android.tv.data.ChannelDataManager;
import com.android.tv.data.api.Channel;
import com.android.tv.testing.data.ChannelInfo;
diff --git a/tests/common/src/com/android/tv/testing/dvr/DvrDataManagerInMemoryImpl.java b/tests/common/src/com/android/tv/testing/dvr/DvrDataManagerInMemoryImpl.java
new file mode 100644
index 00000000..70e8bfb6
--- /dev/null
+++ b/tests/common/src/com/android/tv/testing/dvr/DvrDataManagerInMemoryImpl.java
@@ -0,0 +1,310 @@
+/*
+ * 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.dvr;
+
+import android.content.Context;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+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 java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicLong;
+
+/** A DVR Data manager that stores values in memory suitable for testing. */
+public final class DvrDataManagerInMemoryImpl extends BaseDvrDataManager {
+ 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<>();
+ private final Map<Long, SeriesRecording> mSeriesRecordings = new HashMap<>();
+
+ public DvrDataManagerInMemoryImpl(Context context, Clock clock) {
+ super(context, clock);
+ }
+
+ @Override
+ public boolean isInitialized() {
+ return true;
+ }
+
+ @Override
+ public boolean isDvrScheduleLoadFinished() {
+ return true;
+ }
+
+ @Override
+ public boolean isRecordedProgramLoadFinished() {
+ return true;
+ }
+
+ private List<ScheduledRecording> getScheduledRecordingsPrograms() {
+ return new ArrayList<>(mScheduledRecordings.values());
+ }
+
+ @Override
+ public List<RecordedProgram> getRecordedPrograms() {
+ return new ArrayList<>(mRecordedPrograms.values());
+ }
+
+ @Override
+ public List<ScheduledRecording> getAllScheduledRecordings() {
+ return new ArrayList<>(mScheduledRecordings.values());
+ }
+
+ @Override
+ public List<SeriesRecording> getSeriesRecordings() {
+ return new ArrayList<>(mSeriesRecordings.values());
+ }
+
+ @Override
+ public List<SeriesRecording> getSeriesRecordings(String inputId) {
+ List<SeriesRecording> result = new ArrayList<>();
+ for (SeriesRecording r : mSeriesRecordings.values()) {
+ if (TextUtils.equals(r.getInputId(), inputId)) {
+ result.add(r);
+ }
+ }
+ return result;
+ }
+
+ @Override
+ public long getNextScheduledStartTimeAfter(long startTime) {
+
+ List<ScheduledRecording> temp = getNonStartedScheduledRecordings();
+ Collections.sort(temp, ScheduledRecording.START_TIME_COMPARATOR);
+ for (ScheduledRecording r : temp) {
+ if (r.getStartTimeMs() > startTime) {
+ return r.getStartTimeMs();
+ }
+ }
+ return DvrDataManager.NEXT_START_TIME_NOT_FOUND;
+ }
+
+ @Override
+ public List<ScheduledRecording> getScheduledRecordings(
+ Range<Long> period, @RecordingState int state) {
+ List<ScheduledRecording> temp = getScheduledRecordingsPrograms();
+ List<ScheduledRecording> result = new ArrayList<>();
+ for (ScheduledRecording r : temp) {
+ if (r.isOverLapping(period) && r.getState() == state) {
+ result.add(r);
+ }
+ }
+ return result;
+ }
+
+ @Override
+ public List<ScheduledRecording> getScheduledRecordings(long seriesRecordingId) {
+ List<ScheduledRecording> result = new ArrayList<>();
+ for (ScheduledRecording r : mScheduledRecordings.values()) {
+ if (r.getSeriesRecordingId() == seriesRecordingId) {
+ result.add(r);
+ }
+ }
+ return result;
+ }
+
+ @Override
+ public List<ScheduledRecording> getScheduledRecordings(String inputId) {
+ List<ScheduledRecording> result = new ArrayList<>();
+ for (ScheduledRecording r : mScheduledRecordings.values()) {
+ if (TextUtils.equals(r.getInputId(), inputId)) {
+ result.add(r);
+ }
+ }
+ return result;
+ }
+
+ /** Add a new scheduled recording. */
+ @Override
+ public void addScheduledRecording(ScheduledRecording... scheduledRecordings) {
+ for (ScheduledRecording r : scheduledRecordings) {
+ addScheduledRecordingInternal(r);
+ }
+ }
+
+ public void addRecordedProgram(RecordedProgram recordedProgram) {
+ addRecordedProgramInternal(recordedProgram);
+ }
+
+ public void updateRecordedProgram(RecordedProgram r) {
+ long id = r.getId();
+ if (mRecordedPrograms.containsKey(id)) {
+ mRecordedPrograms.put(id, r);
+ notifyRecordedProgramsChanged(r);
+ } else {
+ throw new IllegalArgumentException("Recording not found:" + r);
+ }
+ }
+
+ public void removeRecordedProgram(RecordedProgram scheduledRecording) {
+ mRecordedPrograms.remove(scheduledRecording.getId());
+ 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();
+ 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();
+ mRecordedPrograms.put(recordedProgram.getId(), recordedProgram);
+ notifyRecordedProgramsAdded(recordedProgram);
+ return recordedProgram;
+ }
+
+ @Override
+ public void addSeriesRecording(SeriesRecording... seriesRecordings) {
+ for (SeriesRecording r : seriesRecordings) {
+ mSeriesRecordings.put(r.getId(), r);
+ }
+ notifySeriesRecordingAdded(seriesRecordings);
+ }
+
+ @Override
+ public void removeScheduledRecording(ScheduledRecording... scheduledRecordings) {
+ for (ScheduledRecording r : scheduledRecordings) {
+ mScheduledRecordings.remove(r.getId());
+ }
+ notifyScheduledRecordingRemoved(scheduledRecordings);
+ }
+
+ @Override
+ public void removeScheduledRecording(boolean forceRemove, ScheduledRecording... schedule) {
+ removeScheduledRecording(schedule);
+ }
+
+ @Override
+ public void removeSeriesRecording(SeriesRecording... seriesRecordings) {
+ for (SeriesRecording r : seriesRecordings) {
+ mSeriesRecordings.remove(r.getId());
+ }
+ notifySeriesRecordingRemoved(seriesRecordings);
+ }
+
+ @Override
+ public void updateScheduledRecording(ScheduledRecording... scheduledRecordings) {
+ for (ScheduledRecording r : scheduledRecordings) {
+ long id = r.getId();
+ if (mScheduledRecordings.containsKey(id)) {
+ mScheduledRecordings.put(id, r);
+ } else {
+ Log.d(TAG, "Recording not found:" + r);
+ }
+ }
+ notifyScheduledRecordingStatusChanged(scheduledRecordings);
+ }
+
+ @Override
+ public void updateSeriesRecording(SeriesRecording... seriesRecordings) {
+ for (SeriesRecording r : seriesRecordings) {
+ long id = r.getId();
+ if (mSeriesRecordings.containsKey(id)) {
+ mSeriesRecordings.put(id, r);
+ } else {
+ throw new IllegalArgumentException("Recording not found:" + r);
+ }
+ }
+ notifySeriesRecordingChanged(seriesRecordings);
+ }
+
+ @Nullable
+ @Override
+ public ScheduledRecording getScheduledRecording(long id) {
+ return mScheduledRecordings.get(id);
+ }
+
+ @Nullable
+ @Override
+ public ScheduledRecording getScheduledRecordingForProgramId(long programId) {
+ for (ScheduledRecording r : mScheduledRecordings.values()) {
+ if (r.getProgramId() == programId) {
+ return r;
+ }
+ }
+ return null;
+ }
+
+ @Nullable
+ @Override
+ public SeriesRecording getSeriesRecording(long seriesRecordingId) {
+ return mSeriesRecordings.get(seriesRecordingId);
+ }
+
+ @Nullable
+ @Override
+ public SeriesRecording getSeriesRecording(String seriesId) {
+ for (SeriesRecording r : mSeriesRecordings.values()) {
+ if (r.getSeriesId().equals(seriesId)) {
+ return r;
+ }
+ }
+ return null;
+ }
+
+ @Nullable
+ @Override
+ public RecordedProgram getRecordedProgram(long recordingId) {
+ return mRecordedPrograms.get(recordingId);
+ }
+
+ @Override
+ @NonNull
+ protected List<ScheduledRecording> getRecordingsWithState(int... states) {
+ ArrayList<ScheduledRecording> result = new ArrayList<>();
+ for (ScheduledRecording r : mScheduledRecordings.values()) {
+ for (int state : states) {
+ if (r.getState() == state) {
+ result.add(r);
+ break;
+ }
+ }
+ }
+ return result;
+ }
+}
diff --git a/tests/common/src/com/android/tv/testing/robo/RobotTestAppHelper.java b/tests/common/src/com/android/tv/testing/robo/RobotTestAppHelper.java
index 3eb97b5f..9eb79298 100644
--- a/tests/common/src/com/android/tv/testing/robo/RobotTestAppHelper.java
+++ b/tests/common/src/com/android/tv/testing/robo/RobotTestAppHelper.java
@@ -1,3 +1,18 @@
+/*
+ * 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;
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/unit/src/com/android/tv/CurrentPositionMediatorTest.java b/tests/unit/src/com/android/tv/CurrentPositionMediatorTest.java
index 1c6a0e3b..abadde31 100644
--- a/tests/unit/src/com/android/tv/CurrentPositionMediatorTest.java
+++ b/tests/unit/src/com/android/tv/CurrentPositionMediatorTest.java
@@ -23,6 +23,7 @@ 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;
diff --git a/tests/unit/src/com/android/tv/MainActivityTest.java b/tests/unit/src/com/android/tv/MainActivityTest.java
index 5bd526cc..c5df21a9 100644
--- a/tests/unit/src/com/android/tv/MainActivityTest.java
+++ b/tests/unit/src/com/android/tv/MainActivityTest.java
@@ -24,6 +24,7 @@ import android.support.test.runner.AndroidJUnit4;
import android.view.View;
import android.widget.TextView;
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 java.util.List;
diff --git a/tests/unit/src/com/android/tv/TimeShiftManagerTest.java b/tests/unit/src/com/android/tv/TimeShiftManagerTest.java
index e30a9226..cb523045 100644
--- a/tests/unit/src/com/android/tv/TimeShiftManagerTest.java
+++ b/tests/unit/src/com/android/tv/TimeShiftManagerTest.java
@@ -26,6 +26,7 @@ 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;
diff --git a/tests/unit/src/com/android/tv/menu/MenuTest.java b/tests/unit/src/com/android/tv/menu/MenuTest.java
index 4d8081bc..9bdb8681 100644
--- a/tests/unit/src/com/android/tv/menu/MenuTest.java
+++ b/tests/unit/src/com/android/tv/menu/MenuTest.java
@@ -20,9 +20,11 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
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.Test;
+import org.junit.runner.RunWith;
import org.mockito.Matchers;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
@@ -30,6 +32,7 @@ import org.mockito.stubbing.Answer;
/** Tests for {@link Menu}. */
@SmallTest
+@RunWith(AndroidJUnit4.class)
public class MenuTest {
private Menu mMenu;
private IMenuView mMenuView;
diff --git a/tests/unit/src/com/android/tv/menu/TvOptionsRowAdapterTest.java b/tests/unit/src/com/android/tv/menu/TvOptionsRowAdapterTest.java
index 04d86bfc..7086e344 100644
--- a/tests/unit/src/com/android/tv/menu/TvOptionsRowAdapterTest.java
+++ b/tests/unit/src/com/android/tv/menu/TvOptionsRowAdapterTest.java
@@ -22,8 +22,9 @@ 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.activities.BaseMainActivityTestCase;
import com.android.tv.testing.constants.Constants;
import com.android.tv.testing.testinput.ChannelState;
import com.android.tv.testing.testinput.ChannelStateData;
@@ -32,9 +33,11 @@ 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}. */
@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;
diff --git a/tuner/tests/TestManifest.xml b/tuner/tests/TestManifest.xml
new file mode 100644
index 00000000..f84aa90f
--- /dev/null
+++ b/tuner/tests/TestManifest.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.tv.tuner.tests">
+ <!-- android_local_test needs minSdkVersion set -->
+ <uses-sdk android:minSdkVersion="23"/>
+
+</manifest> \ No newline at end of file
diff --git a/tuner/tests/unittests/javatests/assets/capture_kqed.ts b/tuner/tests/assets/capture_kqed.ts
index 624ac553..624ac553 100644
--- a/tuner/tests/unittests/javatests/assets/capture_kqed.ts
+++ b/tuner/tests/assets/capture_kqed.ts
Binary files differ
diff --git a/tuner/tests/unittests/javatests/assets/capture_stream.ts b/tuner/tests/assets/capture_stream.ts
index 97ee15c1..97ee15c1 100644
--- a/tuner/tests/unittests/javatests/assets/capture_stream.ts
+++ b/tuner/tests/assets/capture_stream.ts
Binary files differ
diff --git a/version.mk b/version.mk
index 57f3a43b..375249e9 100644
--- a/version.mk
+++ b/version.mk
@@ -58,7 +58,7 @@ code_version_build := 001
#####################################################
#####################################################
# Collect automatic version code parameters
-ifneq "" "$(filter eng.%,$(BUILD_NUMBER))"
+ifeq ($(strip $(HAS_BUILD_NUMBER)),false)
# This is an eng build
base_version_buildtype := 0
else
@@ -94,12 +94,12 @@ version_code_package := $(code_version_major)$(base_version_minor)$(code_version
# and hh is the git hash
# On eng builds, the BUILD_NUMBER has the user and timestamp inline
ifdef TARGET_BUILD_APPS
-ifneq "" "$(filter eng.%,$(BUILD_NUMBER))"
+ifeq ($(strip $(HAS_BUILD_NUMBER)),false)
git_hash := $(shell git --git-dir $(LOCAL_PATH)/.git log -n 1 --pretty=format:%h)
date_string := $(shell date +%Y-%m-%d)
version_name_package := $(base_version_major).$(base_version_minor).$(code_version_build) (eng.$(USER).$(git_hash).$(date_string)-$(base_version_arch)$(base_version_density))
else
- version_name_package := $(base_version_major).$(base_version_minor).$(code_version_build) ($(BUILD_NUMBER)-$(base_version_arch)$(base_version_density))
+ version_name_package := $(base_version_major).$(base_version_minor).$(code_version_build) ($(BUILD_NUMBER_FROM_FILE)-$(base_version_arch)$(base_version_density))
endif
else # !TARGET_BUILD_APPS
version_name_package := $(base_version_major).$(base_version_minor).$(code_version_build)