summaryrefslogtreecommitdiff
path: root/src/com/android/nfc/beam/BeamReceiveService.java
blob: 9327e7359560a9ca42f6ff3b913e7534b16074e3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package com.android.nfc.beam;

import android.app.Service;
import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;

/**
 * @hide
 */
public class BeamReceiveService extends Service implements BeamTransferManager.Callback {
    private static String TAG = "BeamReceiveService";
    private static boolean DBG = true;

    public static final String EXTRA_BEAM_TRANSFER_RECORD
            = "com.android.nfc.beam.EXTRA_BEAM_TRANSFER_RECORD";
    public static final String EXTRA_BEAM_COMPLETE_CALLBACK
            = "com.android.nfc.beam.TRANSFER_COMPLETE_CALLBACK";

    private BeamStatusReceiver mBeamStatusReceiver;
    private boolean mBluetoothEnabledByNfc;
    private int mStartId;
    private BeamTransferManager mTransferManager;
    private Messenger mCompleteCallback;

    private final BluetoothAdapter mBluetoothAdapter;

    public BeamReceiveService() {
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        mStartId = startId;

        BeamTransferRecord transferRecord;
        if (intent == null ||
                (transferRecord = intent.getParcelableExtra(EXTRA_BEAM_TRANSFER_RECORD)) == null) {
            if (DBG) Log.e(TAG, "No transfer record provided. Stopping.");
            stopSelf(startId);
            return START_NOT_STICKY;
        }

        mCompleteCallback = intent.getParcelableExtra(EXTRA_BEAM_COMPLETE_CALLBACK);

        if (prepareToReceive(transferRecord)) {
            if (DBG) Log.i(TAG, "Ready for incoming Beam transfer");
            return START_STICKY;
        } else {
            invokeCompleteCallback(false);
            stopSelf(startId);
            return START_NOT_STICKY;
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (mBeamStatusReceiver != null) {
            unregisterReceiver(mBeamStatusReceiver);
        }
    }

    boolean prepareToReceive(BeamTransferRecord transferRecord) {
        if (mTransferManager != null) {
            return false;
        }

        if (transferRecord.dataLinkType != BeamTransferRecord.DATA_LINK_TYPE_BLUETOOTH) {
            // only support BT
            return false;
        }

        if (!mBluetoothAdapter.isEnabled()) {
            if (!mBluetoothAdapter.enableNoAutoConnect()) {
                Log.e(TAG, "Error enabling Bluetooth.");
                return false;
            }
            mBluetoothEnabledByNfc = true;
            if (DBG) Log.d(TAG, "Queueing out transfer "
                    + Integer.toString(transferRecord.id));
        }

        mTransferManager = new BeamTransferManager(this, this, transferRecord, true);

        // register Beam status receiver
        mBeamStatusReceiver = new BeamStatusReceiver(this, mTransferManager);
        registerReceiver(mBeamStatusReceiver, mBeamStatusReceiver.getIntentFilter(),
                BeamStatusReceiver.BEAM_STATUS_PERMISSION, new Handler());

        mTransferManager.start();
        mTransferManager.updateNotification();
        return true;
    }

    private void invokeCompleteCallback(boolean success) {
        if (mCompleteCallback != null) {
            try {
                Message msg = Message.obtain(null, BeamManager.MSG_BEAM_COMPLETE);
                msg.arg1 = success ? 1 : 0;
                mCompleteCallback.send(msg);
            } catch (RemoteException e) {
                Log.e(TAG, "failed to invoke Beam complete callback", e);
            }
        }
    }

    @Override
    public void onTransferComplete(BeamTransferManager transfer, boolean success) {
        // Play success sound
        if (!success) {
            if (DBG) Log.d(TAG, "Transfer failed, final state: " +
                    Integer.toString(transfer.mState));
        }

        if (mBluetoothEnabledByNfc) {
            mBluetoothEnabledByNfc = false;
            mBluetoothAdapter.disable();
        }

        invokeCompleteCallback(success);
        stopSelf(mStartId);
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}