1/*
2 * Copyright (C) 2015 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
17package com.android.tv.testing;
18
19import android.content.ContentUris;
20import android.content.ContentValues;
21import android.content.Context;
22import android.database.Cursor;
23import android.media.tv.TvContract;
24import android.media.tv.TvContract.Programs;
25import android.net.Uri;
26import android.util.Log;
27
28import com.android.tv.common.TvContentRatingCache;
29
30import java.util.ArrayList;
31import java.util.concurrent.TimeUnit;
32
33public class ProgramUtils {
34    private static final String TAG = "ProgramUtils";
35    private static final boolean DEBUG = false;
36
37    // Populate program data for a week.
38    private static final long PROGRAM_INSERT_DURATION_MS = TimeUnit.DAYS.toMillis(7);
39    private static final int MAX_DB_INSERT_COUNT_AT_ONCE = 500;
40
41    /**
42     * Populate programs by repeating given program information.
43     * This method will populate programs without any gap nor overlapping
44     * starting from the current time.
45     */
46    public static void populatePrograms(Context context, Uri channelUri, ProgramInfo program) {
47        ContentValues values = new ContentValues();
48        long channelId = ContentUris.parseId(channelUri);
49
50        values.put(Programs.COLUMN_CHANNEL_ID, channelId);
51        values.put(Programs.COLUMN_SHORT_DESCRIPTION, program.description);
52        values.put(Programs.COLUMN_CONTENT_RATING,
53                TvContentRatingCache.contentRatingsToString(program.contentRatings));
54
55        long currentTimeMs = System.currentTimeMillis();
56        long targetEndTimeMs = currentTimeMs + PROGRAM_INSERT_DURATION_MS;
57        long timeMs = getLastProgramEndTimeMs(context, channelUri, currentTimeMs, targetEndTimeMs);
58        if (timeMs <= 0) {
59            timeMs = currentTimeMs;
60        }
61        int index = program.getIndex(timeMs, channelId);
62        timeMs = program.getStartTimeMs(index, channelId);
63
64        ArrayList<ContentValues> list = new ArrayList<>();
65        while (timeMs < targetEndTimeMs) {
66            ProgramInfo programAt = program.build(context, index++);
67            values.put(Programs.COLUMN_TITLE, programAt.title);
68            values.put(Programs.COLUMN_EPISODE_TITLE, programAt.episode);
69            values.put(Programs.COLUMN_SEASON_NUMBER, programAt.seasonNumber);
70            values.put(Programs.COLUMN_EPISODE_NUMBER, programAt.episodeNumber);
71            values.put(Programs.COLUMN_POSTER_ART_URI, programAt.posterArtUri);
72            values.put(Programs.COLUMN_START_TIME_UTC_MILLIS, timeMs);
73            values.put(Programs.COLUMN_END_TIME_UTC_MILLIS, timeMs + programAt.durationMs);
74            values.put(Programs.COLUMN_CANONICAL_GENRE, programAt.genre);
75            values.put(Programs.COLUMN_POSTER_ART_URI, programAt.posterArtUri);
76            list.add(new ContentValues(values));
77            timeMs += programAt.durationMs;
78
79            if (list.size() >= MAX_DB_INSERT_COUNT_AT_ONCE
80                    || timeMs >= targetEndTimeMs) {
81                context.getContentResolver().bulkInsert(Programs.CONTENT_URI,
82                        list.toArray(new ContentValues[list.size()]));
83                if (DEBUG) Log.d(TAG, "Inserted " + list.size() + " programs for " + channelUri);
84                list.clear();
85            }
86        }
87    }
88
89    private static long getLastProgramEndTimeMs(
90            Context context, Uri channelUri, long startTimeMs, long endTimeMs) {
91        Uri uri = TvContract.buildProgramsUriForChannel(channelUri, startTimeMs, endTimeMs);
92        String[] projection = {Programs.COLUMN_END_TIME_UTC_MILLIS};
93        try (Cursor cursor =
94                context.getContentResolver().query(uri, projection, null, null, null)) {
95            if (cursor != null && cursor.moveToLast()) {
96                return cursor.getLong(0);
97            }
98        }
99        return 0;
100    }
101
102    private ProgramUtils() {}
103}
104