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 android.media.tv.cts; 18 19 import android.content.ComponentName; 20 import android.content.ContentResolver; 21 import android.content.ContentUris; 22 import android.content.ContentValues; 23 import android.content.res.AssetFileDescriptor; 24 import android.database.Cursor; 25 import android.graphics.Bitmap; 26 import android.graphics.BitmapFactory; 27 import android.media.tv.TvContentRating; 28 import android.media.tv.TvContract; 29 import android.media.tv.TvContract.Channels; 30 import android.media.tv.TvContract.Programs.Genres; 31 import android.net.Uri; 32 import android.test.AndroidTestCase; 33 34 import com.android.cts.tv.R; 35 36 import java.io.InputStream; 37 import java.io.OutputStream; 38 import java.util.Arrays; 39 import java.util.List; 40 41 /** 42 * Test for {@link android.media.tv.TvContract}. 43 */ 44 public class TvContractTest extends AndroidTestCase { 45 private static final String[] CHANNELS_PROJECTION = { 46 TvContract.Channels._ID, 47 TvContract.Channels.COLUMN_INPUT_ID, 48 TvContract.Channels.COLUMN_TYPE, 49 TvContract.Channels.COLUMN_SERVICE_TYPE, 50 TvContract.Channels.COLUMN_ORIGINAL_NETWORK_ID, 51 TvContract.Channels.COLUMN_TRANSPORT_STREAM_ID, 52 TvContract.Channels.COLUMN_SERVICE_ID, 53 TvContract.Channels.COLUMN_DISPLAY_NUMBER, 54 TvContract.Channels.COLUMN_DISPLAY_NAME, 55 TvContract.Channels.COLUMN_NETWORK_AFFILIATION, 56 TvContract.Channels.COLUMN_DESCRIPTION, 57 TvContract.Channels.COLUMN_VIDEO_FORMAT, 58 TvContract.Channels.COLUMN_INTERNAL_PROVIDER_DATA, 59 TvContract.Channels.COLUMN_VERSION_NUMBER, 60 }; 61 62 private static final String[] PROGRAMS_PROJECTION = { 63 TvContract.Programs._ID, 64 TvContract.Programs.COLUMN_CHANNEL_ID, 65 TvContract.Programs.COLUMN_TITLE, 66 TvContract.Programs.COLUMN_SEASON_NUMBER, 67 TvContract.Programs.COLUMN_EPISODE_NUMBER, 68 TvContract.Programs.COLUMN_EPISODE_TITLE, 69 TvContract.Programs.COLUMN_START_TIME_UTC_MILLIS, 70 TvContract.Programs.COLUMN_END_TIME_UTC_MILLIS, 71 TvContract.Programs.COLUMN_BROADCAST_GENRE, 72 TvContract.Programs.COLUMN_CANONICAL_GENRE, 73 TvContract.Programs.COLUMN_SHORT_DESCRIPTION, 74 TvContract.Programs.COLUMN_LONG_DESCRIPTION, 75 TvContract.Programs.COLUMN_VIDEO_WIDTH, 76 TvContract.Programs.COLUMN_VIDEO_HEIGHT, 77 TvContract.Programs.COLUMN_AUDIO_LANGUAGE, 78 TvContract.Programs.COLUMN_CONTENT_RATING, 79 TvContract.Programs.COLUMN_POSTER_ART_URI, 80 TvContract.Programs.COLUMN_THUMBNAIL_URI, 81 TvContract.Programs.COLUMN_INTERNAL_PROVIDER_DATA, 82 TvContract.Programs.COLUMN_VERSION_NUMBER, 83 }; 84 85 private static long OPERATION_TIME = 1000l; 86 87 private static final String ENCODED_GENRE_STRING = Genres.ANIMAL_WILDLIFE + "," + Genres.COMEDY 88 + "," + Genres.DRAMA + "," + Genres.EDUCATION + "," + Genres.FAMILY_KIDS + "," 89 + Genres.GAMING + "," + Genres.MOVIES + "," + Genres.NEWS + "," + Genres.SHOPPING + "," 90 + Genres.SPORTS + "," + Genres.TRAVEL; 91 92 private String mInputId; 93 private ContentResolver mContentResolver; 94 private Uri mChannelsUri; 95 96 @Override setUp()97 protected void setUp() throws Exception { 98 super.setUp(); 99 if (!Utils.hasTvInputFramework(getContext())) { 100 return; 101 } 102 mInputId = TvContract.buildInputId( 103 new ComponentName(getContext(), StubTunerTvInputService.class)); 104 mContentResolver = getContext().getContentResolver(); 105 mChannelsUri = TvContract.buildChannelsUriForInput(mInputId); 106 } 107 108 @Override tearDown()109 protected void tearDown() throws Exception { 110 if (!Utils.hasTvInputFramework(getContext())) { 111 super.tearDown(); 112 return; 113 } 114 // Clean up, just in case we failed to delete the entry when a test failed. 115 // The cotentUris are specific to this package, so this will delete only the 116 // entries inserted by this package. 117 String[] projection = { TvContract.Channels._ID }; 118 try (Cursor cursor = mContentResolver.query(mChannelsUri, projection, null, null, null)) { 119 while (cursor != null && cursor.moveToNext()) { 120 long channelId = cursor.getLong(0); 121 mContentResolver.delete( 122 TvContract.buildProgramsUriForChannel(channelId), null, null); 123 } 124 } 125 mContentResolver.delete(mChannelsUri, null, null); 126 super.tearDown(); 127 } 128 createDummyChannelValues(String inputId)129 private static ContentValues createDummyChannelValues(String inputId) { 130 ContentValues values = new ContentValues(); 131 values.put(TvContract.Channels.COLUMN_INPUT_ID, inputId); 132 values.put(TvContract.Channels.COLUMN_TYPE, TvContract.Channels.TYPE_OTHER); 133 values.put(TvContract.Channels.COLUMN_SERVICE_TYPE, 134 TvContract.Channels.SERVICE_TYPE_AUDIO_VIDEO); 135 values.put(TvContract.Channels.COLUMN_DISPLAY_NUMBER, "1"); 136 values.put(TvContract.Channels.COLUMN_VIDEO_FORMAT, TvContract.Channels.VIDEO_FORMAT_480P); 137 138 return values; 139 } 140 createDummyProgramValues(long channelId)141 private static ContentValues createDummyProgramValues(long channelId) { 142 ContentValues values = new ContentValues(); 143 values.put(TvContract.Programs.COLUMN_CHANNEL_ID, channelId); 144 values.put(TvContract.Programs.COLUMN_EPISODE_TITLE, "Title"); 145 values.put(TvContract.Programs.COLUMN_CANONICAL_GENRE, TvContract.Programs.Genres.encode( 146 TvContract.Programs.Genres.MOVIES, TvContract.Programs.Genres.DRAMA)); 147 TvContentRating rating = TvContentRating.createRating("android.media.tv", "US_TVPG", 148 "US_TVPG_TV_MA", "US_TVPG_S", "US_TVPG_V"); 149 values.put(TvContract.Programs.COLUMN_CONTENT_RATING, rating.flattenToString()); 150 151 return values; 152 } 153 verifyStringColumn(Cursor cursor, ContentValues expectedValues, String columnName)154 private static void verifyStringColumn(Cursor cursor, ContentValues expectedValues, 155 String columnName) { 156 if (expectedValues.containsKey(columnName)) { 157 assertEquals(expectedValues.getAsString(columnName), 158 cursor.getString(cursor.getColumnIndex(columnName))); 159 } 160 } 161 verifyIntegerColumn(Cursor cursor, ContentValues expectedValues, String columnName)162 private static void verifyIntegerColumn(Cursor cursor, ContentValues expectedValues, 163 String columnName) { 164 if (expectedValues.containsKey(columnName)) { 165 assertEquals(expectedValues.getAsInteger(columnName).intValue(), 166 cursor.getInt(cursor.getColumnIndex(columnName))); 167 } 168 } 169 verifyLongColumn(Cursor cursor, ContentValues expectedValues, String columnName)170 private static void verifyLongColumn(Cursor cursor, ContentValues expectedValues, 171 String columnName) { 172 if (expectedValues.containsKey(columnName)) { 173 assertEquals(expectedValues.getAsLong(columnName).longValue(), 174 cursor.getLong(cursor.getColumnIndex(columnName))); 175 } 176 } 177 verifyBlobColumn(Cursor cursor, ContentValues expectedValues, String columnName)178 private static void verifyBlobColumn(Cursor cursor, ContentValues expectedValues, 179 String columnName) { 180 if (expectedValues.containsKey(columnName)) { 181 byte[] expected = expectedValues.getAsByteArray(columnName); 182 byte[] actual = cursor.getBlob(cursor.getColumnIndex(columnName)); 183 assertEquals(expected.length, actual.length); 184 for (int i = 0; i < expected.length; ++i) { 185 assertEquals(expected[i], actual[i]); 186 } 187 } 188 } 189 verifyChannel(Uri channelUri, ContentValues expectedValues, long channelId)190 private void verifyChannel(Uri channelUri, ContentValues expectedValues, long channelId) { 191 try (Cursor cursor = mContentResolver.query( 192 channelUri, CHANNELS_PROJECTION, null, null, null)) { 193 assertNotNull(cursor); 194 assertEquals(cursor.getCount(), 1); 195 assertTrue(cursor.moveToNext()); 196 assertEquals(channelId, cursor.getLong(cursor.getColumnIndex(TvContract.Channels._ID))); 197 verifyStringColumn(cursor, expectedValues, TvContract.Channels.COLUMN_INPUT_ID); 198 verifyStringColumn(cursor, expectedValues, TvContract.Channels.COLUMN_TYPE); 199 verifyStringColumn(cursor, expectedValues, TvContract.Channels.COLUMN_SERVICE_TYPE); 200 verifyIntegerColumn(cursor, expectedValues, 201 TvContract.Channels.COLUMN_ORIGINAL_NETWORK_ID); 202 verifyIntegerColumn(cursor, expectedValues, 203 TvContract.Channels.COLUMN_TRANSPORT_STREAM_ID); 204 verifyIntegerColumn(cursor, expectedValues, 205 TvContract.Channels.COLUMN_SERVICE_ID); 206 verifyStringColumn(cursor, expectedValues, TvContract.Channels.COLUMN_DISPLAY_NUMBER); 207 verifyStringColumn(cursor, expectedValues, TvContract.Channels.COLUMN_DISPLAY_NAME); 208 verifyStringColumn(cursor, expectedValues, 209 TvContract.Channels.COLUMN_NETWORK_AFFILIATION); 210 verifyStringColumn(cursor, expectedValues, TvContract.Channels.COLUMN_DESCRIPTION); 211 verifyStringColumn(cursor, expectedValues, TvContract.Channels.COLUMN_VIDEO_FORMAT); 212 verifyBlobColumn(cursor, expectedValues, 213 TvContract.Channels.COLUMN_INTERNAL_PROVIDER_DATA); 214 verifyIntegerColumn(cursor, expectedValues, TvContract.Channels.COLUMN_VERSION_NUMBER); 215 } 216 } 217 testChannelsTable()218 public void testChannelsTable() throws Exception { 219 if (!Utils.hasTvInputFramework(getContext())) { 220 return; 221 } 222 // Test: insert 223 ContentValues values = createDummyChannelValues(mInputId); 224 225 Uri rowUri = mContentResolver.insert(mChannelsUri, values); 226 long channelId = ContentUris.parseId(rowUri); 227 Uri channelUri = TvContract.buildChannelUri(channelId); 228 verifyChannel(channelUri, values, channelId); 229 230 // Test: update 231 values.put(TvContract.Channels.COLUMN_DISPLAY_NUMBER, "1-1"); 232 values.put(TvContract.Channels.COLUMN_DISPLAY_NAME, "One dash one"); 233 values.put(TvContract.Channels.COLUMN_INTERNAL_PROVIDER_DATA, "Coffee".getBytes()); 234 235 mContentResolver.update(channelUri, values, null, null); 236 verifyChannel(channelUri, values, channelId); 237 238 // Test: delete 239 mContentResolver.delete(mChannelsUri, null, null); 240 try (Cursor cursor = mContentResolver.query( 241 mChannelsUri, CHANNELS_PROJECTION, null, null, null)) { 242 assertEquals(0, cursor.getCount()); 243 } 244 } 245 verifyProgram(Uri programUri, ContentValues expectedValues, long programId)246 private void verifyProgram(Uri programUri, ContentValues expectedValues, long programId) { 247 try (Cursor cursor = mContentResolver.query( 248 programUri, PROGRAMS_PROJECTION, null, null, null)) { 249 assertNotNull(cursor); 250 assertEquals(cursor.getCount(), 1); 251 assertTrue(cursor.moveToNext()); 252 assertEquals(programId, cursor.getLong(cursor.getColumnIndex(TvContract.Programs._ID))); 253 verifyLongColumn(cursor, expectedValues, TvContract.Programs.COLUMN_CHANNEL_ID); 254 verifyStringColumn(cursor, expectedValues, TvContract.Programs.COLUMN_TITLE); 255 verifyIntegerColumn(cursor, expectedValues, TvContract.Programs.COLUMN_SEASON_NUMBER); 256 verifyIntegerColumn(cursor, expectedValues, TvContract.Programs.COLUMN_EPISODE_NUMBER); 257 verifyStringColumn(cursor, expectedValues, TvContract.Programs.COLUMN_EPISODE_TITLE); 258 verifyLongColumn(cursor, expectedValues, 259 TvContract.Programs.COLUMN_START_TIME_UTC_MILLIS); 260 verifyLongColumn(cursor, expectedValues, 261 TvContract.Programs.COLUMN_END_TIME_UTC_MILLIS); 262 verifyStringColumn(cursor, expectedValues, TvContract.Programs.COLUMN_BROADCAST_GENRE); 263 verifyStringColumn(cursor, expectedValues, TvContract.Programs.COLUMN_CANONICAL_GENRE); 264 verifyStringColumn(cursor, expectedValues, 265 TvContract.Programs.COLUMN_SHORT_DESCRIPTION); 266 verifyStringColumn(cursor, expectedValues, TvContract.Programs.COLUMN_LONG_DESCRIPTION); 267 verifyIntegerColumn(cursor, expectedValues, TvContract.Programs.COLUMN_VIDEO_WIDTH); 268 verifyIntegerColumn(cursor, expectedValues, TvContract.Programs.COLUMN_VIDEO_HEIGHT); 269 verifyStringColumn(cursor, expectedValues, TvContract.Programs.COLUMN_AUDIO_LANGUAGE); 270 verifyStringColumn(cursor, expectedValues, TvContract.Programs.COLUMN_CONTENT_RATING); 271 verifyStringColumn(cursor, expectedValues, TvContract.Programs.COLUMN_POSTER_ART_URI); 272 verifyStringColumn(cursor, expectedValues, TvContract.Programs.COLUMN_THUMBNAIL_URI); 273 verifyBlobColumn(cursor, expectedValues, 274 TvContract.Programs.COLUMN_INTERNAL_PROVIDER_DATA); 275 verifyIntegerColumn(cursor, expectedValues, TvContract.Programs.COLUMN_VERSION_NUMBER); 276 } 277 } 278 verifyLogoIsReadable(Uri logoUri)279 private void verifyLogoIsReadable(Uri logoUri) throws Exception { 280 try (AssetFileDescriptor fd = mContentResolver.openAssetFileDescriptor(logoUri, "r")) { 281 try (InputStream is = fd.createInputStream()) { 282 // Assure that the stream is decodable as a Bitmap. 283 BitmapFactory.decodeStream(is); 284 } 285 } 286 } 287 testChannelLogo()288 public void testChannelLogo() throws Exception { 289 if (!Utils.hasTvInputFramework(getContext())) { 290 return; 291 } 292 // Set-up: add a channel. 293 ContentValues values = createDummyChannelValues(mInputId); 294 Uri channelUri = mContentResolver.insert(mChannelsUri, values); 295 Uri logoUri = TvContract.buildChannelLogoUri(channelUri); 296 Bitmap logo = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.robot); 297 298 // Write 299 try (AssetFileDescriptor fd = mContentResolver.openAssetFileDescriptor(logoUri, "w")) { 300 try (OutputStream os = fd.createOutputStream()) { 301 logo.compress(Bitmap.CompressFormat.PNG, 100, os); 302 } 303 } 304 305 // Give some time for TvProvider to process the logo. 306 Thread.sleep(OPERATION_TIME); 307 308 // Read and verify 309 verifyLogoIsReadable(logoUri); 310 311 // Read and verify using alternative logo URI. 312 verifyLogoIsReadable(TvContract.buildChannelLogoUri(ContentUris.parseId(channelUri))); 313 } 314 verifyProgramsTable(Uri programsUri, long channelId)315 public void verifyProgramsTable(Uri programsUri, long channelId) { 316 if (!Utils.hasTvInputFramework(getContext())) { 317 return; 318 } 319 // Test: insert 320 ContentValues values = createDummyProgramValues(channelId); 321 322 Uri rowUri = mContentResolver.insert(programsUri, values); 323 long programId = ContentUris.parseId(rowUri); 324 Uri programUri = TvContract.buildProgramUri(programId); 325 verifyProgram(programUri, values, programId); 326 327 // Test: update 328 values.put(TvContract.Programs.COLUMN_EPISODE_TITLE, "Sample title"); 329 values.put(TvContract.Programs.COLUMN_SHORT_DESCRIPTION, "Short description"); 330 values.put(TvContract.Programs.COLUMN_INTERNAL_PROVIDER_DATA, "Coffee".getBytes()); 331 332 mContentResolver.update(programUri, values, null, null); 333 verifyProgram(programUri, values, programId); 334 335 // Test: delete 336 mContentResolver.delete(programsUri, null, null); 337 try (Cursor cursor = mContentResolver.query( 338 programsUri, PROGRAMS_PROJECTION, null, null, null)) { 339 assertEquals(0, cursor.getCount()); 340 } 341 } 342 testProgramsTable()343 public void testProgramsTable() throws Exception { 344 if (!Utils.hasTvInputFramework(getContext())) { 345 return; 346 } 347 // Set-up: add a channel. 348 ContentValues values = createDummyChannelValues(mInputId); 349 Uri channelUri = mContentResolver.insert(mChannelsUri, values); 350 long channelId = ContentUris.parseId(channelUri); 351 352 verifyProgramsTable(TvContract.buildProgramsUriForChannel(channelId), channelId); 353 verifyProgramsTable(TvContract.buildProgramsUriForChannel(channelUri), channelId); 354 } 355 verifyOverlap(long startMillis, long endMillis, int expectedCount, long channelId, Uri channelUri)356 private void verifyOverlap(long startMillis, long endMillis, int expectedCount, 357 long channelId, Uri channelUri) { 358 try (Cursor cursor = mContentResolver.query(TvContract.buildProgramsUriForChannel( 359 channelId, startMillis, endMillis), PROGRAMS_PROJECTION, null, null, null)) { 360 assertEquals(expectedCount, cursor.getCount()); 361 } 362 try (Cursor cursor = mContentResolver.query(TvContract.buildProgramsUriForChannel( 363 channelUri, startMillis, endMillis), PROGRAMS_PROJECTION, null, null, null)) { 364 assertEquals(expectedCount, cursor.getCount()); 365 } 366 } 367 testProgramsScheduleOverlap()368 public void testProgramsScheduleOverlap() throws Exception { 369 if (!Utils.hasTvInputFramework(getContext())) { 370 return; 371 } 372 final long programStartMillis = 1403712000000l; // Jun 25 2014 16:00 UTC 373 final long programEndMillis = 1403719200000l; // Jun 25 2014 18:00 UTC 374 final long hour = 3600000l; 375 376 // Set-up: add a channel and program. 377 ContentValues values = createDummyChannelValues(mInputId); 378 Uri channelUri = mContentResolver.insert(mChannelsUri, values); 379 long channelId = ContentUris.parseId(channelUri); 380 Uri programsUri = TvContract.buildProgramsUriForChannel(channelId); 381 values = createDummyProgramValues(channelId); 382 values.put(TvContract.Programs.COLUMN_START_TIME_UTC_MILLIS, programStartMillis); 383 values.put(TvContract.Programs.COLUMN_END_TIME_UTC_MILLIS, programEndMillis); 384 mContentResolver.insert(programsUri, values); 385 386 // Overlap 1: starts early, ends early. 387 verifyOverlap(programStartMillis - hour, programEndMillis - hour, 1, channelId, channelUri); 388 389 // Overlap 2: starts early, ends late. 390 verifyOverlap(programStartMillis - hour, programEndMillis + hour, 1, channelId, channelUri); 391 392 // Overlap 3: starts early, ends late. 393 verifyOverlap(programStartMillis + hour / 2, programEndMillis - hour / 2, 1, 394 channelId, channelUri); 395 396 // Overlap 4: starts late, ends late. 397 verifyOverlap(programStartMillis + hour, programEndMillis + hour, 1, channelId, channelUri); 398 399 // Non-overlap 1: ends too early. 400 verifyOverlap(programStartMillis - hour, programStartMillis - hour / 2, 0, 401 channelId, channelUri); 402 403 // Non-overlap 2: starts too late 404 verifyOverlap(programEndMillis + hour, programEndMillis + hour * 2, 0, 405 channelId, channelUri); 406 } 407 verifyQueryWithSortOrder(Uri uri, final String[] projection, String sortOrder)408 private void verifyQueryWithSortOrder(Uri uri, final String[] projection, 409 String sortOrder) throws Exception { 410 try { 411 getContext().getContentResolver().query(uri, projection, null, null, sortOrder); 412 } catch (SecurityException e) { 413 fail("Setting sort order shoud be allowed for " + uri); 414 } 415 } 416 verifyQueryWithSelection(Uri uri, final String[] projection, String selection)417 private void verifyQueryWithSelection(Uri uri, final String[] projection, 418 String selection) throws Exception { 419 try { 420 getContext().getContentResolver().query(uri, projection, selection, null, null); 421 fail("Setting selection should fail without ACCESS_ALL_EPG_DATA permission for " + uri); 422 } catch (SecurityException e) { 423 // Expected exception 424 } 425 } 426 verifyUpdateWithSelection(Uri uri, String selection)427 private void verifyUpdateWithSelection(Uri uri, String selection) throws Exception { 428 try { 429 ContentValues values = new ContentValues(); 430 getContext().getContentResolver().update(uri, values, selection, null); 431 fail("Setting selection should fail without ACCESS_ALL_EPG_DATA permission for " + uri); 432 } catch (SecurityException e) { 433 // Expected exception 434 } 435 } 436 verifyDeleteWithSelection(Uri uri, String selection)437 private void verifyDeleteWithSelection(Uri uri, String selection) throws Exception { 438 try { 439 getContext().getContentResolver().delete(uri, selection, null); 440 fail("Setting selection should fail without ACCESS_ALL_EPG_DATA permission for " + uri); 441 } catch (SecurityException e) { 442 // Expected exception 443 } 444 } 445 testAllEpgPermissionBlocksSortOrderOnQuery_Channels()446 public void testAllEpgPermissionBlocksSortOrderOnQuery_Channels() throws Exception { 447 if (!Utils.hasTvInputFramework(getContext())) { 448 return; 449 } 450 final String[] projection = { TvContract.Channels._ID }; 451 verifyQueryWithSortOrder(TvContract.Channels.CONTENT_URI, projection, 452 TvContract.Channels._ID + " ASC"); 453 } 454 testAllEpgPermissionBlocksSelectionOnQuery_Channels()455 public void testAllEpgPermissionBlocksSelectionOnQuery_Channels() throws Exception { 456 if (!Utils.hasTvInputFramework(getContext())) { 457 return; 458 } 459 final String[] projection = { TvContract.Channels._ID }; 460 verifyQueryWithSelection(TvContract.Channels.CONTENT_URI, projection, 461 TvContract.Channels._ID + ">0"); 462 } 463 testAllEpgPermissionBlocksSelectionOnUpdate_Channels()464 public void testAllEpgPermissionBlocksSelectionOnUpdate_Channels() throws Exception { 465 if (!Utils.hasTvInputFramework(getContext())) { 466 return; 467 } 468 verifyUpdateWithSelection(TvContract.Channels.CONTENT_URI, 469 TvContract.Channels._ID + ">0"); 470 } 471 testAllEpgPermissionBlocksSelectionOnDelete_Channels()472 public void testAllEpgPermissionBlocksSelectionOnDelete_Channels() throws Exception { 473 if (!Utils.hasTvInputFramework(getContext())) { 474 return; 475 } 476 verifyDeleteWithSelection(TvContract.Channels.CONTENT_URI, 477 TvContract.Channels._ID + ">0"); 478 } 479 testAllEpgPermissionBlocksSortOrderOnQuery_Programs()480 public void testAllEpgPermissionBlocksSortOrderOnQuery_Programs() throws Exception { 481 if (!Utils.hasTvInputFramework(getContext())) { 482 return; 483 } 484 final String[] projection = { TvContract.Programs._ID }; 485 verifyQueryWithSortOrder(TvContract.Programs.CONTENT_URI, projection, 486 TvContract.Programs._ID + " ASC"); 487 } 488 testAllEpgPermissionBlocksSelectionOnQuery_Programs()489 public void testAllEpgPermissionBlocksSelectionOnQuery_Programs() throws Exception { 490 if (!Utils.hasTvInputFramework(getContext())) { 491 return; 492 } 493 final String[] projection = { TvContract.Channels._ID }; 494 verifyQueryWithSelection(TvContract.Programs.CONTENT_URI, projection, 495 TvContract.Programs._ID + ">0"); 496 } 497 testAllEpgPermissionBlocksSelectionOnUpdate_Programs()498 public void testAllEpgPermissionBlocksSelectionOnUpdate_Programs() throws Exception { 499 if (!Utils.hasTvInputFramework(getContext())) { 500 return; 501 } 502 verifyUpdateWithSelection(TvContract.Programs.CONTENT_URI, 503 TvContract.Programs._ID + ">0"); 504 } 505 testAllEpgPermissionBlocksSelectionOnDelete_Programs()506 public void testAllEpgPermissionBlocksSelectionOnDelete_Programs() throws Exception { 507 if (!Utils.hasTvInputFramework(getContext())) { 508 return; 509 } 510 verifyDeleteWithSelection(TvContract.Programs.CONTENT_URI, 511 TvContract.Programs._ID + ">0"); 512 } 513 testDefaultValues()514 public void testDefaultValues() throws Exception { 515 if (!Utils.hasTvInputFramework(getContext())) { 516 return; 517 } 518 ContentValues values = new ContentValues(); 519 values.put(TvContract.Channels.COLUMN_INPUT_ID, mInputId); 520 Uri channelUri = mContentResolver.insert(mChannelsUri, values); 521 assertNotNull(channelUri); 522 try (Cursor cursor = mContentResolver.query( 523 channelUri, CHANNELS_PROJECTION, null, null, null)) { 524 cursor.moveToNext(); 525 assertEquals(TvContract.Channels.TYPE_OTHER, 526 cursor.getString(cursor.getColumnIndex(TvContract.Channels.COLUMN_TYPE))); 527 assertEquals(TvContract.Channels.SERVICE_TYPE_AUDIO_VIDEO, 528 cursor.getString(cursor.getColumnIndex( 529 TvContract.Channels.COLUMN_SERVICE_TYPE))); 530 } 531 values.clear(); 532 } 533 testChannelsGetVideoResolution()534 public void testChannelsGetVideoResolution() { 535 if (!Utils.hasTvInputFramework(getContext())) { 536 return; 537 } 538 assertEquals(Channels.VIDEO_RESOLUTION_SD, Channels.getVideoResolution( 539 Channels.VIDEO_FORMAT_480I)); 540 assertEquals(Channels.VIDEO_RESOLUTION_ED, Channels.getVideoResolution( 541 Channels.VIDEO_FORMAT_480P)); 542 assertEquals(Channels.VIDEO_RESOLUTION_SD, Channels.getVideoResolution( 543 Channels.VIDEO_FORMAT_576I)); 544 assertEquals(Channels.VIDEO_RESOLUTION_ED, Channels.getVideoResolution( 545 Channels.VIDEO_FORMAT_576P)); 546 assertEquals(Channels.VIDEO_RESOLUTION_HD, Channels.getVideoResolution( 547 Channels.VIDEO_FORMAT_720P)); 548 assertEquals(Channels.VIDEO_RESOLUTION_HD, Channels.getVideoResolution( 549 Channels.VIDEO_FORMAT_1080I)); 550 assertEquals(Channels.VIDEO_RESOLUTION_FHD, Channels.getVideoResolution( 551 Channels.VIDEO_FORMAT_1080P)); 552 assertEquals(Channels.VIDEO_RESOLUTION_UHD, Channels.getVideoResolution( 553 Channels.VIDEO_FORMAT_2160P)); 554 assertEquals(Channels.VIDEO_RESOLUTION_UHD, Channels.getVideoResolution( 555 Channels.VIDEO_FORMAT_4320P)); 556 assertEquals(null, Channels.getVideoResolution("Unknown format")); 557 } 558 testProgramsGenresDecode()559 public void testProgramsGenresDecode() { 560 if (!Utils.hasTvInputFramework(getContext())) { 561 return; 562 } 563 List genres = Arrays.asList(Genres.decode(ENCODED_GENRE_STRING)); 564 assertEquals(11, genres.size()); 565 assertTrue(genres.contains(Genres.ANIMAL_WILDLIFE)); 566 assertTrue(genres.contains(Genres.COMEDY)); 567 assertTrue(genres.contains(Genres.DRAMA)); 568 assertTrue(genres.contains(Genres.EDUCATION)); 569 assertTrue(genres.contains(Genres.FAMILY_KIDS)); 570 assertTrue(genres.contains(Genres.GAMING)); 571 assertTrue(genres.contains(Genres.MOVIES)); 572 assertTrue(genres.contains(Genres.NEWS)); 573 assertTrue(genres.contains(Genres.SHOPPING)); 574 assertTrue(genres.contains(Genres.SPORTS)); 575 assertTrue(genres.contains(Genres.TRAVEL)); 576 assertFalse(genres.contains(",")); 577 } 578 testProgramsGenresEncode()579 public void testProgramsGenresEncode() { 580 if (!Utils.hasTvInputFramework(getContext())) { 581 return; 582 } 583 assertEquals(ENCODED_GENRE_STRING, Genres.encode(Genres.ANIMAL_WILDLIFE, 584 Genres.COMEDY, Genres.DRAMA, Genres.EDUCATION, Genres.FAMILY_KIDS, Genres.GAMING, 585 Genres.MOVIES, Genres.NEWS, Genres.SHOPPING, Genres.SPORTS, Genres.TRAVEL)); 586 } 587 } 588