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