1 /* 2 * Copyright (C) 2011 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.cellbroadcastreceiver; 18 19 import android.app.IntentService; 20 import android.content.ContentValues; 21 import android.content.Intent; 22 import android.database.sqlite.SQLiteDatabase; 23 import android.util.Log; 24 25 /** 26 * Service to update the SQLite database to add a new broadcast message, 27 * or to delete one or all previously received broadcasts. 28 */ 29 public class CellBroadcastDatabaseService extends IntentService { 30 private static final String TAG = "CellBroadcastDatabaseService"; 31 32 /** Action to insert a new message (passed as CellBroadcastMessage extra). */ 33 static final String ACTION_INSERT_NEW_BROADCAST = "ACTION_INSERT_NEW_BROADCAST"; 34 35 /** Action to delete a single broadcast (row ID passed as extra). */ 36 static final String ACTION_DELETE_BROADCAST = "ACTION_DELETE_BROADCAST"; 37 38 /** Action to mark a broadcast as read by the user (by row ID or delivery time extra). */ 39 static final String ACTION_MARK_BROADCAST_READ = "ACTION_MARK_BROADCAST_READ"; 40 41 /** Action to delete all broadcasts from database (no extras). */ 42 static final String ACTION_DELETE_ALL_BROADCASTS = "ACTION_DELETE_ALL_BROADCASTS"; 43 44 /** Identifier for getExtra() for row ID to delete or mark read. */ 45 public static final String DATABASE_ROW_ID_EXTRA = 46 "com.android.cellbroadcastreceiver.DATABASE_ROW_ID"; 47 48 /** Identifier for getExtra() for delivery time of broadcast to mark read. */ 49 public static final String DATABASE_DELIVERY_TIME_EXTRA = 50 "com.android.cellbroadcastreceiver.DATABASE_DELIVERY_TIME"; 51 52 private SQLiteDatabase mBroadcastDb; 53 54 /** Callback for the active list activity when the contents change. */ 55 private static CellBroadcastListActivity sActiveListActivity; 56 57 public CellBroadcastDatabaseService() { 58 super(TAG); // use class name for worker thread name 59 } 60 61 @Override 62 public void onCreate() { 63 super.onCreate(); 64 65 if (mBroadcastDb == null) { 66 CellBroadcastDatabase.DatabaseHelper helper = 67 new CellBroadcastDatabase.DatabaseHelper(this); 68 mBroadcastDb = helper.getWritableDatabase(); 69 } 70 } 71 72 @Override 73 public void onDestroy() { 74 super.onDestroy(); 75 76 if (mBroadcastDb != null) { 77 mBroadcastDb.close(); 78 mBroadcastDb = null; 79 } 80 } 81 82 static void setActiveListActivity(CellBroadcastListActivity activity) { 83 sActiveListActivity = activity; 84 } 85 86 @Override 87 public void onHandleIntent(Intent intent) { 88 // TODO: security check to detect malicious broadcast injections 89 String action = intent.getAction(); 90 boolean notifyActiveListActivity = false; 91 if (ACTION_INSERT_NEW_BROADCAST.equals(action)) { 92 CellBroadcastMessage cbm = intent.getParcelableExtra( 93 CellBroadcastMessage.SMS_CB_MESSAGE_EXTRA); 94 if (cbm == null) { 95 Log.e(TAG, "ACTION_INSERT_NEW_BROADCAST with no CB message extra"); 96 return; 97 } 98 99 ContentValues cv = cbm.getContentValues(); 100 long rowId = mBroadcastDb.insert(CellBroadcastDatabase.TABLE_NAME, null, cv); 101 if (rowId == -1) { 102 Log.e(TAG, "failed to insert new broadcast into database!"); 103 } else { 104 notifyActiveListActivity = true; 105 } 106 } else if (ACTION_DELETE_BROADCAST.equals(action)) { 107 long rowId = intent.getLongExtra(DATABASE_ROW_ID_EXTRA, -1); 108 if (rowId == -1) { 109 Log.e(TAG, "ACTION_DELETE_BROADCAST missing row ID to delete"); 110 return; 111 } 112 113 int rowCount = mBroadcastDb.delete(CellBroadcastDatabase.TABLE_NAME, 114 CellBroadcastDatabase.Columns._ID + "=?", 115 new String[]{Long.toString(rowId)}); 116 if (rowCount != 0) { 117 notifyActiveListActivity = true; 118 } 119 } else if (ACTION_DELETE_ALL_BROADCASTS.equals(action)) { 120 mBroadcastDb.delete(CellBroadcastDatabase.TABLE_NAME, null, null); 121 notifyActiveListActivity = true; 122 } else if (ACTION_MARK_BROADCAST_READ.equals(action)) { 123 long rowId = intent.getLongExtra(DATABASE_ROW_ID_EXTRA, -1); 124 long deliveryTime = intent.getLongExtra(DATABASE_DELIVERY_TIME_EXTRA, -1); 125 if (rowId == -1 && deliveryTime == -1) { 126 Log.e(TAG, "ACTION_MARK_BROADCAST_READ missing row ID or delivery time"); 127 return; 128 } 129 ContentValues cv = new ContentValues(1); 130 cv.put(CellBroadcastDatabase.Columns.MESSAGE_READ, 1); 131 int rowCount; 132 if (rowId != -1) { 133 rowCount = mBroadcastDb.update(CellBroadcastDatabase.TABLE_NAME, cv, 134 CellBroadcastDatabase.Columns._ID + "=?", 135 new String[]{Long.toString(rowId)}); 136 } else { 137 rowCount = mBroadcastDb.update(CellBroadcastDatabase.TABLE_NAME, cv, 138 CellBroadcastDatabase.Columns.DELIVERY_TIME + "=?", 139 new String[]{Long.toString(deliveryTime)}); 140 } 141 if (rowCount != 0) { 142 notifyActiveListActivity = true; 143 } 144 } else { 145 Log.e(TAG, "ignoring unexpected Intent with action " + action); 146 } 147 if (notifyActiveListActivity && sActiveListActivity != null) { 148 sActiveListActivity.databaseContentChanged(); 149 } 150 } 151 } 152