Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4da775dd authored by Jean-Michel Trivi's avatar Jean-Michel Trivi
Browse files

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
parent 933bf143
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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 {
+17 −0
Original line number Diff line number Diff line
@@ -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
+2 −0
Original line number Diff line number Diff line
@@ -458,4 +458,6 @@ interface IAudioService {

    void registerMuteAwaitConnectionDispatcher(in IMuteAwaitConnectionCallback cb,
            boolean register);

    void setTestDeviceConnectionState(in AudioDeviceAttributes device, boolean connected);
}
+9 −1
Original line number Diff line number Diff line
@@ -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*/);
        }
    }

+23 −6
Original line number Diff line number Diff line
@@ -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,
                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

Loading