1 /*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package com.android.nfc.beam;
17 
18 import com.android.nfc.handover.HandoverDataParser;
19 
20 import android.bluetooth.BluetoothDevice;
21 import android.content.Context;
22 import android.content.Intent;
23 import android.net.Uri;
24 import android.os.Handler;
25 import android.os.Looper;
26 import android.os.Message;
27 import android.os.Messenger;
28 import android.os.UserHandle;
29 import android.util.Log;
30 
31 /**
32  * Manager for starting and stopping Beam transfers. Prevents more than one transfer from
33  * happening at a time.
34  */
35 public class BeamManager implements Handler.Callback {
36     private static final String TAG = "BeamManager";
37     private static final boolean DBG = false;
38 
39     private static final String ACTION_WHITELIST_DEVICE =
40             "android.btopp.intent.action.WHITELIST_DEVICE";
41     public static final int MSG_BEAM_COMPLETE = 0;
42 
43     private final Object mLock;
44 
45     private boolean mBeamInProgress;
46     private final Handler mCallback;
47 
48     private static final class Singleton {
49         public static final BeamManager INSTANCE = new BeamManager();
50     }
51 
BeamManager()52     private BeamManager() {
53         mLock = new Object();
54         mBeamInProgress = false;
55         mCallback = new Handler(Looper.getMainLooper(), this);
56     }
57 
getInstance()58     public static BeamManager getInstance() {
59         return Singleton.INSTANCE;
60     }
61 
isBeamInProgress()62     public boolean isBeamInProgress() {
63         synchronized (mLock) {
64             return mBeamInProgress;
65         }
66     }
67 
startBeamReceive(Context context, HandoverDataParser.BluetoothHandoverData handoverData)68     public boolean startBeamReceive(Context context,
69                                  HandoverDataParser.BluetoothHandoverData handoverData) {
70         synchronized (mLock) {
71             if (mBeamInProgress) {
72                 return false;
73             } else {
74                 mBeamInProgress = true;
75             }
76         }
77 
78         BeamTransferRecord transferRecord =
79                 BeamTransferRecord.forBluetoothDevice(
80                         handoverData.device, handoverData.carrierActivating, null);
81 
82         Intent receiveIntent = new Intent(context.getApplicationContext(),
83                 BeamReceiveService.class);
84         receiveIntent.putExtra(BeamReceiveService.EXTRA_BEAM_TRANSFER_RECORD, transferRecord);
85         receiveIntent.putExtra(BeamReceiveService.EXTRA_BEAM_COMPLETE_CALLBACK,
86                 new Messenger(mCallback));
87         whitelistOppDevice(context, handoverData.device);
88         context.startServiceAsUser(receiveIntent, UserHandle.CURRENT);
89         return true;
90     }
91 
startBeamSend(Context context, HandoverDataParser.BluetoothHandoverData outgoingHandoverData, Uri[] uris, UserHandle userHandle)92     public boolean startBeamSend(Context context,
93                                HandoverDataParser.BluetoothHandoverData outgoingHandoverData,
94                                Uri[] uris, UserHandle userHandle) {
95         synchronized (mLock) {
96             if (mBeamInProgress) {
97                 return false;
98             } else {
99                 mBeamInProgress = true;
100             }
101         }
102 
103         BeamTransferRecord transferRecord = BeamTransferRecord.forBluetoothDevice(
104                 outgoingHandoverData.device, outgoingHandoverData.carrierActivating,
105                 uris);
106         Intent sendIntent = new Intent(context.getApplicationContext(),
107                 BeamSendService.class);
108         sendIntent.putExtra(BeamSendService.EXTRA_BEAM_TRANSFER_RECORD, transferRecord);
109         sendIntent.putExtra(BeamSendService.EXTRA_BEAM_COMPLETE_CALLBACK,
110                 new Messenger(mCallback));
111         context.startServiceAsUser(sendIntent, userHandle);
112         return true;
113     }
114 
115     @Override
handleMessage(Message msg)116     public boolean handleMessage(Message msg) {
117         if (msg.what == MSG_BEAM_COMPLETE) {
118             synchronized (mLock) {
119                 mBeamInProgress = false;
120             }
121             return true;
122         }
123         return false;
124     }
125 
whitelistOppDevice(Context context, BluetoothDevice device)126     void whitelistOppDevice(Context context, BluetoothDevice device) {
127         if (DBG) Log.d(TAG, "Whitelisting " + device + " for BT OPP");
128         Intent intent = new Intent(ACTION_WHITELIST_DEVICE);
129         intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
130         context.sendBroadcastAsUser(intent, UserHandle.CURRENT);
131     }
132 
133 }
134