1816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko/* 2816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * Copyright (C) 2015 The Android Open Source Project 3816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * 4816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * Licensed under the Apache License, Version 2.0 (the "License"); 5816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * you may not use this file except in compliance with the License. 6816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * You may obtain a copy of the License at 7816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * 8816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * http://www.apache.org/licenses/LICENSE-2.0 9816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * 10816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * Unless required by applicable law or agreed to in writing, software 11816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * distributed under the License is distributed on an "AS IS" BASIS, 12816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * See the License for the specific language governing permissions and 14816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * limitations under the License. 15816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko */ 16816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 17816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkopackage com.android.tv.testing; 18816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 19816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.content.ContentUris; 20816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.content.ContentValues; 21816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.content.Context; 22816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.database.Cursor; 23d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalkoimport android.database.sqlite.SQLiteException; 24816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.media.tv.TvContract; 25816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.media.tv.TvContract.Programs; 26816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.net.Uri; 27816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport android.util.Log; 28816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 29ba5845f23b8fbc985890f892961abc8b39886611Nick Chalkoimport com.android.tv.common.TvContentRatingCache; 30ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko 31816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport java.util.ArrayList; 32816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkoimport java.util.concurrent.TimeUnit; 33816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 34816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalkopublic class ProgramUtils { 35816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private static final String TAG = "ProgramUtils"; 361abddd9f6225298066094e20a6c29061b6af4590Nick Chalko private static final boolean DEBUG = false; 37816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 38816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko // Populate program data for a week. 39816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private static final long PROGRAM_INSERT_DURATION_MS = TimeUnit.DAYS.toMillis(7); 40816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private static final int MAX_DB_INSERT_COUNT_AT_ONCE = 500; 41816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 42816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko /** 43816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * Populate programs by repeating given program information. 44816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * This method will populate programs without any gap nor overlapping 45816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko * starting from the current time. 46816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko */ 47816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko public static void populatePrograms(Context context, Uri channelUri, ProgramInfo program) { 48816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko ContentValues values = new ContentValues(); 49816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko long channelId = ContentUris.parseId(channelUri); 50816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 51816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko values.put(Programs.COLUMN_CHANNEL_ID, channelId); 52816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko values.put(Programs.COLUMN_SHORT_DESCRIPTION, program.description); 53816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko values.put(Programs.COLUMN_CONTENT_RATING, 54ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko TvContentRatingCache.contentRatingsToString(program.contentRatings)); 55816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 56816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko long currentTimeMs = System.currentTimeMillis(); 57816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko long targetEndTimeMs = currentTimeMs + PROGRAM_INSERT_DURATION_MS; 58816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko long timeMs = getLastProgramEndTimeMs(context, channelUri, currentTimeMs, targetEndTimeMs); 59816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (timeMs <= 0) { 60816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko timeMs = currentTimeMs; 61816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 62816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko int index = program.getIndex(timeMs, channelId); 63816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko timeMs = program.getStartTimeMs(index, channelId); 64816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 65816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko ArrayList<ContentValues> list = new ArrayList<>(); 66816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko while (timeMs < targetEndTimeMs) { 67816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko ProgramInfo programAt = program.build(context, index++); 68816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko values.put(Programs.COLUMN_TITLE, programAt.title); 69816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko values.put(Programs.COLUMN_EPISODE_TITLE, programAt.episode); 7065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (programAt.seasonNumber != 0) { 7165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko values.put(Programs.COLUMN_SEASON_NUMBER, programAt.seasonNumber); 7265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 7365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (programAt.episodeNumber != 0) { 7465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko values.put(Programs.COLUMN_EPISODE_NUMBER, programAt.episodeNumber); 7565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 76816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko values.put(Programs.COLUMN_POSTER_ART_URI, programAt.posterArtUri); 77816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko values.put(Programs.COLUMN_START_TIME_UTC_MILLIS, timeMs); 78816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko values.put(Programs.COLUMN_END_TIME_UTC_MILLIS, timeMs + programAt.durationMs); 79816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko values.put(Programs.COLUMN_CANONICAL_GENRE, programAt.genre); 80816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko values.put(Programs.COLUMN_POSTER_ART_URI, programAt.posterArtUri); 81816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko list.add(new ContentValues(values)); 82816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko timeMs += programAt.durationMs; 83816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 84816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (list.size() >= MAX_DB_INSERT_COUNT_AT_ONCE 85816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko || timeMs >= targetEndTimeMs) { 86d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko try { 87d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko context.getContentResolver().bulkInsert(Programs.CONTENT_URI, 88d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko list.toArray(new ContentValues[list.size()])); 89d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } catch (SQLiteException e) { 90d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko Log.e(TAG, "Can't insert EPG.", e); 91d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko return; 92d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 931abddd9f6225298066094e20a6c29061b6af4590Nick Chalko if (DEBUG) Log.d(TAG, "Inserted " + list.size() + " programs for " + channelUri); 94816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko list.clear(); 95816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 96816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 97816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 98816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 99816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private static long getLastProgramEndTimeMs( 100816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko Context context, Uri channelUri, long startTimeMs, long endTimeMs) { 101816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko Uri uri = TvContract.buildProgramsUriForChannel(channelUri, startTimeMs, endTimeMs); 102816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko String[] projection = {Programs.COLUMN_END_TIME_UTC_MILLIS}; 103816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko try (Cursor cursor = 104816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko context.getContentResolver().query(uri, projection, null, null, null)) { 105816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko if (cursor != null && cursor.moveToLast()) { 106816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko return cursor.getLong(0); 107816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 108816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 109816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko return 0; 110816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko } 111816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko 112816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko private ProgramUtils() {} 113816a4be1a0f34f6a48877c8afd3dbbca19eac435Nick Chalko} 114