BluetoothOppReceiver.java revision c4fbd756e2645147470c486ae96f2253f5e13a52
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
33package com.android.bluetooth.opp;
34
35import android.app.NotificationManager;
36import android.bluetooth.BluetoothDevice;
37import android.bluetooth.BluetoothDevicePicker;
38import android.content.BroadcastReceiver;
39import android.content.ContentValues;
40import android.content.Context;
41import android.content.Intent;
42import android.database.Cursor;
43import android.net.Uri;
44import android.util.Log;
45import android.widget.Toast;
46
47import 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 */
53public 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);
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