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 com.android.bluetooth.R; 36 37 import android.app.NotificationManager; 38 import android.bluetooth.BluetoothAdapter; 39 import android.bluetooth.BluetoothDevice; 40 import android.bluetooth.BluetoothDevicePicker; 41 import android.content.BroadcastReceiver; 42 import android.content.ContentUris; 43 import android.content.ContentValues; 44 import android.content.Context; 45 import android.content.Intent; 46 import android.database.Cursor; 47 import android.net.Uri; 48 import android.util.Log; 49 import android.widget.Toast; 50 51 /** 52 * Receives and handles: system broadcasts; Intents from other applications; 53 * Intents from OppService; Intents from modules in Opp application layer. 54 */ 55 public class BluetoothOppReceiver extends BroadcastReceiver { 56 private static final String TAG = "BluetoothOppReceiver"; 57 private static final boolean D = Constants.DEBUG; 58 private static final boolean V = Constants.VERBOSE; 59 60 @Override onReceive(Context context, Intent intent)61 public void onReceive(Context context, Intent intent) { 62 String action = intent.getAction(); 63 64 if (action.equals(BluetoothDevicePicker.ACTION_DEVICE_SELECTED)) { 65 BluetoothOppManager mOppManager = BluetoothOppManager.getInstance(context); 66 67 BluetoothDevice remoteDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); 68 69 if (V) Log.v(TAG, "Received BT device selected intent, bt device: " + remoteDevice); 70 71 // Insert transfer session record to database 72 mOppManager.startTransfer(remoteDevice); 73 74 // Display toast message 75 String deviceName = mOppManager.getDeviceName(remoteDevice); 76 String toastMsg; 77 int batchSize = mOppManager.getBatchSize(); 78 if (mOppManager.mMultipleFlag) { 79 toastMsg = context.getString(R.string.bt_toast_5, Integer.toString(batchSize), 80 deviceName); 81 } else { 82 toastMsg = context.getString(R.string.bt_toast_4, deviceName); 83 } 84 Toast.makeText(context, toastMsg, Toast.LENGTH_SHORT).show(); 85 } else if (action.equals(Constants.ACTION_INCOMING_FILE_CONFIRM)) { 86 if (V) Log.v(TAG, "Receiver ACTION_INCOMING_FILE_CONFIRM"); 87 88 Uri uri = intent.getData(); 89 Intent in = new Intent(context, BluetoothOppIncomingFileConfirmActivity.class); 90 in.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 91 in.setDataAndNormalize(uri); 92 context.startActivity(in); 93 94 } else if (action.equals(Constants.ACTION_DECLINE)) { 95 if (V) Log.v(TAG, "Receiver ACTION_DECLINE"); 96 97 Uri uri = intent.getData(); 98 ContentValues values = new ContentValues(); 99 values.put(BluetoothShare.USER_CONFIRMATION, BluetoothShare.USER_CONFIRMATION_DENIED); 100 context.getContentResolver().update(uri, values, null, null); 101 cancelNotification(context, BluetoothOppNotification.NOTIFICATION_ID_PROGRESS); 102 103 } else if (action.equals(Constants.ACTION_ACCEPT)) { 104 if (V) Log.v(TAG, "Receiver ACTION_ACCEPT"); 105 106 Uri uri = intent.getData(); 107 ContentValues values = new ContentValues(); 108 values.put(BluetoothShare.USER_CONFIRMATION, BluetoothShare.USER_CONFIRMATION_CONFIRMED); 109 context.getContentResolver().update(uri, values, null, null); 110 } else if (action.equals(Constants.ACTION_OPEN) || action.equals(Constants.ACTION_LIST)) { 111 if (V) { 112 if (action.equals(Constants.ACTION_OPEN)) { 113 Log.v(TAG, "Receiver open for " + intent.getData()); 114 } else { 115 Log.v(TAG, "Receiver list for " + intent.getData()); 116 } 117 } 118 119 BluetoothOppTransferInfo transInfo = new BluetoothOppTransferInfo(); 120 Uri uri = intent.getData(); 121 transInfo = BluetoothOppUtility.queryRecord(context, uri); 122 if (transInfo == null) { 123 Log.e(TAG, "Error: Can not get data from db"); 124 return; 125 } 126 127 if (transInfo.mDirection == BluetoothShare.DIRECTION_INBOUND 128 && BluetoothShare.isStatusSuccess(transInfo.mStatus)) { 129 // if received file successfully, open this file 130 BluetoothOppUtility.openReceivedFile(context, transInfo.mFileName, 131 transInfo.mFileType, transInfo.mTimeStamp, uri); 132 BluetoothOppUtility.updateVisibilityToHidden(context, uri); 133 } else { 134 Intent in = new Intent(context, BluetoothOppTransferActivity.class); 135 in.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 136 in.setDataAndNormalize(uri); 137 context.startActivity(in); 138 } 139 140 } else if (action.equals(Constants.ACTION_OPEN_OUTBOUND_TRANSFER)) { 141 if (V) Log.v(TAG, "Received ACTION_OPEN_OUTBOUND_TRANSFER."); 142 143 Intent in = new Intent(context, BluetoothOppTransferHistory.class); 144 in.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); 145 in.putExtra("direction", BluetoothShare.DIRECTION_OUTBOUND); 146 context.startActivity(in); 147 } else if (action.equals(Constants.ACTION_OPEN_INBOUND_TRANSFER)) { 148 if (V) Log.v(TAG, "Received ACTION_OPEN_INBOUND_TRANSFER."); 149 150 Intent in = new Intent(context, BluetoothOppTransferHistory.class); 151 in.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); 152 in.putExtra("direction", BluetoothShare.DIRECTION_INBOUND); 153 context.startActivity(in); 154 } else if (action.equals(Constants.ACTION_OPEN_RECEIVED_FILES)) { 155 if (V) Log.v(TAG, "Received ACTION_OPEN_RECEIVED_FILES."); 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_INBOUND); 160 in.putExtra(Constants.EXTRA_SHOW_ALL_FILES, true); 161 context.startActivity(in); 162 } else if (action.equals(Constants.ACTION_HIDE)) { 163 if (V) Log.v(TAG, "Receiver hide for " + intent.getData()); 164 Cursor cursor = context.getContentResolver().query(intent.getData(), null, null, null, 165 null); 166 if (cursor != null) { 167 if (cursor.moveToFirst()) { 168 int visibilityColumn = cursor.getColumnIndexOrThrow(BluetoothShare.VISIBILITY); 169 int visibility = cursor.getInt(visibilityColumn); 170 int userConfirmationColumn = cursor 171 .getColumnIndexOrThrow(BluetoothShare.USER_CONFIRMATION); 172 int userConfirmation = cursor.getInt(userConfirmationColumn); 173 if (((userConfirmation == BluetoothShare.USER_CONFIRMATION_PENDING)) 174 && visibility == BluetoothShare.VISIBILITY_VISIBLE) { 175 ContentValues values = new ContentValues(); 176 values.put(BluetoothShare.VISIBILITY, BluetoothShare.VISIBILITY_HIDDEN); 177 context.getContentResolver().update(intent.getData(), values, null, null); 178 if (V) Log.v(TAG, "Action_hide received and db updated"); 179 } 180 } 181 cursor.close(); 182 } 183 } else if (action.equals(Constants.ACTION_COMPLETE_HIDE)) { 184 if (V) Log.v(TAG, "Receiver ACTION_COMPLETE_HIDE"); 185 ContentValues updateValues = new ContentValues(); 186 updateValues.put(BluetoothShare.VISIBILITY, BluetoothShare.VISIBILITY_HIDDEN); 187 context.getContentResolver().update(BluetoothShare.CONTENT_URI, updateValues, 188 BluetoothOppNotification.WHERE_COMPLETED, null); 189 } else if (action.equals(BluetoothShare.TRANSFER_COMPLETED_ACTION)) { 190 if (V) Log.v(TAG, "Receiver Transfer Complete Intent for " + intent.getData()); 191 192 String toastMsg = null; 193 BluetoothOppTransferInfo transInfo = new BluetoothOppTransferInfo(); 194 transInfo = BluetoothOppUtility.queryRecord(context, intent.getData()); 195 if (transInfo == null) { 196 Log.e(TAG, "Error: Can not get data from db"); 197 return; 198 } 199 200 if (transInfo.mHandoverInitiated) { 201 // Deal with handover-initiated transfers separately 202 Intent handoverIntent = new Intent(Constants.ACTION_BT_OPP_TRANSFER_DONE); 203 if (transInfo.mDirection == BluetoothShare.DIRECTION_INBOUND) { 204 handoverIntent.putExtra(Constants.EXTRA_BT_OPP_TRANSFER_DIRECTION, 205 Constants.DIRECTION_BLUETOOTH_INCOMING); 206 } else { 207 handoverIntent.putExtra(Constants.EXTRA_BT_OPP_TRANSFER_DIRECTION, 208 Constants.DIRECTION_BLUETOOTH_OUTGOING); 209 } 210 handoverIntent.putExtra(Constants.EXTRA_BT_OPP_TRANSFER_ID, transInfo.mID); 211 handoverIntent.putExtra(Constants.EXTRA_BT_OPP_ADDRESS, transInfo.mDestAddr); 212 213 if (BluetoothShare.isStatusSuccess(transInfo.mStatus)) { 214 handoverIntent.putExtra(Constants.EXTRA_BT_OPP_TRANSFER_STATUS, 215 Constants.HANDOVER_TRANSFER_STATUS_SUCCESS); 216 handoverIntent.putExtra(Constants.EXTRA_BT_OPP_TRANSFER_URI, 217 transInfo.mFileName); 218 handoverIntent.putExtra(Constants.EXTRA_BT_OPP_TRANSFER_MIMETYPE, 219 transInfo.mFileType); 220 } else { 221 handoverIntent.putExtra(Constants.EXTRA_BT_OPP_TRANSFER_STATUS, 222 Constants.HANDOVER_TRANSFER_STATUS_FAILURE); 223 } 224 context.sendBroadcast(handoverIntent, Constants.HANDOVER_STATUS_PERMISSION); 225 return; 226 } 227 228 if (BluetoothShare.isStatusSuccess(transInfo.mStatus)) { 229 if (transInfo.mDirection == BluetoothShare.DIRECTION_OUTBOUND) { 230 toastMsg = context.getString(R.string.notification_sent, transInfo.mFileName); 231 } else if (transInfo.mDirection == BluetoothShare.DIRECTION_INBOUND) { 232 toastMsg = context.getString(R.string.notification_received, 233 transInfo.mFileName); 234 } 235 236 } else if (BluetoothShare.isStatusError(transInfo.mStatus)) { 237 if (transInfo.mDirection == BluetoothShare.DIRECTION_OUTBOUND) { 238 toastMsg = context.getString(R.string.notification_sent_fail, 239 transInfo.mFileName); 240 } else if (transInfo.mDirection == BluetoothShare.DIRECTION_INBOUND) { 241 toastMsg = context.getString(R.string.download_fail_line1); 242 } 243 } 244 if (V) Log.v(TAG, "Toast msg == " + toastMsg); 245 if (toastMsg != null) { 246 Toast.makeText(context, toastMsg, Toast.LENGTH_SHORT).show(); 247 } 248 } 249 } 250 cancelNotification(Context context, int id)251 private void cancelNotification(Context context, int id) { 252 NotificationManager notMgr = (NotificationManager)context 253 .getSystemService(Context.NOTIFICATION_SERVICE); 254 if (notMgr == null) return; 255 notMgr.cancel(id); 256 if (V) Log.v(TAG, "notMgr.cancel called"); 257 } 258 } 259