[Audiosharing] Add tests.
Test: atest -c com.android.settings.connecteddevice.audiosharing.audiostreams Bug: 308368124 Change-Id: I6322ccbb5deffe2bc169a898ef0208e135caa819
This commit is contained in:
@@ -37,6 +37,7 @@ import android.util.Log;
|
|||||||
import androidx.annotation.IntRange;
|
import androidx.annotation.IntRange;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.annotation.VisibleForTesting;
|
||||||
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.bluetooth.Utils;
|
import com.android.settings.bluetooth.Utils;
|
||||||
@@ -196,7 +197,7 @@ public class AudioStreamMediaService extends Service {
|
|||||||
// override this value. Otherwise, we raise the volume to 25 when the play button is clicked.
|
// override this value. Otherwise, we raise the volume to 25 when the play button is clicked.
|
||||||
private int mLatestPositiveVolume = 25;
|
private int mLatestPositiveVolume = 25;
|
||||||
private boolean mIsMuted = false;
|
private boolean mIsMuted = false;
|
||||||
@Nullable private MediaSession mLocalSession;
|
@VisibleForTesting @Nullable MediaSession mLocalSession;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
@@ -228,7 +229,7 @@ public class AudioStreamMediaService extends Service {
|
|||||||
NotificationChannel notificationChannel =
|
NotificationChannel notificationChannel =
|
||||||
new NotificationChannel(
|
new NotificationChannel(
|
||||||
CHANNEL_ID,
|
CHANNEL_ID,
|
||||||
this.getString(com.android.settings.R.string.bluetooth),
|
getString(com.android.settings.R.string.bluetooth),
|
||||||
NotificationManager.IMPORTANCE_HIGH);
|
NotificationManager.IMPORTANCE_HIGH);
|
||||||
mNotificationManager.createNotificationChannel(notificationChannel);
|
mNotificationManager.createNotificationChannel(notificationChannel);
|
||||||
}
|
}
|
||||||
@@ -403,7 +404,7 @@ public class AudioStreamMediaService extends Service {
|
|||||||
new Notification.Builder(this, CHANNEL_ID)
|
new Notification.Builder(this, CHANNEL_ID)
|
||||||
.setSmallIcon(com.android.settingslib.R.drawable.ic_bt_le_audio_sharing)
|
.setSmallIcon(com.android.settingslib.R.drawable.ic_bt_le_audio_sharing)
|
||||||
.setStyle(mediaStyle)
|
.setStyle(mediaStyle)
|
||||||
.setContentText(this.getString(BROADCAST_CONTENT_TEXT))
|
.setContentText(getString(BROADCAST_CONTENT_TEXT))
|
||||||
.setSilent(true);
|
.setSilent(true);
|
||||||
return notificationBuilder.build();
|
return notificationBuilder.build();
|
||||||
}
|
}
|
||||||
|
@@ -60,6 +60,7 @@ public class AudioStreamsCategoryController extends AudioSharingBasePreferenceCo
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStart(@NonNull LifecycleOwner owner) {
|
public void onStart(@NonNull LifecycleOwner owner) {
|
||||||
|
if (!isAvailable()) return;
|
||||||
super.onStart(owner);
|
super.onStart(owner);
|
||||||
if (mLocalBtManager != null) {
|
if (mLocalBtManager != null) {
|
||||||
mLocalBtManager.getEventManager().registerCallback(mBluetoothCallback);
|
mLocalBtManager.getEventManager().registerCallback(mBluetoothCallback);
|
||||||
@@ -68,6 +69,7 @@ public class AudioStreamsCategoryController extends AudioSharingBasePreferenceCo
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStop(@NonNull LifecycleOwner owner) {
|
public void onStop(@NonNull LifecycleOwner owner) {
|
||||||
|
if (!isAvailable()) return;
|
||||||
super.onStop(owner);
|
super.onStop(owner);
|
||||||
if (mLocalBtManager != null) {
|
if (mLocalBtManager != null) {
|
||||||
mLocalBtManager.getEventManager().unregisterCallback(mBluetoothCallback);
|
mLocalBtManager.getEventManager().unregisterCallback(mBluetoothCallback);
|
||||||
|
@@ -139,8 +139,10 @@ public class AudioStreamsHelper {
|
|||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Retrieves LocalBluetoothLeBroadcastAssistant. */
|
||||||
|
@VisibleForTesting
|
||||||
@Nullable
|
@Nullable
|
||||||
LocalBluetoothLeBroadcastAssistant getLeBroadcastAssistant() {
|
public LocalBluetoothLeBroadcastAssistant getLeBroadcastAssistant() {
|
||||||
return mLeBroadcastAssistant;
|
return mLeBroadcastAssistant;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -0,0 +1,327 @@
|
|||||||
|
/*
|
||||||
|
* 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.settings.connecteddevice.audiosharing.audiostreams;
|
||||||
|
|
||||||
|
import static com.android.settings.connecteddevice.audiosharing.audiostreams.AudioStreamsDashboardFragment.KEY_BROADCAST_METADATA;
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
import static org.robolectric.shadows.ShadowLooper.shadowMainLooper;
|
||||||
|
|
||||||
|
import android.app.settings.SettingsEnums;
|
||||||
|
import android.bluetooth.BluetoothAdapter;
|
||||||
|
import android.bluetooth.BluetoothDevice;
|
||||||
|
import android.bluetooth.BluetoothStatusCodes;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.platform.test.flag.junit.SetFlagsRule;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.fragment.app.FragmentActivity;
|
||||||
|
import androidx.test.core.app.ApplicationProvider;
|
||||||
|
|
||||||
|
import com.android.settings.R;
|
||||||
|
import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
|
||||||
|
import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
|
||||||
|
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
|
||||||
|
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant;
|
||||||
|
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
||||||
|
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
|
||||||
|
import com.android.settingslib.bluetooth.VolumeControlProfile;
|
||||||
|
import com.android.settingslib.flags.Flags;
|
||||||
|
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.junit.MockitoJUnit;
|
||||||
|
import org.mockito.junit.MockitoRule;
|
||||||
|
import org.robolectric.RobolectricTestRunner;
|
||||||
|
import org.robolectric.annotation.Config;
|
||||||
|
import org.robolectric.shadow.api.Shadow;
|
||||||
|
import org.robolectric.shadows.androidx.fragment.FragmentController;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@RunWith(RobolectricTestRunner.class)
|
||||||
|
@Config(
|
||||||
|
shadows = {
|
||||||
|
ShadowBluetoothAdapter.class,
|
||||||
|
ShadowBluetoothUtils.class,
|
||||||
|
})
|
||||||
|
public class AudioStreamConfirmDialogTest {
|
||||||
|
@Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule();
|
||||||
|
@Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
|
||||||
|
private static final String VALID_METADATA =
|
||||||
|
"BLUETOOTH:UUID:184F;BN:VGVzdA==;AT:1;AD:00A1A1A1A1A1;BI:1E240;BC:VGVzdENvZGU=;"
|
||||||
|
+ "MD:BgNwVGVzdA==;AS:1;PI:A0;NS:1;BS:3;NB:2;SM:BQNUZXN0BARlbmc=;;";
|
||||||
|
private static final String DEVICE_NAME = "device_name";
|
||||||
|
private final Context mContext = ApplicationProvider.getApplicationContext();
|
||||||
|
@Mock private LocalBluetoothManager mLocalBluetoothManager;
|
||||||
|
@Mock private LocalBluetoothProfileManager mLocalBluetoothProfileManager;
|
||||||
|
@Mock private LocalBluetoothLeBroadcast mBroadcast;
|
||||||
|
@Mock private LocalBluetoothLeBroadcastAssistant mAssistant;
|
||||||
|
@Mock private VolumeControlProfile mVolumeControl;
|
||||||
|
@Mock private BluetoothDevice mBluetoothDevice;
|
||||||
|
private AudioStreamConfirmDialog mDialogFragment;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
ShadowBluetoothAdapter shadowBluetoothAdapter =
|
||||||
|
Shadow.extract(BluetoothAdapter.getDefaultAdapter());
|
||||||
|
shadowBluetoothAdapter.setEnabled(true);
|
||||||
|
shadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported(
|
||||||
|
BluetoothStatusCodes.FEATURE_SUPPORTED);
|
||||||
|
shadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported(
|
||||||
|
BluetoothStatusCodes.FEATURE_SUPPORTED);
|
||||||
|
|
||||||
|
ShadowBluetoothUtils.sLocalBluetoothManager = mLocalBluetoothManager;
|
||||||
|
when(mLocalBluetoothManager.getProfileManager()).thenReturn(mLocalBluetoothProfileManager);
|
||||||
|
when(mLocalBluetoothProfileManager.getLeAudioBroadcastProfile()).thenReturn(mBroadcast);
|
||||||
|
when(mLocalBluetoothProfileManager.getLeAudioBroadcastAssistantProfile())
|
||||||
|
.thenReturn(mAssistant);
|
||||||
|
when(mLocalBluetoothProfileManager.getVolumeControlProfile()).thenReturn(mVolumeControl);
|
||||||
|
when(mBroadcast.isProfileReady()).thenReturn(true);
|
||||||
|
when(mAssistant.isProfileReady()).thenReturn(true);
|
||||||
|
when(mVolumeControl.isProfileReady()).thenReturn(true);
|
||||||
|
|
||||||
|
mDialogFragment = new AudioStreamConfirmDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() {
|
||||||
|
ShadowBluetoothUtils.reset();
|
||||||
|
mDialogFragment.dismiss();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void showDialog_unsupported() {
|
||||||
|
mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
||||||
|
FragmentController.setupFragment(
|
||||||
|
mDialogFragment,
|
||||||
|
FragmentActivity.class,
|
||||||
|
/* containerViewId= */ 0,
|
||||||
|
/* bundle= */ null);
|
||||||
|
shadowMainLooper().idle();
|
||||||
|
|
||||||
|
assertThat(mDialogFragment.getMetricsCategory())
|
||||||
|
.isEqualTo(SettingsEnums.DIALOG_AUDIO_STREAM_CONFIRM_FEATURE_UNSUPPORTED);
|
||||||
|
|
||||||
|
var dialog = mDialogFragment.getDialog();
|
||||||
|
assertThat(dialog).isNotNull();
|
||||||
|
assertThat(dialog.isShowing()).isTrue();
|
||||||
|
TextView title = dialog.findViewById(R.id.dialog_title);
|
||||||
|
assertThat(title).isNotNull();
|
||||||
|
assertThat(title.getText())
|
||||||
|
.isEqualTo(mContext.getString(R.string.audio_streams_dialog_cannot_listen));
|
||||||
|
TextView subtitle1 = dialog.findViewById(R.id.dialog_subtitle);
|
||||||
|
assertThat(subtitle1).isNotNull();
|
||||||
|
assertThat(subtitle1.getVisibility()).isEqualTo(View.GONE);
|
||||||
|
TextView subtitle2 = dialog.findViewById(R.id.dialog_subtitle_2);
|
||||||
|
assertThat(subtitle2).isNotNull();
|
||||||
|
assertThat(subtitle2.getText())
|
||||||
|
.isEqualTo(
|
||||||
|
mContext.getString(
|
||||||
|
R.string.audio_streams_dialog_unsupported_device_subtitle));
|
||||||
|
View leftButton = dialog.findViewById(R.id.left_button);
|
||||||
|
assertThat(leftButton).isNotNull();
|
||||||
|
assertThat(leftButton.getVisibility()).isEqualTo(View.GONE);
|
||||||
|
assertThat(leftButton.hasOnClickListeners()).isFalse();
|
||||||
|
View rightButton = dialog.findViewById(R.id.right_button);
|
||||||
|
assertThat(rightButton).isNotNull();
|
||||||
|
assertThat(rightButton.getVisibility()).isEqualTo(View.VISIBLE);
|
||||||
|
assertThat(rightButton.hasOnClickListeners()).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void showDialog_noLeDevice() {
|
||||||
|
FragmentController.setupFragment(
|
||||||
|
mDialogFragment,
|
||||||
|
FragmentActivity.class,
|
||||||
|
/* containerViewId= */ 0,
|
||||||
|
/* bundle= */ null);
|
||||||
|
shadowMainLooper().idle();
|
||||||
|
|
||||||
|
assertThat(mDialogFragment.getMetricsCategory())
|
||||||
|
.isEqualTo(SettingsEnums.DIALOG_AUDIO_STREAM_CONFIRM_NO_LE_DEVICE);
|
||||||
|
|
||||||
|
var dialog = mDialogFragment.getDialog();
|
||||||
|
assertThat(dialog).isNotNull();
|
||||||
|
assertThat(dialog.isShowing()).isTrue();
|
||||||
|
|
||||||
|
TextView title = dialog.findViewById(R.id.dialog_title);
|
||||||
|
assertThat(title).isNotNull();
|
||||||
|
assertThat(title.getText())
|
||||||
|
.isEqualTo(mContext.getString(R.string.audio_streams_dialog_no_le_device_title));
|
||||||
|
TextView subtitle1 = dialog.findViewById(R.id.dialog_subtitle);
|
||||||
|
assertThat(subtitle1).isNotNull();
|
||||||
|
assertThat(subtitle1.getVisibility()).isEqualTo(View.GONE);
|
||||||
|
TextView subtitle2 = dialog.findViewById(R.id.dialog_subtitle_2);
|
||||||
|
assertThat(subtitle2).isNotNull();
|
||||||
|
assertThat(subtitle2.getText())
|
||||||
|
.isEqualTo(mContext.getString(R.string.audio_streams_dialog_no_le_device_subtitle));
|
||||||
|
View leftButton = dialog.findViewById(R.id.left_button);
|
||||||
|
assertThat(leftButton).isNotNull();
|
||||||
|
assertThat(leftButton.getVisibility()).isEqualTo(View.VISIBLE);
|
||||||
|
Button rightButton = dialog.findViewById(R.id.right_button);
|
||||||
|
assertThat(rightButton).isNotNull();
|
||||||
|
assertThat(rightButton.getText())
|
||||||
|
.isEqualTo(mContext.getString(R.string.audio_streams_dialog_no_le_device_button));
|
||||||
|
assertThat(rightButton.hasOnClickListeners()).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void showDialog_noMetadata() {
|
||||||
|
List<BluetoothDevice> devices = new ArrayList<>();
|
||||||
|
devices.add(mBluetoothDevice);
|
||||||
|
when(mAssistant.getDevicesMatchingConnectionStates(any())).thenReturn(devices);
|
||||||
|
when(mBluetoothDevice.getAlias()).thenReturn(DEVICE_NAME);
|
||||||
|
|
||||||
|
FragmentController.setupFragment(
|
||||||
|
mDialogFragment,
|
||||||
|
FragmentActivity.class,
|
||||||
|
/* containerViewId= */ 0,
|
||||||
|
/* bundle= */ null);
|
||||||
|
shadowMainLooper().idle();
|
||||||
|
|
||||||
|
assertThat(mDialogFragment.getMetricsCategory())
|
||||||
|
.isEqualTo(SettingsEnums.DIALOG_AUDIO_STREAM_CONFIRM_DATA_ERROR);
|
||||||
|
|
||||||
|
var dialog = mDialogFragment.getDialog();
|
||||||
|
assertThat(dialog).isNotNull();
|
||||||
|
assertThat(dialog.isShowing()).isTrue();
|
||||||
|
TextView title = dialog.findViewById(R.id.dialog_title);
|
||||||
|
assertThat(title).isNotNull();
|
||||||
|
assertThat(title.getText())
|
||||||
|
.isEqualTo(mContext.getString(R.string.audio_streams_dialog_cannot_listen));
|
||||||
|
TextView subtitle1 = dialog.findViewById(R.id.dialog_subtitle);
|
||||||
|
assertThat(subtitle1).isNotNull();
|
||||||
|
assertThat(subtitle1.getVisibility()).isEqualTo(View.GONE);
|
||||||
|
TextView subtitle2 = dialog.findViewById(R.id.dialog_subtitle_2);
|
||||||
|
assertThat(subtitle2).isNotNull();
|
||||||
|
assertThat(subtitle2.getText())
|
||||||
|
.isEqualTo(
|
||||||
|
mContext.getString(R.string.audio_streams_dialog_cannot_play, DEVICE_NAME));
|
||||||
|
View leftButton = dialog.findViewById(R.id.left_button);
|
||||||
|
assertThat(leftButton).isNotNull();
|
||||||
|
assertThat(leftButton.getVisibility()).isEqualTo(View.GONE);
|
||||||
|
assertThat(leftButton.hasOnClickListeners()).isFalse();
|
||||||
|
View rightButton = dialog.findViewById(R.id.right_button);
|
||||||
|
assertThat(rightButton).isNotNull();
|
||||||
|
assertThat(rightButton.getVisibility()).isEqualTo(View.VISIBLE);
|
||||||
|
assertThat(rightButton.hasOnClickListeners()).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void showDialog_invalidMetadata() {
|
||||||
|
List<BluetoothDevice> devices = new ArrayList<>();
|
||||||
|
devices.add(mBluetoothDevice);
|
||||||
|
when(mAssistant.getDevicesMatchingConnectionStates(any())).thenReturn(devices);
|
||||||
|
when(mBluetoothDevice.getAlias()).thenReturn(DEVICE_NAME);
|
||||||
|
|
||||||
|
Intent intent = new Intent();
|
||||||
|
intent.putExtra(KEY_BROADCAST_METADATA, "invalid");
|
||||||
|
FragmentController.of(mDialogFragment, intent)
|
||||||
|
.create(/* containerViewId= */ 0, /* bundle= */ null)
|
||||||
|
.start()
|
||||||
|
.resume()
|
||||||
|
.visible()
|
||||||
|
.get();
|
||||||
|
shadowMainLooper().idle();
|
||||||
|
|
||||||
|
assertThat(mDialogFragment.getMetricsCategory())
|
||||||
|
.isEqualTo(SettingsEnums.DIALOG_AUDIO_STREAM_CONFIRM_DATA_ERROR);
|
||||||
|
|
||||||
|
var dialog = mDialogFragment.getDialog();
|
||||||
|
assertThat(dialog).isNotNull();
|
||||||
|
assertThat(dialog.isShowing()).isTrue();
|
||||||
|
TextView title = dialog.findViewById(R.id.dialog_title);
|
||||||
|
assertThat(title).isNotNull();
|
||||||
|
assertThat(title.getText())
|
||||||
|
.isEqualTo(mContext.getString(R.string.audio_streams_dialog_cannot_listen));
|
||||||
|
TextView subtitle1 = dialog.findViewById(R.id.dialog_subtitle);
|
||||||
|
assertThat(subtitle1).isNotNull();
|
||||||
|
assertThat(subtitle1.getVisibility()).isEqualTo(View.GONE);
|
||||||
|
TextView subtitle2 = dialog.findViewById(R.id.dialog_subtitle_2);
|
||||||
|
assertThat(subtitle2).isNotNull();
|
||||||
|
assertThat(subtitle2.getText())
|
||||||
|
.isEqualTo(
|
||||||
|
mContext.getString(R.string.audio_streams_dialog_cannot_play, DEVICE_NAME));
|
||||||
|
View leftButton = dialog.findViewById(R.id.left_button);
|
||||||
|
assertThat(leftButton).isNotNull();
|
||||||
|
assertThat(leftButton.getVisibility()).isEqualTo(View.GONE);
|
||||||
|
assertThat(leftButton.hasOnClickListeners()).isFalse();
|
||||||
|
View rightButton = dialog.findViewById(R.id.right_button);
|
||||||
|
assertThat(rightButton).isNotNull();
|
||||||
|
assertThat(rightButton.getVisibility()).isEqualTo(View.VISIBLE);
|
||||||
|
assertThat(rightButton.hasOnClickListeners()).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void showDialog_confirmListen() {
|
||||||
|
List<BluetoothDevice> devices = new ArrayList<>();
|
||||||
|
devices.add(mBluetoothDevice);
|
||||||
|
when(mAssistant.getDevicesMatchingConnectionStates(any())).thenReturn(devices);
|
||||||
|
when(mBluetoothDevice.getAlias()).thenReturn(DEVICE_NAME);
|
||||||
|
|
||||||
|
Intent intent = new Intent();
|
||||||
|
intent.putExtra(KEY_BROADCAST_METADATA, VALID_METADATA);
|
||||||
|
FragmentController.of(mDialogFragment, intent)
|
||||||
|
.create(/* containerViewId= */ 0, /* bundle= */ null)
|
||||||
|
.start()
|
||||||
|
.resume()
|
||||||
|
.visible()
|
||||||
|
.get();
|
||||||
|
shadowMainLooper().idle();
|
||||||
|
|
||||||
|
assertThat(mDialogFragment.getMetricsCategory())
|
||||||
|
.isEqualTo(SettingsEnums.DIALOG_AUDIO_STREAM_CONFIRM_LISTEN);
|
||||||
|
|
||||||
|
var dialog = mDialogFragment.getDialog();
|
||||||
|
assertThat(dialog).isNotNull();
|
||||||
|
assertThat(dialog.isShowing()).isTrue();
|
||||||
|
TextView title = dialog.findViewById(R.id.dialog_title);
|
||||||
|
assertThat(title).isNotNull();
|
||||||
|
assertThat(title.getText())
|
||||||
|
.isEqualTo(
|
||||||
|
mContext.getString(R.string.audio_streams_dialog_listen_to_audio_stream));
|
||||||
|
TextView subtitle1 = dialog.findViewById(R.id.dialog_subtitle);
|
||||||
|
assertThat(subtitle1).isNotNull();
|
||||||
|
assertThat(subtitle1.getVisibility()).isEqualTo(View.VISIBLE);
|
||||||
|
TextView subtitle2 = dialog.findViewById(R.id.dialog_subtitle_2);
|
||||||
|
assertThat(subtitle2).isNotNull();
|
||||||
|
assertThat(subtitle2.getText())
|
||||||
|
.isEqualTo(
|
||||||
|
mContext.getString(
|
||||||
|
R.string.audio_streams_dialog_control_volume, DEVICE_NAME));
|
||||||
|
View leftButton = dialog.findViewById(R.id.left_button);
|
||||||
|
assertThat(leftButton).isNotNull();
|
||||||
|
assertThat(leftButton.getVisibility()).isEqualTo(View.VISIBLE);
|
||||||
|
Button rightButton = dialog.findViewById(R.id.right_button);
|
||||||
|
assertThat(rightButton).isNotNull();
|
||||||
|
assertThat(rightButton.getText())
|
||||||
|
.isEqualTo(mContext.getString(R.string.audio_streams_dialog_listen));
|
||||||
|
assertThat(rightButton.hasOnClickListeners()).isTrue();
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,233 @@
|
|||||||
|
/*
|
||||||
|
* 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.settings.connecteddevice.audiosharing.audiostreams;
|
||||||
|
|
||||||
|
import static com.android.settings.connecteddevice.audiosharing.audiostreams.AudioStreamMediaService.BROADCAST_ID;
|
||||||
|
import static com.android.settings.connecteddevice.audiosharing.audiostreams.AudioStreamMediaService.DEVICES;
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyString;
|
||||||
|
import static org.mockito.Mockito.doReturn;
|
||||||
|
import static org.mockito.Mockito.never;
|
||||||
|
import static org.mockito.Mockito.spy;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import android.app.Notification;
|
||||||
|
import android.app.NotificationManager;
|
||||||
|
import android.bluetooth.BluetoothAdapter;
|
||||||
|
import android.bluetooth.BluetoothDevice;
|
||||||
|
import android.bluetooth.BluetoothStatusCodes;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.pm.ApplicationInfo;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.content.res.Resources;
|
||||||
|
import android.media.session.ISession;
|
||||||
|
import android.media.session.ISessionController;
|
||||||
|
import android.media.session.MediaSessionManager;
|
||||||
|
import android.os.RemoteException;
|
||||||
|
import android.platform.test.flag.junit.SetFlagsRule;
|
||||||
|
import android.util.DisplayMetrics;
|
||||||
|
|
||||||
|
import com.android.settings.connecteddevice.audiosharing.audiostreams.testshadows.ShadowAudioStreamsHelper;
|
||||||
|
import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
|
||||||
|
import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
|
||||||
|
import com.android.settingslib.bluetooth.BluetoothEventManager;
|
||||||
|
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant;
|
||||||
|
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
||||||
|
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
|
||||||
|
import com.android.settingslib.bluetooth.VolumeControlProfile;
|
||||||
|
import com.android.settingslib.flags.Flags;
|
||||||
|
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.junit.MockitoJUnit;
|
||||||
|
import org.mockito.junit.MockitoRule;
|
||||||
|
import org.robolectric.RobolectricTestRunner;
|
||||||
|
import org.robolectric.annotation.Config;
|
||||||
|
import org.robolectric.shadow.api.Shadow;
|
||||||
|
import org.robolectric.util.ReflectionHelpers;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
@RunWith(RobolectricTestRunner.class)
|
||||||
|
@Config(
|
||||||
|
shadows = {
|
||||||
|
ShadowBluetoothAdapter.class,
|
||||||
|
ShadowBluetoothUtils.class,
|
||||||
|
ShadowAudioStreamsHelper.class,
|
||||||
|
})
|
||||||
|
public class AudioStreamMediaServiceTest {
|
||||||
|
@Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule();
|
||||||
|
@Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
|
||||||
|
@Mock private Resources mResources;
|
||||||
|
@Mock private LocalBluetoothManager mLocalBtManager;
|
||||||
|
@Mock private LocalBluetoothLeBroadcastAssistant mLeBroadcastAssistant;
|
||||||
|
@Mock private AudioStreamsHelper mAudioStreamsHelper;
|
||||||
|
@Mock private NotificationManager mNotificationManager;
|
||||||
|
@Mock private MediaSessionManager mMediaSessionManager;
|
||||||
|
@Mock private BluetoothEventManager mBluetoothEventManager;
|
||||||
|
@Mock private LocalBluetoothProfileManager mLocalBluetoothProfileManager;
|
||||||
|
@Mock private VolumeControlProfile mVolumeControlProfile;
|
||||||
|
@Mock private BluetoothDevice mDevice;
|
||||||
|
@Mock private ISession mISession;
|
||||||
|
@Mock private ISessionController mISessionController;
|
||||||
|
@Mock private PackageManager mPackageManager;
|
||||||
|
@Mock private DisplayMetrics mDisplayMetrics;
|
||||||
|
@Mock private Context mContext;
|
||||||
|
private AudioStreamMediaService mAudioStreamMediaService;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
ShadowAudioStreamsHelper.setUseMock(mAudioStreamsHelper);
|
||||||
|
when(mAudioStreamsHelper.getLeBroadcastAssistant()).thenReturn(mLeBroadcastAssistant);
|
||||||
|
ShadowBluetoothAdapter shadowBluetoothAdapter =
|
||||||
|
Shadow.extract(BluetoothAdapter.getDefaultAdapter());
|
||||||
|
shadowBluetoothAdapter.setEnabled(true);
|
||||||
|
shadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported(
|
||||||
|
BluetoothStatusCodes.FEATURE_SUPPORTED);
|
||||||
|
shadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported(
|
||||||
|
BluetoothStatusCodes.FEATURE_SUPPORTED);
|
||||||
|
ShadowBluetoothUtils.sLocalBluetoothManager = mLocalBtManager;
|
||||||
|
when(mLocalBtManager.getEventManager()).thenReturn(mBluetoothEventManager);
|
||||||
|
when(mLocalBtManager.getProfileManager()).thenReturn(mLocalBluetoothProfileManager);
|
||||||
|
when(mLocalBluetoothProfileManager.getVolumeControlProfile())
|
||||||
|
.thenReturn(mVolumeControlProfile);
|
||||||
|
|
||||||
|
mAudioStreamMediaService = spy(new AudioStreamMediaService());
|
||||||
|
ReflectionHelpers.setField(mAudioStreamMediaService, "mBase", mContext);
|
||||||
|
when(mAudioStreamMediaService.getSystemService(anyString()))
|
||||||
|
.thenReturn(mMediaSessionManager);
|
||||||
|
when(mMediaSessionManager.createSession(any(), anyString(), any())).thenReturn(mISession);
|
||||||
|
try {
|
||||||
|
when(mISession.getController()).thenReturn(mISessionController);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
doReturn(mNotificationManager)
|
||||||
|
.when(mAudioStreamMediaService)
|
||||||
|
.getSystemService(NotificationManager.class);
|
||||||
|
when(mAudioStreamMediaService.getApplicationInfo()).thenReturn(new ApplicationInfo());
|
||||||
|
when(mAudioStreamMediaService.getResources()).thenReturn(mResources);
|
||||||
|
when(mAudioStreamMediaService.getPackageManager()).thenReturn(mPackageManager);
|
||||||
|
when(mResources.getDisplayMetrics()).thenReturn(mDisplayMetrics);
|
||||||
|
mDisplayMetrics.density = 1.5f;
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() {
|
||||||
|
mAudioStreamMediaService.stopSelf();
|
||||||
|
ShadowBluetoothUtils.reset();
|
||||||
|
ShadowAudioStreamsHelper.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onCreate_flagOff_doNothing() {
|
||||||
|
mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
||||||
|
|
||||||
|
mAudioStreamMediaService.onCreate();
|
||||||
|
|
||||||
|
verify(mNotificationManager, never()).createNotificationChannel(any());
|
||||||
|
verify(mBluetoothEventManager, never()).registerCallback(any());
|
||||||
|
verify(mLeBroadcastAssistant, never()).registerServiceCallBack(any(), any());
|
||||||
|
verify(mVolumeControlProfile, never()).registerCallback(any(), any());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onCreate_flagOn_init() {
|
||||||
|
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
||||||
|
|
||||||
|
mAudioStreamMediaService.onCreate();
|
||||||
|
|
||||||
|
verify(mNotificationManager).createNotificationChannel(any());
|
||||||
|
verify(mBluetoothEventManager).registerCallback(any());
|
||||||
|
verify(mLeBroadcastAssistant).registerServiceCallBack(any(), any());
|
||||||
|
verify(mVolumeControlProfile).registerCallback(any(), any());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onDestroy_flagOff_doNothing() {
|
||||||
|
mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
||||||
|
|
||||||
|
mAudioStreamMediaService.onCreate();
|
||||||
|
mAudioStreamMediaService.onDestroy();
|
||||||
|
|
||||||
|
verify(mBluetoothEventManager, never()).unregisterCallback(any());
|
||||||
|
verify(mLeBroadcastAssistant, never()).unregisterServiceCallBack(any());
|
||||||
|
verify(mVolumeControlProfile, never()).unregisterCallback(any());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onDestroy_flagOn_cleanup() {
|
||||||
|
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
||||||
|
|
||||||
|
mAudioStreamMediaService.onCreate();
|
||||||
|
mAudioStreamMediaService.onDestroy();
|
||||||
|
|
||||||
|
verify(mBluetoothEventManager).unregisterCallback(any());
|
||||||
|
verify(mLeBroadcastAssistant).unregisterServiceCallBack(any());
|
||||||
|
verify(mVolumeControlProfile).unregisterCallback(any());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onStartCommand_noBroadcastId_stopSelf() {
|
||||||
|
mAudioStreamMediaService.onStartCommand(new Intent(), /* flags= */ 0, /* startId= */ 0);
|
||||||
|
|
||||||
|
assertThat(mAudioStreamMediaService.mLocalSession).isNull();
|
||||||
|
verify(mAudioStreamMediaService).stopSelf();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onStartCommand_noDevice_stopSelf() {
|
||||||
|
Intent intent = new Intent();
|
||||||
|
intent.putExtra(BROADCAST_ID, 1);
|
||||||
|
|
||||||
|
mAudioStreamMediaService.onStartCommand(intent, /* flags= */ 0, /* startId= */ 0);
|
||||||
|
|
||||||
|
assertThat(mAudioStreamMediaService.mLocalSession).isNull();
|
||||||
|
verify(mAudioStreamMediaService).stopSelf();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onStartCommand_createSessionAndStartForeground() {
|
||||||
|
var devices = new ArrayList<BluetoothDevice>();
|
||||||
|
devices.add(mDevice);
|
||||||
|
|
||||||
|
Intent intent = new Intent();
|
||||||
|
intent.putExtra(BROADCAST_ID, 1);
|
||||||
|
intent.putParcelableArrayListExtra(DEVICES, devices);
|
||||||
|
|
||||||
|
mAudioStreamMediaService.onStartCommand(intent, /* flags= */ 0, /* startId= */ 0);
|
||||||
|
|
||||||
|
assertThat(mAudioStreamMediaService.mLocalSession).isNotNull();
|
||||||
|
verify(mAudioStreamMediaService, never()).stopSelf();
|
||||||
|
|
||||||
|
ArgumentCaptor<Notification> notification = ArgumentCaptor.forClass(Notification.class);
|
||||||
|
verify(mAudioStreamMediaService).startForeground(anyInt(), notification.capture());
|
||||||
|
assertThat(notification.getValue().getSmallIcon()).isNotNull();
|
||||||
|
assertThat(notification.getValue().isStyle(Notification.MediaStyle.class)).isTrue();
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,231 @@
|
|||||||
|
/*
|
||||||
|
* 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.settings.connecteddevice.audiosharing.audiostreams;
|
||||||
|
|
||||||
|
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
|
||||||
|
import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.Mockito.never;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
import static org.robolectric.Shadows.shadowOf;
|
||||||
|
|
||||||
|
import android.bluetooth.BluetoothAdapter;
|
||||||
|
import android.bluetooth.BluetoothStatusCodes;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Looper;
|
||||||
|
import android.platform.test.flag.junit.SetFlagsRule;
|
||||||
|
|
||||||
|
import androidx.lifecycle.LifecycleOwner;
|
||||||
|
import androidx.preference.Preference;
|
||||||
|
import androidx.preference.PreferenceScreen;
|
||||||
|
import androidx.test.core.app.ApplicationProvider;
|
||||||
|
|
||||||
|
import com.android.settings.bluetooth.Utils;
|
||||||
|
import com.android.settings.connecteddevice.audiosharing.audiostreams.testshadows.ShadowAudioStreamsHelper;
|
||||||
|
import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
|
||||||
|
import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
|
||||||
|
import com.android.settingslib.bluetooth.BluetoothEventManager;
|
||||||
|
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
|
||||||
|
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
|
||||||
|
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant;
|
||||||
|
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
||||||
|
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
|
||||||
|
import com.android.settingslib.bluetooth.VolumeControlProfile;
|
||||||
|
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||||
|
import com.android.settingslib.flags.Flags;
|
||||||
|
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.junit.MockitoJUnit;
|
||||||
|
import org.mockito.junit.MockitoRule;
|
||||||
|
import org.robolectric.RobolectricTestRunner;
|
||||||
|
import org.robolectric.annotation.Config;
|
||||||
|
import org.robolectric.shadow.api.Shadow;
|
||||||
|
|
||||||
|
@RunWith(RobolectricTestRunner.class)
|
||||||
|
@Config(
|
||||||
|
shadows = {
|
||||||
|
ShadowBluetoothAdapter.class,
|
||||||
|
ShadowBluetoothUtils.class,
|
||||||
|
ShadowAudioStreamsHelper.class,
|
||||||
|
})
|
||||||
|
public class AudioStreamsCategoryControllerTest {
|
||||||
|
private static final String KEY = "audio_streams_settings_category";
|
||||||
|
|
||||||
|
@Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule();
|
||||||
|
@Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
|
||||||
|
|
||||||
|
private final Context mContext = ApplicationProvider.getApplicationContext();
|
||||||
|
@Mock private LocalBluetoothManager mLocalBtManager;
|
||||||
|
@Mock private LocalBluetoothProfileManager mBtProfileManager;
|
||||||
|
@Mock private BluetoothEventManager mBluetoothEventManager;
|
||||||
|
@Mock private LocalBluetoothLeBroadcast mBroadcast;
|
||||||
|
@Mock private LocalBluetoothLeBroadcastAssistant mAssistant;
|
||||||
|
@Mock private VolumeControlProfile mVolumeControl;
|
||||||
|
@Mock private PreferenceScreen mScreen;
|
||||||
|
@Mock private AudioStreamsHelper mAudioStreamsHelper;
|
||||||
|
@Mock private CachedBluetoothDevice mCachedBluetoothDevice;
|
||||||
|
|
||||||
|
private AudioStreamsCategoryController mController;
|
||||||
|
private Lifecycle mLifecycle;
|
||||||
|
private LifecycleOwner mLifecycleOwner;
|
||||||
|
private ShadowBluetoothAdapter mShadowBluetoothAdapter;
|
||||||
|
private LocalBluetoothManager mLocalBluetoothManager;
|
||||||
|
private Preference mPreference;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
ShadowAudioStreamsHelper.setUseMock(mAudioStreamsHelper);
|
||||||
|
mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter());
|
||||||
|
mShadowBluetoothAdapter.setEnabled(true);
|
||||||
|
mShadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported(
|
||||||
|
BluetoothStatusCodes.FEATURE_SUPPORTED);
|
||||||
|
mShadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported(
|
||||||
|
BluetoothStatusCodes.FEATURE_SUPPORTED);
|
||||||
|
mLifecycleOwner = () -> mLifecycle;
|
||||||
|
mLifecycle = new Lifecycle(mLifecycleOwner);
|
||||||
|
ShadowBluetoothUtils.sLocalBluetoothManager = mLocalBtManager;
|
||||||
|
mLocalBluetoothManager = Utils.getLocalBtManager(mContext);
|
||||||
|
when(mLocalBluetoothManager.getEventManager()).thenReturn(mBluetoothEventManager);
|
||||||
|
when(mLocalBluetoothManager.getProfileManager()).thenReturn(mBtProfileManager);
|
||||||
|
when(mBtProfileManager.getLeAudioBroadcastProfile()).thenReturn(mBroadcast);
|
||||||
|
when(mBtProfileManager.getLeAudioBroadcastAssistantProfile()).thenReturn(mAssistant);
|
||||||
|
when(mBtProfileManager.getVolumeControlProfile()).thenReturn(mVolumeControl);
|
||||||
|
when(mBroadcast.isProfileReady()).thenReturn(true);
|
||||||
|
when(mAssistant.isProfileReady()).thenReturn(true);
|
||||||
|
when(mVolumeControl.isProfileReady()).thenReturn(true);
|
||||||
|
mController = new AudioStreamsCategoryController(mContext, KEY);
|
||||||
|
mPreference = new Preference(mContext);
|
||||||
|
when(mScreen.findPreference(KEY)).thenReturn(mPreference);
|
||||||
|
mController.displayPreference(mScreen);
|
||||||
|
mPreference.setVisible(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() {
|
||||||
|
ShadowAudioStreamsHelper.reset();
|
||||||
|
ShadowBluetoothUtils.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getAvailabilityStatus_flagOn() {
|
||||||
|
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_QR_CODE_PRIVATE_BROADCAST_SHARING);
|
||||||
|
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getAvailabilityStatus_flagOff() {
|
||||||
|
mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_QR_CODE_PRIVATE_BROADCAST_SHARING);
|
||||||
|
assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onStart_flagOff_doNothing() {
|
||||||
|
mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_QR_CODE_PRIVATE_BROADCAST_SHARING);
|
||||||
|
mController.onStart(mLifecycleOwner);
|
||||||
|
verify(mBluetoothEventManager, never()).registerCallback(any());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onStart_flagOn_registerCallback() {
|
||||||
|
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_QR_CODE_PRIVATE_BROADCAST_SHARING);
|
||||||
|
mController.onStart(mLifecycleOwner);
|
||||||
|
verify(mBluetoothEventManager).registerCallback(any());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onStop_flagOff_doNothing() {
|
||||||
|
mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_QR_CODE_PRIVATE_BROADCAST_SHARING);
|
||||||
|
mController.onStop(mLifecycleOwner);
|
||||||
|
verify(mBluetoothEventManager, never()).unregisterCallback(any());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onStop_flagOn_unregisterCallback() {
|
||||||
|
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_QR_CODE_PRIVATE_BROADCAST_SHARING);
|
||||||
|
mController.onStop(mLifecycleOwner);
|
||||||
|
verify(mBluetoothEventManager).unregisterCallback(any());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void updateVisibility_flagOff_invisible() {
|
||||||
|
mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_QR_CODE_PRIVATE_BROADCAST_SHARING);
|
||||||
|
mController.updateVisibility();
|
||||||
|
shadowOf(Looper.getMainLooper()).idle();
|
||||||
|
assertThat(mPreference.isVisible()).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void updateVisibility_noConnectedLe_invisible() {
|
||||||
|
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_QR_CODE_PRIVATE_BROADCAST_SHARING);
|
||||||
|
mController.updateVisibility();
|
||||||
|
shadowOf(Looper.getMainLooper()).idle();
|
||||||
|
assertThat(mPreference.isVisible()).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void updateVisibility_isNotProfileReady_invisible() {
|
||||||
|
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_QR_CODE_PRIVATE_BROADCAST_SHARING);
|
||||||
|
ShadowAudioStreamsHelper.setCachedBluetoothDeviceInSharingOrLeConnected(
|
||||||
|
mCachedBluetoothDevice);
|
||||||
|
when(mVolumeControl.isProfileReady()).thenReturn(false);
|
||||||
|
mController.updateVisibility();
|
||||||
|
shadowOf(Looper.getMainLooper()).idle();
|
||||||
|
assertThat(mPreference.isVisible()).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void updateVisibility_isBroadcasting_invisible() {
|
||||||
|
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_QR_CODE_PRIVATE_BROADCAST_SHARING);
|
||||||
|
ShadowAudioStreamsHelper.setCachedBluetoothDeviceInSharingOrLeConnected(
|
||||||
|
mCachedBluetoothDevice);
|
||||||
|
when(mBroadcast.isEnabled(any())).thenReturn(true);
|
||||||
|
mController.updateVisibility();
|
||||||
|
shadowOf(Looper.getMainLooper()).idle();
|
||||||
|
assertThat(mPreference.isVisible()).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void updateVisibility_isBluetoothOff_invisible() {
|
||||||
|
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_QR_CODE_PRIVATE_BROADCAST_SHARING);
|
||||||
|
ShadowAudioStreamsHelper.setCachedBluetoothDeviceInSharingOrLeConnected(
|
||||||
|
mCachedBluetoothDevice);
|
||||||
|
mShadowBluetoothAdapter.setEnabled(false);
|
||||||
|
mController.updateVisibility();
|
||||||
|
shadowOf(Looper.getMainLooper()).idle();
|
||||||
|
assertThat(mPreference.isVisible()).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void updateVisibility_visible() {
|
||||||
|
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_QR_CODE_PRIVATE_BROADCAST_SHARING);
|
||||||
|
ShadowAudioStreamsHelper.setCachedBluetoothDeviceInSharingOrLeConnected(
|
||||||
|
mCachedBluetoothDevice);
|
||||||
|
mController.displayPreference(mScreen);
|
||||||
|
mController.updateVisibility();
|
||||||
|
shadowOf(Looper.getMainLooper()).idle();
|
||||||
|
assertThat(mPreference.isVisible()).isTrue();
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,125 @@
|
|||||||
|
/*
|
||||||
|
* 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.settings.connecteddevice.audiosharing.audiostreams;
|
||||||
|
|
||||||
|
import static com.android.settings.connecteddevice.audiosharing.audiostreams.AudioStreamsDashboardFragment.KEY_BROADCAST_METADATA;
|
||||||
|
import static com.android.settings.connecteddevice.audiosharing.audiostreams.AudioStreamsScanQrCodeController.REQUEST_SCAN_BT_BROADCAST_QR_CODE;
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.Mockito.doReturn;
|
||||||
|
import static org.mockito.Mockito.never;
|
||||||
|
import static org.mockito.Mockito.spy;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
|
||||||
|
import androidx.test.core.app.ApplicationProvider;
|
||||||
|
|
||||||
|
import com.android.settings.R;
|
||||||
|
import com.android.settingslib.core.AbstractPreferenceController;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.junit.MockitoJUnit;
|
||||||
|
import org.mockito.junit.MockitoRule;
|
||||||
|
import org.robolectric.RobolectricTestRunner;
|
||||||
|
|
||||||
|
@RunWith(RobolectricTestRunner.class)
|
||||||
|
public class AudioStreamsDashboardFragmentTest {
|
||||||
|
|
||||||
|
@Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule();
|
||||||
|
private static final String VALID_METADATA =
|
||||||
|
"BLUETOOTH:UUID:184F;BN:VGVzdA==;AT:1;AD:00A1A1A1A1A1;BI:1E240;BC:VGVzdENvZGU=;"
|
||||||
|
+ "MD:BgNwVGVzdA==;AS:1;PI:A0;NS:1;BS:3;NB:2;SM:BQNUZXN0BARlbmc=;;";
|
||||||
|
|
||||||
|
private Context mContext;
|
||||||
|
private AudioStreamsProgressCategoryController mController;
|
||||||
|
private TestFragment mTestFragment;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
mContext = ApplicationProvider.getApplicationContext();
|
||||||
|
mTestFragment = spy(new TestFragment());
|
||||||
|
doReturn(mContext).when(mTestFragment).getContext();
|
||||||
|
mController = spy(new AudioStreamsProgressCategoryController(mContext, "key"));
|
||||||
|
doReturn(mController).when(mTestFragment).use(AudioStreamsProgressCategoryController.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getPreferenceScreenResId_returnsCorrectXml() {
|
||||||
|
assertThat(mTestFragment.getPreferenceScreenResId())
|
||||||
|
.isEqualTo(R.xml.bluetooth_le_audio_streams);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getLogTag_returnsCorrectTag() {
|
||||||
|
assertThat(mTestFragment.getLogTag()).isEqualTo("AudioStreamsDashboardFrag");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getHelpResource_returnsCorrectResource() {
|
||||||
|
assertThat(mTestFragment.getHelpResource()).isEqualTo(R.string.help_url_audio_sharing);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onActivityResult_invalidRequestCode_doNothing() {
|
||||||
|
mTestFragment.onAttach(mContext);
|
||||||
|
|
||||||
|
mTestFragment.onActivityResult(0, 0, null);
|
||||||
|
verify(mController, never()).setSourceFromQrCode(any(), any());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onActivityResult_invalidRequestResult_doNothing() {
|
||||||
|
mTestFragment.onAttach(mContext);
|
||||||
|
|
||||||
|
mTestFragment.onActivityResult(REQUEST_SCAN_BT_BROADCAST_QR_CODE, 0, null);
|
||||||
|
verify(mController, never()).setSourceFromQrCode(any(), any());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onActivityResult_nullData_doNothing() {
|
||||||
|
mTestFragment.onAttach(mContext);
|
||||||
|
|
||||||
|
mTestFragment.onActivityResult(REQUEST_SCAN_BT_BROADCAST_QR_CODE, Activity.RESULT_OK, null);
|
||||||
|
verify(mController, never()).setSourceFromQrCode(any(), any());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onActivityResult_setSourceFromQrCode() {
|
||||||
|
mTestFragment.onAttach(mContext);
|
||||||
|
Intent intent = new Intent();
|
||||||
|
intent.putExtra(KEY_BROADCAST_METADATA, VALID_METADATA);
|
||||||
|
|
||||||
|
mTestFragment.onActivityResult(
|
||||||
|
REQUEST_SCAN_BT_BROADCAST_QR_CODE, Activity.RESULT_OK, intent);
|
||||||
|
verify(mController).setSourceFromQrCode(any(), any());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class TestFragment extends AudioStreamsDashboardFragment {
|
||||||
|
@Override
|
||||||
|
protected <T extends AbstractPreferenceController> T use(Class<T> clazz) {
|
||||||
|
return super.use(clazz);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
* 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.settings.connecteddevice.audiosharing.audiostreams;
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
import static org.mockito.Mockito.spy;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import androidx.preference.PreferenceManager;
|
||||||
|
import androidx.test.core.app.ApplicationProvider;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.junit.MockitoJUnit;
|
||||||
|
import org.mockito.junit.MockitoRule;
|
||||||
|
import org.robolectric.RobolectricTestRunner;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
|
||||||
|
@RunWith(RobolectricTestRunner.class)
|
||||||
|
public class AudioStreamsProgressCategoryPreferenceTest {
|
||||||
|
@Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule();
|
||||||
|
@Mock PreferenceManager mPreferenceManager;
|
||||||
|
private Context mContext;
|
||||||
|
private AudioStreamsProgressCategoryPreference mPreference;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
mContext = ApplicationProvider.getApplicationContext();
|
||||||
|
mPreference = spy(new AudioStreamsProgressCategoryPreference(mContext));
|
||||||
|
when(mPreference.getPreferenceManager()).thenReturn(mPreferenceManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void addAudioStreamPreference_singlePreference() {
|
||||||
|
AudioStreamPreference first = new AudioStreamPreference(mContext, null);
|
||||||
|
mPreference.addAudioStreamPreference(first, (p1, p2) -> 0);
|
||||||
|
|
||||||
|
assertThat(mPreference.getPreferenceCount()).isEqualTo(1);
|
||||||
|
assertThat(mPreference.getPreference(0)).isEqualTo(first);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void addAudioStreamPreference_multiPreference_sorted() {
|
||||||
|
Comparator<AudioStreamPreference> c =
|
||||||
|
Comparator.comparingInt(AudioStreamPreference::getOrder);
|
||||||
|
AudioStreamPreference first = new AudioStreamPreference(mContext, null);
|
||||||
|
first.setOrder(1);
|
||||||
|
AudioStreamPreference second = new AudioStreamPreference(mContext, null);
|
||||||
|
second.setOrder(0);
|
||||||
|
mPreference.addAudioStreamPreference(first, c);
|
||||||
|
mPreference.addAudioStreamPreference(second, c);
|
||||||
|
|
||||||
|
assertThat(mPreference.getPreferenceCount()).isEqualTo(2);
|
||||||
|
assertThat(mPreference.getPreference(0)).isEqualTo(second);
|
||||||
|
assertThat(mPreference.getPreference(1)).isEqualTo(first);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void removeAudioStreamPreferences_shouldBeEmpty() {
|
||||||
|
Comparator<AudioStreamPreference> c =
|
||||||
|
Comparator.comparingInt(AudioStreamPreference::getOrder);
|
||||||
|
AudioStreamPreference first = new AudioStreamPreference(mContext, null);
|
||||||
|
first.setOrder(0);
|
||||||
|
AudioStreamPreference second = new AudioStreamPreference(mContext, null);
|
||||||
|
second.setOrder(1);
|
||||||
|
mPreference.addAudioStreamPreference(first, c);
|
||||||
|
mPreference.addAudioStreamPreference(second, c);
|
||||||
|
mPreference.removeAudioStreamPreferences();
|
||||||
|
|
||||||
|
assertThat(mPreference.getPreferenceCount()).isEqualTo(0);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,98 @@
|
|||||||
|
/*
|
||||||
|
* 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.settings.connecteddevice.audiosharing.audiostreams;
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyString;
|
||||||
|
import static org.mockito.Mockito.doReturn;
|
||||||
|
import static org.mockito.Mockito.spy;
|
||||||
|
|
||||||
|
import android.bluetooth.BluetoothLeBroadcastMetadata;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
|
||||||
|
import androidx.test.core.app.ApplicationProvider;
|
||||||
|
|
||||||
|
import com.android.settingslib.bluetooth.BluetoothLeBroadcastMetadataExt;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.junit.MockitoJUnit;
|
||||||
|
import org.mockito.junit.MockitoRule;
|
||||||
|
import org.robolectric.RobolectricTestRunner;
|
||||||
|
|
||||||
|
@RunWith(RobolectricTestRunner.class)
|
||||||
|
public class AudioStreamsRepositoryTest {
|
||||||
|
@Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule();
|
||||||
|
private static final String METADATA_STR =
|
||||||
|
"BLUETOOTH:UUID:184F;BN:VGVzdA==;AT:1;AD:00A1A1A1A1A1;BI:1E240;BC:VGVzdENvZGU=;"
|
||||||
|
+ "MD:BgNwVGVzdA==;AS:1;PI:A0;NS:1;BS:3;NB:2;SM:BQNUZXN0BARlbmc=;;";
|
||||||
|
private static final String TEST_SHARED_PREFERENCE = "AudioStreamsRepositoryTestPref";
|
||||||
|
private final BluetoothLeBroadcastMetadata mMetadata =
|
||||||
|
BluetoothLeBroadcastMetadataExt.INSTANCE.convertToBroadcastMetadata(METADATA_STR);
|
||||||
|
private Context mContext;
|
||||||
|
private AudioStreamsRepository mAudioStreamsRepository;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
mContext = spy(ApplicationProvider.getApplicationContext());
|
||||||
|
doReturn(getSharedPreferences()).when(mContext).getSharedPreferences(anyString(), anyInt());
|
||||||
|
mAudioStreamsRepository = AudioStreamsRepository.getInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void cacheAndGetMetadata_sameId() {
|
||||||
|
mAudioStreamsRepository.cacheMetadata(mMetadata);
|
||||||
|
|
||||||
|
assertThat(mMetadata).isNotNull();
|
||||||
|
assertThat(mAudioStreamsRepository.getCachedMetadata(mMetadata.getBroadcastId()))
|
||||||
|
.isEqualTo(mMetadata);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void cacheAndGetMetadata_differentId() {
|
||||||
|
mAudioStreamsRepository.cacheMetadata(mMetadata);
|
||||||
|
|
||||||
|
assertThat(mMetadata).isNotNull();
|
||||||
|
assertThat(mAudioStreamsRepository.getCachedMetadata(1)).isNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void saveAndGetMetadata_sameId() {
|
||||||
|
mAudioStreamsRepository.saveMetadata(mContext, mMetadata);
|
||||||
|
|
||||||
|
assertThat(mMetadata).isNotNull();
|
||||||
|
assertThat(mAudioStreamsRepository.getSavedMetadata(mContext, mMetadata.getBroadcastId()))
|
||||||
|
.isEqualTo(mMetadata);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void saveAndGetMetadata_differentId() {
|
||||||
|
mAudioStreamsRepository.saveMetadata(mContext, mMetadata);
|
||||||
|
|
||||||
|
assertThat(mMetadata).isNotNull();
|
||||||
|
assertThat(mAudioStreamsRepository.getSavedMetadata(mContext, 1)).isNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
private SharedPreferences getSharedPreferences() {
|
||||||
|
return mContext.getSharedPreferences(TEST_SHARED_PREFERENCE, Context.MODE_PRIVATE);
|
||||||
|
}
|
||||||
|
}
|
@@ -22,6 +22,7 @@ import androidx.annotation.Nullable;
|
|||||||
|
|
||||||
import com.android.settings.connecteddevice.audiosharing.audiostreams.AudioStreamsHelper;
|
import com.android.settings.connecteddevice.audiosharing.audiostreams.AudioStreamsHelper;
|
||||||
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
|
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
|
||||||
|
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant;
|
||||||
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
||||||
|
|
||||||
import org.robolectric.annotation.Implementation;
|
import org.robolectric.annotation.Implementation;
|
||||||
@@ -63,4 +64,9 @@ public class ShadowAudioStreamsHelper {
|
|||||||
LocalBluetoothManager manager) {
|
LocalBluetoothManager manager) {
|
||||||
return Optional.ofNullable(sCachedBluetoothDevice);
|
return Optional.ofNullable(sCachedBluetoothDevice);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Implementation
|
||||||
|
public LocalBluetoothLeBroadcastAssistant getLeBroadcastAssistant() {
|
||||||
|
return sMockHelper.getLeBroadcastAssistant();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user