blob: 5e0ee1e3e1fa7caf3f33879fda8f4e127e9731d4 [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 Hirono0f325372016-02-21 15:50:30 +090025import java.util.ArrayList;
Daichi Hironoe5323b72015-07-29 16:10:47 +090026import java.util.Arrays;
Daichi Hirono09109562015-07-28 20:57:05 +090027import java.util.HashMap;
Daichi Hirono09109562015-07-28 20:57:05 +090028import java.util.Map;
Daichi Hirono09109562015-07-28 20:57:05 +090029
Daichi Hirono6ee4a1c2015-07-31 10:30:05 +090030public class TestMtpManager extends MtpManager {
Tomasz Mikolajewskib80a3cf2015-08-24 16:10:51 +090031 public static final int CREATED_DOCUMENT_HANDLE = 1000;
32
Daichi Hirono6baa16e2015-08-12 13:51:59 +090033 protected static String pack(int... args) {
Daichi Hironoe5323b72015-07-29 16:10:47 +090034 return Arrays.toString(args);
35 }
36
Daichi Hirono20754c52015-12-15 18:52:26 +090037 private final SparseArray<MtpDeviceRecord> mDevices = new SparseArray<>();
Tomasz Mikolajewskibb430fa2015-08-25 18:34:30 +090038 private final Map<String, MtpObjectInfo> mObjectInfos = new HashMap<>();
Daichi Hirono124d0602015-08-11 17:08:35 +090039 private final Map<String, int[]> mObjectHandles = new HashMap<>();
40 private final Map<String, byte[]> mThumbnailBytes = new HashMap<>();
Daichi Hirono124d0602015-08-11 17:08:35 +090041 private final Map<String, byte[]> mImportFileBytes = new HashMap<>();
Daichi Hirono09109562015-07-28 20:57:05 +090042
Daichi Hirono6ee4a1c2015-07-31 10:30:05 +090043 TestMtpManager(Context context) {
Daichi Hirono09109562015-07-28 20:57:05 +090044 super(context);
45 }
46
Daichi Hirono20754c52015-12-15 18:52:26 +090047 void addValidDevice(MtpDeviceRecord device) {
48 mDevices.put(device.deviceId, device);
Daichi Hirono09109562015-07-28 20:57:05 +090049 }
50
Tomasz Mikolajewskibb430fa2015-08-25 18:34:30 +090051 void setObjectHandles(int deviceId, int storageId, int parentHandle, int[] objectHandles) {
52 mObjectHandles.put(pack(deviceId, storageId, parentHandle), objectHandles);
Daichi Hirono124d0602015-08-11 17:08:35 +090053 }
54
Tomasz Mikolajewskibb430fa2015-08-25 18:34:30 +090055 void setObjectInfo(int deviceId, MtpObjectInfo objectInfo) {
56 mObjectInfos.put(pack(deviceId, objectInfo.getObjectHandle()), objectInfo);
Daichi Hironoe5323b72015-07-29 16:10:47 +090057 }
58
Tomasz Mikolajewski52652ac2015-08-05 17:33:33 +090059 void setImportFileBytes(int deviceId, int objectHandle, byte[] bytes) {
60 mImportFileBytes.put(pack(deviceId, objectHandle), bytes);
Daichi Hirono8ba41912015-07-30 21:22:57 +090061 }
62
Tomasz Mikolajewskib80a3cf2015-08-24 16:10:51 +090063 byte[] getImportFileBytes(int deviceId, int objectHandle) {
64 return mImportFileBytes.get(pack(deviceId, objectHandle));
65 }
66
Daichi Hirono3faa43a2015-08-05 17:15:35 +090067 void setThumbnail(int deviceId, int objectHandle, byte[] bytes) {
68 mThumbnailBytes.put(pack(deviceId, objectHandle), bytes);
69 }
70
Daichi Hirono09109562015-07-28 20:57:05 +090071 @Override
Daichi Hirono20754c52015-12-15 18:52:26 +090072 MtpDeviceRecord[] getDevices() {
73 final MtpDeviceRecord[] result = new MtpDeviceRecord[mDevices.size()];
74 for (int i = 0; i < mDevices.size(); i++) {
75 final MtpDeviceRecord device = mDevices.valueAt(i);
76 if (device.opened) {
77 result[i] = device;
78 } else {
79 result[i] = new MtpDeviceRecord(
Daichi Hironoebd24052016-02-06 21:05:57 +090080 device.deviceId, device.name, device.deviceKey, device.opened,
81 new MtpRoot[0], null, null);
Daichi Hirono20754c52015-12-15 18:52:26 +090082 }
83 }
84 return result;
85 }
86
87 @Override
Daichi Hirono0f325372016-02-21 15:50:30 +090088 MtpDeviceRecord openDevice(int deviceId) throws IOException {
Daichi Hirono20754c52015-12-15 18:52:26 +090089 final MtpDeviceRecord device = mDevices.get(deviceId);
Daichi Hirono4e94b8d2016-02-21 22:42:41 +090090 if (device == null) {
Daichi Hirono09109562015-07-28 20:57:05 +090091 throw new IOException();
92 }
Daichi Hirono0f325372016-02-21 15:50:30 +090093 final MtpDeviceRecord record = new MtpDeviceRecord(
94 device.deviceId, device.name, device.deviceKey, true, device.roots,
95 device.operationsSupported, device.eventsSupported);
96 mDevices.put(deviceId, record);
97 return record;
Daichi Hirono09109562015-07-28 20:57:05 +090098 }
99
100 @Override
101 void closeDevice(int deviceId) throws IOException {
Daichi Hirono20754c52015-12-15 18:52:26 +0900102 final MtpDeviceRecord device = mDevices.get(deviceId);
Daichi Hirono4e94b8d2016-02-21 22:42:41 +0900103 if (device == null) {
Daichi Hirono09109562015-07-28 20:57:05 +0900104 throw new IOException();
105 }
Daichi Hirono20754c52015-12-15 18:52:26 +0900106 mDevices.put(
107 deviceId,
Daichi Hironoebd24052016-02-06 21:05:57 +0900108 new MtpDeviceRecord(device.deviceId, device.name, device.deviceKey, false,
109 device.roots, null, null));
Daichi Hirono09109562015-07-28 20:57:05 +0900110 }
111
112 @Override
Tomasz Mikolajewskib80a3cf2015-08-24 16:10:51 +0900113 MtpObjectInfo getObjectInfo(int deviceId, int objectHandle) throws IOException {
Tomasz Mikolajewskibb430fa2015-08-25 18:34:30 +0900114 final String key = pack(deviceId, objectHandle);
115 if (mObjectInfos.containsKey(key)) {
116 return mObjectInfos.get(key);
117 } else {
118 throw new IOException("getObjectInfo error: " + key);
119 }
Tomasz Mikolajewskib80a3cf2015-08-24 16:10:51 +0900120 }
121
122 @Override
Daichi Hirono124d0602015-08-11 17:08:35 +0900123 int[] getObjectHandles(int deviceId, int storageId, int parentObjectHandle) throws IOException {
124 final String key = pack(deviceId, storageId, parentObjectHandle);
125 if (mObjectHandles.containsKey(key)) {
126 return mObjectHandles.get(key);
127 } else {
128 throw new IOException("getObjectHandles error: " + key);
129 }
Daichi Hironoe5323b72015-07-29 16:10:47 +0900130 }
131
132 @Override
Tomasz Mikolajewskib80a3cf2015-08-24 16:10:51 +0900133 void importFile(int deviceId, int objectHandle, ParcelFileDescriptor target)
134 throws IOException {
135 final String key = pack(deviceId, objectHandle);
Tomasz Mikolajewski52652ac2015-08-05 17:33:33 +0900136 if (mImportFileBytes.containsKey(key)) {
137 try (final ParcelFileDescriptor.AutoCloseOutputStream outputStream =
138 new ParcelFileDescriptor.AutoCloseOutputStream(target)) {
139 outputStream.write(mImportFileBytes.get(key));
140 }
Daichi Hirono8ba41912015-07-30 21:22:57 +0900141 } else {
Tomasz Mikolajewski52652ac2015-08-05 17:33:33 +0900142 throw new IOException("importFile error: " + key);
Daichi Hirono8ba41912015-07-30 21:22:57 +0900143 }
144 }
145
146 @Override
Tomasz Mikolajewskidf544172015-08-31 10:59:43 +0900147 int createDocument(int deviceId, MtpObjectInfo objectInfo, ParcelFileDescriptor source)
148 throws IOException {
Tomasz Mikolajewskib80a3cf2015-08-24 16:10:51 +0900149 final String key = pack(deviceId, CREATED_DOCUMENT_HANDLE);
Tomasz Mikolajewskidf544172015-08-31 10:59:43 +0900150 if (mObjectInfos.containsKey(key)) {
Tomasz Mikolajewskib80a3cf2015-08-24 16:10:51 +0900151 throw new IOException();
152 }
Daichi Hironof578fa22016-02-19 18:05:42 +0900153 final MtpObjectInfo newInfo = new MtpObjectInfo.Builder(objectInfo).
154 setObjectHandle(CREATED_DOCUMENT_HANDLE).build();
155 mObjectInfos.put(key, newInfo);
Tomasz Mikolajewskidf544172015-08-31 10:59:43 +0900156 if (objectInfo.getFormat() != 0x3001) {
157 try (final ParcelFileDescriptor.AutoCloseInputStream inputStream =
158 new ParcelFileDescriptor.AutoCloseInputStream(source)) {
159 final byte[] buffer = new byte[objectInfo.getCompressedSize()];
160 if (inputStream.read(buffer, 0, objectInfo.getCompressedSize()) !=
161 objectInfo.getCompressedSize()) {
162 throw new IOException();
163 }
164
165 mImportFileBytes.put(pack(deviceId, CREATED_DOCUMENT_HANDLE), buffer);
166 }
167 }
Tomasz Mikolajewskib80a3cf2015-08-24 16:10:51 +0900168 return CREATED_DOCUMENT_HANDLE;
169 }
170
171 @Override
Daichi Hirono3faa43a2015-08-05 17:15:35 +0900172 byte[] getThumbnail(int deviceId, int objectHandle) throws IOException {
173 final String key = pack(deviceId, objectHandle);
174 if (mThumbnailBytes.containsKey(key)) {
175 return mThumbnailBytes.get(key);
176 } else {
177 throw new IOException("getThumbnail error: " + key);
178 }
179 }
180
181 @Override
Daichi Hirono5fecc6c2015-08-04 17:45:51 +0900182 void deleteDocument(int deviceId, int objectHandle) throws IOException {
183 final String key = pack(deviceId, objectHandle);
Tomasz Mikolajewskibb430fa2015-08-25 18:34:30 +0900184 if (mObjectInfos.containsKey(key)) {
185 mObjectInfos.remove(key);
Daichi Hirono5fecc6c2015-08-04 17:45:51 +0900186 } else {
187 throw new IOException();
188 }
189 }
190
191 @Override
Tomasz Mikolajewskiab65d362015-08-26 16:50:31 +0900192 int getParent(int deviceId, int objectHandle) throws IOException {
Daichi Hirono5fecc6c2015-08-04 17:45:51 +0900193 final String key = pack(deviceId, objectHandle);
Tomasz Mikolajewskiab65d362015-08-26 16:50:31 +0900194 if (mObjectInfos.containsKey(key)) {
195 return mObjectInfos.get(key).getParent();
Daichi Hirono5fecc6c2015-08-04 17:45:51 +0900196 } else {
197 throw new IOException();
198 }
199 }
200
201 @Override
Daichi Hironocc9a7d72015-10-28 09:43:48 +0900202 byte[] getObject(int deviceId, int objectHandle, int expectedSize) throws IOException {
203 return mImportFileBytes.get(pack(deviceId, objectHandle));
204 }
Daichi Hironob36b1552016-01-25 14:26:14 +0900205
206 @Override
207 long getPartialObject(int deviceId, int objectHandle, long offset, long size, byte[] buffer)
208 throws IOException {
209 final byte[] bytes = mImportFileBytes.get(pack(deviceId, objectHandle));
210 int i = 0;
211 while (i < size && i + offset < bytes.length) {
212 buffer[i] = bytes[(int) (i + offset)];
213 i++;
214 }
215 return i;
216 }
Daichi Hirono09109562015-07-28 20:57:05 +0900217}