diff options
Diffstat (limited to 'tests/common/src/com/android/tv/testing/data/ProgramUtils.java')
-rw-r--r-- | tests/common/src/com/android/tv/testing/data/ProgramUtils.java | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/tests/common/src/com/android/tv/testing/data/ProgramUtils.java b/tests/common/src/com/android/tv/testing/data/ProgramUtils.java new file mode 100644 index 00000000..21647719 --- /dev/null +++ b/tests/common/src/com/android/tv/testing/data/ProgramUtils.java @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2015 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.tv.testing.data; + +import android.content.ContentUris; +import android.content.ContentValues; +import android.content.Context; +import android.database.Cursor; +import android.database.sqlite.SQLiteException; +import android.media.tv.TvContract; +import android.media.tv.TvContract.Programs; +import android.net.Uri; +import android.util.Log; +import com.android.tv.common.TvContentRatingCache; +import com.android.tv.common.util.Clock; +import java.util.ArrayList; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +/** Static utilities for using Programs in tests */ +public final class ProgramUtils { + private static final String TAG = "ProgramUtils"; + private static final boolean DEBUG = false; + + /** Populate program data for a week */ + public static final long PROGRAM_INSERT_DURATION_MS = TimeUnit.DAYS.toMillis(7); + + private static final int MAX_DB_INSERT_COUNT_AT_ONCE = 500; + + /** + * Populate programs by repeating given program information. This method will populate programs + * without any gap nor overlapping starting from the current time. + */ + public static void populatePrograms( + Context context, Uri channelUri, ProgramInfo program, Clock clock) { + populatePrograms(context, channelUri, program, clock, PROGRAM_INSERT_DURATION_MS); + } + + public static void populatePrograms( + Context context, + Uri channelUri, + ProgramInfo program, + Clock clock, + long programInsertDurationMs) { + long currentTimeMs = clock.currentTimeMillis(); + long targetEndTimeMs = currentTimeMs + programInsertDurationMs; + populatePrograms(context, channelUri, program, currentTimeMs, targetEndTimeMs); + } + + public static void populatePrograms( + Context context, + Uri channelUri, + ProgramInfo program, + long currentTimeMs, + long targetEndTimeMs) { + ContentValues values = new ContentValues(); + long channelId = ContentUris.parseId(channelUri); + + values.put(Programs.COLUMN_CHANNEL_ID, channelId); + values.put(Programs.COLUMN_SHORT_DESCRIPTION, program.description); + values.put( + Programs.COLUMN_CONTENT_RATING, + TvContentRatingCache.contentRatingsToString(program.contentRatings)); + + long timeMs = getLastProgramEndTimeMs(context, channelUri, currentTimeMs, targetEndTimeMs); + if (timeMs <= 0) { + timeMs = currentTimeMs; + } + int index = program.getIndex(timeMs, channelId); + timeMs = program.getStartTimeMs(index, channelId); + + ArrayList<ContentValues> list = new ArrayList<>(); + while (timeMs < targetEndTimeMs) { + ProgramInfo programAt = program.build(context, index++); + values.put(Programs.COLUMN_TITLE, programAt.title); + values.put(Programs.COLUMN_EPISODE_TITLE, programAt.episode); + if (programAt.seasonNumber != 0) { + values.put(Programs.COLUMN_SEASON_NUMBER, programAt.seasonNumber); + } + if (programAt.episodeNumber != 0) { + values.put(Programs.COLUMN_EPISODE_NUMBER, programAt.episodeNumber); + } + values.put(Programs.COLUMN_POSTER_ART_URI, programAt.posterArtUri); + values.put(Programs.COLUMN_START_TIME_UTC_MILLIS, timeMs); + values.put(Programs.COLUMN_END_TIME_UTC_MILLIS, timeMs + programAt.durationMs); + values.put(Programs.COLUMN_CANONICAL_GENRE, programAt.genre); + values.put(Programs.COLUMN_POSTER_ART_URI, programAt.posterArtUri); + list.add(new ContentValues(values)); + timeMs += programAt.durationMs; + + if (list.size() >= MAX_DB_INSERT_COUNT_AT_ONCE || timeMs >= targetEndTimeMs) { + try { + context.getContentResolver() + .bulkInsert( + Programs.CONTENT_URI, + list.toArray(new ContentValues[list.size()])); + } catch (SQLiteException e) { + Log.e(TAG, "Can't insert EPG.", e); + return; + } + if (DEBUG) Log.d(TAG, "Inserted " + list.size() + " programs for " + channelUri); + list.clear(); + } + } + } + + private static long getLastProgramEndTimeMs( + Context context, Uri channelUri, long startTimeMs, long endTimeMs) { + Uri uri = TvContract.buildProgramsUriForChannel(channelUri, startTimeMs, endTimeMs); + String[] projection = {Programs.COLUMN_END_TIME_UTC_MILLIS}; + try (Cursor cursor = + context.getContentResolver().query(uri, projection, null, null, null)) { + if (cursor != null && cursor.moveToLast()) { + return cursor.getLong(0); + } + } + return 0; + } + + private ProgramUtils() {} + + public static void updateProgramForAllChannelsOf( + Context context, String inputId, Clock clock, long durationMs) { + // Reload channels so we have the ids. + Map<Long, ChannelInfo> channelIdToInfoMap = + ChannelUtils.queryChannelInfoMapForTvInput(context, inputId); + for (Long channelId : channelIdToInfoMap.keySet()) { + ProgramInfo programInfo = ProgramInfo.create(); + populatePrograms( + context, TvContract.buildChannelUri(channelId), programInfo, clock, durationMs); + } + } +} |