TestUtil.java revision f578fa275a535016f5322c88ad7a92e517d04a12
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; 221d4779c29a95114c89ec353a8899c0cc8eee3ba5Daichi Hironoimport android.os.SystemClock; 23b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono 24f578fa275a535016f5322c88ad7a92e517d04a12Daichi Hironoimport java.io.FileNotFoundException; 25b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hironoimport java.io.IOException; 26b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hironoimport java.util.HashMap; 271d4779c29a95114c89ec353a8899c0cc8eee3ba5Daichi Hironoimport java.util.Objects; 281d4779c29a95114c89ec353a8899c0cc8eee3ba5Daichi Hirono 29b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono/** 30b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono * Static utility methods for testing. 31b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono */ 3299b58052f85c18272e63047b471edfd8089c09d3Daichi Hironofinal class TestUtil { 33b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono private TestUtil() {} 34b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono 35b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono /** 36b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono * Requests permission for a MTP device and returns the first MTP device that has at least one 37b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono * storage. 38b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono */ 39b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono static UsbDevice setupMtpDevice( 40b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono TestResultInstrumentation instrumentation, 41b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono UsbManager usbManager, 421d4779c29a95114c89ec353a8899c0cc8eee3ba5Daichi Hirono MtpManager manager) { 431d4779c29a95114c89ec353a8899c0cc8eee3ba5Daichi Hirono while (true) { 44b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono try { 45ab03cb1b469940ab672850e0d2de3c78025260d3Daichi Hirono final UsbDevice device = findMtpDevice(usbManager, manager); 46b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono waitForStorages(instrumentation, manager, device.getDeviceId()); 47b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono return device; 48b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono } catch (IOException exp) { 491d4779c29a95114c89ec353a8899c0cc8eee3ba5Daichi Hirono instrumentation.show(Objects.toString(exp.getMessage())); 501d4779c29a95114c89ec353a8899c0cc8eee3ba5Daichi Hirono SystemClock.sleep(1000); 51b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono // When the MTP device is Android, and it changes the USB device type from 52b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono // "Charging" to "MTP", the device ID will be updated. We need to find a device 53b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono // again. 54b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono continue; 55b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono } 56b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono } 57b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono } 58b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono 59f578fa275a535016f5322c88ad7a92e517d04a12Daichi Hirono static void addTestDevice(MtpDatabase database) throws FileNotFoundException { 60f578fa275a535016f5322c88ad7a92e517d04a12Daichi Hirono database.getMapper().startAddingDocuments(null); 61f578fa275a535016f5322c88ad7a92e517d04a12Daichi Hirono database.getMapper().putDeviceDocument(new MtpDeviceRecord( 62f578fa275a535016f5322c88ad7a92e517d04a12Daichi Hirono 0, "Device", "device_key", /* opened is */ true, new MtpRoot[0], null, 63f578fa275a535016f5322c88ad7a92e517d04a12Daichi Hirono null)); 64f578fa275a535016f5322c88ad7a92e517d04a12Daichi Hirono database.getMapper().stopAddingDocuments(null); 65f578fa275a535016f5322c88ad7a92e517d04a12Daichi Hirono } 66f578fa275a535016f5322c88ad7a92e517d04a12Daichi Hirono 67f578fa275a535016f5322c88ad7a92e517d04a12Daichi Hirono static void addTestStorage(MtpDatabase database, String parentId) throws FileNotFoundException { 68f578fa275a535016f5322c88ad7a92e517d04a12Daichi Hirono database.getMapper().startAddingDocuments(parentId); 69f578fa275a535016f5322c88ad7a92e517d04a12Daichi Hirono database.getMapper().putStorageDocuments(parentId, new MtpRoot[] { 70f578fa275a535016f5322c88ad7a92e517d04a12Daichi Hirono new MtpRoot(0, 100, "Storage", 1024, 1024, ""), 71f578fa275a535016f5322c88ad7a92e517d04a12Daichi Hirono }); 72f578fa275a535016f5322c88ad7a92e517d04a12Daichi Hirono database.getMapper().stopAddingDocuments(parentId); 73f578fa275a535016f5322c88ad7a92e517d04a12Daichi Hirono } 74f578fa275a535016f5322c88ad7a92e517d04a12Daichi Hirono 75b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono private static UsbDevice findMtpDevice( 76af5ea38b8c51f0878e4070671e240f693f3ad796Daichi Hirono UsbManager usbManager, 77ab03cb1b469940ab672850e0d2de3c78025260d3Daichi Hirono MtpManager manager) throws IOException { 78ab03cb1b469940ab672850e0d2de3c78025260d3Daichi Hirono final HashMap<String,UsbDevice> devices = usbManager.getDeviceList(); 79ab03cb1b469940ab672850e0d2de3c78025260d3Daichi Hirono if (devices.size() == 0) { 80ab03cb1b469940ab672850e0d2de3c78025260d3Daichi Hirono throw new IOException("Device not found."); 81ab03cb1b469940ab672850e0d2de3c78025260d3Daichi Hirono } 82ab03cb1b469940ab672850e0d2de3c78025260d3Daichi Hirono final UsbDevice device = devices.values().iterator().next(); 83ab03cb1b469940ab672850e0d2de3c78025260d3Daichi Hirono // Tries to get ownership of the device in case that another application use it. 84ab03cb1b469940ab672850e0d2de3c78025260d3Daichi Hirono if (usbManager.hasPermission(device)) { 85ab03cb1b469940ab672850e0d2de3c78025260d3Daichi Hirono final UsbDeviceConnection connection = usbManager.openDevice(device); 86ab03cb1b469940ab672850e0d2de3c78025260d3Daichi Hirono for (int i = 0; i < device.getInterfaceCount(); i++) { 87ab03cb1b469940ab672850e0d2de3c78025260d3Daichi Hirono // Since the test runs real environment, we need to call claim interface with 88ab03cb1b469940ab672850e0d2de3c78025260d3Daichi Hirono // force = true to rob interfaces from other applications. 89ab03cb1b469940ab672850e0d2de3c78025260d3Daichi Hirono connection.claimInterface(device.getInterface(i), true); 90ab03cb1b469940ab672850e0d2de3c78025260d3Daichi Hirono connection.releaseInterface(device.getInterface(i)); 91b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono } 92ab03cb1b469940ab672850e0d2de3c78025260d3Daichi Hirono connection.close(); 93b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono } 94ab03cb1b469940ab672850e0d2de3c78025260d3Daichi Hirono manager.openDevice(device.getDeviceId()); 95ab03cb1b469940ab672850e0d2de3c78025260d3Daichi Hirono return device; 96b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono } 97b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono 98b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono private static void waitForStorages( 99b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono TestResultInstrumentation instrumentation, 100b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono MtpManager manager, 1011d4779c29a95114c89ec353a8899c0cc8eee3ba5Daichi Hirono int deviceId) throws IOException { 102b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono while (true) { 10320754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono MtpDeviceRecord device = null; 10420754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono for (final MtpDeviceRecord deviceCandidate : manager.getDevices()) { 10520754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono if (deviceCandidate.deviceId == deviceId) { 10620754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono device = deviceCandidate; 10720754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono break; 10820754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono } 10920754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono } 11020754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono if (device == null) { 11120754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono throw new IOException("Device was detached."); 11220754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono } 11320754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono if (device.roots.length == 0) { 114b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono instrumentation.show("Wait for storages."); 1151d4779c29a95114c89ec353a8899c0cc8eee3ba5Daichi Hirono SystemClock.sleep(1000); 116b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono continue; 117b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono } 118b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono return; 119b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono } 120b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono } 121b255f58904d7a2aa64ba9f03ed0ede3759fd03c5Daichi Hirono} 122