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