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 package com.android.server.usb; 17 18 import static org.junit.Assert.assertEquals; 19 import static org.junit.Assert.assertFalse; 20 import static org.junit.Assert.assertNotEquals; 21 import static org.junit.Assert.assertTrue; 22 import static org.mockito.Mockito.verify; 23 import static org.mockito.Mockito.when; 24 25 import android.app.ActivityManager; 26 import android.content.ContentResolver; 27 import android.content.Context; 28 import android.content.Intent; 29 import android.content.SharedPreferences; 30 import android.hardware.usb.UsbManager; 31 import android.os.Handler; 32 import android.os.Looper; 33 import android.os.Message; 34 import android.provider.Settings; 35 36 import androidx.test.InstrumentationRegistry; 37 import androidx.test.filters.SmallTest; 38 import androidx.test.runner.AndroidJUnit4; 39 40 import com.android.server.FgThread; 41 42 import org.junit.Before; 43 import org.junit.Test; 44 import org.junit.runner.RunWith; 45 import org.mockito.Mock; 46 import org.mockito.MockitoAnnotations; 47 48 import java.util.HashMap; 49 import java.util.Locale; 50 import java.util.Map; 51 52 /** 53 * Tests for UsbHandler state changes. 54 */ 55 @RunWith(AndroidJUnit4.class) 56 public class UsbHandlerTest { 57 private static final String TAG = UsbHandlerTest.class.getSimpleName(); 58 59 @Mock 60 private UsbDeviceManager mUsbDeviceManager; 61 @Mock 62 private UsbAlsaManager mUsbAlsaManager; 63 @Mock 64 private UsbSettingsManager mUsbSettingsManager; 65 @Mock 66 private UsbPermissionManager mUsbPermissionManager; 67 @Mock 68 private SharedPreferences mSharedPreferences; 69 @Mock 70 private SharedPreferences.Editor mEditor; 71 72 private MockUsbHandler mUsbHandler; 73 74 private static final int MSG_UPDATE_STATE = 0; 75 private static final int MSG_ENABLE_ADB = 1; 76 private static final int MSG_SET_CURRENT_FUNCTIONS = 2; 77 private static final int MSG_SYSTEM_READY = 3; 78 private static final int MSG_BOOT_COMPLETED = 4; 79 private static final int MSG_USER_SWITCHED = 5; 80 private static final int MSG_UPDATE_USER_RESTRICTIONS = 6; 81 private static final int MSG_SET_SCREEN_UNLOCKED_FUNCTIONS = 12; 82 private static final int MSG_UPDATE_SCREEN_LOCK = 13; 83 84 private Map<String, String> mMockProperties; 85 private Map<String, Integer> mMockGlobalSettings; 86 87 private class MockUsbHandler extends UsbDeviceManager.UsbHandler { 88 boolean mIsUsbTransferAllowed; 89 Intent mBroadcastedIntent; 90 MockUsbHandler(Looper looper, Context context, UsbDeviceManager deviceManager, UsbAlsaManager alsaManager, UsbSettingsManager settingsManager, UsbPermissionManager permissionManager)91 MockUsbHandler(Looper looper, Context context, UsbDeviceManager deviceManager, 92 UsbAlsaManager alsaManager, UsbSettingsManager settingsManager, 93 UsbPermissionManager permissionManager) { 94 super(looper, context, deviceManager, alsaManager, permissionManager); 95 mUseUsbNotification = false; 96 mIsUsbTransferAllowed = true; 97 mCurrentUsbFunctionsReceived = true; 98 } 99 100 @Override setEnabledFunctions(long functions, boolean force, int operationId)101 protected void setEnabledFunctions(long functions, boolean force, int operationId) { 102 mCurrentFunctions = functions; 103 } 104 105 @Override setSystemProperty(String property, String value)106 protected void setSystemProperty(String property, String value) { 107 mMockProperties.put(property, value); 108 } 109 110 @Override putGlobalSettings(ContentResolver resolver, String setting, int val)111 protected void putGlobalSettings(ContentResolver resolver, String setting, int val) { 112 mMockGlobalSettings.put(setting, val); 113 } 114 115 @Override getSystemProperty(String property, String def)116 protected String getSystemProperty(String property, String def) { 117 if (mMockProperties.containsKey(property)) { 118 return mMockProperties.get(property); 119 } 120 return def; 121 } 122 123 @Override isUsbTransferAllowed()124 protected boolean isUsbTransferAllowed() { 125 return mIsUsbTransferAllowed; 126 } 127 128 @Override getPinnedSharedPrefs(Context context)129 protected SharedPreferences getPinnedSharedPrefs(Context context) { 130 return mSharedPreferences; 131 } 132 133 @Override sendStickyBroadcast(Intent intent)134 protected void sendStickyBroadcast(Intent intent) { 135 mBroadcastedIntent = intent; 136 } 137 138 @Override handlerInitDone(int operationId)139 public void handlerInitDone(int operationId) { 140 } 141 142 @Override setCurrentUsbFunctionsCb(long functions, int status, int mRequest, long mFunctions, boolean mChargingFunctions)143 public void setCurrentUsbFunctionsCb(long functions, 144 int status, int mRequest, long mFunctions, boolean mChargingFunctions){ 145 } 146 147 @Override getUsbSpeedCb(int speed)148 public void getUsbSpeedCb(int speed){ 149 } 150 151 @Override resetCb(int status)152 public void resetCb(int status){ 153 } 154 155 } 156 157 @Before before()158 public void before() { 159 MockitoAnnotations.initMocks(this); 160 mMockProperties = new HashMap<>(); 161 mMockGlobalSettings = new HashMap<>(); 162 when(mSharedPreferences.edit()).thenReturn(mEditor); 163 164 mUsbHandler = new MockUsbHandler(FgThread.get().getLooper(), 165 InstrumentationRegistry.getContext(), mUsbDeviceManager, mUsbAlsaManager, 166 mUsbSettingsManager, mUsbPermissionManager); 167 } 168 169 @SmallTest 170 @Test setFunctionsMtp()171 public void setFunctionsMtp() { 172 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_SET_CURRENT_FUNCTIONS, 173 UsbManager.FUNCTION_MTP)); 174 assertNotEquals(mUsbHandler.getEnabledFunctions() & UsbManager.FUNCTION_MTP, 0); 175 } 176 177 @SmallTest 178 @Test setFunctionsPtp()179 public void setFunctionsPtp() { 180 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_SET_CURRENT_FUNCTIONS, 181 UsbManager.FUNCTION_PTP)); 182 assertNotEquals(mUsbHandler.getEnabledFunctions() & UsbManager.FUNCTION_PTP, 0); 183 } 184 185 @SmallTest 186 @Test setFunctionsMidi()187 public void setFunctionsMidi() { 188 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_SET_CURRENT_FUNCTIONS, 189 UsbManager.FUNCTION_MIDI)); 190 assertNotEquals(mUsbHandler.getEnabledFunctions() & UsbManager.FUNCTION_MIDI, 0); 191 } 192 193 @SmallTest 194 @Test setFunctionsRndis()195 public void setFunctionsRndis() { 196 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_SET_CURRENT_FUNCTIONS, 197 UsbManager.FUNCTION_RNDIS)); 198 assertNotEquals(mUsbHandler.getEnabledFunctions() & UsbManager.FUNCTION_RNDIS, 0); 199 } 200 201 @SmallTest 202 @Test setFunctionsNcm()203 public void setFunctionsNcm() { 204 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_SET_CURRENT_FUNCTIONS, 205 UsbManager.FUNCTION_NCM)); 206 assertNotEquals(mUsbHandler.getEnabledFunctions() & UsbManager.FUNCTION_NCM, 0); 207 } 208 209 @SmallTest 210 @Test setFunctionsNcmAndRndis()211 public void setFunctionsNcmAndRndis() { 212 final long rndisPlusNcm = UsbManager.FUNCTION_RNDIS | UsbManager.FUNCTION_NCM; 213 214 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_SET_CURRENT_FUNCTIONS, 215 UsbManager.FUNCTION_NCM)); 216 assertEquals(UsbManager.FUNCTION_NCM, mUsbHandler.getEnabledFunctions() & rndisPlusNcm); 217 218 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_SET_CURRENT_FUNCTIONS, 219 rndisPlusNcm)); 220 assertEquals(rndisPlusNcm, mUsbHandler.getEnabledFunctions() & rndisPlusNcm); 221 222 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_SET_CURRENT_FUNCTIONS, 223 UsbManager.FUNCTION_NCM)); 224 assertEquals(UsbManager.FUNCTION_NCM, mUsbHandler.getEnabledFunctions() & rndisPlusNcm); 225 } 226 227 @SmallTest 228 @Test enableAdb()229 public void enableAdb() { 230 sendBootCompleteMessages(mUsbHandler); 231 Message msg = mUsbHandler.obtainMessage(MSG_ENABLE_ADB); 232 msg.arg1 = 1; 233 mUsbHandler.handleMessage(msg); 234 assertEquals(mUsbHandler.getEnabledFunctions(), UsbManager.FUNCTION_NONE); 235 assertEquals(mMockProperties.get(UsbDeviceManager.UsbHandler 236 .USB_PERSISTENT_CONFIG_PROPERTY), UsbManager.USB_FUNCTION_ADB); 237 assertTrue(mUsbHandler.isAdbEnabled()); 238 239 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_UPDATE_STATE, 1, 1)); 240 241 assertTrue(mUsbHandler.mBroadcastedIntent.getBooleanExtra(UsbManager.USB_CONNECTED, false)); 242 assertTrue(mUsbHandler.mBroadcastedIntent 243 .getBooleanExtra(UsbManager.USB_CONFIGURED, false)); 244 assertTrue(mUsbHandler.mBroadcastedIntent 245 .getBooleanExtra(UsbManager.USB_FUNCTION_ADB, false)); 246 } 247 248 @SmallTest 249 @Test disableAdb()250 public void disableAdb() { 251 mMockProperties.put(UsbDeviceManager.UsbHandler.USB_PERSISTENT_CONFIG_PROPERTY, 252 UsbManager.USB_FUNCTION_ADB); 253 mUsbHandler = new MockUsbHandler(FgThread.get().getLooper(), 254 InstrumentationRegistry.getContext(), mUsbDeviceManager, mUsbAlsaManager, 255 mUsbSettingsManager, mUsbPermissionManager); 256 257 sendBootCompleteMessages(mUsbHandler); 258 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_ENABLE_ADB, 0)); 259 assertEquals(mUsbHandler.getEnabledFunctions(), UsbManager.FUNCTION_NONE); 260 assertFalse(mUsbHandler.isAdbEnabled()); 261 assertEquals(mMockProperties.get(UsbDeviceManager.UsbHandler 262 .USB_PERSISTENT_CONFIG_PROPERTY), ""); 263 } 264 265 @SmallTest 266 @Test bootCompletedCharging()267 public void bootCompletedCharging() { 268 sendBootCompleteMessages(mUsbHandler); 269 assertEquals(mUsbHandler.getEnabledFunctions(), UsbManager.FUNCTION_NONE); 270 } 271 272 @SmallTest 273 @Test bootCompletedAdbEnabled()274 public void bootCompletedAdbEnabled() { 275 mMockProperties.put(UsbDeviceManager.UsbHandler.USB_PERSISTENT_CONFIG_PROPERTY, "adb"); 276 mUsbHandler = new MockUsbHandler(FgThread.get().getLooper(), 277 InstrumentationRegistry.getContext(), mUsbDeviceManager, mUsbAlsaManager, 278 mUsbSettingsManager, mUsbPermissionManager); 279 280 sendBootCompleteMessages(mUsbHandler); 281 assertEquals(mUsbHandler.getEnabledFunctions(), UsbManager.FUNCTION_NONE); 282 assertEquals(mMockGlobalSettings.get(Settings.Global.ADB_ENABLED).intValue(), 1); 283 assertTrue(mUsbHandler.isAdbEnabled()); 284 } 285 286 @SmallTest 287 @Test userSwitchedDisablesMtp()288 public void userSwitchedDisablesMtp() { 289 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_SET_CURRENT_FUNCTIONS, 290 UsbManager.FUNCTION_MTP)); 291 assertNotEquals(mUsbHandler.getEnabledFunctions() & UsbManager.FUNCTION_MTP, 0); 292 293 Message msg = mUsbHandler.obtainMessage(MSG_USER_SWITCHED); 294 msg.arg1 = ActivityManager.getCurrentUser() + 1; 295 mUsbHandler.handleMessage(msg); 296 assertEquals(mUsbHandler.getEnabledFunctions(), UsbManager.FUNCTION_NONE); 297 } 298 299 @SmallTest 300 @Test changedRestrictionsDisablesMtp()301 public void changedRestrictionsDisablesMtp() { 302 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_SET_CURRENT_FUNCTIONS, 303 UsbManager.FUNCTION_MTP)); 304 assertNotEquals(mUsbHandler.getEnabledFunctions() & UsbManager.FUNCTION_MTP, 0); 305 306 mUsbHandler.mIsUsbTransferAllowed = false; 307 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_UPDATE_USER_RESTRICTIONS)); 308 assertEquals(mUsbHandler.getEnabledFunctions(), UsbManager.FUNCTION_NONE); 309 } 310 311 @SmallTest 312 @Test disconnectResetsCharging()313 public void disconnectResetsCharging() { 314 sendBootCompleteMessages(mUsbHandler); 315 316 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_SET_CURRENT_FUNCTIONS, 317 UsbManager.FUNCTION_MTP)); 318 assertNotEquals(mUsbHandler.getEnabledFunctions() & UsbManager.FUNCTION_MTP, 0); 319 320 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_UPDATE_STATE, 0, 0)); 321 322 assertEquals(mUsbHandler.getEnabledFunctions(), UsbManager.FUNCTION_NONE); 323 } 324 325 @SmallTest 326 @Test configuredSendsBroadcast()327 public void configuredSendsBroadcast() { 328 sendBootCompleteMessages(mUsbHandler); 329 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_SET_CURRENT_FUNCTIONS, 330 UsbManager.FUNCTION_MTP)); 331 assertNotEquals(mUsbHandler.getEnabledFunctions() & UsbManager.FUNCTION_MTP, 0); 332 333 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_UPDATE_STATE, 1, 1)); 334 335 assertNotEquals(mUsbHandler.getEnabledFunctions() & UsbManager.FUNCTION_MTP, 0); 336 assertTrue(mUsbHandler.mBroadcastedIntent.getBooleanExtra(UsbManager.USB_CONNECTED, false)); 337 assertTrue(mUsbHandler.mBroadcastedIntent 338 .getBooleanExtra(UsbManager.USB_CONFIGURED, false)); 339 assertTrue(mUsbHandler.mBroadcastedIntent 340 .getBooleanExtra(UsbManager.USB_FUNCTION_MTP, false)); 341 } 342 343 @SmallTest 344 @Test setScreenUnlockedFunctions()345 public void setScreenUnlockedFunctions() { 346 sendBootCompleteMessages(mUsbHandler); 347 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_UPDATE_SCREEN_LOCK, 0)); 348 349 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_SET_SCREEN_UNLOCKED_FUNCTIONS, 350 UsbManager.FUNCTION_MTP)); 351 assertNotEquals(mUsbHandler.getScreenUnlockedFunctions() & UsbManager.FUNCTION_MTP, 0); 352 assertNotEquals(mUsbHandler.getEnabledFunctions() & UsbManager.FUNCTION_MTP, 0); 353 verify(mEditor).putString(String.format(Locale.ENGLISH, 354 UsbDeviceManager.UNLOCKED_CONFIG_PREF, mUsbHandler.mCurrentUser), 355 UsbManager.USB_FUNCTION_MTP); 356 } 357 358 @SmallTest 359 @Test unlockScreen()360 public void unlockScreen() { 361 when(mSharedPreferences.getString(String.format(Locale.ENGLISH, 362 UsbDeviceManager.UNLOCKED_CONFIG_PREF, mUsbHandler.mCurrentUser), "")) 363 .thenReturn(UsbManager.USB_FUNCTION_MTP); 364 mUsbHandler = new MockUsbHandler(FgThread.get().getLooper(), 365 InstrumentationRegistry.getContext(), mUsbDeviceManager, mUsbAlsaManager, 366 mUsbSettingsManager, mUsbPermissionManager); 367 sendBootCompleteMessages(mUsbHandler); 368 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_UPDATE_SCREEN_LOCK, 1)); 369 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_UPDATE_SCREEN_LOCK, 0)); 370 371 assertNotEquals(mUsbHandler.getScreenUnlockedFunctions() & UsbManager.FUNCTION_MTP, 0); 372 assertNotEquals(mUsbHandler.getEnabledFunctions() & UsbManager.FUNCTION_MTP, 0); 373 } 374 sendBootCompleteMessages(Handler handler)375 private static void sendBootCompleteMessages(Handler handler) { 376 handler.handleMessage(handler.obtainMessage(MSG_BOOT_COMPLETED)); 377 handler.handleMessage(handler.obtainMessage(MSG_SYSTEM_READY)); 378 } 379 } 380