1 /* 2 * Copyright (c) 2008-2009, Motorola, Inc. 3 * 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * - Redistributions of source code must retain the above copyright notice, 10 * this list of conditions and the following disclaimer. 11 * 12 * - Redistributions in binary form must reproduce the above copyright notice, 13 * this list of conditions and the following disclaimer in the documentation 14 * and/or other materials provided with the distribution. 15 * 16 * - Neither the name of the Motorola, Inc. nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 24 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 package com.android.bluetooth.opp; 34 35 import android.app.NotificationManager; 36 import android.bluetooth.BluetoothDevice; 37 import android.bluetooth.BluetoothDevicePicker; 38 import android.content.BroadcastReceiver; 39 import android.content.ContentValues; 40 import android.content.Context; 41 import android.content.Intent; 42 import android.database.Cursor; 43 import android.net.Uri; 44 import android.util.Log; 45 import android.widget.Toast; 46 47 import com.android.bluetooth.R; 48 49 /** 50 * Receives and handles: system broadcasts; Intents from other applications; 51 * Intents from OppService; Intents from modules in Opp application layer. 52 */ 53 public class BluetoothOppReceiver extends BroadcastReceiver { 54 private static final String TAG = "BluetoothOppReceiver"; 55 private static final boolean D = Constants.DEBUG; 56 private static final boolean V = Constants.VERBOSE; 57 58 @Override onReceive(Context context, Intent intent)59 public void onReceive(Context context, Intent intent) { 60 String action = intent.getAction(); 61 if (D) Log.d(TAG, " action :" + action); 62 if (action == null) return; 63 if (action.equals(BluetoothDevicePicker.ACTION_DEVICE_SELECTED)) { 64 BluetoothOppManager mOppManager = BluetoothOppManager.getInstance(context); 65 66 BluetoothDevice remoteDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); 67 68 if (D) { 69 Log.d(TAG, "Received BT device selected intent, bt device: " + remoteDevice); 70 } 71 72 if (remoteDevice == null) { 73 mOppManager.cleanUpSendingFileInfo(); 74 return; 75 } 76 // Insert transfer session record to database 77 mOppManager.startTransfer(remoteDevice); 78 79 // Display toast message 80 String deviceName = mOppManager.getDeviceName(remoteDevice); 81 String toastMsg; 82 int batchSize = mOppManager.getBatchSize(); 83 if (mOppManager.mMultipleFlag) { 84 toastMsg = context.getString(R.string.bt_toast_5, Integer.toString(batchSize), 85 deviceName); 86 } else { 87 toastMsg = context.getString(R.string.bt_toast_4, deviceName); 88 } 89 Toast.makeText(context, toastMsg, Toast.LENGTH_SHORT).show(); 90 } else if (action.equals(Constants.ACTION_INCOMING_FILE_CONFIRM)) { 91 if (V) { 92 Log.v(TAG, "Receiver ACTION_INCOMING_FILE_CONFIRM"); 93 } 94 95 Uri uri = intent.getData(); 96 Intent in = new Intent(context, BluetoothOppIncomingFileConfirmActivity.class); 97 in.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 98 in.setDataAndNormalize(uri); 99 context.startActivity(in); 100 101 } else if (action.equals(Constants.ACTION_DECLINE)) { 102 if (V) { 103 Log.v(TAG, "Receiver ACTION_DECLINE"); 104 } 105 106 Uri uri = intent.getData(); 107 ContentValues values = new ContentValues(); 108 values.put(BluetoothShare.USER_CONFIRMATION, BluetoothShare.USER_CONFIRMATION_DENIED); 109 context.getContentResolver().update(uri, values, null, null); 110 cancelNotification(context, BluetoothOppNotification.NOTIFICATION_ID_PROGRESS); 111 112 } else if (action.equals(Constants.ACTION_ACCEPT)) { 113 if (V) { 114 Log.v(TAG, "Receiver ACTION_ACCEPT"); 115 } 116 117 Uri uri = intent.getData(); 118 ContentValues values = new ContentValues(); 119 values.put(BluetoothShare.USER_CONFIRMATION, 120 BluetoothShare.USER_CONFIRMATION_CONFIRMED); 121 context.getContentResolver().update(uri, values, null, null); 122 } else if (action.equals(Constants.ACTION_OPEN) || action.equals(Constants.ACTION_LIST)) { 123 if (V) { 124 if (action.equals(Constants.ACTION_OPEN)) { 125 Log.v(TAG, "Receiver open for " + intent.getData()); 126 } else { 127 Log.v(TAG, "Receiver list for " + intent.getData()); 128 } 129 } 130 131 BluetoothOppTransferInfo transInfo = new BluetoothOppTransferInfo(); 132 Uri uri = intent.getData(); 133 transInfo = BluetoothOppUtility.queryRecord(context, uri); 134 if (transInfo == null) { 135 Log.e(TAG, "Error: Can not get data from db"); 136 return; 137 } 138 139 if (transInfo.mDirection == BluetoothShare.DIRECTION_INBOUND 140 && BluetoothShare.isStatusSuccess(transInfo.mStatus)) { 141 // if received file successfully, open this file 142 BluetoothOppUtility.openReceivedFile(context, transInfo.mFileName, 143 transInfo.mFileType, transInfo.mTimeStamp, uri); 144 BluetoothOppUtility.updateVisibilityToHidden(context, uri); 145 } else { 146 Intent in = new Intent(context, BluetoothOppTransferActivity.class); 147 in.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); 148 in.setDataAndNormalize(uri); 149 context.startActivity(in); 150 } 151 152 } else if (action.equals(Constants.ACTION_OPEN_OUTBOUND_TRANSFER)) { 153 if (V) { 154 Log.v(TAG, "Received ACTION_OPEN_OUTBOUND_TRANSFER."); 155 } 156 157 Intent in = new Intent(context, BluetoothOppTransferHistory.class); 158 in.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); 159 in.putExtra("direction", BluetoothShare.DIRECTION_OUTBOUND); 160 context.startActivity(in); 161 } else if (action.equals(Constants.ACTION_OPEN_INBOUND_TRANSFER)) { 162 if (V) { 163 Log.v(TAG, "Received ACTION_OPEN_INBOUND_TRANSFER."); 164 } 165 166 Intent in = new Intent(context, BluetoothOppTransferHistory.class); 167 in.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); 168 in.putExtra("direction", BluetoothShare.DIRECTION_INBOUND); 169 context.startActivity(in); 170 } else if (action.equals(Constants.ACTION_OPEN_RECEIVED_FILES)) { 171 if (V) { 172 Log.v(TAG, "Received ACTION_OPEN_RECEIVED_FILES."); 173 } 174 175 Intent in = new Intent(context, BluetoothOppTransferHistory.class); 176 in.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); 177 in.putExtra("direction", BluetoothShare.DIRECTION_INBOUND); 178 in.putExtra(Constants.EXTRA_SHOW_ALL_FILES, true); 179 context.startActivity(in); 180 } else if (action.equals(Constants.ACTION_HIDE)) { 181 if (V) { 182 Log.v(TAG, "Receiver hide for " + intent.getData()); 183 } 184 Cursor cursor = 185 context.getContentResolver().query(intent.getData(), null, null, null, null); 186 if (cursor != null) { 187 if (cursor.moveToFirst()) { 188 int visibilityColumn = cursor.getColumnIndexOrThrow(BluetoothShare.VISIBILITY); 189 int visibility = cursor.getInt(visibilityColumn); 190 int userConfirmationColumn = 191 cursor.getColumnIndexOrThrow(BluetoothShare.USER_CONFIRMATION); 192 int userConfirmation = cursor.getInt(userConfirmationColumn); 193 if (((userConfirmation == BluetoothShare.USER_CONFIRMATION_PENDING)) 194 && visibility == BluetoothShare.VISIBILITY_VISIBLE) { 195 ContentValues values = new ContentValues(); 196 values.put(BluetoothShare.VISIBILITY, BluetoothShare.VISIBILITY_HIDDEN); 197 context.getContentResolver().update(intent.getData(), values, null, null); 198 if (V) { 199 Log.v(TAG, "Action_hide received and db updated"); 200 } 201 } 202 } 203 cursor.close(); 204 } 205 } else if (action.equals(Constants.ACTION_COMPLETE_HIDE)) { 206 if (V) { 207 Log.v(TAG, "Receiver ACTION_COMPLETE_HIDE"); 208 } 209 ContentValues updateValues = new ContentValues(); 210 updateValues.put(BluetoothShare.VISIBILITY, BluetoothShare.VISIBILITY_HIDDEN); 211 context.getContentResolver() 212 .update(BluetoothShare.CONTENT_URI, updateValues, 213 BluetoothOppNotification.WHERE_COMPLETED, null); 214 } else if (action.equals(BluetoothShare.TRANSFER_COMPLETED_ACTION)) { 215 if (V) { 216 Log.v(TAG, "Receiver Transfer Complete Intent for " + intent.getData()); 217 } 218 219 String toastMsg = null; 220 BluetoothOppTransferInfo transInfo = new BluetoothOppTransferInfo(); 221 transInfo = BluetoothOppUtility.queryRecord(context, intent.getData()); 222 if (transInfo == null) { 223 Log.e(TAG, "Error: Can not get data from db"); 224 return; 225 } 226 227 if (transInfo.mHandoverInitiated) { 228 // Deal with handover-initiated transfers separately 229 Intent handoverIntent = new Intent(Constants.ACTION_BT_OPP_TRANSFER_DONE); 230 if (transInfo.mDirection == BluetoothShare.DIRECTION_INBOUND) { 231 handoverIntent.putExtra(Constants.EXTRA_BT_OPP_TRANSFER_DIRECTION, 232 Constants.DIRECTION_BLUETOOTH_INCOMING); 233 } else { 234 handoverIntent.putExtra(Constants.EXTRA_BT_OPP_TRANSFER_DIRECTION, 235 Constants.DIRECTION_BLUETOOTH_OUTGOING); 236 } 237 handoverIntent.putExtra(Constants.EXTRA_BT_OPP_TRANSFER_ID, transInfo.mID); 238 handoverIntent.putExtra(Constants.EXTRA_BT_OPP_ADDRESS, transInfo.mDestAddr); 239 240 if (BluetoothShare.isStatusSuccess(transInfo.mStatus)) { 241 handoverIntent.putExtra(Constants.EXTRA_BT_OPP_TRANSFER_STATUS, 242 Constants.HANDOVER_TRANSFER_STATUS_SUCCESS); 243 handoverIntent.putExtra(Constants.EXTRA_BT_OPP_TRANSFER_URI, 244 transInfo.mFileName); 245 handoverIntent.putExtra(Constants.EXTRA_BT_OPP_TRANSFER_MIMETYPE, 246 transInfo.mFileType); 247 } else { 248 handoverIntent.putExtra(Constants.EXTRA_BT_OPP_TRANSFER_STATUS, 249 Constants.HANDOVER_TRANSFER_STATUS_FAILURE); 250 } 251 context.sendBroadcast(handoverIntent, Constants.HANDOVER_STATUS_PERMISSION); 252 return; 253 } 254 255 if (BluetoothShare.isStatusSuccess(transInfo.mStatus)) { 256 if (transInfo.mDirection == BluetoothShare.DIRECTION_OUTBOUND) { 257 toastMsg = context.getString(R.string.notification_sent, transInfo.mFileName); 258 } else if (transInfo.mDirection == BluetoothShare.DIRECTION_INBOUND) { 259 toastMsg = 260 context.getString(R.string.notification_received, transInfo.mFileName); 261 } 262 263 } else if (BluetoothShare.isStatusError(transInfo.mStatus)) { 264 if (transInfo.mDirection == BluetoothShare.DIRECTION_OUTBOUND) { 265 toastMsg = 266 context.getString(R.string.notification_sent_fail, transInfo.mFileName); 267 } else if (transInfo.mDirection == BluetoothShare.DIRECTION_INBOUND) { 268 toastMsg = context.getString(R.string.download_fail_line1); 269 } 270 } 271 if (V) { 272 Log.v(TAG, "Toast msg == " + toastMsg); 273 } 274 if (toastMsg != null) { 275 Toast.makeText(context, toastMsg, Toast.LENGTH_SHORT).show(); 276 } 277 } 278 } 279 cancelNotification(Context context, int id)280 private void cancelNotification(Context context, int id) { 281 NotificationManager notMgr = 282 (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); 283 if (notMgr == null) { 284 return; 285 } 286 notMgr.cancel(id); 287 if (V) { 288 Log.v(TAG, "notMgr.cancel called"); 289 } 290 } 291 } 292