blob: 8805d19293ebe7f8a341f2b5d1cebed83bd2e06d [file] [log] [blame]
Daichi Hironob255f582015-12-02 12:20:25 +09001/*
2 * Copyright (C) 2015 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
17package com.android.mtp;
18
Daichi Hironob255f582015-12-02 12:20:25 +090019import android.hardware.usb.UsbDevice;
20import android.hardware.usb.UsbDeviceConnection;
21import android.hardware.usb.UsbManager;
Daichi Hirono0f325372016-02-21 15:50:30 +090022import android.mtp.MtpConstants;
Daichi Hirono1d4779c2016-01-06 16:43:32 +090023import android.os.SystemClock;
Daichi Hironob255f582015-12-02 12:20:25 +090024
Daichi Hironof578fa22016-02-19 18:05:42 +090025import java.io.FileNotFoundException;
Daichi Hironob255f582015-12-02 12:20:25 +090026import java.io.IOException;
27import java.util.HashMap;
Daichi Hirono1d4779c2016-01-06 16:43:32 +090028import java.util.Objects;
29
Daichi Hironob255f582015-12-02 12:20:25 +090030/**
31 * Static utility methods for testing.
32 */
Daichi Hirono99b58052015-12-03 18:09:16 +090033final class TestUtil {
Daichi Hironob255f582015-12-02 12:20:25 +090034 private TestUtil() {}
35
Daichi Hirono0f325372016-02-21 15:50:30 +090036 static final int[] OPERATIONS_SUPPORTED = new int[] {
37 MtpConstants.OPERATION_GET_PARTIAL_OBJECT,
38 MtpConstants.OPERATION_SEND_OBJECT,
39 MtpConstants.OPERATION_SEND_OBJECT_INFO,
Daichi Hirono61ba9232016-02-26 12:58:39 +090040 MtpConstants.OPERATION_DELETE_OBJECT,
Daichi Hirono64111e02016-03-24 21:07:38 +090041 MtpConstants.OPERATION_GET_OBJECT_PROP_DESC,
42 MtpConstants.OPERATION_GET_OBJECT_PROP_VALUE
Daichi Hirono0f325372016-02-21 15:50:30 +090043 };
44
Daichi Hironob255f582015-12-02 12:20:25 +090045 /**
46 * Requests permission for a MTP device and returns the first MTP device that has at least one
47 * storage.
Daichi Hironob255f582015-12-02 12:20:25 +090048 */
49 static UsbDevice setupMtpDevice(
50 TestResultInstrumentation instrumentation,
51 UsbManager usbManager,
Daichi Hirono1d4779c2016-01-06 16:43:32 +090052 MtpManager manager) {
53 while (true) {
Daichi Hironob255f582015-12-02 12:20:25 +090054 try {
Daichi Hironoab03cb12016-01-11 15:47:21 +090055 final UsbDevice device = findMtpDevice(usbManager, manager);
Daichi Hironob255f582015-12-02 12:20:25 +090056 waitForStorages(instrumentation, manager, device.getDeviceId());
57 return device;
58 } catch (IOException exp) {
Daichi Hirono1d4779c2016-01-06 16:43:32 +090059 instrumentation.show(Objects.toString(exp.getMessage()));
60 SystemClock.sleep(1000);
Daichi Hironob255f582015-12-02 12:20:25 +090061 // When the MTP device is Android, and it changes the USB device type from
62 // "Charging" to "MTP", the device ID will be updated. We need to find a device
63 // again.
64 continue;
65 }
66 }
Daichi Hironob255f582015-12-02 12:20:25 +090067 }
68
Daichi Hironof578fa22016-02-19 18:05:42 +090069 static void addTestDevice(MtpDatabase database) throws FileNotFoundException {
70 database.getMapper().startAddingDocuments(null);
71 database.getMapper().putDeviceDocument(new MtpDeviceRecord(
Daichi Hirono0f325372016-02-21 15:50:30 +090072 0, "Device", "device_key", /* opened is */ true, new MtpRoot[0],
73 OPERATIONS_SUPPORTED, null));
Daichi Hironof578fa22016-02-19 18:05:42 +090074 database.getMapper().stopAddingDocuments(null);
75 }
76
77 static void addTestStorage(MtpDatabase database, String parentId) throws FileNotFoundException {
78 database.getMapper().startAddingDocuments(parentId);
Daichi Hirono0f325372016-02-21 15:50:30 +090079 database.getMapper().putStorageDocuments(parentId, OPERATIONS_SUPPORTED, new MtpRoot[] {
Daichi Hironof578fa22016-02-19 18:05:42 +090080 new MtpRoot(0, 100, "Storage", 1024, 1024, ""),
81 });
82 database.getMapper().stopAddingDocuments(parentId);
83 }
84
Daichi Hironob255f582015-12-02 12:20:25 +090085 private static UsbDevice findMtpDevice(
Daichi Hironoaf5ea382016-01-07 18:24:59 +090086 UsbManager usbManager,
Daichi Hironoab03cb12016-01-11 15:47:21 +090087 MtpManager manager) throws IOException {
88 final HashMap<String,UsbDevice> devices = usbManager.getDeviceList();
89 if (devices.size() == 0) {
90 throw new IOException("Device not found.");
Daichi Hironob255f582015-12-02 12:20:25 +090091 }
Daichi Hironoab03cb12016-01-11 15:47:21 +090092 final UsbDevice device = devices.values().iterator().next();
93 // Tries to get ownership of the device in case that another application use it.
94 if (usbManager.hasPermission(device)) {
95 final UsbDeviceConnection connection = usbManager.openDevice(device);
96 for (int i = 0; i < device.getInterfaceCount(); i++) {
97 // Since the test runs real environment, we need to call claim interface with
98 // force = true to rob interfaces from other applications.
99 connection.claimInterface(device.getInterface(i), true);
100 connection.releaseInterface(device.getInterface(i));
101 }
102 connection.close();
103 }
104 manager.openDevice(device.getDeviceId());
105 return device;
Daichi Hironob255f582015-12-02 12:20:25 +0900106 }
107
Daichi Hironob255f582015-12-02 12:20:25 +0900108 private static void waitForStorages(
109 TestResultInstrumentation instrumentation,
110 MtpManager manager,
Daichi Hirono1d4779c2016-01-06 16:43:32 +0900111 int deviceId) throws IOException {
Daichi Hironob255f582015-12-02 12:20:25 +0900112 while (true) {
Daichi Hirono20754c52015-12-15 18:52:26 +0900113 MtpDeviceRecord device = null;
114 for (final MtpDeviceRecord deviceCandidate : manager.getDevices()) {
115 if (deviceCandidate.deviceId == deviceId) {
116 device = deviceCandidate;
117 break;
118 }
119 }
120 if (device == null) {
121 throw new IOException("Device was detached.");
122 }
123 if (device.roots.length == 0) {
Daichi Hironob255f582015-12-02 12:20:25 +0900124 instrumentation.show("Wait for storages.");
Daichi Hirono1d4779c2016-01-06 16:43:32 +0900125 SystemClock.sleep(1000);
Daichi Hironob255f582015-12-02 12:20:25 +0900126 continue;
127 }
128 return;
129 }
130 }
131}