blob: 46894aa0add31878086a49174227ba1ca6f96181 [file] [log] [blame]
/*
* Copyright (C) 2014 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.providers.tv;
import com.google.android.collect.Sets;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Intent;
import android.content.pm.ProviderInfo;
import android.database.Cursor;
import android.media.tv.TvContract;
import android.media.tv.TvContract.Channels;
import android.media.tv.TvContract.Programs;
import android.media.tv.TvContract.WatchedPrograms;
import android.net.Uri;
import android.os.Bundle;
import android.os.SystemClock;
import android.provider.Settings;
import android.test.suitebuilder.annotation.Suppress;
import android.test.mock.MockContentProvider;
import android.test.mock.MockContentResolver;
import android.test.ServiceTestCase;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
public class EpgDataCleanupServiceTests extends ServiceTestCase<EpgDataCleanupService> {
private static final String FAKE_INPUT_ID = "EpgDataCleanupServiceTests";
private MockContentResolver mResolver;
private TvProviderForTesting mProvider;
public EpgDataCleanupServiceTests() {
super(EpgDataCleanupService.class);
}
@Override
protected void setUp() throws Exception {
super.setUp();
mResolver = new MockContentResolver();
// DateUtils tries to access Settings provider to get date format string.
mResolver.addProvider(Settings.AUTHORITY, new MockContentProvider() {
@Override
public Bundle call(String method, String request, Bundle args) {
return new Bundle();
}
});
mProvider = new TvProviderForTesting();
mResolver.addProvider(TvContract.AUTHORITY, mProvider);
setContext(new MockTvProviderContext(mResolver, getSystemContext()));
final ProviderInfo info = new ProviderInfo();
info.authority = TvContract.AUTHORITY;
mProvider.attachInfoForTesting(getContext(), info);
Utils.clearTvProvider(mResolver);
startService(new Intent(getContext(), EpgDataCleanupService.class));
}
@Override
protected void tearDown() throws Exception {
Utils.clearTvProvider(mResolver);
mProvider.shutdown();
super.tearDown();
}
private static class Program {
long id;
final long startTime;
final long endTime;
Program(long startTime, long endTime) {
this(-1, startTime, endTime);
}
Program(long id, long startTime, long endTime) {
this.id = id;
this.startTime = startTime;
this.endTime = endTime;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Program)) {
return false;
}
Program that = (Program) obj;
return Objects.equals(id, that.id)
&& Objects.equals(startTime, that.startTime)
&& Objects.equals(endTime, that.endTime);
}
@Override
public int hashCode() {
return Objects.hash(id, startTime, endTime);
}
@Override
public String toString() {
return "Program(id=" + id + ",start=" + startTime + ",end=" + endTime + ")";
}
}
private long insertChannel() {
ContentValues values = new ContentValues();
values.put(Channels.COLUMN_INPUT_ID, FAKE_INPUT_ID);
Uri uri = mResolver.insert(Channels.CONTENT_URI, values);
assertNotNull(uri);
return ContentUris.parseId(uri);
}
private void insertPrograms(Program... programs) {
insertPrograms(Arrays.asList(programs));
}
private void insertPrograms(Collection<Program> programs) {
long channelId = insertChannel();
ContentValues values = new ContentValues();
values.put(Programs.COLUMN_CHANNEL_ID, channelId);
for (Program program : programs) {
values.put(Programs.COLUMN_START_TIME_UTC_MILLIS, program.startTime);
values.put(Programs.COLUMN_END_TIME_UTC_MILLIS, program.endTime);
Uri uri = mResolver.insert(Programs.CONTENT_URI, values);
assertNotNull(uri);
program.id = ContentUris.parseId(uri);
}
}
private Set<Program> queryPrograms() {
String[] projection = new String[] {
Programs._ID,
Programs.COLUMN_START_TIME_UTC_MILLIS,
Programs.COLUMN_END_TIME_UTC_MILLIS,
};
Cursor cursor = mResolver.query(Programs.CONTENT_URI, projection, null, null, null);
assertNotNull(cursor);
try {
Set<Program> programs = Sets.newHashSet();
while (cursor.moveToNext()) {
programs.add(new Program(cursor.getLong(0), cursor.getLong(1), cursor.getLong(2)));
}
return programs;
} finally {
cursor.close();
}
}
private void insertWatchedPrograms(Program... programs) {
insertWatchedPrograms(Arrays.asList(programs));
}
private void insertWatchedPrograms(Collection<Program> programs) {
long channelId = insertChannel();
ContentValues values = new ContentValues();
values.put(WatchedPrograms.COLUMN_PACKAGE_NAME, getContext().getPackageName());
values.put(WatchedPrograms.COLUMN_CHANNEL_ID, channelId);
for (Program program : programs) {
values.put(WatchedPrograms.COLUMN_WATCH_START_TIME_UTC_MILLIS, program.startTime);
values.put(WatchedPrograms.COLUMN_WATCH_END_TIME_UTC_MILLIS, program.endTime);
Uri uri = mProvider.insertWatchedProgramSync(values);
assertNotNull(uri);
program.id = ContentUris.parseId(uri);
}
}
private Set<Program> queryWatchedPrograms() {
String[] projection = new String[] {
WatchedPrograms._ID,
WatchedPrograms.COLUMN_WATCH_START_TIME_UTC_MILLIS,
WatchedPrograms.COLUMN_WATCH_END_TIME_UTC_MILLIS,
};
Cursor cursor = mResolver.query(WatchedPrograms.CONTENT_URI, projection, null, null, null);
assertNotNull(cursor);
try {
Set<Program> programs = Sets.newHashSet();
while (cursor.moveToNext()) {
programs.add(new Program(cursor.getLong(0), cursor.getLong(1), cursor.getLong(2)));
}
return programs;
} finally {
cursor.close();
}
}
@Override
public void testServiceTestCaseSetUpProperly() throws Exception {
assertNotNull(getService());
}
public void testClearOldPrograms() {
Program program = new Program(1, 2);
insertPrograms(program);
getService().clearOldPrograms(2);
assertEquals("Program should NOT be deleted if it ended at given time.",
Sets.newHashSet(program), queryPrograms());
getService().clearOldPrograms(3);
assertTrue("Program should be deleted if it ended before given time.",
queryPrograms().isEmpty());
ArrayList<Program> programs = new ArrayList<Program>();
for (int i = 0; i < 10; i++) {
programs.add(new Program(999 + i, 1000 + i));
}
insertPrograms(programs);
getService().clearOldPrograms(1005);
assertEquals("Program should be deleted if and only if it ended before given time.",
new HashSet<Program>(programs.subList(5, 10)), queryPrograms());
}
// Disable temporarily since it's not trivial to fix due to asynchronous implementation of
// watch history management.
public void testClearOldWatchedPrograms() {
Program program = new Program(1, 2);
insertWatchedPrograms(program);
getService().clearOldWatchHistory(1);
assertEquals("Watch history should NOT be deleted if watch started at given time.",
Sets.newHashSet(program), queryWatchedPrograms());
getService().clearOldWatchHistory(2);
assertTrue("Watch history shuold be deleted if watch started before given time.",
queryWatchedPrograms().isEmpty());
ArrayList<Program> programs = new ArrayList<Program>();
for (int i = 0; i < 10; i++) {
programs.add(new Program(1000 + i, 1001 + i));
}
insertWatchedPrograms(programs);
getService().clearOldWatchHistory(1005);
assertEquals("Watch history should be deleted if and only if it started before given time.",
new HashSet<Program>(programs.subList(5, 10)), queryWatchedPrograms());
}
// Disable temporarily since it's not trivial to fix due to asynchronous implementation of
// watch history management.
public void testClearOverflowWatchHistory() {
ArrayList<Program> programs = new ArrayList<Program>();
for (int i = 0; i < 10; i++) {
programs.add(new Program(1000 + i, 1001 + i));
}
insertWatchedPrograms(programs);
getService().clearOverflowWatchHistory(5);
assertEquals("Watch history should be deleted in watch start time order.",
new HashSet<Program>(programs.subList(5, 10)), queryWatchedPrograms());
getService().clearOverflowWatchHistory(0);
assertTrue("All history should be deleted.", queryWatchedPrograms().isEmpty());
}
}