Home | History | Annotate | Download | only in usb
      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 
     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
     98         protected void setEnabledFunctions(long functions, boolean force) {
     99             mCurrentFunctions = functions;
    100         }
    101 
    102         @Override
    103         protected void setSystemProperty(String property, String value) {
    104             mMockProperties.put(property, value);
    105         }
    106 
    107         @Override
    108         protected void putGlobalSettings(ContentResolver resolver, String setting, int val) {
    109             mMockGlobalSettings.put(setting, val);
    110         }
    111 
    112         @Override
    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
    121         protected boolean isUsbTransferAllowed() {
    122             return mIsUsbTransferAllowed;
    123         }
    124 
    125         @Override
    126         protected SharedPreferences getPinnedSharedPrefs(Context context) {
    127             return mSharedPreferences;
    128         }
    129 
    130         @Override
    131         protected void sendStickyBroadcast(Intent intent) {
    132             mBroadcastedIntent = intent;
    133         }
    134     }
    135 
    136     @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
    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
    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
    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
    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
    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
    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
    220     public void bootCompletedCharging() {
    221         sendBootCompleteMessages(mUsbHandler);
    222         assertEquals(mUsbHandler.getEnabledFunctions(), UsbManager.FUNCTION_NONE);
    223     }
    224 
    225     @SmallTest
    226     @Test
    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
    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
    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
    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
    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
    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
    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 
    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