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