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