TestUtil.java revision af5ea38b8c51f0878e4070671e240f693f3ad796
1b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono/* 2b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono * Copyright (C) 2015 The Android Open Source Project 3b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono * 4b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono * Licensed under the Apache License, Version 2.0 (the "License"); 5b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono * you may not use this file except in compliance with the License. 6b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono * You may obtain a copy of the License at 7b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono * 8b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono * http://www.apache.org/licenses/LICENSE-2.0 9b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono * 10b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono * Unless required by applicable law or agreed to in writing, software 11b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono * distributed under the License is distributed on an "AS IS" BASIS, 12b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono * See the License for the specific language governing permissions and 14b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono * limitations under the License. 15b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono */ 16b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono 17b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hironopackage com.android.mtp; 18b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono 19b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hironoimport android.hardware.usb.UsbDevice; 20b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hironoimport android.hardware.usb.UsbDeviceConnection; 21b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hironoimport android.hardware.usb.UsbManager; 22b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono 23b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hironoimport java.io.IOException; 24b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hironoimport java.util.HashMap; 25b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hironoimport junit.framework.Assert; 26b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono 27b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono/** 28b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono * Static utility methods for testing. 29b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono */ 3099b58052f85c18272e63047b471edfd8089c09d3Daichi Hironofinal class TestUtil { 31b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono private TestUtil() {} 32b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono 33b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono /** 34b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono * Requests permission for a MTP device and returns the first MTP device that has at least one 35b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono * storage. 36b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono */ 37b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono static UsbDevice setupMtpDevice( 38b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono TestResultInstrumentation instrumentation, 39b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono UsbManager usbManager, 4099b58052f85c18272e63047b471edfd8089c09d3Daichi Hirono MtpManager manager) throws InterruptedException, IOException { 41b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono for (int i = 0; i < 2; i++) { 42af5ea38b8c51f0878e4070671e240f693f3ad796Daichi Hirono final UsbDevice device = findMtpDevice(instrumentation, usbManager, manager); 43b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono try { 44b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono waitForStorages(instrumentation, manager, device.getDeviceId()); 45b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono return device; 46b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono } catch (IOException exp) { 47b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono // When the MTP device is Android, and it changes the USB device type from 48b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono // "Charging" to "MTP", the device ID will be updated. We need to find a device 49b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono // again. 50b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono continue; 51b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono } 52b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono } 53b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono throw new IOException("Failed to obtain MTP devices"); 54b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono } 55b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono 56b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono private static UsbDevice findMtpDevice( 57b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono TestResultInstrumentation instrumentation, 58af5ea38b8c51f0878e4070671e240f693f3ad796Daichi Hirono UsbManager usbManager, 59af5ea38b8c51f0878e4070671e240f693f3ad796Daichi Hirono MtpManager manager) throws InterruptedException { 60b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono while (true) { 61b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono final HashMap<String,UsbDevice> devices = usbManager.getDeviceList(); 62b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono if (devices.size() == 0) { 63b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono instrumentation.show("Wait for devices."); 64b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono Thread.sleep(1000); 65b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono continue; 66b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono } 67b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono final UsbDevice device = devices.values().iterator().next(); 68af5ea38b8c51f0878e4070671e240f693f3ad796Daichi Hirono try { 69af5ea38b8c51f0878e4070671e240f693f3ad796Daichi Hirono manager.openDevice(device.getDeviceId()); 70af5ea38b8c51f0878e4070671e240f693f3ad796Daichi Hirono } catch (IOException e) { 71af5ea38b8c51f0878e4070671e240f693f3ad796Daichi Hirono // Maybe other application is using the device. 72af5ea38b8c51f0878e4070671e240f693f3ad796Daichi Hirono // Force to obtain ownership of the device so that we can use the device next call 73af5ea38b8c51f0878e4070671e240f693f3ad796Daichi Hirono // of findMtpDevice. 74af5ea38b8c51f0878e4070671e240f693f3ad796Daichi Hirono instrumentation.show("Tries to get ownership of MTP device."); 75af5ea38b8c51f0878e4070671e240f693f3ad796Daichi Hirono final UsbDeviceConnection connection = usbManager.openDevice(device); 76af5ea38b8c51f0878e4070671e240f693f3ad796Daichi Hirono if (connection == null) { 77af5ea38b8c51f0878e4070671e240f693f3ad796Daichi Hirono Assert.fail("Cannot open USB connection."); 78af5ea38b8c51f0878e4070671e240f693f3ad796Daichi Hirono return null; 79af5ea38b8c51f0878e4070671e240f693f3ad796Daichi Hirono } 80af5ea38b8c51f0878e4070671e240f693f3ad796Daichi Hirono for (int i = 0; i < device.getInterfaceCount(); i++) { 81af5ea38b8c51f0878e4070671e240f693f3ad796Daichi Hirono // Since the test runs real environment, we need to call claim interface with 82af5ea38b8c51f0878e4070671e240f693f3ad796Daichi Hirono // force = true to rob interfaces from other applications. 83af5ea38b8c51f0878e4070671e240f693f3ad796Daichi Hirono connection.claimInterface(device.getInterface(i), true); 84af5ea38b8c51f0878e4070671e240f693f3ad796Daichi Hirono connection.releaseInterface(device.getInterface(i)); 85af5ea38b8c51f0878e4070671e240f693f3ad796Daichi Hirono } 86af5ea38b8c51f0878e4070671e240f693f3ad796Daichi Hirono connection.close(); 87af5ea38b8c51f0878e4070671e240f693f3ad796Daichi Hirono Thread.sleep(1000); 88af5ea38b8c51f0878e4070671e240f693f3ad796Daichi Hirono continue; 89b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono } 90b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono return device; 91b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono } 92b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono } 93b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono 94b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono private static void waitForStorages( 95b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono TestResultInstrumentation instrumentation, 96b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono MtpManager manager, 9720754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono int deviceId) throws InterruptedException, IOException { 98b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono while (true) { 9920754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono MtpDeviceRecord device = null; 10020754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono for (final MtpDeviceRecord deviceCandidate : manager.getDevices()) { 10120754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono if (deviceCandidate.deviceId == deviceId) { 10220754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono device = deviceCandidate; 10320754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono break; 10420754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono } 10520754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono } 10620754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono if (device == null) { 10720754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono throw new IOException("Device was detached."); 10820754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono } 10920754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono if (device.roots.length == 0) { 110b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono instrumentation.show("Wait for storages."); 111b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono Thread.sleep(1000); 112b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono continue; 113b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono } 114b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono return; 115b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono } 116b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono } 117b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono} 118