1 package com.android.nfc.beam;
2 
3 import com.android.nfc.R;
4 
5 import android.content.BroadcastReceiver;
6 import android.content.Context;
7 import android.content.Intent;
8 import android.content.IntentFilter;
9 import android.net.Uri;
10 import android.util.Log;
11 
12 import java.io.File;
13 
14 /**
15  * @hide
16  */
17 public class BeamStatusReceiver extends BroadcastReceiver {
18     private static final boolean DBG = true;
19     private static final String TAG = "BeamStatusReceiver";
20 
21     private static final String ACTION_HANDOVER_STARTED =
22             "android.nfc.handover.intent.action.HANDOVER_STARTED";
23 
24     private static final String ACTION_TRANSFER_PROGRESS =
25             "android.nfc.handover.intent.action.TRANSFER_PROGRESS";
26 
27     private static final String ACTION_TRANSFER_DONE =
28             "android.nfc.handover.intent.action.TRANSFER_DONE";
29 
30     private static final String EXTRA_HANDOVER_DATA_LINK_TYPE =
31             "android.nfc.handover.intent.extra.HANDOVER_DATA_LINK_TYPE";
32 
33 
34     private static final String EXTRA_TRANSFER_PROGRESS =
35             "android.nfc.handover.intent.extra.TRANSFER_PROGRESS";
36 
37     private static final String EXTRA_TRANSFER_URI =
38             "android.nfc.handover.intent.extra.TRANSFER_URI";
39 
40     private static final String EXTRA_OBJECT_COUNT =
41             "android.nfc.handover.intent.extra.OBJECT_COUNT";
42 
43     private static final String EXTRA_TRANSFER_STATUS =
44             "android.nfc.handover.intent.extra.TRANSFER_STATUS";
45 
46     private static final String EXTRA_TRANSFER_MIMETYPE =
47             "android.nfc.handover.intent.extra.TRANSFER_MIME_TYPE";
48 
49     private static final String ACTION_STOP_BLUETOOTH_TRANSFER =
50             "android.btopp.intent.action.STOP_HANDOVER_TRANSFER";
51 
52     // FIXME: Needs to stay in sync with com.android.bluetooth.opp.Constants
53     private static final int HANDOVER_TRANSFER_STATUS_SUCCESS = 0;
54     private static final int HANDOVER_TRANSFER_STATUS_FAILURE = 1;
55 
56     // permission needed to be able to receive handover status requests
57     public static final String BEAM_STATUS_PERMISSION =
58             "android.permission.NFC_HANDOVER_STATUS";
59 
60     // Needed to build cancel intent in Beam notification
61     public static final String EXTRA_INCOMING =
62             "com.android.nfc.handover.extra.INCOMING";
63 
64     public static final String EXTRA_TRANSFER_ID =
65             "android.nfc.handover.intent.extra.TRANSFER_ID";
66 
67     public static final String EXTRA_ADDRESS =
68             "android.nfc.handover.intent.extra.ADDRESS";
69 
70     public static final String ACTION_CANCEL_HANDOVER_TRANSFER =
71             "com.android.nfc.handover.action.CANCEL_HANDOVER_TRANSFER";
72 
73     public static final int DIRECTION_INCOMING = 0;
74     public static final int DIRECTION_OUTGOING = 1;
75 
76     private final Context mContext;
77     private final BeamTransferManager mTransferManager;
78 
BeamStatusReceiver(Context context, BeamTransferManager transferManager)79     BeamStatusReceiver(Context context, BeamTransferManager transferManager) {
80         mContext = context;
81         mTransferManager = transferManager;
82     }
83 
84     @Override
onReceive(Context context, Intent intent)85     public void onReceive(Context context, Intent intent) {
86         String action = intent.getAction();
87         int dataLinkType = intent.getIntExtra(EXTRA_HANDOVER_DATA_LINK_TYPE,
88                 BeamTransferManager.DATA_LINK_TYPE_BLUETOOTH);
89 
90         if (ACTION_CANCEL_HANDOVER_TRANSFER.equals(action)) {
91             if (mTransferManager != null) {
92                 mTransferManager.cancel();
93             }
94         } else if (ACTION_TRANSFER_PROGRESS.equals(action) ||
95                 ACTION_TRANSFER_DONE.equals(action) ||
96                 ACTION_HANDOVER_STARTED.equals(action)) {
97             handleTransferEvent(intent, dataLinkType);
98         }
99     }
100 
getIntentFilter()101     public IntentFilter getIntentFilter() {
102         IntentFilter filter = new IntentFilter(ACTION_TRANSFER_DONE);
103         filter.addAction(ACTION_TRANSFER_PROGRESS);
104         filter.addAction(ACTION_CANCEL_HANDOVER_TRANSFER);
105         filter.addAction(ACTION_HANDOVER_STARTED);
106         return filter;
107     }
108 
handleTransferEvent(Intent intent, int deviceType)109     private void handleTransferEvent(Intent intent, int deviceType) {
110         String action = intent.getAction();
111         int id = intent.getIntExtra(EXTRA_TRANSFER_ID, -1);
112 
113         String sourceAddress = intent.getStringExtra(EXTRA_ADDRESS);
114 
115         if (sourceAddress == null) return;
116 
117         if (mTransferManager == null) {
118             // There is no transfer running for this source address; most likely
119             // the transfer was cancelled. We need to tell BT OPP to stop transferring.
120             if (id != -1) {
121                 if (deviceType == BeamTransferManager.DATA_LINK_TYPE_BLUETOOTH) {
122                     if (DBG) Log.d(TAG, "Didn't find transfer, stopping");
123                     Intent cancelIntent = new Intent(ACTION_STOP_BLUETOOTH_TRANSFER);
124                     cancelIntent.putExtra(EXTRA_TRANSFER_ID, id);
125                     cancelIntent.setPackage(mContext.getString(R.string.bluetooth_package));
126                     mContext.sendBroadcast(cancelIntent);
127                 }
128             }
129             return;
130         }
131 
132         mTransferManager.setBluetoothTransferId(id);
133 
134         if (action.equals(ACTION_TRANSFER_DONE)) {
135             int handoverStatus = intent.getIntExtra(EXTRA_TRANSFER_STATUS,
136                     HANDOVER_TRANSFER_STATUS_FAILURE);
137             if (handoverStatus == HANDOVER_TRANSFER_STATUS_SUCCESS) {
138                 String uriString = intent.getStringExtra(EXTRA_TRANSFER_URI);
139                 String mimeType = intent.getStringExtra(EXTRA_TRANSFER_MIMETYPE);
140                 Uri uri = Uri.parse(uriString);
141                 if (uri != null && uri.getScheme() == null) {
142                     uri = Uri.fromFile(new File(uri.getPath()));
143                 }
144                 mTransferManager.finishTransfer(true, uri, mimeType);
145             } else {
146                 mTransferManager.finishTransfer(false, null, null);
147             }
148         } else if (action.equals(ACTION_TRANSFER_PROGRESS)) {
149             float progress = intent.getFloatExtra(EXTRA_TRANSFER_PROGRESS, 0.0f);
150             mTransferManager.updateFileProgress(progress);
151         } else if (action.equals(ACTION_HANDOVER_STARTED)) {
152             int count = intent.getIntExtra(EXTRA_OBJECT_COUNT, 0);
153             if (count > 0) {
154                 mTransferManager.setObjectCount(count);
155             }
156         }
157     }
158 }
159