Bluetooth: API change.
Split BluetoothDevice into BluetoothDevice and BluetoothAdapter.
BluetoothAdapter: Represents the local BT adapter. Operations on the local
adapter (start a scan, etc).
BluetoothDevice: Represents a remote BT device. Operations on remote devices
(pair, connect, etc).
IBluetoothDevice.aidl -> Bluetooth.aidl
BluetoothDeviceService.java -> BluetoothDeviceService.java
TODO:
Javadoc
This commit is contained in:
@@ -88,8 +88,8 @@ LOCAL_SRC_FILES += \
|
||||
core/java/android/backup/IBackupManager.aidl \
|
||||
core/java/android/backup/IRestoreObserver.aidl \
|
||||
core/java/android/backup/IRestoreSession.aidl \
|
||||
core/java/android/bluetooth/IBluetooth.aidl \
|
||||
core/java/android/bluetooth/IBluetoothA2dp.aidl \
|
||||
core/java/android/bluetooth/IBluetoothDevice.aidl \
|
||||
core/java/android/bluetooth/IBluetoothHeadset.aidl \
|
||||
core/java/android/bluetooth/IBluetoothPbap.aidl \
|
||||
core/java/android/content/IContentService.aidl \
|
||||
|
||||
@@ -22,8 +22,8 @@ import com.google.android.collect.Maps;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.IBluetoothDevice;
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.IBluetooth;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ComponentName;
|
||||
import android.content.ContentResolver;
|
||||
@@ -158,8 +158,6 @@ class ApplicationContext extends Context {
|
||||
private static ConnectivityManager sConnectivityManager;
|
||||
private static WifiManager sWifiManager;
|
||||
private static LocationManager sLocationManager;
|
||||
private static boolean sIsBluetoothDeviceCached = false;
|
||||
private static BluetoothDevice sBluetoothDevice;
|
||||
private static final HashMap<File, SharedPreferencesImpl> sSharedPrefs =
|
||||
new HashMap<File, SharedPreferencesImpl>();
|
||||
|
||||
@@ -184,6 +182,8 @@ class ApplicationContext extends Context {
|
||||
private StatusBarManager mStatusBarManager = null;
|
||||
private TelephonyManager mTelephonyManager = null;
|
||||
private ClipboardManager mClipboardManager = null;
|
||||
private boolean mIsBluetoothAdapterCached = false;
|
||||
private BluetoothAdapter mBluetoothAdapter;
|
||||
private boolean mRestricted;
|
||||
|
||||
private final Object mSync = new Object();
|
||||
@@ -830,7 +830,7 @@ class ApplicationContext extends Context {
|
||||
} else if (SENSOR_SERVICE.equals(name)) {
|
||||
return getSensorManager();
|
||||
} else if (BLUETOOTH_SERVICE.equals(name)) {
|
||||
return getBluetoothDevice();
|
||||
return getBluetoothAdapter();
|
||||
} else if (VIBRATOR_SERVICE.equals(name)) {
|
||||
return getVibrator();
|
||||
} else if (STATUS_BAR_SERVICE.equals(name)) {
|
||||
@@ -980,21 +980,16 @@ class ApplicationContext extends Context {
|
||||
return mSearchManager;
|
||||
}
|
||||
|
||||
private BluetoothDevice getBluetoothDevice() {
|
||||
if (sIsBluetoothDeviceCached) {
|
||||
return sBluetoothDevice;
|
||||
}
|
||||
synchronized (sSync) {
|
||||
private synchronized BluetoothAdapter getBluetoothAdapter() {
|
||||
if (!mIsBluetoothAdapterCached) {
|
||||
mIsBluetoothAdapterCached = true;
|
||||
IBinder b = ServiceManager.getService(BLUETOOTH_SERVICE);
|
||||
if (b == null) {
|
||||
sBluetoothDevice = null;
|
||||
} else {
|
||||
IBluetoothDevice service = IBluetoothDevice.Stub.asInterface(b);
|
||||
sBluetoothDevice = new BluetoothDevice(service);
|
||||
if (b != null) {
|
||||
IBluetooth service = IBluetooth.Stub.asInterface(b);
|
||||
mBluetoothAdapter = new BluetoothAdapter(service);
|
||||
}
|
||||
sIsBluetoothDeviceCached = true;
|
||||
}
|
||||
return sBluetoothDevice;
|
||||
return mBluetoothAdapter;
|
||||
}
|
||||
|
||||
private SensorManager getSensorManager() {
|
||||
|
||||
@@ -25,7 +25,10 @@ import android.os.RemoteException;
|
||||
import android.os.IBinder;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
|
||||
/**
|
||||
* Public API for controlling the Bluetooth A2DP Profile Service.
|
||||
@@ -47,7 +50,7 @@ import java.util.List;
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public class BluetoothA2dp {
|
||||
public final class BluetoothA2dp {
|
||||
private static final String TAG = "BluetoothA2dp";
|
||||
private static final boolean DBG = false;
|
||||
|
||||
@@ -79,6 +82,7 @@ public class BluetoothA2dp {
|
||||
/** Default priority for a2dp devices that should not allow incoming
|
||||
* connections */
|
||||
public static final int PRIORITY_OFF = 0;
|
||||
|
||||
private final IBluetoothA2dp mService;
|
||||
private final Context mContext;
|
||||
|
||||
@@ -89,6 +93,7 @@ public class BluetoothA2dp {
|
||||
*/
|
||||
public BluetoothA2dp(Context c) {
|
||||
mContext = c;
|
||||
|
||||
IBinder b = ServiceManager.getService(BluetoothA2dpService.BLUETOOTH_A2DP_SERVICE);
|
||||
if (b == null) {
|
||||
throw new RuntimeException("Bluetooth A2DP service not available!");
|
||||
@@ -99,14 +104,14 @@ public class BluetoothA2dp {
|
||||
/** Initiate a connection to an A2DP sink.
|
||||
* Listen for SINK_STATE_CHANGED_ACTION to find out when the
|
||||
* connection is completed.
|
||||
* @param address Remote BT address.
|
||||
* @param device Remote BT device.
|
||||
* @return Result code, negative indicates an immediate error.
|
||||
* @hide
|
||||
*/
|
||||
public int connectSink(String address) {
|
||||
if (DBG) log("connectSink(" + address + ")");
|
||||
public int connectSink(BluetoothDevice device) {
|
||||
if (DBG) log("connectSink(" + device + ")");
|
||||
try {
|
||||
return mService.connectSink(address);
|
||||
return mService.connectSink(device);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "", e);
|
||||
return BluetoothError.ERROR_IPC;
|
||||
@@ -116,14 +121,14 @@ public class BluetoothA2dp {
|
||||
/** Initiate disconnect from an A2DP sink.
|
||||
* Listen for SINK_STATE_CHANGED_ACTION to find out when
|
||||
* disconnect is completed.
|
||||
* @param address Remote BT address.
|
||||
* @param device Remote BT device.
|
||||
* @return Result code, negative indicates an immediate error.
|
||||
* @hide
|
||||
*/
|
||||
public int disconnectSink(String address) {
|
||||
if (DBG) log("disconnectSink(" + address + ")");
|
||||
public int disconnectSink(BluetoothDevice device) {
|
||||
if (DBG) log("disconnectSink(" + device + ")");
|
||||
try {
|
||||
return mService.disconnectSink(address);
|
||||
return mService.disconnectSink(device);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "", e);
|
||||
return BluetoothError.ERROR_IPC;
|
||||
@@ -131,24 +136,25 @@ public class BluetoothA2dp {
|
||||
}
|
||||
|
||||
/** Check if a specified A2DP sink is connected.
|
||||
* @param address Remote BT address.
|
||||
* @param device Remote BT device.
|
||||
* @return True if connected (or playing), false otherwise and on error.
|
||||
* @hide
|
||||
*/
|
||||
public boolean isSinkConnected(String address) {
|
||||
if (DBG) log("isSinkConnected(" + address + ")");
|
||||
int state = getSinkState(address);
|
||||
public boolean isSinkConnected(BluetoothDevice device) {
|
||||
if (DBG) log("isSinkConnected(" + device + ")");
|
||||
int state = getSinkState(device);
|
||||
return state == STATE_CONNECTED || state == STATE_PLAYING;
|
||||
}
|
||||
|
||||
/** Check if any A2DP sink is connected.
|
||||
* @return a List of connected A2DP sinks, or null on error.
|
||||
* @return a unmodifiable set of connected A2DP sinks, or null on error.
|
||||
* @hide
|
||||
*/
|
||||
public List<String> listConnectedSinks() {
|
||||
if (DBG) log("listConnectedSinks()");
|
||||
public Set<BluetoothDevice> getConnectedSinks() {
|
||||
if (DBG) log("getConnectedSinks()");
|
||||
try {
|
||||
return mService.listConnectedSinks();
|
||||
return Collections.unmodifiableSet(
|
||||
new HashSet<BluetoothDevice>(Arrays.asList(mService.getConnectedSinks())));
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "", e);
|
||||
return null;
|
||||
@@ -156,14 +162,14 @@ public class BluetoothA2dp {
|
||||
}
|
||||
|
||||
/** Get the state of an A2DP sink
|
||||
* @param address Remote BT address.
|
||||
* @param device Remote BT device.
|
||||
* @return State code, or negative on error
|
||||
* @hide
|
||||
*/
|
||||
public int getSinkState(String address) {
|
||||
if (DBG) log("getSinkState(" + address + ")");
|
||||
public int getSinkState(BluetoothDevice device) {
|
||||
if (DBG) log("getSinkState(" + device + ")");
|
||||
try {
|
||||
return mService.getSinkState(address);
|
||||
return mService.getSinkState(device);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "", e);
|
||||
return BluetoothError.ERROR_IPC;
|
||||
@@ -177,15 +183,15 @@ public class BluetoothA2dp {
|
||||
* Sinks with priority greater than zero will accept incoming connections
|
||||
* (if no sink is currently connected).
|
||||
* Priority for unpaired sink must be PRIORITY_NONE.
|
||||
* @param address Paired sink
|
||||
* @param device Paired sink
|
||||
* @param priority Integer priority, for example PRIORITY_AUTO or
|
||||
* PRIORITY_NONE
|
||||
* @return Result code, negative indicates an error
|
||||
*/
|
||||
public int setSinkPriority(String address, int priority) {
|
||||
if (DBG) log("setSinkPriority(" + address + ", " + priority + ")");
|
||||
public int setSinkPriority(BluetoothDevice device, int priority) {
|
||||
if (DBG) log("setSinkPriority(" + device + ", " + priority + ")");
|
||||
try {
|
||||
return mService.setSinkPriority(address, priority);
|
||||
return mService.setSinkPriority(device, priority);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "", e);
|
||||
return BluetoothError.ERROR_IPC;
|
||||
@@ -194,13 +200,13 @@ public class BluetoothA2dp {
|
||||
|
||||
/**
|
||||
* Get priority of a2dp sink.
|
||||
* @param address Sink
|
||||
* @param device Sink
|
||||
* @return non-negative priority, or negative error code on error.
|
||||
*/
|
||||
public int getSinkPriority(String address) {
|
||||
if (DBG) log("getSinkPriority(" + address + ")");
|
||||
public int getSinkPriority(BluetoothDevice device) {
|
||||
if (DBG) log("getSinkPriority(" + device + ")");
|
||||
try {
|
||||
return mService.getSinkPriority(address);
|
||||
return mService.getSinkPriority(device);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "", e);
|
||||
return BluetoothError.ERROR_IPC;
|
||||
|
||||
331
core/java/android/bluetooth/BluetoothAdapter.java
Normal file
331
core/java/android/bluetooth/BluetoothAdapter.java
Normal file
@@ -0,0 +1,331 @@
|
||||
/*
|
||||
* Copyright (C) 2009 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 android.bluetooth;
|
||||
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
|
||||
/**
|
||||
* Represents the local Bluetooth adapter.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public final class BluetoothAdapter {
|
||||
private static final String TAG = "BluetoothAdapter";
|
||||
|
||||
public static final int BLUETOOTH_STATE_OFF = 0;
|
||||
public static final int BLUETOOTH_STATE_TURNING_ON = 1;
|
||||
public static final int BLUETOOTH_STATE_ON = 2;
|
||||
public static final int BLUETOOTH_STATE_TURNING_OFF = 3;
|
||||
|
||||
/** Inquiry scan and page scan are both off.
|
||||
* Device is neither discoverable nor connectable */
|
||||
public static final int SCAN_MODE_NONE = 0;
|
||||
/** Page scan is on, inquiry scan is off.
|
||||
* Device is connectable, but not discoverable */
|
||||
public static final int SCAN_MODE_CONNECTABLE = 1;
|
||||
/** Page scan and inquiry scan are on.
|
||||
* Device is connectable and discoverable */
|
||||
public static final int SCAN_MODE_CONNECTABLE_DISCOVERABLE = 3;
|
||||
|
||||
public static final int RESULT_FAILURE = -1;
|
||||
public static final int RESULT_SUCCESS = 0;
|
||||
|
||||
/* The user will be prompted to enter a pin */
|
||||
public static final int PAIRING_VARIANT_PIN = 0;
|
||||
/* The user will be prompted to enter a passkey */
|
||||
public static final int PAIRING_VARIANT_PASSKEY = 1;
|
||||
/* The user will be prompted to confirm the passkey displayed on the screen */
|
||||
public static final int PAIRING_VARIANT_CONFIRMATION = 2;
|
||||
|
||||
private final IBluetooth mService;
|
||||
|
||||
/**
|
||||
* Do not use this constructor. Use Context.getSystemService() instead.
|
||||
* @hide
|
||||
*/
|
||||
public BluetoothAdapter(IBluetooth service) {
|
||||
if (service == null) {
|
||||
throw new IllegalArgumentException("service is null");
|
||||
}
|
||||
mService = service;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the remote BluetoothDevice associated with the given MAC address.
|
||||
* Bluetooth MAC address must be upper case, such as "00:11:22:33:AA:BB".
|
||||
* @param address valid Bluetooth MAC address
|
||||
*/
|
||||
public BluetoothDevice getRemoteDevice(String address) {
|
||||
return new BluetoothDevice(address);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is Bluetooth currently turned on.
|
||||
*
|
||||
* @return true if Bluetooth enabled, false otherwise.
|
||||
*/
|
||||
public boolean isEnabled() {
|
||||
try {
|
||||
return mService.isEnabled();
|
||||
} catch (RemoteException e) {Log.e(TAG, "", e);}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current state of Bluetooth.
|
||||
*
|
||||
* @return One of BLUETOOTH_STATE_ or BluetoothError.ERROR.
|
||||
*/
|
||||
public int getBluetoothState() {
|
||||
try {
|
||||
return mService.getBluetoothState();
|
||||
} catch (RemoteException e) {Log.e(TAG, "", e);}
|
||||
return BluetoothError.ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable the Bluetooth device.
|
||||
* Turn on the underlying hardware.
|
||||
* This is an asynchronous call,
|
||||
* BluetoothIntent.BLUETOOTH_STATE_CHANGED_ACTION can be used to check if
|
||||
* and when the device is sucessfully enabled.
|
||||
* @return false if we cannot enable the Bluetooth device. True does not
|
||||
* imply the device was enabled, it only implies that so far there were no
|
||||
* problems.
|
||||
*/
|
||||
public boolean enable() {
|
||||
try {
|
||||
return mService.enable();
|
||||
} catch (RemoteException e) {Log.e(TAG, "", e);}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable the Bluetooth device.
|
||||
* This turns off the underlying hardware.
|
||||
*
|
||||
* @return true if successful, false otherwise.
|
||||
*/
|
||||
public boolean disable() {
|
||||
try {
|
||||
return mService.disable(true);
|
||||
} catch (RemoteException e) {Log.e(TAG, "", e);}
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getAddress() {
|
||||
try {
|
||||
return mService.getAddress();
|
||||
} catch (RemoteException e) {Log.e(TAG, "", e);}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the friendly Bluetooth name of this device.
|
||||
*
|
||||
* This name is visible to remote Bluetooth devices. Currently it is only
|
||||
* possible to retrieve the Bluetooth name when Bluetooth is enabled.
|
||||
*
|
||||
* @return the Bluetooth name, or null if there was a problem.
|
||||
*/
|
||||
public String getName() {
|
||||
try {
|
||||
return mService.getName();
|
||||
} catch (RemoteException e) {Log.e(TAG, "", e);}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the friendly Bluetooth name of this device.
|
||||
*
|
||||
* This name is visible to remote Bluetooth devices. The Bluetooth Service
|
||||
* is responsible for persisting this name.
|
||||
*
|
||||
* @param name the name to set
|
||||
* @return true, if the name was successfully set. False otherwise.
|
||||
*/
|
||||
public boolean setName(String name) {
|
||||
try {
|
||||
return mService.setName(name);
|
||||
} catch (RemoteException e) {Log.e(TAG, "", e);}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current scan mode.
|
||||
* Used to determine if the local device is connectable and/or discoverable
|
||||
* @return Scan mode, one of SCAN_MODE_* or an error code
|
||||
*/
|
||||
public int getScanMode() {
|
||||
try {
|
||||
return mService.getScanMode();
|
||||
} catch (RemoteException e) {Log.e(TAG, "", e);}
|
||||
return BluetoothError.ERROR_IPC;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current scan mode.
|
||||
* Used to make the local device connectable and/or discoverable
|
||||
* @param scanMode One of SCAN_MODE_*
|
||||
*/
|
||||
public void setScanMode(int scanMode) {
|
||||
try {
|
||||
mService.setScanMode(scanMode);
|
||||
} catch (RemoteException e) {Log.e(TAG, "", e);}
|
||||
}
|
||||
|
||||
public int getDiscoverableTimeout() {
|
||||
try {
|
||||
return mService.getDiscoverableTimeout();
|
||||
} catch (RemoteException e) {Log.e(TAG, "", e);}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void setDiscoverableTimeout(int timeout) {
|
||||
try {
|
||||
mService.setDiscoverableTimeout(timeout);
|
||||
} catch (RemoteException e) {Log.e(TAG, "", e);}
|
||||
}
|
||||
|
||||
public boolean startDiscovery() {
|
||||
try {
|
||||
return mService.startDiscovery();
|
||||
} catch (RemoteException e) {Log.e(TAG, "", e);}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void cancelDiscovery() {
|
||||
try {
|
||||
mService.cancelDiscovery();
|
||||
} catch (RemoteException e) {Log.e(TAG, "", e);}
|
||||
}
|
||||
|
||||
public boolean isDiscovering() {
|
||||
try {
|
||||
return mService.isDiscovering();
|
||||
} catch (RemoteException e) {Log.e(TAG, "", e);}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* List remote devices that are bonded (paired) to the local adapter.
|
||||
*
|
||||
* Bonding (pairing) is the process by which the user enters a pin code for
|
||||
* the device, which generates a shared link key, allowing for
|
||||
* authentication and encryption of future connections. In Android we
|
||||
* require bonding before RFCOMM or SCO connections can be made to a remote
|
||||
* device.
|
||||
*
|
||||
* This function lists which remote devices we have a link key for. It does
|
||||
* not cause any RF transmission, and does not check if the remote device
|
||||
* still has it's link key with us. If the other side no longer has its
|
||||
* link key then the RFCOMM or SCO connection attempt will result in an
|
||||
* error.
|
||||
*
|
||||
* This function does not check if the remote device is in range.
|
||||
*
|
||||
* Remote devices that have an in-progress bonding attempt are not
|
||||
* returned.
|
||||
*
|
||||
* @return unmodifiable set of bonded devices, or null on error
|
||||
*/
|
||||
public Set<BluetoothDevice> getBondedDevices() {
|
||||
try {
|
||||
return toDeviceSet(mService.listBonds());
|
||||
} catch (RemoteException e) {Log.e(TAG, "", e);}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a listening, secure RFCOMM server socket.
|
||||
* The remote device connecting to this socket will be authenticated and
|
||||
* communication on this socket will be encrypted.
|
||||
* Call #accept to retrieve connections to this socket.
|
||||
* @return An RFCOMM BluetoothServerSocket
|
||||
* @throws IOException On error, for example Bluetooth not available, or
|
||||
* insufficient permissions.
|
||||
*/
|
||||
public BluetoothServerSocket listenUsingRfcommOn(int port) throws IOException {
|
||||
BluetoothServerSocket socket = new BluetoothServerSocket(
|
||||
BluetoothSocket.TYPE_RFCOMM, true, true, port);
|
||||
try {
|
||||
socket.mSocket.bindListenNative();
|
||||
} catch (IOException e) {
|
||||
try {
|
||||
socket.close();
|
||||
} catch (IOException e2) { }
|
||||
throw e;
|
||||
}
|
||||
return socket;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an unencrypted, unauthenticated, RFCOMM server socket.
|
||||
* Call #accept to retrieve connections to this socket.
|
||||
* @return An RFCOMM BluetoothServerSocket
|
||||
* @throws IOException On error, for example Bluetooth not available, or
|
||||
* insufficient permissions.
|
||||
*/
|
||||
public BluetoothServerSocket listenUsingInsecureRfcommOn(int port) throws IOException {
|
||||
BluetoothServerSocket socket = new BluetoothServerSocket(
|
||||
BluetoothSocket.TYPE_RFCOMM, false, false, port);
|
||||
try {
|
||||
socket.mSocket.bindListenNative();
|
||||
} catch (IOException e) {
|
||||
try {
|
||||
socket.close();
|
||||
} catch (IOException e2) { }
|
||||
throw e;
|
||||
}
|
||||
return socket;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a SCO server socket.
|
||||
* Call #accept to retrieve connections to this socket.
|
||||
* @return A SCO BluetoothServerSocket
|
||||
* @throws IOException On error, for example Bluetooth not available, or
|
||||
* insufficient permissions.
|
||||
*/
|
||||
public static BluetoothServerSocket listenUsingScoOn() throws IOException {
|
||||
BluetoothServerSocket socket = new BluetoothServerSocket(
|
||||
BluetoothSocket.TYPE_SCO, false, false, -1);
|
||||
try {
|
||||
socket.mSocket.bindListenNative();
|
||||
} catch (IOException e) {
|
||||
try {
|
||||
socket.close();
|
||||
} catch (IOException e2) { }
|
||||
throw e;
|
||||
}
|
||||
return socket;
|
||||
}
|
||||
|
||||
private Set<BluetoothDevice> toDeviceSet(String[] addresses) {
|
||||
Set<BluetoothDevice> devices = new HashSet<BluetoothDevice>(addresses.length);
|
||||
for (int i = 0; i < addresses.length; i++) {
|
||||
devices.add(getRemoteDevice(addresses[i]));
|
||||
}
|
||||
return Collections.unmodifiableSet(devices);
|
||||
}
|
||||
}
|
||||
@@ -9,24 +9,22 @@ import android.util.Log;
|
||||
/**
|
||||
* Listen's for incoming RFCOMM connection for the headset / handsfree service.
|
||||
*
|
||||
* This class is planned for deletion, in favor of a generic Rfcomm class.
|
||||
* TODO: Use the new generic BluetoothSocket class instead of this legacy code
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public class BluetoothAudioGateway {
|
||||
public final class BluetoothAudioGateway {
|
||||
private static final String TAG = "BT Audio Gateway";
|
||||
private static final boolean DBG = false;
|
||||
|
||||
private int mNativeData;
|
||||
static { classInitNative(); }
|
||||
|
||||
private BluetoothDevice mBluetooth;
|
||||
|
||||
/* in */
|
||||
private int mHandsfreeAgRfcommChannel = -1;
|
||||
private int mHeadsetAgRfcommChannel = -1;
|
||||
|
||||
/* out */
|
||||
/* out - written by native code */
|
||||
private String mConnectingHeadsetAddress;
|
||||
private int mConnectingHeadsetRfcommChannel; /* -1 when not connected */
|
||||
private int mConnectingHeadsetSocketFd;
|
||||
@@ -35,17 +33,18 @@ public class BluetoothAudioGateway {
|
||||
private int mConnectingHandsfreeSocketFd;
|
||||
private int mTimeoutRemainingMs; /* in/out */
|
||||
|
||||
private final BluetoothAdapter mAdapter;
|
||||
|
||||
public static final int DEFAULT_HF_AG_CHANNEL = 10;
|
||||
public static final int DEFAULT_HS_AG_CHANNEL = 11;
|
||||
|
||||
public BluetoothAudioGateway(BluetoothDevice bluetooth) {
|
||||
this(bluetooth, DEFAULT_HF_AG_CHANNEL, DEFAULT_HS_AG_CHANNEL);
|
||||
public BluetoothAudioGateway(BluetoothAdapter adapter) {
|
||||
this(adapter, DEFAULT_HF_AG_CHANNEL, DEFAULT_HS_AG_CHANNEL);
|
||||
}
|
||||
|
||||
public BluetoothAudioGateway(BluetoothDevice bluetooth,
|
||||
int handsfreeAgRfcommChannel,
|
||||
int headsetAgRfcommChannel) {
|
||||
mBluetooth = bluetooth;
|
||||
public BluetoothAudioGateway(BluetoothAdapter adapter, int handsfreeAgRfcommChannel,
|
||||
int headsetAgRfcommChannel) {
|
||||
mAdapter = adapter;
|
||||
mHandsfreeAgRfcommChannel = handsfreeAgRfcommChannel;
|
||||
mHeadsetAgRfcommChannel = headsetAgRfcommChannel;
|
||||
initializeNativeDataNative();
|
||||
@@ -58,18 +57,17 @@ public class BluetoothAudioGateway {
|
||||
private Handler mCallback;
|
||||
|
||||
public class IncomingConnectionInfo {
|
||||
IncomingConnectionInfo(BluetoothDevice bluetooth, String address, int socketFd,
|
||||
int rfcommChan) {
|
||||
mBluetooth = bluetooth;
|
||||
mAddress = address;
|
||||
public BluetoothAdapter mAdapter;
|
||||
public BluetoothDevice mRemoteDevice;
|
||||
public int mSocketFd;
|
||||
public int mRfcommChan;
|
||||
IncomingConnectionInfo(BluetoothAdapter adapter, BluetoothDevice remoteDevice,
|
||||
int socketFd, int rfcommChan) {
|
||||
mAdapter = adapter;
|
||||
mRemoteDevice = remoteDevice;
|
||||
mSocketFd = socketFd;
|
||||
mRfcommChan = rfcommChan;
|
||||
}
|
||||
|
||||
public BluetoothDevice mBluetooth;
|
||||
public String mAddress;
|
||||
public int mSocketFd;
|
||||
public int mRfcommChan;
|
||||
}
|
||||
|
||||
public static final int MSG_INCOMING_HEADSET_CONNECTION = 100;
|
||||
@@ -111,12 +109,11 @@ public class BluetoothAudioGateway {
|
||||
mConnectingHeadsetRfcommChannel);
|
||||
Message msg = Message.obtain(mCallback);
|
||||
msg.what = MSG_INCOMING_HEADSET_CONNECTION;
|
||||
msg.obj =
|
||||
new IncomingConnectionInfo(
|
||||
mBluetooth,
|
||||
mConnectingHeadsetAddress,
|
||||
mConnectingHeadsetSocketFd,
|
||||
mConnectingHeadsetRfcommChannel);
|
||||
msg.obj = new IncomingConnectionInfo(
|
||||
mAdapter,
|
||||
mAdapter.getRemoteDevice(mConnectingHeadsetAddress),
|
||||
mConnectingHeadsetSocketFd,
|
||||
mConnectingHeadsetRfcommChannel);
|
||||
msg.sendToTarget();
|
||||
}
|
||||
if (mConnectingHandsfreeRfcommChannel >= 0) {
|
||||
@@ -126,12 +123,11 @@ public class BluetoothAudioGateway {
|
||||
Message msg = Message.obtain();
|
||||
msg.setTarget(mCallback);
|
||||
msg.what = MSG_INCOMING_HANDSFREE_CONNECTION;
|
||||
msg.obj =
|
||||
new IncomingConnectionInfo(
|
||||
mBluetooth,
|
||||
mConnectingHandsfreeAddress,
|
||||
mConnectingHandsfreeSocketFd,
|
||||
mConnectingHandsfreeRfcommChannel);
|
||||
msg.obj = new IncomingConnectionInfo(
|
||||
mAdapter,
|
||||
mAdapter.getRemoteDevice(mConnectingHandsfreeAddress),
|
||||
mConnectingHandsfreeSocketFd,
|
||||
mConnectingHandsfreeRfcommChannel);
|
||||
msg.sendToTarget();
|
||||
}
|
||||
}
|
||||
|
||||
19
core/java/android/bluetooth/BluetoothDevice.aidl
Normal file
19
core/java/android/bluetooth/BluetoothDevice.aidl
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2009 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 android.bluetooth;
|
||||
|
||||
parcelable BluetoothDevice;
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
* Copyright (C) 2009 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.
|
||||
@@ -16,39 +16,25 @@
|
||||
|
||||
package android.bluetooth;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.IBinder;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
/**
|
||||
* The Android Bluetooth API is not finalized, and *will* change. Use at your
|
||||
* own risk.
|
||||
*
|
||||
* Manages the local Bluetooth device. Scan for devices, create bondings,
|
||||
* power up and down the adapter.
|
||||
* Represents a remote Bluetooth device.
|
||||
*
|
||||
* TODO: unhide
|
||||
* @hide
|
||||
*/
|
||||
public class BluetoothDevice {
|
||||
|
||||
public static final int BLUETOOTH_STATE_OFF = 0;
|
||||
public static final int BLUETOOTH_STATE_TURNING_ON = 1;
|
||||
public static final int BLUETOOTH_STATE_ON = 2;
|
||||
public static final int BLUETOOTH_STATE_TURNING_OFF = 3;
|
||||
|
||||
/** Inquiry scan and page scan are both off.
|
||||
* Device is neither discoverable nor connectable */
|
||||
public static final int SCAN_MODE_NONE = 0;
|
||||
/** Page scan is on, inquiry scan is off.
|
||||
* Device is connectable, but not discoverable */
|
||||
public static final int SCAN_MODE_CONNECTABLE = 1;
|
||||
/** Page scan and inquiry scan are on.
|
||||
* Device is connectable and discoverable */
|
||||
public static final int SCAN_MODE_CONNECTABLE_DISCOVERABLE = 3;
|
||||
|
||||
public static final int RESULT_FAILURE = -1;
|
||||
public static final int RESULT_SUCCESS = 0;
|
||||
public final class BluetoothDevice implements Parcelable {
|
||||
private static final String TAG = "BluetoothDevice";
|
||||
|
||||
/** We do not have a link key for the remote device, and are therefore not
|
||||
* bonded */
|
||||
@@ -81,84 +67,81 @@ public class BluetoothDevice {
|
||||
/* The user will be prompted to confirm the passkey displayed on the screen */
|
||||
public static final int PAIRING_VARIANT_CONFIRMATION = 2;
|
||||
|
||||
private static final int ADDRESS_LENGTH = 17;
|
||||
|
||||
private static final String TAG = "BluetoothDevice";
|
||||
private static IBluetooth sService; /* Guarenteed constant after first object constructed */
|
||||
|
||||
private final String mAddress;
|
||||
|
||||
private final IBluetoothDevice mService;
|
||||
/**
|
||||
* @hide - hide this because it takes a parameter of type
|
||||
* IBluetoothDevice, which is a System private class.
|
||||
* Also note that Context.getSystemService is a factory that
|
||||
* returns a BlueToothDevice. That is the right way to get
|
||||
* a BluetoothDevice.
|
||||
* Create a new BluetoothDevice
|
||||
* Bluetooth MAC address must be upper case, such as "00:11:22:33:AA:BB",
|
||||
* and is validated in this constructor.
|
||||
* @param address valid Bluetooth MAC address
|
||||
* @throws RuntimeException Bluetooth is not available on this platform
|
||||
* @throws IllegalArgumentException address is invalid
|
||||
* @hide
|
||||
*/
|
||||
public BluetoothDevice(IBluetoothDevice service) {
|
||||
mService = service;
|
||||
/*package*/ BluetoothDevice(String address) {
|
||||
synchronized (BluetoothDevice.class) {
|
||||
if (sService == null) {
|
||||
IBinder b = ServiceManager.getService(Context.BLUETOOTH_SERVICE);
|
||||
if (b == null) {
|
||||
throw new RuntimeException("Bluetooth service not available");
|
||||
}
|
||||
sService = IBluetooth.Stub.asInterface(b);
|
||||
}
|
||||
}
|
||||
|
||||
if (!checkBluetoothAddress(address)) {
|
||||
throw new IllegalArgumentException(address + " is not a valid Bluetooth address");
|
||||
}
|
||||
|
||||
mAddress = address;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is Bluetooth currently turned on.
|
||||
*
|
||||
* @return true if Bluetooth enabled, false otherwise.
|
||||
*/
|
||||
public boolean isEnabled() {
|
||||
try {
|
||||
return mService.isEnabled();
|
||||
} catch (RemoteException e) {Log.e(TAG, "", e);}
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof BluetoothDevice) {
|
||||
return mAddress.equals(((BluetoothDevice)o).getAddress());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current state of Bluetooth.
|
||||
*
|
||||
* @return One of BLUETOOTH_STATE_ or BluetoothError.ERROR.
|
||||
*/
|
||||
public int getBluetoothState() {
|
||||
try {
|
||||
return mService.getBluetoothState();
|
||||
} catch (RemoteException e) {Log.e(TAG, "", e);}
|
||||
return BluetoothError.ERROR;
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return mAddress.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable the Bluetooth device.
|
||||
* Turn on the underlying hardware.
|
||||
* This is an asynchronous call,
|
||||
* BluetoothIntent.BLUETOOTH_STATE_CHANGED_ACTION can be used to check if
|
||||
* and when the device is sucessfully enabled.
|
||||
* @return false if we cannot enable the Bluetooth device. True does not
|
||||
* imply the device was enabled, it only implies that so far there were no
|
||||
* problems.
|
||||
*/
|
||||
public boolean enable() {
|
||||
try {
|
||||
return mService.enable();
|
||||
} catch (RemoteException e) {Log.e(TAG, "", e);}
|
||||
return false;
|
||||
@Override
|
||||
public String toString() {
|
||||
return mAddress;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable the Bluetooth device.
|
||||
* This turns off the underlying hardware.
|
||||
*
|
||||
* @return true if successful, false otherwise.
|
||||
*/
|
||||
public boolean disable() {
|
||||
try {
|
||||
return mService.disable(true);
|
||||
} catch (RemoteException e) {Log.e(TAG, "", e);}
|
||||
return false;
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<BluetoothDevice> CREATOR =
|
||||
new Parcelable.Creator<BluetoothDevice>() {
|
||||
public BluetoothDevice createFromParcel(Parcel in) {
|
||||
return new BluetoothDevice(in.readString());
|
||||
}
|
||||
public BluetoothDevice[] newArray(int size) {
|
||||
return new BluetoothDevice[size];
|
||||
}
|
||||
};
|
||||
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
out.writeString(mAddress);
|
||||
}
|
||||
|
||||
public String getAddress() {
|
||||
try {
|
||||
return mService.getAddress();
|
||||
} catch (RemoteException e) {Log.e(TAG, "", e);}
|
||||
return null;
|
||||
return mAddress;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the friendly Bluetooth name of this device.
|
||||
* Get the friendly Bluetooth name of this remote device.
|
||||
*
|
||||
* This name is visible to remote Bluetooth devices. Currently it is only
|
||||
* possible to retrieve the Bluetooth name when Bluetooth is enabled.
|
||||
@@ -167,97 +150,11 @@ public class BluetoothDevice {
|
||||
*/
|
||||
public String getName() {
|
||||
try {
|
||||
return mService.getName();
|
||||
return sService.getRemoteName(mAddress);
|
||||
} catch (RemoteException e) {Log.e(TAG, "", e);}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the friendly Bluetooth name of this device.
|
||||
*
|
||||
* This name is visible to remote Bluetooth devices. The Bluetooth Service
|
||||
* is responsible for persisting this name.
|
||||
*
|
||||
* @param name the name to set
|
||||
* @return true, if the name was successfully set. False otherwise.
|
||||
*/
|
||||
public boolean setName(String name) {
|
||||
try {
|
||||
return mService.setName(name);
|
||||
} catch (RemoteException e) {Log.e(TAG, "", e);}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current scan mode.
|
||||
* Used to determine if the local device is connectable and/or discoverable
|
||||
* @return Scan mode, one of SCAN_MODE_* or an error code
|
||||
*/
|
||||
public int getScanMode() {
|
||||
try {
|
||||
return mService.getScanMode();
|
||||
} catch (RemoteException e) {Log.e(TAG, "", e);}
|
||||
return BluetoothError.ERROR_IPC;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current scan mode.
|
||||
* Used to make the local device connectable and/or discoverable
|
||||
* @param scanMode One of SCAN_MODE_*
|
||||
*/
|
||||
public void setScanMode(int scanMode) {
|
||||
try {
|
||||
mService.setScanMode(scanMode);
|
||||
} catch (RemoteException e) {Log.e(TAG, "", e);}
|
||||
}
|
||||
|
||||
public int getDiscoverableTimeout() {
|
||||
try {
|
||||
return mService.getDiscoverableTimeout();
|
||||
} catch (RemoteException e) {Log.e(TAG, "", e);}
|
||||
return -1;
|
||||
}
|
||||
public void setDiscoverableTimeout(int timeout) {
|
||||
try {
|
||||
mService.setDiscoverableTimeout(timeout);
|
||||
} catch (RemoteException e) {Log.e(TAG, "", e);}
|
||||
}
|
||||
|
||||
public boolean startDiscovery() {
|
||||
try {
|
||||
return mService.startDiscovery();
|
||||
} catch (RemoteException e) {Log.e(TAG, "", e);}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void cancelDiscovery() {
|
||||
try {
|
||||
mService.cancelDiscovery();
|
||||
} catch (RemoteException e) {Log.e(TAG, "", e);}
|
||||
}
|
||||
|
||||
public boolean isDiscovering() {
|
||||
try {
|
||||
return mService.isDiscovering();
|
||||
} catch (RemoteException e) {Log.e(TAG, "", e);}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the remote device and the pairing information associated
|
||||
* with it.
|
||||
*
|
||||
* @param address the Bluetooth hardware address you want to disconnect.
|
||||
* @return true if the device was disconnected, false otherwise and on
|
||||
* error.
|
||||
*/
|
||||
public boolean removeBond(String address) {
|
||||
try {
|
||||
return mService.removeBond(address);
|
||||
} catch (RemoteException e) {Log.e(TAG, "", e);}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a bonding with a remote bluetooth device.
|
||||
*
|
||||
@@ -268,9 +165,9 @@ public class BluetoothDevice {
|
||||
* @return false If there was an immediate problem creating the bonding,
|
||||
* true otherwise.
|
||||
*/
|
||||
public boolean createBond(String address) {
|
||||
public boolean createBond() {
|
||||
try {
|
||||
return mService.createBond(address);
|
||||
return sService.createBond(mAddress);
|
||||
} catch (RemoteException e) {Log.e(TAG, "", e);}
|
||||
return false;
|
||||
}
|
||||
@@ -278,41 +175,25 @@ public class BluetoothDevice {
|
||||
/**
|
||||
* Cancel an in-progress bonding request started with createBond.
|
||||
*/
|
||||
public boolean cancelBondProcess(String address) {
|
||||
public boolean cancelBondProcess() {
|
||||
try {
|
||||
return mService.cancelBondProcess(address);
|
||||
return sService.cancelBondProcess(mAddress);
|
||||
} catch (RemoteException e) {Log.e(TAG, "", e);}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* List remote devices that are bonded (paired) to the local device.
|
||||
* Removes the remote device and the pairing information associated
|
||||
* with it.
|
||||
*
|
||||
* Bonding (pairing) is the process by which the user enters a pin code for
|
||||
* the device, which generates a shared link key, allowing for
|
||||
* authentication and encryption of future connections. In Android we
|
||||
* require bonding before RFCOMM or SCO connections can be made to a remote
|
||||
* device.
|
||||
*
|
||||
* This function lists which remote devices we have a link key for. It does
|
||||
* not cause any RF transmission, and does not check if the remote device
|
||||
* still has it's link key with us. If the other side no longer has its
|
||||
* link key then the RFCOMM or SCO connection attempt will result in an
|
||||
* error.
|
||||
*
|
||||
* This function does not check if the remote device is in range.
|
||||
*
|
||||
* Remote devices that have an in-progress bonding attempt are not
|
||||
* returned.
|
||||
*
|
||||
* @return bluetooth hardware addresses of remote devices that are
|
||||
* bonded. Array size is 0 if no devices are bonded. Null on error.
|
||||
* @return true if the device was disconnected, false otherwise and on
|
||||
* error.
|
||||
*/
|
||||
public String[] listBonds() {
|
||||
public boolean removeBond() {
|
||||
try {
|
||||
return mService.listBonds();
|
||||
return sService.removeBond(mAddress);
|
||||
} catch (RemoteException e) {Log.e(TAG, "", e);}
|
||||
return null;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -325,69 +206,102 @@ public class BluetoothDevice {
|
||||
* @param address Bluetooth hardware address of the remote device to check.
|
||||
* @return Result code
|
||||
*/
|
||||
public int getBondState(String address) {
|
||||
public int getBondState() {
|
||||
try {
|
||||
return mService.getBondState(address);
|
||||
return sService.getBondState(mAddress);
|
||||
} catch (RemoteException e) {Log.e(TAG, "", e);}
|
||||
return BluetoothError.ERROR_IPC;
|
||||
}
|
||||
|
||||
public String getRemoteName(String address) {
|
||||
public int getBluetoothClass() {
|
||||
try {
|
||||
return mService.getRemoteName(address);
|
||||
} catch (RemoteException e) {Log.e(TAG, "", e);}
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getRemoteClass(String address) {
|
||||
try {
|
||||
return mService.getRemoteClass(address);
|
||||
return sService.getRemoteClass(mAddress);
|
||||
} catch (RemoteException e) {Log.e(TAG, "", e);}
|
||||
return BluetoothError.ERROR_IPC;
|
||||
}
|
||||
|
||||
public String[] getRemoteUuids(String address) {
|
||||
public String[] getUuids() {
|
||||
try {
|
||||
return mService.getRemoteUuids(address);
|
||||
return sService.getRemoteUuids(mAddress);
|
||||
} catch (RemoteException e) {Log.e(TAG, "", e);}
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getRemoteServiceChannel(String address, String uuid) {
|
||||
public int getServiceChannel(String uuid) {
|
||||
try {
|
||||
return mService.getRemoteServiceChannel(address, uuid);
|
||||
return sService.getRemoteServiceChannel(mAddress, uuid);
|
||||
} catch (RemoteException e) {Log.e(TAG, "", e);}
|
||||
return BluetoothError.ERROR_IPC;
|
||||
}
|
||||
|
||||
public boolean setPin(String address, byte[] pin) {
|
||||
public boolean setPin(byte[] pin) {
|
||||
try {
|
||||
return mService.setPin(address, pin);
|
||||
return sService.setPin(mAddress, pin);
|
||||
} catch (RemoteException e) {Log.e(TAG, "", e);}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean setPasskey(String address, int passkey) {
|
||||
public boolean setPasskey(int passkey) {
|
||||
try {
|
||||
return mService.setPasskey(address, passkey);
|
||||
return sService.setPasskey(mAddress, passkey);
|
||||
} catch (RemoteException e) {Log.e(TAG, "", e);}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean setPairingConfirmation(String address, boolean confirm) {
|
||||
public boolean setPairingConfirmation(boolean confirm) {
|
||||
try {
|
||||
return mService.setPairingConfirmation(address, confirm);
|
||||
return sService.setPairingConfirmation(mAddress, confirm);
|
||||
} catch (RemoteException e) {Log.e(TAG, "", e);}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean cancelPairingUserInput(String address) {
|
||||
public boolean cancelPairingUserInput() {
|
||||
try {
|
||||
return mService.cancelPairingUserInput(address);
|
||||
return sService.cancelPairingUserInput(mAddress);
|
||||
} catch (RemoteException e) {Log.e(TAG, "", e);}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a secure RFCOMM socket ready to start an outgoing connection.
|
||||
* Call #connect on the returned #BluetoothSocket to begin the connection.
|
||||
* The remote device will be authenticated and communication on this socket
|
||||
* will be encrypted.
|
||||
* @param port remote port
|
||||
* @return an RFCOMM BluetoothSocket
|
||||
* @throws IOException on error, for example Bluetooth not available, or
|
||||
* insufficient permissions.
|
||||
*/
|
||||
public BluetoothSocket createRfcommSocket(int port) throws IOException {
|
||||
return new BluetoothSocket(BluetoothSocket.TYPE_RFCOMM, -1, true, true, this, port);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an insecure RFCOMM socket ready to start an outgoing
|
||||
* connection.
|
||||
* Call #connect on the returned #BluetoothSocket to begin the connection.
|
||||
* The remote device will not be authenticated and communication on this
|
||||
* socket will not be encrypted.
|
||||
* @param port remote port
|
||||
* @return An RFCOMM BluetoothSocket
|
||||
* @throws IOException On error, for example Bluetooth not available, or
|
||||
* insufficient permissions.
|
||||
*/
|
||||
public BluetoothSocket createInsecureRfcommSocket(int port) throws IOException {
|
||||
return new BluetoothSocket(BluetoothSocket.TYPE_RFCOMM, -1, false, false, this, port);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a SCO socket ready to start an outgoing connection.
|
||||
* Call #connect on the returned #BluetoothSocket to begin the connection.
|
||||
* @return a SCO BluetoothSocket
|
||||
* @throws IOException on error, for example Bluetooth not available, or
|
||||
* insufficient permissions.
|
||||
*/
|
||||
public BluetoothSocket createScoSocket() throws IOException {
|
||||
return new BluetoothSocket(BluetoothSocket.TYPE_SCO, -1, true, true, this, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that a pin is valid and convert to byte array.
|
||||
*
|
||||
@@ -413,7 +327,6 @@ public class BluetoothDevice {
|
||||
return pinBytes;
|
||||
}
|
||||
|
||||
private static final int ADDRESS_LENGTH = 17;
|
||||
/** Sanity check a bluetooth address, such as "00:43:A8:23:10:F0" */
|
||||
public static boolean checkBluetoothAddress(String address) {
|
||||
if (address == null || address.length() != ADDRESS_LENGTH) {
|
||||
|
||||
@@ -49,7 +49,7 @@ import android.util.Log;
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public class BluetoothHeadset {
|
||||
public final class BluetoothHeadset {
|
||||
|
||||
private static final String TAG = "BluetoothHeadset";
|
||||
private static final boolean DBG = false;
|
||||
@@ -163,16 +163,16 @@ public class BluetoothHeadset {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Bluetooth address of the current headset.
|
||||
* @return The Bluetooth address, or null if not in connected or connecting
|
||||
* Get the BluetoothDevice for the current headset.
|
||||
* @return current headset, or null if not in connected or connecting
|
||||
* state, or if this proxy object is not connected to the Headset
|
||||
* service.
|
||||
*/
|
||||
public String getHeadsetAddress() {
|
||||
if (DBG) log("getHeadsetAddress()");
|
||||
public BluetoothDevice getCurrentHeadset() {
|
||||
if (DBG) log("getCurrentHeadset()");
|
||||
if (mService != null) {
|
||||
try {
|
||||
return mService.getHeadsetAddress();
|
||||
return mService.getCurrentHeadset();
|
||||
} catch (RemoteException e) {Log.e(TAG, e.toString());}
|
||||
} else {
|
||||
Log.w(TAG, "Proxy not attached to service");
|
||||
@@ -185,19 +185,19 @@ public class BluetoothHeadset {
|
||||
* Request to initiate a connection to a headset.
|
||||
* This call does not block. Fails if a headset is already connecting
|
||||
* or connected.
|
||||
* Initiates auto-connection if address is null. Tries to connect to all
|
||||
* Initiates auto-connection if device is null. Tries to connect to all
|
||||
* devices with priority greater than PRIORITY_AUTO in descending order.
|
||||
* @param address The Bluetooth Address to connect to, or null to
|
||||
* auto-connect to the last connected headset.
|
||||
* @return False if there was a problem initiating the connection
|
||||
* procedure, and no further HEADSET_STATE_CHANGED intents
|
||||
* will be expected.
|
||||
* @param device device to connect to, or null to auto-connect last connected
|
||||
* headset
|
||||
* @return false if there was a problem initiating the connection
|
||||
* procedure, and no further HEADSET_STATE_CHANGED intents
|
||||
* will be expected.
|
||||
*/
|
||||
public boolean connectHeadset(String address) {
|
||||
if (DBG) log("connectHeadset(" + address + ")");
|
||||
public boolean connectHeadset(BluetoothDevice device) {
|
||||
if (DBG) log("connectHeadset(" + device + ")");
|
||||
if (mService != null) {
|
||||
try {
|
||||
if (mService.connectHeadset(address)) {
|
||||
if (mService.connectHeadset(device)) {
|
||||
return true;
|
||||
}
|
||||
} catch (RemoteException e) {Log.e(TAG, e.toString());}
|
||||
@@ -213,11 +213,11 @@ public class BluetoothHeadset {
|
||||
* connecting). Returns false if not connected, or if this proxy object
|
||||
* if not currently connected to the headset service.
|
||||
*/
|
||||
public boolean isConnected(String address) {
|
||||
if (DBG) log("isConnected(" + address + ")");
|
||||
public boolean isConnected(BluetoothDevice device) {
|
||||
if (DBG) log("isConnected(" + device + ")");
|
||||
if (mService != null) {
|
||||
try {
|
||||
return mService.isConnected(address);
|
||||
return mService.isConnected(device);
|
||||
} catch (RemoteException e) {Log.e(TAG, e.toString());}
|
||||
} else {
|
||||
Log.w(TAG, "Proxy not attached to service");
|
||||
@@ -295,16 +295,16 @@ public class BluetoothHeadset {
|
||||
* auto-connected.
|
||||
* Incoming connections are ignored regardless of priority if there is
|
||||
* already a headset connected.
|
||||
* @param address Paired headset
|
||||
* @param device paired headset
|
||||
* @param priority Integer priority, for example PRIORITY_AUTO or
|
||||
* PRIORITY_NONE
|
||||
* @return True if successful, false if there was some error.
|
||||
* @return true if successful, false if there was some error
|
||||
*/
|
||||
public boolean setPriority(String address, int priority) {
|
||||
if (DBG) log("setPriority(" + address + ", " + priority + ")");
|
||||
public boolean setPriority(BluetoothDevice device, int priority) {
|
||||
if (DBG) log("setPriority(" + device + ", " + priority + ")");
|
||||
if (mService != null) {
|
||||
try {
|
||||
return mService.setPriority(address, priority);
|
||||
return mService.setPriority(device, priority);
|
||||
} catch (RemoteException e) {Log.e(TAG, e.toString());}
|
||||
} else {
|
||||
Log.w(TAG, "Proxy not attached to service");
|
||||
@@ -315,14 +315,14 @@ public class BluetoothHeadset {
|
||||
|
||||
/**
|
||||
* Get priority of headset.
|
||||
* @param address Headset
|
||||
* @return non-negative priority, or negative error code on error.
|
||||
* @param device headset
|
||||
* @return non-negative priority, or negative error code on error
|
||||
*/
|
||||
public int getPriority(String address) {
|
||||
if (DBG) log("getPriority(" + address + ")");
|
||||
public int getPriority(BluetoothDevice device) {
|
||||
if (DBG) log("getPriority(" + device + ")");
|
||||
if (mService != null) {
|
||||
try {
|
||||
return mService.getPriority(address);
|
||||
return mService.getPriority(device);
|
||||
} catch (RemoteException e) {Log.e(TAG, e.toString());}
|
||||
} else {
|
||||
Log.w(TAG, "Proxy not attached to service");
|
||||
|
||||
@@ -31,8 +31,8 @@ import android.annotation.SdkConstant.SdkConstantType;
|
||||
public interface BluetoothIntent {
|
||||
public static final String SCAN_MODE =
|
||||
"android.bluetooth.intent.SCAN_MODE";
|
||||
public static final String ADDRESS =
|
||||
"android.bluetooth.intent.ADDRESS";
|
||||
public static final String DEVICE =
|
||||
"android.bluetooth.intent.DEVICE";
|
||||
public static final String NAME =
|
||||
"android.bluetooth.intent.NAME";
|
||||
public static final String ALIAS =
|
||||
|
||||
@@ -73,11 +73,11 @@ public class BluetoothPbap {
|
||||
|
||||
/** There was an error trying to obtain the state */
|
||||
public static final int STATE_ERROR = -1;
|
||||
/** No Pce currently connected */
|
||||
/** No client currently connected */
|
||||
public static final int STATE_DISCONNECTED = 0;
|
||||
/** Connection attempt in progress */
|
||||
public static final int STATE_CONNECTING = 1;
|
||||
/** A Pce is currently connected */
|
||||
/** Client is currently connected */
|
||||
public static final int STATE_CONNECTED = 2;
|
||||
|
||||
public static final int RESULT_FAILURE = 0;
|
||||
@@ -159,16 +159,16 @@ public class BluetoothPbap {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Bluetooth address of the current Pce.
|
||||
* @return The Bluetooth address, or null if not in connected or connecting
|
||||
* state, or if this proxy object is not connected to the Pbap
|
||||
* service.
|
||||
* Get the currently connected remote Bluetooth device (PCE).
|
||||
* @return The remote Bluetooth device, or null if not in connected or
|
||||
* connecting state, or if this proxy object is not connected to
|
||||
* the Pbap service.
|
||||
*/
|
||||
public String getPceAddress() {
|
||||
if (DBG) log("getPceAddress()");
|
||||
public BluetoothDevice getClient() {
|
||||
if (DBG) log("getClient()");
|
||||
if (mService != null) {
|
||||
try {
|
||||
return mService.getPceAddress();
|
||||
return mService.getClient();
|
||||
} catch (RemoteException e) {Log.e(TAG, e.toString());}
|
||||
} else {
|
||||
Log.w(TAG, "Proxy not attached to service");
|
||||
@@ -178,15 +178,15 @@ public class BluetoothPbap {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the specified Pcs is connected (does not include
|
||||
* connecting). Returns false if not connected, or if this proxy object
|
||||
* if not currently connected to the Pbap service.
|
||||
* Returns true if the specified Bluetooth device is connected (does not
|
||||
* include connecting). Returns false if not connected, or if this proxy
|
||||
* object is not currently connected to the Pbap service.
|
||||
*/
|
||||
public boolean isConnected(String address) {
|
||||
if (DBG) log("isConnected(" + address + ")");
|
||||
public boolean isConnected(BluetoothDevice device) {
|
||||
if (DBG) log("isConnected(" + device + ")");
|
||||
if (mService != null) {
|
||||
try {
|
||||
return mService.isConnected(address);
|
||||
return mService.isConnected(device);
|
||||
} catch (RemoteException e) {Log.e(TAG, e.toString());}
|
||||
} else {
|
||||
Log.w(TAG, "Proxy not attached to service");
|
||||
@@ -196,15 +196,15 @@ public class BluetoothPbap {
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnects the current Pce. Currently this call blocks, it may soon
|
||||
* be made asynchornous. Returns false if this proxy object is
|
||||
* Disconnects the current Pbap client (PCE). Currently this call blocks,
|
||||
* it may soon be made asynchornous. Returns false if this proxy object is
|
||||
* not currently connected to the Pbap service.
|
||||
*/
|
||||
public boolean disconnectPce() {
|
||||
if (DBG) log("disconnectPce()");
|
||||
public boolean disconnect() {
|
||||
if (DBG) log("disconnect()");
|
||||
if (mService != null) {
|
||||
try {
|
||||
mService.disconnectPce();
|
||||
mService.disconnect();
|
||||
return true;
|
||||
} catch (RemoteException e) {Log.e(TAG, e.toString());}
|
||||
} else {
|
||||
|
||||
@@ -33,72 +33,7 @@ import java.io.IOException;
|
||||
* @hide
|
||||
*/
|
||||
public final class BluetoothServerSocket implements Closeable {
|
||||
private final BluetoothSocket mSocket;
|
||||
|
||||
/**
|
||||
* Construct a listening, secure RFCOMM server socket.
|
||||
* The remote device connecting to this socket will be authenticated and
|
||||
* communication on this socket will be encrypted.
|
||||
* Call #accept to retrieve connections to this socket.
|
||||
* @return An RFCOMM BluetoothServerSocket
|
||||
* @throws IOException On error, for example Bluetooth not available, or
|
||||
* insufficient permissions.
|
||||
*/
|
||||
public static BluetoothServerSocket listenUsingRfcommOn(int port) throws IOException {
|
||||
BluetoothServerSocket socket = new BluetoothServerSocket(
|
||||
BluetoothSocket.TYPE_RFCOMM, true, true, port);
|
||||
try {
|
||||
socket.mSocket.bindListenNative();
|
||||
} catch (IOException e) {
|
||||
try {
|
||||
socket.close();
|
||||
} catch (IOException e2) { }
|
||||
throw e;
|
||||
}
|
||||
return socket;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an unencrypted, unauthenticated, RFCOMM server socket.
|
||||
* Call #accept to retrieve connections to this socket.
|
||||
* @return An RFCOMM BluetoothServerSocket
|
||||
* @throws IOException On error, for example Bluetooth not available, or
|
||||
* insufficient permissions.
|
||||
*/
|
||||
public static BluetoothServerSocket listenUsingInsecureRfcommOn(int port) throws IOException {
|
||||
BluetoothServerSocket socket = new BluetoothServerSocket(
|
||||
BluetoothSocket.TYPE_RFCOMM, false, false, port);
|
||||
try {
|
||||
socket.mSocket.bindListenNative();
|
||||
} catch (IOException e) {
|
||||
try {
|
||||
socket.close();
|
||||
} catch (IOException e2) { }
|
||||
throw e;
|
||||
}
|
||||
return socket;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a SCO server socket.
|
||||
* Call #accept to retrieve connections to this socket.
|
||||
* @return A SCO BluetoothServerSocket
|
||||
* @throws IOException On error, for example Bluetooth not available, or
|
||||
* insufficient permissions.
|
||||
*/
|
||||
public static BluetoothServerSocket listenUsingScoOn() throws IOException {
|
||||
BluetoothServerSocket socket = new BluetoothServerSocket(
|
||||
BluetoothSocket.TYPE_SCO, false, false, -1);
|
||||
try {
|
||||
socket.mSocket.bindListenNative();
|
||||
} catch (IOException e) {
|
||||
try {
|
||||
socket.close();
|
||||
} catch (IOException e2) { }
|
||||
throw e;
|
||||
}
|
||||
return socket;
|
||||
}
|
||||
/*package*/ final BluetoothSocket mSocket;
|
||||
|
||||
/**
|
||||
* Construct a socket for incoming connections.
|
||||
@@ -109,7 +44,7 @@ public final class BluetoothServerSocket implements Closeable {
|
||||
* @throws IOException On error, for example Bluetooth not available, or
|
||||
* insufficient priveleges
|
||||
*/
|
||||
private BluetoothServerSocket(int type, boolean auth, boolean encrypt, int port)
|
||||
/*package*/ BluetoothServerSocket(int type, boolean auth, boolean encrypt, int port)
|
||||
throws IOException {
|
||||
mSocket = new BluetoothSocket(type, -1, auth, encrypt, null, port);
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@ public final class BluetoothSocket implements Closeable {
|
||||
|
||||
private final int mType; /* one of TYPE_RFCOMM etc */
|
||||
private final int mPort; /* RFCOMM channel or L2CAP psm */
|
||||
private final BluetoothDevice mDevice; /* remote device */
|
||||
private final String mAddress; /* remote address */
|
||||
private final boolean mAuth;
|
||||
private final boolean mEncrypt;
|
||||
@@ -51,68 +52,27 @@ public final class BluetoothSocket implements Closeable {
|
||||
private int mSocketData; /* used by native code only */
|
||||
|
||||
/**
|
||||
* Construct a secure RFCOMM socket ready to start an outgoing connection.
|
||||
* Call #connect on the returned #BluetoothSocket to begin the connection.
|
||||
* The remote device will be authenticated and communication on this socket
|
||||
* will be encrypted.
|
||||
* @param address remote Bluetooth address that this socket can connect to
|
||||
* @param port remote port
|
||||
* @return an RFCOMM BluetoothSocket
|
||||
* @throws IOException on error, for example Bluetooth not available, or
|
||||
* insufficient permissions.
|
||||
*/
|
||||
public static BluetoothSocket createRfcommSocket(String address, int port)
|
||||
throws IOException {
|
||||
return new BluetoothSocket(TYPE_RFCOMM, -1, true, true, address, port);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an insecure RFCOMM socket ready to start an outgoing
|
||||
* connection.
|
||||
* Call #connect on the returned #BluetoothSocket to begin the connection.
|
||||
* The remote device will not be authenticated and communication on this
|
||||
* socket will not be encrypted.
|
||||
* @param address remote Bluetooth address that this socket can connect to
|
||||
* @param port remote port
|
||||
* @return An RFCOMM BluetoothSocket
|
||||
* @throws IOException On error, for example Bluetooth not available, or
|
||||
* insufficient permissions.
|
||||
*/
|
||||
public static BluetoothSocket createInsecureRfcommSocket(String address, int port)
|
||||
throws IOException {
|
||||
return new BluetoothSocket(TYPE_RFCOMM, -1, false, false, address, port);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a SCO socket ready to start an outgoing connection.
|
||||
* Call #connect on the returned #BluetoothSocket to begin the connection.
|
||||
* @param address remote Bluetooth address that this socket can connect to
|
||||
* @return a SCO BluetoothSocket
|
||||
* @throws IOException on error, for example Bluetooth not available, or
|
||||
* insufficient permissions.
|
||||
*/
|
||||
public static BluetoothSocket createScoSocket(String address, int port)
|
||||
throws IOException {
|
||||
return new BluetoothSocket(TYPE_SCO, -1, true, true, address, port);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a Bluetooth.
|
||||
* Construct a BluetoothSocket.
|
||||
* @param type type of socket
|
||||
* @param fd fd to use for connected socket, or -1 for a new socket
|
||||
* @param auth require the remote device to be authenticated
|
||||
* @param encrypt require the connection to be encrypted
|
||||
* @param address remote Bluetooth address that this socket can connect to
|
||||
* @param device remote device that this socket can connect to
|
||||
* @param port remote port
|
||||
* @throws IOException On error, for example Bluetooth not available, or
|
||||
* insufficient priveleges
|
||||
*/
|
||||
/*package*/ BluetoothSocket(int type, int fd, boolean auth, boolean encrypt, String address,
|
||||
int port) throws IOException {
|
||||
/*package*/ BluetoothSocket(int type, int fd, boolean auth, boolean encrypt,
|
||||
BluetoothDevice device, int port) throws IOException {
|
||||
mType = type;
|
||||
mAuth = auth;
|
||||
mEncrypt = encrypt;
|
||||
mAddress = address;
|
||||
mDevice = device;
|
||||
if (device == null) {
|
||||
mAddress = null;
|
||||
} else {
|
||||
mAddress = device.getAddress();
|
||||
}
|
||||
mPort = port;
|
||||
if (fd == -1) {
|
||||
initSocketNative();
|
||||
@@ -123,6 +83,22 @@ public final class BluetoothSocket implements Closeable {
|
||||
mOutputStream = new BluetoothOutputStream(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a BluetoothSocket from address.
|
||||
* @param type type of socket
|
||||
* @param fd fd to use for connected socket, or -1 for a new socket
|
||||
* @param auth require the remote device to be authenticated
|
||||
* @param encrypt require the connection to be encrypted
|
||||
* @param address remote device that this socket can connect to
|
||||
* @param port remote port
|
||||
* @throws IOException On error, for example Bluetooth not available, or
|
||||
* insufficient priveleges
|
||||
*/
|
||||
private BluetoothSocket(int type, int fd, boolean auth, boolean encrypt, String address,
|
||||
int port) throws IOException {
|
||||
this(type, fd, auth, encrypt, new BluetoothDevice(address), port);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
try {
|
||||
@@ -154,12 +130,12 @@ public final class BluetoothSocket implements Closeable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the address we are connecting, or connected, to.
|
||||
* @return Bluetooth address, or null if this socket has not yet attempted
|
||||
* Return the remote device we are connecting, or connected, to.
|
||||
* @return remote device, or null if this socket has not yet attempted
|
||||
* or established a connection.
|
||||
*/
|
||||
public String getAddress() {
|
||||
return mAddress;
|
||||
public BluetoothDevice getRemoteDevice() {
|
||||
return mDevice;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -31,7 +31,7 @@ import android.util.Log;
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public class HeadsetBase {
|
||||
public final class HeadsetBase {
|
||||
private static final String TAG = "Bluetooth HeadsetBase";
|
||||
private static final boolean DBG = false;
|
||||
|
||||
@@ -42,8 +42,9 @@ public class HeadsetBase {
|
||||
|
||||
private static int sAtInputCount = 0; /* TODO: Consider not using a static variable */
|
||||
|
||||
private final BluetoothDevice mBluetooth;
|
||||
private final String mAddress;
|
||||
private final BluetoothAdapter mAdapter;
|
||||
private final BluetoothDevice mRemoteDevice;
|
||||
private final String mAddress; // for native code
|
||||
private final int mRfcommChannel;
|
||||
private int mNativeData;
|
||||
private Thread mEventThread;
|
||||
@@ -73,12 +74,13 @@ public class HeadsetBase {
|
||||
|
||||
private native void cleanupNativeDataNative();
|
||||
|
||||
public HeadsetBase(PowerManager pm, BluetoothDevice bluetooth, String address,
|
||||
int rfcommChannel) {
|
||||
public HeadsetBase(PowerManager pm, BluetoothAdapter adapter, BluetoothDevice device,
|
||||
int rfcommChannel) {
|
||||
mDirection = DIRECTION_OUTGOING;
|
||||
mConnectTimestamp = System.currentTimeMillis();
|
||||
mBluetooth = bluetooth;
|
||||
mAddress = address;
|
||||
mAdapter = adapter;
|
||||
mRemoteDevice = device;
|
||||
mAddress = device.getAddress();
|
||||
mRfcommChannel = rfcommChannel;
|
||||
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "HeadsetBase");
|
||||
mWakeLock.setReferenceCounted(false);
|
||||
@@ -88,12 +90,13 @@ public class HeadsetBase {
|
||||
}
|
||||
|
||||
/* Create from an already exisiting rfcomm connection */
|
||||
public HeadsetBase(PowerManager pm, BluetoothDevice bluetooth, String address, int socketFd,
|
||||
int rfcommChannel, Handler handler) {
|
||||
public HeadsetBase(PowerManager pm, BluetoothAdapter adapter, BluetoothDevice device,
|
||||
int socketFd, int rfcommChannel, Handler handler) {
|
||||
mDirection = DIRECTION_INCOMING;
|
||||
mConnectTimestamp = System.currentTimeMillis();
|
||||
mBluetooth = bluetooth;
|
||||
mAddress = address;
|
||||
mAdapter = adapter;
|
||||
mRemoteDevice = device;
|
||||
mAddress = device.getAddress();
|
||||
mRfcommChannel = rfcommChannel;
|
||||
mEventThreadHandler = handler;
|
||||
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "HeadsetBase");
|
||||
@@ -252,12 +255,8 @@ public class HeadsetBase {
|
||||
return mEventThread != null;
|
||||
}
|
||||
|
||||
public String getAddress() {
|
||||
return mAddress;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return mBluetooth.getRemoteName(mAddress);
|
||||
public BluetoothDevice getRemoteDevice() {
|
||||
return mRemoteDevice;
|
||||
}
|
||||
|
||||
public int getDirection() {
|
||||
|
||||
@@ -21,7 +21,7 @@ package android.bluetooth;
|
||||
*
|
||||
* {@hide}
|
||||
*/
|
||||
interface IBluetoothDevice
|
||||
interface IBluetooth
|
||||
{
|
||||
boolean isEnabled();
|
||||
int getBluetoothState();
|
||||
@@ -16,16 +16,18 @@
|
||||
|
||||
package android.bluetooth;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
|
||||
/**
|
||||
* System private API for Bluetooth A2DP service
|
||||
*
|
||||
* {@hide}
|
||||
*/
|
||||
interface IBluetoothA2dp {
|
||||
int connectSink(in String address);
|
||||
int disconnectSink(in String address);
|
||||
List<String> listConnectedSinks();
|
||||
int getSinkState(in String address);
|
||||
int setSinkPriority(in String address, int priority);
|
||||
int getSinkPriority(in String address);
|
||||
int connectSink(in BluetoothDevice device);
|
||||
int disconnectSink(in BluetoothDevice device);
|
||||
BluetoothDevice[] getConnectedSinks(); // change to Set<> once AIDL supports
|
||||
int getSinkState(in BluetoothDevice device);
|
||||
int setSinkPriority(in BluetoothDevice device, int priority);
|
||||
int getSinkPriority(in BluetoothDevice device);
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package android.bluetooth;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
|
||||
/**
|
||||
* System private API for Bluetooth Headset service
|
||||
*
|
||||
@@ -23,13 +25,13 @@ package android.bluetooth;
|
||||
*/
|
||||
interface IBluetoothHeadset {
|
||||
int getState();
|
||||
String getHeadsetAddress();
|
||||
boolean connectHeadset(in String address);
|
||||
BluetoothDevice getCurrentHeadset();
|
||||
boolean connectHeadset(in BluetoothDevice device);
|
||||
void disconnectHeadset();
|
||||
boolean isConnected(in String address);
|
||||
boolean isConnected(in BluetoothDevice device);
|
||||
boolean startVoiceRecognition();
|
||||
boolean stopVoiceRecognition();
|
||||
boolean setPriority(in String address, int priority);
|
||||
int getPriority(in String address);
|
||||
boolean setPriority(in BluetoothDevice device, int priority);
|
||||
int getPriority(in BluetoothDevice device);
|
||||
int getBatteryUsageHint();
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package android.bluetooth;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
|
||||
/**
|
||||
* System private API for Bluetooth pbap service
|
||||
*
|
||||
@@ -23,8 +25,8 @@ package android.bluetooth;
|
||||
*/
|
||||
interface IBluetoothPbap {
|
||||
int getState();
|
||||
String getPceAddress();
|
||||
boolean connectPce(in String address);
|
||||
void disconnectPce();
|
||||
boolean isConnected(in String address);
|
||||
BluetoothDevice getClient();
|
||||
boolean connect(in BluetoothDevice device);
|
||||
void disconnect();
|
||||
boolean isConnected(in BluetoothDevice device);
|
||||
}
|
||||
|
||||
@@ -1144,10 +1144,10 @@ public abstract class Context {
|
||||
public static final String SENSOR_SERVICE = "sensor";
|
||||
/**
|
||||
* Use with {@link #getSystemService} to retrieve a {@link
|
||||
* android.bluetooth.BluetoothDevice} for interacting with Bluetooth.
|
||||
* android.bluetooth.BluetoothAdapter} for using Bluetooth.
|
||||
*
|
||||
* @see #getSystemService
|
||||
* @see android.bluetooth.BluetoothDevice
|
||||
* @see android.bluetooth.BluetoothAdapter
|
||||
* @hide
|
||||
*/
|
||||
public static final String BLUETOOTH_SERVICE = "bluetooth";
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
package android.server;
|
||||
|
||||
import android.bluetooth.BluetoothA2dp;
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothError;
|
||||
import android.bluetooth.BluetoothIntent;
|
||||
@@ -40,9 +41,9 @@ import android.util.Log;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
|
||||
@@ -67,26 +68,27 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
|
||||
|
||||
private static int mSinkCount;
|
||||
|
||||
|
||||
private final Context mContext;
|
||||
private final IntentFilter mIntentFilter;
|
||||
private HashMap<String, Integer> mAudioDevices;
|
||||
private HashMap<BluetoothDevice, Integer> mAudioDevices;
|
||||
private final AudioManager mAudioManager;
|
||||
private final BluetoothDeviceService mBluetoothService;
|
||||
private final BluetoothService mBluetoothService;
|
||||
private final BluetoothAdapter mAdapter;
|
||||
|
||||
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
String action = intent.getAction();
|
||||
String address = intent.getStringExtra(BluetoothIntent.ADDRESS);
|
||||
BluetoothDevice device =
|
||||
intent.getParcelableExtra(BluetoothIntent.DEVICE);
|
||||
if (action.equals(BluetoothIntent.BLUETOOTH_STATE_CHANGED_ACTION)) {
|
||||
int state = intent.getIntExtra(BluetoothIntent.BLUETOOTH_STATE,
|
||||
BluetoothError.ERROR);
|
||||
switch (state) {
|
||||
case BluetoothDevice.BLUETOOTH_STATE_ON:
|
||||
case BluetoothAdapter.BLUETOOTH_STATE_ON:
|
||||
onBluetoothEnable();
|
||||
break;
|
||||
case BluetoothDevice.BLUETOOTH_STATE_TURNING_OFF:
|
||||
case BluetoothAdapter.BLUETOOTH_STATE_TURNING_OFF:
|
||||
onBluetoothDisable();
|
||||
break;
|
||||
}
|
||||
@@ -95,28 +97,28 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
|
||||
BluetoothError.ERROR);
|
||||
switch(bondState) {
|
||||
case BluetoothDevice.BOND_BONDED:
|
||||
setSinkPriority(address, BluetoothA2dp.PRIORITY_AUTO);
|
||||
setSinkPriority(device, BluetoothA2dp.PRIORITY_AUTO);
|
||||
break;
|
||||
case BluetoothDevice.BOND_BONDING:
|
||||
case BluetoothDevice.BOND_NOT_BONDED:
|
||||
setSinkPriority(address, BluetoothA2dp.PRIORITY_OFF);
|
||||
setSinkPriority(device, BluetoothA2dp.PRIORITY_OFF);
|
||||
break;
|
||||
}
|
||||
} else if (action.equals(BluetoothIntent.REMOTE_DEVICE_CONNECTED_ACTION)) {
|
||||
if (getSinkPriority(address) > BluetoothA2dp.PRIORITY_OFF &&
|
||||
isSinkDevice(address)) {
|
||||
if (getSinkPriority(device) > BluetoothA2dp.PRIORITY_OFF &&
|
||||
isSinkDevice(device)) {
|
||||
// This device is a preferred sink. Make an A2DP connection
|
||||
// after a delay. We delay to avoid connection collisions,
|
||||
// and to give other profiles such as HFP a chance to
|
||||
// connect first.
|
||||
Message msg = Message.obtain(mHandler, MESSAGE_CONNECT_TO, address);
|
||||
Message msg = Message.obtain(mHandler, MESSAGE_CONNECT_TO, device);
|
||||
mHandler.sendMessageDelayed(msg, 6000);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public BluetoothA2dpService(Context context, BluetoothDeviceService bluetoothService) {
|
||||
public BluetoothA2dpService(Context context, BluetoothService bluetoothService) {
|
||||
mContext = context;
|
||||
|
||||
mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
|
||||
@@ -130,12 +132,14 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
|
||||
throw new RuntimeException("Could not init BluetoothA2dpService");
|
||||
}
|
||||
|
||||
mAdapter = (BluetoothAdapter) context.getSystemService(Context.BLUETOOTH_SERVICE);
|
||||
|
||||
mIntentFilter = new IntentFilter(BluetoothIntent.BLUETOOTH_STATE_CHANGED_ACTION);
|
||||
mIntentFilter.addAction(BluetoothIntent.BOND_STATE_CHANGED_ACTION);
|
||||
mIntentFilter.addAction(BluetoothIntent.REMOTE_DEVICE_CONNECTED_ACTION);
|
||||
mContext.registerReceiver(mReceiver, mIntentFilter);
|
||||
|
||||
mAudioDevices = new HashMap<String, Integer>();
|
||||
mAudioDevices = new HashMap<BluetoothDevice, Integer>();
|
||||
|
||||
if (mBluetoothService.isEnabled())
|
||||
onBluetoothEnable();
|
||||
@@ -155,18 +159,18 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
|
||||
public void handleMessage(Message msg) {
|
||||
switch (msg.what) {
|
||||
case MESSAGE_CONNECT_TO:
|
||||
String address = (String)msg.obj;
|
||||
BluetoothDevice device = (BluetoothDevice) msg.obj;
|
||||
// check bluetooth is still on, device is still preferred, and
|
||||
// nothing is currently connected
|
||||
if (mBluetoothService.isEnabled() &&
|
||||
getSinkPriority(address) > BluetoothA2dp.PRIORITY_OFF &&
|
||||
getSinkPriority(device) > BluetoothA2dp.PRIORITY_OFF &&
|
||||
lookupSinksMatchingStates(new int[] {
|
||||
BluetoothA2dp.STATE_CONNECTING,
|
||||
BluetoothA2dp.STATE_CONNECTED,
|
||||
BluetoothA2dp.STATE_PLAYING,
|
||||
BluetoothA2dp.STATE_DISCONNECTING}).size() == 0) {
|
||||
log("Auto-connecting A2DP to sink " + address);
|
||||
connectSink(address);
|
||||
log("Auto-connecting A2DP to sink " + device);
|
||||
connectSink(device);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -185,8 +189,8 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
|
||||
return -1;
|
||||
}
|
||||
|
||||
private boolean isSinkDevice(String address) {
|
||||
String uuids[] = mBluetoothService.getRemoteUuids(address);
|
||||
private boolean isSinkDevice(BluetoothDevice device) {
|
||||
String uuids[] = mBluetoothService.getRemoteUuids(device.getAddress());
|
||||
UUID uuid;
|
||||
if (uuids != null) {
|
||||
for (String deviceUuid: uuids) {
|
||||
@@ -199,11 +203,11 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
|
||||
return false;
|
||||
}
|
||||
|
||||
private synchronized boolean addAudioSink (String address) {
|
||||
String path = mBluetoothService.getObjectPathFromAddress(address);
|
||||
private synchronized boolean addAudioSink (BluetoothDevice device) {
|
||||
String path = mBluetoothService.getObjectPathFromAddress(device.getAddress());
|
||||
String propValues[] = (String []) getSinkPropertiesNative(path);
|
||||
if (propValues == null) {
|
||||
Log.e(TAG, "Error while getting AudioSink properties for device: " + address);
|
||||
Log.e(TAG, "Error while getting AudioSink properties for device: " + device);
|
||||
return false;
|
||||
}
|
||||
Integer state = null;
|
||||
@@ -214,8 +218,8 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
|
||||
break;
|
||||
}
|
||||
}
|
||||
mAudioDevices.put(address, state);
|
||||
handleSinkStateChange(address, BluetoothA2dp.STATE_DISCONNECTED, state);
|
||||
mAudioDevices.put(device, state);
|
||||
handleSinkStateChange(device, BluetoothA2dp.STATE_DISCONNECTED, state);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -226,6 +230,7 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
|
||||
String [] paths = devices.split(",");
|
||||
for (String path: paths) {
|
||||
String address = mBluetoothService.getAddressFromObjectPath(path);
|
||||
BluetoothDevice device = mAdapter.getRemoteDevice(address);
|
||||
String []uuids = mBluetoothService.getRemoteUuids(address);
|
||||
if (uuids != null)
|
||||
for (String uuid: uuids) {
|
||||
@@ -233,7 +238,7 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
|
||||
if (BluetoothUuid.isAudioSink(remoteUuid) ||
|
||||
BluetoothUuid.isAudioSource(remoteUuid) ||
|
||||
BluetoothUuid.isAdvAudioDist(remoteUuid)) {
|
||||
addAudioSink(address);
|
||||
addAudioSink(device);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -244,36 +249,34 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
|
||||
|
||||
private synchronized void onBluetoothDisable() {
|
||||
if (!mAudioDevices.isEmpty()) {
|
||||
String [] addresses = new String[mAudioDevices.size()];
|
||||
addresses = mAudioDevices.keySet().toArray(addresses);
|
||||
for (String address : addresses) {
|
||||
int state = getSinkState(address);
|
||||
BluetoothDevice[] devices = new BluetoothDevice[mAudioDevices.size()];
|
||||
devices = mAudioDevices.keySet().toArray(devices);
|
||||
for (BluetoothDevice device : devices) {
|
||||
int state = getSinkState(device);
|
||||
switch (state) {
|
||||
case BluetoothA2dp.STATE_CONNECTING:
|
||||
case BluetoothA2dp.STATE_CONNECTED:
|
||||
case BluetoothA2dp.STATE_PLAYING:
|
||||
disconnectSinkNative(mBluetoothService.getObjectPathFromAddress(address));
|
||||
handleSinkStateChange(address,state, BluetoothA2dp.STATE_DISCONNECTED);
|
||||
disconnectSinkNative(mBluetoothService.getObjectPathFromAddress(
|
||||
device.getAddress()));
|
||||
handleSinkStateChange(device, state, BluetoothA2dp.STATE_DISCONNECTED);
|
||||
break;
|
||||
case BluetoothA2dp.STATE_DISCONNECTING:
|
||||
handleSinkStateChange(address, BluetoothA2dp.STATE_DISCONNECTING,
|
||||
BluetoothA2dp.STATE_DISCONNECTED);
|
||||
handleSinkStateChange(device, BluetoothA2dp.STATE_DISCONNECTING,
|
||||
BluetoothA2dp.STATE_DISCONNECTED);
|
||||
break;
|
||||
}
|
||||
}
|
||||
mAudioDevices.clear();
|
||||
}
|
||||
|
||||
mAudioManager.setParameters(BLUETOOTH_ENABLED+"=false");
|
||||
mAudioManager.setParameters(BLUETOOTH_ENABLED + "=false");
|
||||
}
|
||||
|
||||
public synchronized int connectSink(String address) {
|
||||
public synchronized int connectSink(BluetoothDevice device) {
|
||||
mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
|
||||
"Need BLUETOOTH_ADMIN permission");
|
||||
if (DBG) log("connectSink(" + address + ")");
|
||||
if (!BluetoothDevice.checkBluetoothAddress(address)) {
|
||||
return BluetoothError.ERROR;
|
||||
}
|
||||
if (DBG) log("connectSink(" + device + ")");
|
||||
|
||||
// ignore if there are any active sinks
|
||||
if (lookupSinksMatchingStates(new int[] {
|
||||
@@ -284,10 +287,10 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
|
||||
return BluetoothError.ERROR;
|
||||
}
|
||||
|
||||
if (mAudioDevices.get(address) == null && !addAudioSink(address))
|
||||
if (mAudioDevices.get(device) == null && !addAudioSink(device))
|
||||
return BluetoothError.ERROR;
|
||||
|
||||
int state = mAudioDevices.get(address);
|
||||
int state = mAudioDevices.get(device);
|
||||
|
||||
switch (state) {
|
||||
case BluetoothA2dp.STATE_CONNECTED:
|
||||
@@ -298,7 +301,7 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
|
||||
return BluetoothError.SUCCESS;
|
||||
}
|
||||
|
||||
String path = mBluetoothService.getObjectPathFromAddress(address);
|
||||
String path = mBluetoothService.getObjectPathFromAddress(device.getAddress());
|
||||
if (path == null)
|
||||
return BluetoothError.ERROR;
|
||||
|
||||
@@ -309,19 +312,17 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
|
||||
return BluetoothError.SUCCESS;
|
||||
}
|
||||
|
||||
public synchronized int disconnectSink(String address) {
|
||||
public synchronized int disconnectSink(BluetoothDevice device) {
|
||||
mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
|
||||
"Need BLUETOOTH_ADMIN permission");
|
||||
if (DBG) log("disconnectSink(" + address + ")");
|
||||
if (!BluetoothDevice.checkBluetoothAddress(address)) {
|
||||
return BluetoothError.ERROR;
|
||||
}
|
||||
String path = mBluetoothService.getObjectPathFromAddress(address);
|
||||
if (DBG) log("disconnectSink(" + device + ")");
|
||||
|
||||
String path = mBluetoothService.getObjectPathFromAddress(device.getAddress());
|
||||
if (path == null) {
|
||||
return BluetoothError.ERROR;
|
||||
}
|
||||
|
||||
switch (getSinkState(address)) {
|
||||
switch (getSinkState(device)) {
|
||||
case BluetoothA2dp.STATE_DISCONNECTED:
|
||||
return BluetoothError.ERROR;
|
||||
case BluetoothA2dp.STATE_DISCONNECTING:
|
||||
@@ -336,41 +337,36 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized List<String> listConnectedSinks() {
|
||||
public synchronized BluetoothDevice[] getConnectedSinks() {
|
||||
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
|
||||
return lookupSinksMatchingStates(new int[] {BluetoothA2dp.STATE_CONNECTED,
|
||||
BluetoothA2dp.STATE_PLAYING});
|
||||
Set<BluetoothDevice> sinks = lookupSinksMatchingStates(
|
||||
new int[] {BluetoothA2dp.STATE_CONNECTED, BluetoothA2dp.STATE_PLAYING});
|
||||
return sinks.toArray(new BluetoothDevice[sinks.size()]);
|
||||
}
|
||||
|
||||
public synchronized int getSinkState(String address) {
|
||||
public synchronized int getSinkState(BluetoothDevice device) {
|
||||
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
|
||||
if (!BluetoothDevice.checkBluetoothAddress(address)) {
|
||||
return BluetoothError.ERROR;
|
||||
}
|
||||
Integer state = mAudioDevices.get(address);
|
||||
Integer state = mAudioDevices.get(device);
|
||||
if (state == null)
|
||||
return BluetoothA2dp.STATE_DISCONNECTED;
|
||||
return state;
|
||||
}
|
||||
|
||||
public synchronized int getSinkPriority(String address) {
|
||||
public synchronized int getSinkPriority(BluetoothDevice device) {
|
||||
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
|
||||
if (!BluetoothDevice.checkBluetoothAddress(address)) {
|
||||
return BluetoothError.ERROR;
|
||||
}
|
||||
return Settings.Secure.getInt(mContext.getContentResolver(),
|
||||
Settings.Secure.getBluetoothA2dpSinkPriorityKey(address),
|
||||
Settings.Secure.getBluetoothA2dpSinkPriorityKey(device.getAddress()),
|
||||
BluetoothA2dp.PRIORITY_OFF);
|
||||
}
|
||||
|
||||
public synchronized int setSinkPriority(String address, int priority) {
|
||||
public synchronized int setSinkPriority(BluetoothDevice device, int priority) {
|
||||
mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
|
||||
"Need BLUETOOTH_ADMIN permission");
|
||||
if (!BluetoothDevice.checkBluetoothAddress(address)) {
|
||||
if (!BluetoothDevice.checkBluetoothAddress(device.getAddress())) {
|
||||
return BluetoothError.ERROR;
|
||||
}
|
||||
return Settings.Secure.putInt(mContext.getContentResolver(),
|
||||
Settings.Secure.getBluetoothA2dpSinkPriorityKey(address), priority) ?
|
||||
Settings.Secure.getBluetoothA2dpSinkPriorityKey(device.getAddress()), priority) ?
|
||||
BluetoothError.SUCCESS : BluetoothError.ERROR;
|
||||
}
|
||||
|
||||
@@ -386,20 +382,22 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
|
||||
return;
|
||||
}
|
||||
|
||||
BluetoothDevice device = mAdapter.getRemoteDevice(address);
|
||||
|
||||
if (name.equals(PROPERTY_STATE)) {
|
||||
int state = convertBluezSinkStringtoState(propValues[1]);
|
||||
if (mAudioDevices.get(address) == null) {
|
||||
if (mAudioDevices.get(device) == null) {
|
||||
// This is for an incoming connection for a device not known to us.
|
||||
// We have authorized it and bluez state has changed.
|
||||
addAudioSink(address);
|
||||
addAudioSink(device);
|
||||
} else {
|
||||
int prevState = mAudioDevices.get(address);
|
||||
handleSinkStateChange(address, prevState, state);
|
||||
int prevState = mAudioDevices.get(device);
|
||||
handleSinkStateChange(device, prevState, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleSinkStateChange(String address, int prevState, int state) {
|
||||
private void handleSinkStateChange(BluetoothDevice device, int prevState, int state) {
|
||||
if (state != prevState) {
|
||||
if (state == BluetoothA2dp.STATE_DISCONNECTED ||
|
||||
state == BluetoothA2dp.STATE_DISCONNECTING) {
|
||||
@@ -413,28 +411,28 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
|
||||
} else if (state == BluetoothA2dp.STATE_CONNECTED) {
|
||||
mSinkCount ++;
|
||||
}
|
||||
mAudioDevices.put(address, state);
|
||||
mAudioDevices.put(device, state);
|
||||
|
||||
Intent intent = new Intent(BluetoothA2dp.SINK_STATE_CHANGED_ACTION);
|
||||
intent.putExtra(BluetoothIntent.ADDRESS, address);
|
||||
intent.putExtra(BluetoothIntent.DEVICE, device);
|
||||
intent.putExtra(BluetoothA2dp.SINK_PREVIOUS_STATE, prevState);
|
||||
intent.putExtra(BluetoothA2dp.SINK_STATE, state);
|
||||
mContext.sendBroadcast(intent, BLUETOOTH_PERM);
|
||||
|
||||
if (DBG) log("A2DP state : address: " + address + " State:" + prevState + "->" + state);
|
||||
if (DBG) log("A2DP state : device: " + device + " State:" + prevState + "->" + state);
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized List<String> lookupSinksMatchingStates(int[] states) {
|
||||
List<String> sinks = new ArrayList<String>();
|
||||
private synchronized Set<BluetoothDevice> lookupSinksMatchingStates(int[] states) {
|
||||
Set<BluetoothDevice> sinks = new HashSet<BluetoothDevice>();
|
||||
if (mAudioDevices.isEmpty()) {
|
||||
return sinks;
|
||||
}
|
||||
for (String path: mAudioDevices.keySet()) {
|
||||
int sinkState = getSinkState(path);
|
||||
for (BluetoothDevice device: mAudioDevices.keySet()) {
|
||||
int sinkState = getSinkState(device);
|
||||
for (int state : states) {
|
||||
if (state == sinkState) {
|
||||
sinks.add(path);
|
||||
sinks.add(device);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -446,9 +444,9 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
|
||||
protected synchronized void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
|
||||
if (mAudioDevices.isEmpty()) return;
|
||||
pw.println("Cached audio devices:");
|
||||
for (String address : mAudioDevices.keySet()) {
|
||||
int state = mAudioDevices.get(address);
|
||||
pw.println(address + " " + BluetoothA2dp.stateToString(state));
|
||||
for (BluetoothDevice device : mAudioDevices.keySet()) {
|
||||
int state = mAudioDevices.get(device);
|
||||
pw.println(device + " " + BluetoothA2dp.stateToString(state));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ package android.server;
|
||||
|
||||
import android.bluetooth.BluetoothA2dp;
|
||||
import android.bluetooth.BluetoothClass;
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothError;
|
||||
import android.bluetooth.BluetoothIntent;
|
||||
@@ -46,8 +47,10 @@ class BluetoothEventLoop {
|
||||
private Thread mThread;
|
||||
private boolean mStarted;
|
||||
private boolean mInterrupted;
|
||||
|
||||
private final HashMap<String, Integer> mPasskeyAgentRequestData;
|
||||
private final BluetoothDeviceService mBluetoothService;
|
||||
private final BluetoothService mBluetoothService;
|
||||
private final BluetoothAdapter mAdapter;
|
||||
private final Context mContext;
|
||||
|
||||
private static final int EVENT_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY = 1;
|
||||
@@ -84,10 +87,12 @@ class BluetoothEventLoop {
|
||||
static { classInitNative(); }
|
||||
private static native void classInitNative();
|
||||
|
||||
/* pacakge */ BluetoothEventLoop(Context context, BluetoothDeviceService bluetoothService) {
|
||||
/* pacakge */ BluetoothEventLoop(Context context, BluetoothAdapter adapter,
|
||||
BluetoothService bluetoothService) {
|
||||
mBluetoothService = bluetoothService;
|
||||
mContext = context;
|
||||
mPasskeyAgentRequestData = new HashMap();
|
||||
mAdapter = adapter;
|
||||
initializeNativeDataNative();
|
||||
}
|
||||
|
||||
@@ -137,7 +142,7 @@ class BluetoothEventLoop {
|
||||
}
|
||||
if (classValue != null) {
|
||||
Intent intent = new Intent(BluetoothIntent.REMOTE_DEVICE_FOUND_ACTION);
|
||||
intent.putExtra(BluetoothIntent.ADDRESS, address);
|
||||
intent.putExtra(BluetoothIntent.DEVICE, mAdapter.getRemoteDevice(address));
|
||||
intent.putExtra(BluetoothIntent.CLASS, Integer.valueOf(classValue));
|
||||
intent.putExtra(BluetoothIntent.RSSI, rssiValue);
|
||||
intent.putExtra(BluetoothIntent.NAME, name);
|
||||
@@ -158,7 +163,7 @@ class BluetoothEventLoop {
|
||||
|
||||
private void onDeviceDisappeared(String address) {
|
||||
Intent intent = new Intent(BluetoothIntent.REMOTE_DEVICE_DISAPPEARED_ACTION);
|
||||
intent.putExtra(BluetoothIntent.ADDRESS, address);
|
||||
intent.putExtra(BluetoothIntent.DEVICE, mAdapter.getRemoteDevice(address));
|
||||
mContext.sendBroadcast(intent, BLUETOOTH_PERM);
|
||||
}
|
||||
|
||||
@@ -251,7 +256,7 @@ class BluetoothEventLoop {
|
||||
if (pairable == null || discoverable == null)
|
||||
return;
|
||||
|
||||
int mode = BluetoothDeviceService.bluezStringToScanMode(
|
||||
int mode = BluetoothService.bluezStringToScanMode(
|
||||
pairable.equals("true"),
|
||||
discoverable.equals("true"));
|
||||
if (mode >= 0) {
|
||||
@@ -299,15 +304,16 @@ class BluetoothEventLoop {
|
||||
Log.e(TAG, "onDevicePropertyChanged: Address of the remote device in null");
|
||||
return;
|
||||
}
|
||||
BluetoothDevice device = mAdapter.getRemoteDevice(address);
|
||||
if (name.equals("Name")) {
|
||||
Intent intent = new Intent(BluetoothIntent.REMOTE_NAME_UPDATED_ACTION);
|
||||
intent.putExtra(BluetoothIntent.ADDRESS, address);
|
||||
intent.putExtra(BluetoothIntent.DEVICE, device);
|
||||
intent.putExtra(BluetoothIntent.NAME, propValues[1]);
|
||||
mContext.sendBroadcast(intent, BLUETOOTH_PERM);
|
||||
mBluetoothService.setRemoteDeviceProperty(address, name, propValues[1]);
|
||||
} else if (name.equals("Class")) {
|
||||
Intent intent = new Intent(BluetoothIntent.REMOTE_DEVICE_CLASS_UPDATED_ACTION);
|
||||
intent.putExtra(BluetoothIntent.ADDRESS, address);
|
||||
intent.putExtra(BluetoothIntent.DEVICE, device);
|
||||
intent.putExtra(BluetoothIntent.CLASS, propValues[1]);
|
||||
mContext.sendBroadcast(intent, BLUETOOTH_PERM);
|
||||
mBluetoothService.setRemoteDeviceProperty(address, name, propValues[1]);
|
||||
@@ -318,7 +324,7 @@ class BluetoothEventLoop {
|
||||
} else {
|
||||
intent = new Intent(BluetoothIntent.REMOTE_DEVICE_DISCONNECTED_ACTION);
|
||||
}
|
||||
intent.putExtra(BluetoothIntent.ADDRESS, address);
|
||||
intent.putExtra(BluetoothIntent.DEVICE, device);
|
||||
mContext.sendBroadcast(intent, BLUETOOTH_PERM);
|
||||
mBluetoothService.setRemoteDeviceProperty(address, name, propValues[1]);
|
||||
} else if (name.equals("UUIDs")) {
|
||||
@@ -351,7 +357,7 @@ class BluetoothEventLoop {
|
||||
address = address.toUpperCase();
|
||||
mPasskeyAgentRequestData.put(address, new Integer(nativeData));
|
||||
|
||||
if (mBluetoothService.getBluetoothState() == BluetoothDevice.BLUETOOTH_STATE_TURNING_OFF) {
|
||||
if (mBluetoothService.getBluetoothState() == BluetoothAdapter.BLUETOOTH_STATE_TURNING_OFF) {
|
||||
// shutdown path
|
||||
mBluetoothService.cancelPairingUserInput(address);
|
||||
return null;
|
||||
@@ -364,7 +370,7 @@ class BluetoothEventLoop {
|
||||
if (address == null) return;
|
||||
|
||||
Intent intent = new Intent(BluetoothIntent.PAIRING_REQUEST_ACTION);
|
||||
intent.putExtra(BluetoothIntent.ADDRESS, address);
|
||||
intent.putExtra(BluetoothIntent.DEVICE, mAdapter.getRemoteDevice(address));
|
||||
intent.putExtra(BluetoothIntent.PASSKEY, passkey);
|
||||
intent.putExtra(BluetoothIntent.PAIRING_VARIANT,
|
||||
BluetoothDevice.PAIRING_VARIANT_CONFIRMATION);
|
||||
@@ -377,7 +383,7 @@ class BluetoothEventLoop {
|
||||
if (address == null) return;
|
||||
|
||||
Intent intent = new Intent(BluetoothIntent.PAIRING_REQUEST_ACTION);
|
||||
intent.putExtra(BluetoothIntent.ADDRESS, address);
|
||||
intent.putExtra(BluetoothIntent.DEVICE, mAdapter.getRemoteDevice(address));
|
||||
intent.putExtra(BluetoothIntent.PAIRING_VARIANT, BluetoothDevice.PAIRING_VARIANT_PASSKEY);
|
||||
mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
|
||||
return;
|
||||
@@ -409,7 +415,7 @@ class BluetoothEventLoop {
|
||||
}
|
||||
}
|
||||
Intent intent = new Intent(BluetoothIntent.PAIRING_REQUEST_ACTION);
|
||||
intent.putExtra(BluetoothIntent.ADDRESS, address);
|
||||
intent.putExtra(BluetoothIntent.DEVICE, mAdapter.getRemoteDevice(address));
|
||||
intent.putExtra(BluetoothIntent.PAIRING_VARIANT, BluetoothDevice.PAIRING_VARIANT_PIN);
|
||||
mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
|
||||
return;
|
||||
@@ -428,7 +434,8 @@ class BluetoothEventLoop {
|
||||
(BluetoothUuid.isAudioSink(uuid) || BluetoothUuid.isAvrcpController(uuid)
|
||||
|| BluetoothUuid.isAdvAudioDist(uuid))) {
|
||||
BluetoothA2dp a2dp = new BluetoothA2dp(mContext);
|
||||
authorized = a2dp.getSinkPriority(address) > BluetoothA2dp.PRIORITY_OFF;
|
||||
BluetoothDevice device = mAdapter.getRemoteDevice(address);
|
||||
authorized = a2dp.getSinkPriority(device) > BluetoothA2dp.PRIORITY_OFF;
|
||||
if (authorized) {
|
||||
Log.i(TAG, "Allowing incoming A2DP / AVRCP connection from " + address);
|
||||
} else {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
/**
|
||||
* TODO: Move this to
|
||||
* java/services/com/android/server/BluetoothDeviceService.java
|
||||
* java/services/com/android/server/BluetoothService.java
|
||||
* and make the contructor package private again.
|
||||
*
|
||||
* @hide
|
||||
@@ -25,11 +25,12 @@
|
||||
package android.server;
|
||||
|
||||
import android.bluetooth.BluetoothClass;
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothError;
|
||||
import android.bluetooth.BluetoothHeadset;
|
||||
import android.bluetooth.BluetoothIntent;
|
||||
import android.bluetooth.IBluetoothDevice;
|
||||
import android.bluetooth.IBluetooth;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
@@ -55,8 +56,8 @@ import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
public class BluetoothDeviceService extends IBluetoothDevice.Stub {
|
||||
private static final String TAG = "BluetoothDeviceService";
|
||||
public class BluetoothService extends IBluetooth.Stub {
|
||||
private static final String TAG = "BluetoothService";
|
||||
private static final boolean DBG = true;
|
||||
|
||||
private int mNativeData;
|
||||
@@ -65,11 +66,11 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
|
||||
private boolean mIsAirplaneSensitive;
|
||||
private int mBluetoothState;
|
||||
private boolean mRestart = false; // need to call enable() after disable()
|
||||
|
||||
private final BondState mBondState = new BondState(); // local cache of bondings
|
||||
private boolean mIsDiscovering;
|
||||
private final IBatteryStats mBatteryStats;
|
||||
|
||||
private BluetoothAdapter mAdapter; // constant after init()
|
||||
private final BondState mBondState = new BondState(); // local cache of bondings
|
||||
private final IBatteryStats mBatteryStats;
|
||||
private final Context mContext;
|
||||
|
||||
private static final String BLUETOOTH_ADMIN_PERM = android.Manifest.permission.BLUETOOTH_ADMIN;
|
||||
@@ -78,14 +79,14 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
|
||||
private static final int MESSAGE_REGISTER_SDP_RECORDS = 1;
|
||||
private static final int MESSAGE_FINISH_DISABLE = 2;
|
||||
|
||||
private Map<String, String> mProperties;
|
||||
private HashMap <String, Map<String, String>> mRemoteDeviceProperties;
|
||||
private final Map<String, String> mAdapterProperties;
|
||||
private final HashMap <String, Map<String, String>> mDeviceProperties;
|
||||
|
||||
static {
|
||||
classInitNative();
|
||||
}
|
||||
|
||||
public BluetoothDeviceService(Context context) {
|
||||
public BluetoothService(Context context) {
|
||||
mContext = context;
|
||||
|
||||
// Need to do this in place of:
|
||||
@@ -93,11 +94,7 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
|
||||
// Since we can not import BatteryStatsService from here. This class really needs to be
|
||||
// moved to java/services/com/android/server/
|
||||
mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService("batteryinfo"));
|
||||
}
|
||||
|
||||
/** Must be called after construction, and before any other method.
|
||||
*/
|
||||
public synchronized void init() {
|
||||
initializeNativeDataNative();
|
||||
|
||||
if (isEnabledNative() == 1) {
|
||||
@@ -105,12 +102,16 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
|
||||
disableNative();
|
||||
}
|
||||
|
||||
setBluetoothState(BluetoothDevice.BLUETOOTH_STATE_OFF);
|
||||
mBluetoothState = BluetoothAdapter.BLUETOOTH_STATE_OFF;
|
||||
mIsDiscovering = false;
|
||||
mEventLoop = new BluetoothEventLoop(mContext, this);
|
||||
mAdapterProperties = new HashMap<String, String>();
|
||||
mDeviceProperties = new HashMap<String, Map<String,String>>();
|
||||
registerForAirplaneMode();
|
||||
mProperties = new HashMap<String, String>();
|
||||
mRemoteDeviceProperties = new HashMap<String, Map<String,String>>();
|
||||
}
|
||||
|
||||
public synchronized void initAfterRegistration() {
|
||||
mAdapter = (BluetoothAdapter) mContext.getSystemService(Context.BLUETOOTH_SERVICE);
|
||||
mEventLoop = new BluetoothEventLoop(mContext, mAdapter, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -127,7 +128,7 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
|
||||
|
||||
public boolean isEnabled() {
|
||||
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
|
||||
return mBluetoothState == BluetoothDevice.BLUETOOTH_STATE_ON;
|
||||
return mBluetoothState == BluetoothAdapter.BLUETOOTH_STATE_ON;
|
||||
}
|
||||
|
||||
public int getBluetoothState() {
|
||||
@@ -152,9 +153,9 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
|
||||
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
|
||||
|
||||
switch (mBluetoothState) {
|
||||
case BluetoothDevice.BLUETOOTH_STATE_OFF:
|
||||
case BluetoothAdapter.BLUETOOTH_STATE_OFF:
|
||||
return true;
|
||||
case BluetoothDevice.BLUETOOTH_STATE_ON:
|
||||
case BluetoothAdapter.BLUETOOTH_STATE_ON:
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
@@ -162,11 +163,11 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
|
||||
if (mEnableThread != null && mEnableThread.isAlive()) {
|
||||
return false;
|
||||
}
|
||||
setBluetoothState(BluetoothDevice.BLUETOOTH_STATE_TURNING_OFF);
|
||||
setBluetoothState(BluetoothAdapter.BLUETOOTH_STATE_TURNING_OFF);
|
||||
|
||||
// Allow 3 seconds for profiles to gracefully disconnect
|
||||
// TODO: Introduce a callback mechanism so that each profile can notify
|
||||
// BluetoothDeviceService when it is done shutting down
|
||||
// BluetoothService when it is done shutting down
|
||||
mHandler.sendMessageDelayed(
|
||||
mHandler.obtainMessage(MESSAGE_FINISH_DISABLE, saveSetting ? 1 : 0, 0), 3000);
|
||||
return true;
|
||||
@@ -174,7 +175,7 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
|
||||
|
||||
|
||||
private synchronized void finishDisable(boolean saveSetting) {
|
||||
if (mBluetoothState != BluetoothDevice.BLUETOOTH_STATE_TURNING_OFF) {
|
||||
if (mBluetoothState != BluetoothAdapter.BLUETOOTH_STATE_TURNING_OFF) {
|
||||
return;
|
||||
}
|
||||
mEventLoop.stop();
|
||||
@@ -189,17 +190,17 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
|
||||
|
||||
// update mode
|
||||
Intent intent = new Intent(BluetoothIntent.SCAN_MODE_CHANGED_ACTION);
|
||||
intent.putExtra(BluetoothIntent.SCAN_MODE, BluetoothDevice.SCAN_MODE_NONE);
|
||||
intent.putExtra(BluetoothIntent.SCAN_MODE, BluetoothAdapter.SCAN_MODE_NONE);
|
||||
mContext.sendBroadcast(intent, BLUETOOTH_PERM);
|
||||
|
||||
mIsDiscovering = false;
|
||||
mProperties.clear();
|
||||
mAdapterProperties.clear();
|
||||
|
||||
if (saveSetting) {
|
||||
persistBluetoothOnSetting(false);
|
||||
}
|
||||
|
||||
setBluetoothState(BluetoothDevice.BLUETOOTH_STATE_OFF);
|
||||
setBluetoothState(BluetoothAdapter.BLUETOOTH_STATE_OFF);
|
||||
|
||||
// Log bluetooth off to battery stats.
|
||||
long ident = Binder.clearCallingIdentity();
|
||||
@@ -236,13 +237,13 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
|
||||
if (mIsAirplaneSensitive && isAirplaneModeOn()) {
|
||||
return false;
|
||||
}
|
||||
if (mBluetoothState != BluetoothDevice.BLUETOOTH_STATE_OFF) {
|
||||
if (mBluetoothState != BluetoothAdapter.BLUETOOTH_STATE_OFF) {
|
||||
return false;
|
||||
}
|
||||
if (mEnableThread != null && mEnableThread.isAlive()) {
|
||||
return false;
|
||||
}
|
||||
setBluetoothState(BluetoothDevice.BLUETOOTH_STATE_TURNING_ON);
|
||||
setBluetoothState(BluetoothAdapter.BLUETOOTH_STATE_TURNING_ON);
|
||||
mEnableThread = new EnableThread(saveSetting);
|
||||
mEnableThread.start();
|
||||
return true;
|
||||
@@ -250,7 +251,7 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
|
||||
|
||||
/** Forcibly restart Bluetooth if it is on */
|
||||
/* package */ synchronized void restart() {
|
||||
if (mBluetoothState != BluetoothDevice.BLUETOOTH_STATE_ON) {
|
||||
if (mBluetoothState != BluetoothAdapter.BLUETOOTH_STATE_ON) {
|
||||
return;
|
||||
}
|
||||
mRestart = true;
|
||||
@@ -356,8 +357,8 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
|
||||
mEnableThread = null;
|
||||
|
||||
setBluetoothState(res ?
|
||||
BluetoothDevice.BLUETOOTH_STATE_ON :
|
||||
BluetoothDevice.BLUETOOTH_STATE_OFF);
|
||||
BluetoothAdapter.BLUETOOTH_STATE_ON :
|
||||
BluetoothAdapter.BLUETOOTH_STATE_OFF);
|
||||
|
||||
if (res) {
|
||||
// Update mode
|
||||
@@ -410,7 +411,7 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
|
||||
));
|
||||
|
||||
public synchronized void loadBondState() {
|
||||
if (mBluetoothState != BluetoothDevice.BLUETOOTH_STATE_TURNING_ON) {
|
||||
if (mBluetoothState != BluetoothAdapter.BLUETOOTH_STATE_TURNING_ON) {
|
||||
return;
|
||||
}
|
||||
String []bonds = null;
|
||||
@@ -442,7 +443,7 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
|
||||
if (DBG) log(address + " bond state " + oldState + " -> " + state + " (" +
|
||||
reason + ")");
|
||||
Intent intent = new Intent(BluetoothIntent.BOND_STATE_CHANGED_ACTION);
|
||||
intent.putExtra(BluetoothIntent.ADDRESS, address);
|
||||
intent.putExtra(BluetoothIntent.DEVICE, mAdapter.getRemoteDevice(address));
|
||||
intent.putExtra(BluetoothIntent.BOND_STATE, state);
|
||||
intent.putExtra(BluetoothIntent.BOND_PREVIOUS_STATE, oldState);
|
||||
if (state == BluetoothDevice.BOND_NOT_BONDED) {
|
||||
@@ -539,7 +540,7 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
|
||||
|
||||
/*package*/synchronized void getAllProperties() {
|
||||
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
|
||||
mProperties.clear();
|
||||
mAdapterProperties.clear();
|
||||
|
||||
String properties[] = (String [])getAdapterPropertiesNative();
|
||||
// The String Array consists of key-value pairs.
|
||||
@@ -568,17 +569,17 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
|
||||
} else {
|
||||
newValue = properties[++i];
|
||||
}
|
||||
mProperties.put(name, newValue);
|
||||
mAdapterProperties.put(name, newValue);
|
||||
}
|
||||
|
||||
// Add adapter object path property.
|
||||
String adapterPath = getAdapterPathNative();
|
||||
if (adapterPath != null)
|
||||
mProperties.put("ObjectPath", adapterPath + "/dev_");
|
||||
mAdapterProperties.put("ObjectPath", adapterPath + "/dev_");
|
||||
}
|
||||
|
||||
/* package */ synchronized void setProperty(String name, String value) {
|
||||
mProperties.put(name, value);
|
||||
mAdapterProperties.put(name, value);
|
||||
}
|
||||
|
||||
public synchronized boolean setName(String name) {
|
||||
@@ -646,10 +647,10 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
|
||||
}
|
||||
|
||||
/*package*/ synchronized String getProperty (String name) {
|
||||
if (!mProperties.isEmpty())
|
||||
return mProperties.get(name);
|
||||
if (!mAdapterProperties.isEmpty())
|
||||
return mAdapterProperties.get(name);
|
||||
getAllProperties();
|
||||
return mProperties.get(name);
|
||||
return mAdapterProperties.get(name);
|
||||
}
|
||||
|
||||
public synchronized String getAddress() {
|
||||
@@ -678,7 +679,7 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
|
||||
if (!BluetoothDevice.checkBluetoothAddress(address)) {
|
||||
return null;
|
||||
}
|
||||
Map <String, String> properties = mRemoteDeviceProperties.get(address);
|
||||
Map <String, String> properties = mDeviceProperties.get(address);
|
||||
if (properties != null) return properties.get("Name");
|
||||
return null;
|
||||
}
|
||||
@@ -805,7 +806,7 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
|
||||
}
|
||||
|
||||
/*package*/ boolean isRemoteDeviceInCache(String address) {
|
||||
return (mRemoteDeviceProperties.get(address) != null);
|
||||
return (mDeviceProperties.get(address) != null);
|
||||
}
|
||||
|
||||
/*package*/ String[] getRemoteDeviceProperties(String address) {
|
||||
@@ -814,7 +815,7 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
|
||||
}
|
||||
|
||||
/*package*/ synchronized String getRemoteDeviceProperty(String address, String property) {
|
||||
Map<String, String> properties = mRemoteDeviceProperties.get(address);
|
||||
Map<String, String> properties = mDeviceProperties.get(address);
|
||||
if (properties != null) {
|
||||
return properties.get(property);
|
||||
} else {
|
||||
@@ -835,7 +836,7 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
|
||||
/*
|
||||
* We get a DeviceFound signal every time RSSI changes or name changes.
|
||||
* Don't create a new Map object every time */
|
||||
Map<String, String> propertyValues = mRemoteDeviceProperties.get(address);
|
||||
Map<String, String> propertyValues = mDeviceProperties.get(address);
|
||||
if (propertyValues != null) {
|
||||
propertyValues.clear();
|
||||
} else {
|
||||
@@ -864,19 +865,19 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
|
||||
}
|
||||
propertyValues.put(name, newValue);
|
||||
}
|
||||
mRemoteDeviceProperties.put(address, propertyValues);
|
||||
mDeviceProperties.put(address, propertyValues);
|
||||
}
|
||||
|
||||
/* package */ void removeRemoteDeviceProperties(String address) {
|
||||
mRemoteDeviceProperties.remove(address);
|
||||
mDeviceProperties.remove(address);
|
||||
}
|
||||
|
||||
/* package */ synchronized void setRemoteDeviceProperty(String address, String name,
|
||||
String value) {
|
||||
Map <String, String> propVal = mRemoteDeviceProperties.get(address);
|
||||
Map <String, String> propVal = mDeviceProperties.get(address);
|
||||
if (propVal != null) {
|
||||
propVal.put(name, value);
|
||||
mRemoteDeviceProperties.put(address, propVal);
|
||||
mDeviceProperties.put(address, propVal);
|
||||
} else {
|
||||
Log.e(TAG, "setRemoteDeviceProperty for a device not in cache:" + address);
|
||||
}
|
||||
@@ -1059,16 +1060,16 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
|
||||
pw.println("\nmIsAirplaneSensitive = " + mIsAirplaneSensitive + "\n");
|
||||
|
||||
switch(mBluetoothState) {
|
||||
case BluetoothDevice.BLUETOOTH_STATE_OFF:
|
||||
case BluetoothAdapter.BLUETOOTH_STATE_OFF:
|
||||
pw.println("\nBluetooth OFF\n");
|
||||
return;
|
||||
case BluetoothDevice.BLUETOOTH_STATE_TURNING_ON:
|
||||
case BluetoothAdapter.BLUETOOTH_STATE_TURNING_ON:
|
||||
pw.println("\nBluetooth TURNING ON\n");
|
||||
return;
|
||||
case BluetoothDevice.BLUETOOTH_STATE_TURNING_OFF:
|
||||
case BluetoothAdapter.BLUETOOTH_STATE_TURNING_OFF:
|
||||
pw.println("\nBluetooth TURNING OFF\n");
|
||||
return;
|
||||
case BluetoothDevice.BLUETOOTH_STATE_ON:
|
||||
case BluetoothAdapter.BLUETOOTH_STATE_ON:
|
||||
pw.println("\nBluetooth ON\n");
|
||||
}
|
||||
|
||||
@@ -1079,7 +1080,7 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
|
||||
BluetoothHeadset headset = new BluetoothHeadset(mContext, null);
|
||||
|
||||
pw.println("\n--Known devices--");
|
||||
for (String address : mRemoteDeviceProperties.keySet()) {
|
||||
for (String address : mDeviceProperties.keySet()) {
|
||||
pw.printf("%s %10s (%d) %s\n", address,
|
||||
toBondStateString(mBondState.getBondState(address)),
|
||||
mBondState.getAttempt(address),
|
||||
@@ -1113,7 +1114,7 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
|
||||
pw.println("getState() = STATE_ERROR");
|
||||
break;
|
||||
}
|
||||
pw.println("getHeadsetAddress() = " + headset.getHeadsetAddress());
|
||||
pw.println("getCurrentHeadset() = " + headset.getCurrentHeadset());
|
||||
pw.println("getBatteryUsageHint() = " + headset.getBatteryUsageHint());
|
||||
|
||||
headset.close();
|
||||
@@ -1121,20 +1122,20 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
|
||||
|
||||
/* package */ static int bluezStringToScanMode(boolean pairable, boolean discoverable) {
|
||||
if (pairable && discoverable)
|
||||
return BluetoothDevice.SCAN_MODE_CONNECTABLE_DISCOVERABLE;
|
||||
return BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE;
|
||||
else if (pairable && !discoverable)
|
||||
return BluetoothDevice.SCAN_MODE_CONNECTABLE;
|
||||
return BluetoothAdapter.SCAN_MODE_CONNECTABLE;
|
||||
else
|
||||
return BluetoothDevice.SCAN_MODE_NONE;
|
||||
return BluetoothAdapter.SCAN_MODE_NONE;
|
||||
}
|
||||
|
||||
/* package */ static String scanModeToBluezString(int mode) {
|
||||
switch (mode) {
|
||||
case BluetoothDevice.SCAN_MODE_NONE:
|
||||
case BluetoothAdapter.SCAN_MODE_NONE:
|
||||
return "off";
|
||||
case BluetoothDevice.SCAN_MODE_CONNECTABLE:
|
||||
case BluetoothAdapter.SCAN_MODE_CONNECTABLE:
|
||||
return "connectable";
|
||||
case BluetoothDevice.SCAN_MODE_CONNECTABLE_DISCOVERABLE:
|
||||
case BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE:
|
||||
return "discoverable";
|
||||
}
|
||||
return null;
|
||||
@@ -21,8 +21,8 @@ import android.app.ActivityManagerNative;
|
||||
import android.app.IActivityManager;
|
||||
import android.app.ProgressDialog;
|
||||
import android.app.AlertDialog;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.IBluetoothDevice;
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.IBluetooth;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
@@ -179,13 +179,13 @@ public final class ShutdownThread extends Thread {
|
||||
|
||||
final ITelephony phone =
|
||||
ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
|
||||
final IBluetoothDevice bluetooth =
|
||||
IBluetoothDevice.Stub.asInterface(ServiceManager.checkService(
|
||||
final IBluetooth bluetooth =
|
||||
IBluetooth.Stub.asInterface(ServiceManager.checkService(
|
||||
Context.BLUETOOTH_SERVICE));
|
||||
|
||||
try {
|
||||
bluetoothOff = bluetooth == null ||
|
||||
bluetooth.getBluetoothState() == BluetoothDevice.BLUETOOTH_STATE_OFF;
|
||||
bluetooth.getBluetoothState() == BluetoothAdapter.BLUETOOTH_STATE_OFF;
|
||||
if (!bluetoothOff) {
|
||||
Log.w(TAG, "Disabling Bluetooth...");
|
||||
bluetooth.disable(false); // disable but don't persist new state
|
||||
@@ -213,7 +213,7 @@ public final class ShutdownThread extends Thread {
|
||||
if (!bluetoothOff) {
|
||||
try {
|
||||
bluetoothOff =
|
||||
bluetooth.getBluetoothState() == BluetoothDevice.BLUETOOTH_STATE_OFF;
|
||||
bluetooth.getBluetoothState() == BluetoothAdapter.BLUETOOTH_STATE_OFF;
|
||||
} catch (RemoteException ex) {
|
||||
Log.e(TAG, "RemoteException during bluetooth shutdown", ex);
|
||||
bluetoothOff = true;
|
||||
|
||||
@@ -114,7 +114,7 @@ LOCAL_SRC_FILES:= \
|
||||
android_bluetooth_BluetoothAudioGateway.cpp \
|
||||
android_bluetooth_BluetoothSocket.cpp \
|
||||
android_bluetooth_ScoSocket.cpp \
|
||||
android_server_BluetoothDeviceService.cpp \
|
||||
android_server_BluetoothService.cpp \
|
||||
android_server_BluetoothEventLoop.cpp \
|
||||
android_server_BluetoothA2dpService.cpp \
|
||||
android_message_digest_sha1.cpp \
|
||||
|
||||
@@ -146,7 +146,7 @@ extern int register_android_bluetooth_HeadsetBase(JNIEnv* env);
|
||||
extern int register_android_bluetooth_BluetoothAudioGateway(JNIEnv* env);
|
||||
extern int register_android_bluetooth_BluetoothSocket(JNIEnv *env);
|
||||
extern int register_android_bluetooth_ScoSocket(JNIEnv *env);
|
||||
extern int register_android_server_BluetoothDeviceService(JNIEnv* env);
|
||||
extern int register_android_server_BluetoothService(JNIEnv* env);
|
||||
extern int register_android_server_BluetoothEventLoop(JNIEnv *env);
|
||||
extern int register_android_server_BluetoothA2dpService(JNIEnv* env);
|
||||
extern int register_android_ddm_DdmHandleNativeHeap(JNIEnv *env);
|
||||
@@ -1241,7 +1241,7 @@ static const RegJNIRec gRegJNI[] = {
|
||||
REG_JNI(register_android_bluetooth_BluetoothAudioGateway),
|
||||
REG_JNI(register_android_bluetooth_BluetoothSocket),
|
||||
REG_JNI(register_android_bluetooth_ScoSocket),
|
||||
REG_JNI(register_android_server_BluetoothDeviceService),
|
||||
REG_JNI(register_android_server_BluetoothService),
|
||||
REG_JNI(register_android_server_BluetoothEventLoop),
|
||||
REG_JNI(register_android_server_BluetoothA2dpService),
|
||||
REG_JNI(register_android_message_digest_sha1),
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
#define DBUS_ADAPTER_IFACE BLUEZ_DBUS_BASE_IFC ".Adapter"
|
||||
#define DBUS_DEVICE_IFACE BLUEZ_DBUS_BASE_IFC ".Device"
|
||||
#define LOG_TAG "BluetoothDeviceService.cpp"
|
||||
#define LOG_TAG "BluetoothService.cpp"
|
||||
|
||||
#include "android_bluetooth_common.h"
|
||||
#include "android_runtime/AndroidRuntime.h"
|
||||
@@ -49,7 +49,7 @@ namespace android {
|
||||
|
||||
#ifdef HAVE_BLUETOOTH
|
||||
// We initialize these variables when we load class
|
||||
// android.server.BluetoothDeviceService
|
||||
// android.server.BluetoothService
|
||||
static jfieldID field_mNativeData;
|
||||
static jfieldID field_mEventLoop;
|
||||
|
||||
@@ -732,9 +732,9 @@ static JNINativeMethod sMethods[] = {
|
||||
(void *)cancelPairingUserInputNative},
|
||||
};
|
||||
|
||||
int register_android_server_BluetoothDeviceService(JNIEnv *env) {
|
||||
int register_android_server_BluetoothService(JNIEnv *env) {
|
||||
return AndroidRuntime::registerNativeMethods(env,
|
||||
"android/server/BluetoothDeviceService", sMethods, NELEM(sMethods));
|
||||
"android/server/BluetoothService", sMethods, NELEM(sMethods));
|
||||
}
|
||||
|
||||
} /* namespace android */
|
||||
@@ -17,16 +17,16 @@
|
||||
package android.media;
|
||||
|
||||
import android.app.ActivityManagerNative;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.bluetooth.BluetoothIntent;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.bluetooth.BluetoothHeadset;
|
||||
import android.bluetooth.BluetoothA2dp;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothClass;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothIntent;
|
||||
import android.bluetooth.BluetoothHeadset;
|
||||
|
||||
import android.content.pm.PackageManager;
|
||||
import android.database.ContentObserver;
|
||||
@@ -236,8 +236,6 @@ public class AudioService extends IAudioService.Stub {
|
||||
// Forced device usage for communications
|
||||
private int mForcedUseForComm;
|
||||
|
||||
private BluetoothDevice mBluetoothDevice = null;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Construction
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
@@ -1371,8 +1369,8 @@ public class AudioService extends IAudioService.Stub {
|
||||
if (action.equals(BluetoothA2dp.SINK_STATE_CHANGED_ACTION)) {
|
||||
int state = intent.getIntExtra(BluetoothA2dp.SINK_STATE,
|
||||
BluetoothA2dp.STATE_DISCONNECTED);
|
||||
String address = intent.getStringExtra(BluetoothIntent.ADDRESS);
|
||||
|
||||
BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothIntent.DEVICE);
|
||||
String address = btDevice.getAddress();
|
||||
boolean isConnected = (mConnectedDevices.containsKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP) &&
|
||||
((String)mConnectedDevices.get(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP)).equals(address));
|
||||
|
||||
@@ -1387,30 +1385,27 @@ public class AudioService extends IAudioService.Stub {
|
||||
AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
|
||||
AudioSystem.DEVICE_STATE_AVAILABLE,
|
||||
address);
|
||||
mConnectedDevices.put( new Integer(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP), address);
|
||||
mConnectedDevices.put( new Integer(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP),
|
||||
address);
|
||||
}
|
||||
} else if (action.equals(BluetoothIntent.HEADSET_STATE_CHANGED_ACTION)) {
|
||||
int state = intent.getIntExtra(BluetoothIntent.HEADSET_STATE,
|
||||
BluetoothHeadset.STATE_ERROR);
|
||||
String address = intent.getStringExtra(BluetoothIntent.ADDRESS);
|
||||
BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothIntent.DEVICE);
|
||||
String address = btDevice.getAddress();
|
||||
int device = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO;
|
||||
if (mBluetoothDevice == null) {
|
||||
mBluetoothDevice = (BluetoothDevice)mContext.getSystemService(Context.BLUETOOTH_SERVICE);
|
||||
}
|
||||
if (mBluetoothDevice != null) {
|
||||
int btClass = mBluetoothDevice.getRemoteClass(address);
|
||||
if (BluetoothClass.Device.Major.getDeviceMajor(btClass) == BluetoothClass.Device.Major.AUDIO_VIDEO) {
|
||||
switch (BluetoothClass.Device.getDevice(btClass)) {
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET:
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE:
|
||||
device = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
|
||||
break;
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_CAR_AUDIO:
|
||||
device = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
int btClass = btDevice.getBluetoothClass();
|
||||
if (BluetoothClass.Device.Major.getDeviceMajor(btClass) == BluetoothClass.Device.Major.AUDIO_VIDEO) {
|
||||
switch (BluetoothClass.Device.getDevice(btClass)) {
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET:
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE:
|
||||
device = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
|
||||
break;
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_CAR_AUDIO:
|
||||
device = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1426,7 +1421,7 @@ public class AudioService extends IAudioService.Stub {
|
||||
AudioSystem.setDeviceConnectionState(device,
|
||||
AudioSystem.DEVICE_STATE_AVAILABLE,
|
||||
address);
|
||||
mConnectedDevices.put( new Integer(device), address);
|
||||
mConnectedDevices.put(new Integer(device), address);
|
||||
}
|
||||
} else if (action.equals(Intent.ACTION_HEADSET_PLUG)) {
|
||||
int state = intent.getIntExtra("state", 0);
|
||||
|
||||
@@ -30,7 +30,7 @@ import java.util.zip.CRC32;
|
||||
import android.backup.BackupDataInput;
|
||||
import android.backup.BackupDataOutput;
|
||||
import android.backup.BackupHelperAgent;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
@@ -393,7 +393,7 @@ public class SettingsBackupAgent extends BackupHelperAgent {
|
||||
}
|
||||
|
||||
private void enableBluetooth(boolean enable) {
|
||||
BluetoothDevice bt = (BluetoothDevice) getSystemService(Context.BLUETOOTH_SERVICE);
|
||||
BluetoothAdapter bt = (BluetoothAdapter) getSystemService(Context.BLUETOOTH_SERVICE);
|
||||
if (bt != null) {
|
||||
if (!enable) {
|
||||
bt.disable();
|
||||
|
||||
@@ -36,7 +36,7 @@ import android.os.*;
|
||||
import android.provider.Contacts.People;
|
||||
import android.provider.Settings;
|
||||
import android.server.BluetoothA2dpService;
|
||||
import android.server.BluetoothDeviceService;
|
||||
import android.server.BluetoothService;
|
||||
import android.server.search.SearchManagerService;
|
||||
import android.util.EventLog;
|
||||
import android.util.Log;
|
||||
@@ -89,7 +89,7 @@ class ServerThread extends Thread {
|
||||
IPackageManager pm = null;
|
||||
Context context = null;
|
||||
WindowManagerService wm = null;
|
||||
BluetoothDeviceService bluetooth = null;
|
||||
BluetoothService bluetooth = null;
|
||||
BluetoothA2dpService bluetoothA2dp = null;
|
||||
HeadsetObserver headset = null;
|
||||
DockObserver dock = null;
|
||||
@@ -176,9 +176,9 @@ class ServerThread extends Thread {
|
||||
ServiceManager.addService(Context.BLUETOOTH_SERVICE, null);
|
||||
} else {
|
||||
Log.i(TAG, "Starting Bluetooth Service.");
|
||||
bluetooth = new BluetoothDeviceService(context);
|
||||
bluetooth.init();
|
||||
bluetooth = new BluetoothService(context);
|
||||
ServiceManager.addService(Context.BLUETOOTH_SERVICE, bluetooth);
|
||||
bluetooth.initAfterRegistration();
|
||||
bluetoothA2dp = new BluetoothA2dpService(context, bluetooth);
|
||||
ServiceManager.addService(BluetoothA2dpService.BLUETOOTH_A2DP_SERVICE,
|
||||
bluetoothA2dp);
|
||||
|
||||
@@ -18,7 +18,7 @@ package com.android.server.status;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.bluetooth.BluetoothA2dp;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothError;
|
||||
import android.bluetooth.BluetoothHeadset;
|
||||
import android.bluetooth.BluetoothIntent;
|
||||
@@ -473,10 +473,10 @@ public class StatusBarPolicy {
|
||||
mBluetoothData = IconData.makeIcon("bluetooth",
|
||||
null, com.android.internal.R.drawable.stat_sys_data_bluetooth, 0, 0);
|
||||
mBluetoothIcon = service.addIcon(mBluetoothData, null);
|
||||
BluetoothDevice bluetooth =
|
||||
(BluetoothDevice) mContext.getSystemService(Context.BLUETOOTH_SERVICE);
|
||||
if (bluetooth != null) {
|
||||
mBluetoothEnabled = bluetooth.isEnabled();
|
||||
BluetoothAdapter adapter =
|
||||
(BluetoothAdapter) mContext.getSystemService(Context.BLUETOOTH_SERVICE);
|
||||
if (adapter != null) {
|
||||
mBluetoothEnabled = adapter.isEnabled();
|
||||
} else {
|
||||
mBluetoothEnabled = false;
|
||||
}
|
||||
@@ -1083,7 +1083,7 @@ public class StatusBarPolicy {
|
||||
if (action.equals(BluetoothIntent.BLUETOOTH_STATE_CHANGED_ACTION)) {
|
||||
int state = intent.getIntExtra(BluetoothIntent.BLUETOOTH_STATE,
|
||||
BluetoothError.ERROR);
|
||||
mBluetoothEnabled = state == BluetoothDevice.BLUETOOTH_STATE_ON;
|
||||
mBluetoothEnabled = state == BluetoothAdapter.BLUETOOTH_STATE_ON;
|
||||
} else if (action.equals(BluetoothIntent.HEADSET_STATE_CHANGED_ACTION)) {
|
||||
mBluetoothHeadsetState = intent.getIntExtra(BluetoothIntent.HEADSET_STATE,
|
||||
BluetoothHeadset.STATE_ERROR);
|
||||
|
||||
@@ -39,6 +39,7 @@ import android.util.Log;
|
||||
import android.util.Config;
|
||||
import android.app.Notification;
|
||||
import android.app.PendingIntent;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothHeadset;
|
||||
import android.bluetooth.BluetoothA2dp;
|
||||
import android.content.ContentResolver;
|
||||
@@ -49,6 +50,7 @@ import com.android.internal.app.IBatteryStats;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Set;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
/**
|
||||
@@ -645,10 +647,10 @@ public class WifiStateTracker extends NetworkStateTracker {
|
||||
|
||||
private void checkIsBluetoothPlaying() {
|
||||
boolean isBluetoothPlaying = false;
|
||||
List<String> connected = mBluetoothA2dp.listConnectedSinks();
|
||||
Set<BluetoothDevice> connected = mBluetoothA2dp.getConnectedSinks();
|
||||
|
||||
for (String address : connected) {
|
||||
if (mBluetoothA2dp.getSinkState(address) == BluetoothA2dp.STATE_PLAYING) {
|
||||
for (BluetoothDevice device : connected) {
|
||||
if (mBluetoothA2dp.getSinkState(device) == BluetoothA2dp.STATE_PLAYING) {
|
||||
isBluetoothPlaying = true;
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user