summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/audio/AudioDeviceBroker.java27
-rw-r--r--services/core/java/com/android/server/audio/AudioDeviceInventory.java2
-rw-r--r--services/core/java/com/android/server/audio/AudioSystemAdapter.java85
-rw-r--r--services/core/java/com/android/server/audio/SystemServerAdapter.java43
-rw-r--r--services/tests/servicestests/src/com/android/server/audio/AudioDeviceBrokerTest.java96
-rw-r--r--services/tests/servicestests/src/com/android/server/audio/AudioServiceTest.java10
-rw-r--r--services/tests/servicestests/src/com/android/server/audio/NoOpAudioSystemAdapter.java107
-rw-r--r--services/tests/servicestests/src/com/android/server/audio/NoOpSystemServerAdapter.java42
8 files changed, 264 insertions, 148 deletions
diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
index 032ad63a8570..6067ccb2da27 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
@@ -25,7 +25,6 @@ import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.media.AudioDeviceAttributes;
-import android.media.AudioManager;
import android.media.AudioRoutesInfo;
import android.media.AudioSystem;
import android.media.IAudioRoutesObserver;
@@ -38,7 +37,6 @@ import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
import android.os.SystemClock;
-import android.os.UserHandle;
import android.util.Log;
import android.util.PrintWriterPrinter;
@@ -71,6 +69,8 @@ import java.io.PrintWriter;
private final AudioDeviceInventory mDeviceInventory;
// Manages notifications to BT service
private final BtHelper mBtHelper;
+ // Adapter for system_server-reserved operations
+ private final SystemServerAdapter mSystemServer;
//-------------------------------------------------------------------
@@ -97,17 +97,21 @@ import java.io.PrintWriter;
mAudioService = service;
mBtHelper = new BtHelper(this);
mDeviceInventory = new AudioDeviceInventory(this);
+ mSystemServer = SystemServerAdapter.getDefaultAdapter(mContext);
init();
}
- /** for test purposes only, inject AudioDeviceInventory */
+ /** for test purposes only, inject AudioDeviceInventory and adapter for operations running
+ * in system_server */
AudioDeviceBroker(@NonNull Context context, @NonNull AudioService service,
- @NonNull AudioDeviceInventory mockDeviceInventory) {
+ @NonNull AudioDeviceInventory mockDeviceInventory,
+ @NonNull SystemServerAdapter mockSystemServer) {
mContext = context;
mAudioService = service;
mBtHelper = new BtHelper(this);
mDeviceInventory = mockDeviceInventory;
+ mSystemServer = mockSystemServer;
init();
}
@@ -682,7 +686,7 @@ import java.io.PrintWriter;
private void onSendBecomingNoisyIntent() {
AudioService.sDeviceLogger.log((new AudioEventLogger.StringEvent(
"broadcast ACTION_AUDIO_BECOMING_NOISY")).printLog(TAG));
- sendBroadcastToAll(new Intent(AudioManager.ACTION_AUDIO_BECOMING_NOISY));
+ mSystemServer.sendDeviceBecomingNoisyIntent();
}
//---------------------------------------------------------------------
@@ -1100,17 +1104,4 @@ import java.io.PrintWriter;
time);
}
}
-
- //-------------------------------------------------------------
- // internal utilities
- private void sendBroadcastToAll(Intent intent) {
- intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
- intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
- final long ident = Binder.clearCallingIdentity();
- try {
- mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
}
diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
index 3e97a1e136c6..266dfc7e257e 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
@@ -1118,7 +1118,7 @@ public class AudioDeviceInventory {
&& AudioSystem.isSingleAudioDeviceType(devices, device)
&& !mDeviceBroker.hasMediaDynamicPolicy()
&& (musicDevice != AudioSystem.DEVICE_OUT_REMOTE_SUBMIX)) {
- if (!AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0 /*not looking in past*/)
+ if (!mAudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0 /*not looking in past*/)
&& !mDeviceBroker.hasAudioFocusUsers()) {
// no media playback, not a "becoming noisy" situation, otherwise it could cause
// the pausing of some apps that are playing remotely
diff --git a/services/core/java/com/android/server/audio/AudioSystemAdapter.java b/services/core/java/com/android/server/audio/AudioSystemAdapter.java
index 40c13904fbc9..e60243fc481c 100644
--- a/services/core/java/com/android/server/audio/AudioSystemAdapter.java
+++ b/services/core/java/com/android/server/audio/AudioSystemAdapter.java
@@ -19,7 +19,6 @@ package com.android.server.audio;
import android.annotation.NonNull;
import android.media.AudioDeviceAttributes;
import android.media.AudioSystem;
-import android.util.Log;
/**
* Provides an adapter to access functionality of the android.media.AudioSystem class for device
@@ -39,15 +38,6 @@ public class AudioSystemAdapter {
}
/**
- * Create an adapter for AudioSystem that always succeeds, and does nothing.
- * Overridden methods can be configured
- * @return a no-op AudioSystem adapter with configurable adapter
- */
- static final @NonNull AudioSystemAdapter getConfigurableAdapter() {
- return new AudioSystemConfigurableAdapter();
- }
-
- /**
* Same as {@link AudioSystem#setDeviceConnectionState(int, int, String, String, int)}
* @param device
* @param state
@@ -143,75 +133,10 @@ public class AudioSystemAdapter {
return AudioSystem.setCurrentImeUid(uid);
}
- //--------------------------------------------------------------------
- protected static class AudioSystemConfigurableAdapter extends AudioSystemAdapter {
- private static final String TAG = "ASA";
- private boolean mIsMicMuted = false;
- private boolean mMuteMicrophoneFails = false;
-
- public void configureIsMicrophoneMuted(boolean muted) {
- mIsMicMuted = muted;
- }
-
- public void configureMuteMicrophoneToFail(boolean fail) {
- mMuteMicrophoneFails = fail;
- }
-
- //-----------------------------------------------------------------
- // Overrides of AudioSystemAdapter
- @Override
- public int setDeviceConnectionState(int device, int state, String deviceAddress,
- String deviceName, int codecFormat) {
- Log.i(TAG, String.format("setDeviceConnectionState(0x%s, %s, %s, 0x%s",
- Integer.toHexString(device), state, deviceAddress, deviceName,
- Integer.toHexString(codecFormat)));
- return AudioSystem.AUDIO_STATUS_OK;
- }
-
- @Override
- public int getDeviceConnectionState(int device, String deviceAddress) {
- return AudioSystem.AUDIO_STATUS_OK;
- }
-
- @Override
- public int handleDeviceConfigChange(int device, String deviceAddress,
- String deviceName, int codecFormat) {
- return AudioSystem.AUDIO_STATUS_OK;
- }
-
- @Override
- public int setPreferredDeviceForStrategy(int strategy,
- @NonNull AudioDeviceAttributes device) {
- return AudioSystem.AUDIO_STATUS_OK;
- }
-
- @Override
- public int removePreferredDeviceForStrategy(int strategy) {
- return AudioSystem.AUDIO_STATUS_OK;
- }
-
- @Override
- public int setParameters(String keyValuePairs) {
- return AudioSystem.AUDIO_STATUS_OK;
- }
-
- @Override
- public boolean isMicrophoneMuted() {
- return mIsMicMuted;
- }
-
- @Override
- public int muteMicrophone(boolean on) {
- if (mMuteMicrophoneFails) {
- return AudioSystem.AUDIO_STATUS_ERROR;
- }
- mIsMicMuted = on;
- return AudioSystem.AUDIO_STATUS_OK;
- }
-
- @Override
- public int setCurrentImeUid(int uid) {
- return AudioSystem.AUDIO_STATUS_OK;
- }
+ /**
+ * Same as {@link AudioSystem#isStreamActive(int, int)}
+ */
+ public boolean isStreamActive(int stream, int inPastMs) {
+ return AudioSystem.isStreamActive(stream, inPastMs);
}
}
diff --git a/services/core/java/com/android/server/audio/SystemServerAdapter.java b/services/core/java/com/android/server/audio/SystemServerAdapter.java
index 509f6be76f17..68893f8ca6c7 100644
--- a/services/core/java/com/android/server/audio/SystemServerAdapter.java
+++ b/services/core/java/com/android/server/audio/SystemServerAdapter.java
@@ -21,8 +21,11 @@ import android.annotation.Nullable;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
+import android.os.Binder;
import android.os.UserHandle;
+import java.util.Objects;
+
/**
* Provides an adapter to access functionality reserved to components running in system_server
* Functionality such as sending privileged broadcasts is to be accessed through the default
@@ -32,7 +35,7 @@ public class SystemServerAdapter {
protected final Context mContext;
- private SystemServerAdapter(@Nullable Context context) {
+ protected SystemServerAdapter(@Nullable Context context) {
mContext = context;
}
/**
@@ -40,19 +43,11 @@ public class SystemServerAdapter {
* @return the adapter
*/
static final @NonNull SystemServerAdapter getDefaultAdapter(Context context) {
+ Objects.requireNonNull(context);
return new SystemServerAdapter(context);
}
/**
- * Create an adapter that does nothing.
- * Use for running non-privileged tests, such as unit tests
- * @return a no-op adapter
- */
- static final @NonNull SystemServerAdapter getNoOpAdapter() {
- return new NoOpSystemServerAdapter();
- }
-
- /**
* @return true if this is supposed to be run in system_server, false otherwise (e.g. for a
* unit test)
*/
@@ -70,21 +65,21 @@ public class SystemServerAdapter {
UserHandle.ALL);
}
- //--------------------------------------------------------------------
- protected static class NoOpSystemServerAdapter extends SystemServerAdapter {
-
- NoOpSystemServerAdapter() {
- super(null);
- }
-
- @Override
- public boolean isPrivileged() {
- return false;
+ /**
+ * Broadcast ACTION_AUDIO_BECOMING_NOISY
+ */
+ public void sendDeviceBecomingNoisyIntent() {
+ if (mContext == null) {
+ return;
}
-
- @Override
- public void sendMicrophoneMuteChangedIntent() {
- // no-op
+ final Intent intent = new Intent(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
+ intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
+ intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
}
}
}
diff --git a/services/tests/servicestests/src/com/android/server/audio/AudioDeviceBrokerTest.java b/services/tests/servicestests/src/com/android/server/audio/AudioDeviceBrokerTest.java
index 22f8b9c8ae92..4ecaac55ce96 100644
--- a/services/tests/servicestests/src/com/android/server/audio/AudioDeviceBrokerTest.java
+++ b/services/tests/servicestests/src/com/android/server/audio/AudioDeviceBrokerTest.java
@@ -58,6 +58,7 @@ public class AudioDeviceBrokerTest {
@Mock private AudioService mMockAudioService;
@Spy private AudioDeviceInventory mSpyDevInventory;
@Spy private AudioSystemAdapter mSpyAudioSystem;
+ private SystemServerAdapter mSystemServer;
private BluetoothDevice mFakeBtDevice;
@@ -66,9 +67,11 @@ public class AudioDeviceBrokerTest {
mContext = InstrumentationRegistry.getTargetContext();
mMockAudioService = mock(AudioService.class);
- mSpyAudioSystem = spy(AudioSystemAdapter.getConfigurableAdapter());
+ mSpyAudioSystem = spy(new NoOpAudioSystemAdapter());
mSpyDevInventory = spy(new AudioDeviceInventory(mSpyAudioSystem));
- mAudioDeviceBroker = new AudioDeviceBroker(mContext, mMockAudioService, mSpyDevInventory);
+ mSystemServer = new NoOpSystemServerAdapter();
+ mAudioDeviceBroker = new AudioDeviceBroker(mContext, mMockAudioService, mSpyDevInventory,
+ mSystemServer);
mSpyDevInventory.setDeviceBroker(mAudioDeviceBroker);
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
@@ -79,8 +82,8 @@ public class AudioDeviceBrokerTest {
@After
public void tearDown() throws Exception { }
- @Test
- public void testSetUpAndTearDown() { }
+// @Test
+// public void testSetUpAndTearDown() { }
/**
* postBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent() for connection:
@@ -90,7 +93,7 @@ public class AudioDeviceBrokerTest {
*/
@Test
public void testPostA2dpDeviceConnectionChange() throws Exception {
- Log.i(TAG, "testPostA2dpDeviceConnectionChange");
+ Log.i(TAG, "starting testPostA2dpDeviceConnectionChange");
Assert.assertNotNull("invalid null BT device", mFakeBtDevice);
mAudioDeviceBroker.postBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(mFakeBtDevice,
@@ -104,13 +107,8 @@ public class AudioDeviceBrokerTest {
ArgumentMatchers.eq(1) /*a2dpVolume*/
);
- final String expectedName = mFakeBtDevice.getName() == null ? "" : mFakeBtDevice.getName();
- verify(mSpyAudioSystem, times(1)).setDeviceConnectionState(
- ArgumentMatchers.eq(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP),
- ArgumentMatchers.eq(AudioSystem.DEVICE_STATE_AVAILABLE),
- ArgumentMatchers.eq(mFakeBtDevice.getAddress()),
- ArgumentMatchers.eq(expectedName),
- anyInt() /*codec*/);
+ // verify the connection was reported to AudioSystem
+ checkSingleSystemConnection(mFakeBtDevice);
}
/**
@@ -121,31 +119,70 @@ public class AudioDeviceBrokerTest {
*/
@Test
public void testA2dpDeviceConnectionDisconnectionConnectionChange() throws Exception {
- Log.i(TAG, "testA2dpDeviceConnectionDisconnectionConnectionChange");
+ Log.i(TAG, "starting testA2dpDeviceConnectionDisconnectionConnectionChange");
- doTestConnectionDisconnectionReconnection(0);
+ doTestConnectionDisconnectionReconnection(0, false,
+ // cannot guarantee single connection since commands are posted in separate thread
+ // than they are processed
+ false);
}
/**
* Verify device disconnection and reconnection within the BECOMING_NOISY window
+ * in the absence of media playback
* @throws Exception
*/
@Test
public void testA2dpDeviceReconnectionWithinBecomingNoisyDelay() throws Exception {
- Log.i(TAG, "testA2dpDeviceReconnectionWithinBecomingNoisyDelay");
+ Log.i(TAG, "starting testA2dpDeviceReconnectionWithinBecomingNoisyDelay");
+
+ doTestConnectionDisconnectionReconnection(AudioService.BECOMING_NOISY_DELAY_MS / 2,
+ false,
+ // do not check single connection since the connection command will come much
+ // after the disconnection command
+ false);
+ }
- doTestConnectionDisconnectionReconnection(AudioService.BECOMING_NOISY_DELAY_MS / 2);
+ /**
+ * Same as testA2dpDeviceConnectionDisconnectionConnectionChange() but with mock media playback
+ * @throws Exception
+ */
+ @Test
+ public void testA2dpConnectionDisconnectionConnectionChange_MediaPlayback() throws Exception {
+ Log.i(TAG, "starting testA2dpConnectionDisconnectionConnectionChange_MediaPlayback");
+
+ doTestConnectionDisconnectionReconnection(0, true,
+ // guarantee single connection since because of media playback the disconnection
+ // is supposed to be delayed, and thus cancelled because of the connection
+ true);
+ }
+
+ /**
+ * Same as testA2dpDeviceReconnectionWithinBecomingNoisyDelay() but with mock media playback
+ * @throws Exception
+ */
+ @Test
+ public void testA2dpReconnectionWithinBecomingNoisyDelay_MediaPlayback() throws Exception {
+ Log.i(TAG, "starting testA2dpReconnectionWithinBecomingNoisyDelay_MediaPlayback");
+
+ doTestConnectionDisconnectionReconnection(AudioService.BECOMING_NOISY_DELAY_MS / 2,
+ true,
+ // guarantee single connection since because of media playback the disconnection
+ // is supposed to be delayed, and thus cancelled because of the connection
+ true);
}
- private void doTestConnectionDisconnectionReconnection(int delayAfterDisconnection)
- throws Exception {
+ private void doTestConnectionDisconnectionReconnection(int delayAfterDisconnection,
+ boolean mockMediaPlayback, boolean guaranteeSingleConnection) throws Exception {
when(mMockAudioService.getDeviceForStream(AudioManager.STREAM_MUSIC))
.thenReturn(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP);
when(mMockAudioService.isInCommunication()).thenReturn(false);
when(mMockAudioService.hasMediaDynamicPolicy()).thenReturn(false);
when(mMockAudioService.hasAudioFocusUsers()).thenReturn(false);
- // first connection
+ ((NoOpAudioSystemAdapter) mSpyAudioSystem).configureIsStreamActive(mockMediaPlayback);
+
+ // first connection: ensure the device is connected as a starting condition for the test
mAudioDeviceBroker.postBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(mFakeBtDevice,
BluetoothProfile.STATE_CONNECTED, BluetoothProfile.A2DP, true, 1);
Thread.sleep(MAX_MESSAGE_HANDLING_DELAY_MS);
@@ -169,5 +206,26 @@ public class AudioDeviceBrokerTest {
ArgumentMatchers.eq(BluetoothProfile.STATE_CONNECTED));
Assert.assertTrue("Mock device not connected",
mSpyDevInventory.isA2dpDeviceConnected(mFakeBtDevice));
+
+ if (guaranteeSingleConnection) {
+ // when the disconnection was expected to be cancelled, there should have been a single
+ // call to AudioSystem to declare the device connected (available)
+ checkSingleSystemConnection(mFakeBtDevice);
+ }
+ }
+
+ /**
+ * Verifies the given device was reported to AudioSystem exactly once as available
+ * @param btDevice
+ * @throws Exception
+ */
+ private void checkSingleSystemConnection(BluetoothDevice btDevice) throws Exception {
+ final String expectedName = btDevice.getName() == null ? "" : btDevice.getName();
+ verify(mSpyAudioSystem, times(1)).setDeviceConnectionState(
+ ArgumentMatchers.eq(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP),
+ ArgumentMatchers.eq(AudioSystem.DEVICE_STATE_AVAILABLE),
+ ArgumentMatchers.eq(btDevice.getAddress()),
+ ArgumentMatchers.eq(expectedName),
+ anyInt() /*codec*/);
}
}
diff --git a/services/tests/servicestests/src/com/android/server/audio/AudioServiceTest.java b/services/tests/servicestests/src/com/android/server/audio/AudioServiceTest.java
index 6185ae6d93f9..54945fbc2dd2 100644
--- a/services/tests/servicestests/src/com/android/server/audio/AudioServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/audio/AudioServiceTest.java
@@ -57,8 +57,8 @@ public class AudioServiceTest {
sLooperPrepared = true;
}
mContext = InstrumentationRegistry.getTargetContext();
- mAudioSystem = AudioSystemAdapter.getConfigurableAdapter();
- mSpySystemServer = spy(SystemServerAdapter.getNoOpAdapter());
+ mAudioSystem = new NoOpAudioSystemAdapter();
+ mSpySystemServer = spy(new NoOpSystemServerAdapter());
mAudioService = new AudioService(mContext, mAudioSystem, mSpySystemServer);
}
@@ -70,8 +70,7 @@ public class AudioServiceTest {
public void testMuteMicrophone() throws Exception {
Log.i(TAG, "running testMuteMicrophone");
Assert.assertNotNull(mAudioService);
- final AudioSystemAdapter.AudioSystemConfigurableAdapter testAudioSystem =
- (AudioSystemAdapter.AudioSystemConfigurableAdapter) mAudioSystem;
+ final NoOpAudioSystemAdapter testAudioSystem = (NoOpAudioSystemAdapter) mAudioSystem;
testAudioSystem.configureMuteMicrophoneToFail(false);
for (boolean muted : new boolean[] { true, false}) {
testAudioSystem.configureIsMicrophoneMuted(!muted);
@@ -96,8 +95,7 @@ public class AudioServiceTest {
public void testMuteMicrophoneWhenFail() throws Exception {
Log.i(TAG, "running testMuteMicrophoneWhenFail");
Assert.assertNotNull(mAudioService);
- final AudioSystemAdapter.AudioSystemConfigurableAdapter testAudioSystem =
- (AudioSystemAdapter.AudioSystemConfigurableAdapter) mAudioSystem;
+ final NoOpAudioSystemAdapter testAudioSystem = (NoOpAudioSystemAdapter) mAudioSystem;
testAudioSystem.configureMuteMicrophoneToFail(true);
for (boolean muted : new boolean[] { true, false}) {
testAudioSystem.configureIsMicrophoneMuted(!muted);
diff --git a/services/tests/servicestests/src/com/android/server/audio/NoOpAudioSystemAdapter.java b/services/tests/servicestests/src/com/android/server/audio/NoOpAudioSystemAdapter.java
new file mode 100644
index 000000000000..a9cef20268f4
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/audio/NoOpAudioSystemAdapter.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2020 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 com.android.server.audio;
+
+import android.annotation.NonNull;
+import android.media.AudioDeviceAttributes;
+import android.media.AudioSystem;
+import android.util.Log;
+
+/**
+ * Provides an adapter for AudioSystem that does nothing.
+ * Overridden methods can be configured.
+ */
+public class NoOpAudioSystemAdapter extends AudioSystemAdapter {
+ private static final String TAG = "ASA";
+ private boolean mIsMicMuted = false;
+ private boolean mMuteMicrophoneFails = false;
+ private boolean mIsStreamActive = false;
+
+ public void configureIsMicrophoneMuted(boolean muted) {
+ mIsMicMuted = muted;
+ }
+
+ public void configureIsStreamActive(boolean active) {
+ mIsStreamActive = active;
+ }
+
+ public void configureMuteMicrophoneToFail(boolean fail) {
+ mMuteMicrophoneFails = fail;
+ }
+
+ //-----------------------------------------------------------------
+ // Overrides of AudioSystemAdapter
+ @Override
+ public int setDeviceConnectionState(int device, int state, String deviceAddress,
+ String deviceName, int codecFormat) {
+ Log.i(TAG, String.format("setDeviceConnectionState(0x%s, %d, %s, %s, 0x%s",
+ Integer.toHexString(device), state, deviceAddress, deviceName,
+ Integer.toHexString(codecFormat)));
+ return AudioSystem.AUDIO_STATUS_OK;
+ }
+
+ @Override
+ public int getDeviceConnectionState(int device, String deviceAddress) {
+ return AudioSystem.AUDIO_STATUS_OK;
+ }
+
+ @Override
+ public int handleDeviceConfigChange(int device, String deviceAddress,
+ String deviceName, int codecFormat) {
+ return AudioSystem.AUDIO_STATUS_OK;
+ }
+
+ @Override
+ public int setPreferredDeviceForStrategy(int strategy,
+ @NonNull AudioDeviceAttributes device) {
+ return AudioSystem.AUDIO_STATUS_OK;
+ }
+
+ @Override
+ public int removePreferredDeviceForStrategy(int strategy) {
+ return AudioSystem.AUDIO_STATUS_OK;
+ }
+
+ @Override
+ public int setParameters(String keyValuePairs) {
+ return AudioSystem.AUDIO_STATUS_OK;
+ }
+
+ @Override
+ public boolean isMicrophoneMuted() {
+ return mIsMicMuted;
+ }
+
+ @Override
+ public int muteMicrophone(boolean on) {
+ if (mMuteMicrophoneFails) {
+ return AudioSystem.AUDIO_STATUS_ERROR;
+ }
+ mIsMicMuted = on;
+ return AudioSystem.AUDIO_STATUS_OK;
+ }
+
+ @Override
+ public int setCurrentImeUid(int uid) {
+ return AudioSystem.AUDIO_STATUS_OK;
+ }
+
+ @Override
+ public boolean isStreamActive(int stream, int inPastMs) {
+ return mIsStreamActive;
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/audio/NoOpSystemServerAdapter.java b/services/tests/servicestests/src/com/android/server/audio/NoOpSystemServerAdapter.java
new file mode 100644
index 000000000000..83c566376e44
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/audio/NoOpSystemServerAdapter.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2020 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 com.android.server.audio;
+
+/**
+ * Provides a no-op adapter that implements SystemServerAdapter
+ */
+public class NoOpSystemServerAdapter extends SystemServerAdapter {
+
+ NoOpSystemServerAdapter() {
+ super(null);
+ }
+
+ @Override
+ public boolean isPrivileged() {
+ return false;
+ }
+
+ @Override
+ public void sendMicrophoneMuteChangedIntent() {
+ // no-op
+ }
+
+ @Override
+ public void sendDeviceBecomingNoisyIntent() {
+ // no-op
+ }
+}