/* * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.nfc.beam; import com.android.nfc.NfcService; import com.android.nfc.R; import com.android.nfc.handover.HandoverDataParser; import android.bluetooth.BluetoothDevice; import android.content.Context; import android.content.Intent; import android.net.Uri; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.Messenger; import android.os.UserHandle; import android.util.Log; /** * Manager for starting and stopping Beam transfers. Prevents more than one transfer from * happening at a time. */ public class BeamManager implements Handler.Callback { private static final String TAG = "BeamManager"; private static final boolean DBG = false; private static final String ACTION_ALLOWLIST_DEVICE = "android.btopp.intent.action.WHITELIST_DEVICE"; public static final int MSG_BEAM_COMPLETE = 0; private final Object mLock; private boolean mBeamInProgress; private final Handler mCallback; private NfcService mNfcService; private static final class Singleton { public static final BeamManager INSTANCE = new BeamManager(); } private BeamManager() { mLock = new Object(); mBeamInProgress = false; mCallback = new Handler(Looper.getMainLooper(), this); mNfcService = NfcService.getInstance(); } public static BeamManager getInstance() { return Singleton.INSTANCE; } public boolean isBeamInProgress() { synchronized (mLock) { return mBeamInProgress; } } public boolean startBeamReceive(Context context, HandoverDataParser.BluetoothHandoverData handoverData) { synchronized (mLock) { if (mBeamInProgress) { return false; } else { mBeamInProgress = true; } } BeamTransferRecord transferRecord = BeamTransferRecord.forBluetoothDevice( handoverData.device, handoverData.carrierActivating, null); Intent receiveIntent = new Intent(context.getApplicationContext(), BeamReceiveService.class); receiveIntent.putExtra(BeamReceiveService.EXTRA_BEAM_TRANSFER_RECORD, transferRecord); receiveIntent.putExtra(BeamReceiveService.EXTRA_BEAM_COMPLETE_CALLBACK, new Messenger(mCallback)); allowlistOppDevice(context, handoverData.device); context.startServiceAsUser(receiveIntent, UserHandle.CURRENT); return true; } public boolean startBeamSend(Context context, HandoverDataParser.BluetoothHandoverData outgoingHandoverData, Uri[] uris, UserHandle userHandle) { synchronized (mLock) { if (mBeamInProgress) { return false; } else { mBeamInProgress = true; } } BeamTransferRecord transferRecord = BeamTransferRecord.forBluetoothDevice( outgoingHandoverData.device, outgoingHandoverData.carrierActivating, uris); Intent sendIntent = new Intent(context.getApplicationContext(), BeamSendService.class); sendIntent.putExtra(BeamSendService.EXTRA_BEAM_TRANSFER_RECORD, transferRecord); sendIntent.putExtra(BeamSendService.EXTRA_BEAM_COMPLETE_CALLBACK, new Messenger(mCallback)); context.startServiceAsUser(sendIntent, userHandle); return true; } @Override public boolean handleMessage(Message msg) { if (msg.what == MSG_BEAM_COMPLETE) { synchronized (mLock) { mBeamInProgress = false; } boolean success = msg.arg1 == 1; if (success) { mNfcService.playSound(NfcService.SOUND_END); } return true; } return false; } void allowlistOppDevice(Context context, BluetoothDevice device) { if (DBG) Log.d(TAG, "Allowlist " + device + " for BT OPP"); Intent intent = new Intent(ACTION_ALLOWLIST_DEVICE); intent.setPackage(context.getString(R.string.bluetooth_package)); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); context.sendBroadcastAsUser(intent, UserHandle.CURRENT); } }