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