1 /* 2 * Copyright (C) 2018 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.connecteddevice.usb; 18 19 import static com.google.common.truth.Truth.assertThat; 20 21 import static org.mockito.ArgumentMatchers.anyLong; 22 import static org.mockito.Mockito.verify; 23 import static org.mockito.Mockito.when; 24 25 import android.app.Activity; 26 import android.content.Context; 27 import android.hardware.usb.UsbManager; 28 import android.hardware.usb.UsbPort; 29 import android.support.v7.preference.PreferenceCategory; 30 import android.support.v7.preference.PreferenceManager; 31 import android.support.v7.preference.PreferenceScreen; 32 33 import com.android.settings.testutils.SettingsRobolectricTestRunner; 34 import com.android.settings.testutils.shadow.ShadowUtils; 35 import com.android.settings.widget.RadioButtonPreference; 36 import com.android.settingslib.core.lifecycle.Lifecycle; 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.RuntimeEnvironment; 44 import org.robolectric.annotation.Config; 45 46 import java.util.ArrayList; 47 import java.util.Iterator; 48 import java.util.List; 49 50 @RunWith(SettingsRobolectricTestRunner.class) 51 public class UsbDetailsFunctionsControllerTest { 52 53 private UsbDetailsFunctionsController mDetailsFunctionsController; 54 private Context mContext; 55 private Lifecycle mLifecycle; 56 private PreferenceCategory mPreference; 57 private PreferenceManager mPreferenceManager; 58 private PreferenceScreen mScreen; 59 60 @Mock 61 private UsbBackend mUsbBackend; 62 @Mock 63 private UsbDetailsFragment mFragment; 64 @Mock 65 private Activity mActivity; 66 67 @Before 68 public void setUp() { 69 MockitoAnnotations.initMocks(this); 70 71 mContext = RuntimeEnvironment.application; 72 mLifecycle = new Lifecycle(() -> mLifecycle); 73 mPreferenceManager = new PreferenceManager(mContext); 74 mScreen = mPreferenceManager.createPreferenceScreen(mContext); 75 76 when(mFragment.getActivity()).thenReturn(mActivity); 77 when(mActivity.getApplicationContext()).thenReturn(mContext); 78 when(mFragment.getContext()).thenReturn(mContext); 79 when(mFragment.getPreferenceManager()).thenReturn(mPreferenceManager); 80 when(mFragment.getPreferenceScreen()).thenReturn(mScreen); 81 82 mDetailsFunctionsController = new UsbDetailsFunctionsController(mContext, mFragment, 83 mUsbBackend); 84 mPreference = new PreferenceCategory(mContext); 85 mPreference.setKey(mDetailsFunctionsController.getPreferenceKey()); 86 mScreen.addPreference(mPreference); 87 } 88 89 @Test 90 public void displayRefresh_allAllowed_shouldCreatePrefs() { 91 when(mUsbBackend.areFunctionsSupported(anyLong())).thenReturn(true); 92 93 mDetailsFunctionsController.displayPreference(mScreen); 94 mDetailsFunctionsController.refresh(true, UsbManager.FUNCTION_NONE, UsbPort.POWER_ROLE_SINK, 95 UsbPort.DATA_ROLE_DEVICE); 96 List<RadioButtonPreference> prefs = getRadioPreferences(); 97 Iterator<Long> iter = UsbDetailsFunctionsController.FUNCTIONS_MAP.keySet().iterator(); 98 99 for (RadioButtonPreference pref : prefs) { 100 assertThat(pref.getKey()).isEqualTo(UsbBackend.usbFunctionsToString(iter.next())); 101 } 102 } 103 104 @Test 105 public void displayRefresh_disconnected_shouldDisable() { 106 when(mUsbBackend.areFunctionsSupported(anyLong())).thenReturn(true); 107 108 mDetailsFunctionsController.displayPreference(mScreen); 109 mDetailsFunctionsController.refresh(false, UsbManager.FUNCTION_NONE, 110 UsbPort.POWER_ROLE_SINK, UsbPort.DATA_ROLE_DEVICE); 111 assertThat(mPreference.isEnabled()).isFalse(); 112 } 113 114 @Test 115 public void displayRefresh_onlyMidiAllowed_shouldCreateOnlyMidiPref() { 116 when(mUsbBackend.areFunctionsSupported(UsbManager.FUNCTION_MIDI)).thenReturn(true); 117 when(mUsbBackend.areFunctionsSupported(UsbManager.FUNCTION_MTP)).thenReturn(false); 118 when(mUsbBackend.areFunctionsSupported(UsbManager.FUNCTION_PTP)).thenReturn(false); 119 when(mUsbBackend.areFunctionsSupported(UsbManager.FUNCTION_RNDIS)).thenReturn(false); 120 121 mDetailsFunctionsController.displayPreference(mScreen); 122 mDetailsFunctionsController.refresh(true, UsbManager.FUNCTION_NONE, UsbPort.POWER_ROLE_SINK, 123 UsbPort.DATA_ROLE_DEVICE); 124 List<RadioButtonPreference> prefs = getRadioPreferences(); 125 assertThat(prefs.size()).isEqualTo(1); 126 assertThat(prefs.get(0).getKey()) 127 .isEqualTo(UsbBackend.usbFunctionsToString(UsbManager.FUNCTION_MIDI)); 128 } 129 130 @Test 131 public void displayRefresh_mtpEnabled_shouldCheckSwitches() { 132 when(mUsbBackend.areFunctionsSupported(anyLong())).thenReturn(true); 133 134 mDetailsFunctionsController.displayPreference(mScreen); 135 mDetailsFunctionsController.refresh(true, UsbManager.FUNCTION_MTP, UsbPort.POWER_ROLE_SINK, 136 UsbPort.DATA_ROLE_DEVICE); 137 List<RadioButtonPreference> prefs = getRadioPreferences(); 138 139 assertThat(prefs.get(0).getKey()) 140 .isEqualTo(UsbBackend.usbFunctionsToString(UsbManager.FUNCTION_MTP)); 141 assertThat(prefs.get(0).isChecked()).isTrue(); 142 } 143 144 @Test 145 public void onClickMtp_noneEnabled_shouldEnableMtp() { 146 when(mUsbBackend.areFunctionsSupported(anyLong())).thenReturn(true); 147 148 mDetailsFunctionsController.displayPreference(mScreen); 149 mDetailsFunctionsController.refresh(true, UsbManager.FUNCTION_NONE, UsbPort.POWER_ROLE_SINK, 150 UsbPort.DATA_ROLE_DEVICE); 151 when(mUsbBackend.getCurrentFunctions()).thenReturn(UsbManager.FUNCTION_NONE); 152 List<RadioButtonPreference> prefs = getRadioPreferences(); 153 prefs.get(0).performClick(); 154 155 assertThat(prefs.get(0).getKey()) 156 .isEqualTo(UsbBackend.usbFunctionsToString(UsbManager.FUNCTION_MTP)); 157 verify(mUsbBackend).setCurrentFunctions(UsbManager.FUNCTION_MTP); 158 mDetailsFunctionsController.refresh(true, UsbManager.FUNCTION_MTP, UsbPort.POWER_ROLE_SINK, 159 UsbPort.DATA_ROLE_DEVICE); 160 assertThat(prefs.get(0).isChecked()).isTrue(); 161 } 162 163 @Test 164 public void onClickMtp_ptpEnabled_shouldEnableMtp() { 165 when(mUsbBackend.areFunctionsSupported(anyLong())).thenReturn(true); 166 167 mDetailsFunctionsController.displayPreference(mScreen); 168 mDetailsFunctionsController.refresh(true, UsbManager.FUNCTION_PTP, UsbPort.POWER_ROLE_SINK, 169 UsbPort.DATA_ROLE_DEVICE); 170 when(mUsbBackend.getCurrentFunctions()).thenReturn(UsbManager.FUNCTION_PTP); 171 List<RadioButtonPreference> prefs = getRadioPreferences(); 172 prefs.get(0).performClick(); 173 174 assertThat(prefs.get(0).getKey()) 175 .isEqualTo(UsbBackend.usbFunctionsToString(UsbManager.FUNCTION_MTP)); 176 verify(mUsbBackend).setCurrentFunctions(UsbManager.FUNCTION_MTP); 177 mDetailsFunctionsController.refresh(true, UsbManager.FUNCTION_MTP, UsbPort.POWER_ROLE_SINK, 178 UsbPort.DATA_ROLE_DEVICE); 179 assertThat(prefs.get(0).isChecked()).isTrue(); 180 assertThat(prefs.get(3).getKey()) 181 .isEqualTo(UsbBackend.usbFunctionsToString(UsbManager.FUNCTION_PTP)); 182 assertThat(prefs.get(3).isChecked()).isFalse(); 183 } 184 185 @Test 186 public void onClickNone_mtpEnabled_shouldDisableMtp() { 187 when(mUsbBackend.areFunctionsSupported(anyLong())).thenReturn(true); 188 189 mDetailsFunctionsController.displayPreference(mScreen); 190 mDetailsFunctionsController.refresh(true, UsbManager.FUNCTION_MTP, UsbPort.POWER_ROLE_SINK, 191 UsbPort.DATA_ROLE_DEVICE); 192 when(mUsbBackend.getCurrentFunctions()).thenReturn(UsbManager.FUNCTION_MTP); 193 List<RadioButtonPreference> prefs = getRadioPreferences(); 194 prefs.get(4).performClick(); 195 196 assertThat(prefs.get(4).getKey()) 197 .isEqualTo(UsbBackend.usbFunctionsToString(UsbManager.FUNCTION_NONE)); 198 verify(mUsbBackend).setCurrentFunctions(UsbManager.FUNCTION_NONE); 199 mDetailsFunctionsController.refresh(true, UsbManager.FUNCTION_NONE, UsbPort.POWER_ROLE_SINK, 200 UsbPort.DATA_ROLE_DEVICE); 201 assertThat(prefs.get(0).isChecked()).isFalse(); 202 } 203 204 @Test 205 @Config(shadows = ShadowUtils.class) 206 public void isAvailable_isMonkey_shouldReturnFalse() { 207 ShadowUtils.setIsUserAMonkey(true); 208 assertThat(mDetailsFunctionsController.isAvailable()).isFalse(); 209 } 210 211 private List<RadioButtonPreference> getRadioPreferences() { 212 ArrayList<RadioButtonPreference> result = new ArrayList<>(); 213 for (int i = 0; i < mPreference.getPreferenceCount(); i++) { 214 result.add((RadioButtonPreference) mPreference.getPreference(i)); 215 } 216 return result; 217 } 218 } 219