blob: 597b17aaeac70276d1b44465a3afd3641e2ee337 [file] [log] [blame]
/*
* Copyright (C) 2017 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.googlecode.android_scripting.facade.bluetooth;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import com.googlecode.android_scripting.Log;
import com.googlecode.android_scripting.event.Event;
import com.googlecode.android_scripting.facade.EventFacade;
public class BluetoothPairingHelper extends BroadcastReceiver {
private final EventFacade mEventFacade;
private static final int DEFAULT_TIMEOUT_MS = 5000;
private boolean mAutoConfirm = true;
public BluetoothPairingHelper(EventFacade eventFacade) {
super();
mEventFacade = eventFacade;
Log.d("Pairing helper created.");
}
/**
* Confirms bluetooth connection/bonding requests.
*/
@Override
public void onReceive(Context c, Intent intent) {
String action = intent.getAction();
Bundle result = new Bundle();
Log.d("Bluetooth pairing intent received: " + action);
BluetoothDevice mDevice = intent.getParcelableExtra(
BluetoothDevice.EXTRA_DEVICE);
if (action.equals(BluetoothDevice.ACTION_PAIRING_REQUEST)) {
mDevice.setMessageAccessPermission(BluetoothDevice.ACCESS_ALLOWED);
mDevice.setPhonebookAccessPermission(
BluetoothDevice.ACCESS_ALLOWED);
int type = intent.getIntExtra(
BluetoothDevice.EXTRA_PAIRING_VARIANT,
BluetoothDevice.ERROR);
Log.d("Processing Action Paring Request with type " + type);
int pin = intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_KEY, 0);
String deviceAddress = mDevice.getAddress();
result.putInt("Pin", pin);
result.putInt("PairingVariant", type);
result.putString("DeviceAddress", deviceAddress);
mEventFacade.postEvent("BluetoothActionPairingRequest",
result.clone());
result.clear();
if (type == BluetoothDevice.PAIRING_VARIANT_CONSENT) {
mDevice.setPairingConfirmation(true);
Log.d("Connection auto-confirmed by consent");
// Abort the broadcast so Settings app doesn't get it.
abortBroadcast();
} else if (type
== BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION) {
if (mAutoConfirm) {
mDevice.setPairingConfirmation(true);
Log.d("Connection auto-confirmed");
} else {
// Wait for confirmation
Event userConfirmEvent = null;
try {
userConfirmEvent = mEventFacade.eventWaitFor(
"BluetoothActionPairingRequestUserConfirm",
true, DEFAULT_TIMEOUT_MS);
} catch (InterruptedException e) {
Log.d("Connection interrupted");
userConfirmEvent = null;
}
if (userConfirmEvent == null) {
Log.d("Null response received from test server or timeout");
mDevice.setPairingConfirmation(false);
} else {
String userConfirmEventData =
(String) userConfirmEvent.getData();
if (userConfirmEventData.equalsIgnoreCase("True")) {
mDevice.setPairingConfirmation(true);
Log.d("Connection confirmed");
} else {
mDevice.setPairingConfirmation(false);
Log.d("Connection rejected");
}
}
}
// Abort the broadcast so Settings app doesn't get it.
abortBroadcast();
}
} else if (action.equals(
BluetoothDevice.ACTION_CONNECTION_ACCESS_REQUEST)) {
int type = intent.getIntExtra(
BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE,
BluetoothDevice.ERROR);
Log.d("Processing Action Connection Access Request type " + type);
if (type == BluetoothDevice.REQUEST_TYPE_MESSAGE_ACCESS
|| type == BluetoothDevice.REQUEST_TYPE_PHONEBOOK_ACCESS
|| type
== BluetoothDevice.REQUEST_TYPE_PROFILE_CONNECTION) {
Intent newIntent =
new Intent(
BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY);
String mReturnPackage =
intent.getStringExtra(
BluetoothDevice.EXTRA_PACKAGE_NAME);
String mReturnClass =
intent.getStringExtra(BluetoothDevice.EXTRA_CLASS_NAME);
int mRequestType =
intent.getIntExtra(
BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE,
BluetoothDevice.REQUEST_TYPE_MESSAGE_ACCESS);
if (mReturnPackage != null && mReturnClass != null) {
newIntent.setClassName(mReturnPackage, mReturnClass);
}
newIntent.putExtra(BluetoothDevice.EXTRA_CONNECTION_ACCESS_RESULT,
BluetoothDevice.CONNECTION_ACCESS_YES);
newIntent.putExtra(BluetoothDevice.EXTRA_ALWAYS_ALLOWED, true);
newIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, mDevice);
newIntent.putExtra(BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE,
mRequestType);
Log.d("Sending connection access acceptance intent.");
abortBroadcast();
c.sendBroadcast(newIntent,
android.Manifest.permission.BLUETOOTH_ADMIN);
}
}
}
/**
* Set autoConfirm flag to Value.
*/
public synchronized void setAutoConfirm(boolean value) {
mAutoConfirm = value;
}
}