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 SharedPreferences mSharedPreferences; 67 @Mock 68 private SharedPreferences.Editor mEditor; 69 70 private MockUsbHandler mUsbHandler; 71 72 private static final int MSG_UPDATE_STATE = 0; 73 private static final int MSG_ENABLE_ADB = 1; 74 private static final int MSG_SET_CURRENT_FUNCTIONS = 2; 75 private static final int MSG_SYSTEM_READY = 3; 76 private static final int MSG_BOOT_COMPLETED = 4; 77 private static final int MSG_USER_SWITCHED = 5; 78 private static final int MSG_UPDATE_USER_RESTRICTIONS = 6; 79 private static final int MSG_SET_SCREEN_UNLOCKED_FUNCTIONS = 12; 80 private static final int MSG_UPDATE_SCREEN_LOCK = 13; 81 82 private Map<String, String> mMockProperties; 83 private Map<String, Integer> mMockGlobalSettings; 84 85 private class MockUsbHandler extends UsbDeviceManager.UsbHandler { 86 boolean mIsUsbTransferAllowed; 87 Intent mBroadcastedIntent; 88 MockUsbHandler(Looper looper, Context context, UsbDeviceManager deviceManager, UsbAlsaManager alsaManager, UsbSettingsManager settingsManager)89 MockUsbHandler(Looper looper, Context context, UsbDeviceManager deviceManager, 90 UsbAlsaManager alsaManager, UsbSettingsManager settingsManager) { 91 super(looper, context, deviceManager, alsaManager, settingsManager); 92 mUseUsbNotification = false; 93 mIsUsbTransferAllowed = true; 94 mCurrentUsbFunctionsReceived = true; 95 } 96 97 @Override setEnabledFunctions(long functions, boolean force)98 protected void setEnabledFunctions(long functions, boolean force) { 99 mCurrentFunctions = functions; 100 } 101 102 @Override setSystemProperty(String property, String value)103 protected void setSystemProperty(String property, String value) { 104 mMockProperties.put(property, value); 105 } 106 107 @Override putGlobalSettings(ContentResolver resolver, String setting, int val)108 protected void putGlobalSettings(ContentResolver resolver, String setting, int val) { 109 mMockGlobalSettings.put(setting, val); 110 } 111 112 @Override getSystemProperty(String property, String def)113 protected String getSystemProperty(String property, String def) { 114 if (mMockProperties.containsKey(property)) { 115 return mMockProperties.get(property); 116 } 117 return def; 118 } 119 120 @Override isUsbTransferAllowed()121 protected boolean isUsbTransferAllowed() { 122 return mIsUsbTransferAllowed; 123 } 124 125 @Override getPinnedSharedPrefs(Context context)126 protected SharedPreferences getPinnedSharedPrefs(Context context) { 127 return mSharedPreferences; 128 } 129 130 @Override sendStickyBroadcast(Intent intent)131 protected void sendStickyBroadcast(Intent intent) { 132 mBroadcastedIntent = intent; 133 } 134 } 135 136 @Before before()137 public void before() { 138 MockitoAnnotations.initMocks(this); 139 mMockProperties = new HashMap<>(); 140 mMockGlobalSettings = new HashMap<>(); 141 when(mSharedPreferences.edit()).thenReturn(mEditor); 142 143 mUsbHandler = new MockUsbHandler(FgThread.get().getLooper(), 144 InstrumentationRegistry.getContext(), mUsbDeviceManager, mUsbAlsaManager, 145 mUsbSettingsManager); 146 } 147 148 @SmallTest 149 @Test setFunctionsMtp()150 public void setFunctionsMtp() { 151 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_SET_CURRENT_FUNCTIONS, 152 UsbManager.FUNCTION_MTP)); 153 assertNotEquals(mUsbHandler.getEnabledFunctions() & UsbManager.FUNCTION_MTP, 0); 154 } 155 156 @SmallTest 157 @Test setFunctionsPtp()158 public void setFunctionsPtp() { 159 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_SET_CURRENT_FUNCTIONS, 160 UsbManager.FUNCTION_PTP)); 161 assertNotEquals(mUsbHandler.getEnabledFunctions() & UsbManager.FUNCTION_PTP, 0); 162 } 163 164 @SmallTest 165 @Test setFunctionsMidi()166 public void setFunctionsMidi() { 167 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_SET_CURRENT_FUNCTIONS, 168 UsbManager.FUNCTION_MIDI)); 169 assertNotEquals(mUsbHandler.getEnabledFunctions() & UsbManager.FUNCTION_MIDI, 0); 170 } 171 172 @SmallTest 173 @Test setFunctionsRndis()174 public void setFunctionsRndis() { 175 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_SET_CURRENT_FUNCTIONS, 176 UsbManager.FUNCTION_RNDIS)); 177 assertNotEquals(mUsbHandler.getEnabledFunctions() & UsbManager.FUNCTION_RNDIS, 0); 178 } 179 180 @SmallTest 181 @Test enableAdb()182 public void enableAdb() { 183 sendBootCompleteMessages(mUsbHandler); 184 Message msg = mUsbHandler.obtainMessage(MSG_ENABLE_ADB); 185 msg.arg1 = 1; 186 mUsbHandler.handleMessage(msg); 187 assertEquals(mUsbHandler.getEnabledFunctions(), UsbManager.FUNCTION_NONE); 188 assertEquals(mMockProperties.get(UsbDeviceManager.UsbHandler 189 .USB_PERSISTENT_CONFIG_PROPERTY), UsbManager.USB_FUNCTION_ADB); 190 assertTrue(mUsbHandler.isAdbEnabled()); 191 192 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_UPDATE_STATE, 1, 1)); 193 194 assertTrue(mUsbHandler.mBroadcastedIntent.getBooleanExtra(UsbManager.USB_CONNECTED, false)); 195 assertTrue(mUsbHandler.mBroadcastedIntent 196 .getBooleanExtra(UsbManager.USB_CONFIGURED, false)); 197 assertTrue(mUsbHandler.mBroadcastedIntent 198 .getBooleanExtra(UsbManager.USB_FUNCTION_ADB, false)); 199 } 200 201 @SmallTest 202 @Test disableAdb()203 public void disableAdb() { 204 mMockProperties.put(UsbDeviceManager.UsbHandler.USB_PERSISTENT_CONFIG_PROPERTY, 205 UsbManager.USB_FUNCTION_ADB); 206 mUsbHandler = new MockUsbHandler(FgThread.get().getLooper(), 207 InstrumentationRegistry.getContext(), mUsbDeviceManager, mUsbAlsaManager, 208 mUsbSettingsManager); 209 210 sendBootCompleteMessages(mUsbHandler); 211 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_ENABLE_ADB, 0)); 212 assertEquals(mUsbHandler.getEnabledFunctions(), UsbManager.FUNCTION_NONE); 213 assertFalse(mUsbHandler.isAdbEnabled()); 214 assertEquals(mMockProperties.get(UsbDeviceManager.UsbHandler 215 .USB_PERSISTENT_CONFIG_PROPERTY), ""); 216 } 217 218 @SmallTest 219 @Test bootCompletedCharging()220 public void bootCompletedCharging() { 221 sendBootCompleteMessages(mUsbHandler); 222 assertEquals(mUsbHandler.getEnabledFunctions(), UsbManager.FUNCTION_NONE); 223 } 224 225 @SmallTest 226 @Test bootCompletedAdbEnabled()227 public void bootCompletedAdbEnabled() { 228 mMockProperties.put(UsbDeviceManager.UsbHandler.USB_PERSISTENT_CONFIG_PROPERTY, "adb"); 229 mUsbHandler = new MockUsbHandler(FgThread.get().getLooper(), 230 InstrumentationRegistry.getContext(), mUsbDeviceManager, mUsbAlsaManager, 231 mUsbSettingsManager); 232 233 sendBootCompleteMessages(mUsbHandler); 234 assertEquals(mUsbHandler.getEnabledFunctions(), UsbManager.FUNCTION_NONE); 235 assertEquals(mMockGlobalSettings.get(Settings.Global.ADB_ENABLED).intValue(), 1); 236 assertTrue(mUsbHandler.isAdbEnabled()); 237 } 238 239 @SmallTest 240 @Test userSwitchedDisablesMtp()241 public void userSwitchedDisablesMtp() { 242 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_SET_CURRENT_FUNCTIONS, 243 UsbManager.FUNCTION_MTP)); 244 assertNotEquals(mUsbHandler.getEnabledFunctions() & UsbManager.FUNCTION_MTP, 0); 245 246 Message msg = mUsbHandler.obtainMessage(MSG_USER_SWITCHED); 247 msg.arg1 = ActivityManager.getCurrentUser() + 1; 248 mUsbHandler.handleMessage(msg); 249 assertEquals(mUsbHandler.getEnabledFunctions(), UsbManager.FUNCTION_NONE); 250 } 251 252 @SmallTest 253 @Test changedRestrictionsDisablesMtp()254 public void changedRestrictionsDisablesMtp() { 255 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_SET_CURRENT_FUNCTIONS, 256 UsbManager.FUNCTION_MTP)); 257 assertNotEquals(mUsbHandler.getEnabledFunctions() & UsbManager.FUNCTION_MTP, 0); 258 259 mUsbHandler.mIsUsbTransferAllowed = false; 260 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_UPDATE_USER_RESTRICTIONS)); 261 assertEquals(mUsbHandler.getEnabledFunctions(), UsbManager.FUNCTION_NONE); 262 } 263 264 @SmallTest 265 @Test disconnectResetsCharging()266 public void disconnectResetsCharging() { 267 sendBootCompleteMessages(mUsbHandler); 268 269 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_SET_CURRENT_FUNCTIONS, 270 UsbManager.FUNCTION_MTP)); 271 assertNotEquals(mUsbHandler.getEnabledFunctions() & UsbManager.FUNCTION_MTP, 0); 272 273 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_UPDATE_STATE, 0, 0)); 274 275 assertEquals(mUsbHandler.getEnabledFunctions(), UsbManager.FUNCTION_NONE); 276 } 277 278 @SmallTest 279 @Test configuredSendsBroadcast()280 public void configuredSendsBroadcast() { 281 sendBootCompleteMessages(mUsbHandler); 282 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_SET_CURRENT_FUNCTIONS, 283 UsbManager.FUNCTION_MTP)); 284 assertNotEquals(mUsbHandler.getEnabledFunctions() & UsbManager.FUNCTION_MTP, 0); 285 286 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_UPDATE_STATE, 1, 1)); 287 288 assertNotEquals(mUsbHandler.getEnabledFunctions() & UsbManager.FUNCTION_MTP, 0); 289 assertTrue(mUsbHandler.mBroadcastedIntent.getBooleanExtra(UsbManager.USB_CONNECTED, false)); 290 assertTrue(mUsbHandler.mBroadcastedIntent 291 .getBooleanExtra(UsbManager.USB_CONFIGURED, false)); 292 assertTrue(mUsbHandler.mBroadcastedIntent 293 .getBooleanExtra(UsbManager.USB_FUNCTION_MTP, false)); 294 } 295 296 @SmallTest 297 @Test setScreenUnlockedFunctions()298 public void setScreenUnlockedFunctions() { 299 sendBootCompleteMessages(mUsbHandler); 300 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_UPDATE_SCREEN_LOCK, 0)); 301 302 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_SET_SCREEN_UNLOCKED_FUNCTIONS, 303 UsbManager.FUNCTION_MTP)); 304 assertNotEquals(mUsbHandler.getScreenUnlockedFunctions() & UsbManager.FUNCTION_MTP, 0); 305 assertNotEquals(mUsbHandler.getEnabledFunctions() & UsbManager.FUNCTION_MTP, 0); 306 verify(mEditor).putString(String.format(Locale.ENGLISH, 307 UsbDeviceManager.UNLOCKED_CONFIG_PREF, mUsbHandler.mCurrentUser), 308 UsbManager.USB_FUNCTION_MTP); 309 } 310 311 @SmallTest 312 @Test unlockScreen()313 public void unlockScreen() { 314 when(mSharedPreferences.getString(String.format(Locale.ENGLISH, 315 UsbDeviceManager.UNLOCKED_CONFIG_PREF, mUsbHandler.mCurrentUser), "")) 316 .thenReturn(UsbManager.USB_FUNCTION_MTP); 317 mUsbHandler = new MockUsbHandler(FgThread.get().getLooper(), 318 InstrumentationRegistry.getContext(), mUsbDeviceManager, mUsbAlsaManager, 319 mUsbSettingsManager); 320 sendBootCompleteMessages(mUsbHandler); 321 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_UPDATE_SCREEN_LOCK, 1)); 322 mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_UPDATE_SCREEN_LOCK, 0)); 323 324 assertNotEquals(mUsbHandler.getScreenUnlockedFunctions() & UsbManager.FUNCTION_MTP, 0); 325 assertNotEquals(mUsbHandler.getEnabledFunctions() & UsbManager.FUNCTION_MTP, 0); 326 } 327 sendBootCompleteMessages(Handler handler)328 private static void sendBootCompleteMessages(Handler handler) { 329 handler.handleMessage(handler.obtainMessage(MSG_BOOT_COMPLETED)); 330 handler.handleMessage(handler.obtainMessage(MSG_SYSTEM_READY)); 331 } 332 } 333