diff options
Diffstat (limited to 'framework/java/android/bluetooth/BluetoothMapClient.java')
-rw-r--r-- | framework/java/android/bluetooth/BluetoothMapClient.java | 98 |
1 files changed, 83 insertions, 15 deletions
diff --git a/framework/java/android/bluetooth/BluetoothMapClient.java b/framework/java/android/bluetooth/BluetoothMapClient.java index 03536f9aad..b29d7b0413 100644 --- a/framework/java/android/bluetooth/BluetoothMapClient.java +++ b/framework/java/android/bluetooth/BluetoothMapClient.java @@ -18,12 +18,12 @@ package android.bluetooth; import static android.bluetooth.BluetoothUtils.getSyncTimeout; -import android.Manifest; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; +import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.app.PendingIntent; import android.bluetooth.annotations.RequiresBluetoothConnectPermission; @@ -34,6 +34,7 @@ import android.net.Uri; import android.os.Build; import android.os.IBinder; import android.os.RemoteException; +import android.util.CloseGuard; import android.util.Log; import com.android.modules.utils.SynchronousResultReceiver; @@ -49,15 +50,37 @@ import java.util.concurrent.TimeoutException; * @hide */ @SystemApi -public final class BluetoothMapClient implements BluetoothProfile { +public final class BluetoothMapClient implements BluetoothProfile, AutoCloseable { private static final String TAG = "BluetoothMapClient"; private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG); private static final boolean VDBG = Log.isLoggable(TAG, Log.VERBOSE); - /** @hide */ + private final CloseGuard mCloseGuard; + + /** + * Intent used to broadcast the change in connection state of the MAP Client profile. + * + * <p>This intent will have 3 extras: + * <ul> + * <li> {@link #EXTRA_STATE} - The current state of the profile. </li> + * <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li> + * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li> + * </ul> + * + * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of + * {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING}, + * {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTING}. + * + * @hide + */ + @SystemApi + @SuppressLint("ActionValue") @RequiresBluetoothConnectPermission - @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) + @RequiresPermission(allOf = { + android.Manifest.permission.BLUETOOTH_CONNECT, + android.Manifest.permission.BLUETOOTH_PRIVILEGED, + }) @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.mapmce.profile.action.CONNECTION_STATE_CHANGED"; @@ -197,6 +220,16 @@ public final class BluetoothMapClient implements BluetoothProfile { mAdapter = adapter; mAttributionSource = adapter.getAttributionSource(); mProfileConnector.connect(context, listener); + mCloseGuard = new CloseGuard(); + mCloseGuard.open("close"); + } + + /** @hide */ + protected void finalize() { + if (mCloseGuard != null) { + mCloseGuard.warnIfOpen(); + } + close(); } /** @@ -208,6 +241,9 @@ public final class BluetoothMapClient implements BluetoothProfile { */ public void close() { mProfileConnector.disconnect(); + if (mCloseGuard != null) { + mCloseGuard.close(); + } } private IBluetoothMapClient getService() { @@ -309,10 +345,14 @@ public final class BluetoothMapClient implements BluetoothProfile { * @return list of connected devices * @hide */ + @SystemApi @Override @RequiresBluetoothConnectPermission - @RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT) - public List<BluetoothDevice> getConnectedDevices() { + @RequiresPermission(allOf = { + android.Manifest.permission.BLUETOOTH_CONNECT, + android.Manifest.permission.BLUETOOTH_PRIVILEGED, + }) + public @NonNull List<BluetoothDevice> getConnectedDevices() { if (DBG) Log.d(TAG, "getConnectedDevices()"); final IBluetoothMapClient service = getService(); final List<BluetoothDevice> defaultValue = new ArrayList<>(); @@ -327,7 +367,10 @@ public final class BluetoothMapClient implements BluetoothProfile { return Attributable.setAttributionSource( recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue), mAttributionSource); - } catch (RemoteException | TimeoutException e) { + } catch (RemoteException e) { + Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); + throw e.rethrowFromSystemServer(); + } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } } @@ -337,13 +380,19 @@ public final class BluetoothMapClient implements BluetoothProfile { /** * Get the list of devices matching specified states. Currently at most one. * + * @param states The connection states to match for. * @return list of matching devices * @hide */ + @SystemApi @Override @RequiresBluetoothConnectPermission - @RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT) - public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) { + @RequiresPermission(allOf = { + android.Manifest.permission.BLUETOOTH_CONNECT, + android.Manifest.permission.BLUETOOTH_PRIVILEGED, + }) + public + @NonNull List<BluetoothDevice> getDevicesMatchingConnectionStates(@NonNull int[] states) { if (DBG) Log.d(TAG, "getDevicesMatchingStates()"); final IBluetoothMapClient service = getService(); final List<BluetoothDevice> defaultValue = new ArrayList<>(); @@ -358,7 +407,10 @@ public final class BluetoothMapClient implements BluetoothProfile { return Attributable.setAttributionSource( recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue), mAttributionSource); - } catch (RemoteException | TimeoutException e) { + } catch (RemoteException e) { + Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); + throw e.rethrowFromSystemServer(); + } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } } @@ -368,13 +420,18 @@ public final class BluetoothMapClient implements BluetoothProfile { /** * Get connection state of device * + * @param device The remote device whose connection state is to be ascertained. * @return device connection state * @hide */ + @SystemApi @Override @RequiresBluetoothConnectPermission - @RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT) - public int getConnectionState(BluetoothDevice device) { + @RequiresPermission(allOf = { + android.Manifest.permission.BLUETOOTH_CONNECT, + android.Manifest.permission.BLUETOOTH_PRIVILEGED, + }) + public @BtProfileState int getConnectionState(@NonNull BluetoothDevice device) { if (DBG) Log.d(TAG, "getConnectionState(" + device + ")"); final IBluetoothMapClient service = getService(); final int defaultValue = BluetoothProfile.STATE_DISCONNECTED; @@ -386,7 +443,10 @@ public final class BluetoothMapClient implements BluetoothProfile { final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver<>(); service.getConnectionState(device, mAttributionSource, recv); return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue); - } catch (RemoteException | TimeoutException e) { + } catch (RemoteException e) { + Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); + throw e.rethrowFromSystemServer(); + } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } } @@ -426,6 +486,7 @@ public final class BluetoothMapClient implements BluetoothProfile { * @return true if connectionPolicy is set, false on error * @hide */ + @SystemApi @RequiresBluetoothConnectPermission @RequiresPermission(allOf = { android.Manifest.permission.BLUETOOTH_CONNECT, @@ -446,7 +507,10 @@ public final class BluetoothMapClient implements BluetoothProfile { final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver(); service.setConnectionPolicy(device, connectionPolicy, mAttributionSource, recv); return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue); - } catch (RemoteException | TimeoutException e) { + } catch (RemoteException e) { + Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); + throw e.rethrowFromSystemServer(); + } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } } @@ -484,6 +548,7 @@ public final class BluetoothMapClient implements BluetoothProfile { * @return connection policy of the device * @hide */ + @SystemApi @RequiresBluetoothConnectPermission @RequiresPermission(allOf = { android.Manifest.permission.BLUETOOTH_CONNECT, @@ -501,7 +566,10 @@ public final class BluetoothMapClient implements BluetoothProfile { final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver(); service.getConnectionPolicy(device, mAttributionSource, recv); return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue); - } catch (RemoteException | TimeoutException e) { + } catch (RemoteException e) { + Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); + throw e.rethrowFromSystemServer(); + } catch (TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } } |