blob: 3043ce896a7e45f3690c295edba0b7dc8d7d56ec [file] [log] [blame]
Daichi Hirono09109562015-07-28 20:57:05 +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
19import android.content.Context;
Tomasz Mikolajewskib80a3cf2015-08-24 16:10:51 +090020import android.mtp.MtpObjectInfo;
Tomasz Mikolajewski52652ac2015-08-05 17:33:33 +090021import android.os.ParcelFileDescriptor;
Daichi Hirono20754c52015-12-15 18:52:26 +090022import android.util.SparseArray;
Daichi Hirono09109562015-07-28 20:57:05 +090023
24import java.io.IOException;
Daichi Hironoe5323b72015-07-29 16:10:47 +090025import java.util.Arrays;
Daichi Hirono09109562015-07-28 20:57:05 +090026import java.util.HashMap;
Daichi Hirono09109562015-07-28 20:57:05 +090027import java.util.Map;
Daichi Hirono09109562015-07-28 20:57:05 +090028
Daichi Hirono6ee4a1c2015-07-31 10:30:05 +090029public class TestMtpManager extends MtpManager {
Tomasz Mikolajewskib80a3cf2015-08-24 16:10:51 +090030 public static final int CREATED_DOCUMENT_HANDLE = 1000;
31
Daichi Hirono6baa16e2015-08-12 13:51:59 +090032 protected static String pack(int... args) {
Daichi Hironoe5323b72015-07-29 16:10:47 +090033 return Arrays.toString(args);
34 }
35
Daichi Hirono20754c52015-12-15 18:52:26 +090036 private final SparseArray<MtpDeviceRecord> mDevices = new SparseArray<>();
Tomasz Mikolajewskibb430fa2015-08-25 18:34:30 +090037 private final Map<String, MtpObjectInfo> mObjectInfos = new HashMap<>();
Daichi Hirono124d0602015-08-11 17:08:35 +090038 private final Map<String, int[]> mObjectHandles = new HashMap<>();
39 private final Map<String, byte[]> mThumbnailBytes = new HashMap<>();
Daichi Hirono124d0602015-08-11 17:08:35 +090040 private final Map<String, byte[]> mImportFileBytes = new HashMap<>();
Daichi Hirono09109562015-07-28 20:57:05 +090041
Daichi Hirono6ee4a1c2015-07-31 10:30:05 +090042 TestMtpManager(Context context) {
Daichi Hirono09109562015-07-28 20:57:05 +090043 super(context);
44 }
45
Daichi Hirono20754c52015-12-15 18:52:26 +090046 void addValidDevice(MtpDeviceRecord device) {
47 mDevices.put(device.deviceId, device);
Daichi Hirono09109562015-07-28 20:57:05 +090048 }
49
Tomasz Mikolajewskibb430fa2015-08-25 18:34:30 +090050 void setObjectHandles(int deviceId, int storageId, int parentHandle, int[] objectHandles) {
51 mObjectHandles.put(pack(deviceId, storageId, parentHandle), objectHandles);
Daichi Hirono124d0602015-08-11 17:08:35 +090052 }
53
Tomasz Mikolajewskibb430fa2015-08-25 18:34:30 +090054 void setObjectInfo(int deviceId, MtpObjectInfo objectInfo) {
55 mObjectInfos.put(pack(deviceId, objectInfo.getObjectHandle()), objectInfo);
Daichi Hironoe5323b72015-07-29 16:10:47 +090056 }
57
Tomasz Mikolajewski52652ac2015-08-05 17:33:33 +090058 void setImportFileBytes(int deviceId, int objectHandle, byte[] bytes) {
59 mImportFileBytes.put(pack(deviceId, objectHandle), bytes);
Daichi Hirono8ba41912015-07-30 21:22:57 +090060 }
61
Tomasz Mikolajewskib80a3cf2015-08-24 16:10:51 +090062 byte[] getImportFileBytes(int deviceId, int objectHandle) {
63 return mImportFileBytes.get(pack(deviceId, objectHandle));
64 }
65
Daichi Hirono3faa43a2015-08-05 17:15:35 +090066 void setThumbnail(int deviceId, int objectHandle, byte[] bytes) {
67 mThumbnailBytes.put(pack(deviceId, objectHandle), bytes);
68 }
69
Daichi Hirono09109562015-07-28 20:57:05 +090070 @Override
Daichi Hirono20754c52015-12-15 18:52:26 +090071 MtpDeviceRecord[] getDevices() {
72 final MtpDeviceRecord[] result = new MtpDeviceRecord[mDevices.size()];
73 for (int i = 0; i < mDevices.size(); i++) {
74 final MtpDeviceRecord device = mDevices.valueAt(i);
75 if (device.opened) {
76 result[i] = device;
77 } else {
78 result[i] = new MtpDeviceRecord(
Daichi Hironoebd24052016-02-06 21:05:57 +090079 device.deviceId, device.name, device.deviceKey, device.opened,
80 new MtpRoot[0], null, null);
Daichi Hirono20754c52015-12-15 18:52:26 +090081 }
82 }
83 return result;
84 }
85
86 @Override
Daichi Hirono09109562015-07-28 20:57:05 +090087 void openDevice(int deviceId) throws IOException {
Daichi Hirono20754c52015-12-15 18:52:26 +090088 final MtpDeviceRecord device = mDevices.get(deviceId);
Daichi Hirono4e94b8d2016-02-21 22:42:41 +090089 if (device == null) {
Daichi Hirono09109562015-07-28 20:57:05 +090090 throw new IOException();
91 }
Daichi Hirono20754c52015-12-15 18:52:26 +090092 mDevices.put(
93 deviceId,
Daichi Hironoebd24052016-02-06 21:05:57 +090094 new MtpDeviceRecord(
95 device.deviceId, device.name, device.deviceKey, true, device.roots, null,
96 null));
Daichi Hirono09109562015-07-28 20:57:05 +090097 }
98
99 @Override
100 void closeDevice(int deviceId) throws IOException {
Daichi Hirono20754c52015-12-15 18:52:26 +0900101 final MtpDeviceRecord device = mDevices.get(deviceId);
Daichi Hirono4e94b8d2016-02-21 22:42:41 +0900102 if (device == null) {
Daichi Hirono09109562015-07-28 20:57:05 +0900103 throw new IOException();
104 }
Daichi Hirono20754c52015-12-15 18:52:26 +0900105 mDevices.put(
106 deviceId,
Daichi Hironoebd24052016-02-06 21:05:57 +0900107 new MtpDeviceRecord(device.deviceId, device.name, device.deviceKey, false,
108 device.roots, null, null));
Daichi Hirono09109562015-07-28 20:57:05 +0900109 }
110
111 @Override
Tomasz Mikolajewskib80a3cf2015-08-24 16:10:51 +0900112 MtpObjectInfo getObjectInfo(int deviceId, int objectHandle) throws IOException {
Tomasz Mikolajewskibb430fa2015-08-25 18:34:30 +0900113 final String key = pack(deviceId, objectHandle);
114 if (mObjectInfos.containsKey(key)) {
115 return mObjectInfos.get(key);
116 } else {
117 throw new IOException("getObjectInfo error: " + key);
118 }
Tomasz Mikolajewskib80a3cf2015-08-24 16:10:51 +0900119 }
120
121 @Override
Daichi Hirono124d0602015-08-11 17:08:35 +0900122 int[] getObjectHandles(int deviceId, int storageId, int parentObjectHandle) throws IOException {
123 final String key = pack(deviceId, storageId, parentObjectHandle);
124 if (mObjectHandles.containsKey(key)) {
125 return mObjectHandles.get(key);
126 } else {
127 throw new IOException("getObjectHandles error: " + key);
128 }
Daichi Hironoe5323b72015-07-29 16:10:47 +0900129 }
130
131 @Override
Tomasz Mikolajewskib80a3cf2015-08-24 16:10:51 +0900132 void importFile(int deviceId, int objectHandle, ParcelFileDescriptor target)
133 throws IOException {
134 final String key = pack(deviceId, objectHandle);
Tomasz Mikolajewski52652ac2015-08-05 17:33:33 +0900135 if (mImportFileBytes.containsKey(key)) {
136 try (final ParcelFileDescriptor.AutoCloseOutputStream outputStream =
137 new ParcelFileDescriptor.AutoCloseOutputStream(target)) {
138 outputStream.write(mImportFileBytes.get(key));
139 }
Daichi Hirono8ba41912015-07-30 21:22:57 +0900140 } else {
Tomasz Mikolajewski52652ac2015-08-05 17:33:33 +0900141 throw new IOException("importFile error: " + key);
Daichi Hirono8ba41912015-07-30 21:22:57 +0900142 }
143 }
144
145 @Override
Tomasz Mikolajewskidf544172015-08-31 10:59:43 +0900146 int createDocument(int deviceId, MtpObjectInfo objectInfo, ParcelFileDescriptor source)
147 throws IOException {
Tomasz Mikolajewskib80a3cf2015-08-24 16:10:51 +0900148 final String key = pack(deviceId, CREATED_DOCUMENT_HANDLE);
Tomasz Mikolajewskidf544172015-08-31 10:59:43 +0900149 if (mObjectInfos.containsKey(key)) {
Tomasz Mikolajewskib80a3cf2015-08-24 16:10:51 +0900150 throw new IOException();
151 }
Daichi Hironof578fa22016-02-19 18:05:42 +0900152 final MtpObjectInfo newInfo = new MtpObjectInfo.Builder(objectInfo).
153 setObjectHandle(CREATED_DOCUMENT_HANDLE).build();
154 mObjectInfos.put(key, newInfo);
Tomasz Mikolajewskidf544172015-08-31 10:59:43 +0900155 if (objectInfo.getFormat() != 0x3001) {
156 try (final ParcelFileDescriptor.AutoCloseInputStream inputStream =
157 new ParcelFileDescriptor.AutoCloseInputStream(source)) {
158 final byte[] buffer = new byte[objectInfo.getCompressedSize()];
159 if (inputStream.read(buffer, 0, objectInfo.getCompressedSize()) !=
160 objectInfo.getCompressedSize()) {
161 throw new IOException();
162 }
163
164 mImportFileBytes.put(pack(deviceId, CREATED_DOCUMENT_HANDLE), buffer);
165 }
166 }
Tomasz Mikolajewskib80a3cf2015-08-24 16:10:51 +0900167 return CREATED_DOCUMENT_HANDLE;
168 }
169
170 @Override
Daichi Hirono3faa43a2015-08-05 17:15:35 +0900171 byte[] getThumbnail(int deviceId, int objectHandle) throws IOException {
172 final String key = pack(deviceId, objectHandle);
173 if (mThumbnailBytes.containsKey(key)) {
174 return mThumbnailBytes.get(key);
175 } else {
176 throw new IOException("getThumbnail error: " + key);
177 }
178 }
179
180 @Override
Daichi Hirono5fecc6c2015-08-04 17:45:51 +0900181 void deleteDocument(int deviceId, int objectHandle) throws IOException {
182 final String key = pack(deviceId, objectHandle);
Tomasz Mikolajewskibb430fa2015-08-25 18:34:30 +0900183 if (mObjectInfos.containsKey(key)) {
184 mObjectInfos.remove(key);
Daichi Hirono5fecc6c2015-08-04 17:45:51 +0900185 } else {
186 throw new IOException();
187 }
188 }
189
190 @Override
Tomasz Mikolajewskiab65d362015-08-26 16:50:31 +0900191 int getParent(int deviceId, int objectHandle) throws IOException {
Daichi Hirono5fecc6c2015-08-04 17:45:51 +0900192 final String key = pack(deviceId, objectHandle);
Tomasz Mikolajewskiab65d362015-08-26 16:50:31 +0900193 if (mObjectInfos.containsKey(key)) {
194 return mObjectInfos.get(key).getParent();
Daichi Hirono5fecc6c2015-08-04 17:45:51 +0900195 } else {
196 throw new IOException();
197 }
198 }
199
200 @Override
Daichi Hirono09109562015-07-28 20:57:05 +0900201 int[] getOpenedDeviceIds() {
Daichi Hirono20754c52015-12-15 18:52:26 +0900202 final int[] result = new int[mDevices.size()];
203 int count = 0;
204 for (int i = 0; i < mDevices.size(); i++) {
205 final MtpDeviceRecord device = mDevices.valueAt(i);
206 if (device.opened) {
207 result[count++] = device.deviceId;
208 }
Daichi Hirono09109562015-07-28 20:57:05 +0900209 }
Daichi Hirono20754c52015-12-15 18:52:26 +0900210 return Arrays.copyOf(result, count);
Daichi Hironob3fe72b2015-12-15 07:45:06 +0000211 }
Daichi Hironocc9a7d72015-10-28 09:43:48 +0900212
213 @Override
214 byte[] getObject(int deviceId, int objectHandle, int expectedSize) throws IOException {
215 return mImportFileBytes.get(pack(deviceId, objectHandle));
216 }
Daichi Hironob36b1552016-01-25 14:26:14 +0900217
218 @Override
219 long getPartialObject(int deviceId, int objectHandle, long offset, long size, byte[] buffer)
220 throws IOException {
221 final byte[] bytes = mImportFileBytes.get(pack(deviceId, objectHandle));
222 int i = 0;
223 while (i < size && i + offset < bytes.length) {
224 buffer[i] = bytes[(int) (i + offset)];
225 i++;
226 }
227 return i;
228 }
Daichi Hirono09109562015-07-28 20:57:05 +0900229}