diff options
3 files changed, 95 insertions, 9 deletions
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/NoOpInfoMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/NoOpInfoMediaManager.java index ff4d4dd837d2..2b8c2dd0d0e3 100644 --- a/packages/SettingsLib/src/com/android/settingslib/media/NoOpInfoMediaManager.java +++ b/packages/SettingsLib/src/com/android/settingslib/media/NoOpInfoMediaManager.java @@ -37,6 +37,23 @@ import java.util.List; */ // TODO - b/293578081: Remove once PackageNotAvailableException is propagated to library clients. /* package */ final class NoOpInfoMediaManager extends InfoMediaManager { + /** + * Placeholder routing session to return as active session of {@link NoOpInfoMediaManager}. + * + * <p>Returning this routing session avoids crashes in {@link InfoMediaManager} and maintains + * the same client-facing behaviour as if no routing session was found for the target package + * name. + * + * <p>Volume and max volume are set to {@code -1} to emulate a non-existing routing session in + * {@link #getSessionVolume()} and {@link #getSessionVolumeMax()}. + */ + private static final RoutingSessionInfo PLACEHOLDER_SESSION = + new RoutingSessionInfo.Builder( + /* id */ "FAKE_ROUTING_SESSION", /* clientPackageName */ "") + .addSelectedRoute(/* routeId */ "FAKE_SELECTED_ROUTE_ID") + .setVolumeMax(-1) + .setVolume(-1) + .build(); NoOpInfoMediaManager( Context context, @@ -118,7 +135,7 @@ import java.util.List; @NonNull @Override protected List<RoutingSessionInfo> getRoutingSessionsForPackage() { - return Collections.emptyList(); + return List.of(PLACEHOLDER_SESSION); } @Nullable diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/NoOpInfoMediaManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/NoOpInfoMediaManagerTest.java new file mode 100644 index 000000000000..d630301a083b --- /dev/null +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/NoOpInfoMediaManagerTest.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2024 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.settingslib.media; + +import static com.google.common.truth.Truth.assertThat; + +import android.content.Context; + +import androidx.test.core.app.ApplicationProvider; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; + +/** + * Tests for {@link NoOpInfoMediaManager} to avoid exceptions in {@link InfoMediaManager}. + * + * <p>While {@link NoOpInfoMediaManager} should not perform any actions, it should still return + * placeholder information in certain cases to not change the behaviour of {@link InfoMediaManager} + * and prevent crashes. + */ +@RunWith(RobolectricTestRunner.class) +public class NoOpInfoMediaManagerTest { + private InfoMediaManager mInfoMediaManager; + private Context mContext; + + @Before + public void setUp() { + mContext = ApplicationProvider.getApplicationContext(); + mInfoMediaManager = + new NoOpInfoMediaManager( + mContext, + /* packageName */ "FAKE_PACKAGE_NAME", + /* localBluetoothManager */ null); + } + + @Test + public void getSessionVolumeMax_returnsNotFound() { + assertThat(mInfoMediaManager.getSessionVolumeMax()).isEqualTo(-1); + } + + @Test + public void getSessionVolume_returnsNotFound() { + assertThat(mInfoMediaManager.getSessionVolume()).isEqualTo(-1); + } + + @Test + public void getSessionName_returnsNull() { + assertThat(mInfoMediaManager.getSessionName()).isNull(); + } + + @Test + public void getRoutingSessionForPackage_returnsPlaceholderSession() { + // Make sure we return a placeholder routing session so that we avoid OOB exceptions. + assertThat(mInfoMediaManager.getRoutingSessionsForPackage()).hasSize(1); + } + + @Test + public void getSelectedMediaDevices_returnsEmptyList() { + assertThat(mInfoMediaManager.getSelectedMediaDevices()).isEmpty(); + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java index ca403e0addec..695d3b2c6c78 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java @@ -19,7 +19,6 @@ package com.android.systemui.media.dialog; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.any; -import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; @@ -48,7 +47,6 @@ import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager; import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast; import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.bluetooth.LocalBluetoothProfileManager; -import com.android.settingslib.media.LocalMediaManager; import com.android.systemui.SysuiTestCase; import com.android.systemui.animation.DialogTransitionAnimator; import com.android.systemui.broadcast.BroadcastSender; @@ -129,12 +127,6 @@ public class MediaOutputBaseDialogTest extends SysuiTestCase { mNearbyMediaDevicesManager, mAudioManager, mPowerExemptionManager, mKeyguardManager, mFlags, mUserTracker); - // Using a fake package will cause routing operations to fail, so we intercept - // scanning-related operations. - mMediaOutputController.mLocalMediaManager = mock(LocalMediaManager.class); - doNothing().when(mMediaOutputController.mLocalMediaManager).startScan(); - doNothing().when(mMediaOutputController.mLocalMediaManager).stopScan(); - mMediaOutputBaseDialogImpl = new MediaOutputBaseDialogImpl(mContext, mBroadcastSender, mMediaOutputController); mMediaOutputBaseDialogImpl.onCreate(new Bundle()); |