1 package com.android.nfc.beam; 2 3 import android.app.Service; 4 import android.bluetooth.BluetoothAdapter; 5 import android.content.Context; 6 import android.content.Intent; 7 import android.content.IntentFilter; 8 import android.os.Handler; 9 import android.os.IBinder; 10 import android.os.Message; 11 import android.os.Messenger; 12 import android.os.RemoteException; 13 import android.util.Log; 14 15 16 /** 17 * @hide 18 */ 19 public class BeamReceiveService extends Service implements BeamTransferManager.Callback { 20 private static String TAG = "BeamReceiveService"; 21 private static boolean DBG = true; 22 23 public static final String EXTRA_BEAM_TRANSFER_RECORD 24 = "com.android.nfc.beam.EXTRA_BEAM_TRANSFER_RECORD"; 25 public static final String EXTRA_BEAM_COMPLETE_CALLBACK 26 = "com.android.nfc.beam.TRANSFER_COMPLETE_CALLBACK"; 27 28 private BeamStatusReceiver mBeamStatusReceiver; 29 private boolean mBluetoothEnabledByNfc; 30 private int mStartId; 31 private BeamTransferManager mTransferManager; 32 private Messenger mCompleteCallback; 33 34 private final BluetoothAdapter mBluetoothAdapter; 35 BeamReceiveService()36 public BeamReceiveService() { 37 mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); 38 } 39 40 @Override onStartCommand(Intent intent, int flags, int startId)41 public int onStartCommand(Intent intent, int flags, int startId) { 42 mStartId = startId; 43 44 BeamTransferRecord transferRecord; 45 if (intent == null || 46 (transferRecord = intent.getParcelableExtra(EXTRA_BEAM_TRANSFER_RECORD)) == null) { 47 if (DBG) Log.e(TAG, "No transfer record provided. Stopping."); 48 stopSelf(startId); 49 return START_NOT_STICKY; 50 } 51 52 mCompleteCallback = intent.getParcelableExtra(EXTRA_BEAM_COMPLETE_CALLBACK); 53 54 if (prepareToReceive(transferRecord)) { 55 if (DBG) Log.i(TAG, "Ready for incoming Beam transfer"); 56 return START_STICKY; 57 } else { 58 invokeCompleteCallback(false); 59 stopSelf(startId); 60 return START_NOT_STICKY; 61 } 62 } 63 64 @Override onDestroy()65 public void onDestroy() { 66 super.onDestroy(); 67 if (mBeamStatusReceiver != null) { 68 unregisterReceiver(mBeamStatusReceiver); 69 } 70 } 71 prepareToReceive(BeamTransferRecord transferRecord)72 boolean prepareToReceive(BeamTransferRecord transferRecord) { 73 if (mTransferManager != null) { 74 return false; 75 } 76 77 if (transferRecord.dataLinkType != BeamTransferRecord.DATA_LINK_TYPE_BLUETOOTH) { 78 // only support BT 79 return false; 80 } 81 82 if (!mBluetoothAdapter.isEnabled()) { 83 if (!mBluetoothAdapter.enableNoAutoConnect()) { 84 Log.e(TAG, "Error enabling Bluetooth."); 85 return false; 86 } 87 mBluetoothEnabledByNfc = true; 88 if (DBG) Log.d(TAG, "Queueing out transfer " 89 + Integer.toString(transferRecord.id)); 90 } 91 92 mTransferManager = new BeamTransferManager(this, this, transferRecord, true); 93 94 // register Beam status receiver 95 mBeamStatusReceiver = new BeamStatusReceiver(this, mTransferManager); 96 registerReceiver(mBeamStatusReceiver, mBeamStatusReceiver.getIntentFilter(), 97 BeamStatusReceiver.BEAM_STATUS_PERMISSION, new Handler()); 98 99 mTransferManager.start(); 100 mTransferManager.updateNotification(); 101 return true; 102 } 103 invokeCompleteCallback(boolean success)104 private void invokeCompleteCallback(boolean success) { 105 if (mCompleteCallback != null) { 106 try { 107 Message msg = Message.obtain(null, BeamManager.MSG_BEAM_COMPLETE); 108 msg.arg1 = success ? 1 : 0; 109 mCompleteCallback.send(msg); 110 } catch (RemoteException e) { 111 Log.e(TAG, "failed to invoke Beam complete callback", e); 112 } 113 } 114 } 115 116 @Override onTransferComplete(BeamTransferManager transfer, boolean success)117 public void onTransferComplete(BeamTransferManager transfer, boolean success) { 118 // Play success sound 119 if (!success) { 120 if (DBG) Log.d(TAG, "Transfer failed, final state: " + 121 Integer.toString(transfer.mState)); 122 } 123 124 if (mBluetoothEnabledByNfc) { 125 mBluetoothEnabledByNfc = false; 126 mBluetoothAdapter.disable(); 127 } 128 129 invokeCompleteCallback(success); 130 stopSelf(mStartId); 131 } 132 133 @Override onBind(Intent intent)134 public IBinder onBind(Intent intent) { 135 return null; 136 } 137 } 138