AudioManager: test API for device connection
Add a test API to simulate the connection/disconnection of an audio device. The simulation of the connection goes as far as AudioService, but doesn't go into the lower layers of the native audio policy or the HAL. Bug: 200218901 Test: atest com.google.android.gts.audioservice.AudioServiceHostTest#testMuteAwaitConnection Change-Id: I36ae9e07b4c7408a0deb471e9b89263c4db21591
This commit is contained in:
@@ -1458,6 +1458,7 @@ package android.media {
|
||||
method @RequiresPermission(android.Manifest.permission.CALL_AUDIO_INTERCEPTION) public boolean isPstnCallAudioInterceptable();
|
||||
method @RequiresPermission("android.permission.QUERY_AUDIO_STATE") public int requestAudioFocusForTest(@NonNull android.media.AudioFocusRequest, @NonNull String, int, int);
|
||||
method public void setRampingRingerEnabled(boolean);
|
||||
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setTestDeviceConnectionState(@NonNull android.media.AudioDeviceAttributes, boolean);
|
||||
}
|
||||
|
||||
public static final class AudioRecord.MetricsConstants {
|
||||
|
||||
@@ -5775,6 +5775,23 @@ public class AudioManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate wired accessory connection state change.
|
||||
* @param device {@link AudioDeviceAttributes} of the device to "fake-connect"
|
||||
* @param connected true for connected, false for disconnected
|
||||
* {@hide}
|
||||
*/
|
||||
@TestApi
|
||||
@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
|
||||
public void setTestDeviceConnectionState(@NonNull AudioDeviceAttributes device,
|
||||
boolean connected) {
|
||||
try {
|
||||
getService().setTestDeviceConnectionState(device, connected);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate Bluetooth profile connection state change.
|
||||
* Configuration changes for A2DP are indicated by having the same <code>newDevice</code> and
|
||||
|
||||
@@ -458,4 +458,6 @@ interface IAudioService {
|
||||
|
||||
void registerMuteAwaitConnectionDispatcher(in IMuteAwaitConnectionCallback cb,
|
||||
boolean register);
|
||||
|
||||
void setTestDeviceConnectionState(in AudioDeviceAttributes device, boolean connected);
|
||||
}
|
||||
|
||||
@@ -508,6 +508,13 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
}
|
||||
}
|
||||
|
||||
/*package*/ void setTestDeviceConnectionState(@NonNull AudioDeviceAttributes device,
|
||||
@AudioService.ConnectionState int state) {
|
||||
synchronized (mDeviceStateLock) {
|
||||
mDeviceInventory.setTestDeviceConnectionState(device, state);
|
||||
}
|
||||
}
|
||||
|
||||
/*package*/ static final class BleVolumeInfo {
|
||||
final int mIndex;
|
||||
final int mMaxIndex;
|
||||
@@ -1008,7 +1015,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
/*package*/ boolean handleDeviceConnection(boolean connect, int device, String address,
|
||||
String deviceName) {
|
||||
synchronized (mDeviceStateLock) {
|
||||
return mDeviceInventory.handleDeviceConnection(connect, device, address, deviceName);
|
||||
return mDeviceInventory.handleDeviceConnection(connect, device, address, deviceName,
|
||||
false /*for test*/);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -224,6 +224,7 @@ public class AudioDeviceInventory {
|
||||
public final String mAddress;
|
||||
public final String mName;
|
||||
public final String mCaller;
|
||||
public boolean mForTest = false;
|
||||
|
||||
/*package*/ WiredDeviceConnectionState(int type, @AudioService.ConnectionState int state,
|
||||
String address, String name, String caller) {
|
||||
@@ -521,7 +522,7 @@ public class AudioDeviceInventory {
|
||||
}
|
||||
|
||||
if (!handleDeviceConnection(wdcs.mState == AudioService.CONNECTION_STATE_CONNECTED,
|
||||
wdcs.mType, wdcs.mAddress, wdcs.mName)) {
|
||||
wdcs.mType, wdcs.mAddress, wdcs.mName, wdcs.mForTest)) {
|
||||
// change of connection state failed, bailout
|
||||
mmi.set(MediaMetrics.Property.EARLY_RETURN, "change of connection state failed")
|
||||
.record();
|
||||
@@ -681,7 +682,7 @@ public class AudioDeviceInventory {
|
||||
* @param device the device whose connection state is queried
|
||||
* @return true if connected
|
||||
*/
|
||||
@GuardedBy("AudioDeviceBroker.mDeviceStateLock")
|
||||
// called with AudioDeviceBroker.mDeviceStateLock lock held
|
||||
public boolean isDeviceConnected(@NonNull AudioDeviceAttributes device) {
|
||||
final String key = DeviceInfo.makeDeviceListKey(device.getInternalType(),
|
||||
device.getAddress());
|
||||
@@ -696,10 +697,12 @@ public class AudioDeviceInventory {
|
||||
* @param device the device type
|
||||
* @param address the address of the device
|
||||
* @param deviceName human-readable name of device
|
||||
* @param isForTesting if true, not calling AudioSystem for the connection as this is
|
||||
* just for testing
|
||||
* @return false if an error was reported by AudioSystem
|
||||
*/
|
||||
/*package*/ boolean handleDeviceConnection(boolean connect, int device, String address,
|
||||
String deviceName) {
|
||||
String deviceName, boolean isForTesting) {
|
||||
if (AudioService.DEBUG_DEVICES) {
|
||||
Slog.i(TAG, "handleDeviceConnection(" + connect + " dev:"
|
||||
+ Integer.toHexString(device) + " address:" + address
|
||||
@@ -722,9 +725,14 @@ public class AudioDeviceInventory {
|
||||
Slog.i(TAG, "deviceInfo:" + di + " is(already)Connected:" + isConnected);
|
||||
}
|
||||
if (connect && !isConnected) {
|
||||
final int res = mAudioSystem.setDeviceConnectionState(device,
|
||||
AudioSystem.DEVICE_STATE_AVAILABLE, address, deviceName,
|
||||
AudioSystem.AUDIO_FORMAT_DEFAULT);
|
||||
final int res;
|
||||
if (isForTesting) {
|
||||
res = AudioSystem.AUDIO_STATUS_OK;
|
||||
} else {
|
||||
res = mAudioSystem.setDeviceConnectionState(device,
|
||||
AudioSystem.DEVICE_STATE_AVAILABLE, address, deviceName,
|
||||
AudioSystem.AUDIO_FORMAT_DEFAULT);
|
||||
}
|
||||
if (res != AudioSystem.AUDIO_STATUS_OK) {
|
||||
final String reason = "not connecting device 0x" + Integer.toHexString(device)
|
||||
+ " due to command error " + res;
|
||||
@@ -930,6 +938,15 @@ public class AudioDeviceInventory {
|
||||
}
|
||||
}
|
||||
|
||||
/*package*/ void setTestDeviceConnectionState(@NonNull AudioDeviceAttributes device,
|
||||
@AudioService.ConnectionState int state) {
|
||||
final WiredDeviceConnectionState connection = new WiredDeviceConnectionState(
|
||||
device.getInternalType(), state, device.getAddress(),
|
||||
"test device", "com.android.server.audio");
|
||||
connection.mForTest = true;
|
||||
onSetWiredDeviceConnectionState(connection);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Internal utilities
|
||||
|
||||
|
||||
@@ -6364,6 +6364,20 @@ public class AudioService extends IAudioService.Stub
|
||||
mDeviceBroker.setWiredDeviceConnectionState(type, state, address, name, caller);
|
||||
}
|
||||
|
||||
/** @see AudioManager#setTestDeviceConnectionState(AudioDeviceAttributes, boolean) */
|
||||
public void setTestDeviceConnectionState(@NonNull AudioDeviceAttributes device,
|
||||
boolean connected) {
|
||||
Objects.requireNonNull(device);
|
||||
enforceModifyAudioRoutingPermission();
|
||||
mDeviceBroker.setTestDeviceConnectionState(device,
|
||||
connected ? CONNECTION_STATE_CONNECTED : CONNECTION_STATE_DISCONNECTED);
|
||||
// simulate a routing update from native
|
||||
sendMsg(mAudioHandler,
|
||||
MSG_ROUTING_UPDATED,
|
||||
SENDMSG_REPLACE, 0, 0, null,
|
||||
/*delay*/ 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* The states that can be used with AudioService.setBluetoothHearingAidDeviceConnectionState()
|
||||
|
||||
Reference in New Issue
Block a user