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