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