• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.providers.tv;
18 
19 import com.google.android.collect.Sets;
20 
21 import android.content.ContentUris;
22 import android.content.ContentValues;
23 import android.content.Intent;
24 import android.content.pm.ProviderInfo;
25 import android.database.Cursor;
26 import android.media.tv.TvContract;
27 import android.media.tv.TvContract.Channels;
28 import android.media.tv.TvContract.Programs;
29 import android.media.tv.TvContract.WatchedPrograms;
30 import android.net.Uri;
31 import android.os.Bundle;
32 import android.os.SystemClock;
33 import android.provider.Settings;
34 import android.test.ServiceTestCase;
35 import android.test.mock.MockContentProvider;
36 import android.test.mock.MockContentResolver;
37 
38 import java.util.ArrayList;
39 import java.util.Arrays;
40 import java.util.Collection;
41 import java.util.HashSet;
42 import java.util.Objects;
43 import java.util.Set;
44 
45 public class EpgDataCleanupServiceTests extends ServiceTestCase<EpgDataCleanupService> {
46     private static final String FAKE_INPUT_ID = "EpgDataCleanupServiceTests";
47 
48     private MockContentResolver mResolver;
49     private TvProvider mProvider;
50 
EpgDataCleanupServiceTests()51     public EpgDataCleanupServiceTests() {
52         super(EpgDataCleanupService.class);
53     }
54 
55     @Override
setUp()56     protected void setUp() throws Exception {
57         super.setUp();
58 
59         mResolver = new MockContentResolver();
60         // DateUtils tries to access Settings provider to get date format string.
61         mResolver.addProvider(Settings.AUTHORITY, new MockContentProvider() {
62             @Override
63             public Bundle call(String method, String request, Bundle args) {
64                 return new Bundle();
65             }
66         });
67 
68         mProvider = new TvProviderForTesting();
69         mResolver.addProvider(TvContract.AUTHORITY, mProvider);
70 
71         setContext(new MockTvProviderContext(mResolver, getSystemContext()));
72 
73         final ProviderInfo info = new ProviderInfo();
74         info.authority = TvContract.AUTHORITY;
75         mProvider.attachInfoForTesting(getContext(), info);
76 
77         startService(new Intent(getContext(), EpgDataCleanupService.class));
78     }
79 
80     @Override
tearDown()81     protected void tearDown() throws Exception {
82         mProvider.shutdown();
83         super.tearDown();
84     }
85 
86     private static class Program {
87         long id;
88         final long startTime;
89         final long endTime;
90 
Program(long startTime, long endTime)91         Program(long startTime, long endTime) {
92             this(-1, startTime, endTime);
93         }
94 
Program(long id, long startTime, long endTime)95         Program(long id, long startTime, long endTime) {
96             this.id = id;
97             this.startTime = startTime;
98             this.endTime = endTime;
99         }
100 
101         @Override
equals(Object obj)102         public boolean equals(Object obj) {
103             if (!(obj instanceof Program)) {
104                 return false;
105             }
106             Program that = (Program) obj;
107             return Objects.equals(id, that.id)
108                     && Objects.equals(startTime, that.startTime)
109                     && Objects.equals(endTime, that.endTime);
110         }
111 
112         @Override
hashCode()113         public int hashCode() {
114             return Objects.hash(id, startTime, endTime);
115         }
116 
117         @Override
toString()118         public String toString() {
119             return "Program(id=" + id + ",start=" + startTime + ",end=" + endTime + ")";
120         }
121     }
122 
insertChannel()123     private long insertChannel() {
124         ContentValues values = new ContentValues();
125         values.put(Channels.COLUMN_INPUT_ID, FAKE_INPUT_ID);
126         Uri uri = mResolver.insert(Channels.CONTENT_URI, values);
127         assertNotNull(uri);
128         return ContentUris.parseId(uri);
129     }
130 
insertPrograms(Program... programs)131     private void insertPrograms(Program... programs) {
132         insertPrograms(Arrays.asList(programs));
133     }
134 
insertPrograms(Collection<Program> programs)135     private void insertPrograms(Collection<Program> programs) {
136         long channelId = insertChannel();
137 
138         ContentValues values = new ContentValues();
139         values.put(Programs.COLUMN_CHANNEL_ID, channelId);
140         for (Program program : programs) {
141             values.put(Programs.COLUMN_START_TIME_UTC_MILLIS, program.startTime);
142             values.put(Programs.COLUMN_END_TIME_UTC_MILLIS, program.endTime);
143             Uri uri = mResolver.insert(Programs.CONTENT_URI, values);
144             assertNotNull(uri);
145             program.id = ContentUris.parseId(uri);
146         }
147     }
148 
queryPrograms()149     private Set<Program> queryPrograms() {
150         String[] projection = new String[] {
151             Programs._ID,
152             Programs.COLUMN_START_TIME_UTC_MILLIS,
153             Programs.COLUMN_END_TIME_UTC_MILLIS,
154         };
155 
156         Cursor cursor = mResolver.query(Programs.CONTENT_URI, projection, null, null, null);
157         assertNotNull(cursor);
158         try {
159             Set<Program> programs = Sets.newHashSet();
160             while (cursor.moveToNext()) {
161                 programs.add(new Program(cursor.getLong(0), cursor.getLong(1), cursor.getLong(2)));
162             }
163             return programs;
164         } finally {
165             cursor.close();
166         }
167     }
168 
insertWatchedPrograms(Program... programs)169     private void insertWatchedPrograms(Program... programs) {
170         insertWatchedPrograms(Arrays.asList(programs));
171     }
172 
insertWatchedPrograms(Collection<Program> programs)173     private void insertWatchedPrograms(Collection<Program> programs) {
174         long channelId = insertChannel();
175 
176         ContentValues values = new ContentValues();
177         values.put(WatchedPrograms.COLUMN_PACKAGE_NAME, getContext().getPackageName());
178         values.put(WatchedPrograms.COLUMN_CHANNEL_ID, channelId);
179         for (Program program : programs) {
180             values.put(WatchedPrograms.COLUMN_WATCH_START_TIME_UTC_MILLIS, program.startTime);
181             values.put(WatchedPrograms.COLUMN_WATCH_END_TIME_UTC_MILLIS, program.endTime);
182             Uri uri = mResolver.insert(WatchedPrograms.CONTENT_URI, values);
183             assertNotNull(uri);
184             program.id = ContentUris.parseId(uri);
185         }
186     }
187 
queryWatchedPrograms()188     private Set<Program> queryWatchedPrograms() {
189         String[] projection = new String[] {
190             WatchedPrograms._ID,
191             WatchedPrograms.COLUMN_WATCH_START_TIME_UTC_MILLIS,
192             WatchedPrograms.COLUMN_WATCH_END_TIME_UTC_MILLIS,
193         };
194 
195         Cursor cursor = mResolver.query(WatchedPrograms.CONTENT_URI, projection, null, null, null);
196         assertNotNull(cursor);
197         try {
198             Set<Program> programs = Sets.newHashSet();
199             while (cursor.moveToNext()) {
200                 programs.add(new Program(cursor.getLong(0), cursor.getLong(1), cursor.getLong(2)));
201             }
202             return programs;
203         } finally {
204             cursor.close();
205         }
206     }
207 
208     @Override
testServiceTestCaseSetUpProperly()209     public void testServiceTestCaseSetUpProperly() throws Exception {
210         assertNotNull(getService());
211     }
212 
testClearOldPrograms()213     public void testClearOldPrograms() {
214         Program program = new Program(1, 2);
215         insertPrograms(program);
216 
217         getService().clearOldPrograms(2);
218         assertEquals("Program should NOT be deleted if it ended at given time.",
219                 Sets.newHashSet(program), queryPrograms());
220 
221         getService().clearOldPrograms(3);
222         assertTrue("Program should be deleted if it ended before given time.",
223                 queryPrograms().isEmpty());
224 
225         ArrayList<Program> programs = new ArrayList<Program>();
226         for (int i = 0; i < 10; i++) {
227             programs.add(new Program(999 + i, 1000 + i));
228         }
229         insertPrograms(programs);
230 
231         getService().clearOldPrograms(1005);
232         assertEquals("Program should be deleted if and only if it ended before given time.",
233                 new HashSet<Program>(programs.subList(5, 10)), queryPrograms());
234     }
235 
testClearOldWatchedPrograms()236     public void testClearOldWatchedPrograms() {
237         Program program = new Program(1, 2);
238         insertWatchedPrograms(program);
239 
240         getService().clearOldWatchHistory(1);
241         assertEquals("Watch history should NOT be deleted if watch started at given time.",
242                 Sets.newHashSet(program), queryWatchedPrograms());
243 
244         getService().clearOldWatchHistory(2);
245         assertTrue("Watch history shuold be deleted if watch started before given time.",
246                 queryWatchedPrograms().isEmpty());
247 
248         ArrayList<Program> programs = new ArrayList<Program>();
249         for (int i = 0; i < 10; i++) {
250             programs.add(new Program(1000 + i, 1001 + i));
251         }
252         insertWatchedPrograms(programs);
253 
254         getService().clearOldWatchHistory(1005);
255         assertEquals("Watch history should be deleted if and only if it started before given time.",
256                 new HashSet<Program>(programs.subList(5, 10)), queryWatchedPrograms());
257     }
258 
testClearOverflowWatchHistory()259     public void testClearOverflowWatchHistory() {
260         ArrayList<Program> programs = new ArrayList<Program>();
261         for (int i = 0; i < 10; i++) {
262             programs.add(new Program(1000 + i, 1001 + i));
263         }
264         insertWatchedPrograms(programs);
265 
266         getService().clearOverflowWatchHistory(5);
267         assertEquals("Watch history should be deleted in watch start time order.",
268                 new HashSet<Program>(programs.subList(5, 10)), queryWatchedPrograms());
269 
270         getService().clearOverflowWatchHistory(0);
271         assertTrue("All history should be deleted.", queryWatchedPrograms().isEmpty());
272     }
273 }
274