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.helper.aoa; 17 18 import static com.android.helper.aoa.AoaDevice.GOOGLE_VID; 19 20 import static org.junit.Assert.assertEquals; 21 import static org.junit.Assert.assertNotNull; 22 import static org.junit.Assert.assertNull; 23 import static org.mockito.ArgumentMatchers.any; 24 import static org.mockito.ArgumentMatchers.eq; 25 import static org.mockito.Mockito.doReturn; 26 import static org.mockito.Mockito.mock; 27 import static org.mockito.Mockito.never; 28 import static org.mockito.Mockito.spy; 29 import static org.mockito.Mockito.times; 30 import static org.mockito.Mockito.verify; 31 import static org.mockito.Mockito.when; 32 33 import com.google.common.collect.Sets; 34 import com.sun.jna.Memory; 35 import com.sun.jna.Pointer; 36 import com.sun.jna.ptr.PointerByReference; 37 38 import org.junit.Before; 39 import org.junit.Test; 40 import org.junit.runner.RunWith; 41 import org.junit.runners.JUnit4; 42 43 import java.util.HashSet; 44 45 /** Unit tests for {@link UsbHelper} */ 46 @RunWith(JUnit4.class) 47 public class UsbHelperTest { 48 49 private static final String SERIAL_NUMBER = "serial-number"; 50 private static final int ACCESSORY_PID = 0x2D00; 51 52 private UsbHelper mHelper; 53 54 private IUsbNative mUsb; 55 private UsbDevice mDevice; 56 57 @Before setUp()58 public void setUp() { 59 // create dummy pointer 60 Pointer pointer = new Memory(1); 61 62 mUsb = mock(IUsbNative.class); 63 // populate context when initialized 64 when(mUsb.libusb_init(any())) 65 .then( 66 invocation -> { 67 PointerByReference context = 68 (PointerByReference) invocation.getArguments()[0]; 69 context.setValue(pointer); 70 return null; 71 }); 72 // find device pointer when listing devices 73 when(mUsb.libusb_get_device_list(any(), any())) 74 .then( 75 invocation -> { 76 PointerByReference list = 77 (PointerByReference) invocation.getArguments()[1]; 78 list.setValue(pointer); 79 return 1; 80 }); 81 82 // device is valid, has right serial number, and is in accessory mode by default 83 mDevice = mock(UsbDevice.class); 84 when(mDevice.isValid()).thenReturn(true); 85 when(mDevice.getSerialNumber()).thenReturn(SERIAL_NUMBER); 86 when(mDevice.getVendorId()).thenReturn(GOOGLE_VID); 87 when(mDevice.getProductId()).thenReturn(ACCESSORY_PID); 88 89 mHelper = spy(new UsbHelper(mUsb)); 90 // always return the mocked device 91 doReturn(mDevice).when(mHelper).connect(any()); 92 } 93 94 @Test testContext()95 public void testContext() { 96 // initialized on creation 97 verify(mUsb, times(1)).libusb_init(any()); 98 99 // exited on close 100 mHelper.close(); 101 verify(mUsb, times(1)).libusb_exit(any()); 102 } 103 104 @Test testCheckResult()105 public void testCheckResult() { 106 // non-negative numbers are always valid 107 assertEquals(0, mHelper.checkResult(0)); 108 assertEquals(1, mHelper.checkResult(1)); 109 assertEquals(Integer.MAX_VALUE, mHelper.checkResult(Integer.MAX_VALUE)); 110 } 111 112 @Test(expected = UsbException.class) testCheckResult_invalid()113 public void testCheckResult_invalid() { 114 // negative numbers indicate errors 115 mHelper.checkResult(-1); 116 } 117 118 @Test testGetSerialNumbers()119 public void testGetSerialNumbers() { 120 assertEquals(Sets.newHashSet(SERIAL_NUMBER), mHelper.getSerialNumbers(false)); 121 122 // device list and device were closed 123 verify(mDevice, times(1)).close(); 124 verify(mUsb, times(1)).libusb_free_device_list(any(), eq(true)); 125 } 126 127 @Test testGetSerialNumbers_aoaOnly()128 public void testGetSerialNumbers_aoaOnly() { 129 when(mDevice.isAoaCompatible()).thenReturn(false); 130 assertEquals(Sets.newHashSet(SERIAL_NUMBER), mHelper.getSerialNumbers(false)); 131 assertEquals(new HashSet<>(), mHelper.getSerialNumbers(true)); 132 133 when(mDevice.isAoaCompatible()).thenReturn(true); 134 assertEquals(Sets.newHashSet(SERIAL_NUMBER), mHelper.getSerialNumbers(false)); 135 assertEquals(Sets.newHashSet(SERIAL_NUMBER), mHelper.getSerialNumbers(true)); 136 } 137 138 @Test testGetDevice()139 public void testGetDevice() { 140 // valid connection was found and opened 141 assertEquals(mDevice, mHelper.getDevice(SERIAL_NUMBER)); 142 143 // device list was closed, but not connection 144 verify(mDevice, never()).close(); 145 verify(mUsb, times(1)).libusb_free_device_list(any(), eq(true)); 146 } 147 148 @Test testGetDevice_invalid()149 public void testGetDevice_invalid() { 150 when(mDevice.getSerialNumber()).thenReturn(null); 151 152 // valid device not found 153 assertNull(mHelper.getDevice(SERIAL_NUMBER)); 154 155 // connection and device list were closed 156 verify(mDevice, times(1)).close(); 157 verify(mUsb, times(1)).libusb_free_device_list(any(), eq(true)); 158 } 159 160 @Test testGetAoaDevice()161 public void testGetAoaDevice() { 162 when(mDevice.isAoaCompatible()).thenReturn(true); 163 assertNotNull(mHelper.getAoaDevice(SERIAL_NUMBER)); 164 } 165 166 @Test testGetAoaDevice_incompatible()167 public void testGetAoaDevice_incompatible() { 168 when(mDevice.isAoaCompatible()).thenReturn(false); 169 assertNull(mHelper.getAoaDevice(SERIAL_NUMBER)); 170 } 171 } 172