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