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