1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.settings.notification; 18 19 import static com.android.settings.core.BasePreferenceController.AVAILABLE_UNSEARCHABLE; 20 import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE; 21 22 import static com.google.common.truth.Truth.assertThat; 23 24 import static org.mockito.Mockito.doReturn; 25 import static org.mockito.Mockito.mock; 26 import static org.mockito.Mockito.spy; 27 import static org.mockito.Mockito.when; 28 29 import android.content.Context; 30 import android.content.SharedPreferences; 31 import android.content.pm.ApplicationInfo; 32 import android.content.pm.PackageInfo; 33 import android.content.pm.PackageStats; 34 import android.media.MediaRoute2Info; 35 import android.media.MediaRouter2Manager; 36 import android.media.RoutingSessionInfo; 37 import android.media.session.MediaSessionManager; 38 39 import androidx.preference.Preference; 40 import androidx.preference.PreferenceCategory; 41 import androidx.preference.PreferenceManager; 42 import androidx.preference.PreferenceScreen; 43 44 import com.android.settings.R; 45 import com.android.settings.Utils; 46 import com.android.settings.testutils.shadow.ShadowBluetoothAdapter; 47 import com.android.settings.testutils.shadow.ShadowInteractionJankMonitor; 48 import com.android.settings.widget.SeekBarPreference; 49 import com.android.settingslib.media.LocalMediaManager; 50 51 import org.junit.Before; 52 import org.junit.Test; 53 import org.junit.runner.RunWith; 54 import org.mockito.Mock; 55 import org.mockito.MockitoAnnotations; 56 import org.robolectric.RobolectricTestRunner; 57 import org.robolectric.RuntimeEnvironment; 58 import org.robolectric.Shadows; 59 import org.robolectric.annotation.Config; 60 import org.robolectric.shadows.ShadowPackageManager; 61 62 import java.util.ArrayList; 63 import java.util.List; 64 65 @RunWith(RobolectricTestRunner.class) 66 @Config(shadows = {ShadowBluetoothAdapter.class, ShadowInteractionJankMonitor.class}) 67 public class RemoteVolumeGroupControllerTest { 68 69 private static final String KEY_REMOTE_VOLUME_GROUP = "remote_media_group"; 70 private static final String TEST_SESSION_1_ID = "test_session_1_id"; 71 private static final String TEST_SESSION_1_NAME = "test_session_1_name"; 72 private static final String TEST_PACKAGE_NAME = "com.test"; 73 private static final String TEST_APPLICATION_LABEL = "APP Test Label"; 74 private static final int CURRENT_VOLUME = 30; 75 private static final int MAX_VOLUME = 100; 76 77 @Mock 78 private LocalMediaManager mLocalMediaManager; 79 @Mock 80 private PreferenceScreen mScreen; 81 @Mock 82 private PreferenceManager mPreferenceManager; 83 @Mock 84 private SharedPreferences mSharedPreferences; 85 @Mock 86 private MediaSessionManager mMediaSessionManager; 87 @Mock 88 private MediaRouter2Manager mRouterManager; 89 90 private final List<RoutingSessionInfo> mRoutingSessionInfos = new ArrayList<>(); 91 92 private Context mContext; 93 private RemoteVolumeGroupController mController; 94 private PreferenceCategory mPreferenceCategory; 95 private ShadowPackageManager mShadowPackageManager; 96 private ApplicationInfo mAppInfo; 97 private PackageInfo mPackageInfo; 98 private PackageStats mPackageStats; 99 100 @Before setUp()101 public void setUp() { 102 MockitoAnnotations.initMocks(this); 103 mContext = spy(RuntimeEnvironment.application); 104 doReturn(mMediaSessionManager).when(mContext).getSystemService( 105 Context.MEDIA_SESSION_SERVICE); 106 mController = 107 new RemoteVolumeGroupController( 108 mContext, KEY_REMOTE_VOLUME_GROUP, mLocalMediaManager, mRouterManager); 109 mPreferenceCategory = spy(new PreferenceCategory(mContext)); 110 mPreferenceCategory.setKey(mController.getPreferenceKey()); 111 112 when(mPreferenceCategory.getPreferenceManager()).thenReturn(mPreferenceManager); 113 when(mPreferenceManager.getSharedPreferences()).thenReturn(mSharedPreferences); 114 when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn( 115 mPreferenceCategory); 116 final RoutingSessionInfo remoteSessionInfo = mock(RoutingSessionInfo.class); 117 when(remoteSessionInfo.getId()).thenReturn(TEST_SESSION_1_ID); 118 when(remoteSessionInfo.getName()).thenReturn(TEST_SESSION_1_NAME); 119 when(remoteSessionInfo.getVolumeMax()).thenReturn(MAX_VOLUME); 120 when(remoteSessionInfo.getVolume()).thenReturn(CURRENT_VOLUME); 121 when(remoteSessionInfo.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME); 122 when(remoteSessionInfo.isSystemSession()).thenReturn(false); 123 mRoutingSessionInfos.add(remoteSessionInfo); 124 when(mLocalMediaManager.getRemoteRoutingSessions()).thenReturn(mRoutingSessionInfos); 125 } 126 127 @Test getAvailabilityStatus_withActiveSession_returnAvailableUnsearchable()128 public void getAvailabilityStatus_withActiveSession_returnAvailableUnsearchable() { 129 mController.displayPreference(mScreen); 130 131 assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE_UNSEARCHABLE); 132 } 133 134 @Test getAvailabilityStatus_noActiveSession_returnConditionallyUnavailable()135 public void getAvailabilityStatus_noActiveSession_returnConditionallyUnavailable() { 136 mRoutingSessionInfos.clear(); 137 mController.displayPreference(mScreen); 138 139 assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE); 140 } 141 142 @Test displayPreference_noActiveSession_checkPreferenceCount()143 public void displayPreference_noActiveSession_checkPreferenceCount() { 144 mRoutingSessionInfos.clear(); 145 mController.displayPreference(mScreen); 146 147 assertThat(mPreferenceCategory.getPreferenceCount()).isEqualTo(0); 148 } 149 150 @Test displayPreference_withActiveSession_checkPreferenceCount()151 public void displayPreference_withActiveSession_checkPreferenceCount() { 152 mController.displayPreference(mScreen); 153 154 assertThat(mPreferenceCategory.getPreferenceCount()).isEqualTo(2); 155 } 156 157 @Test displayPreference_withActiveSession_checkSeekBarTitle()158 public void displayPreference_withActiveSession_checkSeekBarTitle() { 159 mController.displayPreference(mScreen); 160 final Preference preference = mPreferenceCategory.findPreference(TEST_SESSION_1_ID); 161 162 assertThat(preference.getTitle()).isEqualTo(mContext.getText( 163 R.string.remote_media_volume_option_title)); 164 } 165 166 @Test displayPreference_withActiveSession_checkSeekBarMaxVolume()167 public void displayPreference_withActiveSession_checkSeekBarMaxVolume() { 168 mController.displayPreference(mScreen); 169 final SeekBarPreference preference = mPreferenceCategory.findPreference(TEST_SESSION_1_ID); 170 171 assertThat(preference.getMax()).isEqualTo(MAX_VOLUME); 172 } 173 174 @Test displayPreference_withActiveSession_checkSeekBarCurrentVolume()175 public void displayPreference_withActiveSession_checkSeekBarCurrentVolume() { 176 mController.displayPreference(mScreen); 177 final SeekBarPreference preference = mPreferenceCategory.findPreference(TEST_SESSION_1_ID); 178 179 assertThat(preference.getProgress()).isEqualTo(CURRENT_VOLUME); 180 } 181 182 @Test displayPreference_withActiveSession_checkSwitcherPreferenceTitle()183 public void displayPreference_withActiveSession_checkSwitcherPreferenceTitle() { 184 // Preference title needs media output to be enabled. 185 when(mRouterManager.getTransferableRoutes(TEST_PACKAGE_NAME)).thenReturn(List.of(mock( 186 MediaRoute2Info.class))); 187 188 initPackage(); 189 mShadowPackageManager.addPackage(mPackageInfo, mPackageStats); 190 mController.displayPreference(mScreen); 191 final Preference preference = mPreferenceCategory.findPreference( 192 RemoteVolumeGroupController.SWITCHER_PREFIX + TEST_SESSION_1_ID); 193 194 assertThat(preference.getTitle()).isEqualTo(mContext.getString( 195 R.string.media_output_label_title, Utils.getApplicationLabel(mContext, 196 TEST_PACKAGE_NAME))); 197 } 198 199 @Test displayPreference_withActiveSession_checkSwitcherPreferenceSummary()200 public void displayPreference_withActiveSession_checkSwitcherPreferenceSummary() { 201 mController.displayPreference(mScreen); 202 final Preference preference = mPreferenceCategory.findPreference( 203 RemoteVolumeGroupController.SWITCHER_PREFIX + TEST_SESSION_1_ID); 204 205 assertThat(preference.getSummary()).isEqualTo(TEST_SESSION_1_NAME); 206 } 207 initPackage()208 private void initPackage() { 209 mShadowPackageManager = Shadows.shadowOf(mContext.getPackageManager()); 210 mAppInfo = new ApplicationInfo(); 211 mAppInfo.flags = ApplicationInfo.FLAG_INSTALLED; 212 mAppInfo.packageName = TEST_PACKAGE_NAME; 213 mAppInfo.name = TEST_APPLICATION_LABEL; 214 mPackageInfo = new PackageInfo(); 215 mPackageInfo.packageName = TEST_PACKAGE_NAME; 216 mPackageInfo.applicationInfo = mAppInfo; 217 mPackageStats = new PackageStats(TEST_PACKAGE_NAME); 218 } 219 } 220