1/*
2 * Copyright (C) 2017 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.providers.tv;
18
19import android.content.Context;
20import android.content.pm.ProviderInfo;
21import android.database.Cursor;
22import android.database.sqlite.SQLiteDatabase;
23import android.media.tv.TvContract;
24import android.os.Bundle;
25import android.provider.Settings;
26import android.test.AndroidTestCase;
27import android.test.mock.MockContentProvider;
28import android.test.mock.MockContentResolver;
29
30public class DatabaseHelperTest extends AndroidTestCase {
31    private static final int BASE_DATABASE_VERSION = 23;
32
33    private DatabaseHelperForTesting mDatabaseHelper;
34    private MockContentResolver mResolver;
35    private TvProviderForTesting mProvider;
36
37    @Override
38    protected void setUp() throws Exception {
39        super.setUp();
40        mResolver = new MockContentResolver();
41        mResolver.addProvider(Settings.AUTHORITY, new MockContentProvider() {
42            @Override
43            public Bundle call(String method, String request, Bundle args) {
44                return new Bundle();
45            }
46        });
47
48        mProvider = new TvProviderForTesting();
49        mResolver.addProvider(TvContract.AUTHORITY, mProvider);
50
51        setContext(new MockTvProviderContext(mResolver, getContext()));
52
53        final ProviderInfo info = new ProviderInfo();
54        info.authority = TvContract.AUTHORITY;
55        mProvider.attachInfoForTesting(getContext(), info);
56        mDatabaseHelper = new DatabaseHelperForTesting(getContext(), BASE_DATABASE_VERSION);
57        mProvider.setOpenHelper(mDatabaseHelper);
58    }
59
60    @Override
61    protected void tearDown() throws Exception {
62        mProvider.shutdown();
63        super.tearDown();
64    }
65
66    public void testUpgradeDatabase() {
67        SQLiteDatabase db = mDatabaseHelper.getReadableDatabase();
68        assertEquals(BASE_DATABASE_VERSION, db.getVersion());
69        mDatabaseHelper.close();
70
71        mProvider.setOpenHelper(
72                new DatabaseHelperForTesting(getContext(), TvProvider.DATABASE_VERSION));
73
74        try (Cursor cursor = mResolver.query(
75                TvContract.Channels.CONTENT_URI, null, null, null, null)) {
76            assertNotNull(cursor);
77        }
78        try (Cursor cursor = mResolver.query(
79                TvContract.Programs.CONTENT_URI, null, null, null, null)) {
80            assertNotNull(cursor);
81        }
82        try (Cursor cursor = mResolver.query(
83                TvContract.WatchedPrograms.CONTENT_URI, null, null, null, null)) {
84            assertNotNull(cursor);
85        }
86        try (Cursor cursor = mResolver.query(
87                TvContract.RecordedPrograms.CONTENT_URI, null, null, null, null)) {
88            assertNotNull(cursor);
89        }
90        try (Cursor cursor = mResolver.query(
91                TvContract.PreviewPrograms.CONTENT_URI, null, null, null, null)) {
92            assertNotNull(cursor);
93        }
94        try (Cursor cursor = mResolver.query(
95                TvContract.WatchNextPrograms.CONTENT_URI, null, null, null, null)) {
96            assertNotNull(cursor);
97        }
98    }
99
100    private static class DatabaseHelperForTesting extends TvProvider.DatabaseHelper {
101        private static final String DATABASE_NAME ="tvtest.db";
102
103        private DatabaseHelperForTesting(Context context, int version) {
104            super(context, DATABASE_NAME, version);
105        }
106
107        @Override
108        public void onCreate(SQLiteDatabase db) {
109            // Set up the database schema for version 23.
110            db.execSQL("CREATE TABLE " + TvProvider.CHANNELS_TABLE + " ("
111                    + TvContract.Channels._ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
112                    + TvContract.Channels.COLUMN_PACKAGE_NAME + " TEXT NOT NULL,"
113                    + TvContract.Channels.COLUMN_INPUT_ID + " TEXT NOT NULL,"
114                    + TvContract.Channels.COLUMN_TYPE + " TEXT NOT NULL DEFAULT '" + TvContract
115                    .Channels.TYPE_OTHER + "',"
116                    + TvContract.Channels.COLUMN_SERVICE_TYPE + " TEXT NOT NULL DEFAULT '"
117                    + TvContract.Channels.SERVICE_TYPE_AUDIO_VIDEO + "',"
118                    + TvContract.Channels.COLUMN_ORIGINAL_NETWORK_ID
119                    + " INTEGER NOT NULL DEFAULT 0,"
120                    + TvContract.Channels.COLUMN_TRANSPORT_STREAM_ID
121                    + " INTEGER NOT NULL DEFAULT 0,"
122                    + TvContract.Channels.COLUMN_SERVICE_ID + " INTEGER NOT NULL DEFAULT 0,"
123                    + TvContract.Channels.COLUMN_DISPLAY_NUMBER + " TEXT,"
124                    + TvContract.Channels.COLUMN_DISPLAY_NAME + " TEXT,"
125                    + TvContract.Channels.COLUMN_NETWORK_AFFILIATION + " TEXT,"
126                    + TvContract.Channels.COLUMN_DESCRIPTION + " TEXT,"
127                    + TvContract.Channels.COLUMN_VIDEO_FORMAT + " TEXT,"
128                    + TvContract.Channels.COLUMN_BROWSABLE + " INTEGER NOT NULL DEFAULT 0,"
129                    + TvContract.Channels.COLUMN_SEARCHABLE + " INTEGER NOT NULL DEFAULT 1,"
130                    + TvContract.Channels.COLUMN_LOCKED + " INTEGER NOT NULL DEFAULT 0,"
131                    + TvContract.Channels.COLUMN_INTERNAL_PROVIDER_DATA + " BLOB,"
132                    + TvProvider.CHANNELS_COLUMN_LOGO + " BLOB,"
133                    + TvContract.Channels.COLUMN_VERSION_NUMBER + " INTEGER,"
134                    // Needed for foreign keys in other tables.
135                    + "UNIQUE(" + TvContract.Channels._ID + ","
136                    + TvContract.Channels.COLUMN_PACKAGE_NAME + ")"
137                    + ");");
138            db.execSQL("CREATE TABLE " + TvProvider.PROGRAMS_TABLE + " ("
139                    + TvContract.Programs._ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
140                    + TvContract.Programs.COLUMN_PACKAGE_NAME + " TEXT NOT NULL,"
141                    + TvContract.Programs.COLUMN_CHANNEL_ID + " INTEGER,"
142                    + TvContract.Programs.COLUMN_TITLE + " TEXT,"
143                    + TvContract.Programs.COLUMN_SEASON_NUMBER + " TEXT,"
144                    + TvContract.Programs.COLUMN_EPISODE_NUMBER + " TEXT,"
145                    + TvContract.Programs.COLUMN_EPISODE_TITLE + " TEXT,"
146                    + TvContract.Programs.COLUMN_START_TIME_UTC_MILLIS + " INTEGER,"
147                    + TvContract.Programs.COLUMN_END_TIME_UTC_MILLIS + " INTEGER,"
148                    + TvContract.Programs.COLUMN_BROADCAST_GENRE + " TEXT,"
149                    + TvContract.Programs.COLUMN_CANONICAL_GENRE + " TEXT,"
150                    + TvContract.Programs.COLUMN_SHORT_DESCRIPTION + " TEXT,"
151                    + TvContract.Programs.COLUMN_LONG_DESCRIPTION + " TEXT,"
152                    + TvContract.Programs.COLUMN_VIDEO_WIDTH + " INTEGER,"
153                    + TvContract.Programs.COLUMN_VIDEO_HEIGHT + " INTEGER,"
154                    + TvContract.Programs.COLUMN_AUDIO_LANGUAGE + " TEXT,"
155                    + TvContract.Programs.COLUMN_CONTENT_RATING + " TEXT,"
156                    + TvContract.Programs.COLUMN_POSTER_ART_URI + " TEXT,"
157                    + TvContract.Programs.COLUMN_THUMBNAIL_URI + " TEXT,"
158                    + TvContract.Programs.COLUMN_INTERNAL_PROVIDER_DATA + " BLOB,"
159                    + TvContract.Programs.COLUMN_VERSION_NUMBER + " INTEGER,"
160                    + "FOREIGN KEY("
161                    + TvContract.Programs.COLUMN_CHANNEL_ID + ","
162                    + TvContract.Programs.COLUMN_PACKAGE_NAME
163                    + ") REFERENCES " + TvProvider.CHANNELS_TABLE + "("
164                    + TvContract.Channels._ID + "," + TvContract.Channels.COLUMN_PACKAGE_NAME
165                    + ") ON UPDATE CASCADE ON DELETE CASCADE"
166                    + ");");
167            db.execSQL("CREATE INDEX " + TvProvider.PROGRAMS_TABLE_PACKAGE_NAME_INDEX + " ON "
168                    + TvProvider.PROGRAMS_TABLE
169                    + "(" + TvContract.Programs.COLUMN_PACKAGE_NAME + ");");
170            db.execSQL("CREATE INDEX " + TvProvider.PROGRAMS_TABLE_CHANNEL_ID_INDEX + " ON "
171                    + TvProvider.PROGRAMS_TABLE
172                    + "(" + TvContract.Programs.COLUMN_CHANNEL_ID + ");");
173            db.execSQL("CREATE INDEX " + TvProvider.PROGRAMS_TABLE_START_TIME_INDEX + " ON "
174                    + TvProvider.PROGRAMS_TABLE
175                    + "(" + TvContract.Programs.COLUMN_START_TIME_UTC_MILLIS + ");");
176            db.execSQL("CREATE INDEX " + TvProvider.PROGRAMS_TABLE_END_TIME_INDEX + " ON "
177                    + TvProvider.PROGRAMS_TABLE
178                    + "(" + TvContract.Programs.COLUMN_END_TIME_UTC_MILLIS + ");");
179            db.execSQL("CREATE TABLE " + TvProvider.WATCHED_PROGRAMS_TABLE + " ("
180                    + TvContract.WatchedPrograms._ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
181                    + TvContract.WatchedPrograms.COLUMN_PACKAGE_NAME + " TEXT NOT NULL,"
182                    + TvContract.WatchedPrograms.COLUMN_WATCH_START_TIME_UTC_MILLIS
183                    + " INTEGER NOT NULL DEFAULT 0,"
184                    + TvContract.WatchedPrograms.COLUMN_WATCH_END_TIME_UTC_MILLIS
185                    + " INTEGER NOT NULL DEFAULT 0,"
186                    + TvContract.WatchedPrograms.COLUMN_CHANNEL_ID + " INTEGER,"
187                    + TvContract.WatchedPrograms.COLUMN_TITLE + " TEXT,"
188                    + TvContract.WatchedPrograms.COLUMN_START_TIME_UTC_MILLIS + " INTEGER,"
189                    + TvContract.WatchedPrograms.COLUMN_END_TIME_UTC_MILLIS + " INTEGER,"
190                    + TvContract.WatchedPrograms.COLUMN_DESCRIPTION + " TEXT,"
191                    + TvContract.WatchedPrograms.COLUMN_INTERNAL_TUNE_PARAMS + " TEXT,"
192                    + TvContract.WatchedPrograms.COLUMN_INTERNAL_SESSION_TOKEN + " TEXT NOT NULL,"
193                    + TvProvider.WATCHED_PROGRAMS_COLUMN_CONSOLIDATED
194                    + " INTEGER NOT NULL DEFAULT 0,"
195                    + "FOREIGN KEY("
196                    + TvContract.WatchedPrograms.COLUMN_CHANNEL_ID + ","
197                    + TvContract.WatchedPrograms.COLUMN_PACKAGE_NAME
198                    + ") REFERENCES " + TvProvider.CHANNELS_TABLE + "("
199                    + TvContract.Channels._ID + "," + TvContract.Channels.COLUMN_PACKAGE_NAME
200                    + ") ON UPDATE CASCADE ON DELETE CASCADE"
201                    + ");");
202            db.execSQL("CREATE INDEX " + TvProvider.WATCHED_PROGRAMS_TABLE_CHANNEL_ID_INDEX + " ON "
203                    + TvProvider.WATCHED_PROGRAMS_TABLE
204                    + "(" + TvContract.WatchedPrograms.COLUMN_CHANNEL_ID + ");");
205        }
206
207        @Override
208        public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
209            assertEquals(BASE_DATABASE_VERSION, newVersion);
210            db.execSQL("DROP TABLE IF EXISTS " + TvProvider.WATCH_NEXT_PROGRAMS_TABLE);
211            db.execSQL("DROP TABLE IF EXISTS " + TvProvider.PREVIEW_PROGRAMS_TABLE);
212            db.execSQL("DROP TABLE IF EXISTS " + TvProvider.RECORDED_PROGRAMS_TABLE);
213            db.execSQL("DROP TABLE IF EXISTS " + TvProvider.WATCHED_PROGRAMS_TABLE);
214            db.execSQL("DROP TABLE IF EXISTS " + TvProvider.PROGRAMS_TABLE);
215            db.execSQL("DROP TABLE IF EXISTS " + TvProvider.CHANNELS_TABLE);
216            onCreate(db);
217        }
218    }
219}
220