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 18d822fd4358912161f637968610588e71493bbcd2Atsushi Sugaimport com.android.nfc.NfcService; 19073f0981e3920c085a57ff46f7f41bf329071c89Akinobu Nakashimaimport com.android.nfc.R; 20b82d80d891077ccd74729e4143925a66eb89eef2Andres Moralesimport com.android.nfc.handover.HandoverDataParser; 21b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales 22b82d80d891077ccd74729e4143925a66eb89eef2Andres Moralesimport android.bluetooth.BluetoothDevice; 23b82d80d891077ccd74729e4143925a66eb89eef2Andres Moralesimport android.content.Context; 24b82d80d891077ccd74729e4143925a66eb89eef2Andres Moralesimport android.content.Intent; 25b82d80d891077ccd74729e4143925a66eb89eef2Andres Moralesimport android.net.Uri; 26b82d80d891077ccd74729e4143925a66eb89eef2Andres Moralesimport android.os.Handler; 27b82d80d891077ccd74729e4143925a66eb89eef2Andres Moralesimport android.os.Looper; 28b82d80d891077ccd74729e4143925a66eb89eef2Andres Moralesimport android.os.Message; 29b82d80d891077ccd74729e4143925a66eb89eef2Andres Moralesimport android.os.Messenger; 30b82d80d891077ccd74729e4143925a66eb89eef2Andres Moralesimport android.os.UserHandle; 31b82d80d891077ccd74729e4143925a66eb89eef2Andres Moralesimport android.util.Log; 32b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales 33b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales/** 34b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales * Manager for starting and stopping Beam transfers. Prevents more than one transfer from 35b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales * happening at a time. 36b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales */ 37b82d80d891077ccd74729e4143925a66eb89eef2Andres Moralespublic class BeamManager implements Handler.Callback { 38b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales private static final String TAG = "BeamManager"; 39b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales private static final boolean DBG = false; 40b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales 41b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales private static final String ACTION_WHITELIST_DEVICE = 42b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales "android.btopp.intent.action.WHITELIST_DEVICE"; 43b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales public static final int MSG_BEAM_COMPLETE = 0; 44b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales 45b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales private final Object mLock; 46b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales 47b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales private boolean mBeamInProgress; 48b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales private final Handler mCallback; 49b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales 50d822fd4358912161f637968610588e71493bbcd2Atsushi Suga private NfcService mNfcService; 51d822fd4358912161f637968610588e71493bbcd2Atsushi Suga 52b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales private static final class Singleton { 53b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales public static final BeamManager INSTANCE = new BeamManager(); 54b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales } 55b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales 56b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales private BeamManager() { 57b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales mLock = new Object(); 58b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales mBeamInProgress = false; 59b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales mCallback = new Handler(Looper.getMainLooper(), this); 60d822fd4358912161f637968610588e71493bbcd2Atsushi Suga mNfcService = NfcService.getInstance(); 61b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales } 62b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales 63b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales public static BeamManager getInstance() { 64b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales return Singleton.INSTANCE; 65b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales } 66b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales 67b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales public boolean isBeamInProgress() { 68b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales synchronized (mLock) { 69b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales return mBeamInProgress; 70b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales } 71b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales } 72b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales 73b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales public boolean startBeamReceive(Context context, 74b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales HandoverDataParser.BluetoothHandoverData handoverData) { 75b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales synchronized (mLock) { 76b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales if (mBeamInProgress) { 77b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales return false; 78b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales } else { 79b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales mBeamInProgress = true; 80b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales } 81b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales } 82b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales 83b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales BeamTransferRecord transferRecord = 84b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales BeamTransferRecord.forBluetoothDevice( 85b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales handoverData.device, handoverData.carrierActivating, null); 86b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales 87b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales Intent receiveIntent = new Intent(context.getApplicationContext(), 88b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales BeamReceiveService.class); 89b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales receiveIntent.putExtra(BeamReceiveService.EXTRA_BEAM_TRANSFER_RECORD, transferRecord); 90b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales receiveIntent.putExtra(BeamReceiveService.EXTRA_BEAM_COMPLETE_CALLBACK, 91b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales new Messenger(mCallback)); 92b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales whitelistOppDevice(context, handoverData.device); 93b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales context.startServiceAsUser(receiveIntent, UserHandle.CURRENT); 94b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales return true; 95b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales } 96b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales 97b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales public boolean startBeamSend(Context context, 98b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales HandoverDataParser.BluetoothHandoverData outgoingHandoverData, 99b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales Uri[] uris, UserHandle userHandle) { 100b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales synchronized (mLock) { 101b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales if (mBeamInProgress) { 102b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales return false; 103b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales } else { 104b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales mBeamInProgress = true; 105b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales } 106b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales } 107b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales 108b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales BeamTransferRecord transferRecord = BeamTransferRecord.forBluetoothDevice( 109b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales outgoingHandoverData.device, outgoingHandoverData.carrierActivating, 110b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales uris); 111b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales Intent sendIntent = new Intent(context.getApplicationContext(), 112b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales BeamSendService.class); 113b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales sendIntent.putExtra(BeamSendService.EXTRA_BEAM_TRANSFER_RECORD, transferRecord); 114b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales sendIntent.putExtra(BeamSendService.EXTRA_BEAM_COMPLETE_CALLBACK, 115b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales new Messenger(mCallback)); 116b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales context.startServiceAsUser(sendIntent, userHandle); 117b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales return true; 118b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales } 119b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales 120b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales @Override 121b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales public boolean handleMessage(Message msg) { 122b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales if (msg.what == MSG_BEAM_COMPLETE) { 123b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales synchronized (mLock) { 124b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales mBeamInProgress = false; 125b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales } 126d822fd4358912161f637968610588e71493bbcd2Atsushi Suga 127d822fd4358912161f637968610588e71493bbcd2Atsushi Suga boolean success = msg.arg1 == 1; 128d822fd4358912161f637968610588e71493bbcd2Atsushi Suga if (success) { 129d822fd4358912161f637968610588e71493bbcd2Atsushi Suga mNfcService.playSound(NfcService.SOUND_END); 130d822fd4358912161f637968610588e71493bbcd2Atsushi Suga } 131b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales return true; 132b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales } 133b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales return false; 134b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales } 135b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales 136b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales void whitelistOppDevice(Context context, BluetoothDevice device) { 137b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales if (DBG) Log.d(TAG, "Whitelisting " + device + " for BT OPP"); 138b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales Intent intent = new Intent(ACTION_WHITELIST_DEVICE); 139073f0981e3920c085a57ff46f7f41bf329071c89Akinobu Nakashima intent.setPackage(context.getString(R.string.bluetooth_package)); 140b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); 141b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales context.sendBroadcastAsUser(intent, UserHandle.CURRENT); 142b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales } 143b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales 144b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales} 145