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