1 /* 2 * Copyright (C) 2017 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.bluetooth; 18 19 import android.app.Activity; 20 import android.content.Context; 21 import android.os.Bundle; 22 import android.view.View; 23 import android.view.ViewGroup; 24 import android.widget.CheckBox; 25 26 import com.android.settings.testutils.SettingsRobolectricTestRunner; 27 import com.android.settings.TestConfig; 28 import com.android.settings.testutils.shadow.ShadowEventLogWriter; 29 import com.android.settingslib.R; 30 import com.android.settingslib.bluetooth.A2dpProfile; 31 import com.android.settingslib.bluetooth.CachedBluetoothDevice; 32 import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager; 33 import com.android.settingslib.bluetooth.LocalBluetoothAdapter; 34 import com.android.settingslib.bluetooth.LocalBluetoothManager; 35 import com.android.settingslib.bluetooth.LocalBluetoothProfile; 36 import com.android.settingslib.bluetooth.LocalBluetoothProfileManager; 37 38 import org.junit.Before; 39 import org.junit.Test; 40 import org.junit.runner.RunWith; 41 import org.mockito.Mock; 42 import org.mockito.MockitoAnnotations; 43 import org.robolectric.annotation.Config; 44 import org.robolectric.util.FragmentTestUtil; 45 import org.robolectric.util.ReflectionHelpers; 46 import org.robolectric.RuntimeEnvironment; 47 48 import static com.google.common.truth.Truth.assertThat; 49 50 import static org.mockito.Matchers.any; 51 import static org.mockito.Matchers.eq; 52 import static org.mockito.Mockito.when; 53 import static org.mockito.Mockito.verify; 54 55 import java.util.ArrayList; 56 57 58 @RunWith(SettingsRobolectricTestRunner.class) 59 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION, shadows = { 60 ShadowEventLogWriter.class 61 }) 62 public class DeviceProfilesSettingsTest { 63 Context mContext; 64 @Mock Activity mActivity; 65 @Mock LocalBluetoothManager mManager; 66 @Mock LocalBluetoothAdapter mAdapter; 67 @Mock LocalBluetoothProfileManager mProfileManager; 68 @Mock CachedBluetoothDeviceManager mDeviceManager; 69 @Mock CachedBluetoothDevice mCachedDevice; 70 @Mock A2dpProfile mProfile; 71 72 ArrayList<LocalBluetoothProfile> mProfiles; 73 DeviceProfilesSettings mFragment; 74 75 @Before setUp()76 public void setUp() { 77 MockitoAnnotations.initMocks(this); 78 mContext = RuntimeEnvironment.application; 79 80 when(mProfile.getNameResource(any())).thenReturn(R.string.bluetooth_profile_a2dp); 81 mProfiles = new ArrayList<>(); 82 mProfiles.add(mProfile); 83 when(mCachedDevice.getConnectableProfiles()).thenReturn(mProfiles); 84 85 mFragment = new DeviceProfilesSettings(); 86 mFragment.setArguments(new Bundle()); 87 88 ReflectionHelpers.setStaticField(LocalBluetoothManager.class, "sInstance", mManager); 89 when(mManager.getCachedDeviceManager()).thenReturn(mDeviceManager); 90 when(mManager.getBluetoothAdapter()).thenReturn(mAdapter); 91 when(mManager.getProfileManager()).thenReturn(mProfileManager); 92 when(mProfileManager.getMapProfile()).thenReturn(null); 93 when(mDeviceManager.findDevice(any())).thenReturn(mCachedDevice); 94 } 95 96 @Test deviceHasHighQualityAudio()97 public void deviceHasHighQualityAudio() { 98 when(mProfile.supportsHighQualityAudio(any())).thenReturn(true); 99 when(mProfile.isHighQualityAudioEnabled(any())).thenReturn(true); 100 when(mProfile.isPreferred(any())).thenReturn(true); 101 FragmentTestUtil.startFragment(mFragment); 102 103 ViewGroup profilesGroup = mFragment.getDialog().findViewById(R.id.profiles_section); 104 CheckBox box = (CheckBox) profilesGroup.findViewWithTag( 105 DeviceProfilesSettings.HIGH_QUALITY_AUDIO_PREF_TAG); 106 assertThat(box).isNotNull(); 107 assertThat(box.getVisibility()).isEqualTo(View.VISIBLE); 108 assertThat(box.isEnabled()).isTrue(); 109 assertThat(box.isChecked()).isTrue(); 110 111 box.performClick(); 112 verify(mProfile).setHighQualityAudioEnabled(any(), eq(false)); 113 box.performClick(); 114 verify(mProfile).setHighQualityAudioEnabled(any(), eq(true)); 115 } 116 117 @Test busyDeviceDisablesControl()118 public void busyDeviceDisablesControl() { 119 when(mProfile.supportsHighQualityAudio(any())).thenReturn(true); 120 when(mProfile.isHighQualityAudioEnabled(any())).thenReturn(true); 121 when(mProfile.isPreferred(any())).thenReturn(true); 122 when(mCachedDevice.isBusy()).thenReturn(true); 123 FragmentTestUtil.startFragment(mFragment); 124 125 // Make sure that the high quality audio option is present but disabled when the device 126 // is busy. 127 ViewGroup profilesGroup = mFragment.getDialog().findViewById(R.id.profiles_section); 128 CheckBox box = (CheckBox) profilesGroup.findViewWithTag( 129 DeviceProfilesSettings.HIGH_QUALITY_AUDIO_PREF_TAG); 130 assertThat(box).isNotNull(); 131 assertThat(box.getVisibility()).isEqualTo(View.VISIBLE); 132 assertThat(box.isEnabled()).isFalse(); 133 } 134 135 @Test mediaAudioGetsDisabledAndReEnabled()136 public void mediaAudioGetsDisabledAndReEnabled() { 137 when(mProfile.supportsHighQualityAudio(any())).thenReturn(true); 138 when(mProfile.isHighQualityAudioEnabled(any())).thenReturn(true); 139 when(mProfile.isPreferred(any())).thenReturn(true); 140 FragmentTestUtil.startFragment(mFragment); 141 142 ViewGroup profilesGroup = mFragment.getDialog().findViewById(R.id.profiles_section); 143 CheckBox audioBox = profilesGroup.findViewWithTag(mProfile.toString()); 144 CheckBox highQualityAudioBox = profilesGroup.findViewWithTag( 145 DeviceProfilesSettings.HIGH_QUALITY_AUDIO_PREF_TAG); 146 assertThat(audioBox).isNotNull(); 147 assertThat(audioBox.isChecked()).isTrue(); 148 assertThat(highQualityAudioBox).isNotNull(); 149 assertThat(highQualityAudioBox.isChecked()).isTrue(); 150 151 // Disabling media audio should cause the high quality audio box to disappear. 152 when(mProfile.isPreferred(any())).thenReturn(false); 153 mFragment.onDeviceAttributesChanged(); 154 audioBox = profilesGroup.findViewWithTag(mProfile.toString()); 155 highQualityAudioBox = profilesGroup.findViewWithTag( 156 DeviceProfilesSettings.HIGH_QUALITY_AUDIO_PREF_TAG); 157 assertThat(audioBox).isNotNull(); 158 assertThat(audioBox.isChecked()).isFalse(); 159 assertThat(highQualityAudioBox).isNotNull(); 160 assertThat(highQualityAudioBox.getVisibility()).isEqualTo(View.GONE); 161 162 // And re-enabling media audio should make it reappear. 163 when(mProfile.isPreferred(any())).thenReturn(true); 164 mFragment.onDeviceAttributesChanged(); 165 audioBox = profilesGroup.findViewWithTag(mProfile.toString()); 166 highQualityAudioBox = profilesGroup.findViewWithTag( 167 DeviceProfilesSettings.HIGH_QUALITY_AUDIO_PREF_TAG); 168 assertThat(audioBox).isNotNull(); 169 assertThat(audioBox.isChecked()).isTrue(); 170 assertThat(highQualityAudioBox).isNotNull(); 171 assertThat(highQualityAudioBox.isChecked()).isTrue(); 172 } 173 174 @Test mediaAudioStartsDisabled()175 public void mediaAudioStartsDisabled() { 176 when(mProfile.supportsHighQualityAudio(any())).thenReturn(true); 177 when(mProfile.isHighQualityAudioEnabled(any())).thenReturn(true); 178 when(mProfile.isPreferred(any())).thenReturn(false); 179 180 FragmentTestUtil.startFragment(mFragment); 181 ViewGroup profilesGroup = mFragment.getDialog().findViewById(R.id.profiles_section); 182 CheckBox audioBox = profilesGroup.findViewWithTag(mProfile.toString()); 183 CheckBox highQualityAudioBox = profilesGroup.findViewWithTag( 184 DeviceProfilesSettings.HIGH_QUALITY_AUDIO_PREF_TAG); 185 186 assertThat(audioBox).isNotNull(); 187 assertThat(audioBox.isChecked()).isFalse(); 188 assertThat(highQualityAudioBox).isNotNull(); 189 assertThat(highQualityAudioBox.getVisibility()).isEqualTo(View.GONE); 190 } 191 192 @Test deviceDoesntHaveHighQualityAudio()193 public void deviceDoesntHaveHighQualityAudio() { 194 when(mProfile.supportsHighQualityAudio(any())).thenReturn(false); 195 when(mProfile.isPreferred(any())).thenReturn(true); 196 FragmentTestUtil.startFragment(mFragment); 197 198 // A device that doesn't support high quality audio shouldn't have the checkbox for 199 // high quality audio support. 200 ViewGroup profilesGroup = mFragment.getDialog().findViewById(R.id.profiles_section); 201 CheckBox box = (CheckBox) profilesGroup.findViewWithTag( 202 DeviceProfilesSettings.HIGH_QUALITY_AUDIO_PREF_TAG); 203 assertThat(box).isNull(); 204 } 205 206 } 207