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 17 package com.android.usbtuner; 18 19 import android.content.ContentProvider; 20 import android.content.ContentValues; 21 import android.content.Context; 22 import android.content.UriMatcher; 23 import android.database.Cursor; 24 import android.database.sqlite.SQLiteDatabase; 25 import android.database.sqlite.SQLiteException; 26 import android.database.sqlite.SQLiteOpenHelper; 27 import android.net.Uri; 28 29 /** 30 * A content provider for storing the preferences. It's used across TV app and USB tuner TV input. 31 */ 32 public class UsbTunerPreferenceProvider extends ContentProvider { 33 /** The authority of the provider */ 34 public static final String AUTHORITY = "com.android.usbtuner.preferences"; 35 36 private static final String PATH_PREFERENCES = "preferences"; 37 38 private static final int DATABASE_VERSION = 1; 39 private static final String DATABASE_NAME = "usbtuner_preferences.db"; 40 private static final String PREFERENCES_TABLE = "preferences"; 41 private static final String PREFERENCES_TABLE_ID_INDEX = "preferences_id_index"; 42 private static final String PREFERENCES_TABLE_KEY_INDEX = "preferences_key_index"; 43 44 private static final int MATCH_PREFERENCE = 1; 45 private static final int MATCH_PREFERENCE_KEY = 2; 46 47 private static UriMatcher sUriMatcher; 48 49 private DatabaseOpenHelper mDatabaseOpenHelper; 50 51 static { 52 sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); sUriMatcher.addURI(AUTHORITY, "preferences", MATCH_PREFERENCE)53 sUriMatcher.addURI(AUTHORITY, "preferences", MATCH_PREFERENCE); sUriMatcher.addURI(AUTHORITY, "preferences/*", MATCH_PREFERENCE_KEY)54 sUriMatcher.addURI(AUTHORITY, "preferences/*", MATCH_PREFERENCE_KEY); 55 } 56 57 /** 58 * Builds a Uri that points to a specific preference. 59 60 * @param key a key of the preference to point to 61 */ buildPreferenceUri(String key)62 public static Uri buildPreferenceUri(String key) { 63 return Preferences.CONTENT_URI.buildUpon().appendPath(key).build(); 64 } 65 66 /** 67 * Columns definitions for the preferences table. 68 */ 69 public interface Preferences { 70 71 /** 72 * The content:// style for the preferences table. 73 */ 74 Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" + PATH_PREFERENCES); 75 76 /** 77 * The MIME type of a directory of preferences. 78 */ 79 String CONTENT_TYPE = "vnd.android.cursor.dir/preferences"; 80 81 /** 82 * The MIME type of a single preference. 83 */ 84 String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/preferences"; 85 86 /** 87 * The ID of this preference. 88 * 89 * <p>This is auto-incremented. 90 * 91 * <p>Type: INTEGER 92 */ 93 String _ID = "_id"; 94 95 /** 96 * The key of this preference. 97 * 98 * <p>Should be unique. 99 * 100 * <p>Type: TEXT 101 */ 102 String COLUMN_KEY = "key"; 103 104 /** 105 * The value of this preference. 106 * 107 * <p>Type: TEXT 108 */ 109 String COLUMN_VALUE = "value"; 110 } 111 112 private static class DatabaseOpenHelper extends SQLiteOpenHelper { DatabaseOpenHelper(Context context)113 public DatabaseOpenHelper(Context context) { 114 super(context, DATABASE_NAME, null, DATABASE_VERSION); 115 } 116 117 @Override onCreate(SQLiteDatabase db)118 public void onCreate(SQLiteDatabase db) { 119 db.execSQL("CREATE TABLE " + PREFERENCES_TABLE + " (" 120 + Preferences._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," 121 + Preferences.COLUMN_KEY + " TEXT NOT NULL," 122 + Preferences.COLUMN_VALUE + " TEXT," 123 + "UNIQUE(" + Preferences._ID + "," + Preferences.COLUMN_KEY + ")" 124 + ");"); 125 db.execSQL("CREATE INDEX " + PREFERENCES_TABLE_ID_INDEX + " ON " + PREFERENCES_TABLE 126 + "(" + Preferences.COLUMN_KEY + ");"); 127 db.execSQL("CREATE INDEX " + PREFERENCES_TABLE_KEY_INDEX + " ON " + PREFERENCES_TABLE 128 + "(" + Preferences.COLUMN_KEY + ");"); 129 } 130 131 @Override onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)132 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 133 // No-op 134 } 135 } 136 137 @Override onCreate()138 public boolean onCreate() { 139 mDatabaseOpenHelper = new DatabaseOpenHelper(getContext()); 140 return true; 141 } 142 143 @Override query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)144 public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, 145 String sortOrder) { 146 if (sUriMatcher.match(uri) != MATCH_PREFERENCE_KEY) { 147 throw new UnsupportedOperationException(); 148 } 149 SQLiteDatabase db = mDatabaseOpenHelper.getReadableDatabase(); 150 Cursor cursor = db.query(PREFERENCES_TABLE, projection, selection, selectionArgs, 151 null, null, sortOrder); 152 cursor.setNotificationUri(getContext().getContentResolver(), uri); 153 return cursor; 154 } 155 156 @Override getType(Uri uri)157 public String getType(Uri uri) { 158 switch (sUriMatcher.match(uri)) { 159 case MATCH_PREFERENCE: 160 return Preferences.CONTENT_TYPE; 161 case MATCH_PREFERENCE_KEY: 162 return Preferences.CONTENT_ITEM_TYPE; 163 } 164 throw new IllegalArgumentException("Unknown URI " + uri); 165 } 166 167 /** 168 * Inserts a preference row into the preference table. 169 * 170 * If a key is already exists in the table, it removes the old row and inserts a new row. 171 * 172 * @param uri the URL of the table to insert into 173 * @param values the initial values for the newly inserted row 174 * @return the URL of the newly created row 175 */ 176 @Override insert(Uri uri, ContentValues values)177 public Uri insert(Uri uri, ContentValues values) { 178 if (sUriMatcher.match(uri) != MATCH_PREFERENCE) { 179 throw new UnsupportedOperationException(); 180 } 181 return insertRow(uri, values); 182 } 183 insertRow(Uri uri, ContentValues values)184 private Uri insertRow(Uri uri, ContentValues values) { 185 SQLiteDatabase db = mDatabaseOpenHelper.getWritableDatabase(); 186 187 // Remove the old row. 188 db.delete(PREFERENCES_TABLE, Preferences.COLUMN_KEY + " like ?", 189 new String[]{values.getAsString(Preferences.COLUMN_KEY)}); 190 191 long rowId = db.insert(PREFERENCES_TABLE, null, values); 192 if (rowId > 0) { 193 Uri rowUri = buildPreferenceUri(values.getAsString(Preferences.COLUMN_KEY)); 194 getContext().getContentResolver().notifyChange(rowUri, null); 195 return rowUri; 196 } 197 198 throw new SQLiteException("Failed to insert row into " + uri); 199 } 200 201 @Override delete(Uri uri, String selection, String[] selectionArgs)202 public int delete(Uri uri, String selection, String[] selectionArgs) { 203 throw new UnsupportedOperationException(); 204 } 205 206 @Override update(Uri uri, ContentValues values, String selection, String[] selectionArgs)207 public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { 208 throw new UnsupportedOperationException(); 209 } 210 } 211