Make BluetoothHeadset APIs used by Telecom into System APIs
Tag: #feature Bug: 195156304 Test: Manual CTS-Coverage-Bug: 211914959 Change-Id: I13d6f553f5b9d6ca7c2ae9a42450875b16cd1490
This commit is contained in:
@@ -9742,13 +9742,14 @@ package android.bluetooth {
|
||||
field public static final int ERROR_BLUETOOTH_NOT_ALLOWED = 2; // 0x2
|
||||
field public static final int ERROR_BLUETOOTH_NOT_ENABLED = 1; // 0x1
|
||||
field public static final int ERROR_DEVICE_NOT_BONDED = 3; // 0x3
|
||||
field public static final int ERROR_FEATURE_NOT_SUPPORTED = 10; // 0xa
|
||||
field public static final int ERROR_GATT_WRITE_NOT_ALLOWED = 101; // 0x65
|
||||
field public static final int ERROR_GATT_WRITE_REQUEST_BUSY = 102; // 0x66
|
||||
field public static final int ERROR_GATT_WRITE_NOT_ALLOWED = 200; // 0xc8
|
||||
field public static final int ERROR_GATT_WRITE_REQUEST_BUSY = 201; // 0xc9
|
||||
field public static final int ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION = 6; // 0x6
|
||||
field public static final int ERROR_MISSING_BLUETOOTH_PRIVILEGED_PERMISSION = 8; // 0x8
|
||||
field public static final int ERROR_PROFILE_SERVICE_NOT_BOUND = 9; // 0x9
|
||||
field public static final int ERROR_UNKNOWN = 2147483647; // 0x7fffffff
|
||||
field public static final int FEATURE_NOT_SUPPORTED = 11; // 0xb
|
||||
field public static final int FEATURE_SUPPORTED = 10; // 0xa
|
||||
field public static final int SUCCESS = 0; // 0x0
|
||||
}
|
||||
|
||||
|
||||
@@ -2218,9 +2218,12 @@ package android.bluetooth {
|
||||
|
||||
public final class BluetoothHeadset implements android.bluetooth.BluetoothProfile {
|
||||
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.MODIFY_PHONE_STATE}) public boolean connect(android.bluetooth.BluetoothDevice);
|
||||
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int connectAudio();
|
||||
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean disconnect(android.bluetooth.BluetoothDevice);
|
||||
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int disconnectAudio();
|
||||
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getAudioState(@NonNull android.bluetooth.BluetoothDevice);
|
||||
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice);
|
||||
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean isInbandRingingEnabled();
|
||||
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean isInbandRingingEnabled();
|
||||
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED, android.Manifest.permission.MODIFY_PHONE_STATE}) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int);
|
||||
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.MODIFY_PHONE_STATE}) public boolean startScoUsingVirtualVoiceCall();
|
||||
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.MODIFY_PHONE_STATE}) public boolean stopScoUsingVirtualVoiceCall();
|
||||
@@ -2299,6 +2302,14 @@ package android.bluetooth {
|
||||
|
||||
public final class BluetoothStatusCodes {
|
||||
field public static final int ERROR_ANOTHER_ACTIVE_OOB_REQUEST = 1000; // 0x3e8
|
||||
field public static final int ERROR_AUDIO_DEVICE_ALREADY_CONNECTED = 1116; // 0x45c
|
||||
field public static final int ERROR_AUDIO_DEVICE_ALREADY_DISCONNECTED = 1117; // 0x45d
|
||||
field public static final int ERROR_AUDIO_ROUTE_BLOCKED = 1118; // 0x45e
|
||||
field public static final int ERROR_CALL_ACTIVE = 1119; // 0x45f
|
||||
field public static final int ERROR_NOT_ACTIVE_DEVICE = 12; // 0xc
|
||||
field public static final int ERROR_NO_ACTIVE_DEVICES = 13; // 0xd
|
||||
field public static final int ERROR_PROFILE_NOT_CONNECTED = 14; // 0xe
|
||||
field public static final int ERROR_TIMEOUT = 15; // 0xf
|
||||
}
|
||||
|
||||
public final class BluetoothUuid {
|
||||
|
||||
@@ -2249,17 +2249,17 @@ public final class BluetoothAdapter {
|
||||
/** @hide */
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef(value = {
|
||||
BluetoothStatusCodes.SUCCESS,
|
||||
BluetoothStatusCodes.FEATURE_SUPPORTED,
|
||||
BluetoothStatusCodes.ERROR_UNKNOWN,
|
||||
BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED,
|
||||
BluetoothStatusCodes.ERROR_FEATURE_NOT_SUPPORTED,
|
||||
BluetoothStatusCodes.FEATURE_NOT_SUPPORTED,
|
||||
})
|
||||
public @interface LeFeatureReturnValues {}
|
||||
|
||||
/**
|
||||
* Returns {@link BluetoothStatusCodes#SUCCESS} if the LE audio feature is
|
||||
* supported, returns {@link BluetoothStatusCodes#ERROR_FEATURE_NOT_SUPPORTED} if
|
||||
* the feature is not supported or an error code.
|
||||
* Returns {@link BluetoothStatusCodes#FEATURE_SUPPORTED} if the LE audio feature is
|
||||
* supported, {@link BluetoothStatusCodes#FEATURE_NOT_SUPPORTED} if the feature is not
|
||||
* supported, or an error code.
|
||||
*
|
||||
* @return whether the LE audio is supported
|
||||
*/
|
||||
@@ -2282,9 +2282,10 @@ public final class BluetoothAdapter {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@link BluetoothStatusCodes#SUCCESS} if LE Periodic Advertising Sync Transfer Sender
|
||||
* feature is supported, returns {@link BluetoothStatusCodes#ERROR_FEATURE_NOT_SUPPORTED} if the
|
||||
* feature is not supported or an error code
|
||||
* Returns {@link BluetoothStatusCodes#FEATURE_SUPPORTED} if LE Periodic Advertising Sync
|
||||
* Transfer Sender feature is supported,
|
||||
* {@link BluetoothStatusCodes#FEATURE_NOT_SUPPORTED} if the feature is not supported, or
|
||||
* an error code
|
||||
*
|
||||
* @return whether the chipset supports the LE Periodic Advertising Sync Transfer Sender feature
|
||||
*/
|
||||
|
||||
@@ -18,6 +18,7 @@ package android.bluetooth;
|
||||
|
||||
import static android.bluetooth.BluetoothUtils.getSyncTimeout;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.RequiresPermission;
|
||||
@@ -44,6 +45,8 @@ import android.util.Log;
|
||||
|
||||
import com.android.modules.utils.SynchronousResultReceiver;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
@@ -895,17 +898,36 @@ public final class BluetoothHeadset implements BluetoothProfile {
|
||||
com.android.internal.R.bool.config_bluetooth_sco_off_call);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef(value = {
|
||||
BluetoothHeadset.STATE_AUDIO_DISCONNECTED,
|
||||
BluetoothHeadset.STATE_AUDIO_CONNECTING,
|
||||
BluetoothHeadset.STATE_AUDIO_CONNECTED,
|
||||
BluetoothStatusCodes.ERROR_TIMEOUT
|
||||
})
|
||||
public @interface GetAudioStateReturnValues {}
|
||||
|
||||
/**
|
||||
* Get the current audio state of the Headset.
|
||||
* Note: This is an internal function and shouldn't be exposed
|
||||
*
|
||||
* @param device is the Bluetooth device for which the audio state is being queried
|
||||
* @return the audio state of the device or an error code
|
||||
* @throws IllegalArgumentException if the device is null
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
|
||||
@SystemApi
|
||||
@RequiresBluetoothConnectPermission
|
||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||
public int getAudioState(BluetoothDevice device) {
|
||||
@RequiresPermission(allOf = {
|
||||
android.Manifest.permission.BLUETOOTH_CONNECT,
|
||||
android.Manifest.permission.BLUETOOTH_PRIVILEGED,
|
||||
})
|
||||
public @GetAudioStateReturnValues int getAudioState(@NonNull BluetoothDevice device) {
|
||||
if (VDBG) log("getAudioState");
|
||||
if (device == null) {
|
||||
throw new IllegalArgumentException("device cannot be null");
|
||||
}
|
||||
final IBluetoothHeadset service = mService;
|
||||
final int defaultValue = BluetoothHeadset.STATE_AUDIO_DISCONNECTED;
|
||||
if (service == null) {
|
||||
@@ -916,8 +938,12 @@ public final class BluetoothHeadset implements BluetoothProfile {
|
||||
final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
|
||||
service.getAudioState(device, mAttributionSource, recv);
|
||||
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||
} catch (RemoteException | TimeoutException e) {
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||
throw e.rethrowFromSystemServer();
|
||||
} catch (TimeoutException e) {
|
||||
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||
return BluetoothStatusCodes.ERROR_TIMEOUT;
|
||||
}
|
||||
}
|
||||
return defaultValue;
|
||||
@@ -1005,103 +1031,112 @@ public final class BluetoothHeadset implements BluetoothProfile {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if at least one headset's SCO audio is connected or connecting
|
||||
*
|
||||
* @return true if at least one device's SCO audio is connected or connecting, false otherwise
|
||||
* or on error
|
||||
* @hide
|
||||
*/
|
||||
@RequiresLegacyBluetoothPermission
|
||||
@RequiresBluetoothConnectPermission
|
||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||
public boolean isAudioOn() {
|
||||
if (VDBG) log("isAudioOn()");
|
||||
final IBluetoothHeadset service = mService;
|
||||
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 {
|
||||
final SynchronousResultReceiver<Boolean> recv = new SynchronousResultReceiver();
|
||||
service.isAudioOn(mAttributionSource, recv);
|
||||
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||
} catch (RemoteException | TimeoutException e) {
|
||||
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||
}
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
/** @hide */
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef(value = {
|
||||
BluetoothStatusCodes.SUCCESS,
|
||||
BluetoothStatusCodes.ERROR_UNKNOWN,
|
||||
BluetoothStatusCodes.ERROR_PROFILE_SERVICE_NOT_BOUND,
|
||||
BluetoothStatusCodes.ERROR_TIMEOUT,
|
||||
BluetoothStatusCodes.ERROR_AUDIO_DEVICE_ALREADY_CONNECTED,
|
||||
BluetoothStatusCodes.ERROR_NO_ACTIVE_DEVICES,
|
||||
BluetoothStatusCodes.ERROR_NOT_ACTIVE_DEVICE,
|
||||
BluetoothStatusCodes.ERROR_AUDIO_ROUTE_BLOCKED,
|
||||
BluetoothStatusCodes.ERROR_CALL_ACTIVE,
|
||||
BluetoothStatusCodes.ERROR_PROFILE_NOT_CONNECTED
|
||||
})
|
||||
public @interface ConnectAudioReturnValues {}
|
||||
|
||||
/**
|
||||
* Initiates a connection of headset audio to the current active device
|
||||
* Initiates a connection of SCO audio to the current active HFP device. The active HFP device
|
||||
* can be identified with {@link BluetoothAdapter#getActiveDevices(int)}.
|
||||
* <p>
|
||||
* If this function returns {@link BluetoothStatusCodes#SUCCESS}, the intent
|
||||
* {@link #ACTION_AUDIO_STATE_CHANGED} will be broadcasted twice. First with {@link #EXTRA_STATE}
|
||||
* set to {@link #STATE_AUDIO_CONNECTING}. This will be followed by a broadcast with
|
||||
* {@link #EXTRA_STATE} set to either {@link #STATE_AUDIO_CONNECTED} if the audio connection is
|
||||
* established or {@link #STATE_AUDIO_DISCONNECTED} if there was a failure in establishing the
|
||||
* audio connection.
|
||||
*
|
||||
* <p> Users can listen to {@link #ACTION_AUDIO_STATE_CHANGED}.
|
||||
* If this function returns true, this intent will be broadcasted with
|
||||
* {@link #EXTRA_STATE} set to {@link #STATE_AUDIO_CONNECTING}.
|
||||
*
|
||||
* <p> {@link #EXTRA_STATE} will transition from
|
||||
* {@link #STATE_AUDIO_CONNECTING} to {@link #STATE_AUDIO_CONNECTED} when
|
||||
* audio connection is established and to {@link #STATE_AUDIO_DISCONNECTED}
|
||||
* in case of failure to establish the audio connection.
|
||||
*
|
||||
* Note that this intent will not be sent if {@link BluetoothHeadset#isAudioOn()} is true
|
||||
* before calling this method
|
||||
*
|
||||
* @return false if there was some error such as there is no active headset
|
||||
* @return whether the connection was successfully initiated or an error code on failure
|
||||
* @hide
|
||||
*/
|
||||
@UnsupportedAppUsage
|
||||
@SystemApi
|
||||
@RequiresBluetoothConnectPermission
|
||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||
public boolean connectAudio() {
|
||||
@RequiresPermission(allOf = {
|
||||
android.Manifest.permission.BLUETOOTH_CONNECT,
|
||||
android.Manifest.permission.BLUETOOTH_PRIVILEGED,
|
||||
})
|
||||
public @ConnectAudioReturnValues int connectAudio() {
|
||||
if (VDBG) log("connectAudio()");
|
||||
final IBluetoothHeadset service = mService;
|
||||
final boolean defaultValue = false;
|
||||
final int defaultValue = BluetoothStatusCodes.ERROR_UNKNOWN;
|
||||
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();
|
||||
final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
|
||||
service.connectAudio(mAttributionSource, recv);
|
||||
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||
} catch (RemoteException | TimeoutException e) {
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||
throw e.rethrowFromSystemServer();
|
||||
} catch (TimeoutException e) {
|
||||
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||
return BluetoothStatusCodes.ERROR_TIMEOUT;
|
||||
}
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef(value = {
|
||||
BluetoothStatusCodes.SUCCESS,
|
||||
BluetoothStatusCodes.ERROR_UNKNOWN,
|
||||
BluetoothStatusCodes.ERROR_PROFILE_SERVICE_NOT_BOUND,
|
||||
BluetoothStatusCodes.ERROR_TIMEOUT,
|
||||
BluetoothStatusCodes.ERROR_PROFILE_NOT_CONNECTED,
|
||||
BluetoothStatusCodes.ERROR_AUDIO_DEVICE_ALREADY_DISCONNECTED
|
||||
})
|
||||
public @interface DisconnectAudioReturnValues {}
|
||||
|
||||
/**
|
||||
* Initiates a disconnection of HFP SCO audio.
|
||||
* Tear down voice recognition or virtual voice call if any.
|
||||
* Initiates a disconnection of HFP SCO audio from actively connected devices. It also tears
|
||||
* down voice recognition or virtual voice call, if any exists.
|
||||
*
|
||||
* <p> Users can listen to {@link #ACTION_AUDIO_STATE_CHANGED}.
|
||||
* If this function returns true, this intent will be broadcasted with
|
||||
* {@link #EXTRA_STATE} set to {@link #STATE_AUDIO_DISCONNECTED}.
|
||||
* <p> If this function returns {@link BluetoothStatusCodes#SUCCESS}, the intent
|
||||
* {@link #ACTION_AUDIO_STATE_CHANGED} will be broadcasted with {@link #EXTRA_STATE} set to
|
||||
* {@link #STATE_AUDIO_DISCONNECTED}.
|
||||
*
|
||||
* @return false if audio is not connected, or on error, true otherwise
|
||||
* @return whether the disconnection was initiated successfully or an error code on failure
|
||||
* @hide
|
||||
*/
|
||||
@UnsupportedAppUsage
|
||||
@SystemApi
|
||||
@RequiresBluetoothConnectPermission
|
||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||
public boolean disconnectAudio() {
|
||||
@RequiresPermission(allOf = {
|
||||
android.Manifest.permission.BLUETOOTH_CONNECT,
|
||||
android.Manifest.permission.BLUETOOTH_PRIVILEGED,
|
||||
})
|
||||
public @DisconnectAudioReturnValues int disconnectAudio() {
|
||||
if (VDBG) log("disconnectAudio()");
|
||||
final IBluetoothHeadset service = mService;
|
||||
final boolean defaultValue = false;
|
||||
final int defaultValue = BluetoothStatusCodes.ERROR_UNKNOWN;
|
||||
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();
|
||||
final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
|
||||
service.disconnectAudio(mAttributionSource, recv);
|
||||
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
|
||||
} catch (RemoteException | TimeoutException e) {
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||
throw e.rethrowFromSystemServer();
|
||||
} catch (TimeoutException e) {
|
||||
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
|
||||
return BluetoothStatusCodes.ERROR_TIMEOUT;
|
||||
}
|
||||
}
|
||||
return defaultValue;
|
||||
@@ -1386,7 +1421,10 @@ public final class BluetoothHeadset implements BluetoothProfile {
|
||||
@SystemApi
|
||||
@RequiresLegacyBluetoothPermission
|
||||
@RequiresBluetoothConnectPermission
|
||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
|
||||
@RequiresPermission(allOf = {
|
||||
android.Manifest.permission.BLUETOOTH_CONNECT,
|
||||
android.Manifest.permission.BLUETOOTH_PRIVILEGED,
|
||||
})
|
||||
public boolean isInbandRingingEnabled() {
|
||||
if (DBG) log("isInbandRingingEnabled()");
|
||||
final IBluetoothHeadset service = mService;
|
||||
|
||||
@@ -20,7 +20,7 @@ import android.annotation.SystemApi;
|
||||
|
||||
/**
|
||||
* A class with constants representing possible return values for Bluetooth APIs. General return
|
||||
* values occupy the range 0 to 99. Profile-specific return values occupy the range 100-999.
|
||||
* values occupy the range 0 to 199. Profile-specific return values occupy the range 200-999.
|
||||
* API-specific return values start at 1000. The exception to this is the "UNKNOWN" error code which
|
||||
* occupies the max integer value.
|
||||
*/
|
||||
@@ -29,28 +29,28 @@ public final class BluetoothStatusCodes {
|
||||
private BluetoothStatusCodes() {}
|
||||
|
||||
/**
|
||||
* Indicates that the API call was successful
|
||||
* Indicates that the API call was successful.
|
||||
*/
|
||||
public static final int SUCCESS = 0;
|
||||
|
||||
/**
|
||||
* Error code indicating that Bluetooth is not enabled
|
||||
* Error code indicating that Bluetooth is not enabled.
|
||||
*/
|
||||
public static final int ERROR_BLUETOOTH_NOT_ENABLED = 1;
|
||||
|
||||
/**
|
||||
* Error code indicating that the API call was initiated by neither the system nor the active
|
||||
* user
|
||||
* user.
|
||||
*/
|
||||
public static final int ERROR_BLUETOOTH_NOT_ALLOWED = 2;
|
||||
|
||||
/**
|
||||
* Error code indicating that the Bluetooth Device specified is not bonded
|
||||
* Error code indicating that the Bluetooth Device specified is not bonded.
|
||||
*/
|
||||
public static final int ERROR_DEVICE_NOT_BONDED = 3;
|
||||
|
||||
/**
|
||||
* Error code indicating that the Bluetooth Device specified is not connected, but is bonded
|
||||
* Error code indicating that the Bluetooth Device specified is not connected, but is bonded.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@@ -58,7 +58,7 @@ public final class BluetoothStatusCodes {
|
||||
|
||||
/**
|
||||
* Error code indicating that the caller does not have the
|
||||
* {@link android.Manifest.permission#BLUETOOTH_ADVERTISE} permission
|
||||
* {@link android.Manifest.permission#BLUETOOTH_ADVERTISE} permission.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@@ -66,13 +66,13 @@ public final class BluetoothStatusCodes {
|
||||
|
||||
/**
|
||||
* Error code indicating that the caller does not have the
|
||||
* {@link android.Manifest.permission#BLUETOOTH_CONNECT} permission
|
||||
* {@link android.Manifest.permission#BLUETOOTH_CONNECT} permission.
|
||||
*/
|
||||
public static final int ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION = 6;
|
||||
|
||||
/**
|
||||
* Error code indicating that the caller does not have the
|
||||
* {@link android.Manifest.permission#BLUETOOTH_SCAN} permission
|
||||
* {@link android.Manifest.permission#BLUETOOTH_SCAN} permission.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@@ -80,30 +80,67 @@ public final class BluetoothStatusCodes {
|
||||
|
||||
/**
|
||||
* Error code indicating that the caller does not have the
|
||||
* {@link android.Manifest.permission#BLUETOOTH_PRIVILEGED} permission
|
||||
* {@link android.Manifest.permission#BLUETOOTH_PRIVILEGED} permission.
|
||||
*/
|
||||
public static final int ERROR_MISSING_BLUETOOTH_PRIVILEGED_PERMISSION = 8;
|
||||
|
||||
/**
|
||||
* Error code indicating that the profile service is not bound. You can bind a profile service
|
||||
* by calling {@link BluetoothAdapter#getProfileProxy}
|
||||
* by calling {@link BluetoothAdapter#getProfileProxy}.
|
||||
*/
|
||||
public static final int ERROR_PROFILE_SERVICE_NOT_BOUND = 9;
|
||||
|
||||
/**
|
||||
* Error code indicating that the feature is not supported.
|
||||
* Indicates that the feature is supported.
|
||||
*/
|
||||
public static final int ERROR_FEATURE_NOT_SUPPORTED = 10;
|
||||
public static final int FEATURE_SUPPORTED = 10;
|
||||
|
||||
/**
|
||||
* Indicates that the feature is not supported.
|
||||
*/
|
||||
public static final int FEATURE_NOT_SUPPORTED = 11;
|
||||
|
||||
/**
|
||||
* Error code indicating that the device is not the active device for this profile.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public static final int ERROR_NOT_ACTIVE_DEVICE = 12;
|
||||
|
||||
/**
|
||||
* Error code indicating that there are no active devices for the profile.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public static final int ERROR_NO_ACTIVE_DEVICES = 13;
|
||||
|
||||
/**
|
||||
* Indicates that the Bluetooth profile is not connected to this device.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public static final int ERROR_PROFILE_NOT_CONNECTED = 14;
|
||||
|
||||
/**
|
||||
* Error code indicating that the requested operation timed out.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public static final int ERROR_TIMEOUT = 15;
|
||||
|
||||
/**
|
||||
* A GATT writeCharacteristic request is not permitted on the remote device.
|
||||
*/
|
||||
public static final int ERROR_GATT_WRITE_NOT_ALLOWED = 101;
|
||||
public static final int ERROR_GATT_WRITE_NOT_ALLOWED = 200;
|
||||
|
||||
/**
|
||||
* A GATT writeCharacteristic request is issued to a busy remote device.
|
||||
*/
|
||||
public static final int ERROR_GATT_WRITE_REQUEST_BUSY = 102;
|
||||
public static final int ERROR_GATT_WRITE_REQUEST_BUSY = 201;
|
||||
|
||||
/**
|
||||
* If another application has already requested {@link OobData} then another fetch will be
|
||||
@@ -285,6 +322,38 @@ public final class BluetoothStatusCodes {
|
||||
*/
|
||||
public static final int ERROR_LE_AUDIO_BROADCAST_SOURCE_DISABLE_ENCRYPTION_FAILED = 1115;
|
||||
|
||||
/**
|
||||
* Indicates that there is already one device for which SCO audio is connected or connecting.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public static final int ERROR_AUDIO_DEVICE_ALREADY_CONNECTED = 1116;
|
||||
|
||||
/**
|
||||
* Indicates that SCO audio was already not connected for this device.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public static final int ERROR_AUDIO_DEVICE_ALREADY_DISCONNECTED = 1117;
|
||||
|
||||
/**
|
||||
* Indicates that there audio route is currently blocked by the system.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public static final int ERROR_AUDIO_ROUTE_BLOCKED = 1118;
|
||||
|
||||
/**
|
||||
* Indicates that there is an active call preventing this operation from succeeding.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public static final int ERROR_CALL_ACTIVE = 1119;
|
||||
|
||||
/**
|
||||
* Indicates that an unknown error has occurred has occurred.
|
||||
*/
|
||||
|
||||
@@ -275,6 +275,7 @@ applications that come with the platform
|
||||
<privapp-permissions package="com.android.server.telecom">
|
||||
<permission name="android.permission.BIND_CONNECTION_SERVICE"/>
|
||||
<permission name="android.permission.BIND_INCALL_SERVICE"/>
|
||||
<permission name="android.permission.BLUETOOTH_PRIVILEGED"/>
|
||||
<permission name="android.permission.CALL_PRIVILEGED"/>
|
||||
<permission name="android.permission.HANDLE_CAR_MODE_CHANGES"/>
|
||||
<permission name="android.permission.INTERACT_ACROSS_USERS"/>
|
||||
|
||||
@@ -138,13 +138,6 @@ public class HeadsetProfile implements LocalBluetoothProfile {
|
||||
return mService.getActiveDevice();
|
||||
}
|
||||
|
||||
public boolean isAudioOn() {
|
||||
if (mService == null) {
|
||||
return false;
|
||||
}
|
||||
return mService.isAudioOn();
|
||||
}
|
||||
|
||||
public int getAudioState(BluetoothDevice device) {
|
||||
if (mService == null) {
|
||||
return BluetoothHeadset.STATE_AUDIO_DISCONNECTED;
|
||||
|
||||
@@ -54,15 +54,6 @@ public class HeadsetProfileTest {
|
||||
mServiceListener.onServiceConnected(BluetoothProfile.HEADSET, mService);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bluetoothProfile_shouldReturnTheAudioStatusFromBlueToothHeadsetService() {
|
||||
when(mService.isAudioOn()).thenReturn(true);
|
||||
assertThat(mProfile.isAudioOn()).isTrue();
|
||||
|
||||
when(mService.isAudioOn()).thenReturn(false);
|
||||
assertThat(mProfile.isAudioOn()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHeadsetProfile_shouldReturnAudioState() {
|
||||
when(mService.getAudioState(mBluetoothDevice)).
|
||||
|
||||
@@ -102,8 +102,6 @@ public class BtHelper {
|
||||
/*package*/ static final int SCO_MODE_UNDEFINED = -1;
|
||||
// SCO audio mode is virtual voice call (BluetoothHeadset.startScoUsingVirtualVoiceCall())
|
||||
/*package*/ static final int SCO_MODE_VIRTUAL_CALL = 0;
|
||||
// SCO audio mode is raw audio (BluetoothHeadset.connectAudio())
|
||||
private static final int SCO_MODE_RAW = 1;
|
||||
// SCO audio mode is Voice Recognition (BluetoothHeadset.startVoiceRecognition())
|
||||
private static final int SCO_MODE_VR = 2;
|
||||
// max valid SCO audio mode values
|
||||
@@ -122,8 +120,6 @@ public class BtHelper {
|
||||
return "SCO_MODE_UNDEFINED";
|
||||
case SCO_MODE_VIRTUAL_CALL:
|
||||
return "SCO_MODE_VIRTUAL_CALL";
|
||||
case SCO_MODE_RAW:
|
||||
return "SCO_MODE_RAW";
|
||||
case SCO_MODE_VR:
|
||||
return "SCO_MODE_VR";
|
||||
default:
|
||||
@@ -812,8 +808,6 @@ public class BtHelper {
|
||||
private static boolean disconnectBluetoothScoAudioHelper(BluetoothHeadset bluetoothHeadset,
|
||||
BluetoothDevice device, int scoAudioMode) {
|
||||
switch (scoAudioMode) {
|
||||
case SCO_MODE_RAW:
|
||||
return bluetoothHeadset.disconnectAudio();
|
||||
case SCO_MODE_VIRTUAL_CALL:
|
||||
return bluetoothHeadset.stopScoUsingVirtualVoiceCall();
|
||||
case SCO_MODE_VR:
|
||||
@@ -826,8 +820,6 @@ public class BtHelper {
|
||||
private static boolean connectBluetoothScoAudioHelper(BluetoothHeadset bluetoothHeadset,
|
||||
BluetoothDevice device, int scoAudioMode) {
|
||||
switch (scoAudioMode) {
|
||||
case SCO_MODE_RAW:
|
||||
return bluetoothHeadset.connectAudio();
|
||||
case SCO_MODE_VIRTUAL_CALL:
|
||||
return bluetoothHeadset.startScoUsingVirtualVoiceCall();
|
||||
case SCO_MODE_VR:
|
||||
|
||||
Reference in New Issue
Block a user