am 8c411fb1
: Merge change I79420b02 into eclair
Merge commit '8c411fb13923d1fa28fcd98452bf3d17b8b1a338' into eclair-mr2 * commit '8c411fb13923d1fa28fcd98452bf3d17b8b1a338': Add support for Car Dock.
This commit is contained in:
@ -624,6 +624,14 @@ public final class BluetoothDevice implements Parcelable {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @hide */
|
||||||
|
public boolean isBluetoothDock() {
|
||||||
|
try {
|
||||||
|
return sService.isBluetoothDock(mAddress);
|
||||||
|
} catch (RemoteException e) {Log.e(TAG, "", e);}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an RFCOMM {@link BluetoothSocket} ready to start a secure
|
* Create an RFCOMM {@link BluetoothSocket} ready to start a secure
|
||||||
* outgoing connection to this remote device on given channel.
|
* outgoing connection to this remote device on given channel.
|
||||||
|
@ -64,6 +64,7 @@ interface IBluetooth
|
|||||||
|
|
||||||
boolean setTrust(in String address, in boolean value);
|
boolean setTrust(in String address, in boolean value);
|
||||||
boolean getTrustState(in String address);
|
boolean getTrustState(in String address);
|
||||||
|
boolean isBluetoothDock(in String address);
|
||||||
|
|
||||||
int addRfcommServiceRecord(in String serviceName, in ParcelUuid uuid, int channel, IBinder b);
|
int addRfcommServiceRecord(in String serviceName, in ParcelUuid uuid, int channel, IBinder b);
|
||||||
void removeServiceRecord(int handle);
|
void removeServiceRecord(int handle);
|
||||||
|
@ -492,6 +492,14 @@ class BluetoothEventLoop {
|
|||||||
mBluetoothService.getBondState().getPendingOutgoingBonding();
|
mBluetoothService.getBondState().getPendingOutgoingBonding();
|
||||||
if (address.equals(pendingOutgoingAddress)) {
|
if (address.equals(pendingOutgoingAddress)) {
|
||||||
// we initiated the bonding
|
// we initiated the bonding
|
||||||
|
|
||||||
|
// Check if its a dock
|
||||||
|
if (mBluetoothService.isBluetoothDock(address)) {
|
||||||
|
String pin = mBluetoothService.getDockPin();
|
||||||
|
mBluetoothService.setPin(address, BluetoothDevice.convertPinToBytes(pin));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
BluetoothClass btClass = new BluetoothClass(mBluetoothService.getRemoteClass(address));
|
BluetoothClass btClass = new BluetoothClass(mBluetoothService.getRemoteClass(address));
|
||||||
|
|
||||||
// try 0000 once if the device looks dumb
|
// try 0000 once if the device looks dumb
|
||||||
|
@ -32,16 +32,16 @@ import android.bluetooth.BluetoothSocket;
|
|||||||
import android.bluetooth.BluetoothUuid;
|
import android.bluetooth.BluetoothUuid;
|
||||||
import android.bluetooth.IBluetooth;
|
import android.bluetooth.IBluetooth;
|
||||||
import android.bluetooth.IBluetoothCallback;
|
import android.bluetooth.IBluetoothCallback;
|
||||||
import android.os.ParcelUuid;
|
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.IBinder;
|
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
|
import android.os.IBinder;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
|
import android.os.ParcelUuid;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.ServiceManager;
|
import android.os.ServiceManager;
|
||||||
import android.os.SystemService;
|
import android.os.SystemService;
|
||||||
@ -50,7 +50,13 @@ import android.util.Log;
|
|||||||
|
|
||||||
import com.android.internal.app.IBatteryStats;
|
import com.android.internal.app.IBatteryStats;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.BufferedWriter;
|
||||||
import java.io.FileDescriptor;
|
import java.io.FileDescriptor;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -58,6 +64,7 @@ import java.util.Arrays;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
public class BluetoothService extends IBluetooth.Stub {
|
public class BluetoothService extends IBluetooth.Stub {
|
||||||
private static final String TAG = "BluetoothService";
|
private static final String TAG = "BluetoothService";
|
||||||
@ -79,6 +86,9 @@ public class BluetoothService extends IBluetooth.Stub {
|
|||||||
private static final String BLUETOOTH_ADMIN_PERM = android.Manifest.permission.BLUETOOTH_ADMIN;
|
private static final String BLUETOOTH_ADMIN_PERM = android.Manifest.permission.BLUETOOTH_ADMIN;
|
||||||
private static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH;
|
private static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH;
|
||||||
|
|
||||||
|
private static final String DOCK_ADDRESS_PATH = "/sys/class/switch/dock/bt_addr";
|
||||||
|
private static final String DOCK_PIN_PATH = "/sys/class/switch/dock/bt_pin";
|
||||||
|
|
||||||
private static final int MESSAGE_REGISTER_SDP_RECORDS = 1;
|
private static final int MESSAGE_REGISTER_SDP_RECORDS = 1;
|
||||||
private static final int MESSAGE_FINISH_DISABLE = 2;
|
private static final int MESSAGE_FINISH_DISABLE = 2;
|
||||||
private static final int MESSAGE_UUID_INTENT = 3;
|
private static final int MESSAGE_UUID_INTENT = 3;
|
||||||
@ -104,6 +114,9 @@ public class BluetoothService extends IBluetooth.Stub {
|
|||||||
|
|
||||||
private final HashMap<Integer, Integer> mServiceRecordToPid;
|
private final HashMap<Integer, Integer> mServiceRecordToPid;
|
||||||
|
|
||||||
|
private static String mDockAddress;
|
||||||
|
private String mDockPin;
|
||||||
|
|
||||||
private static class RemoteService {
|
private static class RemoteService {
|
||||||
public String address;
|
public String address;
|
||||||
public ParcelUuid uuid;
|
public ParcelUuid uuid;
|
||||||
@ -151,6 +164,96 @@ public class BluetoothService extends IBluetooth.Stub {
|
|||||||
mUuidCallbackTracker = new HashMap<RemoteService, IBluetoothCallback>();
|
mUuidCallbackTracker = new HashMap<RemoteService, IBluetoothCallback>();
|
||||||
mServiceRecordToPid = new HashMap<Integer, Integer>();
|
mServiceRecordToPid = new HashMap<Integer, Integer>();
|
||||||
registerForAirplaneMode();
|
registerForAirplaneMode();
|
||||||
|
|
||||||
|
IntentFilter filter = new IntentFilter();
|
||||||
|
filter.addAction(Intent.ACTION_DOCK_EVENT);
|
||||||
|
mContext.registerReceiver(mBroadcastReceiver, filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
if (intent != null) {
|
||||||
|
String action = intent.getAction();
|
||||||
|
|
||||||
|
if (Intent.ACTION_DOCK_EVENT.equals(action)) {
|
||||||
|
int state = intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
|
||||||
|
Intent.EXTRA_DOCK_STATE_UNDOCKED);
|
||||||
|
if (DBG) Log.v(TAG, "Received ACTION_DOCK_EVENT with State:" + state);
|
||||||
|
if (state == Intent.EXTRA_DOCK_STATE_UNDOCKED) {
|
||||||
|
mDockAddress = null;
|
||||||
|
mDockPin = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public static synchronized String readDockBluetoothAddress() {
|
||||||
|
if (mDockAddress != null) return mDockAddress;
|
||||||
|
|
||||||
|
BufferedInputStream file = null;
|
||||||
|
String dockAddress;
|
||||||
|
try {
|
||||||
|
file = new BufferedInputStream(new FileInputStream(DOCK_ADDRESS_PATH));
|
||||||
|
byte[] address = new byte[17];
|
||||||
|
file.read(address);
|
||||||
|
dockAddress = new String(address);
|
||||||
|
dockAddress = dockAddress.toUpperCase();
|
||||||
|
if (BluetoothAdapter.checkBluetoothAddress(dockAddress)) {
|
||||||
|
mDockAddress = dockAddress;
|
||||||
|
return mDockAddress;
|
||||||
|
} else {
|
||||||
|
log("CheckBluetoothAddress failed for car dock address:" + dockAddress);
|
||||||
|
}
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
log("FileNotFoundException while trying to read dock address");
|
||||||
|
} catch (IOException e) {
|
||||||
|
log("IOException while trying to read dock address");
|
||||||
|
} finally {
|
||||||
|
if (file != null) {
|
||||||
|
try {
|
||||||
|
file.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mDockAddress = null;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized boolean writeDockPin() {
|
||||||
|
BufferedWriter out = null;
|
||||||
|
try {
|
||||||
|
out = new BufferedWriter(new FileWriter(DOCK_PIN_PATH));
|
||||||
|
|
||||||
|
// Generate a random 4 digit pin between 0000 and 9999
|
||||||
|
// This is not truly random but good enough for our purposes.
|
||||||
|
int pin = (int) Math.floor(Math.random() * 10000);
|
||||||
|
|
||||||
|
mDockPin = String.format("%04d", pin);
|
||||||
|
out.write(mDockPin);
|
||||||
|
return true;
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
log("FileNotFoundException while trying to write dock pairing pin");
|
||||||
|
} catch (IOException e) {
|
||||||
|
log("IOException while while trying to write dock pairing pin");
|
||||||
|
} finally {
|
||||||
|
if (out != null) {
|
||||||
|
try {
|
||||||
|
out.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mDockPin = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*package*/ synchronized String getDockPin() {
|
||||||
|
return mDockPin;
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void initAfterRegistration() {
|
public synchronized void initAfterRegistration() {
|
||||||
@ -922,6 +1025,13 @@ public class BluetoothService extends IBluetooth.Stub {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (address.equals(mDockAddress)) {
|
||||||
|
if (!writeDockPin()) {
|
||||||
|
log("Error while writing Pin for the dock");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!createPairedDeviceNative(address, 60000 /* 1 minute */)) {
|
if (!createPairedDeviceNative(address, 60000 /* 1 minute */)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -975,6 +1085,11 @@ public class BluetoothService extends IBluetooth.Stub {
|
|||||||
return mBondState.getBondState(address.toUpperCase());
|
return mBondState.getBondState(address.toUpperCase());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public synchronized boolean isBluetoothDock(String address) {
|
||||||
|
if (address.equals(mDockAddress)) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/*package*/ boolean isRemoteDeviceInCache(String address) {
|
/*package*/ boolean isRemoteDeviceInCache(String address) {
|
||||||
return (mDeviceProperties.get(address) != null);
|
return (mDeviceProperties.get(address) != null);
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,8 @@ package com.android.server;
|
|||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.KeyguardManager;
|
import android.app.KeyguardManager;
|
||||||
|
import android.bluetooth.BluetoothAdapter;
|
||||||
|
import android.bluetooth.BluetoothDevice;
|
||||||
import android.content.ActivityNotFoundException;
|
import android.content.ActivityNotFoundException;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@ -27,12 +29,13 @@ import android.os.Message;
|
|||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.os.UEventObserver;
|
import android.os.UEventObserver;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
|
import android.server.BluetoothService;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.android.internal.widget.LockPatternUtils;
|
import com.android.internal.widget.LockPatternUtils;
|
||||||
|
|
||||||
import java.io.FileReader;
|
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileReader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>DockObserver monitors for a docking station.
|
* <p>DockObserver monitors for a docking station.
|
||||||
@ -178,6 +181,12 @@ class DockObserver extends UEventObserver {
|
|||||||
Intent intent = new Intent(Intent.ACTION_DOCK_EVENT);
|
Intent intent = new Intent(Intent.ACTION_DOCK_EVENT);
|
||||||
intent.putExtra(Intent.EXTRA_DOCK_STATE, mDockState);
|
intent.putExtra(Intent.EXTRA_DOCK_STATE, mDockState);
|
||||||
|
|
||||||
|
// Check if this is Bluetooth Dock
|
||||||
|
String address = BluetoothService.readDockBluetoothAddress();
|
||||||
|
if (address != null)
|
||||||
|
intent.putExtra(BluetoothDevice.EXTRA_DEVICE,
|
||||||
|
BluetoothAdapter.getDefaultAdapter().getRemoteDevice(address));
|
||||||
|
|
||||||
// Send the ordered broadcast; the result receiver will receive after all
|
// Send the ordered broadcast; the result receiver will receive after all
|
||||||
// broadcasts have been sent. If any broadcast receiver changes the result
|
// broadcasts have been sent. If any broadcast receiver changes the result
|
||||||
// code from the initial value of RESULT_OK, then the result receiver will
|
// code from the initial value of RESULT_OK, then the result receiver will
|
||||||
|
Reference in New Issue
Block a user