diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/java/android/bluetooth/BluetoothAdapter.java | 10 | ||||
-rw-r--r-- | core/java/android/bluetooth/BluetoothMap.java | 244 | ||||
-rw-r--r-- | core/java/android/bluetooth/BluetoothUuid.java | 10 | ||||
-rw-r--r-- | core/java/android/bluetooth/IBluetoothMap.aidl | 7 | ||||
-rw-r--r-- | core/java/android/provider/Settings.java | 10 |
5 files changed, 208 insertions, 73 deletions
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java index 676fd1f..2172a7b 100644 --- a/core/java/android/bluetooth/BluetoothAdapter.java +++ b/core/java/android/bluetooth/BluetoothAdapter.java @@ -27,7 +27,6 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.util.Log; import android.util.Pair; - import java.io.IOException; import java.lang.ref.WeakReference; import java.util.ArrayList; @@ -51,7 +50,7 @@ import java.util.UUID; * devices, and start a scan for Bluetooth LE devices. * * <p>To get a {@link BluetoothAdapter} representing the local Bluetooth - * adapter, when running on JELLY_BEAN_MR1 and below, call the + * adapter, when running on JELLY_BEAN_MR1 and below, call the * static {@link #getDefaultAdapter} method; when running on JELLY_BEAN_MR2 and * higher, retrieve it through * {@link android.content.Context#getSystemService} with @@ -1229,6 +1228,9 @@ public final class BluetoothAdapter { } else if (profile == BluetoothProfile.HEALTH) { BluetoothHealth health = new BluetoothHealth(context, listener); return true; + } else if (profile == BluetoothProfile.MAP) { + BluetoothMap map = new BluetoothMap(context, listener); + return true; } else { return false; } @@ -1277,6 +1279,10 @@ public final class BluetoothAdapter { BluetoothGattServer gattServer = (BluetoothGattServer)proxy; gattServer.close(); break; + case BluetoothProfile.MAP: + BluetoothMap map = (BluetoothMap)proxy; + map.close(); + break; } } diff --git a/core/java/android/bluetooth/BluetoothMap.java b/core/java/android/bluetooth/BluetoothMap.java index 7de309f..fac8fd5 100644 --- a/core/java/android/bluetooth/BluetoothMap.java +++ b/core/java/android/bluetooth/BluetoothMap.java @@ -16,6 +16,8 @@ package android.bluetooth; +import java.util.List; +import java.util.ArrayList; import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -30,25 +32,14 @@ import android.util.Log; * Profile. *@hide */ -public class BluetoothMap { +public final class BluetoothMap implements BluetoothProfile { private static final String TAG = "BluetoothMap"; private static final boolean DBG = true; private static final boolean VDBG = false; - /** int extra for MAP_STATE_CHANGED_ACTION */ - public static final String MAP_STATE = - "android.bluetooth.map.intent.MAP_STATE"; - /** int extra for MAP_STATE_CHANGED_ACTION */ - public static final String MAP_PREVIOUS_STATE = - "android.bluetooth.map.intent.MAP_PREVIOUS_STATE"; - - /** Indicates the state of a Map connection state has changed. - * This intent will always contain MAP_STATE, MAP_PREVIOUS_STATE and - * BluetoothIntent.ADDRESS extras. - */ - public static final String MAP_STATE_CHANGED_ACTION = - "android.bluetooth.map.intent.action.MAP_STATE_CHANGED"; + public static final String ACTION_CONNECTION_STATE_CHANGED = + "android.bluetooth.map.profile.action.CONNECTION_STATE_CHANGED"; private IBluetoothMap mService; private final Context mContext; @@ -57,41 +48,12 @@ public class BluetoothMap { /** There was an error trying to obtain the state */ public static final int STATE_ERROR = -1; - /** No client currently connected */ - public static final int STATE_DISCONNECTED = 0; - /** Connection attempt in progress */ - public static final int STATE_CONNECTING = 1; - /** Client is currently connected */ - public static final int STATE_CONNECTED = 2; public static final int RESULT_FAILURE = 0; public static final int RESULT_SUCCESS = 1; /** Connection canceled before completion. */ public static final int RESULT_CANCELED = 2; - /** - * An interface for notifying Bluetooth PCE IPC clients when they have - * been connected to the BluetoothMap service. - */ - public interface ServiceListener { - /** - * Called to notify the client when this proxy object has been - * connected to the BluetoothMap service. Clients must wait for - * this callback before making IPC calls on the BluetoothMap - * service. - */ - public void onServiceConnected(BluetoothMap proxy); - - /** - * Called to notify the client that this proxy object has been - * disconnected from the BluetoothMap service. Clients must not - * make IPC calls on the BluetoothMap service after this callback. - * This callback will currently only occur if the application hosting - * the BluetoothMap service, but may be called more often in future. - */ - public void onServiceDisconnected(); - } - final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback = new IBluetoothStateChangeCallback.Stub() { public void onBluetoothStateChange(boolean up) { @@ -111,11 +73,7 @@ public class BluetoothMap { try { if (mService == null) { if (VDBG) Log.d(TAG,"Binding service..."); - if (!mContext.bindService( - new Intent(IBluetoothMap.class.getName()), - mConnection, 0)) { - Log.e(TAG, "Could not bind to Bluetooth MAP Service"); - } + doBind(); } } catch (Exception re) { Log.e(TAG,"",re); @@ -128,7 +86,8 @@ public class BluetoothMap { /** * Create a BluetoothMap proxy object. */ - public BluetoothMap(Context context, ServiceListener l) { + /*package*/ BluetoothMap(Context context, ServiceListener l) { + if (DBG) Log.d(TAG, "Create BluetoothMap proxy object"); mContext = context; mServiceListener = l; mAdapter = BluetoothAdapter.getDefaultAdapter(); @@ -140,9 +99,18 @@ public class BluetoothMap { Log.e(TAG,"",e); } } - if (!context.bindService(new Intent(IBluetoothMap.class.getName()), mConnection, 0)) { - Log.e(TAG, "Could not bind to Bluetooth Map Service"); + doBind(); + } + + boolean doBind() { + Intent intent = new Intent(IBluetoothMap.class.getName()); + ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0); + intent.setComponent(comp); + if (comp == null || !mContext.bindService(intent, mConnection, 0)) { + Log.e(TAG, "Could not bind to Bluetooth MAP Service with " + intent); + return false; } + return true; } protected void finalize() throws Throwable { @@ -221,9 +189,9 @@ public class BluetoothMap { } /** - * 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 Map service. + * Returns true if the specified Bluetooth device is connected. + * Returns false if not connected, or if this proxy object is not + * currently connected to the Map service. */ public boolean isConnected(BluetoothDevice device) { if (VDBG) log("isConnected(" + device + ")"); @@ -239,21 +207,33 @@ public class BluetoothMap { } /** - * Disconnects the current Map Client. Currently this call blocks, - * it may soon be made asynchronous. Returns false if this proxy object is - * not currently connected to the Map service. + * Initiate connection. Initiation of outgoing connections is not + * supported for MAP server. */ - public boolean disconnect() { - if (DBG) log("disconnect()"); - if (mService != null) { + public boolean connect(BluetoothDevice device) { + if (DBG) log("connect(" + device + ")" + "not supported for MAPS"); + return false; + } + + /** + * Initiate disconnect. + * + * @param device Remote Bluetooth Device + * @return false on error, + * true otherwise + */ + public boolean disconnect(BluetoothDevice device) { + if (DBG) log("disconnect(" + device + ")"); + if (mService != null && isEnabled() && + isValidDevice(device)) { try { - mService.disconnect(); - return true; - } catch (RemoteException e) {Log.e(TAG, e.toString());} - } else { - Log.w(TAG, "Proxy not attached to service"); - if (DBG) log(Log.getStackTraceString(new Throwable())); + return mService.disconnect(device); + } catch (RemoteException e) { + Log.e(TAG, Log.getStackTraceString(new Throwable())); + return false; + } } + if (mService == null) Log.w(TAG, "Proxy not attached to service"); return false; } @@ -277,19 +257,132 @@ public class BluetoothMap { } } + /** + * Get the list of connected devices. Currently at most one. + * + * @return list of connected devices + */ + public List<BluetoothDevice> getConnectedDevices() { + if (DBG) log("getConnectedDevices()"); + if (mService != null && isEnabled()) { + try { + return mService.getConnectedDevices(); + } catch (RemoteException e) { + Log.e(TAG, Log.getStackTraceString(new Throwable())); + return new ArrayList<BluetoothDevice>(); + } + } + if (mService == null) Log.w(TAG, "Proxy not attached to service"); + return new ArrayList<BluetoothDevice>(); + } + + /** + * Get the list of devices matching specified states. Currently at most one. + * + * @return list of matching devices + */ + public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) { + if (DBG) log("getDevicesMatchingStates()"); + if (mService != null && isEnabled()) { + try { + return mService.getDevicesMatchingConnectionStates(states); + } catch (RemoteException e) { + Log.e(TAG, Log.getStackTraceString(new Throwable())); + return new ArrayList<BluetoothDevice>(); + } + } + if (mService == null) Log.w(TAG, "Proxy not attached to service"); + return new ArrayList<BluetoothDevice>(); + } + + /** + * Get connection state of device + * + * @return device connection state + */ + public int getConnectionState(BluetoothDevice device) { + if (DBG) log("getConnectionState(" + device + ")"); + if (mService != null && isEnabled() && + isValidDevice(device)) { + try { + return mService.getConnectionState(device); + } catch (RemoteException e) { + Log.e(TAG, Log.getStackTraceString(new Throwable())); + return BluetoothProfile.STATE_DISCONNECTED; + } + } + if (mService == null) Log.w(TAG, "Proxy not attached to service"); + return BluetoothProfile.STATE_DISCONNECTED; + } + + /** + * Set priority of the profile + * + * <p> The device should already be paired. + * Priority can be one of {@link #PRIORITY_ON} or + * {@link #PRIORITY_OFF}, + * + * @param device Paired bluetooth device + * @param priority + * @return true if priority is set, false on error + */ + public boolean setPriority(BluetoothDevice device, int priority) { + if (DBG) log("setPriority(" + device + ", " + priority + ")"); + if (mService != null && isEnabled() && + isValidDevice(device)) { + if (priority != BluetoothProfile.PRIORITY_OFF && + priority != BluetoothProfile.PRIORITY_ON) { + return false; + } + try { + return mService.setPriority(device, priority); + } catch (RemoteException e) { + Log.e(TAG, Log.getStackTraceString(new Throwable())); + return false; + } + } + if (mService == null) Log.w(TAG, "Proxy not attached to service"); + return false; + } + + /** + * Get the priority of the profile. + * + * <p> The priority can be any of: + * {@link #PRIORITY_AUTO_CONNECT}, {@link #PRIORITY_OFF}, + * {@link #PRIORITY_ON}, {@link #PRIORITY_UNDEFINED} + * + * @param device Bluetooth device + * @return priority of the device + */ + public int getPriority(BluetoothDevice device) { + if (VDBG) log("getPriority(" + device + ")"); + if (mService != null && isEnabled() && + isValidDevice(device)) { + try { + return mService.getPriority(device); + } catch (RemoteException e) { + Log.e(TAG, Log.getStackTraceString(new Throwable())); + return PRIORITY_OFF; + } + } + if (mService == null) Log.w(TAG, "Proxy not attached to service"); + return PRIORITY_OFF; + } + private ServiceConnection mConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { if (DBG) log("Proxy object connected"); mService = IBluetoothMap.Stub.asInterface(service); if (mServiceListener != null) { - mServiceListener.onServiceConnected(BluetoothMap.this); + mServiceListener.onServiceConnected(BluetoothProfile.MAP, BluetoothMap.this); } } public void onServiceDisconnected(ComponentName className) { if (DBG) log("Proxy object disconnected"); mService = null; if (mServiceListener != null) { - mServiceListener.onServiceDisconnected(); + mServiceListener.onServiceDisconnected(BluetoothProfile.MAP); } } }; @@ -297,4 +390,19 @@ public class BluetoothMap { private static void log(String msg) { Log.d(TAG, msg); } + + private boolean isEnabled() { + BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); + if (adapter != null && adapter.getState() == BluetoothAdapter.STATE_ON) return true; + log("Bluetooth is Not enabled"); + return false; + } + private boolean isValidDevice(BluetoothDevice device) { + if (device == null) return false; + + if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true; + return false; + } + + } diff --git a/core/java/android/bluetooth/BluetoothUuid.java b/core/java/android/bluetooth/BluetoothUuid.java index 6609b98..abdf949 100644 --- a/core/java/android/bluetooth/BluetoothUuid.java +++ b/core/java/android/bluetooth/BluetoothUuid.java @@ -67,13 +67,16 @@ public final class BluetoothUuid { public static final ParcelUuid PBAP_PSE = ParcelUuid.fromString("0000112f-0000-1000-8000-00805F9B34FB"); public static final ParcelUuid MAP = - ParcelUuid.fromString("00001132-0000-1000-8000-00805F9B34FB"); + ParcelUuid.fromString("00001134-0000-1000-8000-00805F9B34FB"); public static final ParcelUuid MNS = ParcelUuid.fromString("00001133-0000-1000-8000-00805F9B34FB"); + public static final ParcelUuid MAS = + ParcelUuid.fromString("00001132-0000-1000-8000-00805F9B34FB"); + public static final ParcelUuid[] RESERVED_UUIDS = { AudioSink, AudioSource, AdvAudioDist, HSP, Handsfree, AvrcpController, AvrcpTarget, - ObexObjectPush, PANU, NAP, MAP, MNS}; + ObexObjectPush, PANU, NAP, MAP, MNS, MAS}; public static boolean isAudioSource(ParcelUuid uuid) { return uuid.equals(AudioSource); @@ -124,6 +127,9 @@ public final class BluetoothUuid { public static boolean isMns(ParcelUuid uuid) { return uuid.equals(MNS); } + public static boolean isMas(ParcelUuid uuid) { + return uuid.equals(MAS); + } /** * Returns true if ParcelUuid is present in uuidArray diff --git a/core/java/android/bluetooth/IBluetoothMap.aidl b/core/java/android/bluetooth/IBluetoothMap.aidl index 0c18e06..d4af63d 100644 --- a/core/java/android/bluetooth/IBluetoothMap.aidl +++ b/core/java/android/bluetooth/IBluetoothMap.aidl @@ -27,6 +27,11 @@ interface IBluetoothMap { int getState(); BluetoothDevice getClient(); boolean connect(in BluetoothDevice device); - void disconnect(); + boolean disconnect(in BluetoothDevice device); boolean isConnected(in BluetoothDevice device); + List<BluetoothDevice> getConnectedDevices(); + List<BluetoothDevice> getDevicesMatchingConnectionStates(in int[] states); + int getConnectionState(in BluetoothDevice device); + boolean setPriority(in BluetoothDevice device, int priority); + int getPriority(in BluetoothDevice device); } diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 1a80818..99a4e93 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -5635,6 +5635,9 @@ public final class Settings { /** {@hide} */ public static final String BLUETOOTH_INPUT_DEVICE_PRIORITY_PREFIX = "bluetooth_input_device_priority_"; + /** {@hide} */ + public static final String + BLUETOOTH_MAP_PRIORITY_PREFIX = "bluetooth_map_priority_"; /** * Get the key that retrieves a bluetooth headset's priority. @@ -5661,6 +5664,13 @@ public final class Settings { } /** + * Get the key that retrieves a bluetooth map priority. + * @hide + */ + public static final String getBluetoothMapPriorityKey(String address) { + return BLUETOOTH_MAP_PRIORITY_PREFIX + address.toUpperCase(Locale.ROOT); + } + /** * Scaling factor for normal window animations. Setting to 0 will * disable window animations. */ |