HFP: Add APIs for set and get active device (1/3)
1. Call BluetoothHeadset.setActiveDevice(BluetoothDevice device) to set a connected HFP/HSP device as active. 2. Listen for BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED intent that will contain the latest active device (in EXTRA_DEVICE field). If the active device could not be changed, the EXTRA_DEVICE field could be null. 3. If setActiveDevice() is NOT in-progress, BluetoothA2dp.getActiveDevice() can be used. If setActiveDevice() is in-progress, the result is undefined. 4. BluetoothHeadset.setActiveDevice() could be called by some other parts of the system, so interested parties should always listen for BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED intents and prepared for active device updates. Bug: 68951996 Test: manual Change-Id: I22ca639a04fed7bf17df59c405ddeda90dafb8ff
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
|
||||
package android.bluetooth;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.RequiresPermission;
|
||||
import android.annotation.SdkConstant;
|
||||
import android.annotation.SdkConstant.SdkConstantType;
|
||||
@@ -93,6 +94,23 @@ public final class BluetoothHeadset implements BluetoothProfile {
|
||||
public static final String ACTION_AUDIO_STATE_CHANGED =
|
||||
"android.bluetooth.headset.profile.action.AUDIO_STATE_CHANGED";
|
||||
|
||||
/**
|
||||
* Intent used to broadcast the selection of a connected device as active.
|
||||
*
|
||||
* <p>This intent will have one extra:
|
||||
* <ul>
|
||||
* <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. It can
|
||||
* be null if no device is active. </li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to
|
||||
* receive.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
|
||||
public static final String ACTION_ACTIVE_DEVICE_CHANGED =
|
||||
"android.bluetooth.headset.profile.action.ACTIVE_DEVICE_CHANGED";
|
||||
|
||||
/**
|
||||
* Intent used to broadcast that the headset has posted a
|
||||
@@ -982,6 +1000,76 @@ public final class BluetoothHeadset implements BluetoothProfile {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Select a connected device as active.
|
||||
*
|
||||
* The active device selection is per profile. An active device's
|
||||
* purpose is profile-specific. For example, in HFP and HSP profiles,
|
||||
* it is the device used for phone call audio. If a remote device is not
|
||||
* connected, it cannot be selected as active.
|
||||
*
|
||||
* <p> This API returns false in scenarios like the profile on the
|
||||
* device is not connected or Bluetooth is not turned on.
|
||||
* When this API returns true, it is guaranteed that the
|
||||
* {@link #ACTION_ACTIVE_DEVICE_CHANGED} intent will be broadcasted
|
||||
* with the active device.
|
||||
*
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
|
||||
* permission.
|
||||
*
|
||||
* @param device Remote Bluetooth Device, could be null if phone call audio should not be
|
||||
* streamed to a headset
|
||||
* @return false on immediate error, true otherwise
|
||||
* @hide
|
||||
*/
|
||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN)
|
||||
public boolean setActiveDevice(@Nullable BluetoothDevice device) {
|
||||
if (DBG) {
|
||||
Log.d(TAG, "setActiveDevice: " + device);
|
||||
}
|
||||
final IBluetoothHeadset service = mService;
|
||||
if (service != null && isEnabled() && (device == null || isValidDevice(device))) {
|
||||
try {
|
||||
return service.setActiveDevice(device);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
||||
}
|
||||
}
|
||||
if (service == null) {
|
||||
Log.w(TAG, "Proxy not attached to service");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the connected device that is active.
|
||||
*
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH}
|
||||
* permission.
|
||||
*
|
||||
* @return the connected device that is active or null if no device
|
||||
* is active.
|
||||
* @hide
|
||||
*/
|
||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH)
|
||||
public BluetoothDevice getActiveDevice() {
|
||||
if (VDBG) {
|
||||
Log.d(TAG, "getActiveDevice");
|
||||
}
|
||||
final IBluetoothHeadset service = mService;
|
||||
if (service != null && isEnabled()) {
|
||||
try {
|
||||
return service.getActiveDevice();
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, Log.getStackTraceString(new Throwable()));
|
||||
}
|
||||
}
|
||||
if (service == null) {
|
||||
Log.w(TAG, "Proxy not attached to service");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* check if in-band ringing is supported for this platform.
|
||||
*
|
||||
|
||||
@@ -158,6 +158,8 @@
|
||||
android:name="android.bluetooth.headset.action.VENDOR_SPECIFIC_HEADSET_EVENT" />
|
||||
<protected-broadcast
|
||||
android:name="android.bluetooth.headset.action.HF_INDICATORS_VALUE_CHANGED" />
|
||||
<protected-broadcast
|
||||
android:name="android.bluetooth.headset.profile.action.ACTIVE_DEVICE_CHANGED" />
|
||||
<protected-broadcast
|
||||
android:name="android.bluetooth.headsetclient.profile.action.CONNECTION_STATE_CHANGED" />
|
||||
<protected-broadcast
|
||||
|
||||
Reference in New Issue
Block a user