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)101 protected void setEnabledFunctions(long functions, boolean force) { 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 139 @Before before()140 public void before() { 141 MockitoAnnotations.initMocks(this); 142 mMockProperties = new HashMap<>(); 143 mMockGlobalSettings = new HashMap<>(); 144 when(mSharedPreferences.edit()).thenReturn(mEditor); 145 146 mUsbHandler = new MockUsbHandler(FgThread.get().getLooper(), 147 InstrumentationRegistry.getContext(), mUsbDeviceManager, mUsbAlsaManager, 148 mUsbSettingsManager, mUsbPermissionManager); 149 } 150 151 @SmallTest 152 @Test setFunctionsMtp()153 public void setFunctionsMtp() { 154 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_SET_CURRENT_FUNCTIONS, 155 UsbManager.FUNCTION_MTP)); 156 assertNotEquals(mUsbHandler.getEnabledFunctions() & UsbManager.FUNCTION_MTP, 0); 157 } 158 159 @SmallTest 160 @Test setFunctionsPtp()161 public void setFunctionsPtp() { 162 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_SET_CURRENT_FUNCTIONS, 163 UsbManager.FUNCTION_PTP)); 164 assertNotEquals(mUsbHandler.getEnabledFunctions() & UsbManager.FUNCTION_PTP, 0); 165 } 166 167 @SmallTest 168 @Test setFunctionsMidi()169 public void setFunctionsMidi() { 170 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_SET_CURRENT_FUNCTIONS, 171 UsbManager.FUNCTION_MIDI)); 172 assertNotEquals(mUsbHandler.getEnabledFunctions() & UsbManager.FUNCTION_MIDI, 0); 173 } 174 175 @SmallTest 176 @Test setFunctionsRndis()177 public void setFunctionsRndis() { 178 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_SET_CURRENT_FUNCTIONS, 179 UsbManager.FUNCTION_RNDIS)); 180 assertNotEquals(mUsbHandler.getEnabledFunctions() & UsbManager.FUNCTION_RNDIS, 0); 181 } 182 183 @SmallTest 184 @Test setFunctionsNcmAndRndis()185 public void setFunctionsNcmAndRndis() { 186 final long rndisPlusNcm = UsbManager.FUNCTION_RNDIS | UsbManager.FUNCTION_NCM; 187 188 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_SET_CURRENT_FUNCTIONS, 189 UsbManager.FUNCTION_NCM)); 190 assertEquals(UsbManager.FUNCTION_NCM, mUsbHandler.getEnabledFunctions() & rndisPlusNcm); 191 192 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_SET_CURRENT_FUNCTIONS, 193 rndisPlusNcm)); 194 assertEquals(rndisPlusNcm, mUsbHandler.getEnabledFunctions() & rndisPlusNcm); 195 196 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_SET_CURRENT_FUNCTIONS, 197 UsbManager.FUNCTION_NCM)); 198 assertEquals(UsbManager.FUNCTION_NCM, mUsbHandler.getEnabledFunctions() & rndisPlusNcm); 199 } 200 201 @SmallTest 202 @Test enableAdb()203 public void enableAdb() { 204 sendBootCompleteMessages(mUsbHandler); 205 Message msg = mUsbHandler.obtainMessage(MSG_ENABLE_ADB); 206 msg.arg1 = 1; 207 mUsbHandler.handleMessage(msg); 208 assertEquals(mUsbHandler.getEnabledFunctions(), UsbManager.FUNCTION_NONE); 209 assertEquals(mMockProperties.get(UsbDeviceManager.UsbHandler 210 .USB_PERSISTENT_CONFIG_PROPERTY), UsbManager.USB_FUNCTION_ADB); 211 assertTrue(mUsbHandler.isAdbEnabled()); 212 213 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_UPDATE_STATE, 1, 1)); 214 215 assertTrue(mUsbHandler.mBroadcastedIntent.getBooleanExtra(UsbManager.USB_CONNECTED, false)); 216 assertTrue(mUsbHandler.mBroadcastedIntent 217 .getBooleanExtra(UsbManager.USB_CONFIGURED, false)); 218 assertTrue(mUsbHandler.mBroadcastedIntent 219 .getBooleanExtra(UsbManager.USB_FUNCTION_ADB, false)); 220 } 221 222 @SmallTest 223 @Test disableAdb()224 public void disableAdb() { 225 mMockProperties.put(UsbDeviceManager.UsbHandler.USB_PERSISTENT_CONFIG_PROPERTY, 226 UsbManager.USB_FUNCTION_ADB); 227 mUsbHandler = new MockUsbHandler(FgThread.get().getLooper(), 228 InstrumentationRegistry.getContext(), mUsbDeviceManager, mUsbAlsaManager, 229 mUsbSettingsManager, mUsbPermissionManager); 230 231 sendBootCompleteMessages(mUsbHandler); 232 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_ENABLE_ADB, 0)); 233 assertEquals(mUsbHandler.getEnabledFunctions(), UsbManager.FUNCTION_NONE); 234 assertFalse(mUsbHandler.isAdbEnabled()); 235 assertEquals(mMockProperties.get(UsbDeviceManager.UsbHandler 236 .USB_PERSISTENT_CONFIG_PROPERTY), ""); 237 } 238 239 @SmallTest 240 @Test bootCompletedCharging()241 public void bootCompletedCharging() { 242 sendBootCompleteMessages(mUsbHandler); 243 assertEquals(mUsbHandler.getEnabledFunctions(), UsbManager.FUNCTION_NONE); 244 } 245 246 @SmallTest 247 @Test bootCompletedAdbEnabled()248 public void bootCompletedAdbEnabled() { 249 mMockProperties.put(UsbDeviceManager.UsbHandler.USB_PERSISTENT_CONFIG_PROPERTY, "adb"); 250 mUsbHandler = new MockUsbHandler(FgThread.get().getLooper(), 251 InstrumentationRegistry.getContext(), mUsbDeviceManager, mUsbAlsaManager, 252 mUsbSettingsManager, mUsbPermissionManager); 253 254 sendBootCompleteMessages(mUsbHandler); 255 assertEquals(mUsbHandler.getEnabledFunctions(), UsbManager.FUNCTION_NONE); 256 assertEquals(mMockGlobalSettings.get(Settings.Global.ADB_ENABLED).intValue(), 1); 257 assertTrue(mUsbHandler.isAdbEnabled()); 258 } 259 260 @SmallTest 261 @Test userSwitchedDisablesMtp()262 public void userSwitchedDisablesMtp() { 263 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_SET_CURRENT_FUNCTIONS, 264 UsbManager.FUNCTION_MTP)); 265 assertNotEquals(mUsbHandler.getEnabledFunctions() & UsbManager.FUNCTION_MTP, 0); 266 267 Message msg = mUsbHandler.obtainMessage(MSG_USER_SWITCHED); 268 msg.arg1 = ActivityManager.getCurrentUser() + 1; 269 mUsbHandler.handleMessage(msg); 270 assertEquals(mUsbHandler.getEnabledFunctions(), UsbManager.FUNCTION_NONE); 271 } 272 273 @SmallTest 274 @Test changedRestrictionsDisablesMtp()275 public void changedRestrictionsDisablesMtp() { 276 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_SET_CURRENT_FUNCTIONS, 277 UsbManager.FUNCTION_MTP)); 278 assertNotEquals(mUsbHandler.getEnabledFunctions() & UsbManager.FUNCTION_MTP, 0); 279 280 mUsbHandler.mIsUsbTransferAllowed = false; 281 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_UPDATE_USER_RESTRICTIONS)); 282 assertEquals(mUsbHandler.getEnabledFunctions(), UsbManager.FUNCTION_NONE); 283 } 284 285 @SmallTest 286 @Test disconnectResetsCharging()287 public void disconnectResetsCharging() { 288 sendBootCompleteMessages(mUsbHandler); 289 290 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_SET_CURRENT_FUNCTIONS, 291 UsbManager.FUNCTION_MTP)); 292 assertNotEquals(mUsbHandler.getEnabledFunctions() & UsbManager.FUNCTION_MTP, 0); 293 294 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_UPDATE_STATE, 0, 0)); 295 296 assertEquals(mUsbHandler.getEnabledFunctions(), UsbManager.FUNCTION_NONE); 297 } 298 299 @SmallTest 300 @Test configuredSendsBroadcast()301 public void configuredSendsBroadcast() { 302 sendBootCompleteMessages(mUsbHandler); 303 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_SET_CURRENT_FUNCTIONS, 304 UsbManager.FUNCTION_MTP)); 305 assertNotEquals(mUsbHandler.getEnabledFunctions() & UsbManager.FUNCTION_MTP, 0); 306 307 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_UPDATE_STATE, 1, 1)); 308 309 assertNotEquals(mUsbHandler.getEnabledFunctions() & UsbManager.FUNCTION_MTP, 0); 310 assertTrue(mUsbHandler.mBroadcastedIntent.getBooleanExtra(UsbManager.USB_CONNECTED, false)); 311 assertTrue(mUsbHandler.mBroadcastedIntent 312 .getBooleanExtra(UsbManager.USB_CONFIGURED, false)); 313 assertTrue(mUsbHandler.mBroadcastedIntent 314 .getBooleanExtra(UsbManager.USB_FUNCTION_MTP, false)); 315 } 316 317 @SmallTest 318 @Test setScreenUnlockedFunctions()319 public void setScreenUnlockedFunctions() { 320 sendBootCompleteMessages(mUsbHandler); 321 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_UPDATE_SCREEN_LOCK, 0)); 322 323 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_SET_SCREEN_UNLOCKED_FUNCTIONS, 324 UsbManager.FUNCTION_MTP)); 325 assertNotEquals(mUsbHandler.getScreenUnlockedFunctions() & UsbManager.FUNCTION_MTP, 0); 326 assertNotEquals(mUsbHandler.getEnabledFunctions() & UsbManager.FUNCTION_MTP, 0); 327 verify(mEditor).putString(String.format(Locale.ENGLISH, 328 UsbDeviceManager.UNLOCKED_CONFIG_PREF, mUsbHandler.mCurrentUser), 329 UsbManager.USB_FUNCTION_MTP); 330 } 331 332 @SmallTest 333 @Test unlockScreen()334 public void unlockScreen() { 335 when(mSharedPreferences.getString(String.format(Locale.ENGLISH, 336 UsbDeviceManager.UNLOCKED_CONFIG_PREF, mUsbHandler.mCurrentUser), "")) 337 .thenReturn(UsbManager.USB_FUNCTION_MTP); 338 mUsbHandler = new MockUsbHandler(FgThread.get().getLooper(), 339 InstrumentationRegistry.getContext(), mUsbDeviceManager, mUsbAlsaManager, 340 mUsbSettingsManager, mUsbPermissionManager); 341 sendBootCompleteMessages(mUsbHandler); 342 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_UPDATE_SCREEN_LOCK, 1)); 343 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_UPDATE_SCREEN_LOCK, 0)); 344 345 assertNotEquals(mUsbHandler.getScreenUnlockedFunctions() & UsbManager.FUNCTION_MTP, 0); 346 assertNotEquals(mUsbHandler.getEnabledFunctions() & UsbManager.FUNCTION_MTP, 0); 347 } 348 sendBootCompleteMessages(Handler handler)349 private static void sendBootCompleteMessages(Handler handler) { 350 handler.handleMessage(handler.obtainMessage(MSG_BOOT_COMPLETED)); 351 handler.handleMessage(handler.obtainMessage(MSG_SYSTEM_READY)); 352 } 353 } 354