summaryrefslogtreecommitdiffstats
path: root/core/java/android/server/BluetoothService.java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android/server/BluetoothService.java')
-rwxr-xr-xcore/java/android/server/BluetoothService.java91
1 files changed, 82 insertions, 9 deletions
diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java
index 34f1971..9e66957 100755
--- a/core/java/android/server/BluetoothService.java
+++ b/core/java/android/server/BluetoothService.java
@@ -39,6 +39,7 @@ import android.bluetooth.BluetoothUuid;
import android.bluetooth.IBluetooth;
import android.bluetooth.IBluetoothCallback;
import android.bluetooth.IBluetoothHealthCallback;
+import android.bluetooth.IBluetoothStateChangeCallback;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
@@ -68,13 +69,15 @@ import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
-import java.io.InputStreamReader;
import java.io.IOException;
+import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.RandomAccessFile;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
@@ -101,6 +104,8 @@ public class BluetoothService extends IBluetooth.Stub {
private final BluetoothBondState mBondState; // local cache of bondings
private final IBatteryStats mBatteryStats;
private final Context mContext;
+ private Map<Integer, IBluetoothStateChangeCallback> mStateChangeTracker =
+ Collections.synchronizedMap(new HashMap<Integer, IBluetoothStateChangeCallback>());
private static final String BLUETOOTH_ADMIN_PERM = android.Manifest.permission.BLUETOOTH_ADMIN;
static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH;
@@ -114,6 +119,9 @@ public class BluetoothService extends IBluetooth.Stub {
private static final int MESSAGE_UUID_INTENT = 1;
private static final int MESSAGE_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY = 2;
+ private static final int RFCOMM_RECORD_REAPER = 10;
+ private static final int STATE_CHANGE_REAPER = 11;
+
// The time (in millisecs) to delay the pairing attempt after the first
// auto pairing attempt fails. We use an exponential delay with
// INIT_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY as the initial value and
@@ -1466,7 +1474,7 @@ public class BluetoothService extends IBluetooth.Stub {
int pid = Binder.getCallingPid();
mServiceRecordToPid.put(new Integer(handle), new Integer(pid));
try {
- b.linkToDeath(new Reaper(handle, pid), 0);
+ b.linkToDeath(new Reaper(handle, pid, RFCOMM_RECORD_REAPER), 0);
} catch (RemoteException e) {}
return handle;
}
@@ -1489,20 +1497,85 @@ public class BluetoothService extends IBluetooth.Stub {
}
private class Reaper implements IBinder.DeathRecipient {
- int pid;
- int handle;
- Reaper(int handle, int pid) {
- this.pid = pid;
- this.handle = handle;
+ int mPid;
+ int mHandle;
+ int mType;
+
+ Reaper(int handle, int pid, int type) {
+ mPid = pid;
+ mHandle = handle;
+ mType = type;
+ }
+
+ Reaper(int pid, int type) {
+ mPid = pid;
+ mType = type;
}
+
+ @Override
public void binderDied() {
synchronized (BluetoothService.this) {
- if (DBG) Log.d(TAG, "Tracked app " + pid + " died");
- checkAndRemoveRecord(handle, pid);
+ if (DBG) Log.d(TAG, "Tracked app " + mPid + " died" + "Type:" + mType);
+ if (mType == RFCOMM_RECORD_REAPER) {
+ checkAndRemoveRecord(mHandle, mPid);
+ } else if (mType == STATE_CHANGE_REAPER) {
+ mStateChangeTracker.remove(mPid);
+ }
}
}
}
+
+ @Override
+ public boolean changeApplicationBluetoothState(boolean on,
+ IBluetoothStateChangeCallback callback, IBinder binder) {
+ int pid = Binder.getCallingPid();
+ //mStateChangeTracker is a synchronized map
+ if (!mStateChangeTracker.containsKey(pid)) {
+ if (on) {
+ mStateChangeTracker.put(pid, callback);
+ } else {
+ return false;
+ }
+ } else if (!on) {
+ mStateChangeTracker.remove(pid);
+ }
+
+ if (binder != null) {
+ try {
+ binder.linkToDeath(new Reaper(pid, STATE_CHANGE_REAPER), 0);
+ } catch (RemoteException e) {
+ return false;
+ }
+ }
+
+ int type;
+ if (on) {
+ type = BluetoothAdapterStateMachine.PER_PROCESS_TURN_ON;
+ } else {
+ type = BluetoothAdapterStateMachine.PER_PROCESS_TURN_OFF;
+ }
+
+ mBluetoothState.sendMessage(type, callback);
+ return true;
+ }
+
+ boolean isApplicationStateChangeTrackerEmpty() {
+ return mStateChangeTracker.isEmpty();
+ }
+
+ void clearApplicationStateChangeTracker() {
+ mStateChangeTracker.clear();
+ }
+
+ Collection<IBluetoothStateChangeCallback> getApplicationStateChangeCallbacks() {
+ return mStateChangeTracker.values();
+ }
+
+ int getNumberOfApplicationStateChangeTrackers() {
+ return mStateChangeTracker.size();
+ }
+
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {