From 83ec0a30f395dfab03880df827fb74a9f6f5c55c Mon Sep 17 00:00:00 2001 From: chelseahao Date: Mon, 20 May 2024 17:29:07 +0800 Subject: [PATCH] [Audiosharing] Add tests. Test: atest -c com.android.settings.connecteddevice.audiosharing.audiostreams Bug: 308368124 Change-Id: I8fc458d37cc3456085e1017ca0e6ca86cdae1a9c --- .../AudioStreamDetailsFragment.java | 4 +- .../audiostreams/AudioStreamPreference.java | 4 +- .../AudioStreamConfirmDialogActivityTest.java | 45 +++++ .../AudioStreamDetailsFragmentTest.java | 47 +++++ .../AudioStreamPreferenceTest.java | 172 ++++++++++++++++++ ...udioStreamsActiveDeviceControllerTest.java | 71 ++++++++ ...StreamsActiveDeviceSummaryUpdaterTest.java | 98 ++++++++++ 7 files changed, 439 insertions(+), 2 deletions(-) create mode 100644 tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamConfirmDialogActivityTest.java create mode 100644 tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamDetailsFragmentTest.java create mode 100644 tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamPreferenceTest.java create mode 100644 tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsActiveDeviceControllerTest.java create mode 100644 tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsActiveDeviceSummaryUpdaterTest.java diff --git a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamDetailsFragment.java b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamDetailsFragment.java index 94e6644f2a9..1f71b73e379 100644 --- a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamDetailsFragment.java +++ b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamDetailsFragment.java @@ -19,13 +19,15 @@ package com.android.settings.connecteddevice.audiosharing.audiostreams; import android.content.Context; import android.os.Bundle; +import androidx.annotation.VisibleForTesting; + import com.android.settings.R; import com.android.settings.dashboard.DashboardFragment; public class AudioStreamDetailsFragment extends DashboardFragment { static final String BROADCAST_NAME_ARG = "broadcast_name"; static final String BROADCAST_ID_ARG = "broadcast_id"; - private static final String TAG = "AudioStreamDetailsFragment"; + @VisibleForTesting static final String TAG = "AudioStreamDetailsFragment"; @Override public void onAttach(Context context) { diff --git a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamPreference.java b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamPreference.java index 0334e055036..ab9612529dd 100644 --- a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamPreference.java +++ b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamPreference.java @@ -23,6 +23,7 @@ import android.util.AttributeSet; import android.view.View; import androidx.annotation.Nullable; +import androidx.annotation.VisibleForTesting; import androidx.preference.PreferenceViewHolder; import com.android.settings.R; @@ -60,7 +61,8 @@ class AudioStreamPreference extends TwoTargetPreference { notifyChanged(); } - private AudioStreamPreference(Context context, @Nullable AttributeSet attrs) { + @VisibleForTesting + AudioStreamPreference(Context context, @Nullable AttributeSet attrs) { super(context, attrs); setIcon(com.android.settingslib.R.drawable.ic_bt_le_audio_sharing); } diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamConfirmDialogActivityTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamConfirmDialogActivityTest.java new file mode 100644 index 00000000000..e967a12bb1c --- /dev/null +++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamConfirmDialogActivityTest.java @@ -0,0 +1,45 @@ +/* + * 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 org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.Robolectric; +import org.robolectric.RobolectricTestRunner; + +@RunWith(RobolectricTestRunner.class) +public class AudioStreamConfirmDialogActivityTest { + private AudioStreamConfirmDialogActivity mActivity; + + @Before + public void setUp() { + mActivity = Robolectric.buildActivity(AudioStreamConfirmDialogActivity.class).get(); + } + + @Test + public void isValidFragment_returnsTrue() { + assertThat(mActivity.isValidFragment(AudioStreamConfirmDialog.class.getName())).isTrue(); + } + + @Test + public void isValidFragment_returnsFalse() { + assertThat(mActivity.isValidFragment("")).isFalse(); + } +} diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamDetailsFragmentTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamDetailsFragmentTest.java new file mode 100644 index 00000000000..724c7721f11 --- /dev/null +++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamDetailsFragmentTest.java @@ -0,0 +1,47 @@ +/* + * 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 com.android.settings.R; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; + +@RunWith(RobolectricTestRunner.class) +public class AudioStreamDetailsFragmentTest { + private AudioStreamDetailsFragment mFragment; + + @Before + public void setUp() { + mFragment = new AudioStreamDetailsFragment(); + } + + @Test + public void getPreferenceScreenResId_returnsCorrectXml() { + assertThat(mFragment.getPreferenceScreenResId()) + .isEqualTo(R.xml.bluetooth_le_audio_stream_details_fragment); + } + + @Test + public void getLogTag_returnsCorrectTag() { + assertThat(mFragment.getLogTag()).isEqualTo(AudioStreamDetailsFragment.TAG); + } +} diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamPreferenceTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamPreferenceTest.java new file mode 100644 index 00000000000..0c93e3e1879 --- /dev/null +++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamPreferenceTest.java @@ -0,0 +1,172 @@ +/* + * 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.mock; +import static org.mockito.Mockito.when; + +import android.bluetooth.BluetoothLeAudioContentMetadata; +import android.bluetooth.BluetoothLeBroadcastMetadata; +import android.bluetooth.BluetoothLeBroadcastReceiveState; +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; + +import androidx.preference.Preference.OnPreferenceClickListener; +import androidx.preference.PreferenceViewHolder; + +import com.android.settings.R; +import com.android.settings.connecteddevice.audiosharing.audiostreams.AudioStreamsProgressCategoryController.AudioStreamState; + +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.RuntimeEnvironment; + +import java.util.Collections; + +@RunWith(RobolectricTestRunner.class) +public class AudioStreamPreferenceTest { + private static final int BROADCAST_ID = 1; + private static final String BROADCAST_NAME = "broadcast_name"; + private static final String PROGRAM_NAME = "program_name"; + private static final int BROADCAST_RSSI = 1; + @Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule(); + private Context mContext; + private AudioStreamPreference mPreference; + @Mock private BluetoothLeBroadcastMetadata mBluetoothLeBroadcastMetadata; + @Mock private BluetoothLeBroadcastReceiveState mBluetoothLeBroadcastReceiveState; + @Mock private BluetoothLeAudioContentMetadata mBluetoothLeAudioContentMetadata; + + @Before + public void setUp() { + mContext = RuntimeEnvironment.application; + mPreference = new AudioStreamPreference(mContext, null); + when(mBluetoothLeBroadcastMetadata.getBroadcastId()).thenReturn(BROADCAST_ID); + when(mBluetoothLeBroadcastMetadata.getBroadcastName()).thenReturn(BROADCAST_NAME); + when(mBluetoothLeBroadcastMetadata.getRssi()).thenReturn(BROADCAST_RSSI); + when(mBluetoothLeBroadcastReceiveState.getBroadcastId()).thenReturn(BROADCAST_ID); + when(mBluetoothLeBroadcastReceiveState.getSubgroupMetadata()) + .thenReturn(Collections.singletonList(mBluetoothLeAudioContentMetadata)); + when(mBluetoothLeAudioContentMetadata.getProgramInfo()).thenReturn(PROGRAM_NAME); + } + + @Test + public void createNewPreference_shouldSetIcon() { + assertThat(mPreference.getIcon()).isNotNull(); + } + + @Test + public void onBind_shouldHideDivider() { + PreferenceViewHolder holder = + PreferenceViewHolder.createInstanceForTests( + LayoutInflater.from(mContext) + .inflate(mPreference.getLayoutResource(), null)); + View divider = + holder.findViewById( + com.android.settingslib.widget.preference.twotarget.R.id + .two_target_divider); + assertThat(divider).isNotNull(); + + mPreference.onBindViewHolder(holder); + + assertThat(divider.getVisibility()).isEqualTo(View.GONE); + } + + @Test + public void setConnected_shouldUpdatePreferenceUI() { + String summary = "Connected"; + OnPreferenceClickListener listener = mock(OnPreferenceClickListener.class); + mPreference.setIsConnected(true, summary, listener); + + assertThat(mPreference.getSummary()).isNotNull(); + assertThat(mPreference.getSummary().toString()).isEqualTo(summary); + assertThat(mPreference.getOnPreferenceClickListener()).isEqualTo(listener); + } + + @Test + public void setAudioStreamMetadata_shouldUpdateMetadata() { + AudioStreamPreference p = + AudioStreamPreference.fromMetadata(mContext, mBluetoothLeBroadcastMetadata); + BluetoothLeBroadcastMetadata metadata = mock(BluetoothLeBroadcastMetadata.class); + p.setAudioStreamMetadata(metadata); + + assertThat(p.getAudioStreamMetadata()).isEqualTo(metadata); + } + + @Test + public void setAudioStreamState_shouldUpdateState() { + AudioStreamPreference p = + AudioStreamPreference.fromMetadata(mContext, mBluetoothLeBroadcastMetadata); + AudioStreamState state = AudioStreamState.SOURCE_ADDED; + p.setAudioStreamState(state); + + assertThat(p.getAudioStreamState()).isEqualTo(state); + } + + @Test + public void fromMetadata_shouldReturnBroadcastInfo() { + AudioStreamPreference p = + AudioStreamPreference.fromMetadata(mContext, mBluetoothLeBroadcastMetadata); + assertThat(p.getAudioStreamBroadcastId()).isEqualTo(BROADCAST_ID); + assertThat(p.getAudioStreamBroadcastName()).isEqualTo(BROADCAST_NAME); + assertThat(p.getAudioStreamRssi()).isEqualTo(BROADCAST_RSSI); + } + + @Test + public void fromReceiveState_shouldReturnBroadcastInfo() { + AudioStreamPreference p = + AudioStreamPreference.fromReceiveState(mContext, mBluetoothLeBroadcastReceiveState); + assertThat(p.getAudioStreamBroadcastId()).isEqualTo(BROADCAST_ID); + assertThat(p.getAudioStreamBroadcastName()).isEqualTo(PROGRAM_NAME); + assertThat(p.getAudioStreamRssi()).isEqualTo(Integer.MAX_VALUE); + } + + @Test + public void shouldHideSecondTarget_connected() { + mPreference.setIsConnected(true, "", null); + assertThat(mPreference.shouldHideSecondTarget()).isTrue(); + } + + @Test + public void shouldHideSecondTarget_notEncrypted() { + when(mBluetoothLeBroadcastMetadata.isEncrypted()).thenReturn(false); + AudioStreamPreference p = + AudioStreamPreference.fromMetadata(mContext, mBluetoothLeBroadcastMetadata); + assertThat(p.shouldHideSecondTarget()).isTrue(); + } + + @Test + public void shouldShowSecondTarget_encrypted() { + when(mBluetoothLeBroadcastMetadata.isEncrypted()).thenReturn(true); + AudioStreamPreference p = + AudioStreamPreference.fromMetadata(mContext, mBluetoothLeBroadcastMetadata); + assertThat(p.shouldHideSecondTarget()).isFalse(); + } + + @Test + public void secondTargetResId_shouldReturnLockLayoutId() { + assertThat(mPreference.getSecondTargetResId()).isEqualTo(R.layout.preference_widget_lock); + } +} diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsActiveDeviceControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsActiveDeviceControllerTest.java new file mode 100644 index 00000000000..c0296350db4 --- /dev/null +++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsActiveDeviceControllerTest.java @@ -0,0 +1,71 @@ +/* + * 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.google.common.truth.Truth.assertThat; + +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.content.Context; + +import androidx.preference.Preference; +import androidx.preference.PreferenceScreen; + +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.RuntimeEnvironment; + +@RunWith(RobolectricTestRunner.class) +public class AudioStreamsActiveDeviceControllerTest { + @Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule(); + private AudioStreamsActiveDeviceController mController; + @Mock private PreferenceScreen mScreen; + @Mock private Preference mPreference; + + @Before + public void setUp() { + Context context = RuntimeEnvironment.application; + mController = + new AudioStreamsActiveDeviceController( + context, AudioStreamsActiveDeviceController.KEY); + when(mScreen.findPreference(anyString())).thenReturn(mPreference); + } + + @Test + public void getAvailabilityStatus() { + assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE); + } + + @Test + public void onSummaryChanged_shouldSetPreferenceSummary() { + String summary = "summary"; + mController.displayPreference(mScreen); + mController.onSummaryChanged(summary); + + verify(mPreference).setSummary(summary); + } +} diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsActiveDeviceSummaryUpdaterTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsActiveDeviceSummaryUpdaterTest.java new file mode 100644 index 00000000000..3bcc9a3d079 --- /dev/null +++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsActiveDeviceSummaryUpdaterTest.java @@ -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.Mockito.when; + +import android.bluetooth.BluetoothProfile; +import android.content.Context; + +import androidx.annotation.Nullable; +import androidx.test.core.app.ApplicationProvider; + +import com.android.settings.R; +import com.android.settings.connecteddevice.audiosharing.audiostreams.testshadows.ShadowAudioStreamsHelper; +import com.android.settingslib.bluetooth.CachedBluetoothDevice; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Spy; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; + +@RunWith(RobolectricTestRunner.class) +@Config( + shadows = { + ShadowAudioStreamsHelper.class, + }) +public class AudioStreamsActiveDeviceSummaryUpdaterTest { + @Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule(); + private static final String DEVICE_NAME = "device_name"; + @Spy private final Context mContext = ApplicationProvider.getApplicationContext(); + private final AudioStreamsActiveDeviceSummaryUpdater.OnSummaryChangeListener mFakeListener = + summary -> mUpdatedSummary = summary; + @Mock private CachedBluetoothDevice mCachedBluetoothDevice; + @Mock private AudioStreamsHelper mAudioStreamsHelper; + private @Nullable String mUpdatedSummary; + private AudioStreamsActiveDeviceSummaryUpdater mUpdater; + + @Before + public void setUp() { + ShadowAudioStreamsHelper.setUseMock(mAudioStreamsHelper); + ShadowAudioStreamsHelper.resetCachedBluetoothDevice(); + mUpdater = new AudioStreamsActiveDeviceSummaryUpdater(mContext, mFakeListener); + } + + @Test + public void register_summaryUpdated() { + mUpdater.register(true); + + assertThat(mUpdatedSummary).isNotNull(); + } + + @Test + public void onActiveDeviceChanged_notLeProfile_doNothing() { + mUpdater.onActiveDeviceChanged(mCachedBluetoothDevice, 0); + + assertThat(mUpdatedSummary).isNull(); + } + + @Test + public void onActiveDeviceChanged_leProfile_summaryUpdated() { + ShadowAudioStreamsHelper.setCachedBluetoothDeviceInSharingOrLeConnected( + mCachedBluetoothDevice); + when(mCachedBluetoothDevice.getName()).thenReturn(DEVICE_NAME); + mUpdater.onActiveDeviceChanged(mCachedBluetoothDevice, BluetoothProfile.LE_AUDIO); + + assertThat(mUpdatedSummary).isEqualTo(DEVICE_NAME); + } + + @Test + public void onActiveDeviceChanged_leProfile_noDevice_summaryUpdated() { + mUpdater.onActiveDeviceChanged(mCachedBluetoothDevice, BluetoothProfile.LE_AUDIO); + + assertThat(mUpdatedSummary) + .isEqualTo(mContext.getString(R.string.audio_streams_dialog_no_le_device_title)); + } +}