1 package com.android.cellbroadcastreceiver.tests; 2 3 import android.annotation.NonNull; 4 import android.content.ContentProvider; 5 import android.content.ContentValues; 6 import android.content.Context; 7 import android.content.UriMatcher; 8 import android.database.Cursor; 9 import android.database.sqlite.SQLiteDatabase; 10 import android.database.sqlite.SQLiteOpenHelper; 11 import android.database.sqlite.SQLiteQueryBuilder; 12 import android.net.Uri; 13 import android.os.Bundle; 14 import android.provider.Telephony; 15 import android.util.Log; 16 17 import java.util.Arrays; 18 19 /** 20 * This is a sample content provider for OEM data migration, including 21 * both sharedPreference and message history migration. 22 * authority: content://cellbroadcast-legacy 23 */ 24 public class DataMigrationContentProvider extends ContentProvider { 25 private static final String TAG = DataMigrationContentProvider.class.getSimpleName(); 26 /** URI matcher for ContentProvider queries. */ 27 private static final UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); 28 29 /** The database for this content provider. */ 30 private SQLiteOpenHelper mOpenHelper; 31 32 /** Authority string for content URIs. */ 33 static final String CB_AUTHORITY = "cellbroadcast-legacy"; 34 35 /** Content URI for notifying observers. */ 36 static final Uri CONTENT_URI = Uri.parse("content://cellbroadcast-legacy/"); 37 38 /** URI matcher type to get all cell broadcasts. */ 39 private static final int CB_ALL = 0; 40 41 static { sUriMatcher.addURI(CB_AUTHORITY, null, CB_ALL)42 sUriMatcher.addURI(CB_AUTHORITY, null, CB_ALL); 43 } 44 45 @Override onCreate()46 public boolean onCreate() { 47 Log.d(TAG, "onCreate"); 48 mOpenHelper = new CellBroadcastMigrationDatabaseHelper(getContext()); 49 return true; 50 } 51 52 @Override query(Uri uri, String[] projectionIn, String selection, String[] selectionArgs, String sortOrder)53 public Cursor query(Uri uri, String[] projectionIn, String selection, 54 String[] selectionArgs, String sortOrder) { 55 Log.d(TAG, "query:" 56 + " uri=" + uri 57 + " values=" + Arrays.toString(projectionIn) 58 + " selection=" + selection 59 + " selectionArgs=" + Arrays.toString(selectionArgs)); 60 61 final int match = sUriMatcher.match(uri); 62 if (match == CB_ALL) { 63 SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); 64 qb.setTables(CellBroadcastMigrationDatabaseHelper.TABLE_NAME); 65 66 SQLiteDatabase db = mOpenHelper.getReadableDatabase(); 67 Cursor c = qb.query(db, projectionIn, selection, selectionArgs, null, null, sortOrder); 68 Log.d(TAG, "query from legacy cellbroadcast, returned " + c.getCount() + " messges"); 69 return c; 70 } else { 71 Log.e(TAG, "unsupported URI: " + uri); 72 } 73 74 return null; 75 } 76 77 @Override call(String method, String name, Bundle args)78 public Bundle call(String method, String name, Bundle args) { 79 Log.d(TAG, "call:" 80 + " method=" + method 81 + " name=" + name 82 + " args=" + args); 83 84 if (Telephony.CellBroadcasts.CALL_METHOD_GET_PREFERENCE.equals(method)) { 85 switch (name) { 86 case Telephony.CellBroadcasts.Preference.ENABLE_AREA_UPDATE_INFO_PREF: 87 return packageValueForCallResult(Telephony.CellBroadcasts.Preference 88 .ENABLE_AREA_UPDATE_INFO_PREF, false); 89 case Telephony.CellBroadcasts.Preference.ENABLE_CMAS_AMBER_PREF: 90 return packageValueForCallResult(Telephony.CellBroadcasts.Preference 91 .ENABLE_CMAS_AMBER_PREF, false); 92 case Telephony.CellBroadcasts.Preference.ENABLE_TEST_ALERT_PREF: 93 return packageValueForCallResult(Telephony.CellBroadcasts.Preference 94 .ENABLE_TEST_ALERT_PREF, false); 95 case Telephony.CellBroadcasts.Preference.ENABLE_STATE_LOCAL_TEST_PREF: 96 return packageValueForCallResult(Telephony.CellBroadcasts.Preference 97 .ENABLE_STATE_LOCAL_TEST_PREF, false); 98 case Telephony.CellBroadcasts.Preference.ENABLE_PUBLIC_SAFETY_PREF: 99 return packageValueForCallResult(Telephony.CellBroadcasts.Preference 100 .ENABLE_PUBLIC_SAFETY_PREF, false); 101 case Telephony.CellBroadcasts.Preference.ENABLE_CMAS_EXTREME_THREAT_PREF: 102 return packageValueForCallResult(Telephony.CellBroadcasts.Preference 103 .ENABLE_CMAS_EXTREME_THREAT_PREF, false); 104 case Telephony.CellBroadcasts.Preference.ENABLE_CMAS_PRESIDENTIAL_PREF: 105 return packageValueForCallResult(Telephony.CellBroadcasts.Preference 106 .ENABLE_CMAS_PRESIDENTIAL_PREF, false); 107 case Telephony.CellBroadcasts.Preference.ENABLE_EMERGENCY_PERF: 108 return packageValueForCallResult(Telephony.CellBroadcasts.Preference 109 .ENABLE_EMERGENCY_PERF, false); 110 case Telephony.CellBroadcasts.Preference.ENABLE_CMAS_SEVERE_THREAT_PREF: 111 return packageValueForCallResult(Telephony.CellBroadcasts.Preference 112 .ENABLE_CMAS_SEVERE_THREAT_PREF, false); 113 case Telephony.CellBroadcasts.Preference.ENABLE_ALERT_VIBRATION_PREF: 114 return packageValueForCallResult(Telephony.CellBroadcasts.Preference 115 .ENABLE_ALERT_VIBRATION_PREF, false); 116 case Telephony.CellBroadcasts.Preference.ENABLE_CMAS_IN_SECOND_LANGUAGE_PREF: 117 return packageValueForCallResult(Telephony.CellBroadcasts.Preference 118 .ENABLE_CMAS_IN_SECOND_LANGUAGE_PREF, false); 119 default: 120 Log.e(TAG, "unsupported preference name" + name); 121 } 122 } 123 Log.e(TAG, "unsuppprted call method: " + method); 124 return null; 125 } 126 packageValueForCallResult(String pref, Boolean val)127 private static @NonNull Bundle packageValueForCallResult(String pref, Boolean val) { 128 Bundle result = new Bundle(); 129 result.putBoolean(pref, val); 130 return result; 131 } 132 133 134 @Override getType(Uri uri)135 public String getType(Uri uri) { 136 Log.d(TAG, "getType"); 137 return null; 138 } 139 140 @Override insert(Uri uri, ContentValues values)141 public Uri insert(Uri uri, ContentValues values) { 142 throw new UnsupportedOperationException("insert not supported"); 143 } 144 145 @Override delete(Uri uri, String selection, String[] selectionArgs)146 public int delete(Uri uri, String selection, String[] selectionArgs) { 147 throw new UnsupportedOperationException("delete not supported"); 148 } 149 150 @Override update(Uri uri, ContentValues values, String selection, String[] selectionArgs)151 public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { 152 throw new UnsupportedOperationException("update not supported"); 153 } 154 155 // create in-memory database 156 private static class CellBroadcastMigrationDatabaseHelper extends SQLiteOpenHelper { 157 158 private static final String TAG = 159 CellBroadcastMigrationDatabaseHelper.class.getSimpleName(); 160 private static final String TABLE_NAME = "broadcasts_legacy"; 161 CellBroadcastMigrationDatabaseHelper(Context context)162 CellBroadcastMigrationDatabaseHelper(Context context) { 163 super(null, // no context is needed for in-memory db 164 null, // db file name is null for in-memory db 165 null, // CursorFactory is null by default 166 1); // db version is no-op for tests 167 Log.d(TAG, "creating in-memory database"); 168 } 169 170 @Override onCreate(SQLiteDatabase db)171 public void onCreate(SQLiteDatabase db) { 172 Log.d(TAG, "onCreate creating the cellbroadcast legacy table"); 173 db.execSQL("CREATE TABLE " + TABLE_NAME + " (" 174 + Telephony.CellBroadcasts._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," 175 + Telephony.CellBroadcasts.SLOT_INDEX + " INTEGER DEFAULT 0," 176 + Telephony.CellBroadcasts.GEOGRAPHICAL_SCOPE + " INTEGER," 177 + Telephony.CellBroadcasts.PLMN + " TEXT," 178 + Telephony.CellBroadcasts.LAC + " INTEGER," 179 + Telephony.CellBroadcasts.CID + " INTEGER," 180 + Telephony.CellBroadcasts.SERIAL_NUMBER + " INTEGER," 181 + Telephony.CellBroadcasts.SERVICE_CATEGORY + " INTEGER," 182 + Telephony.CellBroadcasts.LANGUAGE_CODE + " TEXT," 183 + Telephony.CellBroadcasts.MESSAGE_BODY + " TEXT," 184 + Telephony.CellBroadcasts.DELIVERY_TIME + " INTEGER," 185 + Telephony.CellBroadcasts.MESSAGE_READ + " INTEGER," 186 + Telephony.CellBroadcasts.MESSAGE_FORMAT + " INTEGER," 187 + Telephony.CellBroadcasts.MESSAGE_PRIORITY + " INTEGER," 188 + Telephony.CellBroadcasts.ETWS_WARNING_TYPE + " INTEGER," 189 + Telephony.CellBroadcasts.CMAS_MESSAGE_CLASS + " INTEGER," 190 + Telephony.CellBroadcasts.CMAS_CATEGORY + " INTEGER," 191 + Telephony.CellBroadcasts.CMAS_RESPONSE_TYPE + " INTEGER," 192 + Telephony.CellBroadcasts.CMAS_SEVERITY + " INTEGER," 193 + Telephony.CellBroadcasts.CMAS_URGENCY + " INTEGER," 194 + Telephony.CellBroadcasts.CMAS_CERTAINTY + " INTEGER);"); 195 196 db.execSQL("CREATE INDEX IF NOT EXISTS deliveryTimeIndex ON " + TABLE_NAME 197 + " (" + Telephony.CellBroadcasts.DELIVERY_TIME + ");"); 198 // insert a fake message 199 ContentValues contentVal = new ContentValues(); 200 contentVal.put(Telephony.CellBroadcasts.SLOT_INDEX, 0); 201 contentVal.put(Telephony.CellBroadcasts.GEOGRAPHICAL_SCOPE, 1); 202 contentVal.put(Telephony.CellBroadcasts.PLMN, "311480"); 203 contentVal.put(Telephony.CellBroadcasts.SERIAL_NUMBER, 19724); 204 contentVal.put(Telephony.CellBroadcasts.SERVICE_CATEGORY, 4379); 205 contentVal.put(Telephony.CellBroadcasts.LANGUAGE_CODE, "en"); 206 contentVal.put(Telephony.CellBroadcasts.MESSAGE_BODY, "migration test"); 207 contentVal.put(Telephony.CellBroadcasts.MESSAGE_PRIORITY, 3); 208 contentVal.put(Telephony.CellBroadcasts.MESSAGE_FORMAT, 1); 209 if (db.insertWithOnConflict(TABLE_NAME, null, contentVal, 210 SQLiteDatabase.CONFLICT_IGNORE) > 0) { 211 Log.d(TAG, "insertion succeed"); 212 } 213 } 214 215 @Override onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)216 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 217 Log.d(TAG, "onUpgrade doing nothing"); 218 return; 219 } 220 } 221 } 222 223