diff options
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 + } +} |