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