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