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