Merge "Remove allowBlocking from all BluetoothProfiles" am: a39eb360db
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1927380 Change-Id: Ibdf98bd48a34c12d55681124bc19f5bc8f0fe72c
This commit is contained in:
@@ -350,6 +350,7 @@ java_defaults {
|
|||||||
"tv_tuner_resource_manager_aidl_interface-java",
|
"tv_tuner_resource_manager_aidl_interface-java",
|
||||||
"soundtrigger_middleware-aidl-java",
|
"soundtrigger_middleware-aidl-java",
|
||||||
"modules-utils-preconditions",
|
"modules-utils-preconditions",
|
||||||
|
"modules-utils-synchronous-result-receiver",
|
||||||
"modules-utils-os",
|
"modules-utils-os",
|
||||||
"framework-permission-aidl-java",
|
"framework-permission-aidl-java",
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package android.bluetooth;
|
package android.bluetooth;
|
||||||
|
|
||||||
|
import static android.bluetooth.BluetoothUtils.getSyncTimeout;
|
||||||
|
|
||||||
import android.annotation.IntDef;
|
import android.annotation.IntDef;
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
@@ -30,17 +32,19 @@ import android.bluetooth.annotations.RequiresLegacyBluetoothPermission;
|
|||||||
import android.compat.annotation.UnsupportedAppUsage;
|
import android.compat.annotation.UnsupportedAppUsage;
|
||||||
import android.content.AttributionSource;
|
import android.content.AttributionSource;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Binder;
|
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.ParcelUuid;
|
import android.os.ParcelUuid;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.android.modules.utils.SynchronousResultReceiver;
|
||||||
|
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -271,7 +275,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
|
|||||||
IBluetoothA2dp.class.getName()) {
|
IBluetoothA2dp.class.getName()) {
|
||||||
@Override
|
@Override
|
||||||
public IBluetoothA2dp getServiceInterface(IBinder service) {
|
public IBluetoothA2dp getServiceInterface(IBinder service) {
|
||||||
return IBluetoothA2dp.Stub.asInterface(Binder.allowBlocking(service));
|
return IBluetoothA2dp.Stub.asInterface(service);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -322,17 +326,21 @@ public final class BluetoothA2dp implements BluetoothProfile {
|
|||||||
@UnsupportedAppUsage
|
@UnsupportedAppUsage
|
||||||
public boolean connect(BluetoothDevice device) {
|
public boolean connect(BluetoothDevice device) {
|
||||||
if (DBG) log("connect(" + device + ")");
|
if (DBG) log("connect(" + device + ")");
|
||||||
try {
|
|
||||||
final IBluetoothA2dp service = getService();
|
final IBluetoothA2dp service = getService();
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final boolean defaultValue = false;
|
||||||
return service.connect(device);
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
|
service.connectWithAttribution(device, mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
|
||||||
return false;
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -364,17 +372,21 @@ public final class BluetoothA2dp implements BluetoothProfile {
|
|||||||
@UnsupportedAppUsage
|
@UnsupportedAppUsage
|
||||||
public boolean disconnect(BluetoothDevice device) {
|
public boolean disconnect(BluetoothDevice device) {
|
||||||
if (DBG) log("disconnect(" + device + ")");
|
if (DBG) log("disconnect(" + device + ")");
|
||||||
try {
|
|
||||||
final IBluetoothA2dp service = getService();
|
final IBluetoothA2dp service = getService();
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final boolean defaultValue = false;
|
||||||
return service.disconnect(device);
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
|
service.disconnectWithAttribution(device, mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
|
||||||
return false;
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -385,19 +397,24 @@ public final class BluetoothA2dp implements BluetoothProfile {
|
|||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public List<BluetoothDevice> getConnectedDevices() {
|
public List<BluetoothDevice> getConnectedDevices() {
|
||||||
if (VDBG) log("getConnectedDevices()");
|
if (VDBG) log("getConnectedDevices()");
|
||||||
try {
|
|
||||||
final IBluetoothA2dp service = getService();
|
final IBluetoothA2dp service = getService();
|
||||||
if (service != null && isEnabled()) {
|
final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<List<BluetoothDevice>> recv =
|
||||||
|
new SynchronousResultReceiver();
|
||||||
|
service.getConnectedDevicesWithAttribution(mAttributionSource, recv);
|
||||||
return Attributable.setAttributionSource(
|
return Attributable.setAttributionSource(
|
||||||
service.getConnectedDevicesWithAttribution(mAttributionSource),
|
recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
|
||||||
mAttributionSource);
|
mAttributionSource);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
|
||||||
return new ArrayList<BluetoothDevice>();
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
|
||||||
return new ArrayList<BluetoothDevice>();
|
|
||||||
}
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -408,20 +425,25 @@ public final class BluetoothA2dp implements BluetoothProfile {
|
|||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
|
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
|
||||||
if (VDBG) log("getDevicesMatchingStates()");
|
if (VDBG) log("getDevicesMatchingStates()");
|
||||||
try {
|
|
||||||
final IBluetoothA2dp service = getService();
|
final IBluetoothA2dp service = getService();
|
||||||
if (service != null && isEnabled()) {
|
final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
|
||||||
return Attributable.setAttributionSource(
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<List<BluetoothDevice>> recv =
|
||||||
|
new SynchronousResultReceiver();
|
||||||
service.getDevicesMatchingConnectionStatesWithAttribution(states,
|
service.getDevicesMatchingConnectionStatesWithAttribution(states,
|
||||||
mAttributionSource),
|
mAttributionSource, recv);
|
||||||
|
return Attributable.setAttributionSource(
|
||||||
|
recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
|
||||||
mAttributionSource);
|
mAttributionSource);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
|
||||||
return new ArrayList<BluetoothDevice>();
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
|
||||||
return new ArrayList<BluetoothDevice>();
|
|
||||||
}
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -432,18 +454,21 @@ public final class BluetoothA2dp implements BluetoothProfile {
|
|||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public @BtProfileState int getConnectionState(BluetoothDevice device) {
|
public @BtProfileState int getConnectionState(BluetoothDevice device) {
|
||||||
if (VDBG) log("getState(" + device + ")");
|
if (VDBG) log("getState(" + device + ")");
|
||||||
try {
|
|
||||||
final IBluetoothA2dp service = getService();
|
final IBluetoothA2dp service = getService();
|
||||||
if (service != null && isEnabled()
|
final int defaultValue = BluetoothProfile.STATE_DISCONNECTED;
|
||||||
&& isValidDevice(device)) {
|
if (service == null) {
|
||||||
return service.getConnectionState(device);
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
|
||||||
|
service.getConnectionStateWithAttribution(device, mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
|
||||||
return BluetoothProfile.STATE_DISCONNECTED;
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
|
||||||
return BluetoothProfile.STATE_DISCONNECTED;
|
|
||||||
}
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -471,18 +496,21 @@ public final class BluetoothA2dp implements BluetoothProfile {
|
|||||||
@UnsupportedAppUsage(trackingBug = 171933273)
|
@UnsupportedAppUsage(trackingBug = 171933273)
|
||||||
public boolean setActiveDevice(@Nullable BluetoothDevice device) {
|
public boolean setActiveDevice(@Nullable BluetoothDevice device) {
|
||||||
if (DBG) log("setActiveDevice(" + device + ")");
|
if (DBG) log("setActiveDevice(" + device + ")");
|
||||||
try {
|
|
||||||
final IBluetoothA2dp service = getService();
|
final IBluetoothA2dp service = getService();
|
||||||
if (service != null && isEnabled()
|
final boolean defaultValue = false;
|
||||||
&& ((device == null) || isValidDevice(device))) {
|
if (service == null) {
|
||||||
return service.setActiveDevice(device, mAttributionSource);
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && ((device == null) || isValidDevice(device))) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
|
service.setActiveDevice(device, mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
|
||||||
return false;
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -499,18 +527,24 @@ public final class BluetoothA2dp implements BluetoothProfile {
|
|||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public BluetoothDevice getActiveDevice() {
|
public BluetoothDevice getActiveDevice() {
|
||||||
if (VDBG) log("getActiveDevice()");
|
if (VDBG) log("getActiveDevice()");
|
||||||
try {
|
|
||||||
final IBluetoothA2dp service = getService();
|
final IBluetoothA2dp service = getService();
|
||||||
if (service != null && isEnabled()) {
|
final BluetoothDevice defaultValue = null;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<BluetoothDevice> recv =
|
||||||
|
new SynchronousResultReceiver();
|
||||||
|
service.getActiveDevice(mAttributionSource, recv);
|
||||||
return Attributable.setAttributionSource(
|
return Attributable.setAttributionSource(
|
||||||
service.getActiveDevice(mAttributionSource), mAttributionSource);
|
recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
|
||||||
|
mAttributionSource);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
|
||||||
return null;
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -555,22 +589,23 @@ public final class BluetoothA2dp implements BluetoothProfile {
|
|||||||
public boolean setConnectionPolicy(@NonNull BluetoothDevice device,
|
public boolean setConnectionPolicy(@NonNull BluetoothDevice device,
|
||||||
@ConnectionPolicy int connectionPolicy) {
|
@ConnectionPolicy int connectionPolicy) {
|
||||||
if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
|
if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
|
||||||
try {
|
|
||||||
final IBluetoothA2dp service = getService();
|
final IBluetoothA2dp service = getService();
|
||||||
if (service != null && isEnabled()
|
final boolean defaultValue = false;
|
||||||
&& isValidDevice(device)) {
|
if (service == null) {
|
||||||
if (connectionPolicy != BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
&& connectionPolicy != BluetoothProfile.CONNECTION_POLICY_ALLOWED) {
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
return false;
|
} else if (isEnabled() && isValidDevice(device)
|
||||||
|
&& (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
|
||||||
|
|| connectionPolicy == BluetoothProfile.CONNECTION_POLICY_ALLOWED)) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
|
service.setConnectionPolicy(device, connectionPolicy, mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
return service.setConnectionPolicy(device, connectionPolicy, mAttributionSource);
|
|
||||||
}
|
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
|
||||||
return false;
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -589,19 +624,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
|
|||||||
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
|
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
|
||||||
public int getPriority(BluetoothDevice device) {
|
public int getPriority(BluetoothDevice device) {
|
||||||
if (VDBG) log("getPriority(" + device + ")");
|
if (VDBG) log("getPriority(" + device + ")");
|
||||||
try {
|
return BluetoothAdapter.connectionPolicyToPriority(getConnectionPolicy(device));
|
||||||
final IBluetoothA2dp service = getService();
|
|
||||||
if (service != null && isEnabled()
|
|
||||||
&& isValidDevice(device)) {
|
|
||||||
return BluetoothAdapter.connectionPolicyToPriority(
|
|
||||||
service.getPriority(device, mAttributionSource));
|
|
||||||
}
|
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
|
||||||
return BluetoothProfile.PRIORITY_OFF;
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
|
||||||
return BluetoothProfile.PRIORITY_OFF;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -623,18 +646,21 @@ public final class BluetoothA2dp implements BluetoothProfile {
|
|||||||
})
|
})
|
||||||
public @ConnectionPolicy int getConnectionPolicy(@NonNull BluetoothDevice device) {
|
public @ConnectionPolicy int getConnectionPolicy(@NonNull BluetoothDevice device) {
|
||||||
if (VDBG) log("getConnectionPolicy(" + device + ")");
|
if (VDBG) log("getConnectionPolicy(" + device + ")");
|
||||||
try {
|
|
||||||
final IBluetoothA2dp service = getService();
|
final IBluetoothA2dp service = getService();
|
||||||
if (service != null && isEnabled()
|
final int defaultValue = BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
|
||||||
&& isValidDevice(device)) {
|
if (service == null) {
|
||||||
return service.getConnectionPolicy(device, mAttributionSource);
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
|
||||||
|
service.getConnectionPolicy(device, mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
|
||||||
return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
|
||||||
return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
|
|
||||||
}
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -646,17 +672,21 @@ public final class BluetoothA2dp implements BluetoothProfile {
|
|||||||
@RequiresNoPermission
|
@RequiresNoPermission
|
||||||
public boolean isAvrcpAbsoluteVolumeSupported() {
|
public boolean isAvrcpAbsoluteVolumeSupported() {
|
||||||
if (DBG) Log.d(TAG, "isAvrcpAbsoluteVolumeSupported");
|
if (DBG) Log.d(TAG, "isAvrcpAbsoluteVolumeSupported");
|
||||||
try {
|
|
||||||
final IBluetoothA2dp service = getService();
|
final IBluetoothA2dp service = getService();
|
||||||
if (service != null && isEnabled()) {
|
final boolean defaultValue = false;
|
||||||
return service.isAvrcpAbsoluteVolumeSupported();
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
|
service.isAvrcpAbsoluteVolumeSupported(recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
|
||||||
return false;
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Error talking to BT service in isAvrcpAbsoluteVolumeSupported()", e);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -669,14 +699,16 @@ public final class BluetoothA2dp implements BluetoothProfile {
|
|||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public void setAvrcpAbsoluteVolume(int volume) {
|
public void setAvrcpAbsoluteVolume(int volume) {
|
||||||
if (DBG) Log.d(TAG, "setAvrcpAbsoluteVolume");
|
if (DBG) Log.d(TAG, "setAvrcpAbsoluteVolume");
|
||||||
try {
|
|
||||||
final IBluetoothA2dp service = getService();
|
final IBluetoothA2dp service = getService();
|
||||||
if (service != null && isEnabled()) {
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
|
try {
|
||||||
service.setAvrcpAbsoluteVolume(volume, mAttributionSource);
|
service.setAvrcpAbsoluteVolume(volume, mAttributionSource);
|
||||||
}
|
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.e(TAG, "Error talking to BT service in setAvrcpAbsoluteVolume()", e);
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -689,18 +721,22 @@ public final class BluetoothA2dp implements BluetoothProfile {
|
|||||||
@RequiresBluetoothConnectPermission
|
@RequiresBluetoothConnectPermission
|
||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public boolean isA2dpPlaying(BluetoothDevice device) {
|
public boolean isA2dpPlaying(BluetoothDevice device) {
|
||||||
try {
|
if (DBG) log("isA2dpPlaying(" + device + ")");
|
||||||
final IBluetoothA2dp service = getService();
|
final IBluetoothA2dp service = getService();
|
||||||
if (service != null && isEnabled()
|
final boolean defaultValue = false;
|
||||||
&& isValidDevice(device)) {
|
if (service == null) {
|
||||||
return service.isA2dpPlaying(device, mAttributionSource);
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
|
service.isA2dpPlaying(device, mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
|
||||||
return false;
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -729,8 +765,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
|
|||||||
/**
|
/**
|
||||||
* Gets the current codec status (configuration and capability).
|
* Gets the current codec status (configuration and capability).
|
||||||
*
|
*
|
||||||
* @param device the remote Bluetooth device. If null, use the current
|
* @param device the remote Bluetooth device.
|
||||||
* active A2DP Bluetooth device.
|
|
||||||
* @return the current codec status
|
* @return the current codec status
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
@@ -742,26 +777,28 @@ public final class BluetoothA2dp implements BluetoothProfile {
|
|||||||
public BluetoothCodecStatus getCodecStatus(@NonNull BluetoothDevice device) {
|
public BluetoothCodecStatus getCodecStatus(@NonNull BluetoothDevice device) {
|
||||||
if (DBG) Log.d(TAG, "getCodecStatus(" + device + ")");
|
if (DBG) Log.d(TAG, "getCodecStatus(" + device + ")");
|
||||||
verifyDeviceNotNull(device, "getCodecStatus");
|
verifyDeviceNotNull(device, "getCodecStatus");
|
||||||
try {
|
|
||||||
final IBluetoothA2dp service = getService();
|
final IBluetoothA2dp service = getService();
|
||||||
if (service != null && isEnabled()) {
|
final BluetoothCodecStatus defaultValue = null;
|
||||||
return service.getCodecStatus(device, mAttributionSource);
|
|
||||||
}
|
|
||||||
if (service == null) {
|
if (service == null) {
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<BluetoothCodecStatus> recv =
|
||||||
|
new SynchronousResultReceiver();
|
||||||
|
service.getCodecStatus(device, mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Error talking to BT service in getCodecStatus()", e);
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the codec configuration preference.
|
* Sets the codec configuration preference.
|
||||||
*
|
*
|
||||||
* @param device the remote Bluetooth device. If null, use the current
|
* @param device the remote Bluetooth device.
|
||||||
* active A2DP Bluetooth device.
|
|
||||||
* @param codecConfig the codec configuration preference
|
* @param codecConfig the codec configuration preference
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
@@ -777,24 +814,23 @@ public final class BluetoothA2dp implements BluetoothProfile {
|
|||||||
Log.e(TAG, "setCodecConfigPreference: Codec config can't be null");
|
Log.e(TAG, "setCodecConfigPreference: Codec config can't be null");
|
||||||
throw new IllegalArgumentException("codecConfig cannot be null");
|
throw new IllegalArgumentException("codecConfig cannot be null");
|
||||||
}
|
}
|
||||||
try {
|
|
||||||
final IBluetoothA2dp service = getService();
|
final IBluetoothA2dp service = getService();
|
||||||
if (service != null && isEnabled()) {
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
|
try {
|
||||||
service.setCodecConfigPreference(device, codecConfig, mAttributionSource);
|
service.setCodecConfigPreference(device, codecConfig, mAttributionSource);
|
||||||
}
|
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
|
||||||
return;
|
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.e(TAG, "Error talking to BT service in setCodecConfigPreference()", e);
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
return;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enables the optional codecs.
|
* Enables the optional codecs.
|
||||||
*
|
*
|
||||||
* @param device the remote Bluetooth device. If null, use the currect
|
* @param device the remote Bluetooth device.
|
||||||
* active A2DP Bluetooth device.
|
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
|
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
|
||||||
@@ -810,8 +846,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
|
|||||||
/**
|
/**
|
||||||
* Disables the optional codecs.
|
* Disables the optional codecs.
|
||||||
*
|
*
|
||||||
* @param device the remote Bluetooth device. If null, use the currect
|
* @param device the remote Bluetooth device.
|
||||||
* active A2DP Bluetooth device.
|
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
|
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
|
||||||
@@ -827,26 +862,25 @@ public final class BluetoothA2dp implements BluetoothProfile {
|
|||||||
/**
|
/**
|
||||||
* Enables or disables the optional codecs.
|
* Enables or disables the optional codecs.
|
||||||
*
|
*
|
||||||
* @param device the remote Bluetooth device. If null, use the currect
|
* @param device the remote Bluetooth device.
|
||||||
* active A2DP Bluetooth device.
|
|
||||||
* @param enable if true, enable the optional codecs, other disable them
|
* @param enable if true, enable the optional codecs, other disable them
|
||||||
*/
|
*/
|
||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
private void enableDisableOptionalCodecs(BluetoothDevice device, boolean enable) {
|
private void enableDisableOptionalCodecs(BluetoothDevice device, boolean enable) {
|
||||||
try {
|
|
||||||
final IBluetoothA2dp service = getService();
|
final IBluetoothA2dp service = getService();
|
||||||
if (service != null && isEnabled()) {
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
|
try {
|
||||||
if (enable) {
|
if (enable) {
|
||||||
service.enableOptionalCodecs(device, mAttributionSource);
|
service.enableOptionalCodecs(device, mAttributionSource);
|
||||||
} else {
|
} else {
|
||||||
service.disableOptionalCodecs(device, mAttributionSource);
|
service.disableOptionalCodecs(device, mAttributionSource);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
|
||||||
return;
|
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.e(TAG, "Error talking to BT service in enableDisableOptionalCodecs()", e);
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
return;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -864,18 +898,23 @@ public final class BluetoothA2dp implements BluetoothProfile {
|
|||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
@OptionalCodecsSupportStatus
|
@OptionalCodecsSupportStatus
|
||||||
public int isOptionalCodecsSupported(@NonNull BluetoothDevice device) {
|
public int isOptionalCodecsSupported(@NonNull BluetoothDevice device) {
|
||||||
|
if (DBG) log("isOptionalCodecsSupported(" + device + ")");
|
||||||
verifyDeviceNotNull(device, "isOptionalCodecsSupported");
|
verifyDeviceNotNull(device, "isOptionalCodecsSupported");
|
||||||
try {
|
|
||||||
final IBluetoothA2dp service = getService();
|
final IBluetoothA2dp service = getService();
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final int defaultValue = OPTIONAL_CODECS_SUPPORT_UNKNOWN;
|
||||||
return service.supportsOptionalCodecs(device, mAttributionSource);
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
|
||||||
|
service.supportsOptionalCodecs(device, mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
|
||||||
return OPTIONAL_CODECS_SUPPORT_UNKNOWN;
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Error talking to BT service in supportsOptionalCodecs()", e);
|
|
||||||
return OPTIONAL_CODECS_SUPPORT_UNKNOWN;
|
|
||||||
}
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -892,18 +931,23 @@ public final class BluetoothA2dp implements BluetoothProfile {
|
|||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
@OptionalCodecsPreferenceStatus
|
@OptionalCodecsPreferenceStatus
|
||||||
public int isOptionalCodecsEnabled(@NonNull BluetoothDevice device) {
|
public int isOptionalCodecsEnabled(@NonNull BluetoothDevice device) {
|
||||||
|
if (DBG) log("isOptionalCodecsEnabled(" + device + ")");
|
||||||
verifyDeviceNotNull(device, "isOptionalCodecsEnabled");
|
verifyDeviceNotNull(device, "isOptionalCodecsEnabled");
|
||||||
try {
|
|
||||||
final IBluetoothA2dp service = getService();
|
final IBluetoothA2dp service = getService();
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final int defaultValue = OPTIONAL_CODECS_PREF_UNKNOWN;
|
||||||
return service.getOptionalCodecsEnabled(device, mAttributionSource);
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
|
||||||
|
service.getOptionalCodecsEnabled(device, mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
|
||||||
return OPTIONAL_CODECS_PREF_UNKNOWN;
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Error talking to BT service in getOptionalCodecsEnabled()", e);
|
|
||||||
return OPTIONAL_CODECS_PREF_UNKNOWN;
|
|
||||||
}
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -921,8 +965,8 @@ public final class BluetoothA2dp implements BluetoothProfile {
|
|||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public void setOptionalCodecsEnabled(@NonNull BluetoothDevice device,
|
public void setOptionalCodecsEnabled(@NonNull BluetoothDevice device,
|
||||||
@OptionalCodecsPreferenceStatus int value) {
|
@OptionalCodecsPreferenceStatus int value) {
|
||||||
|
if (DBG) log("setOptionalCodecsEnabled(" + device + ")");
|
||||||
verifyDeviceNotNull(device, "setOptionalCodecsEnabled");
|
verifyDeviceNotNull(device, "setOptionalCodecsEnabled");
|
||||||
try {
|
|
||||||
if (value != BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN
|
if (value != BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN
|
||||||
&& value != BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED
|
&& value != BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED
|
||||||
&& value != BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED) {
|
&& value != BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED) {
|
||||||
@@ -930,15 +974,15 @@ public final class BluetoothA2dp implements BluetoothProfile {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final IBluetoothA2dp service = getService();
|
final IBluetoothA2dp service = getService();
|
||||||
if (service != null && isEnabled()
|
if (service == null) {
|
||||||
&& isValidDevice(device)) {
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
|
try {
|
||||||
service.setOptionalCodecsEnabled(device, value, mAttributionSource);
|
service.setOptionalCodecsEnabled(device, value, mAttributionSource);
|
||||||
}
|
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
|
||||||
return;
|
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
return;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -961,17 +1005,21 @@ public final class BluetoothA2dp implements BluetoothProfile {
|
|||||||
})
|
})
|
||||||
public @Type int getDynamicBufferSupport() {
|
public @Type int getDynamicBufferSupport() {
|
||||||
if (VDBG) log("getDynamicBufferSupport()");
|
if (VDBG) log("getDynamicBufferSupport()");
|
||||||
try {
|
|
||||||
final IBluetoothA2dp service = getService();
|
final IBluetoothA2dp service = getService();
|
||||||
if (service != null && isEnabled()) {
|
final int defaultValue = DYNAMIC_BUFFER_SUPPORT_NONE;
|
||||||
return service.getDynamicBufferSupport(mAttributionSource);
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
|
||||||
|
service.getDynamicBufferSupport(mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
|
||||||
return DYNAMIC_BUFFER_SUPPORT_NONE;
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "failed to get getDynamicBufferSupport, error: ", e);
|
|
||||||
return DYNAMIC_BUFFER_SUPPORT_NONE;
|
|
||||||
}
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -992,17 +1040,22 @@ public final class BluetoothA2dp implements BluetoothProfile {
|
|||||||
})
|
})
|
||||||
public @Nullable BufferConstraints getBufferConstraints() {
|
public @Nullable BufferConstraints getBufferConstraints() {
|
||||||
if (VDBG) log("getBufferConstraints()");
|
if (VDBG) log("getBufferConstraints()");
|
||||||
try {
|
|
||||||
final IBluetoothA2dp service = getService();
|
final IBluetoothA2dp service = getService();
|
||||||
if (service != null && isEnabled()) {
|
final BufferConstraints defaultValue = null;
|
||||||
return service.getBufferConstraints(mAttributionSource);
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<BufferConstraints> recv =
|
||||||
|
new SynchronousResultReceiver();
|
||||||
|
service.getBufferConstraints(mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
|
||||||
return null;
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "", e);
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1027,17 +1080,21 @@ public final class BluetoothA2dp implements BluetoothProfile {
|
|||||||
Log.e(TAG, "Trying to set audio buffer length to a negative value: " + value);
|
Log.e(TAG, "Trying to set audio buffer length to a negative value: " + value);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
try {
|
|
||||||
final IBluetoothA2dp service = getService();
|
final IBluetoothA2dp service = getService();
|
||||||
if (service != null && isEnabled()) {
|
final boolean defaultValue = false;
|
||||||
return service.setBufferLengthMillis(codec, value, mAttributionSource);
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
|
service.setBufferLengthMillis(codec, value, mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
|
||||||
return false;
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "", e);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package android.bluetooth;
|
package android.bluetooth;
|
||||||
|
|
||||||
|
import static android.bluetooth.BluetoothUtils.getSyncTimeout;
|
||||||
|
|
||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.RequiresPermission;
|
import android.annotation.RequiresPermission;
|
||||||
@@ -29,14 +31,16 @@ import android.bluetooth.annotations.RequiresLegacyBluetoothPermission;
|
|||||||
import android.compat.annotation.UnsupportedAppUsage;
|
import android.compat.annotation.UnsupportedAppUsage;
|
||||||
import android.content.AttributionSource;
|
import android.content.AttributionSource;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Binder;
|
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.android.modules.utils.SynchronousResultReceiver;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class provides the public APIs to control the Bluetooth A2DP Sink
|
* This class provides the public APIs to control the Bluetooth A2DP Sink
|
||||||
@@ -86,7 +90,7 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
|
|||||||
"BluetoothA2dpSink", IBluetoothA2dpSink.class.getName()) {
|
"BluetoothA2dpSink", IBluetoothA2dpSink.class.getName()) {
|
||||||
@Override
|
@Override
|
||||||
public IBluetoothA2dpSink getServiceInterface(IBinder service) {
|
public IBluetoothA2dpSink getServiceInterface(IBinder service) {
|
||||||
return IBluetoothA2dpSink.Stub.asInterface(Binder.allowBlocking(service));
|
return IBluetoothA2dpSink.Stub.asInterface(service);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -140,16 +144,20 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
|
|||||||
public boolean connect(BluetoothDevice device) {
|
public boolean connect(BluetoothDevice device) {
|
||||||
if (DBG) log("connect(" + device + ")");
|
if (DBG) log("connect(" + device + ")");
|
||||||
final IBluetoothA2dpSink service = getService();
|
final IBluetoothA2dpSink service = getService();
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final boolean defaultValue = false;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.connect(device, mAttributionSource);
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.connect(device, mAttributionSource, recv);
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
return false;
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -181,16 +189,20 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
|
|||||||
public boolean disconnect(BluetoothDevice device) {
|
public boolean disconnect(BluetoothDevice device) {
|
||||||
if (DBG) log("disconnect(" + device + ")");
|
if (DBG) log("disconnect(" + device + ")");
|
||||||
final IBluetoothA2dpSink service = getService();
|
final IBluetoothA2dpSink service = getService();
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final boolean defaultValue = false;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.disconnect(device, mAttributionSource);
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.disconnect(device, mAttributionSource, recv);
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
return false;
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -204,17 +216,23 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
|
|||||||
public List<BluetoothDevice> getConnectedDevices() {
|
public List<BluetoothDevice> getConnectedDevices() {
|
||||||
if (VDBG) log("getConnectedDevices()");
|
if (VDBG) log("getConnectedDevices()");
|
||||||
final IBluetoothA2dpSink service = getService();
|
final IBluetoothA2dpSink service = getService();
|
||||||
if (service != null && isEnabled()) {
|
final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
try {
|
try {
|
||||||
|
final SynchronousResultReceiver<List<BluetoothDevice>> recv =
|
||||||
|
new SynchronousResultReceiver();
|
||||||
|
service.getConnectedDevices(mAttributionSource, recv);
|
||||||
return Attributable.setAttributionSource(
|
return Attributable.setAttributionSource(
|
||||||
service.getConnectedDevices(mAttributionSource), mAttributionSource);
|
recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
|
||||||
} catch (RemoteException e) {
|
mAttributionSource);
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
} catch (RemoteException | TimeoutException e) {
|
||||||
return new ArrayList<BluetoothDevice>();
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return new ArrayList<BluetoothDevice>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -228,18 +246,23 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
|
|||||||
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
|
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
|
||||||
if (VDBG) log("getDevicesMatchingStates()");
|
if (VDBG) log("getDevicesMatchingStates()");
|
||||||
final IBluetoothA2dpSink service = getService();
|
final IBluetoothA2dpSink service = getService();
|
||||||
if (service != null && isEnabled()) {
|
final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
try {
|
try {
|
||||||
|
final SynchronousResultReceiver<List<BluetoothDevice>> recv =
|
||||||
|
new SynchronousResultReceiver();
|
||||||
|
service.getDevicesMatchingConnectionStates(states, mAttributionSource, recv);
|
||||||
return Attributable.setAttributionSource(
|
return Attributable.setAttributionSource(
|
||||||
service.getDevicesMatchingConnectionStates(states, mAttributionSource),
|
recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
|
||||||
mAttributionSource);
|
mAttributionSource);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException | TimeoutException e) {
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
return new ArrayList<BluetoothDevice>();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return new ArrayList<BluetoothDevice>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -251,18 +274,22 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
|
|||||||
@RequiresBluetoothConnectPermission
|
@RequiresBluetoothConnectPermission
|
||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public int getConnectionState(BluetoothDevice device) {
|
public int getConnectionState(BluetoothDevice device) {
|
||||||
if (VDBG) log("getState(" + device + ")");
|
if (VDBG) log("getConnectionState(" + device + ")");
|
||||||
final IBluetoothA2dpSink service = getService();
|
final IBluetoothA2dpSink service = getService();
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final int defaultValue = BluetoothProfile.STATE_DISCONNECTED;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.getConnectionState(device, mAttributionSource);
|
final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.getConnectionState(device, mAttributionSource, recv);
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
return BluetoothProfile.STATE_DISCONNECTED;
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return BluetoothProfile.STATE_DISCONNECTED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -282,16 +309,21 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
|
|||||||
public BluetoothAudioConfig getAudioConfig(BluetoothDevice device) {
|
public BluetoothAudioConfig getAudioConfig(BluetoothDevice device) {
|
||||||
if (VDBG) log("getAudioConfig(" + device + ")");
|
if (VDBG) log("getAudioConfig(" + device + ")");
|
||||||
final IBluetoothA2dpSink service = getService();
|
final IBluetoothA2dpSink service = getService();
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final BluetoothAudioConfig defaultValue = null;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.getAudioConfig(device, mAttributionSource);
|
final SynchronousResultReceiver<BluetoothAudioConfig> recv =
|
||||||
} catch (RemoteException e) {
|
new SynchronousResultReceiver();
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
service.getAudioConfig(device, mAttributionSource, recv);
|
||||||
return null;
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -337,20 +369,22 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
|
|||||||
@ConnectionPolicy int connectionPolicy) {
|
@ConnectionPolicy int connectionPolicy) {
|
||||||
if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
|
if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
|
||||||
final IBluetoothA2dpSink service = getService();
|
final IBluetoothA2dpSink service = getService();
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final boolean defaultValue = false;
|
||||||
if (connectionPolicy != BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
|
if (service == null) {
|
||||||
&& connectionPolicy != BluetoothProfile.CONNECTION_POLICY_ALLOWED) {
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
return false;
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
}
|
} else if (isEnabled() && isValidDevice(device)
|
||||||
|
&& (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
|
||||||
|
|| connectionPolicy == BluetoothProfile.CONNECTION_POLICY_ALLOWED)) {
|
||||||
try {
|
try {
|
||||||
return service.setConnectionPolicy(device, connectionPolicy, mAttributionSource);
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.setConnectionPolicy(device, connectionPolicy, mAttributionSource, recv);
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
return false;
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -393,16 +427,20 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
|
|||||||
public @ConnectionPolicy int getConnectionPolicy(@NonNull BluetoothDevice device) {
|
public @ConnectionPolicy int getConnectionPolicy(@NonNull BluetoothDevice device) {
|
||||||
if (VDBG) log("getConnectionPolicy(" + device + ")");
|
if (VDBG) log("getConnectionPolicy(" + device + ")");
|
||||||
final IBluetoothA2dpSink service = getService();
|
final IBluetoothA2dpSink service = getService();
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final int defaultValue = BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.getConnectionPolicy(device, mAttributionSource);
|
final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.getConnectionPolicy(device, mAttributionSource, recv);
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -420,17 +458,22 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
|
|||||||
android.Manifest.permission.BLUETOOTH_PRIVILEGED,
|
android.Manifest.permission.BLUETOOTH_PRIVILEGED,
|
||||||
})
|
})
|
||||||
public boolean isAudioPlaying(@NonNull BluetoothDevice device) {
|
public boolean isAudioPlaying(@NonNull BluetoothDevice device) {
|
||||||
|
if (VDBG) log("isAudioPlaying(" + device + ")");
|
||||||
final IBluetoothA2dpSink service = getService();
|
final IBluetoothA2dpSink service = getService();
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final boolean defaultValue = false;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.isA2dpPlaying(device, mAttributionSource);
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.isA2dpPlaying(device, mAttributionSource, recv);
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
return false;
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package android.bluetooth;
|
package android.bluetooth;
|
||||||
|
|
||||||
|
import static android.bluetooth.BluetoothUtils.getSyncTimeout;
|
||||||
|
|
||||||
import android.annotation.RequiresPermission;
|
import android.annotation.RequiresPermission;
|
||||||
import android.annotation.SdkConstant;
|
import android.annotation.SdkConstant;
|
||||||
import android.annotation.SdkConstant.SdkConstantType;
|
import android.annotation.SdkConstant.SdkConstantType;
|
||||||
@@ -23,13 +25,15 @@ import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
|
|||||||
import android.bluetooth.annotations.RequiresLegacyBluetoothPermission;
|
import android.bluetooth.annotations.RequiresLegacyBluetoothPermission;
|
||||||
import android.content.AttributionSource;
|
import android.content.AttributionSource;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Binder;
|
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.android.modules.utils.SynchronousResultReceiver;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class provides the public APIs to control the Bluetooth AVRCP Controller. It currently
|
* This class provides the public APIs to control the Bluetooth AVRCP Controller. It currently
|
||||||
@@ -93,8 +97,7 @@ public final class BluetoothAvrcpController implements BluetoothProfile {
|
|||||||
"BluetoothAvrcpController", IBluetoothAvrcpController.class.getName()) {
|
"BluetoothAvrcpController", IBluetoothAvrcpController.class.getName()) {
|
||||||
@Override
|
@Override
|
||||||
public IBluetoothAvrcpController getServiceInterface(IBinder service) {
|
public IBluetoothAvrcpController getServiceInterface(IBinder service) {
|
||||||
return IBluetoothAvrcpController.Stub.asInterface(
|
return IBluetoothAvrcpController.Stub.asInterface(service);
|
||||||
Binder.allowBlocking(service));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -130,19 +133,24 @@ public final class BluetoothAvrcpController implements BluetoothProfile {
|
|||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public List<BluetoothDevice> getConnectedDevices() {
|
public List<BluetoothDevice> getConnectedDevices() {
|
||||||
if (VDBG) log("getConnectedDevices()");
|
if (VDBG) log("getConnectedDevices()");
|
||||||
final IBluetoothAvrcpController service =
|
final IBluetoothAvrcpController service = getService();
|
||||||
getService();
|
final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
|
||||||
if (service != null && isEnabled()) {
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
try {
|
try {
|
||||||
|
final SynchronousResultReceiver<List<BluetoothDevice>> recv =
|
||||||
|
new SynchronousResultReceiver();
|
||||||
|
service.getConnectedDevices(mAttributionSource, recv);
|
||||||
return Attributable.setAttributionSource(
|
return Attributable.setAttributionSource(
|
||||||
service.getConnectedDevices(mAttributionSource), mAttributionSource);
|
recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
|
||||||
} catch (RemoteException e) {
|
mAttributionSource);
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
} catch (RemoteException | TimeoutException e) {
|
||||||
return new ArrayList<BluetoothDevice>();
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return new ArrayList<BluetoothDevice>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -153,20 +161,24 @@ public final class BluetoothAvrcpController implements BluetoothProfile {
|
|||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
|
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
|
||||||
if (VDBG) log("getDevicesMatchingStates()");
|
if (VDBG) log("getDevicesMatchingStates()");
|
||||||
final IBluetoothAvrcpController service =
|
final IBluetoothAvrcpController service = getService();
|
||||||
getService();
|
final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
|
||||||
if (service != null && isEnabled()) {
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
try {
|
try {
|
||||||
|
final SynchronousResultReceiver<List<BluetoothDevice>> recv =
|
||||||
|
new SynchronousResultReceiver();
|
||||||
|
service.getDevicesMatchingConnectionStates(states, mAttributionSource, recv);
|
||||||
return Attributable.setAttributionSource(
|
return Attributable.setAttributionSource(
|
||||||
service.getDevicesMatchingConnectionStates(states, mAttributionSource),
|
recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
|
||||||
mAttributionSource);
|
mAttributionSource);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException | TimeoutException e) {
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
return new ArrayList<BluetoothDevice>();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return new ArrayList<BluetoothDevice>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -177,18 +189,21 @@ public final class BluetoothAvrcpController implements BluetoothProfile {
|
|||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public int getConnectionState(BluetoothDevice device) {
|
public int getConnectionState(BluetoothDevice device) {
|
||||||
if (VDBG) log("getState(" + device + ")");
|
if (VDBG) log("getState(" + device + ")");
|
||||||
final IBluetoothAvrcpController service =
|
final IBluetoothAvrcpController service = getService();
|
||||||
getService();
|
final int defaultValue = BluetoothProfile.STATE_DISCONNECTED;
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.getConnectionState(device, mAttributionSource);
|
final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.getConnectionState(device, mAttributionSource, recv);
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
return BluetoothProfile.STATE_DISCONNECTED;
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return BluetoothProfile.STATE_DISCONNECTED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -201,17 +216,22 @@ public final class BluetoothAvrcpController implements BluetoothProfile {
|
|||||||
public BluetoothAvrcpPlayerSettings getPlayerSettings(BluetoothDevice device) {
|
public BluetoothAvrcpPlayerSettings getPlayerSettings(BluetoothDevice device) {
|
||||||
if (DBG) Log.d(TAG, "getPlayerSettings");
|
if (DBG) Log.d(TAG, "getPlayerSettings");
|
||||||
BluetoothAvrcpPlayerSettings settings = null;
|
BluetoothAvrcpPlayerSettings settings = null;
|
||||||
final IBluetoothAvrcpController service =
|
final IBluetoothAvrcpController service = getService();
|
||||||
getService();
|
final BluetoothAvrcpPlayerSettings defaultValue = null;
|
||||||
if (service != null && isEnabled()) {
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
try {
|
try {
|
||||||
settings = service.getPlayerSettings(device, mAttributionSource);
|
final SynchronousResultReceiver<BluetoothAvrcpPlayerSettings> recv =
|
||||||
} catch (RemoteException e) {
|
new SynchronousResultReceiver();
|
||||||
Log.e(TAG, "Error talking to BT service in getMetadata() " + e);
|
service.getPlayerSettings(device, mAttributionSource, recv);
|
||||||
return null;
|
settings = recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return settings;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -222,18 +242,21 @@ public final class BluetoothAvrcpController implements BluetoothProfile {
|
|||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public boolean setPlayerApplicationSetting(BluetoothAvrcpPlayerSettings plAppSetting) {
|
public boolean setPlayerApplicationSetting(BluetoothAvrcpPlayerSettings plAppSetting) {
|
||||||
if (DBG) Log.d(TAG, "setPlayerApplicationSetting");
|
if (DBG) Log.d(TAG, "setPlayerApplicationSetting");
|
||||||
final IBluetoothAvrcpController service =
|
final IBluetoothAvrcpController service = getService();
|
||||||
getService();
|
final boolean defaultValue = false;
|
||||||
if (service != null && isEnabled()) {
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
try {
|
try {
|
||||||
return service.setPlayerApplicationSetting(plAppSetting, mAttributionSource);
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.setPlayerApplicationSetting(plAppSetting, mAttributionSource, recv);
|
||||||
Log.e(TAG, "Error talking to BT service in setPlayerApplicationSetting() " + e);
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
return false;
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -245,18 +268,20 @@ public final class BluetoothAvrcpController implements BluetoothProfile {
|
|||||||
public void sendGroupNavigationCmd(BluetoothDevice device, int keyCode, int keyState) {
|
public void sendGroupNavigationCmd(BluetoothDevice device, int keyCode, int keyState) {
|
||||||
Log.d(TAG, "sendGroupNavigationCmd dev = " + device + " key " + keyCode + " State = "
|
Log.d(TAG, "sendGroupNavigationCmd dev = " + device + " key " + keyCode + " State = "
|
||||||
+ keyState);
|
+ keyState);
|
||||||
final IBluetoothAvrcpController service =
|
final IBluetoothAvrcpController service = getService();
|
||||||
getService();
|
if (service == null) {
|
||||||
if (service != null && isEnabled()) {
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
try {
|
try {
|
||||||
service.sendGroupNavigationCmd(device, keyCode, keyState, mAttributionSource);
|
final SynchronousResultReceiver recv = new SynchronousResultReceiver();
|
||||||
return;
|
service.sendGroupNavigationCmd(device, keyCode, keyState, mAttributionSource, recv);
|
||||||
} catch (RemoteException e) {
|
recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(null);
|
||||||
Log.e(TAG, "Error talking to BT service in sendGroupNavigationCmd()", e);
|
|
||||||
return;
|
return;
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isEnabled() {
|
private boolean isEnabled() {
|
||||||
|
|||||||
@@ -17,6 +17,8 @@
|
|||||||
|
|
||||||
package android.bluetooth;
|
package android.bluetooth;
|
||||||
|
|
||||||
|
import static android.bluetooth.BluetoothUtils.getSyncTimeout;
|
||||||
|
|
||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
import android.annotation.CallbackExecutor;
|
import android.annotation.CallbackExecutor;
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
@@ -27,13 +29,14 @@ import android.annotation.SdkConstant.SdkConstantType;
|
|||||||
import android.annotation.SystemApi;
|
import android.annotation.SystemApi;
|
||||||
import android.content.AttributionSource;
|
import android.content.AttributionSource;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Binder;
|
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.ParcelUuid;
|
import android.os.ParcelUuid;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.util.CloseGuard;
|
import android.util.CloseGuard;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.android.modules.utils.SynchronousResultReceiver;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@@ -41,6 +44,7 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class provides the public APIs to control the Bluetooth CSIP set coordinator.
|
* This class provides the public APIs to control the Bluetooth CSIP set coordinator.
|
||||||
@@ -229,8 +233,7 @@ public final class BluetoothCsipSetCoordinator implements BluetoothProfile, Auto
|
|||||||
IBluetoothCsipSetCoordinator.class.getName()) {
|
IBluetoothCsipSetCoordinator.class.getName()) {
|
||||||
@Override
|
@Override
|
||||||
public IBluetoothCsipSetCoordinator getServiceInterface(IBinder service) {
|
public IBluetoothCsipSetCoordinator getServiceInterface(IBinder service) {
|
||||||
return IBluetoothCsipSetCoordinator.Stub.asInterface(
|
return IBluetoothCsipSetCoordinator.Stub.asInterface(service);
|
||||||
Binder.allowBlocking(service));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -283,26 +286,27 @@ public final class BluetoothCsipSetCoordinator implements BluetoothProfile, Auto
|
|||||||
public
|
public
|
||||||
@Nullable UUID groupLock(int groupId, @Nullable @CallbackExecutor Executor executor,
|
@Nullable UUID groupLock(int groupId, @Nullable @CallbackExecutor Executor executor,
|
||||||
@Nullable ClientLockCallback cb) {
|
@Nullable ClientLockCallback cb) {
|
||||||
if (VDBG) {
|
if (VDBG) log("groupLockSet()");
|
||||||
log("groupLockSet()");
|
|
||||||
}
|
|
||||||
final IBluetoothCsipSetCoordinator service = getService();
|
final IBluetoothCsipSetCoordinator service = getService();
|
||||||
try {
|
final UUID defaultValue = null;
|
||||||
if (service != null && isEnabled()) {
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
IBluetoothCsipSetCoordinatorLockCallback delegate = null;
|
IBluetoothCsipSetCoordinatorLockCallback delegate = null;
|
||||||
if ((executor != null) && (cb != null)) {
|
if ((executor != null) && (cb != null)) {
|
||||||
delegate = new BluetoothCsipSetCoordinatorLockCallbackDelegate(executor, cb);
|
delegate = new BluetoothCsipSetCoordinatorLockCallbackDelegate(executor, cb);
|
||||||
}
|
}
|
||||||
return service.groupLock(groupId, delegate, mAttributionSource).getUuid();
|
try {
|
||||||
|
final SynchronousResultReceiver<ParcelUuid> recv = new SynchronousResultReceiver();
|
||||||
|
service.groupLock(groupId, delegate, mAttributionSource, recv);
|
||||||
|
final ParcelUuid ret = recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(null);
|
||||||
|
return ret == null ? defaultValue : ret.getUuid();
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
if (service == null) {
|
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -315,27 +319,26 @@ public final class BluetoothCsipSetCoordinator implements BluetoothProfile, Auto
|
|||||||
@SystemApi
|
@SystemApi
|
||||||
@RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
|
@RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
|
||||||
public boolean groupUnlock(@NonNull UUID lockUuid) {
|
public boolean groupUnlock(@NonNull UUID lockUuid) {
|
||||||
if (VDBG) {
|
if (VDBG) log("groupLockSet()");
|
||||||
log("groupLockSet()");
|
|
||||||
}
|
|
||||||
if (lockUuid == null) {
|
if (lockUuid == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
final IBluetoothCsipSetCoordinator service = getService();
|
final IBluetoothCsipSetCoordinator service = getService();
|
||||||
try {
|
final boolean defaultValue = false;
|
||||||
if (service != null && isEnabled()) {
|
|
||||||
service.groupUnlock(new ParcelUuid(lockUuid), mAttributionSource);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (service == null) {
|
if (service == null) {
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver recv = new SynchronousResultReceiver();
|
||||||
|
service.groupUnlock(new ParcelUuid(lockUuid), mAttributionSource, recv);
|
||||||
|
recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(null);
|
||||||
|
return true;
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -348,22 +351,22 @@ public final class BluetoothCsipSetCoordinator implements BluetoothProfile, Auto
|
|||||||
@SystemApi
|
@SystemApi
|
||||||
@RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
|
@RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
|
||||||
public @NonNull Map getGroupUuidMapByDevice(@Nullable BluetoothDevice device) {
|
public @NonNull Map getGroupUuidMapByDevice(@Nullable BluetoothDevice device) {
|
||||||
if (VDBG) {
|
if (VDBG) log("getGroupUuidMapByDevice()");
|
||||||
log("getGroupUuidMapByDevice()");
|
|
||||||
}
|
|
||||||
final IBluetoothCsipSetCoordinator service = getService();
|
final IBluetoothCsipSetCoordinator service = getService();
|
||||||
try {
|
final Map defaultValue = new HashMap<>();
|
||||||
if (service != null && isEnabled()) {
|
|
||||||
return service.getGroupUuidMapByDevice(device, mAttributionSource);
|
|
||||||
}
|
|
||||||
if (service == null) {
|
if (service == null) {
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Map> recv = new SynchronousResultReceiver();
|
||||||
|
service.getGroupUuidMapByDevice(device, mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
return new HashMap<>();
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
|
||||||
return new HashMap<>();
|
|
||||||
}
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -376,22 +379,23 @@ public final class BluetoothCsipSetCoordinator implements BluetoothProfile, Auto
|
|||||||
@SystemApi
|
@SystemApi
|
||||||
@RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
|
@RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
|
||||||
public @NonNull List<Integer> getAllGroupIds(@Nullable ParcelUuid uuid) {
|
public @NonNull List<Integer> getAllGroupIds(@Nullable ParcelUuid uuid) {
|
||||||
if (VDBG) {
|
if (VDBG) log("getAllGroupIds()");
|
||||||
log("getAllGroupIds()");
|
|
||||||
}
|
|
||||||
final IBluetoothCsipSetCoordinator service = getService();
|
final IBluetoothCsipSetCoordinator service = getService();
|
||||||
try {
|
final List<Integer> defaultValue = new ArrayList<>();
|
||||||
if (service != null && isEnabled()) {
|
|
||||||
return service.getAllGroupIds(uuid, mAttributionSource);
|
|
||||||
}
|
|
||||||
if (service == null) {
|
if (service == null) {
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<List<Integer>> recv =
|
||||||
|
new SynchronousResultReceiver();
|
||||||
|
service.getAllGroupIds(uuid, mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
return new ArrayList<Integer>();
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
|
||||||
return new ArrayList<Integer>();
|
|
||||||
}
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -399,22 +403,23 @@ public final class BluetoothCsipSetCoordinator implements BluetoothProfile, Auto
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public @NonNull List<BluetoothDevice> getConnectedDevices() {
|
public @NonNull List<BluetoothDevice> getConnectedDevices() {
|
||||||
if (VDBG) {
|
if (VDBG) log("getConnectedDevices()");
|
||||||
log("getConnectedDevices()");
|
|
||||||
}
|
|
||||||
final IBluetoothCsipSetCoordinator service = getService();
|
final IBluetoothCsipSetCoordinator service = getService();
|
||||||
if (service != null && isEnabled()) {
|
final List<BluetoothDevice> defaultValue = new ArrayList<>();
|
||||||
try {
|
|
||||||
return service.getConnectedDevices(mAttributionSource);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
|
||||||
return new ArrayList<BluetoothDevice>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (service == null) {
|
if (service == null) {
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<List<BluetoothDevice>> recv =
|
||||||
|
new SynchronousResultReceiver();
|
||||||
|
service.getConnectedDevices(mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
return new ArrayList<BluetoothDevice>();
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -422,24 +427,24 @@ public final class BluetoothCsipSetCoordinator implements BluetoothProfile, Auto
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public
|
public
|
||||||
@NonNull List<BluetoothDevice> getDevicesMatchingConnectionStates(
|
@NonNull List<BluetoothDevice> getDevicesMatchingConnectionStates(@NonNull int[] states) {
|
||||||
@NonNull int[] states) {
|
if (VDBG) log("getDevicesMatchingStates(states=" + Arrays.toString(states) + ")");
|
||||||
if (VDBG) {
|
|
||||||
log("getDevicesMatchingStates(states=" + Arrays.toString(states) + ")");
|
|
||||||
}
|
|
||||||
final IBluetoothCsipSetCoordinator service = getService();
|
final IBluetoothCsipSetCoordinator service = getService();
|
||||||
if (service != null && isEnabled()) {
|
final List<BluetoothDevice> defaultValue = new ArrayList<>();
|
||||||
try {
|
|
||||||
return service.getDevicesMatchingConnectionStates(states, mAttributionSource);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
|
||||||
return new ArrayList<BluetoothDevice>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (service == null) {
|
if (service == null) {
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<List<BluetoothDevice>> recv =
|
||||||
|
new SynchronousResultReceiver();
|
||||||
|
service.getDevicesMatchingConnectionStates(states, mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
return new ArrayList<BluetoothDevice>();
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -447,24 +452,23 @@ public final class BluetoothCsipSetCoordinator implements BluetoothProfile, Auto
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public
|
public
|
||||||
@BluetoothProfile.BtProfileState int getConnectionState(
|
@BluetoothProfile.BtProfileState int getConnectionState(@Nullable BluetoothDevice device) {
|
||||||
@Nullable BluetoothDevice device) {
|
if (VDBG) log("getState(" + device + ")");
|
||||||
if (VDBG) {
|
|
||||||
log("getState(" + device + ")");
|
|
||||||
}
|
|
||||||
final IBluetoothCsipSetCoordinator service = getService();
|
final IBluetoothCsipSetCoordinator service = getService();
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final int defaultValue = BluetoothProfile.STATE_DISCONNECTED;
|
||||||
try {
|
|
||||||
return service.getConnectionState(device, mAttributionSource);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
|
||||||
return BluetoothProfile.STATE_DISCONNECTED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (service == null) {
|
if (service == null) {
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
|
||||||
|
service.getConnectionState(device, mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
return BluetoothProfile.STATE_DISCONNECTED;
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -484,26 +488,24 @@ public final class BluetoothCsipSetCoordinator implements BluetoothProfile, Auto
|
|||||||
@RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
|
@RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
|
||||||
public boolean setConnectionPolicy(
|
public boolean setConnectionPolicy(
|
||||||
@Nullable BluetoothDevice device, @ConnectionPolicy int connectionPolicy) {
|
@Nullable BluetoothDevice device, @ConnectionPolicy int connectionPolicy) {
|
||||||
if (DBG) {
|
if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
|
||||||
log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
|
|
||||||
}
|
|
||||||
final IBluetoothCsipSetCoordinator service = getService();
|
final IBluetoothCsipSetCoordinator service = getService();
|
||||||
try {
|
final boolean defaultValue = false;
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
|
||||||
if (connectionPolicy != BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
|
|
||||||
&& connectionPolicy != BluetoothProfile.CONNECTION_POLICY_ALLOWED) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return service.setConnectionPolicy(device, connectionPolicy, mAttributionSource);
|
|
||||||
}
|
|
||||||
if (service == null) {
|
if (service == null) {
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)
|
||||||
|
&& (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
|
||||||
|
|| connectionPolicy == BluetoothProfile.CONNECTION_POLICY_ALLOWED)) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
|
service.setConnectionPolicy(device, connectionPolicy, mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -521,22 +523,22 @@ public final class BluetoothCsipSetCoordinator implements BluetoothProfile, Auto
|
|||||||
@SystemApi
|
@SystemApi
|
||||||
@RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
|
@RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
|
||||||
public @ConnectionPolicy int getConnectionPolicy(@Nullable BluetoothDevice device) {
|
public @ConnectionPolicy int getConnectionPolicy(@Nullable BluetoothDevice device) {
|
||||||
if (VDBG) {
|
if (VDBG) log("getConnectionPolicy(" + device + ")");
|
||||||
log("getConnectionPolicy(" + device + ")");
|
|
||||||
}
|
|
||||||
final IBluetoothCsipSetCoordinator service = getService();
|
final IBluetoothCsipSetCoordinator service = getService();
|
||||||
try {
|
final int defaultValue = BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
|
||||||
return service.getConnectionPolicy(device, mAttributionSource);
|
|
||||||
}
|
|
||||||
if (service == null) {
|
if (service == null) {
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
|
||||||
|
service.getConnectionPolicy(device, mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
|
||||||
return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
|
|
||||||
}
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isEnabled() {
|
private boolean isEnabled() {
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package android.bluetooth;
|
package android.bluetooth;
|
||||||
|
|
||||||
|
import static android.bluetooth.BluetoothUtils.getSyncTimeout;
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.annotation.RequiresPermission;
|
import android.annotation.RequiresPermission;
|
||||||
@@ -31,7 +33,6 @@ import android.content.AttributionSource;
|
|||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.os.Binder;
|
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
@@ -41,8 +42,11 @@ import android.os.RemoteException;
|
|||||||
import android.util.CloseGuard;
|
import android.util.CloseGuard;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.android.modules.utils.SynchronousResultReceiver;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Public API for controlling the Bluetooth Headset Service. This includes both
|
* Public API for controlling the Bluetooth Headset Service. This includes both
|
||||||
@@ -479,16 +483,20 @@ public final class BluetoothHeadset implements BluetoothProfile {
|
|||||||
public boolean connect(BluetoothDevice device) {
|
public boolean connect(BluetoothDevice device) {
|
||||||
if (DBG) log("connect(" + device + ")");
|
if (DBG) log("connect(" + device + ")");
|
||||||
final IBluetoothHeadset service = mService;
|
final IBluetoothHeadset service = mService;
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final boolean defaultValue = false;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.connect(device);
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.connectWithAttribution(device, mAttributionSource, recv);
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
return false;
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -520,16 +528,20 @@ public final class BluetoothHeadset implements BluetoothProfile {
|
|||||||
public boolean disconnect(BluetoothDevice device) {
|
public boolean disconnect(BluetoothDevice device) {
|
||||||
if (DBG) log("disconnect(" + device + ")");
|
if (DBG) log("disconnect(" + device + ")");
|
||||||
final IBluetoothHeadset service = mService;
|
final IBluetoothHeadset service = mService;
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final boolean defaultValue = false;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.disconnect(device);
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.disconnectWithAttribution(device, mAttributionSource, recv);
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
return false;
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -541,18 +553,23 @@ public final class BluetoothHeadset implements BluetoothProfile {
|
|||||||
public List<BluetoothDevice> getConnectedDevices() {
|
public List<BluetoothDevice> getConnectedDevices() {
|
||||||
if (VDBG) log("getConnectedDevices()");
|
if (VDBG) log("getConnectedDevices()");
|
||||||
final IBluetoothHeadset service = mService;
|
final IBluetoothHeadset service = mService;
|
||||||
if (service != null && isEnabled()) {
|
final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
try {
|
try {
|
||||||
|
final SynchronousResultReceiver<List<BluetoothDevice>> recv =
|
||||||
|
new SynchronousResultReceiver();
|
||||||
|
service.getConnectedDevicesWithAttribution(mAttributionSource, recv);
|
||||||
return Attributable.setAttributionSource(
|
return Attributable.setAttributionSource(
|
||||||
service.getConnectedDevicesWithAttribution(mAttributionSource),
|
recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
|
||||||
mAttributionSource);
|
mAttributionSource);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException | TimeoutException e) {
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
return new ArrayList<BluetoothDevice>();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return new ArrayList<BluetoothDevice>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -564,18 +581,23 @@ public final class BluetoothHeadset implements BluetoothProfile {
|
|||||||
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
|
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
|
||||||
if (VDBG) log("getDevicesMatchingStates()");
|
if (VDBG) log("getDevicesMatchingStates()");
|
||||||
final IBluetoothHeadset service = mService;
|
final IBluetoothHeadset service = mService;
|
||||||
if (service != null && isEnabled()) {
|
final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
try {
|
try {
|
||||||
|
final SynchronousResultReceiver<List<BluetoothDevice>> recv =
|
||||||
|
new SynchronousResultReceiver();
|
||||||
|
service.getDevicesMatchingConnectionStates(states, mAttributionSource, recv);
|
||||||
return Attributable.setAttributionSource(
|
return Attributable.setAttributionSource(
|
||||||
service.getDevicesMatchingConnectionStates(states, mAttributionSource),
|
recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
|
||||||
mAttributionSource);
|
mAttributionSource);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException | TimeoutException e) {
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
return new ArrayList<BluetoothDevice>();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return new ArrayList<BluetoothDevice>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -587,16 +609,20 @@ public final class BluetoothHeadset implements BluetoothProfile {
|
|||||||
public int getConnectionState(BluetoothDevice device) {
|
public int getConnectionState(BluetoothDevice device) {
|
||||||
if (VDBG) log("getConnectionState(" + device + ")");
|
if (VDBG) log("getConnectionState(" + device + ")");
|
||||||
final IBluetoothHeadset service = mService;
|
final IBluetoothHeadset service = mService;
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final int defaultValue = BluetoothProfile.STATE_DISCONNECTED;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.getConnectionState(device);
|
final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.getConnectionStateWithAttribution(device, mAttributionSource, recv);
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
return BluetoothProfile.STATE_DISCONNECTED;
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return BluetoothProfile.STATE_DISCONNECTED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -623,23 +649,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
|
|||||||
})
|
})
|
||||||
public boolean setPriority(BluetoothDevice device, int priority) {
|
public boolean setPriority(BluetoothDevice device, int priority) {
|
||||||
if (DBG) log("setPriority(" + device + ", " + priority + ")");
|
if (DBG) log("setPriority(" + device + ", " + priority + ")");
|
||||||
final IBluetoothHeadset service = mService;
|
return setConnectionPolicy(device, BluetoothAdapter.priorityToConnectionPolicy(priority));
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
|
||||||
if (priority != BluetoothProfile.PRIORITY_OFF
|
|
||||||
&& priority != BluetoothProfile.PRIORITY_ON) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
return service.setPriority(
|
|
||||||
device, BluetoothAdapter.priorityToConnectionPolicy(priority),
|
|
||||||
mAttributionSource);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -665,20 +675,22 @@ public final class BluetoothHeadset implements BluetoothProfile {
|
|||||||
@ConnectionPolicy int connectionPolicy) {
|
@ConnectionPolicy int connectionPolicy) {
|
||||||
if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
|
if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
|
||||||
final IBluetoothHeadset service = mService;
|
final IBluetoothHeadset service = mService;
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final boolean defaultValue = false;
|
||||||
if (connectionPolicy != BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
|
if (service == null) {
|
||||||
&& connectionPolicy != BluetoothProfile.CONNECTION_POLICY_ALLOWED) {
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
return false;
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
}
|
} else if (isEnabled() && isValidDevice(device)
|
||||||
|
&& (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
|
||||||
|
|| connectionPolicy == BluetoothProfile.CONNECTION_POLICY_ALLOWED)) {
|
||||||
try {
|
try {
|
||||||
return service.setConnectionPolicy(device, connectionPolicy, mAttributionSource);
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.setConnectionPolicy(device, connectionPolicy, mAttributionSource, recv);
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
return false;
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -698,18 +710,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
|
|||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public int getPriority(BluetoothDevice device) {
|
public int getPriority(BluetoothDevice device) {
|
||||||
if (VDBG) log("getPriority(" + device + ")");
|
if (VDBG) log("getPriority(" + device + ")");
|
||||||
final IBluetoothHeadset service = mService;
|
return BluetoothAdapter.connectionPolicyToPriority(getConnectionPolicy(device));
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
|
||||||
try {
|
|
||||||
return BluetoothAdapter.connectionPolicyToPriority(
|
|
||||||
service.getPriority(device, mAttributionSource));
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
|
||||||
return BluetoothProfile.PRIORITY_OFF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
|
||||||
return BluetoothProfile.PRIORITY_OFF;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -732,16 +733,20 @@ public final class BluetoothHeadset implements BluetoothProfile {
|
|||||||
public @ConnectionPolicy int getConnectionPolicy(@NonNull BluetoothDevice device) {
|
public @ConnectionPolicy int getConnectionPolicy(@NonNull BluetoothDevice device) {
|
||||||
if (VDBG) log("getConnectionPolicy(" + device + ")");
|
if (VDBG) log("getConnectionPolicy(" + device + ")");
|
||||||
final IBluetoothHeadset service = mService;
|
final IBluetoothHeadset service = mService;
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final int defaultValue = BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.getConnectionPolicy(device, mAttributionSource);
|
final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.getConnectionPolicy(device, mAttributionSource, recv);
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -756,15 +761,20 @@ public final class BluetoothHeadset implements BluetoothProfile {
|
|||||||
public boolean isNoiseReductionSupported(@NonNull BluetoothDevice device) {
|
public boolean isNoiseReductionSupported(@NonNull BluetoothDevice device) {
|
||||||
if (DBG) log("isNoiseReductionSupported()");
|
if (DBG) log("isNoiseReductionSupported()");
|
||||||
final IBluetoothHeadset service = mService;
|
final IBluetoothHeadset service = mService;
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final boolean defaultValue = false;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.isNoiseReductionSupported(device, mAttributionSource);
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.isNoiseReductionSupported(device, mAttributionSource, recv);
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -779,15 +789,20 @@ public final class BluetoothHeadset implements BluetoothProfile {
|
|||||||
public boolean isVoiceRecognitionSupported(@NonNull BluetoothDevice device) {
|
public boolean isVoiceRecognitionSupported(@NonNull BluetoothDevice device) {
|
||||||
if (DBG) log("isVoiceRecognitionSupported()");
|
if (DBG) log("isVoiceRecognitionSupported()");
|
||||||
final IBluetoothHeadset service = mService;
|
final IBluetoothHeadset service = mService;
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final boolean defaultValue = false;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.isVoiceRecognitionSupported(device, mAttributionSource);
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.isVoiceRecognitionSupported(device, mAttributionSource, recv);
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -818,15 +833,20 @@ public final class BluetoothHeadset implements BluetoothProfile {
|
|||||||
public boolean startVoiceRecognition(BluetoothDevice device) {
|
public boolean startVoiceRecognition(BluetoothDevice device) {
|
||||||
if (DBG) log("startVoiceRecognition()");
|
if (DBG) log("startVoiceRecognition()");
|
||||||
final IBluetoothHeadset service = mService;
|
final IBluetoothHeadset service = mService;
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final boolean defaultValue = false;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.startVoiceRecognition(device, mAttributionSource);
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.startVoiceRecognition(device, mAttributionSource, recv);
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -847,15 +867,20 @@ public final class BluetoothHeadset implements BluetoothProfile {
|
|||||||
public boolean stopVoiceRecognition(BluetoothDevice device) {
|
public boolean stopVoiceRecognition(BluetoothDevice device) {
|
||||||
if (DBG) log("stopVoiceRecognition()");
|
if (DBG) log("stopVoiceRecognition()");
|
||||||
final IBluetoothHeadset service = mService;
|
final IBluetoothHeadset service = mService;
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final boolean defaultValue = false;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.stopVoiceRecognition(device, mAttributionSource);
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.stopVoiceRecognition(device, mAttributionSource, recv);
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -870,15 +895,20 @@ public final class BluetoothHeadset implements BluetoothProfile {
|
|||||||
public boolean isAudioConnected(BluetoothDevice device) {
|
public boolean isAudioConnected(BluetoothDevice device) {
|
||||||
if (VDBG) log("isAudioConnected()");
|
if (VDBG) log("isAudioConnected()");
|
||||||
final IBluetoothHeadset service = mService;
|
final IBluetoothHeadset service = mService;
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final boolean defaultValue = false;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.isAudioConnected(device, mAttributionSource);
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.isAudioConnected(device, mAttributionSource, recv);
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -904,17 +934,20 @@ public final class BluetoothHeadset implements BluetoothProfile {
|
|||||||
public int getAudioState(BluetoothDevice device) {
|
public int getAudioState(BluetoothDevice device) {
|
||||||
if (VDBG) log("getAudioState");
|
if (VDBG) log("getAudioState");
|
||||||
final IBluetoothHeadset service = mService;
|
final IBluetoothHeadset service = mService;
|
||||||
if (service != null && !isDisabled()) {
|
final int defaultValue = BluetoothHeadset.STATE_AUDIO_DISCONNECTED;
|
||||||
try {
|
if (service == null) {
|
||||||
return service.getAudioState(device, mAttributionSource);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, e.toString());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (!isDisabled()) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
|
||||||
|
service.getAudioState(device, mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
return BluetoothHeadset.STATE_AUDIO_DISCONNECTED;
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -932,15 +965,17 @@ public final class BluetoothHeadset implements BluetoothProfile {
|
|||||||
public void setAudioRouteAllowed(boolean allowed) {
|
public void setAudioRouteAllowed(boolean allowed) {
|
||||||
if (VDBG) log("setAudioRouteAllowed");
|
if (VDBG) log("setAudioRouteAllowed");
|
||||||
final IBluetoothHeadset service = mService;
|
final IBluetoothHeadset service = mService;
|
||||||
if (service != null && isEnabled()) {
|
if (service == null) {
|
||||||
try {
|
|
||||||
service.setAudioRouteAllowed(allowed, mAttributionSource);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, e.toString());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver recv = new SynchronousResultReceiver();
|
||||||
|
service.setAudioRouteAllowed(allowed, mAttributionSource, recv);
|
||||||
|
recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(null);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -955,17 +990,20 @@ public final class BluetoothHeadset implements BluetoothProfile {
|
|||||||
public boolean getAudioRouteAllowed() {
|
public boolean getAudioRouteAllowed() {
|
||||||
if (VDBG) log("getAudioRouteAllowed");
|
if (VDBG) log("getAudioRouteAllowed");
|
||||||
final IBluetoothHeadset service = mService;
|
final IBluetoothHeadset service = mService;
|
||||||
if (service != null && isEnabled()) {
|
final boolean defaultValue = false;
|
||||||
try {
|
if (service == null) {
|
||||||
return service.getAudioRouteAllowed(mAttributionSource);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, e.toString());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
|
service.getAudioRouteAllowed(mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
return false;
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -980,15 +1018,17 @@ public final class BluetoothHeadset implements BluetoothProfile {
|
|||||||
public void setForceScoAudio(boolean forced) {
|
public void setForceScoAudio(boolean forced) {
|
||||||
if (VDBG) log("setForceScoAudio " + String.valueOf(forced));
|
if (VDBG) log("setForceScoAudio " + String.valueOf(forced));
|
||||||
final IBluetoothHeadset service = mService;
|
final IBluetoothHeadset service = mService;
|
||||||
if (service != null && isEnabled()) {
|
if (service == null) {
|
||||||
try {
|
|
||||||
service.setForceScoAudio(forced, mAttributionSource);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, e.toString());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver recv = new SynchronousResultReceiver();
|
||||||
|
service.setForceScoAudio(forced, mAttributionSource, recv);
|
||||||
|
recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(null);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1005,16 +1045,20 @@ public final class BluetoothHeadset implements BluetoothProfile {
|
|||||||
public boolean isAudioOn() {
|
public boolean isAudioOn() {
|
||||||
if (VDBG) log("isAudioOn()");
|
if (VDBG) log("isAudioOn()");
|
||||||
final IBluetoothHeadset service = mService;
|
final IBluetoothHeadset service = mService;
|
||||||
if (service != null && isEnabled()) {
|
final boolean defaultValue = false;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
try {
|
try {
|
||||||
return service.isAudioOn(mAttributionSource);
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.isAudioOn(mAttributionSource, recv);
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return false;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1039,18 +1083,22 @@ public final class BluetoothHeadset implements BluetoothProfile {
|
|||||||
@RequiresBluetoothConnectPermission
|
@RequiresBluetoothConnectPermission
|
||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public boolean connectAudio() {
|
public boolean connectAudio() {
|
||||||
|
if (VDBG) log("connectAudio()");
|
||||||
final IBluetoothHeadset service = mService;
|
final IBluetoothHeadset service = mService;
|
||||||
if (service != null && isEnabled()) {
|
final boolean defaultValue = false;
|
||||||
try {
|
if (service == null) {
|
||||||
return service.connectAudio(mAttributionSource);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, e.toString());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
|
service.connectAudio(mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
return false;
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1068,18 +1116,22 @@ public final class BluetoothHeadset implements BluetoothProfile {
|
|||||||
@RequiresBluetoothConnectPermission
|
@RequiresBluetoothConnectPermission
|
||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public boolean disconnectAudio() {
|
public boolean disconnectAudio() {
|
||||||
|
if (VDBG) log("disconnectAudio()");
|
||||||
final IBluetoothHeadset service = mService;
|
final IBluetoothHeadset service = mService;
|
||||||
if (service != null && isEnabled()) {
|
final boolean defaultValue = false;
|
||||||
try {
|
if (service == null) {
|
||||||
return service.disconnectAudio(mAttributionSource);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, e.toString());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
|
service.disconnectAudio(mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
return false;
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1113,17 +1165,20 @@ public final class BluetoothHeadset implements BluetoothProfile {
|
|||||||
public boolean startScoUsingVirtualVoiceCall() {
|
public boolean startScoUsingVirtualVoiceCall() {
|
||||||
if (DBG) log("startScoUsingVirtualVoiceCall()");
|
if (DBG) log("startScoUsingVirtualVoiceCall()");
|
||||||
final IBluetoothHeadset service = mService;
|
final IBluetoothHeadset service = mService;
|
||||||
if (service != null && isEnabled()) {
|
final boolean defaultValue = false;
|
||||||
try {
|
if (service == null) {
|
||||||
return service.startScoUsingVirtualVoiceCall(mAttributionSource);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, e.toString());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
|
service.startScoUsingVirtualVoiceCall(mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
return false;
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1148,17 +1203,20 @@ public final class BluetoothHeadset implements BluetoothProfile {
|
|||||||
public boolean stopScoUsingVirtualVoiceCall() {
|
public boolean stopScoUsingVirtualVoiceCall() {
|
||||||
if (DBG) log("stopScoUsingVirtualVoiceCall()");
|
if (DBG) log("stopScoUsingVirtualVoiceCall()");
|
||||||
final IBluetoothHeadset service = mService;
|
final IBluetoothHeadset service = mService;
|
||||||
if (service != null && isEnabled()) {
|
final boolean defaultValue = false;
|
||||||
try {
|
if (service == null) {
|
||||||
return service.stopScoUsingVirtualVoiceCall(mAttributionSource);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, e.toString());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
|
service.stopScoUsingVirtualVoiceCall(mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
return false;
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1178,16 +1236,16 @@ public final class BluetoothHeadset implements BluetoothProfile {
|
|||||||
public void phoneStateChanged(int numActive, int numHeld, int callState, String number,
|
public void phoneStateChanged(int numActive, int numHeld, int callState, String number,
|
||||||
int type, String name) {
|
int type, String name) {
|
||||||
final IBluetoothHeadset service = mService;
|
final IBluetoothHeadset service = mService;
|
||||||
if (service != null && isEnabled()) {
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
try {
|
try {
|
||||||
service.phoneStateChanged(numActive, numHeld, callState, number, type, name,
|
service.phoneStateChanged(numActive, numHeld, callState, number, type, name,
|
||||||
mAttributionSource);
|
mAttributionSource);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.e(TAG, e.toString());
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
|
||||||
if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1204,16 +1262,18 @@ public final class BluetoothHeadset implements BluetoothProfile {
|
|||||||
public void clccResponse(int index, int direction, int status, int mode, boolean mpty,
|
public void clccResponse(int index, int direction, int status, int mode, boolean mpty,
|
||||||
String number, int type) {
|
String number, int type) {
|
||||||
final IBluetoothHeadset service = mService;
|
final IBluetoothHeadset service = mService;
|
||||||
if (service != null && isEnabled()) {
|
if (service == null) {
|
||||||
try {
|
|
||||||
service.clccResponse(index, direction, status, mode, mpty, number, type,
|
|
||||||
mAttributionSource);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, e.toString());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver recv = new SynchronousResultReceiver();
|
||||||
|
service.clccResponse(index, direction, status, mode, mpty, number, type,
|
||||||
|
mAttributionSource, recv);
|
||||||
|
recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(null);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1245,18 +1305,21 @@ public final class BluetoothHeadset implements BluetoothProfile {
|
|||||||
throw new IllegalArgumentException("command is null");
|
throw new IllegalArgumentException("command is null");
|
||||||
}
|
}
|
||||||
final IBluetoothHeadset service = mService;
|
final IBluetoothHeadset service = mService;
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final boolean defaultValue = false;
|
||||||
try {
|
|
||||||
return service.sendVendorSpecificResultCode(device, command, arg,
|
|
||||||
mAttributionSource);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (service == null) {
|
if (service == null) {
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
|
service.sendVendorSpecificResultCode(device, command, arg,
|
||||||
|
mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
return false;
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1290,17 +1353,20 @@ public final class BluetoothHeadset implements BluetoothProfile {
|
|||||||
Log.d(TAG, "setActiveDevice: " + device);
|
Log.d(TAG, "setActiveDevice: " + device);
|
||||||
}
|
}
|
||||||
final IBluetoothHeadset service = mService;
|
final IBluetoothHeadset service = mService;
|
||||||
if (service != null && isEnabled() && (device == null || isValidDevice(device))) {
|
final boolean defaultValue = false;
|
||||||
try {
|
|
||||||
return service.setActiveDevice(device, mAttributionSource);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (service == null) {
|
if (service == null) {
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && (device == null || isValidDevice(device))) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
|
service.setActiveDevice(device, mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
return false;
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1316,22 +1382,25 @@ public final class BluetoothHeadset implements BluetoothProfile {
|
|||||||
@RequiresBluetoothConnectPermission
|
@RequiresBluetoothConnectPermission
|
||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public BluetoothDevice getActiveDevice() {
|
public BluetoothDevice getActiveDevice() {
|
||||||
if (VDBG) {
|
if (VDBG) Log.d(TAG, "getActiveDevice");
|
||||||
Log.d(TAG, "getActiveDevice");
|
|
||||||
}
|
|
||||||
final IBluetoothHeadset service = mService;
|
final IBluetoothHeadset service = mService;
|
||||||
if (service != null && isEnabled()) {
|
final BluetoothDevice defaultValue = null;
|
||||||
try {
|
|
||||||
return Attributable.setAttributionSource(
|
|
||||||
service.getActiveDevice(mAttributionSource), mAttributionSource);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (service == null) {
|
if (service == null) {
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<BluetoothDevice> recv =
|
||||||
|
new SynchronousResultReceiver();
|
||||||
|
service.getActiveDevice(mAttributionSource, recv);
|
||||||
|
return Attributable.setAttributionSource(
|
||||||
|
recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
|
||||||
|
mAttributionSource);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
return null;
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1346,21 +1415,22 @@ public final class BluetoothHeadset implements BluetoothProfile {
|
|||||||
@RequiresBluetoothConnectPermission
|
@RequiresBluetoothConnectPermission
|
||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
|
||||||
public boolean isInbandRingingEnabled() {
|
public boolean isInbandRingingEnabled() {
|
||||||
if (DBG) {
|
if (DBG) log("isInbandRingingEnabled()");
|
||||||
log("isInbandRingingEnabled()");
|
|
||||||
}
|
|
||||||
final IBluetoothHeadset service = mService;
|
final IBluetoothHeadset service = mService;
|
||||||
if (service != null && isEnabled()) {
|
final boolean defaultValue = false;
|
||||||
try {
|
|
||||||
return service.isInbandRingingEnabled(mAttributionSource);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (service == null) {
|
if (service == null) {
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
|
service.isInbandRingingEnabled(mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
return false;
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1380,7 +1450,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
|
|||||||
@Override
|
@Override
|
||||||
public void onServiceConnected(ComponentName className, IBinder service) {
|
public void onServiceConnected(ComponentName className, IBinder service) {
|
||||||
if (DBG) Log.d(TAG, "Proxy object connected");
|
if (DBG) Log.d(TAG, "Proxy object connected");
|
||||||
mService = IBluetoothHeadset.Stub.asInterface(Binder.allowBlocking(service));
|
mService = IBluetoothHeadset.Stub.asInterface(service);
|
||||||
mHandler.sendMessage(mHandler.obtainMessage(
|
mHandler.sendMessage(mHandler.obtainMessage(
|
||||||
MESSAGE_HEADSET_SERVICE_CONNECTED));
|
MESSAGE_HEADSET_SERVICE_CONNECTED));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package android.bluetooth;
|
package android.bluetooth;
|
||||||
|
|
||||||
|
import static android.bluetooth.BluetoothUtils.getSyncTimeout;
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.RequiresPermission;
|
import android.annotation.RequiresPermission;
|
||||||
import android.annotation.SdkConstant;
|
import android.annotation.SdkConstant;
|
||||||
@@ -25,15 +27,17 @@ import android.bluetooth.annotations.RequiresLegacyBluetoothPermission;
|
|||||||
import android.compat.annotation.UnsupportedAppUsage;
|
import android.compat.annotation.UnsupportedAppUsage;
|
||||||
import android.content.AttributionSource;
|
import android.content.AttributionSource;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Binder;
|
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.android.modules.utils.SynchronousResultReceiver;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Public API to control Hands Free Profile (HFP role only).
|
* Public API to control Hands Free Profile (HFP role only).
|
||||||
@@ -432,7 +436,7 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
|
|||||||
"BluetoothHeadsetClient", IBluetoothHeadsetClient.class.getName()) {
|
"BluetoothHeadsetClient", IBluetoothHeadsetClient.class.getName()) {
|
||||||
@Override
|
@Override
|
||||||
public IBluetoothHeadsetClient getServiceInterface(IBinder service) {
|
public IBluetoothHeadsetClient getServiceInterface(IBinder service) {
|
||||||
return IBluetoothHeadsetClient.Stub.asInterface(Binder.allowBlocking(service));
|
return IBluetoothHeadsetClient.Stub.asInterface(service);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -479,18 +483,21 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
|
|||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public boolean connect(BluetoothDevice device) {
|
public boolean connect(BluetoothDevice device) {
|
||||||
if (DBG) log("connect(" + device + ")");
|
if (DBG) log("connect(" + device + ")");
|
||||||
final IBluetoothHeadsetClient service =
|
final IBluetoothHeadsetClient service = getService();
|
||||||
getService();
|
final boolean defaultValue = false;
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.connect(device, mAttributionSource);
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.connect(device, mAttributionSource, recv);
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
return false;
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -507,18 +514,21 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
|
|||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public boolean disconnect(BluetoothDevice device) {
|
public boolean disconnect(BluetoothDevice device) {
|
||||||
if (DBG) log("disconnect(" + device + ")");
|
if (DBG) log("disconnect(" + device + ")");
|
||||||
final IBluetoothHeadsetClient service =
|
final IBluetoothHeadsetClient service = getService();
|
||||||
getService();
|
final boolean defaultValue = false;
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.disconnect(device, mAttributionSource);
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.disconnect(device, mAttributionSource, recv);
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
return false;
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -531,19 +541,24 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
|
|||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public List<BluetoothDevice> getConnectedDevices() {
|
public List<BluetoothDevice> getConnectedDevices() {
|
||||||
if (VDBG) log("getConnectedDevices()");
|
if (VDBG) log("getConnectedDevices()");
|
||||||
final IBluetoothHeadsetClient service =
|
final IBluetoothHeadsetClient service = getService();
|
||||||
getService();
|
final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
|
||||||
if (service != null && isEnabled()) {
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
try {
|
try {
|
||||||
|
final SynchronousResultReceiver<List<BluetoothDevice>> recv =
|
||||||
|
new SynchronousResultReceiver();
|
||||||
|
service.getConnectedDevices(mAttributionSource, recv);
|
||||||
return Attributable.setAttributionSource(
|
return Attributable.setAttributionSource(
|
||||||
service.getConnectedDevices(mAttributionSource), mAttributionSource);
|
recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
|
||||||
} catch (RemoteException e) {
|
mAttributionSource);
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
} catch (RemoteException | TimeoutException e) {
|
||||||
return new ArrayList<BluetoothDevice>();
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return new ArrayList<BluetoothDevice>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -558,20 +573,24 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
|
|||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
|
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
|
||||||
if (VDBG) log("getDevicesMatchingStates()");
|
if (VDBG) log("getDevicesMatchingStates()");
|
||||||
final IBluetoothHeadsetClient service =
|
final IBluetoothHeadsetClient service = getService();
|
||||||
getService();
|
final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
|
||||||
if (service != null && isEnabled()) {
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
try {
|
try {
|
||||||
|
final SynchronousResultReceiver<List<BluetoothDevice>> recv =
|
||||||
|
new SynchronousResultReceiver();
|
||||||
|
service.getDevicesMatchingConnectionStates(states, mAttributionSource, recv);
|
||||||
return Attributable.setAttributionSource(
|
return Attributable.setAttributionSource(
|
||||||
service.getDevicesMatchingConnectionStates(states, mAttributionSource),
|
recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
|
||||||
mAttributionSource);
|
mAttributionSource);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException | TimeoutException e) {
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
return new ArrayList<BluetoothDevice>();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return new ArrayList<BluetoothDevice>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -585,18 +604,21 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
|
|||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public int getConnectionState(BluetoothDevice device) {
|
public int getConnectionState(BluetoothDevice device) {
|
||||||
if (VDBG) log("getConnectionState(" + device + ")");
|
if (VDBG) log("getConnectionState(" + device + ")");
|
||||||
final IBluetoothHeadsetClient service =
|
final IBluetoothHeadsetClient service = getService();
|
||||||
getService();
|
final int defaultValue = BluetoothProfile.STATE_DISCONNECTED;
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.getConnectionState(device, mAttributionSource);
|
final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.getConnectionState(device, mAttributionSource, recv);
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
return BluetoothProfile.STATE_DISCONNECTED;
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return BluetoothProfile.STATE_DISCONNECTED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -634,22 +656,23 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
|
|||||||
public boolean setConnectionPolicy(@NonNull BluetoothDevice device,
|
public boolean setConnectionPolicy(@NonNull BluetoothDevice device,
|
||||||
@ConnectionPolicy int connectionPolicy) {
|
@ConnectionPolicy int connectionPolicy) {
|
||||||
if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
|
if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
|
||||||
final IBluetoothHeadsetClient service =
|
final IBluetoothHeadsetClient service = getService();
|
||||||
getService();
|
final boolean defaultValue = false;
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
if (service == null) {
|
||||||
if (connectionPolicy != BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
&& connectionPolicy != BluetoothProfile.CONNECTION_POLICY_ALLOWED) {
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
return false;
|
} else if (isEnabled() && isValidDevice(device)
|
||||||
}
|
&& (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
|
||||||
|
|| connectionPolicy == BluetoothProfile.CONNECTION_POLICY_ALLOWED)) {
|
||||||
try {
|
try {
|
||||||
return service.setConnectionPolicy(device, connectionPolicy, mAttributionSource);
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.setConnectionPolicy(device, connectionPolicy, mAttributionSource, recv);
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
return false;
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -686,18 +709,21 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
|
|||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public @ConnectionPolicy int getConnectionPolicy(@NonNull BluetoothDevice device) {
|
public @ConnectionPolicy int getConnectionPolicy(@NonNull BluetoothDevice device) {
|
||||||
if (VDBG) log("getConnectionPolicy(" + device + ")");
|
if (VDBG) log("getConnectionPolicy(" + device + ")");
|
||||||
final IBluetoothHeadsetClient service =
|
final IBluetoothHeadsetClient service = getService();
|
||||||
getService();
|
final @ConnectionPolicy int defaultValue = BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.getConnectionPolicy(device, mAttributionSource);
|
final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.getConnectionPolicy(device, mAttributionSource, recv);
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -715,17 +741,21 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
|
|||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public boolean startVoiceRecognition(BluetoothDevice device) {
|
public boolean startVoiceRecognition(BluetoothDevice device) {
|
||||||
if (DBG) log("startVoiceRecognition()");
|
if (DBG) log("startVoiceRecognition()");
|
||||||
final IBluetoothHeadsetClient service =
|
final IBluetoothHeadsetClient service = getService();
|
||||||
getService();
|
final boolean defaultValue = false;
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.startVoiceRecognition(device, mAttributionSource);
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.startVoiceRecognition(device, mAttributionSource, recv);
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -739,20 +769,23 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
|
|||||||
*/
|
*/
|
||||||
@RequiresBluetoothConnectPermission
|
@RequiresBluetoothConnectPermission
|
||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public boolean sendVendorAtCommand(BluetoothDevice device, int vendorId,
|
public boolean sendVendorAtCommand(BluetoothDevice device, int vendorId, String atCommand) {
|
||||||
String atCommand) {
|
|
||||||
if (DBG) log("sendVendorSpecificCommand()");
|
if (DBG) log("sendVendorSpecificCommand()");
|
||||||
final IBluetoothHeadsetClient service =
|
final IBluetoothHeadsetClient service = getService();
|
||||||
getService();
|
final boolean defaultValue = false;
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.sendVendorAtCommand(device, vendorId, atCommand, mAttributionSource);
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.sendVendorAtCommand(device, vendorId, atCommand, mAttributionSource, recv);
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -770,17 +803,21 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
|
|||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public boolean stopVoiceRecognition(BluetoothDevice device) {
|
public boolean stopVoiceRecognition(BluetoothDevice device) {
|
||||||
if (DBG) log("stopVoiceRecognition()");
|
if (DBG) log("stopVoiceRecognition()");
|
||||||
final IBluetoothHeadsetClient service =
|
final IBluetoothHeadsetClient service = getService();
|
||||||
getService();
|
final boolean defaultValue = false;
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.stopVoiceRecognition(device, mAttributionSource);
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.stopVoiceRecognition(device, mAttributionSource, recv);
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -793,18 +830,24 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
|
|||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public List<BluetoothHeadsetClientCall> getCurrentCalls(BluetoothDevice device) {
|
public List<BluetoothHeadsetClientCall> getCurrentCalls(BluetoothDevice device) {
|
||||||
if (DBG) log("getCurrentCalls()");
|
if (DBG) log("getCurrentCalls()");
|
||||||
final IBluetoothHeadsetClient service =
|
final IBluetoothHeadsetClient service = getService();
|
||||||
getService();
|
final List<BluetoothHeadsetClientCall> defaultValue = null;
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
|
final SynchronousResultReceiver<List<BluetoothHeadsetClientCall>> recv =
|
||||||
|
new SynchronousResultReceiver();
|
||||||
|
service.getCurrentCalls(device, mAttributionSource, recv);
|
||||||
return Attributable.setAttributionSource(
|
return Attributable.setAttributionSource(
|
||||||
service.getCurrentCalls(device, mAttributionSource), mAttributionSource);
|
recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
|
||||||
} catch (RemoteException e) {
|
mAttributionSource);
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -817,17 +860,21 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
|
|||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public Bundle getCurrentAgEvents(BluetoothDevice device) {
|
public Bundle getCurrentAgEvents(BluetoothDevice device) {
|
||||||
if (DBG) log("getCurrentAgEvents()");
|
if (DBG) log("getCurrentAgEvents()");
|
||||||
final IBluetoothHeadsetClient service =
|
final IBluetoothHeadsetClient service = getService();
|
||||||
getService();
|
final Bundle defaultValue = null;
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.getCurrentAgEvents(device, mAttributionSource);
|
final SynchronousResultReceiver<Bundle> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.getCurrentAgEvents(device, mAttributionSource, recv);
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -844,17 +891,21 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
|
|||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public boolean acceptCall(BluetoothDevice device, int flag) {
|
public boolean acceptCall(BluetoothDevice device, int flag) {
|
||||||
if (DBG) log("acceptCall()");
|
if (DBG) log("acceptCall()");
|
||||||
final IBluetoothHeadsetClient service =
|
final IBluetoothHeadsetClient service = getService();
|
||||||
getService();
|
final boolean defaultValue = false;
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.acceptCall(device, flag, mAttributionSource);
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.acceptCall(device, flag, mAttributionSource, recv);
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -868,17 +919,21 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
|
|||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public boolean holdCall(BluetoothDevice device) {
|
public boolean holdCall(BluetoothDevice device) {
|
||||||
if (DBG) log("holdCall()");
|
if (DBG) log("holdCall()");
|
||||||
final IBluetoothHeadsetClient service =
|
final IBluetoothHeadsetClient service = getService();
|
||||||
getService();
|
final boolean defaultValue = false;
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.holdCall(device, mAttributionSource);
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.holdCall(device, mAttributionSource, recv);
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -897,17 +952,21 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
|
|||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public boolean rejectCall(BluetoothDevice device) {
|
public boolean rejectCall(BluetoothDevice device) {
|
||||||
if (DBG) log("rejectCall()");
|
if (DBG) log("rejectCall()");
|
||||||
final IBluetoothHeadsetClient service =
|
final IBluetoothHeadsetClient service = getService();
|
||||||
getService();
|
final boolean defaultValue = false;
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.rejectCall(device, mAttributionSource);
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.rejectCall(device, mAttributionSource, recv);
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -930,17 +989,21 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
|
|||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public boolean terminateCall(BluetoothDevice device, BluetoothHeadsetClientCall call) {
|
public boolean terminateCall(BluetoothDevice device, BluetoothHeadsetClientCall call) {
|
||||||
if (DBG) log("terminateCall()");
|
if (DBG) log("terminateCall()");
|
||||||
final IBluetoothHeadsetClient service =
|
final IBluetoothHeadsetClient service = getService();
|
||||||
getService();
|
final boolean defaultValue = false;
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.terminateCall(device, call, mAttributionSource);
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.terminateCall(device, call, mAttributionSource, recv);
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -961,17 +1024,21 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
|
|||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public boolean enterPrivateMode(BluetoothDevice device, int index) {
|
public boolean enterPrivateMode(BluetoothDevice device, int index) {
|
||||||
if (DBG) log("enterPrivateMode()");
|
if (DBG) log("enterPrivateMode()");
|
||||||
final IBluetoothHeadsetClient service =
|
final IBluetoothHeadsetClient service = getService();
|
||||||
getService();
|
final boolean defaultValue = false;
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.enterPrivateMode(device, index, mAttributionSource);
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.enterPrivateMode(device, index, mAttributionSource, recv);
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -991,17 +1058,21 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
|
|||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public boolean explicitCallTransfer(BluetoothDevice device) {
|
public boolean explicitCallTransfer(BluetoothDevice device) {
|
||||||
if (DBG) log("explicitCallTransfer()");
|
if (DBG) log("explicitCallTransfer()");
|
||||||
final IBluetoothHeadsetClient service =
|
final IBluetoothHeadsetClient service = getService();
|
||||||
getService();
|
final boolean defaultValue = false;
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.explicitCallTransfer(device, mAttributionSource);
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.explicitCallTransfer(device, mAttributionSource, recv);
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1017,18 +1088,24 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
|
|||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public BluetoothHeadsetClientCall dial(BluetoothDevice device, String number) {
|
public BluetoothHeadsetClientCall dial(BluetoothDevice device, String number) {
|
||||||
if (DBG) log("dial()");
|
if (DBG) log("dial()");
|
||||||
final IBluetoothHeadsetClient service =
|
final IBluetoothHeadsetClient service = getService();
|
||||||
getService();
|
final BluetoothHeadsetClientCall defaultValue = null;
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
|
final SynchronousResultReceiver<BluetoothHeadsetClientCall> recv =
|
||||||
|
new SynchronousResultReceiver();
|
||||||
|
service.dial(device, number, mAttributionSource, recv);
|
||||||
return Attributable.setAttributionSource(
|
return Attributable.setAttributionSource(
|
||||||
service.dial(device, number, mAttributionSource), mAttributionSource);
|
recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
|
||||||
} catch (RemoteException e) {
|
mAttributionSource);
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1045,17 +1122,21 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
|
|||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public boolean sendDTMF(BluetoothDevice device, byte code) {
|
public boolean sendDTMF(BluetoothDevice device, byte code) {
|
||||||
if (DBG) log("sendDTMF()");
|
if (DBG) log("sendDTMF()");
|
||||||
final IBluetoothHeadsetClient service =
|
final IBluetoothHeadsetClient service = getService();
|
||||||
getService();
|
final boolean defaultValue = false;
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.sendDTMF(device, code, mAttributionSource);
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.sendDTMF(device, code, mAttributionSource, recv);
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1074,17 +1155,21 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
|
|||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public boolean getLastVoiceTagNumber(BluetoothDevice device) {
|
public boolean getLastVoiceTagNumber(BluetoothDevice device) {
|
||||||
if (DBG) log("getLastVoiceTagNumber()");
|
if (DBG) log("getLastVoiceTagNumber()");
|
||||||
final IBluetoothHeadsetClient service =
|
final IBluetoothHeadsetClient service = getService();
|
||||||
getService();
|
final boolean defaultValue = false;
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.getLastVoiceTagNumber(device, mAttributionSource);
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.getLastVoiceTagNumber(device, mAttributionSource, recv);
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1097,17 +1182,21 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
|
|||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public int getAudioState(BluetoothDevice device) {
|
public int getAudioState(BluetoothDevice device) {
|
||||||
if (VDBG) log("getAudioState");
|
if (VDBG) log("getAudioState");
|
||||||
final IBluetoothHeadsetClient service =
|
final IBluetoothHeadsetClient service = getService();
|
||||||
getService();
|
final int defaultValue = BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED;
|
||||||
if (service != null && isEnabled()) {
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
try {
|
try {
|
||||||
return service.getAudioState(device, mAttributionSource);
|
final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.getAudioState(device, mAttributionSource, recv);
|
||||||
Log.e(TAG, e.toString());
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
|
|
||||||
}
|
}
|
||||||
return BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED;
|
return BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED;
|
||||||
}
|
}
|
||||||
@@ -1123,17 +1212,18 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
|
|||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public void setAudioRouteAllowed(BluetoothDevice device, boolean allowed) {
|
public void setAudioRouteAllowed(BluetoothDevice device, boolean allowed) {
|
||||||
if (VDBG) log("setAudioRouteAllowed");
|
if (VDBG) log("setAudioRouteAllowed");
|
||||||
final IBluetoothHeadsetClient service =
|
final IBluetoothHeadsetClient service = getService();
|
||||||
getService();
|
if (service == null) {
|
||||||
if (service != null && isEnabled()) {
|
|
||||||
try {
|
|
||||||
service.setAudioRouteAllowed(device, allowed, mAttributionSource);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, e.toString());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver recv = new SynchronousResultReceiver();
|
||||||
|
service.setAudioRouteAllowed(device, allowed, mAttributionSource, recv);
|
||||||
|
recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(null);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1148,19 +1238,21 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
|
|||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public boolean getAudioRouteAllowed(BluetoothDevice device) {
|
public boolean getAudioRouteAllowed(BluetoothDevice device) {
|
||||||
if (VDBG) log("getAudioRouteAllowed");
|
if (VDBG) log("getAudioRouteAllowed");
|
||||||
final IBluetoothHeadsetClient service =
|
final IBluetoothHeadsetClient service = getService();
|
||||||
getService();
|
final boolean defaultValue = false;
|
||||||
if (service != null && isEnabled()) {
|
if (service == null) {
|
||||||
try {
|
|
||||||
return service.getAudioRouteAllowed(device, mAttributionSource);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, e.toString());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
|
service.getAudioRouteAllowed(device, mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
return false;
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1175,19 +1267,22 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
|
|||||||
@RequiresBluetoothConnectPermission
|
@RequiresBluetoothConnectPermission
|
||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public boolean connectAudio(BluetoothDevice device) {
|
public boolean connectAudio(BluetoothDevice device) {
|
||||||
final IBluetoothHeadsetClient service =
|
if (VDBG) log("connectAudio");
|
||||||
getService();
|
final IBluetoothHeadsetClient service = getService();
|
||||||
if (service != null && isEnabled()) {
|
final boolean defaultValue = false;
|
||||||
try {
|
if (service == null) {
|
||||||
return service.connectAudio(device, mAttributionSource);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, e.toString());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
|
service.connectAudio(device, mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
return false;
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1202,19 +1297,22 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
|
|||||||
@RequiresBluetoothConnectPermission
|
@RequiresBluetoothConnectPermission
|
||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public boolean disconnectAudio(BluetoothDevice device) {
|
public boolean disconnectAudio(BluetoothDevice device) {
|
||||||
final IBluetoothHeadsetClient service =
|
if (VDBG) log("disconnectAudio");
|
||||||
getService();
|
final IBluetoothHeadsetClient service = getService();
|
||||||
if (service != null && isEnabled()) {
|
final boolean defaultValue = false;
|
||||||
try {
|
if (service == null) {
|
||||||
return service.disconnectAudio(device, mAttributionSource);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, e.toString());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
|
service.disconnectAudio(device, mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
return false;
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1226,19 +1324,22 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
|
|||||||
@RequiresBluetoothConnectPermission
|
@RequiresBluetoothConnectPermission
|
||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public Bundle getCurrentAgFeatures(BluetoothDevice device) {
|
public Bundle getCurrentAgFeatures(BluetoothDevice device) {
|
||||||
final IBluetoothHeadsetClient service =
|
if (VDBG) log("getCurrentAgFeatures");
|
||||||
getService();
|
final IBluetoothHeadsetClient service = getService();
|
||||||
if (service != null && isEnabled()) {
|
final Bundle defaultValue = null;
|
||||||
try {
|
if (service == null) {
|
||||||
return service.getCurrentAgFeatures(device, mAttributionSource);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, e.toString());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Bundle> recv = new SynchronousResultReceiver();
|
||||||
|
service.getCurrentAgFeatures(device, mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
return null;
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isEnabled() {
|
private boolean isEnabled() {
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package android.bluetooth;
|
package android.bluetooth;
|
||||||
|
|
||||||
|
import static android.bluetooth.BluetoothUtils.getSyncTimeout;
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.annotation.RequiresPermission;
|
import android.annotation.RequiresPermission;
|
||||||
@@ -28,14 +30,16 @@ import android.bluetooth.annotations.RequiresLegacyBluetoothPermission;
|
|||||||
import android.compat.annotation.UnsupportedAppUsage;
|
import android.compat.annotation.UnsupportedAppUsage;
|
||||||
import android.content.AttributionSource;
|
import android.content.AttributionSource;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Binder;
|
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.android.modules.utils.SynchronousResultReceiver;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class provides the public APIs to control the Hearing Aid profile.
|
* This class provides the public APIs to control the Hearing Aid profile.
|
||||||
@@ -136,7 +140,7 @@ public final class BluetoothHearingAid implements BluetoothProfile {
|
|||||||
"BluetoothHearingAid", IBluetoothHearingAid.class.getName()) {
|
"BluetoothHearingAid", IBluetoothHearingAid.class.getName()) {
|
||||||
@Override
|
@Override
|
||||||
public IBluetoothHearingAid getServiceInterface(IBinder service) {
|
public IBluetoothHearingAid getServiceInterface(IBinder service) {
|
||||||
return IBluetoothHearingAid.Stub.asInterface(Binder.allowBlocking(service));
|
return IBluetoothHearingAid.Stub.asInterface(service);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -181,16 +185,20 @@ public final class BluetoothHearingAid implements BluetoothProfile {
|
|||||||
public boolean connect(BluetoothDevice device) {
|
public boolean connect(BluetoothDevice device) {
|
||||||
if (DBG) log("connect(" + device + ")");
|
if (DBG) log("connect(" + device + ")");
|
||||||
final IBluetoothHearingAid service = getService();
|
final IBluetoothHearingAid service = getService();
|
||||||
|
final boolean defaultValue = false;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
return service.connect(device, mAttributionSource);
|
service.connect(device, mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
|
||||||
return false;
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -223,16 +231,20 @@ public final class BluetoothHearingAid implements BluetoothProfile {
|
|||||||
public boolean disconnect(BluetoothDevice device) {
|
public boolean disconnect(BluetoothDevice device) {
|
||||||
if (DBG) log("disconnect(" + device + ")");
|
if (DBG) log("disconnect(" + device + ")");
|
||||||
final IBluetoothHearingAid service = getService();
|
final IBluetoothHearingAid service = getService();
|
||||||
|
final boolean defaultValue = false;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
return service.disconnect(device, mAttributionSource);
|
service.disconnect(device, mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
|
||||||
return false;
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -244,17 +256,23 @@ public final class BluetoothHearingAid implements BluetoothProfile {
|
|||||||
public @NonNull List<BluetoothDevice> getConnectedDevices() {
|
public @NonNull List<BluetoothDevice> getConnectedDevices() {
|
||||||
if (VDBG) log("getConnectedDevices()");
|
if (VDBG) log("getConnectedDevices()");
|
||||||
final IBluetoothHearingAid service = getService();
|
final IBluetoothHearingAid service = getService();
|
||||||
|
final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
try {
|
try {
|
||||||
if (service != null && isEnabled()) {
|
final SynchronousResultReceiver<List<BluetoothDevice>> recv =
|
||||||
|
new SynchronousResultReceiver();
|
||||||
|
service.getConnectedDevices(mAttributionSource, recv);
|
||||||
return Attributable.setAttributionSource(
|
return Attributable.setAttributionSource(
|
||||||
service.getConnectedDevices(mAttributionSource), mAttributionSource);
|
recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
|
||||||
|
mAttributionSource);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
|
||||||
return new ArrayList<BluetoothDevice>();
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
|
||||||
return new ArrayList<BluetoothDevice>();
|
|
||||||
}
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -267,18 +285,23 @@ public final class BluetoothHearingAid implements BluetoothProfile {
|
|||||||
@NonNull int[] states) {
|
@NonNull int[] states) {
|
||||||
if (VDBG) log("getDevicesMatchingStates()");
|
if (VDBG) log("getDevicesMatchingStates()");
|
||||||
final IBluetoothHearingAid service = getService();
|
final IBluetoothHearingAid service = getService();
|
||||||
|
final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
try {
|
try {
|
||||||
if (service != null && isEnabled()) {
|
final SynchronousResultReceiver<List<BluetoothDevice>> recv =
|
||||||
|
new SynchronousResultReceiver();
|
||||||
|
service.getDevicesMatchingConnectionStates(states, mAttributionSource, recv);
|
||||||
return Attributable.setAttributionSource(
|
return Attributable.setAttributionSource(
|
||||||
service.getDevicesMatchingConnectionStates(states, mAttributionSource),
|
recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
|
||||||
mAttributionSource);
|
mAttributionSource);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
|
||||||
return new ArrayList<BluetoothDevice>();
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
|
||||||
return new ArrayList<BluetoothDevice>();
|
|
||||||
}
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -291,17 +314,20 @@ public final class BluetoothHearingAid implements BluetoothProfile {
|
|||||||
@NonNull BluetoothDevice device) {
|
@NonNull BluetoothDevice device) {
|
||||||
if (VDBG) log("getState(" + device + ")");
|
if (VDBG) log("getState(" + device + ")");
|
||||||
final IBluetoothHearingAid service = getService();
|
final IBluetoothHearingAid service = getService();
|
||||||
|
final int defaultValue = BluetoothProfile.STATE_DISCONNECTED;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
if (service != null && isEnabled()
|
final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
|
||||||
&& isValidDevice(device)) {
|
service.getConnectionState(device, mAttributionSource, recv);
|
||||||
return service.getConnectionState(device, mAttributionSource);
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
|
||||||
return BluetoothProfile.STATE_DISCONNECTED;
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
|
||||||
return BluetoothProfile.STATE_DISCONNECTED;
|
|
||||||
}
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -330,18 +356,20 @@ public final class BluetoothHearingAid implements BluetoothProfile {
|
|||||||
public boolean setActiveDevice(@Nullable BluetoothDevice device) {
|
public boolean setActiveDevice(@Nullable BluetoothDevice device) {
|
||||||
if (DBG) log("setActiveDevice(" + device + ")");
|
if (DBG) log("setActiveDevice(" + device + ")");
|
||||||
final IBluetoothHearingAid service = getService();
|
final IBluetoothHearingAid service = getService();
|
||||||
|
final boolean defaultValue = false;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && ((device == null) || isValidDevice(device))) {
|
||||||
try {
|
try {
|
||||||
if (service != null && isEnabled()
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
&& ((device == null) || isValidDevice(device))) {
|
service.setActiveDevice(device, mAttributionSource, recv);
|
||||||
service.setActiveDevice(device, mAttributionSource);
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
return true;
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
|
||||||
return false;
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -359,17 +387,23 @@ public final class BluetoothHearingAid implements BluetoothProfile {
|
|||||||
public @NonNull List<BluetoothDevice> getActiveDevices() {
|
public @NonNull List<BluetoothDevice> getActiveDevices() {
|
||||||
if (VDBG) log("getActiveDevices()");
|
if (VDBG) log("getActiveDevices()");
|
||||||
final IBluetoothHearingAid service = getService();
|
final IBluetoothHearingAid service = getService();
|
||||||
|
final List<BluetoothDevice> defaultValue = new ArrayList<>();
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
try {
|
try {
|
||||||
if (service != null && isEnabled()) {
|
final SynchronousResultReceiver<List<BluetoothDevice>> recv =
|
||||||
|
new SynchronousResultReceiver();
|
||||||
|
service.getActiveDevices(mAttributionSource, recv);
|
||||||
return Attributable.setAttributionSource(
|
return Attributable.setAttributionSource(
|
||||||
service.getActiveDevices(mAttributionSource), mAttributionSource);
|
recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
|
||||||
|
mAttributionSource);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
|
||||||
return new ArrayList<>();
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
|
||||||
return new ArrayList<>();
|
|
||||||
}
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -416,21 +450,22 @@ public final class BluetoothHearingAid implements BluetoothProfile {
|
|||||||
if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
|
if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
|
||||||
verifyDeviceNotNull(device, "setConnectionPolicy");
|
verifyDeviceNotNull(device, "setConnectionPolicy");
|
||||||
final IBluetoothHearingAid service = getService();
|
final IBluetoothHearingAid service = getService();
|
||||||
|
final boolean defaultValue = false;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)
|
||||||
|
&& (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
|
||||||
|
|| connectionPolicy == BluetoothProfile.CONNECTION_POLICY_ALLOWED)) {
|
||||||
try {
|
try {
|
||||||
if (service != null && isEnabled()
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
&& isValidDevice(device)) {
|
service.setConnectionPolicy(device, connectionPolicy, mAttributionSource, recv);
|
||||||
if (connectionPolicy != BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
&& connectionPolicy != BluetoothProfile.CONNECTION_POLICY_ALLOWED) {
|
} catch (RemoteException | TimeoutException e) {
|
||||||
return false;
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
return service.setConnectionPolicy(device, connectionPolicy, mAttributionSource);
|
|
||||||
}
|
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
|
||||||
return false;
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -474,17 +509,20 @@ public final class BluetoothHearingAid implements BluetoothProfile {
|
|||||||
if (VDBG) log("getConnectionPolicy(" + device + ")");
|
if (VDBG) log("getConnectionPolicy(" + device + ")");
|
||||||
verifyDeviceNotNull(device, "getConnectionPolicy");
|
verifyDeviceNotNull(device, "getConnectionPolicy");
|
||||||
final IBluetoothHearingAid service = getService();
|
final IBluetoothHearingAid service = getService();
|
||||||
|
final int defaultValue = BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
if (service != null && isEnabled()
|
final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
|
||||||
&& isValidDevice(device)) {
|
service.getConnectionPolicy(device, mAttributionSource, recv);
|
||||||
return service.getConnectionPolicy(device, mAttributionSource);
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
|
||||||
return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
|
||||||
return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
|
|
||||||
}
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -519,19 +557,18 @@ public final class BluetoothHearingAid implements BluetoothProfile {
|
|||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public void setVolume(int volume) {
|
public void setVolume(int volume) {
|
||||||
if (DBG) Log.d(TAG, "setVolume(" + volume + ")");
|
if (DBG) Log.d(TAG, "setVolume(" + volume + ")");
|
||||||
|
|
||||||
final IBluetoothHearingAid service = getService();
|
final IBluetoothHearingAid service = getService();
|
||||||
try {
|
|
||||||
if (service == null) {
|
if (service == null) {
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
return;
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver recv = new SynchronousResultReceiver();
|
||||||
|
service.setVolume(volume, mAttributionSource, recv);
|
||||||
|
recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(null);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isEnabled()) return;
|
|
||||||
|
|
||||||
service.setVolume(volume, mAttributionSource);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -552,24 +589,23 @@ public final class BluetoothHearingAid implements BluetoothProfile {
|
|||||||
android.Manifest.permission.BLUETOOTH_PRIVILEGED,
|
android.Manifest.permission.BLUETOOTH_PRIVILEGED,
|
||||||
})
|
})
|
||||||
public long getHiSyncId(@NonNull BluetoothDevice device) {
|
public long getHiSyncId(@NonNull BluetoothDevice device) {
|
||||||
if (VDBG) {
|
if (VDBG) log("getHiSyncId(" + device + ")");
|
||||||
log("getHiSyncId(" + device + ")");
|
|
||||||
}
|
|
||||||
verifyDeviceNotNull(device, "getConnectionPolicy");
|
verifyDeviceNotNull(device, "getConnectionPolicy");
|
||||||
final IBluetoothHearingAid service = getService();
|
final IBluetoothHearingAid service = getService();
|
||||||
try {
|
final long defaultValue = HI_SYNC_ID_INVALID;
|
||||||
if (service == null) {
|
if (service == null) {
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
return HI_SYNC_ID_INVALID;
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Long> recv = new SynchronousResultReceiver();
|
||||||
|
service.getHiSyncId(device, mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isEnabled() || !isValidDevice(device)) return HI_SYNC_ID_INVALID;
|
|
||||||
|
|
||||||
return service.getHiSyncId(device, mAttributionSource);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
|
||||||
return HI_SYNC_ID_INVALID;
|
|
||||||
}
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -583,21 +619,22 @@ public final class BluetoothHearingAid implements BluetoothProfile {
|
|||||||
@RequiresBluetoothConnectPermission
|
@RequiresBluetoothConnectPermission
|
||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public int getDeviceSide(BluetoothDevice device) {
|
public int getDeviceSide(BluetoothDevice device) {
|
||||||
if (VDBG) {
|
if (VDBG) log("getDeviceSide(" + device + ")");
|
||||||
log("getDeviceSide(" + device + ")");
|
|
||||||
}
|
|
||||||
final IBluetoothHearingAid service = getService();
|
final IBluetoothHearingAid service = getService();
|
||||||
|
final int defaultValue = SIDE_LEFT;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
if (service != null && isEnabled()
|
final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
|
||||||
&& isValidDevice(device)) {
|
service.getDeviceSide(device, mAttributionSource, recv);
|
||||||
return service.getDeviceSide(device, mAttributionSource);
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
|
||||||
return SIDE_LEFT;
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
|
||||||
return SIDE_LEFT;
|
|
||||||
}
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -611,21 +648,22 @@ public final class BluetoothHearingAid implements BluetoothProfile {
|
|||||||
@RequiresBluetoothConnectPermission
|
@RequiresBluetoothConnectPermission
|
||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public int getDeviceMode(BluetoothDevice device) {
|
public int getDeviceMode(BluetoothDevice device) {
|
||||||
if (VDBG) {
|
if (VDBG) log("getDeviceMode(" + device + ")");
|
||||||
log("getDeviceMode(" + device + ")");
|
|
||||||
}
|
|
||||||
final IBluetoothHearingAid service = getService();
|
final IBluetoothHearingAid service = getService();
|
||||||
|
final int defaultValue = MODE_MONAURAL;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
if (service != null && isEnabled()
|
final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
|
||||||
&& isValidDevice(device)) {
|
service.getDeviceMode(device, mAttributionSource, recv);
|
||||||
return service.getDeviceMode(device, mAttributionSource);
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
|
||||||
return MODE_MONAURAL;
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
|
||||||
return MODE_MONAURAL;
|
|
||||||
}
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isEnabled() {
|
private boolean isEnabled() {
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package android.bluetooth;
|
package android.bluetooth;
|
||||||
|
|
||||||
|
import static android.bluetooth.BluetoothUtils.getSyncTimeout;
|
||||||
|
|
||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.RequiresPermission;
|
import android.annotation.RequiresPermission;
|
||||||
@@ -26,14 +28,16 @@ import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
|
|||||||
import android.bluetooth.annotations.RequiresLegacyBluetoothPermission;
|
import android.bluetooth.annotations.RequiresLegacyBluetoothPermission;
|
||||||
import android.content.AttributionSource;
|
import android.content.AttributionSource;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Binder;
|
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.android.modules.utils.SynchronousResultReceiver;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the public APIs to control the Bluetooth HID Device profile.
|
* Provides the public APIs to control the Bluetooth HID Device profile.
|
||||||
@@ -431,7 +435,7 @@ public final class BluetoothHidDevice implements BluetoothProfile {
|
|||||||
"BluetoothHidDevice", IBluetoothHidDevice.class.getName()) {
|
"BluetoothHidDevice", IBluetoothHidDevice.class.getName()) {
|
||||||
@Override
|
@Override
|
||||||
public IBluetoothHidDevice getServiceInterface(IBinder service) {
|
public IBluetoothHidDevice getServiceInterface(IBinder service) {
|
||||||
return IBluetoothHidDevice.Stub.asInterface(Binder.allowBlocking(service));
|
return IBluetoothHidDevice.Stub.asInterface(service);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -455,18 +459,23 @@ public final class BluetoothHidDevice implements BluetoothProfile {
|
|||||||
@RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public List<BluetoothDevice> getConnectedDevices() {
|
public List<BluetoothDevice> getConnectedDevices() {
|
||||||
final IBluetoothHidDevice service = getService();
|
final IBluetoothHidDevice service = getService();
|
||||||
if (service != null) {
|
final List<BluetoothDevice> defaultValue = new ArrayList<>();
|
||||||
try {
|
if (service == null) {
|
||||||
return Attributable.setAttributionSource(
|
|
||||||
service.getConnectedDevices(mAttributionSource), mAttributionSource);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, e.toString());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<List<BluetoothDevice>> recv =
|
||||||
|
new SynchronousResultReceiver();
|
||||||
|
service.getConnectedDevices(mAttributionSource, recv);
|
||||||
|
return Attributable.setAttributionSource(
|
||||||
|
recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
|
||||||
|
mAttributionSource);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return new ArrayList<>();
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
@@ -475,19 +484,23 @@ public final class BluetoothHidDevice implements BluetoothProfile {
|
|||||||
@RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
|
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
|
||||||
final IBluetoothHidDevice service = getService();
|
final IBluetoothHidDevice service = getService();
|
||||||
if (service != null) {
|
final List<BluetoothDevice> defaultValue = new ArrayList<>();
|
||||||
try {
|
if (service == null) {
|
||||||
return Attributable.setAttributionSource(
|
|
||||||
service.getDevicesMatchingConnectionStates(states, mAttributionSource),
|
|
||||||
mAttributionSource);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, e.toString());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<List<BluetoothDevice>> recv =
|
||||||
|
new SynchronousResultReceiver();
|
||||||
|
service.getDevicesMatchingConnectionStates(states, mAttributionSource, recv);
|
||||||
|
return Attributable.setAttributionSource(
|
||||||
|
recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
|
||||||
|
mAttributionSource);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return new ArrayList<>();
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
@@ -496,17 +509,20 @@ public final class BluetoothHidDevice implements BluetoothProfile {
|
|||||||
@RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public int getConnectionState(BluetoothDevice device) {
|
public int getConnectionState(BluetoothDevice device) {
|
||||||
final IBluetoothHidDevice service = getService();
|
final IBluetoothHidDevice service = getService();
|
||||||
if (service != null) {
|
final int defaultValue = STATE_DISCONNECTED;
|
||||||
try {
|
if (service == null) {
|
||||||
return service.getConnectionState(device, mAttributionSource);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, e.toString());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
|
||||||
|
service.getConnectionState(device, mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return STATE_DISCONNECTED;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -555,18 +571,21 @@ public final class BluetoothHidDevice implements BluetoothProfile {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final IBluetoothHidDevice service = getService();
|
final IBluetoothHidDevice service = getService();
|
||||||
if (service != null) {
|
final boolean defaultValue = result;
|
||||||
try {
|
if (service == null) {
|
||||||
CallbackWrapper cbw = new CallbackWrapper(executor, callback, mAttributionSource);
|
|
||||||
result = service.registerApp(sdp, inQos, outQos, cbw, mAttributionSource);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, e.toString());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
|
CallbackWrapper cbw = new CallbackWrapper(executor, callback, mAttributionSource);
|
||||||
|
service.registerApp(sdp, inQos, outQos, cbw, mAttributionSource, recv);
|
||||||
|
result = recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return result;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -582,20 +601,21 @@ public final class BluetoothHidDevice implements BluetoothProfile {
|
|||||||
@RequiresBluetoothConnectPermission
|
@RequiresBluetoothConnectPermission
|
||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public boolean unregisterApp() {
|
public boolean unregisterApp() {
|
||||||
boolean result = false;
|
|
||||||
|
|
||||||
final IBluetoothHidDevice service = getService();
|
final IBluetoothHidDevice service = getService();
|
||||||
if (service != null) {
|
final boolean defaultValue = false;
|
||||||
try {
|
if (service == null) {
|
||||||
result = service.unregisterApp(mAttributionSource);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, e.toString());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
|
service.unregisterApp(mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return result;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -609,20 +629,21 @@ public final class BluetoothHidDevice implements BluetoothProfile {
|
|||||||
@RequiresBluetoothConnectPermission
|
@RequiresBluetoothConnectPermission
|
||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public boolean sendReport(BluetoothDevice device, int id, byte[] data) {
|
public boolean sendReport(BluetoothDevice device, int id, byte[] data) {
|
||||||
boolean result = false;
|
|
||||||
|
|
||||||
final IBluetoothHidDevice service = getService();
|
final IBluetoothHidDevice service = getService();
|
||||||
if (service != null) {
|
final boolean defaultValue = false;
|
||||||
try {
|
if (service == null) {
|
||||||
result = service.sendReport(device, id, data, mAttributionSource);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, e.toString());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
|
service.sendReport(device, id, data, mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return result;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -637,20 +658,21 @@ public final class BluetoothHidDevice implements BluetoothProfile {
|
|||||||
@RequiresBluetoothConnectPermission
|
@RequiresBluetoothConnectPermission
|
||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public boolean replyReport(BluetoothDevice device, byte type, byte id, byte[] data) {
|
public boolean replyReport(BluetoothDevice device, byte type, byte id, byte[] data) {
|
||||||
boolean result = false;
|
|
||||||
|
|
||||||
final IBluetoothHidDevice service = getService();
|
final IBluetoothHidDevice service = getService();
|
||||||
if (service != null) {
|
final boolean defaultValue = false;
|
||||||
try {
|
if (service == null) {
|
||||||
result = service.replyReport(device, type, id, data, mAttributionSource);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, e.toString());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
|
service.replyReport(device, type, id, data, mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return result;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -663,20 +685,21 @@ public final class BluetoothHidDevice implements BluetoothProfile {
|
|||||||
@RequiresBluetoothConnectPermission
|
@RequiresBluetoothConnectPermission
|
||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public boolean reportError(BluetoothDevice device, byte error) {
|
public boolean reportError(BluetoothDevice device, byte error) {
|
||||||
boolean result = false;
|
|
||||||
|
|
||||||
final IBluetoothHidDevice service = getService();
|
final IBluetoothHidDevice service = getService();
|
||||||
if (service != null) {
|
final boolean defaultValue = false;
|
||||||
try {
|
if (service == null) {
|
||||||
result = service.reportError(device, error, mAttributionSource);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, e.toString());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
|
service.reportError(device, error, mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return result;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -689,18 +712,20 @@ public final class BluetoothHidDevice implements BluetoothProfile {
|
|||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public String getUserAppName() {
|
public String getUserAppName() {
|
||||||
final IBluetoothHidDevice service = getService();
|
final IBluetoothHidDevice service = getService();
|
||||||
|
final String defaultValue = "";
|
||||||
if (service != null) {
|
if (service == null) {
|
||||||
try {
|
|
||||||
return service.getUserAppName(mAttributionSource);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, e.toString());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<String> recv = new SynchronousResultReceiver();
|
||||||
|
service.getUserAppName(mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return "";
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -714,20 +739,21 @@ public final class BluetoothHidDevice implements BluetoothProfile {
|
|||||||
@RequiresBluetoothConnectPermission
|
@RequiresBluetoothConnectPermission
|
||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public boolean connect(BluetoothDevice device) {
|
public boolean connect(BluetoothDevice device) {
|
||||||
boolean result = false;
|
|
||||||
|
|
||||||
final IBluetoothHidDevice service = getService();
|
final IBluetoothHidDevice service = getService();
|
||||||
if (service != null) {
|
final boolean defaultValue = false;
|
||||||
try {
|
if (service == null) {
|
||||||
result = service.connect(device, mAttributionSource);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, e.toString());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
|
service.connect(device, mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return result;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -740,20 +766,21 @@ public final class BluetoothHidDevice implements BluetoothProfile {
|
|||||||
@RequiresBluetoothConnectPermission
|
@RequiresBluetoothConnectPermission
|
||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public boolean disconnect(BluetoothDevice device) {
|
public boolean disconnect(BluetoothDevice device) {
|
||||||
boolean result = false;
|
|
||||||
|
|
||||||
final IBluetoothHidDevice service = getService();
|
final IBluetoothHidDevice service = getService();
|
||||||
if (service != null) {
|
final boolean defaultValue = false;
|
||||||
try {
|
if (service == null) {
|
||||||
result = service.disconnect(device, mAttributionSource);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, e.toString());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
|
service.disconnect(device, mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return result;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -781,23 +808,24 @@ public final class BluetoothHidDevice implements BluetoothProfile {
|
|||||||
})
|
})
|
||||||
public boolean setConnectionPolicy(@NonNull BluetoothDevice device,
|
public boolean setConnectionPolicy(@NonNull BluetoothDevice device,
|
||||||
@ConnectionPolicy int connectionPolicy) {
|
@ConnectionPolicy int connectionPolicy) {
|
||||||
log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
|
if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
|
||||||
try {
|
|
||||||
final IBluetoothHidDevice service = getService();
|
final IBluetoothHidDevice service = getService();
|
||||||
if (service != null && isEnabled()
|
final boolean defaultValue = false;
|
||||||
&& isValidDevice(device)) {
|
if (service == null) {
|
||||||
if (connectionPolicy != BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
&& connectionPolicy != BluetoothProfile.CONNECTION_POLICY_ALLOWED) {
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
return false;
|
} else if (isEnabled() && isValidDevice(device)
|
||||||
|
&& (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
|
||||||
|
|| connectionPolicy == BluetoothProfile.CONNECTION_POLICY_ALLOWED)) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
|
service.setConnectionPolicy(device, connectionPolicy, mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
return service.setConnectionPolicy(device, connectionPolicy, mAttributionSource);
|
|
||||||
}
|
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
|
||||||
return false;
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isEnabled() {
|
private boolean isEnabled() {
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package android.bluetooth;
|
package android.bluetooth;
|
||||||
|
|
||||||
|
import static android.bluetooth.BluetoothUtils.getSyncTimeout;
|
||||||
|
|
||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.RequiresPermission;
|
import android.annotation.RequiresPermission;
|
||||||
@@ -28,13 +30,15 @@ import android.bluetooth.annotations.RequiresLegacyBluetoothAdminPermission;
|
|||||||
import android.bluetooth.annotations.RequiresLegacyBluetoothPermission;
|
import android.bluetooth.annotations.RequiresLegacyBluetoothPermission;
|
||||||
import android.content.AttributionSource;
|
import android.content.AttributionSource;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Binder;
|
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.android.modules.utils.SynchronousResultReceiver;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -244,7 +248,7 @@ public final class BluetoothHidHost implements BluetoothProfile {
|
|||||||
"BluetoothHidHost", IBluetoothHidHost.class.getName()) {
|
"BluetoothHidHost", IBluetoothHidHost.class.getName()) {
|
||||||
@Override
|
@Override
|
||||||
public IBluetoothHidHost getServiceInterface(IBinder service) {
|
public IBluetoothHidHost getServiceInterface(IBinder service) {
|
||||||
return IBluetoothHidHost.Stub.asInterface(Binder.allowBlocking(service));
|
return IBluetoothHidHost.Stub.asInterface(service);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -292,16 +296,20 @@ public final class BluetoothHidHost implements BluetoothProfile {
|
|||||||
public boolean connect(BluetoothDevice device) {
|
public boolean connect(BluetoothDevice device) {
|
||||||
if (DBG) log("connect(" + device + ")");
|
if (DBG) log("connect(" + device + ")");
|
||||||
final IBluetoothHidHost service = getService();
|
final IBluetoothHidHost service = getService();
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final boolean defaultValue = false;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.connect(device, mAttributionSource);
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.connect(device, mAttributionSource, recv);
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
return false;
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -334,16 +342,20 @@ public final class BluetoothHidHost implements BluetoothProfile {
|
|||||||
public boolean disconnect(BluetoothDevice device) {
|
public boolean disconnect(BluetoothDevice device) {
|
||||||
if (DBG) log("disconnect(" + device + ")");
|
if (DBG) log("disconnect(" + device + ")");
|
||||||
final IBluetoothHidHost service = getService();
|
final IBluetoothHidHost service = getService();
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final boolean defaultValue = false;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.disconnect(device, mAttributionSource);
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.disconnect(device, mAttributionSource, recv);
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
return false;
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -358,17 +370,23 @@ public final class BluetoothHidHost implements BluetoothProfile {
|
|||||||
public @NonNull List<BluetoothDevice> getConnectedDevices() {
|
public @NonNull List<BluetoothDevice> getConnectedDevices() {
|
||||||
if (VDBG) log("getConnectedDevices()");
|
if (VDBG) log("getConnectedDevices()");
|
||||||
final IBluetoothHidHost service = getService();
|
final IBluetoothHidHost service = getService();
|
||||||
if (service != null && isEnabled()) {
|
final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
try {
|
try {
|
||||||
|
final SynchronousResultReceiver<List<BluetoothDevice>> recv =
|
||||||
|
new SynchronousResultReceiver();
|
||||||
|
service.getConnectedDevices(mAttributionSource, recv);
|
||||||
return Attributable.setAttributionSource(
|
return Attributable.setAttributionSource(
|
||||||
service.getConnectedDevices(mAttributionSource), mAttributionSource);
|
recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
|
||||||
} catch (RemoteException e) {
|
mAttributionSource);
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
} catch (RemoteException | TimeoutException e) {
|
||||||
return new ArrayList<BluetoothDevice>();
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return new ArrayList<BluetoothDevice>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -382,18 +400,23 @@ public final class BluetoothHidHost implements BluetoothProfile {
|
|||||||
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
|
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
|
||||||
if (VDBG) log("getDevicesMatchingStates()");
|
if (VDBG) log("getDevicesMatchingStates()");
|
||||||
final IBluetoothHidHost service = getService();
|
final IBluetoothHidHost service = getService();
|
||||||
if (service != null && isEnabled()) {
|
final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
try {
|
try {
|
||||||
|
final SynchronousResultReceiver<List<BluetoothDevice>> recv =
|
||||||
|
new SynchronousResultReceiver();
|
||||||
|
service.getDevicesMatchingConnectionStates(states, mAttributionSource, recv);
|
||||||
return Attributable.setAttributionSource(
|
return Attributable.setAttributionSource(
|
||||||
service.getDevicesMatchingConnectionStates(states, mAttributionSource),
|
recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
|
||||||
mAttributionSource);
|
mAttributionSource);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException | TimeoutException e) {
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
return new ArrayList<BluetoothDevice>();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return new ArrayList<BluetoothDevice>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -411,16 +434,20 @@ public final class BluetoothHidHost implements BluetoothProfile {
|
|||||||
throw new IllegalArgumentException("device must not be null");
|
throw new IllegalArgumentException("device must not be null");
|
||||||
}
|
}
|
||||||
final IBluetoothHidHost service = getService();
|
final IBluetoothHidHost service = getService();
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final int defaultValue = BluetoothProfile.STATE_DISCONNECTED;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.getConnectionState(device, mAttributionSource);
|
final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.getConnectionState(device, mAttributionSource, recv);
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
return BluetoothProfile.STATE_DISCONNECTED;
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return BluetoothProfile.STATE_DISCONNECTED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -469,20 +496,22 @@ public final class BluetoothHidHost implements BluetoothProfile {
|
|||||||
throw new IllegalArgumentException("device must not be null");
|
throw new IllegalArgumentException("device must not be null");
|
||||||
}
|
}
|
||||||
final IBluetoothHidHost service = getService();
|
final IBluetoothHidHost service = getService();
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final boolean defaultValue = false;
|
||||||
if (connectionPolicy != BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
|
if (service == null) {
|
||||||
&& connectionPolicy != BluetoothProfile.CONNECTION_POLICY_ALLOWED) {
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
return false;
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
}
|
} else if (isEnabled() && isValidDevice(device)
|
||||||
|
&& (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
|
||||||
|
|| connectionPolicy == BluetoothProfile.CONNECTION_POLICY_ALLOWED)) {
|
||||||
try {
|
try {
|
||||||
return service.setConnectionPolicy(device, connectionPolicy, mAttributionSource);
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.setConnectionPolicy(device, connectionPolicy, mAttributionSource, recv);
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
return false;
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -528,16 +557,20 @@ public final class BluetoothHidHost implements BluetoothProfile {
|
|||||||
throw new IllegalArgumentException("device must not be null");
|
throw new IllegalArgumentException("device must not be null");
|
||||||
}
|
}
|
||||||
final IBluetoothHidHost service = getService();
|
final IBluetoothHidHost service = getService();
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final int defaultValue = BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.getConnectionPolicy(device, mAttributionSource);
|
final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.getConnectionPolicy(device, mAttributionSource, recv);
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isEnabled() {
|
private boolean isEnabled() {
|
||||||
@@ -561,18 +594,20 @@ public final class BluetoothHidHost implements BluetoothProfile {
|
|||||||
public boolean virtualUnplug(BluetoothDevice device) {
|
public boolean virtualUnplug(BluetoothDevice device) {
|
||||||
if (DBG) log("virtualUnplug(" + device + ")");
|
if (DBG) log("virtualUnplug(" + device + ")");
|
||||||
final IBluetoothHidHost service = getService();
|
final IBluetoothHidHost service = getService();
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final boolean defaultValue = false;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.virtualUnplug(device, mAttributionSource);
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.virtualUnplug(device, mAttributionSource, recv);
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
return false;
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return defaultValue;
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
|
||||||
return false;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -588,16 +623,20 @@ public final class BluetoothHidHost implements BluetoothProfile {
|
|||||||
public boolean getProtocolMode(BluetoothDevice device) {
|
public boolean getProtocolMode(BluetoothDevice device) {
|
||||||
if (VDBG) log("getProtocolMode(" + device + ")");
|
if (VDBG) log("getProtocolMode(" + device + ")");
|
||||||
final IBluetoothHidHost service = getService();
|
final IBluetoothHidHost service = getService();
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final boolean defaultValue = false;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.getProtocolMode(device, mAttributionSource);
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.getProtocolMode(device, mAttributionSource, recv);
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
return false;
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -613,16 +652,20 @@ public final class BluetoothHidHost implements BluetoothProfile {
|
|||||||
public boolean setProtocolMode(BluetoothDevice device, int protocolMode) {
|
public boolean setProtocolMode(BluetoothDevice device, int protocolMode) {
|
||||||
if (DBG) log("setProtocolMode(" + device + ")");
|
if (DBG) log("setProtocolMode(" + device + ")");
|
||||||
final IBluetoothHidHost service = getService();
|
final IBluetoothHidHost service = getService();
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final boolean defaultValue = false;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.setProtocolMode(device, protocolMode, mAttributionSource);
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.setProtocolMode(device, protocolMode, mAttributionSource, recv);
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
return false;
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -645,17 +688,21 @@ public final class BluetoothHidHost implements BluetoothProfile {
|
|||||||
+ "bufferSize=" + bufferSize);
|
+ "bufferSize=" + bufferSize);
|
||||||
}
|
}
|
||||||
final IBluetoothHidHost service = getService();
|
final IBluetoothHidHost service = getService();
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final boolean defaultValue = false;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.getReport(device, reportType, reportId, bufferSize,
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
mAttributionSource);
|
service.getReport(device, reportType, reportId, bufferSize, mAttributionSource,
|
||||||
} catch (RemoteException e) {
|
recv);
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
return false;
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -673,16 +720,20 @@ public final class BluetoothHidHost implements BluetoothProfile {
|
|||||||
public boolean setReport(BluetoothDevice device, byte reportType, String report) {
|
public boolean setReport(BluetoothDevice device, byte reportType, String report) {
|
||||||
if (VDBG) log("setReport(" + device + "), reportType=" + reportType + " report=" + report);
|
if (VDBG) log("setReport(" + device + "), reportType=" + reportType + " report=" + report);
|
||||||
final IBluetoothHidHost service = getService();
|
final IBluetoothHidHost service = getService();
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final boolean defaultValue = false;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.setReport(device, reportType, report, mAttributionSource);
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.setReport(device, reportType, report, mAttributionSource, recv);
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
return false;
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -699,16 +750,20 @@ public final class BluetoothHidHost implements BluetoothProfile {
|
|||||||
public boolean sendData(BluetoothDevice device, String report) {
|
public boolean sendData(BluetoothDevice device, String report) {
|
||||||
if (DBG) log("sendData(" + device + "), report=" + report);
|
if (DBG) log("sendData(" + device + "), report=" + report);
|
||||||
final IBluetoothHidHost service = getService();
|
final IBluetoothHidHost service = getService();
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final boolean defaultValue = false;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.sendData(device, report, mAttributionSource);
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.sendData(device, report, mAttributionSource, recv);
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
return false;
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -724,16 +779,20 @@ public final class BluetoothHidHost implements BluetoothProfile {
|
|||||||
public boolean getIdleTime(BluetoothDevice device) {
|
public boolean getIdleTime(BluetoothDevice device) {
|
||||||
if (DBG) log("getIdletime(" + device + ")");
|
if (DBG) log("getIdletime(" + device + ")");
|
||||||
final IBluetoothHidHost service = getService();
|
final IBluetoothHidHost service = getService();
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final boolean defaultValue = false;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.getIdleTime(device, mAttributionSource);
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.getIdleTime(device, mAttributionSource, recv);
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
return false;
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -750,16 +809,20 @@ public final class BluetoothHidHost implements BluetoothProfile {
|
|||||||
public boolean setIdleTime(BluetoothDevice device, byte idleTime) {
|
public boolean setIdleTime(BluetoothDevice device, byte idleTime) {
|
||||||
if (DBG) log("setIdletime(" + device + "), idleTime=" + idleTime);
|
if (DBG) log("setIdletime(" + device + "), idleTime=" + idleTime);
|
||||||
final IBluetoothHidHost service = getService();
|
final IBluetoothHidHost service = getService();
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final boolean defaultValue = false;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.setIdleTime(device, idleTime, mAttributionSource);
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.setIdleTime(device, idleTime, mAttributionSource, recv);
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
return false;
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void log(String msg) {
|
private static void log(String msg) {
|
||||||
|
|||||||
@@ -17,6 +17,8 @@
|
|||||||
|
|
||||||
package android.bluetooth;
|
package android.bluetooth;
|
||||||
|
|
||||||
|
import static android.bluetooth.BluetoothUtils.getSyncTimeout;
|
||||||
|
|
||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
@@ -27,14 +29,16 @@ import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
|
|||||||
import android.bluetooth.annotations.RequiresLegacyBluetoothPermission;
|
import android.bluetooth.annotations.RequiresLegacyBluetoothPermission;
|
||||||
import android.content.AttributionSource;
|
import android.content.AttributionSource;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Binder;
|
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.util.CloseGuard;
|
import android.util.CloseGuard;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.android.modules.utils.SynchronousResultReceiver;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class provides the public APIs to control the LeAudio profile.
|
* This class provides the public APIs to control the LeAudio profile.
|
||||||
@@ -331,7 +335,7 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
|
|||||||
IBluetoothLeAudio.class.getName()) {
|
IBluetoothLeAudio.class.getName()) {
|
||||||
@Override
|
@Override
|
||||||
public IBluetoothLeAudio getServiceInterface(IBinder service) {
|
public IBluetoothLeAudio getServiceInterface(IBinder service) {
|
||||||
return IBluetoothLeAudio.Stub.asInterface(Binder.allowBlocking(service));
|
return IBluetoothLeAudio.Stub.asInterface(service);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -385,17 +389,21 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
|
|||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public boolean connect(@Nullable BluetoothDevice device) {
|
public boolean connect(@Nullable BluetoothDevice device) {
|
||||||
if (DBG) log("connect(" + device + ")");
|
if (DBG) log("connect(" + device + ")");
|
||||||
try {
|
|
||||||
final IBluetoothLeAudio service = getService();
|
final IBluetoothLeAudio service = getService();
|
||||||
if (service != null && mAdapter.isEnabled() && isValidDevice(device)) {
|
final boolean defaultValue = false;
|
||||||
return service.connect(device, mAttributionSource);
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (mAdapter.isEnabled() && isValidDevice(device)) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
|
service.connect(device, mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
|
||||||
return false;
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -425,17 +433,21 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
|
|||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public boolean disconnect(@Nullable BluetoothDevice device) {
|
public boolean disconnect(@Nullable BluetoothDevice device) {
|
||||||
if (DBG) log("disconnect(" + device + ")");
|
if (DBG) log("disconnect(" + device + ")");
|
||||||
try {
|
|
||||||
final IBluetoothLeAudio service = getService();
|
final IBluetoothLeAudio service = getService();
|
||||||
if (service != null && mAdapter.isEnabled() && isValidDevice(device)) {
|
final boolean defaultValue = false;
|
||||||
return service.disconnect(device, mAttributionSource);
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (mAdapter.isEnabled() && isValidDevice(device)) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
|
service.disconnect(device, mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
|
||||||
return false;
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -446,18 +458,24 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
|
|||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public @NonNull List<BluetoothDevice> getConnectedDevices() {
|
public @NonNull List<BluetoothDevice> getConnectedDevices() {
|
||||||
if (VDBG) log("getConnectedDevices()");
|
if (VDBG) log("getConnectedDevices()");
|
||||||
try {
|
|
||||||
final IBluetoothLeAudio service = getService();
|
final IBluetoothLeAudio service = getService();
|
||||||
if (service != null && mAdapter.isEnabled()) {
|
final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (mAdapter.isEnabled()) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<List<BluetoothDevice>> recv =
|
||||||
|
new SynchronousResultReceiver();
|
||||||
|
service.getConnectedDevices(mAttributionSource, recv);
|
||||||
return Attributable.setAttributionSource(
|
return Attributable.setAttributionSource(
|
||||||
service.getConnectedDevices(mAttributionSource), mAttributionSource);
|
recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
|
||||||
|
mAttributionSource);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
|
||||||
return new ArrayList<BluetoothDevice>();
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
|
||||||
return new ArrayList<BluetoothDevice>();
|
|
||||||
}
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -469,19 +487,24 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
|
|||||||
public @NonNull List<BluetoothDevice> getDevicesMatchingConnectionStates(
|
public @NonNull List<BluetoothDevice> getDevicesMatchingConnectionStates(
|
||||||
@NonNull int[] states) {
|
@NonNull int[] states) {
|
||||||
if (VDBG) log("getDevicesMatchingStates()");
|
if (VDBG) log("getDevicesMatchingStates()");
|
||||||
try {
|
|
||||||
final IBluetoothLeAudio service = getService();
|
final IBluetoothLeAudio service = getService();
|
||||||
if (service != null && mAdapter.isEnabled()) {
|
final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (mAdapter.isEnabled()) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<List<BluetoothDevice>> recv =
|
||||||
|
new SynchronousResultReceiver();
|
||||||
|
service.getDevicesMatchingConnectionStates(states, mAttributionSource, recv);
|
||||||
return Attributable.setAttributionSource(
|
return Attributable.setAttributionSource(
|
||||||
service.getDevicesMatchingConnectionStates(states, mAttributionSource),
|
recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
|
||||||
mAttributionSource);
|
mAttributionSource);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
|
||||||
return new ArrayList<BluetoothDevice>();
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
|
||||||
return new ArrayList<BluetoothDevice>();
|
|
||||||
}
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -493,18 +516,21 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
|
|||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public @BtProfileState int getConnectionState(@NonNull BluetoothDevice device) {
|
public @BtProfileState int getConnectionState(@NonNull BluetoothDevice device) {
|
||||||
if (VDBG) log("getState(" + device + ")");
|
if (VDBG) log("getState(" + device + ")");
|
||||||
try {
|
|
||||||
final IBluetoothLeAudio service = getService();
|
final IBluetoothLeAudio service = getService();
|
||||||
if (service != null && mAdapter.isEnabled()
|
final int defaultValue = BluetoothProfile.STATE_DISCONNECTED;
|
||||||
&& isValidDevice(device)) {
|
if (service == null) {
|
||||||
return service.getConnectionState(device, mAttributionSource);
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (mAdapter.isEnabled() && isValidDevice(device)) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
|
||||||
|
service.getConnectionState(device, mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
|
||||||
return BluetoothProfile.STATE_DISCONNECTED;
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
|
||||||
return BluetoothProfile.STATE_DISCONNECTED;
|
|
||||||
}
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -531,19 +557,21 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
|
|||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public boolean setActiveDevice(@Nullable BluetoothDevice device) {
|
public boolean setActiveDevice(@Nullable BluetoothDevice device) {
|
||||||
if (DBG) log("setActiveDevice(" + device + ")");
|
if (DBG) log("setActiveDevice(" + device + ")");
|
||||||
try {
|
|
||||||
final IBluetoothLeAudio service = getService();
|
final IBluetoothLeAudio service = getService();
|
||||||
if (service != null && mAdapter.isEnabled()
|
final boolean defaultValue = false;
|
||||||
&& ((device == null) || isValidDevice(device))) {
|
if (service == null) {
|
||||||
service.setActiveDevice(device, mAttributionSource);
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
return true;
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (mAdapter.isEnabled() && ((device == null) || isValidDevice(device))) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
|
service.setActiveDevice(device, mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
|
||||||
return false;
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -557,19 +585,25 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
|
|||||||
@RequiresBluetoothConnectPermission
|
@RequiresBluetoothConnectPermission
|
||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public List<BluetoothDevice> getActiveDevices() {
|
public List<BluetoothDevice> getActiveDevices() {
|
||||||
if (VDBG) log("getActiveDevices()");
|
if (VDBG) log("getActiveDevice()");
|
||||||
try {
|
|
||||||
final IBluetoothLeAudio service = getService();
|
final IBluetoothLeAudio service = getService();
|
||||||
if (service != null && mAdapter.isEnabled()) {
|
final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (mAdapter.isEnabled()) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<List<BluetoothDevice>> recv =
|
||||||
|
new SynchronousResultReceiver();
|
||||||
|
service.getActiveDevices(mAttributionSource, recv);
|
||||||
return Attributable.setAttributionSource(
|
return Attributable.setAttributionSource(
|
||||||
service.getActiveDevices(mAttributionSource), mAttributionSource);
|
recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
|
||||||
|
mAttributionSource);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
|
||||||
return new ArrayList<>();
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
|
||||||
return new ArrayList<>();
|
|
||||||
}
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -583,17 +617,21 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
|
|||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public int getGroupId(@NonNull BluetoothDevice device) {
|
public int getGroupId(@NonNull BluetoothDevice device) {
|
||||||
if (VDBG) log("getGroupId()");
|
if (VDBG) log("getGroupId()");
|
||||||
try {
|
|
||||||
final IBluetoothLeAudio service = getService();
|
final IBluetoothLeAudio service = getService();
|
||||||
if (service != null && mAdapter.isEnabled()) {
|
final int defaultValue = GROUP_ID_INVALID;
|
||||||
return service.getGroupId(device, mAttributionSource);
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (mAdapter.isEnabled()) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
|
||||||
|
service.getGroupId(device, mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
|
||||||
return GROUP_ID_INVALID;
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
|
||||||
return GROUP_ID_INVALID;
|
|
||||||
}
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -606,17 +644,18 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
|
|||||||
@RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED})
|
@RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED})
|
||||||
public void setVolume(int volume) {
|
public void setVolume(int volume) {
|
||||||
if (VDBG) log("setVolume(vol: " + volume + " )");
|
if (VDBG) log("setVolume(vol: " + volume + " )");
|
||||||
try {
|
|
||||||
final IBluetoothLeAudio service = getService();
|
final IBluetoothLeAudio service = getService();
|
||||||
if (service != null && mAdapter.isEnabled()) {
|
if (service == null) {
|
||||||
service.setVolume(volume, mAttributionSource);
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
return;
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (mAdapter.isEnabled()) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver recv = new SynchronousResultReceiver();
|
||||||
|
service.setVolume(volume, mAttributionSource, recv);
|
||||||
|
recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(null);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
|
||||||
return;
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -635,16 +674,20 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
|
|||||||
public boolean groupAddNode(int group_id, @NonNull BluetoothDevice device) {
|
public boolean groupAddNode(int group_id, @NonNull BluetoothDevice device) {
|
||||||
if (VDBG) log("groupAddNode()");
|
if (VDBG) log("groupAddNode()");
|
||||||
final IBluetoothLeAudio service = getService();
|
final IBluetoothLeAudio service = getService();
|
||||||
|
final boolean defaultValue = false;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (mAdapter.isEnabled()) {
|
||||||
try {
|
try {
|
||||||
if (service != null && mAdapter.isEnabled()) {
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
return service.groupAddNode(group_id, device, mAttributionSource);
|
service.groupAddNode(group_id, device, mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
|
||||||
return false;
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -663,16 +706,20 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
|
|||||||
public boolean groupRemoveNode(int group_id, @NonNull BluetoothDevice device) {
|
public boolean groupRemoveNode(int group_id, @NonNull BluetoothDevice device) {
|
||||||
if (VDBG) log("groupRemoveNode()");
|
if (VDBG) log("groupRemoveNode()");
|
||||||
final IBluetoothLeAudio service = getService();
|
final IBluetoothLeAudio service = getService();
|
||||||
|
final boolean defaultValue = false;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (mAdapter.isEnabled()) {
|
||||||
try {
|
try {
|
||||||
if (service != null && mAdapter.isEnabled()) {
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
return service.groupRemoveNode(group_id, device, mAttributionSource);
|
service.groupRemoveNode(group_id, device, mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
|
||||||
return false;
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -695,22 +742,23 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
|
|||||||
public boolean setConnectionPolicy(@NonNull BluetoothDevice device,
|
public boolean setConnectionPolicy(@NonNull BluetoothDevice device,
|
||||||
@ConnectionPolicy int connectionPolicy) {
|
@ConnectionPolicy int connectionPolicy) {
|
||||||
if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
|
if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
|
||||||
try {
|
|
||||||
final IBluetoothLeAudio service = getService();
|
final IBluetoothLeAudio service = getService();
|
||||||
if (service != null && mAdapter.isEnabled()
|
final boolean defaultValue = false;
|
||||||
&& isValidDevice(device)) {
|
if (service == null) {
|
||||||
if (connectionPolicy != BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
&& connectionPolicy != BluetoothProfile.CONNECTION_POLICY_ALLOWED) {
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
return false;
|
} else if (mAdapter.isEnabled() && isValidDevice(device)
|
||||||
|
&& (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
|
||||||
|
|| connectionPolicy == BluetoothProfile.CONNECTION_POLICY_ALLOWED)) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
|
service.setConnectionPolicy(device, connectionPolicy, mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
return service.setConnectionPolicy(device, connectionPolicy, mAttributionSource);
|
|
||||||
}
|
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
|
||||||
return false;
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -728,18 +776,21 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
|
|||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public @ConnectionPolicy int getConnectionPolicy(@Nullable BluetoothDevice device) {
|
public @ConnectionPolicy int getConnectionPolicy(@Nullable BluetoothDevice device) {
|
||||||
if (VDBG) log("getConnectionPolicy(" + device + ")");
|
if (VDBG) log("getConnectionPolicy(" + device + ")");
|
||||||
try {
|
|
||||||
final IBluetoothLeAudio service = getService();
|
final IBluetoothLeAudio service = getService();
|
||||||
if (service != null && mAdapter.isEnabled()
|
final int defaultValue = BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
|
||||||
&& isValidDevice(device)) {
|
if (service == null) {
|
||||||
return service.getConnectionPolicy(device, mAttributionSource);
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (mAdapter.isEnabled() && isValidDevice(device)) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
|
||||||
|
service.getConnectionPolicy(device, mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
|
||||||
return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
|
||||||
return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
|
|
||||||
}
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package android.bluetooth;
|
package android.bluetooth;
|
||||||
|
|
||||||
|
import static android.bluetooth.BluetoothUtils.getSyncTimeout;
|
||||||
|
|
||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.RequiresNoPermission;
|
import android.annotation.RequiresNoPermission;
|
||||||
@@ -28,15 +30,17 @@ import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
|
|||||||
import android.compat.annotation.UnsupportedAppUsage;
|
import android.compat.annotation.UnsupportedAppUsage;
|
||||||
import android.content.AttributionSource;
|
import android.content.AttributionSource;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Binder;
|
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.util.CloseGuard;
|
import android.util.CloseGuard;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.android.modules.utils.SynchronousResultReceiver;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class provides the APIs to control the Bluetooth MAP
|
* This class provides the APIs to control the Bluetooth MAP
|
||||||
@@ -87,7 +91,7 @@ public final class BluetoothMap implements BluetoothProfile, AutoCloseable {
|
|||||||
"BluetoothMap", IBluetoothMap.class.getName()) {
|
"BluetoothMap", IBluetoothMap.class.getName()) {
|
||||||
@Override
|
@Override
|
||||||
public IBluetoothMap getServiceInterface(IBinder service) {
|
public IBluetoothMap getServiceInterface(IBinder service) {
|
||||||
return IBluetoothMap.Stub.asInterface(Binder.allowBlocking(service));
|
return IBluetoothMap.Stub.asInterface(service);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -142,17 +146,20 @@ public final class BluetoothMap implements BluetoothProfile, AutoCloseable {
|
|||||||
public int getState() {
|
public int getState() {
|
||||||
if (VDBG) log("getState()");
|
if (VDBG) log("getState()");
|
||||||
final IBluetoothMap service = getService();
|
final IBluetoothMap service = getService();
|
||||||
if (service != null) {
|
final int defaultValue = BluetoothMap.STATE_ERROR;
|
||||||
try {
|
if (service == null) {
|
||||||
return service.getState(mAttributionSource);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, e.toString());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
|
||||||
|
service.getState(mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
return BluetoothMap.STATE_ERROR;
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -168,18 +175,23 @@ public final class BluetoothMap implements BluetoothProfile, AutoCloseable {
|
|||||||
public BluetoothDevice getClient() {
|
public BluetoothDevice getClient() {
|
||||||
if (VDBG) log("getClient()");
|
if (VDBG) log("getClient()");
|
||||||
final IBluetoothMap service = getService();
|
final IBluetoothMap service = getService();
|
||||||
if (service != null) {
|
final BluetoothDevice defaultValue = null;
|
||||||
try {
|
if (service == null) {
|
||||||
return Attributable.setAttributionSource(
|
|
||||||
service.getClient(mAttributionSource), mAttributionSource);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, e.toString());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<BluetoothDevice> recv =
|
||||||
|
new SynchronousResultReceiver();
|
||||||
|
service.getClient(mAttributionSource, recv);
|
||||||
|
return Attributable.setAttributionSource(
|
||||||
|
recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
|
||||||
|
mAttributionSource);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
return null;
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -194,17 +206,20 @@ public final class BluetoothMap implements BluetoothProfile, AutoCloseable {
|
|||||||
public boolean isConnected(BluetoothDevice device) {
|
public boolean isConnected(BluetoothDevice device) {
|
||||||
if (VDBG) log("isConnected(" + device + ")");
|
if (VDBG) log("isConnected(" + device + ")");
|
||||||
final IBluetoothMap service = getService();
|
final IBluetoothMap service = getService();
|
||||||
if (service != null) {
|
final boolean defaultValue = false;
|
||||||
try {
|
if (service == null) {
|
||||||
return service.isConnected(device, mAttributionSource);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, e.toString());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
|
service.isConnected(device, mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
return false;
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -233,16 +248,20 @@ public final class BluetoothMap implements BluetoothProfile, AutoCloseable {
|
|||||||
public boolean disconnect(BluetoothDevice device) {
|
public boolean disconnect(BluetoothDevice device) {
|
||||||
if (DBG) log("disconnect(" + device + ")");
|
if (DBG) log("disconnect(" + device + ")");
|
||||||
final IBluetoothMap service = getService();
|
final IBluetoothMap service = getService();
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final boolean defaultValue = false;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.disconnect(device, mAttributionSource);
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.disconnect(device, mAttributionSource, recv);
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
return false;
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -284,17 +303,23 @@ public final class BluetoothMap implements BluetoothProfile, AutoCloseable {
|
|||||||
public @NonNull List<BluetoothDevice> getConnectedDevices() {
|
public @NonNull List<BluetoothDevice> getConnectedDevices() {
|
||||||
if (DBG) log("getConnectedDevices()");
|
if (DBG) log("getConnectedDevices()");
|
||||||
final IBluetoothMap service = getService();
|
final IBluetoothMap service = getService();
|
||||||
if (service != null && isEnabled()) {
|
final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
try {
|
try {
|
||||||
|
final SynchronousResultReceiver<List<BluetoothDevice>> recv =
|
||||||
|
new SynchronousResultReceiver();
|
||||||
|
service.getConnectedDevices(mAttributionSource, recv);
|
||||||
return Attributable.setAttributionSource(
|
return Attributable.setAttributionSource(
|
||||||
service.getConnectedDevices(mAttributionSource), mAttributionSource);
|
recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
|
||||||
} catch (RemoteException e) {
|
mAttributionSource);
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
} catch (RemoteException | TimeoutException e) {
|
||||||
return new ArrayList<BluetoothDevice>();
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return new ArrayList<BluetoothDevice>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -309,18 +334,23 @@ public final class BluetoothMap implements BluetoothProfile, AutoCloseable {
|
|||||||
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
|
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
|
||||||
if (DBG) log("getDevicesMatchingStates()");
|
if (DBG) log("getDevicesMatchingStates()");
|
||||||
final IBluetoothMap service = getService();
|
final IBluetoothMap service = getService();
|
||||||
if (service != null && isEnabled()) {
|
final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
try {
|
try {
|
||||||
|
final SynchronousResultReceiver<List<BluetoothDevice>> recv =
|
||||||
|
new SynchronousResultReceiver();
|
||||||
|
service.getDevicesMatchingConnectionStates(states, mAttributionSource, recv);
|
||||||
return Attributable.setAttributionSource(
|
return Attributable.setAttributionSource(
|
||||||
service.getDevicesMatchingConnectionStates(states, mAttributionSource),
|
recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
|
||||||
mAttributionSource);
|
mAttributionSource);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException | TimeoutException e) {
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
return new ArrayList<BluetoothDevice>();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return new ArrayList<BluetoothDevice>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -335,16 +365,21 @@ public final class BluetoothMap implements BluetoothProfile, AutoCloseable {
|
|||||||
public int getConnectionState(BluetoothDevice device) {
|
public int getConnectionState(BluetoothDevice device) {
|
||||||
if (DBG) log("getConnectionState(" + device + ")");
|
if (DBG) log("getConnectionState(" + device + ")");
|
||||||
final IBluetoothMap service = getService();
|
final IBluetoothMap service = getService();
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final int defaultValue = BluetoothProfile.STATE_DISCONNECTED;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.getConnectionState(device, mAttributionSource);
|
final SynchronousResultReceiver<Integer> recv =
|
||||||
} catch (RemoteException e) {
|
new SynchronousResultReceiver();
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
service.getConnectionState(device, mAttributionSource, recv);
|
||||||
return BluetoothProfile.STATE_DISCONNECTED;
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return BluetoothProfile.STATE_DISCONNECTED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -390,20 +425,22 @@ public final class BluetoothMap implements BluetoothProfile, AutoCloseable {
|
|||||||
@ConnectionPolicy int connectionPolicy) {
|
@ConnectionPolicy int connectionPolicy) {
|
||||||
if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
|
if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
|
||||||
final IBluetoothMap service = getService();
|
final IBluetoothMap service = getService();
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final boolean defaultValue = false;
|
||||||
if (connectionPolicy != BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
|
if (service == null) {
|
||||||
&& connectionPolicy != BluetoothProfile.CONNECTION_POLICY_ALLOWED) {
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
return false;
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
}
|
} else if (isEnabled() && isValidDevice(device)
|
||||||
|
&& (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
|
||||||
|
|| connectionPolicy == BluetoothProfile.CONNECTION_POLICY_ALLOWED)) {
|
||||||
try {
|
try {
|
||||||
return service.setConnectionPolicy(device, connectionPolicy, mAttributionSource);
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.setConnectionPolicy(device, connectionPolicy, mAttributionSource, recv);
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
return false;
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -446,16 +483,20 @@ public final class BluetoothMap implements BluetoothProfile, AutoCloseable {
|
|||||||
public @ConnectionPolicy int getConnectionPolicy(@NonNull BluetoothDevice device) {
|
public @ConnectionPolicy int getConnectionPolicy(@NonNull BluetoothDevice device) {
|
||||||
if (VDBG) log("getConnectionPolicy(" + device + ")");
|
if (VDBG) log("getConnectionPolicy(" + device + ")");
|
||||||
final IBluetoothMap service = getService();
|
final IBluetoothMap service = getService();
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final int defaultValue = BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.getConnectionPolicy(device, mAttributionSource);
|
final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.getConnectionPolicy(device, mAttributionSource, recv);
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void log(String msg) {
|
private static void log(String msg) {
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package android.bluetooth;
|
package android.bluetooth;
|
||||||
|
|
||||||
|
import static android.bluetooth.BluetoothUtils.getSyncTimeout;
|
||||||
|
|
||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
@@ -29,15 +31,17 @@ import android.compat.annotation.UnsupportedAppUsage;
|
|||||||
import android.content.AttributionSource;
|
import android.content.AttributionSource;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Binder;
|
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.android.modules.utils.SynchronousResultReceiver;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class provides the APIs to control the Bluetooth MAP MCE Profile.
|
* This class provides the APIs to control the Bluetooth MAP MCE Profile.
|
||||||
@@ -180,7 +184,7 @@ public final class BluetoothMapClient implements BluetoothProfile {
|
|||||||
"BluetoothMapClient", IBluetoothMapClient.class.getName()) {
|
"BluetoothMapClient", IBluetoothMapClient.class.getName()) {
|
||||||
@Override
|
@Override
|
||||||
public IBluetoothMapClient getServiceInterface(IBinder service) {
|
public IBluetoothMapClient getServiceInterface(IBinder service) {
|
||||||
return IBluetoothMapClient.Stub.asInterface(Binder.allowBlocking(service));
|
return IBluetoothMapClient.Stub.asInterface(service);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -221,17 +225,20 @@ public final class BluetoothMapClient implements BluetoothProfile {
|
|||||||
public boolean isConnected(BluetoothDevice device) {
|
public boolean isConnected(BluetoothDevice device) {
|
||||||
if (VDBG) Log.d(TAG, "isConnected(" + device + ")");
|
if (VDBG) Log.d(TAG, "isConnected(" + device + ")");
|
||||||
final IBluetoothMapClient service = getService();
|
final IBluetoothMapClient service = getService();
|
||||||
if (service != null) {
|
final boolean defaultValue = false;
|
||||||
try {
|
if (service == null) {
|
||||||
return service.isConnected(device, mAttributionSource);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, e.toString());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
|
if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
|
service.isConnected(device, mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
return false;
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -248,17 +255,20 @@ public final class BluetoothMapClient implements BluetoothProfile {
|
|||||||
public boolean connect(BluetoothDevice device) {
|
public boolean connect(BluetoothDevice device) {
|
||||||
if (DBG) Log.d(TAG, "connect(" + device + ")" + "for MAPS MCE");
|
if (DBG) Log.d(TAG, "connect(" + device + ")" + "for MAPS MCE");
|
||||||
final IBluetoothMapClient service = getService();
|
final IBluetoothMapClient service = getService();
|
||||||
if (service != null) {
|
final boolean defaultValue = false;
|
||||||
try {
|
if (service == null) {
|
||||||
return service.connect(device, mAttributionSource);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, e.toString());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
|
if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
|
service.connect(device, mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
return false;
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -277,15 +287,20 @@ public final class BluetoothMapClient implements BluetoothProfile {
|
|||||||
public boolean disconnect(BluetoothDevice device) {
|
public boolean disconnect(BluetoothDevice device) {
|
||||||
if (DBG) Log.d(TAG, "disconnect(" + device + ")");
|
if (DBG) Log.d(TAG, "disconnect(" + device + ")");
|
||||||
final IBluetoothMapClient service = getService();
|
final IBluetoothMapClient service = getService();
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final boolean defaultValue = false;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.disconnect(device, mAttributionSource);
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.disconnect(device, mAttributionSource, recv);
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -300,17 +315,23 @@ public final class BluetoothMapClient implements BluetoothProfile {
|
|||||||
public List<BluetoothDevice> getConnectedDevices() {
|
public List<BluetoothDevice> getConnectedDevices() {
|
||||||
if (DBG) Log.d(TAG, "getConnectedDevices()");
|
if (DBG) Log.d(TAG, "getConnectedDevices()");
|
||||||
final IBluetoothMapClient service = getService();
|
final IBluetoothMapClient service = getService();
|
||||||
if (service != null && isEnabled()) {
|
final List<BluetoothDevice> defaultValue = new ArrayList<>();
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
try {
|
try {
|
||||||
|
final SynchronousResultReceiver<List<BluetoothDevice>> recv =
|
||||||
|
new SynchronousResultReceiver();
|
||||||
|
service.getConnectedDevices(mAttributionSource, recv);
|
||||||
return Attributable.setAttributionSource(
|
return Attributable.setAttributionSource(
|
||||||
service.getConnectedDevices(mAttributionSource), mAttributionSource);
|
recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
|
||||||
} catch (RemoteException e) {
|
mAttributionSource);
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
} catch (RemoteException | TimeoutException e) {
|
||||||
return new ArrayList<>();
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return new ArrayList<>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -325,18 +346,23 @@ public final class BluetoothMapClient implements BluetoothProfile {
|
|||||||
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
|
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
|
||||||
if (DBG) Log.d(TAG, "getDevicesMatchingStates()");
|
if (DBG) Log.d(TAG, "getDevicesMatchingStates()");
|
||||||
final IBluetoothMapClient service = getService();
|
final IBluetoothMapClient service = getService();
|
||||||
if (service != null && isEnabled()) {
|
final List<BluetoothDevice> defaultValue = new ArrayList<>();
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
try {
|
try {
|
||||||
|
final SynchronousResultReceiver<List<BluetoothDevice>> recv =
|
||||||
|
new SynchronousResultReceiver();
|
||||||
|
service.getDevicesMatchingConnectionStates(states, mAttributionSource, recv);
|
||||||
return Attributable.setAttributionSource(
|
return Attributable.setAttributionSource(
|
||||||
service.getDevicesMatchingConnectionStates(states, mAttributionSource),
|
recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
|
||||||
mAttributionSource);
|
mAttributionSource);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException | TimeoutException e) {
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
return new ArrayList<>();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return new ArrayList<>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -351,16 +377,20 @@ public final class BluetoothMapClient implements BluetoothProfile {
|
|||||||
public int getConnectionState(BluetoothDevice device) {
|
public int getConnectionState(BluetoothDevice device) {
|
||||||
if (DBG) Log.d(TAG, "getConnectionState(" + device + ")");
|
if (DBG) Log.d(TAG, "getConnectionState(" + device + ")");
|
||||||
final IBluetoothMapClient service = getService();
|
final IBluetoothMapClient service = getService();
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final int defaultValue = BluetoothProfile.STATE_DISCONNECTED;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.getConnectionState(device, mAttributionSource);
|
final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver<>();
|
||||||
} catch (RemoteException e) {
|
service.getConnectionState(device, mAttributionSource, recv);
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
return BluetoothProfile.STATE_DISCONNECTED;
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return BluetoothProfile.STATE_DISCONNECTED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -405,20 +435,22 @@ public final class BluetoothMapClient implements BluetoothProfile {
|
|||||||
@ConnectionPolicy int connectionPolicy) {
|
@ConnectionPolicy int connectionPolicy) {
|
||||||
if (DBG) Log.d(TAG, "setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
|
if (DBG) Log.d(TAG, "setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
|
||||||
final IBluetoothMapClient service = getService();
|
final IBluetoothMapClient service = getService();
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final boolean defaultValue = false;
|
||||||
if (connectionPolicy != BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
|
if (service == null) {
|
||||||
&& connectionPolicy != BluetoothProfile.CONNECTION_POLICY_ALLOWED) {
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
return false;
|
if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
|
||||||
}
|
} else if (isEnabled() && isValidDevice(device)
|
||||||
|
&& (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
|
||||||
|
|| connectionPolicy == BluetoothProfile.CONNECTION_POLICY_ALLOWED)) {
|
||||||
try {
|
try {
|
||||||
return service.setConnectionPolicy(device, connectionPolicy, mAttributionSource);
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.setConnectionPolicy(device, connectionPolicy, mAttributionSource, recv);
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
return false;
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -460,16 +492,20 @@ public final class BluetoothMapClient implements BluetoothProfile {
|
|||||||
public @ConnectionPolicy int getConnectionPolicy(@NonNull BluetoothDevice device) {
|
public @ConnectionPolicy int getConnectionPolicy(@NonNull BluetoothDevice device) {
|
||||||
if (VDBG) Log.d(TAG, "getConnectionPolicy(" + device + ")");
|
if (VDBG) Log.d(TAG, "getConnectionPolicy(" + device + ")");
|
||||||
final IBluetoothMapClient service = getService();
|
final IBluetoothMapClient service = getService();
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final int defaultValue = BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.getConnectionPolicy(device, mAttributionSource);
|
final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.getConnectionPolicy(device, mAttributionSource, recv);
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -494,18 +530,8 @@ public final class BluetoothMapClient implements BluetoothProfile {
|
|||||||
public boolean sendMessage(@NonNull BluetoothDevice device, @NonNull Collection<Uri> contacts,
|
public boolean sendMessage(@NonNull BluetoothDevice device, @NonNull Collection<Uri> contacts,
|
||||||
@NonNull String message, @Nullable PendingIntent sentIntent,
|
@NonNull String message, @Nullable PendingIntent sentIntent,
|
||||||
@Nullable PendingIntent deliveredIntent) {
|
@Nullable PendingIntent deliveredIntent) {
|
||||||
if (DBG) Log.d(TAG, "sendMessage(" + device + ", " + contacts + ", " + message);
|
return sendMessage(device, contacts.toArray(new Uri[contacts.size()]), message, sentIntent,
|
||||||
final IBluetoothMapClient service = getService();
|
deliveredIntent);
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
|
||||||
try {
|
|
||||||
return service.sendMessage(device, contacts.toArray(new Uri[contacts.size()]),
|
|
||||||
message, sentIntent, deliveredIntent, mAttributionSource);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -531,16 +557,21 @@ public final class BluetoothMapClient implements BluetoothProfile {
|
|||||||
PendingIntent sentIntent, PendingIntent deliveredIntent) {
|
PendingIntent sentIntent, PendingIntent deliveredIntent) {
|
||||||
if (DBG) Log.d(TAG, "sendMessage(" + device + ", " + contacts + ", " + message);
|
if (DBG) Log.d(TAG, "sendMessage(" + device + ", " + contacts + ", " + message);
|
||||||
final IBluetoothMapClient service = getService();
|
final IBluetoothMapClient service = getService();
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final boolean defaultValue = false;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.sendMessage(device, contacts, message, sentIntent, deliveredIntent,
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
mAttributionSource);
|
service.sendMessage(device, contacts, message, sentIntent, deliveredIntent,
|
||||||
} catch (RemoteException e) {
|
mAttributionSource, recv);
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
return false;
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -558,15 +589,20 @@ public final class BluetoothMapClient implements BluetoothProfile {
|
|||||||
public boolean getUnreadMessages(BluetoothDevice device) {
|
public boolean getUnreadMessages(BluetoothDevice device) {
|
||||||
if (DBG) Log.d(TAG, "getUnreadMessages(" + device + ")");
|
if (DBG) Log.d(TAG, "getUnreadMessages(" + device + ")");
|
||||||
final IBluetoothMapClient service = getService();
|
final IBluetoothMapClient service = getService();
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final boolean defaultValue = false;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.getUnreadMessages(device, mAttributionSource);
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.getUnreadMessages(device, mAttributionSource, recv);
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
return false;
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -580,13 +616,21 @@ public final class BluetoothMapClient implements BluetoothProfile {
|
|||||||
@RequiresBluetoothConnectPermission
|
@RequiresBluetoothConnectPermission
|
||||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
public boolean isUploadingSupported(BluetoothDevice device) {
|
public boolean isUploadingSupported(BluetoothDevice device) {
|
||||||
|
if (DBG) Log.d(TAG, "isUploadingSupported(" + device + ")");
|
||||||
final IBluetoothMapClient service = getService();
|
final IBluetoothMapClient service = getService();
|
||||||
|
final int defaultValue = 0;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return (service != null && isEnabled() && isValidDevice(device))
|
final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
|
||||||
&& ((service.getSupportedFeatures(device, mAttributionSource)
|
service.getSupportedFeatures(device, mAttributionSource, recv);
|
||||||
& UPLOADING_FEATURE_BITMASK) > 0);
|
return (recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue)
|
||||||
} catch (RemoteException e) {
|
& UPLOADING_FEATURE_BITMASK) > 0;
|
||||||
Log.e(TAG, e.getMessage());
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -615,16 +659,21 @@ public final class BluetoothMapClient implements BluetoothProfile {
|
|||||||
public boolean setMessageStatus(BluetoothDevice device, String handle, int status) {
|
public boolean setMessageStatus(BluetoothDevice device, String handle, int status) {
|
||||||
if (DBG) Log.d(TAG, "setMessageStatus(" + device + ", " + handle + ", " + status + ")");
|
if (DBG) Log.d(TAG, "setMessageStatus(" + device + ", " + handle + ", " + status + ")");
|
||||||
final IBluetoothMapClient service = getService();
|
final IBluetoothMapClient service = getService();
|
||||||
if (service != null && isEnabled() && isValidDevice(device) && handle != null &&
|
final boolean defaultValue = false;
|
||||||
(status == READ || status == UNREAD || status == UNDELETED || status == DELETED)) {
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device) && handle != null && (status == READ
|
||||||
|
|| status == UNREAD || status == UNDELETED || status == DELETED)) {
|
||||||
try {
|
try {
|
||||||
return service.setMessageStatus(device, handle, status, mAttributionSource);
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.setMessageStatus(device, handle, status, mAttributionSource, recv);
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
return false;
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isEnabled() {
|
private boolean isEnabled() {
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package android.bluetooth;
|
package android.bluetooth;
|
||||||
|
|
||||||
|
import static android.bluetooth.BluetoothUtils.getSyncTimeout;
|
||||||
|
|
||||||
import android.annotation.IntDef;
|
import android.annotation.IntDef;
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.RequiresPermission;
|
import android.annotation.RequiresPermission;
|
||||||
@@ -28,16 +30,18 @@ import android.bluetooth.annotations.RequiresLegacyBluetoothPermission;
|
|||||||
import android.compat.annotation.UnsupportedAppUsage;
|
import android.compat.annotation.UnsupportedAppUsage;
|
||||||
import android.content.AttributionSource;
|
import android.content.AttributionSource;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Binder;
|
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.android.modules.utils.SynchronousResultReceiver;
|
||||||
|
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class provides the APIs to control the Bluetooth Pan
|
* This class provides the APIs to control the Bluetooth Pan
|
||||||
@@ -188,7 +192,7 @@ public final class BluetoothPan implements BluetoothProfile {
|
|||||||
"BluetoothPan", IBluetoothPan.class.getName()) {
|
"BluetoothPan", IBluetoothPan.class.getName()) {
|
||||||
@Override
|
@Override
|
||||||
public IBluetoothPan getServiceInterface(IBinder service) {
|
public IBluetoothPan getServiceInterface(IBinder service) {
|
||||||
return IBluetoothPan.Stub.asInterface(Binder.allowBlocking(service));
|
return IBluetoothPan.Stub.asInterface(service);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -249,16 +253,20 @@ public final class BluetoothPan implements BluetoothProfile {
|
|||||||
public boolean connect(BluetoothDevice device) {
|
public boolean connect(BluetoothDevice device) {
|
||||||
if (DBG) log("connect(" + device + ")");
|
if (DBG) log("connect(" + device + ")");
|
||||||
final IBluetoothPan service = getService();
|
final IBluetoothPan service = getService();
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final boolean defaultValue = false;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.connect(device, mAttributionSource);
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.connect(device, mAttributionSource, recv);
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
return false;
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -289,16 +297,20 @@ public final class BluetoothPan implements BluetoothProfile {
|
|||||||
public boolean disconnect(BluetoothDevice device) {
|
public boolean disconnect(BluetoothDevice device) {
|
||||||
if (DBG) log("disconnect(" + device + ")");
|
if (DBG) log("disconnect(" + device + ")");
|
||||||
final IBluetoothPan service = getService();
|
final IBluetoothPan service = getService();
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final boolean defaultValue = false;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.disconnect(device, mAttributionSource);
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.disconnect(device, mAttributionSource, recv);
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
return false;
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -322,22 +334,23 @@ public final class BluetoothPan implements BluetoothProfile {
|
|||||||
public boolean setConnectionPolicy(@NonNull BluetoothDevice device,
|
public boolean setConnectionPolicy(@NonNull BluetoothDevice device,
|
||||||
@ConnectionPolicy int connectionPolicy) {
|
@ConnectionPolicy int connectionPolicy) {
|
||||||
if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
|
if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
|
||||||
try {
|
|
||||||
final IBluetoothPan service = getService();
|
final IBluetoothPan service = getService();
|
||||||
if (service != null && isEnabled()
|
final boolean defaultValue = false;
|
||||||
&& isValidDevice(device)) {
|
if (service == null) {
|
||||||
if (connectionPolicy != BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
&& connectionPolicy != BluetoothProfile.CONNECTION_POLICY_ALLOWED) {
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
return false;
|
} else if (isEnabled() && isValidDevice(device)
|
||||||
|
&& (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
|
||||||
|
|| connectionPolicy == BluetoothProfile.CONNECTION_POLICY_ALLOWED)) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
|
service.setConnectionPolicy(device, connectionPolicy, mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
return service.setConnectionPolicy(device, connectionPolicy, mAttributionSource);
|
|
||||||
}
|
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
|
||||||
return false;
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -354,17 +367,23 @@ public final class BluetoothPan implements BluetoothProfile {
|
|||||||
public @NonNull List<BluetoothDevice> getConnectedDevices() {
|
public @NonNull List<BluetoothDevice> getConnectedDevices() {
|
||||||
if (VDBG) log("getConnectedDevices()");
|
if (VDBG) log("getConnectedDevices()");
|
||||||
final IBluetoothPan service = getService();
|
final IBluetoothPan service = getService();
|
||||||
if (service != null && isEnabled()) {
|
final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
try {
|
try {
|
||||||
|
final SynchronousResultReceiver<List<BluetoothDevice>> recv =
|
||||||
|
new SynchronousResultReceiver();
|
||||||
|
service.getConnectedDevices(mAttributionSource, recv);
|
||||||
return Attributable.setAttributionSource(
|
return Attributable.setAttributionSource(
|
||||||
service.getConnectedDevices(mAttributionSource), mAttributionSource);
|
recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
|
||||||
} catch (RemoteException e) {
|
mAttributionSource);
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
} catch (RemoteException | TimeoutException e) {
|
||||||
return new ArrayList<BluetoothDevice>();
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return new ArrayList<BluetoothDevice>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -381,18 +400,23 @@ public final class BluetoothPan implements BluetoothProfile {
|
|||||||
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
|
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
|
||||||
if (VDBG) log("getDevicesMatchingStates()");
|
if (VDBG) log("getDevicesMatchingStates()");
|
||||||
final IBluetoothPan service = getService();
|
final IBluetoothPan service = getService();
|
||||||
if (service != null && isEnabled()) {
|
final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
try {
|
try {
|
||||||
|
final SynchronousResultReceiver<List<BluetoothDevice>> recv =
|
||||||
|
new SynchronousResultReceiver();
|
||||||
|
service.getDevicesMatchingConnectionStates(states, mAttributionSource, recv);
|
||||||
return Attributable.setAttributionSource(
|
return Attributable.setAttributionSource(
|
||||||
service.getDevicesMatchingConnectionStates(states, mAttributionSource),
|
recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
|
||||||
mAttributionSource);
|
mAttributionSource);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException | TimeoutException e) {
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
return new ArrayList<BluetoothDevice>();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return new ArrayList<BluetoothDevice>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -409,16 +433,20 @@ public final class BluetoothPan implements BluetoothProfile {
|
|||||||
public int getConnectionState(@NonNull BluetoothDevice device) {
|
public int getConnectionState(@NonNull BluetoothDevice device) {
|
||||||
if (VDBG) log("getState(" + device + ")");
|
if (VDBG) log("getState(" + device + ")");
|
||||||
final IBluetoothPan service = getService();
|
final IBluetoothPan service = getService();
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final int defaultValue = BluetoothProfile.STATE_DISCONNECTED;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.getConnectionState(device, mAttributionSource);
|
final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.getConnectionState(device, mAttributionSource, recv);
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
return BluetoothProfile.STATE_DISCONNECTED;
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return BluetoothProfile.STATE_DISCONNECTED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -438,11 +466,16 @@ public final class BluetoothPan implements BluetoothProfile {
|
|||||||
String pkgName = mContext.getOpPackageName();
|
String pkgName = mContext.getOpPackageName();
|
||||||
if (DBG) log("setBluetoothTethering(" + value + "), calling package:" + pkgName);
|
if (DBG) log("setBluetoothTethering(" + value + "), calling package:" + pkgName);
|
||||||
final IBluetoothPan service = getService();
|
final IBluetoothPan service = getService();
|
||||||
if (service != null && isEnabled()) {
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
try {
|
try {
|
||||||
service.setBluetoothTethering(value, mAttributionSource);
|
final SynchronousResultReceiver recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.setBluetoothTethering(value, mAttributionSource, recv);
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(null);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -459,14 +492,20 @@ public final class BluetoothPan implements BluetoothProfile {
|
|||||||
public boolean isTetheringOn() {
|
public boolean isTetheringOn() {
|
||||||
if (VDBG) log("isTetheringOn()");
|
if (VDBG) log("isTetheringOn()");
|
||||||
final IBluetoothPan service = getService();
|
final IBluetoothPan service = getService();
|
||||||
if (service != null && isEnabled()) {
|
final boolean defaultValue = false;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
try {
|
try {
|
||||||
return service.isTetheringOn(mAttributionSource);
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.isTetheringOn(mAttributionSource, recv);
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@UnsupportedAppUsage
|
@UnsupportedAppUsage
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package android.bluetooth;
|
package android.bluetooth;
|
||||||
|
|
||||||
|
import static android.bluetooth.BluetoothUtils.getSyncTimeout;
|
||||||
|
|
||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.RequiresPermission;
|
import android.annotation.RequiresPermission;
|
||||||
@@ -24,13 +26,15 @@ import android.annotation.SdkConstant.SdkConstantType;
|
|||||||
import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
|
import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
|
||||||
import android.content.AttributionSource;
|
import android.content.AttributionSource;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Binder;
|
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.android.modules.utils.SynchronousResultReceiver;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class provides the APIs to control the Bluetooth PBAP Client Profile.
|
* This class provides the APIs to control the Bluetooth PBAP Client Profile.
|
||||||
@@ -64,7 +68,7 @@ public final class BluetoothPbapClient implements BluetoothProfile {
|
|||||||
"BluetoothPbapClient", IBluetoothPbapClient.class.getName()) {
|
"BluetoothPbapClient", IBluetoothPbapClient.class.getName()) {
|
||||||
@Override
|
@Override
|
||||||
public IBluetoothPbapClient getServiceInterface(IBinder service) {
|
public IBluetoothPbapClient getServiceInterface(IBinder service) {
|
||||||
return IBluetoothPbapClient.Stub.asInterface(Binder.allowBlocking(service));
|
return IBluetoothPbapClient.Stub.asInterface(service);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -123,18 +127,20 @@ public final class BluetoothPbapClient implements BluetoothProfile {
|
|||||||
log("connect(" + device + ") for PBAP Client.");
|
log("connect(" + device + ") for PBAP Client.");
|
||||||
}
|
}
|
||||||
final IBluetoothPbapClient service = getService();
|
final IBluetoothPbapClient service = getService();
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final boolean defaultValue = false;
|
||||||
try {
|
|
||||||
return service.connect(device, mAttributionSource);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (service == null) {
|
if (service == null) {
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
|
service.connect(device, mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
return false;
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -155,19 +161,21 @@ public final class BluetoothPbapClient implements BluetoothProfile {
|
|||||||
log("disconnect(" + device + ")" + new Exception());
|
log("disconnect(" + device + ")" + new Exception());
|
||||||
}
|
}
|
||||||
final IBluetoothPbapClient service = getService();
|
final IBluetoothPbapClient service = getService();
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final boolean defaultValue = true;
|
||||||
try {
|
|
||||||
service.disconnect(device, mAttributionSource);
|
|
||||||
return true;
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (service == null) {
|
if (service == null) {
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
|
service.disconnect(device, mAttributionSource, recv);
|
||||||
|
recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
return true;
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
return false;
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -184,19 +192,23 @@ public final class BluetoothPbapClient implements BluetoothProfile {
|
|||||||
log("getConnectedDevices()");
|
log("getConnectedDevices()");
|
||||||
}
|
}
|
||||||
final IBluetoothPbapClient service = getService();
|
final IBluetoothPbapClient service = getService();
|
||||||
if (service != null && isEnabled()) {
|
final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
|
||||||
try {
|
|
||||||
return Attributable.setAttributionSource(
|
|
||||||
service.getConnectedDevices(mAttributionSource), mAttributionSource);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
|
||||||
return new ArrayList<BluetoothDevice>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (service == null) {
|
if (service == null) {
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<List<BluetoothDevice>> recv =
|
||||||
|
new SynchronousResultReceiver();
|
||||||
|
service.getConnectedDevices(mAttributionSource, recv);
|
||||||
|
return Attributable.setAttributionSource(
|
||||||
|
recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
|
||||||
|
mAttributionSource);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
return new ArrayList<BluetoothDevice>();
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -212,20 +224,23 @@ public final class BluetoothPbapClient implements BluetoothProfile {
|
|||||||
log("getDevicesMatchingStates()");
|
log("getDevicesMatchingStates()");
|
||||||
}
|
}
|
||||||
final IBluetoothPbapClient service = getService();
|
final IBluetoothPbapClient service = getService();
|
||||||
if (service != null && isEnabled()) {
|
final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
|
||||||
try {
|
|
||||||
return Attributable.setAttributionSource(
|
|
||||||
service.getDevicesMatchingConnectionStates(states, mAttributionSource),
|
|
||||||
mAttributionSource);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
|
||||||
return new ArrayList<BluetoothDevice>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (service == null) {
|
if (service == null) {
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<List<BluetoothDevice>> recv =
|
||||||
|
new SynchronousResultReceiver();
|
||||||
|
service.getDevicesMatchingConnectionStates(states, mAttributionSource, recv);
|
||||||
|
return Attributable.setAttributionSource(
|
||||||
|
recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
|
||||||
|
mAttributionSource);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
return new ArrayList<BluetoothDevice>();
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -241,18 +256,20 @@ public final class BluetoothPbapClient implements BluetoothProfile {
|
|||||||
log("getConnectionState(" + device + ")");
|
log("getConnectionState(" + device + ")");
|
||||||
}
|
}
|
||||||
final IBluetoothPbapClient service = getService();
|
final IBluetoothPbapClient service = getService();
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final int defaultValue = BluetoothProfile.STATE_DISCONNECTED;
|
||||||
try {
|
|
||||||
return service.getConnectionState(device, mAttributionSource);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
|
||||||
return BluetoothProfile.STATE_DISCONNECTED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (service == null) {
|
if (service == null) {
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
|
||||||
|
service.getConnectionState(device, mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
return BluetoothProfile.STATE_DISCONNECTED;
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void log(String msg) {
|
private static void log(String msg) {
|
||||||
@@ -311,22 +328,22 @@ public final class BluetoothPbapClient implements BluetoothProfile {
|
|||||||
log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
|
log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
|
||||||
}
|
}
|
||||||
final IBluetoothPbapClient service = getService();
|
final IBluetoothPbapClient service = getService();
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final boolean defaultValue = false;
|
||||||
if (connectionPolicy != BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
|
|
||||||
&& connectionPolicy != BluetoothProfile.CONNECTION_POLICY_ALLOWED) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
return service.setConnectionPolicy(device, connectionPolicy, mAttributionSource);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (service == null) {
|
if (service == null) {
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)
|
||||||
|
&& (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
|
||||||
|
|| connectionPolicy == BluetoothProfile.CONNECTION_POLICY_ALLOWED)) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
|
service.setConnectionPolicy(device, connectionPolicy, mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
return false;
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -370,17 +387,19 @@ public final class BluetoothPbapClient implements BluetoothProfile {
|
|||||||
log("getConnectionPolicy(" + device + ")");
|
log("getConnectionPolicy(" + device + ")");
|
||||||
}
|
}
|
||||||
final IBluetoothPbapClient service = getService();
|
final IBluetoothPbapClient service = getService();
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final int defaultValue = BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
|
||||||
try {
|
|
||||||
return service.getConnectionPolicy(device, mAttributionSource);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
|
||||||
return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (service == null) {
|
if (service == null) {
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
}
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
|
||||||
|
service.getConnectionPolicy(device, mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package android.bluetooth;
|
package android.bluetooth;
|
||||||
|
|
||||||
|
import static android.bluetooth.BluetoothUtils.getSyncTimeout;
|
||||||
|
|
||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
import android.annotation.RequiresNoPermission;
|
import android.annotation.RequiresNoPermission;
|
||||||
import android.annotation.RequiresPermission;
|
import android.annotation.RequiresPermission;
|
||||||
@@ -26,14 +28,16 @@ import android.bluetooth.annotations.RequiresLegacyBluetoothPermission;
|
|||||||
import android.compat.annotation.UnsupportedAppUsage;
|
import android.compat.annotation.UnsupportedAppUsage;
|
||||||
import android.content.AttributionSource;
|
import android.content.AttributionSource;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Binder;
|
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.android.modules.utils.SynchronousResultReceiver;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class provides the APIs to control the Bluetooth SIM
|
* This class provides the APIs to control the Bluetooth SIM
|
||||||
@@ -104,7 +108,7 @@ public final class BluetoothSap implements BluetoothProfile {
|
|||||||
"BluetoothSap", IBluetoothSap.class.getName()) {
|
"BluetoothSap", IBluetoothSap.class.getName()) {
|
||||||
@Override
|
@Override
|
||||||
public IBluetoothSap getServiceInterface(IBinder service) {
|
public IBluetoothSap getServiceInterface(IBinder service) {
|
||||||
return IBluetoothSap.Stub.asInterface(Binder.allowBlocking(service));
|
return IBluetoothSap.Stub.asInterface(service);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -155,17 +159,20 @@ public final class BluetoothSap implements BluetoothProfile {
|
|||||||
public int getState() {
|
public int getState() {
|
||||||
if (VDBG) log("getState()");
|
if (VDBG) log("getState()");
|
||||||
final IBluetoothSap service = getService();
|
final IBluetoothSap service = getService();
|
||||||
if (service != null) {
|
final int defaultValue = BluetoothSap.STATE_ERROR;
|
||||||
try {
|
if (service == null) {
|
||||||
return service.getState(mAttributionSource);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, e.toString());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
|
||||||
|
service.getState(mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
return BluetoothSap.STATE_ERROR;
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -180,18 +187,23 @@ public final class BluetoothSap implements BluetoothProfile {
|
|||||||
public BluetoothDevice getClient() {
|
public BluetoothDevice getClient() {
|
||||||
if (VDBG) log("getClient()");
|
if (VDBG) log("getClient()");
|
||||||
final IBluetoothSap service = getService();
|
final IBluetoothSap service = getService();
|
||||||
if (service != null) {
|
final BluetoothDevice defaultValue = null;
|
||||||
try {
|
if (service == null) {
|
||||||
return Attributable.setAttributionSource(
|
|
||||||
service.getClient(mAttributionSource), mAttributionSource);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, e.toString());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<BluetoothDevice> recv =
|
||||||
|
new SynchronousResultReceiver();
|
||||||
|
service.getClient(mAttributionSource, recv);
|
||||||
|
return Attributable.setAttributionSource(
|
||||||
|
recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
|
||||||
|
mAttributionSource);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
return null;
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -206,17 +218,20 @@ public final class BluetoothSap implements BluetoothProfile {
|
|||||||
public boolean isConnected(BluetoothDevice device) {
|
public boolean isConnected(BluetoothDevice device) {
|
||||||
if (VDBG) log("isConnected(" + device + ")");
|
if (VDBG) log("isConnected(" + device + ")");
|
||||||
final IBluetoothSap service = getService();
|
final IBluetoothSap service = getService();
|
||||||
if (service != null) {
|
final boolean defaultValue = false;
|
||||||
try {
|
if (service == null) {
|
||||||
return service.isConnected(device, mAttributionSource);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, e.toString());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
|
service.isConnected(device, mAttributionSource, recv);
|
||||||
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
return false;
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -244,16 +259,20 @@ public final class BluetoothSap implements BluetoothProfile {
|
|||||||
public boolean disconnect(BluetoothDevice device) {
|
public boolean disconnect(BluetoothDevice device) {
|
||||||
if (DBG) log("disconnect(" + device + ")");
|
if (DBG) log("disconnect(" + device + ")");
|
||||||
final IBluetoothSap service = getService();
|
final IBluetoothSap service = getService();
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final boolean defaultValue = false;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.disconnect(device, mAttributionSource);
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.disconnect(device, mAttributionSource, recv);
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
return false;
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -267,17 +286,23 @@ public final class BluetoothSap implements BluetoothProfile {
|
|||||||
public List<BluetoothDevice> getConnectedDevices() {
|
public List<BluetoothDevice> getConnectedDevices() {
|
||||||
if (DBG) log("getConnectedDevices()");
|
if (DBG) log("getConnectedDevices()");
|
||||||
final IBluetoothSap service = getService();
|
final IBluetoothSap service = getService();
|
||||||
if (service != null && isEnabled()) {
|
final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
try {
|
try {
|
||||||
|
final SynchronousResultReceiver<List<BluetoothDevice>> recv =
|
||||||
|
new SynchronousResultReceiver();
|
||||||
|
service.getConnectedDevices(mAttributionSource, recv);
|
||||||
return Attributable.setAttributionSource(
|
return Attributable.setAttributionSource(
|
||||||
service.getConnectedDevices(mAttributionSource), mAttributionSource);
|
recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
|
||||||
} catch (RemoteException e) {
|
mAttributionSource);
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
} catch (RemoteException | TimeoutException e) {
|
||||||
return new ArrayList<BluetoothDevice>();
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return new ArrayList<BluetoothDevice>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -291,18 +316,23 @@ public final class BluetoothSap implements BluetoothProfile {
|
|||||||
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
|
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
|
||||||
if (DBG) log("getDevicesMatchingStates()");
|
if (DBG) log("getDevicesMatchingStates()");
|
||||||
final IBluetoothSap service = getService();
|
final IBluetoothSap service = getService();
|
||||||
if (service != null && isEnabled()) {
|
final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
try {
|
try {
|
||||||
|
final SynchronousResultReceiver<List<BluetoothDevice>> recv =
|
||||||
|
new SynchronousResultReceiver();
|
||||||
|
service.getDevicesMatchingConnectionStates(states, mAttributionSource, recv);
|
||||||
return Attributable.setAttributionSource(
|
return Attributable.setAttributionSource(
|
||||||
service.getDevicesMatchingConnectionStates(states, mAttributionSource),
|
recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
|
||||||
mAttributionSource);
|
mAttributionSource);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException | TimeoutException e) {
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
return new ArrayList<BluetoothDevice>();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return new ArrayList<BluetoothDevice>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -316,16 +346,20 @@ public final class BluetoothSap implements BluetoothProfile {
|
|||||||
public int getConnectionState(BluetoothDevice device) {
|
public int getConnectionState(BluetoothDevice device) {
|
||||||
if (DBG) log("getConnectionState(" + device + ")");
|
if (DBG) log("getConnectionState(" + device + ")");
|
||||||
final IBluetoothSap service = getService();
|
final IBluetoothSap service = getService();
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final int defaultValue = BluetoothProfile.STATE_DISCONNECTED;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.getConnectionState(device, mAttributionSource);
|
final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.getConnectionState(device, mAttributionSource, recv);
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
return BluetoothProfile.STATE_DISCONNECTED;
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return BluetoothProfile.STATE_DISCONNECTED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -370,20 +404,22 @@ public final class BluetoothSap implements BluetoothProfile {
|
|||||||
@ConnectionPolicy int connectionPolicy) {
|
@ConnectionPolicy int connectionPolicy) {
|
||||||
if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
|
if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
|
||||||
final IBluetoothSap service = getService();
|
final IBluetoothSap service = getService();
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final boolean defaultValue = false;
|
||||||
if (connectionPolicy != BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
|
if (service == null) {
|
||||||
&& connectionPolicy != BluetoothProfile.CONNECTION_POLICY_ALLOWED) {
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
return false;
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
}
|
} else if (isEnabled() && isValidDevice(device)
|
||||||
|
&& (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
|
||||||
|
|| connectionPolicy == BluetoothProfile.CONNECTION_POLICY_ALLOWED)) {
|
||||||
try {
|
try {
|
||||||
return service.setConnectionPolicy(device, connectionPolicy, mAttributionSource);
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.setConnectionPolicy(device, connectionPolicy, mAttributionSource, recv);
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
return false;
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -425,16 +461,20 @@ public final class BluetoothSap implements BluetoothProfile {
|
|||||||
public @ConnectionPolicy int getConnectionPolicy(BluetoothDevice device) {
|
public @ConnectionPolicy int getConnectionPolicy(BluetoothDevice device) {
|
||||||
if (VDBG) log("getConnectionPolicy(" + device + ")");
|
if (VDBG) log("getConnectionPolicy(" + device + ")");
|
||||||
final IBluetoothSap service = getService();
|
final IBluetoothSap service = getService();
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final int defaultValue = BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.getConnectionPolicy(device, mAttributionSource);
|
final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.getConnectionPolicy(device, mAttributionSource, recv);
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void log(String msg) {
|
private static void log(String msg) {
|
||||||
|
|||||||
41
core/java/android/bluetooth/BluetoothUtils.java
Normal file
41
core/java/android/bluetooth/BluetoothUtils.java
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 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 java.time.Duration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@hide}
|
||||||
|
*/
|
||||||
|
public final class BluetoothUtils {
|
||||||
|
/**
|
||||||
|
* This utility class cannot be instantiated
|
||||||
|
*/
|
||||||
|
private BluetoothUtils() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Timeout value for synchronous binder call
|
||||||
|
*/
|
||||||
|
private static final Duration SYNC_CALLS_TIMEOUT = Duration.ofSeconds(5);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return timeout value for synchronous binder call
|
||||||
|
*/
|
||||||
|
static Duration getSyncTimeout() {
|
||||||
|
return SYNC_CALLS_TIMEOUT;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,6 +17,8 @@
|
|||||||
|
|
||||||
package android.bluetooth;
|
package android.bluetooth;
|
||||||
|
|
||||||
|
import static android.bluetooth.BluetoothUtils.getSyncTimeout;
|
||||||
|
|
||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
import android.annotation.IntRange;
|
import android.annotation.IntRange;
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
@@ -29,14 +31,16 @@ import android.annotation.SystemApi;
|
|||||||
import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
|
import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
|
||||||
import android.content.AttributionSource;
|
import android.content.AttributionSource;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Binder;
|
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.util.CloseGuard;
|
import android.util.CloseGuard;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.android.modules.utils.SynchronousResultReceiver;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class provides the public APIs to control the Bluetooth Volume Control service.
|
* This class provides the public APIs to control the Bluetooth Volume Control service.
|
||||||
@@ -86,7 +90,7 @@ public final class BluetoothVolumeControl implements BluetoothProfile, AutoClose
|
|||||||
IBluetoothVolumeControl.class.getName()) {
|
IBluetoothVolumeControl.class.getName()) {
|
||||||
@Override
|
@Override
|
||||||
public IBluetoothVolumeControl getServiceInterface(IBinder service) {
|
public IBluetoothVolumeControl getServiceInterface(IBinder service) {
|
||||||
return IBluetoothVolumeControl.Stub.asInterface(Binder.allowBlocking(service));
|
return IBluetoothVolumeControl.Stub.asInterface(service);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -134,17 +138,23 @@ public final class BluetoothVolumeControl implements BluetoothProfile, AutoClose
|
|||||||
public @NonNull List<BluetoothDevice> getConnectedDevices() {
|
public @NonNull List<BluetoothDevice> getConnectedDevices() {
|
||||||
if (DBG) log("getConnectedDevices()");
|
if (DBG) log("getConnectedDevices()");
|
||||||
final IBluetoothVolumeControl service = getService();
|
final IBluetoothVolumeControl service = getService();
|
||||||
if (service != null && isEnabled()) {
|
final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
try {
|
try {
|
||||||
|
final SynchronousResultReceiver<List<BluetoothDevice>> recv =
|
||||||
|
new SynchronousResultReceiver();
|
||||||
|
service.getConnectedDevices(mAttributionSource, recv);
|
||||||
return Attributable.setAttributionSource(
|
return Attributable.setAttributionSource(
|
||||||
service.getConnectedDevices(mAttributionSource), mAttributionSource);
|
recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
|
||||||
} catch (RemoteException e) {
|
mAttributionSource);
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
} catch (RemoteException | TimeoutException e) {
|
||||||
return new ArrayList<BluetoothDevice>();
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return new ArrayList<BluetoothDevice>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -159,18 +169,23 @@ public final class BluetoothVolumeControl implements BluetoothProfile, AutoClose
|
|||||||
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
|
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
|
||||||
if (DBG) log("getDevicesMatchingStates()");
|
if (DBG) log("getDevicesMatchingStates()");
|
||||||
final IBluetoothVolumeControl service = getService();
|
final IBluetoothVolumeControl service = getService();
|
||||||
if (service != null && isEnabled()) {
|
final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled()) {
|
||||||
try {
|
try {
|
||||||
|
final SynchronousResultReceiver<List<BluetoothDevice>> recv =
|
||||||
|
new SynchronousResultReceiver();
|
||||||
|
service.getDevicesMatchingConnectionStates(states, mAttributionSource, recv);
|
||||||
return Attributable.setAttributionSource(
|
return Attributable.setAttributionSource(
|
||||||
service.getDevicesMatchingConnectionStates(states, mAttributionSource),
|
recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue),
|
||||||
mAttributionSource);
|
mAttributionSource);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException | TimeoutException e) {
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
return new ArrayList<BluetoothDevice>();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return new ArrayList<BluetoothDevice>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -185,16 +200,20 @@ public final class BluetoothVolumeControl implements BluetoothProfile, AutoClose
|
|||||||
public int getConnectionState(BluetoothDevice device) {
|
public int getConnectionState(BluetoothDevice device) {
|
||||||
if (DBG) log("getConnectionState(" + device + ")");
|
if (DBG) log("getConnectionState(" + device + ")");
|
||||||
final IBluetoothVolumeControl service = getService();
|
final IBluetoothVolumeControl service = getService();
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final int defaultValue = BluetoothProfile.STATE_DISCONNECTED;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.getConnectionState(device, mAttributionSource);
|
final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.getConnectionState(device, mAttributionSource, recv);
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
return BluetoothProfile.STATE_DISCONNECTED;
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return BluetoothProfile.STATE_DISCONNECTED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -212,18 +231,19 @@ public final class BluetoothVolumeControl implements BluetoothProfile, AutoClose
|
|||||||
})
|
})
|
||||||
public void setVolume(@Nullable BluetoothDevice device,
|
public void setVolume(@Nullable BluetoothDevice device,
|
||||||
@IntRange(from = 0, to = 255) int volume) {
|
@IntRange(from = 0, to = 255) int volume) {
|
||||||
if (DBG)
|
if (DBG) log("setVolume(" + volume + ")");
|
||||||
log("setVolume(" + volume + ")");
|
|
||||||
final IBluetoothVolumeControl service = getService();
|
final IBluetoothVolumeControl service = getService();
|
||||||
try {
|
if (service == null) {
|
||||||
if (service != null && isEnabled()) {
|
|
||||||
service.setVolume(device, volume, mAttributionSource);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (service == null)
|
|
||||||
Log.w(TAG, "Proxy not attached to service");
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
} catch (RemoteException e) {
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
|
} else if (isEnabled()) {
|
||||||
|
try {
|
||||||
|
final SynchronousResultReceiver recv = new SynchronousResultReceiver();
|
||||||
|
service.setVolume(device, volume, mAttributionSource, recv);
|
||||||
|
recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(null);
|
||||||
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -249,20 +269,22 @@ public final class BluetoothVolumeControl implements BluetoothProfile, AutoClose
|
|||||||
@ConnectionPolicy int connectionPolicy) {
|
@ConnectionPolicy int connectionPolicy) {
|
||||||
if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
|
if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
|
||||||
final IBluetoothVolumeControl service = getService();
|
final IBluetoothVolumeControl service = getService();
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final boolean defaultValue = false;
|
||||||
if (connectionPolicy != BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
|
if (service == null) {
|
||||||
&& connectionPolicy != BluetoothProfile.CONNECTION_POLICY_ALLOWED) {
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
return false;
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
}
|
} else if (isEnabled() && isValidDevice(device)
|
||||||
|
&& (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
|
||||||
|
|| connectionPolicy == BluetoothProfile.CONNECTION_POLICY_ALLOWED)) {
|
||||||
try {
|
try {
|
||||||
return service.setConnectionPolicy(device, connectionPolicy, mAttributionSource);
|
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.setConnectionPolicy(device, connectionPolicy, mAttributionSource, recv);
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
return false;
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -285,16 +307,20 @@ public final class BluetoothVolumeControl implements BluetoothProfile, AutoClose
|
|||||||
public @ConnectionPolicy int getConnectionPolicy(@NonNull BluetoothDevice device) {
|
public @ConnectionPolicy int getConnectionPolicy(@NonNull BluetoothDevice device) {
|
||||||
if (VDBG) log("getConnectionPolicy(" + device + ")");
|
if (VDBG) log("getConnectionPolicy(" + device + ")");
|
||||||
final IBluetoothVolumeControl service = getService();
|
final IBluetoothVolumeControl service = getService();
|
||||||
if (service != null && isEnabled() && isValidDevice(device)) {
|
final int defaultValue = BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
|
||||||
|
if (service == null) {
|
||||||
|
Log.w(TAG, "Proxy not attached to service");
|
||||||
|
if (DBG) log(Log.getStackTraceString(new Throwable()));
|
||||||
|
} else if (isEnabled() && isValidDevice(device)) {
|
||||||
try {
|
try {
|
||||||
return service.getConnectionPolicy(device, mAttributionSource);
|
final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
|
||||||
} catch (RemoteException e) {
|
service.getConnectionPolicy(device, mAttributionSource, recv);
|
||||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||||
return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
|
} catch (RemoteException | TimeoutException e) {
|
||||||
|
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (service == null) Log.w(TAG, "Proxy not attached to service");
|
return defaultValue;
|
||||||
return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isEnabled() {
|
private boolean isEnabled() {
|
||||||
|
|||||||
Reference in New Issue
Block a user