1 /* 2 * Copyright (C) 2017 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 static junit.framework.Assert.assertNotNull; 20 21 import android.content.BroadcastReceiver; 22 import android.content.ContentResolver; 23 import android.content.ContentUris; 24 import android.content.ContentValues; 25 import android.database.Cursor; 26 import android.media.tv.TvContract; 27 import android.media.tv.TvContract.Channels; 28 import android.media.tv.TvContract.RecordedPrograms; 29 import android.net.Uri; 30 31 import com.google.android.collect.Sets; 32 33 import java.util.Objects; 34 import java.util.Set; 35 36 public class Utils { 37 private static final String FAKE_INPUT_ID = "PackageRemovedReceiverTest"; 38 private static final String FAKE_SESSION_TOKEN = "fakeSessionToken"; 39 clearTvProvider(ContentResolver resolver)40 public static void clearTvProvider(ContentResolver resolver) { 41 resolver.delete(Channels.CONTENT_URI, null, null); 42 // Programs, PreviewPrograms, and WatchedPrograms table will be automatically cleared when 43 // the Channels table is cleared. 44 resolver.delete(TvContract.RecordedPrograms.CONTENT_URI, null, null); 45 resolver.delete(TvContract.WatchNextPrograms.CONTENT_URI, null, null); 46 } 47 48 private static class BaseProgram { 49 long id; 50 final String packageName; 51 BaseProgram(String pkgName)52 BaseProgram(String pkgName) { 53 this(-1, pkgName); 54 } 55 BaseProgram(long id, String pkgName)56 BaseProgram(long id, String pkgName) { 57 this.id = id; 58 this.packageName = pkgName; 59 } 60 61 @Override equals(Object obj)62 public boolean equals(Object obj) { 63 if (!(obj instanceof BaseProgram)) { 64 return false; 65 } 66 BaseProgram that = (BaseProgram) obj; 67 return Objects.equals(id, that.id) 68 && Objects.equals(packageName, that.packageName); 69 } 70 71 @Override hashCode()72 public int hashCode() { 73 return Objects.hash(id, packageName); 74 } 75 76 @Override toString()77 public String toString() { 78 return getClass().getSimpleName() + "(id=" + id + ",packageName=" + packageName + ")"; 79 } 80 } 81 82 public static class Program extends BaseProgram { Program(String pkgName)83 Program(String pkgName) { 84 super(-1, pkgName); 85 } 86 Program(long id, String pkgName)87 Program(long id, String pkgName) { 88 super(id, pkgName); 89 } 90 91 @Override equals(Object obj)92 public boolean equals(Object obj) { 93 if (!(obj instanceof Program)) { 94 return false; 95 } 96 Program that = (Program) obj; 97 return Objects.equals(id, that.id) 98 && Objects.equals(packageName, that.packageName); 99 } 100 } 101 102 public static class PreviewProgram extends BaseProgram { PreviewProgram(String pkgName)103 PreviewProgram(String pkgName) { 104 super(-1, pkgName); 105 } 106 PreviewProgram(long id, String pkgName)107 PreviewProgram(long id, String pkgName) { 108 super(id, pkgName); 109 } 110 111 @Override equals(Object obj)112 public boolean equals(Object obj) { 113 if (!(obj instanceof PreviewProgram)) { 114 return false; 115 } 116 PreviewProgram that = (PreviewProgram) obj; 117 return Objects.equals(id, that.id) 118 && Objects.equals(packageName, that.packageName); 119 } 120 } 121 122 public static class RecordedProgram extends BaseProgram { 123 Long channelId; RecordedProgram(String pkgName, Long channelId)124 RecordedProgram(String pkgName, Long channelId) { 125 this(-1, pkgName, channelId); 126 } 127 RecordedProgram(long id, String pkgName, Long channelId)128 RecordedProgram(long id, String pkgName, Long channelId) { 129 super(id, pkgName); 130 this.channelId = channelId; 131 } 132 133 @Override equals(Object obj)134 public boolean equals(Object obj) { 135 if (!(obj instanceof RecordedProgram)) { 136 return false; 137 } 138 RecordedProgram that = (RecordedProgram) obj; 139 return Objects.equals(id, that.id) 140 && Objects.equals(packageName, that.packageName) 141 && Objects.equals(channelId, that.channelId); 142 } 143 144 @Override toString()145 public String toString() { 146 return "RecordedProgram(id=" + id + ",packageName=" + packageName + ",channelId=" 147 + channelId + ")"; 148 } 149 } 150 151 public static class WatchedProgram extends BaseProgram { WatchedProgram(String pkgName)152 WatchedProgram(String pkgName) { 153 super(-1, pkgName); 154 } 155 WatchedProgram(long id, String pkgName)156 WatchedProgram(long id, String pkgName) { 157 super(id, pkgName); 158 } 159 160 @Override equals(Object obj)161 public boolean equals(Object obj) { 162 if (!(obj instanceof WatchedProgram)) { 163 return false; 164 } 165 WatchedProgram that = (WatchedProgram) obj; 166 return Objects.equals(id, that.id) 167 && Objects.equals(packageName, that.packageName); 168 } 169 } 170 171 public static class WatchNextProgram extends BaseProgram { WatchNextProgram(String pkgName)172 WatchNextProgram(String pkgName) { 173 super(-1, pkgName); 174 } 175 WatchNextProgram(long id, String pkgName)176 WatchNextProgram(long id, String pkgName) { 177 super(id, pkgName); 178 } 179 180 @Override equals(Object obj)181 public boolean equals(Object obj) { 182 if (!(obj instanceof WatchNextProgram)) { 183 return false; 184 } 185 WatchNextProgram that = (WatchNextProgram) obj; 186 return Objects.equals(id, that.id) 187 && Objects.equals(packageName, that.packageName); 188 } 189 } 190 insertChannel(ContentResolver resolver)191 public static long insertChannel(ContentResolver resolver) { 192 ContentValues values = new ContentValues(); 193 values.put(Channels.COLUMN_INPUT_ID, FAKE_INPUT_ID); 194 Uri uri = resolver.insert(Channels.CONTENT_URI, values); 195 assertNotNull(uri); 196 return ContentUris.parseId(uri); 197 } 198 insertPrograms( ContentResolver resolver, long channelId, Program... programs)199 public static void insertPrograms( 200 ContentResolver resolver, long channelId, Program... programs) { 201 ContentValues values = new ContentValues(); 202 values.put(TvContract.Programs.COLUMN_CHANNEL_ID, channelId); 203 for (Program program : programs) { 204 Uri uri = resolver.insert(TvContract.Programs.CONTENT_URI, values); 205 assertNotNull(uri); 206 program.id = ContentUris.parseId(uri); 207 } 208 } 209 queryPrograms(ContentResolver resolver)210 public static Set<Program> queryPrograms(ContentResolver resolver) { 211 String[] projection = new String[] { 212 TvContract.Programs._ID, 213 TvContract.BaseTvColumns.COLUMN_PACKAGE_NAME, 214 }; 215 216 Cursor cursor = 217 resolver.query(TvContract.Programs.CONTENT_URI, projection, null, null, null); 218 assertNotNull(cursor); 219 try { 220 Set<Program> programs = Sets.newHashSet(); 221 while (cursor.moveToNext()) { 222 programs.add(new Program(cursor.getLong(0), cursor.getString(1))); 223 } 224 return programs; 225 } finally { 226 cursor.close(); 227 } 228 } 229 insertPreviewPrograms( ContentResolver resolver, long channelId, PreviewProgram... programs)230 public static void insertPreviewPrograms( 231 ContentResolver resolver, long channelId, PreviewProgram... programs) { 232 ContentValues values = new ContentValues(); 233 values.put(TvContract.PreviewPrograms.COLUMN_CHANNEL_ID, channelId); 234 values.put( 235 TvContract.PreviewPrograms.COLUMN_TYPE, TvContract.PreviewPrograms.TYPE_TV_EPISODE); 236 for (PreviewProgram program : programs) { 237 Uri uri = resolver.insert(TvContract.PreviewPrograms.CONTENT_URI, values); 238 assertNotNull(uri); 239 program.id = ContentUris.parseId(uri); 240 } 241 } 242 queryPreviewPrograms(ContentResolver resolver)243 public static Set<PreviewProgram> queryPreviewPrograms(ContentResolver resolver) { 244 String[] projection = new String[] { 245 TvContract.PreviewPrograms._ID, 246 TvContract.BaseTvColumns.COLUMN_PACKAGE_NAME, 247 }; 248 249 Cursor cursor = 250 resolver.query( 251 TvContract.PreviewPrograms.CONTENT_URI, projection, null, null, null); 252 assertNotNull(cursor); 253 try { 254 Set<PreviewProgram> programs = Sets.newHashSet(); 255 while (cursor.moveToNext()) { 256 programs.add(new PreviewProgram(cursor.getLong(0), cursor.getString(1))); 257 } 258 return programs; 259 } finally { 260 cursor.close(); 261 } 262 } 263 insertRecordedPrograms( ContentResolver resolver, long channelId, RecordedProgram... programs)264 public static void insertRecordedPrograms( 265 ContentResolver resolver, long channelId, RecordedProgram... programs) { 266 ContentValues values = new ContentValues(); 267 values.put(RecordedPrograms.COLUMN_CHANNEL_ID, channelId); 268 values.put(RecordedPrograms.COLUMN_INPUT_ID, FAKE_INPUT_ID); 269 for (RecordedProgram program : programs) { 270 Uri uri = resolver.insert(RecordedPrograms.CONTENT_URI, values); 271 assertNotNull(uri); 272 program.id = ContentUris.parseId(uri); 273 } 274 } 275 queryRecordedPrograms(ContentResolver resolver)276 public static Set<RecordedProgram> queryRecordedPrograms(ContentResolver resolver) { 277 String[] projection = new String[] { 278 RecordedPrograms._ID, 279 TvContract.BaseTvColumns.COLUMN_PACKAGE_NAME, 280 RecordedPrograms.COLUMN_CHANNEL_ID, 281 }; 282 283 Cursor cursor = resolver.query(RecordedPrograms.CONTENT_URI, projection, null, null, null); 284 assertNotNull(cursor); 285 try { 286 Set<RecordedProgram> programs = Sets.newHashSet(); 287 while (cursor.moveToNext()) { 288 Long channelId = cursor.isNull(2) ? null : cursor.getLong(2); 289 programs.add( 290 new RecordedProgram(cursor.getLong(0), cursor.getString(1), channelId)); 291 } 292 return programs; 293 } finally { 294 cursor.close(); 295 } 296 } 297 insertWatchedPrograms(ContentResolver resolver, String packageName, long channelId, WatchedProgram... programs)298 public static void insertWatchedPrograms(ContentResolver resolver, String packageName, 299 long channelId, WatchedProgram... programs) { 300 ContentValues values = new ContentValues(); 301 values.put(TvContract.WatchedPrograms.COLUMN_PACKAGE_NAME, packageName); 302 values.put(TvContract.WatchedPrograms.COLUMN_CHANNEL_ID, channelId); 303 values.put(TvContract.WatchedPrograms.COLUMN_WATCH_START_TIME_UTC_MILLIS, 1000); 304 values.put(TvContract.WatchedPrograms.COLUMN_INTERNAL_SESSION_TOKEN, FAKE_SESSION_TOKEN); 305 values.put(TvProvider.WATCHED_PROGRAMS_COLUMN_CONSOLIDATED, 1); 306 for (WatchedProgram program : programs) { 307 Uri uri = resolver.insert(TvContract.WatchedPrograms.CONTENT_URI, values); 308 assertNotNull(uri); 309 program.id = ContentUris.parseId(uri); 310 } 311 } 312 queryWatchedPrograms(ContentResolver resolver)313 public static Set<WatchedProgram> queryWatchedPrograms(ContentResolver resolver) { 314 String[] projection = new String[] { 315 TvContract.WatchedPrograms._ID, 316 TvContract.BaseTvColumns.COLUMN_PACKAGE_NAME, 317 }; 318 319 Cursor cursor = 320 resolver.query( 321 TvContract.WatchedPrograms.CONTENT_URI, projection, null, null, null); 322 assertNotNull(cursor); 323 try { 324 Set<WatchedProgram> programs = Sets.newHashSet(); 325 while (cursor.moveToNext()) { 326 programs.add(new WatchedProgram(cursor.getLong(0), cursor.getString(1))); 327 } 328 return programs; 329 } finally { 330 cursor.close(); 331 } 332 } 333 insertWatchNextPrograms(ContentResolver resolver, String packageName, WatchNextProgram... programs)334 public static void insertWatchNextPrograms(ContentResolver resolver, String packageName, 335 WatchNextProgram... programs) { 336 ContentValues values = new ContentValues(); 337 values.put(TvContract.WatchNextPrograms.COLUMN_PACKAGE_NAME, packageName); 338 values.put(TvContract.WatchNextPrograms.COLUMN_TYPE, 339 TvContract.WatchNextPrograms.TYPE_TV_EPISODE); 340 for (WatchNextProgram program : programs) { 341 Uri uri = resolver.insert(TvContract.WatchNextPrograms.CONTENT_URI, values); 342 assertNotNull(uri); 343 program.id = ContentUris.parseId(uri); 344 } 345 } 346 queryWatchNextPrograms(ContentResolver resolver)347 public static Set<WatchNextProgram> queryWatchNextPrograms(ContentResolver resolver) { 348 String[] projection = new String[] { 349 TvContract.WatchNextPrograms._ID, 350 TvContract.BaseTvColumns.COLUMN_PACKAGE_NAME, 351 }; 352 353 Cursor cursor = 354 resolver.query( 355 TvContract.WatchNextPrograms.CONTENT_URI, projection, null, null, null); 356 assertNotNull(cursor); 357 try { 358 Set<WatchNextProgram> programs = Sets.newHashSet(); 359 while (cursor.moveToNext()) { 360 programs.add(new WatchNextProgram(cursor.getLong(0), cursor.getString(1))); 361 } 362 return programs; 363 } finally { 364 cursor.close(); 365 } 366 } 367 getChannelCount(ContentResolver resolver)368 public static long getChannelCount(ContentResolver resolver) { 369 String[] projection = new String[] { 370 Channels._ID, 371 }; 372 373 Cursor cursor = resolver.query(Channels.CONTENT_URI, projection, null, null, null); 374 assertNotNull(cursor); 375 try { 376 return cursor.getCount(); 377 } finally { 378 cursor.close(); 379 } 380 } 381 createFakePendingResultForTests()382 public static BroadcastReceiver.PendingResult createFakePendingResultForTests() { 383 return new BroadcastReceiver.PendingResult(0, null, null, 0, true, false, null, 0, 0); 384 } 385 Utils()386 private Utils() { } 387 } 388