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 */ 16package com.android.server.usb; 17 18import static org.junit.Assert.assertEquals; 19import static org.junit.Assert.assertFalse; 20import static org.junit.Assert.assertNotEquals; 21import static org.junit.Assert.assertTrue; 22import static org.mockito.Mockito.verify; 23import static org.mockito.Mockito.when; 24 25import android.app.ActivityManager; 26import android.content.ContentResolver; 27import android.content.Context; 28import android.content.Intent; 29import android.content.SharedPreferences; 30import android.hardware.usb.UsbManager; 31import android.os.Handler; 32import android.os.Looper; 33import android.os.Message; 34import android.os.UserHandle; 35import android.provider.Settings; 36import android.support.test.InstrumentationRegistry; 37import android.support.test.filters.SmallTest; 38import android.support.test.runner.AndroidJUnit4; 39 40import com.android.server.FgThread; 41 42import org.junit.Before; 43import org.junit.Test; 44import org.junit.runner.RunWith; 45import org.mockito.Mock; 46import org.mockito.MockitoAnnotations; 47 48import java.util.HashMap; 49import java.util.Locale; 50import java.util.Map; 51 52/** 53 * Tests for UsbHandler state changes. 54 */ 55@RunWith(AndroidJUnit4.class) 56public class UsbHandlerTest { 57 private static final String TAG = UsbHandlerTest.class.getSimpleName(); 58 59 @Mock 60 private UsbDeviceManager mUsbDeviceManager; 61 @Mock 62 private UsbDebuggingManager mUsbDebuggingManager; 63 @Mock 64 private UsbAlsaManager mUsbAlsaManager; 65 @Mock 66 private UsbSettingsManager mUsbSettingsManager; 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 91 MockUsbHandler(Looper looper, Context context, UsbDeviceManager deviceManager, 92 UsbDebuggingManager debuggingManager, UsbAlsaManager alsaManager, 93 UsbSettingsManager settingsManager) { 94 super(looper, context, deviceManager, debuggingManager, alsaManager, settingsManager); 95 mUseUsbNotification = false; 96 mIsUsbTransferAllowed = true; 97 mCurrentUsbFunctionsReceived = true; 98 } 99 100 @Override 101 protected void setEnabledFunctions(long functions, boolean force) { 102 mCurrentFunctions = functions; 103 } 104 105 @Override 106 protected void setSystemProperty(String property, String value) { 107 mMockProperties.put(property, value); 108 } 109 110 @Override 111 protected void putGlobalSettings(ContentResolver resolver, String setting, int val) { 112 mMockGlobalSettings.put(setting, val); 113 } 114 115 @Override 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 124 protected boolean isUsbTransferAllowed() { 125 return mIsUsbTransferAllowed; 126 } 127 128 @Override 129 protected SharedPreferences getPinnedSharedPrefs(Context context) { 130 return mSharedPreferences; 131 } 132 133 @Override 134 protected void sendStickyBroadcast(Intent intent) { 135 mBroadcastedIntent = intent; 136 } 137 } 138 139 @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, mUsbDebuggingManager, 148 mUsbAlsaManager, mUsbSettingsManager); 149 } 150 151 @SmallTest 152 @Test 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 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 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 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 185 public void enableAdb() { 186 sendBootCompleteMessages(mUsbHandler); 187 Message msg = mUsbHandler.obtainMessage(MSG_ENABLE_ADB); 188 msg.arg1 = 1; 189 mUsbHandler.handleMessage(msg); 190 assertEquals(mUsbHandler.getEnabledFunctions(), UsbManager.FUNCTION_NONE); 191 assertEquals(mMockProperties.get(UsbDeviceManager.UsbHandler 192 .USB_PERSISTENT_CONFIG_PROPERTY), UsbManager.USB_FUNCTION_ADB); 193 verify(mUsbDebuggingManager).setAdbEnabled(true); 194 assertTrue(mUsbHandler.mAdbEnabled); 195 196 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_UPDATE_STATE, 1, 1)); 197 198 assertTrue(mUsbHandler.mBroadcastedIntent.getBooleanExtra(UsbManager.USB_CONNECTED, false)); 199 assertTrue(mUsbHandler.mBroadcastedIntent 200 .getBooleanExtra(UsbManager.USB_CONFIGURED, false)); 201 assertTrue(mUsbHandler.mBroadcastedIntent 202 .getBooleanExtra(UsbManager.USB_FUNCTION_ADB, false)); 203 } 204 205 @SmallTest 206 @Test 207 public void disableAdb() { 208 mMockProperties.put(UsbDeviceManager.UsbHandler.USB_PERSISTENT_CONFIG_PROPERTY, 209 UsbManager.USB_FUNCTION_ADB); 210 mUsbHandler = new MockUsbHandler(FgThread.get().getLooper(), 211 InstrumentationRegistry.getContext(), mUsbDeviceManager, mUsbDebuggingManager, 212 mUsbAlsaManager, mUsbSettingsManager); 213 214 sendBootCompleteMessages(mUsbHandler); 215 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_ENABLE_ADB, 0)); 216 assertEquals(mUsbHandler.getEnabledFunctions(), UsbManager.FUNCTION_NONE); 217 assertFalse(mUsbHandler.mAdbEnabled); 218 assertEquals(mMockProperties.get(UsbDeviceManager.UsbHandler 219 .USB_PERSISTENT_CONFIG_PROPERTY), ""); 220 verify(mUsbDebuggingManager).setAdbEnabled(false); 221 } 222 223 @SmallTest 224 @Test 225 public void bootCompletedCharging() { 226 sendBootCompleteMessages(mUsbHandler); 227 assertEquals(mUsbHandler.getEnabledFunctions(), UsbManager.FUNCTION_NONE); 228 } 229 230 @SmallTest 231 @Test 232 public void bootCompletedAdbEnabled() { 233 mMockProperties.put(UsbDeviceManager.UsbHandler.USB_PERSISTENT_CONFIG_PROPERTY, "adb"); 234 mUsbHandler = new MockUsbHandler(FgThread.get().getLooper(), 235 InstrumentationRegistry.getContext(), mUsbDeviceManager, mUsbDebuggingManager, 236 mUsbAlsaManager, mUsbSettingsManager); 237 238 sendBootCompleteMessages(mUsbHandler); 239 assertEquals(mUsbHandler.getEnabledFunctions(), UsbManager.FUNCTION_NONE); 240 assertEquals(mMockGlobalSettings.get(Settings.Global.ADB_ENABLED).intValue(), 1); 241 assertTrue(mUsbHandler.mAdbEnabled); 242 verify(mUsbDebuggingManager).setAdbEnabled(true); 243 } 244 245 @SmallTest 246 @Test 247 public void userSwitchedDisablesMtp() { 248 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_SET_CURRENT_FUNCTIONS, 249 UsbManager.FUNCTION_MTP)); 250 assertNotEquals(mUsbHandler.getEnabledFunctions() & UsbManager.FUNCTION_MTP, 0); 251 252 Message msg = mUsbHandler.obtainMessage(MSG_USER_SWITCHED); 253 msg.arg1 = ActivityManager.getCurrentUser() + 1; 254 mUsbHandler.handleMessage(msg); 255 assertEquals(mUsbHandler.getEnabledFunctions(), UsbManager.FUNCTION_NONE); 256 } 257 258 @SmallTest 259 @Test 260 public void changedRestrictionsDisablesMtp() { 261 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_SET_CURRENT_FUNCTIONS, 262 UsbManager.FUNCTION_MTP)); 263 assertNotEquals(mUsbHandler.getEnabledFunctions() & UsbManager.FUNCTION_MTP, 0); 264 265 mUsbHandler.mIsUsbTransferAllowed = false; 266 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_UPDATE_USER_RESTRICTIONS)); 267 assertEquals(mUsbHandler.getEnabledFunctions(), UsbManager.FUNCTION_NONE); 268 } 269 270 @SmallTest 271 @Test 272 public void disconnectResetsCharging() { 273 sendBootCompleteMessages(mUsbHandler); 274 275 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_SET_CURRENT_FUNCTIONS, 276 UsbManager.FUNCTION_MTP)); 277 assertNotEquals(mUsbHandler.getEnabledFunctions() & UsbManager.FUNCTION_MTP, 0); 278 279 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_UPDATE_STATE, 0, 0)); 280 281 assertEquals(mUsbHandler.getEnabledFunctions(), UsbManager.FUNCTION_NONE); 282 } 283 284 @SmallTest 285 @Test 286 public void configuredSendsBroadcast() { 287 sendBootCompleteMessages(mUsbHandler); 288 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_SET_CURRENT_FUNCTIONS, 289 UsbManager.FUNCTION_MTP)); 290 assertNotEquals(mUsbHandler.getEnabledFunctions() & UsbManager.FUNCTION_MTP, 0); 291 292 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_UPDATE_STATE, 1, 1)); 293 294 assertNotEquals(mUsbHandler.getEnabledFunctions() & UsbManager.FUNCTION_MTP, 0); 295 assertTrue(mUsbHandler.mBroadcastedIntent.getBooleanExtra(UsbManager.USB_CONNECTED, false)); 296 assertTrue(mUsbHandler.mBroadcastedIntent 297 .getBooleanExtra(UsbManager.USB_CONFIGURED, false)); 298 assertTrue(mUsbHandler.mBroadcastedIntent 299 .getBooleanExtra(UsbManager.USB_FUNCTION_MTP, false)); 300 } 301 302 @SmallTest 303 @Test 304 public void setScreenUnlockedFunctions() { 305 sendBootCompleteMessages(mUsbHandler); 306 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_UPDATE_SCREEN_LOCK, 0)); 307 308 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_SET_SCREEN_UNLOCKED_FUNCTIONS, 309 UsbManager.FUNCTION_MTP)); 310 assertNotEquals(mUsbHandler.getScreenUnlockedFunctions() & UsbManager.FUNCTION_MTP, 0); 311 assertNotEquals(mUsbHandler.getEnabledFunctions() & UsbManager.FUNCTION_MTP, 0); 312 verify(mEditor).putString(String.format(Locale.ENGLISH, 313 UsbDeviceManager.UNLOCKED_CONFIG_PREF, mUsbHandler.mCurrentUser), 314 UsbManager.USB_FUNCTION_MTP); 315 } 316 317 @SmallTest 318 @Test 319 public void unlockScreen() { 320 when(mSharedPreferences.getString(String.format(Locale.ENGLISH, 321 UsbDeviceManager.UNLOCKED_CONFIG_PREF, mUsbHandler.mCurrentUser), "")) 322 .thenReturn(UsbManager.USB_FUNCTION_MTP); 323 mUsbHandler = new MockUsbHandler(FgThread.get().getLooper(), 324 InstrumentationRegistry.getContext(), mUsbDeviceManager, mUsbDebuggingManager, 325 mUsbAlsaManager, mUsbSettingsManager); 326 sendBootCompleteMessages(mUsbHandler); 327 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_UPDATE_SCREEN_LOCK, 1)); 328 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_UPDATE_SCREEN_LOCK, 0)); 329 330 assertNotEquals(mUsbHandler.getScreenUnlockedFunctions() & UsbManager.FUNCTION_MTP, 0); 331 assertNotEquals(mUsbHandler.getEnabledFunctions() & UsbManager.FUNCTION_MTP, 0); 332 } 333 334 private static void sendBootCompleteMessages(Handler handler) { 335 handler.handleMessage(handler.obtainMessage(MSG_BOOT_COMPLETED)); 336 handler.handleMessage(handler.obtainMessage(MSG_SYSTEM_READY)); 337 } 338}