• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 package com.android.mtp;
18 
19 import android.content.Context;
20 import android.mtp.MtpObjectInfo;
21 import android.os.ParcelFileDescriptor;
22 import android.util.SparseArray;
23 
24 import java.io.IOException;
25 import java.util.ArrayList;
26 import java.util.Arrays;
27 import java.util.HashMap;
28 import java.util.Map;
29 import junit.framework.Assert;
30 
31 public class TestMtpManager extends MtpManager {
32     public static final int CREATED_DOCUMENT_HANDLE = 1000;
33 
pack(int... args)34     protected static String pack(int... args) {
35         return Arrays.toString(args);
36     }
37 
38     private final SparseArray<MtpDeviceRecord> mDevices = new SparseArray<>();
39     private final Map<String, MtpObjectInfo> mObjectInfos = new HashMap<>();
40     private final Map<String, int[]> mObjectHandles = new HashMap<>();
41     private final Map<String, byte[]> mThumbnailBytes = new HashMap<>();
42     private final Map<String, byte[]> mImportFileBytes = new HashMap<>();
43     private final Map<String, Long> mObjectSizeLongs = new HashMap<>();
44 
TestMtpManager(Context context)45     TestMtpManager(Context context) {
46         super(context);
47     }
48 
addValidDevice(MtpDeviceRecord device)49     void addValidDevice(MtpDeviceRecord device) {
50         mDevices.put(device.deviceId, device);
51     }
52 
setObjectHandles(int deviceId, int storageId, int parentHandle, int[] objectHandles)53     void setObjectHandles(int deviceId, int storageId, int parentHandle, int[] objectHandles) {
54         mObjectHandles.put(pack(deviceId, storageId, parentHandle), objectHandles);
55     }
56 
setObjectInfo(int deviceId, MtpObjectInfo objectInfo)57     void setObjectInfo(int deviceId, MtpObjectInfo objectInfo) {
58         mObjectInfos.put(pack(deviceId, objectInfo.getObjectHandle()), objectInfo);
59     }
60 
setImportFileBytes(int deviceId, int objectHandle, byte[] bytes)61     void setImportFileBytes(int deviceId, int objectHandle, byte[] bytes) {
62         mImportFileBytes.put(pack(deviceId, objectHandle), bytes);
63     }
64 
getImportFileBytes(int deviceId, int objectHandle)65     byte[] getImportFileBytes(int deviceId, int objectHandle) {
66         return mImportFileBytes.get(pack(deviceId, objectHandle));
67     }
68 
setThumbnail(int deviceId, int objectHandle, byte[] bytes)69     void setThumbnail(int deviceId, int objectHandle, byte[] bytes) {
70         mThumbnailBytes.put(pack(deviceId, objectHandle), bytes);
71     }
72 
setObjectSizeLong(int deviceId, int objectHandle, int format, long value)73     void setObjectSizeLong(int deviceId, int objectHandle, int format, long value) {
74         mObjectSizeLongs.put(pack(deviceId, objectHandle, format), value);
75     }
76 
77     @Override
getDevices()78     synchronized MtpDeviceRecord[] getDevices() {
79         final MtpDeviceRecord[] result = new MtpDeviceRecord[mDevices.size()];
80         for (int i = 0; i < mDevices.size(); i++) {
81             final MtpDeviceRecord device = mDevices.valueAt(i);
82             if (device.opened) {
83                 result[i] = device;
84             } else {
85                 result[i] = new MtpDeviceRecord(
86                         device.deviceId, device.name, device.deviceKey, device.opened,
87                         new MtpRoot[0], null, null);
88             }
89         }
90         return result;
91     }
92 
93     @Override
openDevice(int deviceId)94     synchronized MtpDeviceRecord openDevice(int deviceId) throws IOException {
95         final MtpDeviceRecord device = mDevices.get(deviceId);
96         if (device == null) {
97             throw new IOException();
98         }
99         final MtpDeviceRecord record = new MtpDeviceRecord(
100                 device.deviceId, device.name, device.deviceKey, true, device.roots,
101                 device.operationsSupported, device.eventsSupported);
102         mDevices.put(deviceId, record);
103         return record;
104     }
105 
106     @Override
closeDevice(int deviceId)107     synchronized void closeDevice(int deviceId) throws IOException {
108         final MtpDeviceRecord device = mDevices.get(deviceId);
109         if (device == null) {
110             throw new IOException();
111         }
112         mDevices.put(
113                 deviceId,
114                 new MtpDeviceRecord(device.deviceId, device.name, device.deviceKey, false,
115                         device.roots, device.operationsSupported, device.eventsSupported));
116     }
117 
118     @Override
getObjectInfo(int deviceId, int objectHandle)119     MtpObjectInfo getObjectInfo(int deviceId, int objectHandle) throws IOException {
120         final String key = pack(deviceId, objectHandle);
121         if (mObjectInfos.containsKey(key)) {
122             return mObjectInfos.get(key);
123         } else {
124             throw new IOException("getObjectInfo error: " + key);
125         }
126     }
127 
128     @Override
getObjectHandles(int deviceId, int storageId, int parentObjectHandle)129     int[] getObjectHandles(int deviceId, int storageId, int parentObjectHandle) throws IOException {
130         final String key = pack(deviceId, storageId, parentObjectHandle);
131         if (mObjectHandles.containsKey(key)) {
132             return mObjectHandles.get(key);
133         } else {
134             throw new IOException("getObjectHandles error: " + key);
135         }
136     }
137 
138     @Override
importFile(int deviceId, int objectHandle, ParcelFileDescriptor target)139     void importFile(int deviceId, int objectHandle, ParcelFileDescriptor target)
140             throws IOException {
141         final String key = pack(deviceId, objectHandle);
142         if (mImportFileBytes.containsKey(key)) {
143             try (final ParcelFileDescriptor.AutoCloseOutputStream outputStream =
144                     new ParcelFileDescriptor.AutoCloseOutputStream(target)) {
145                 outputStream.write(mImportFileBytes.get(key));
146             }
147         } else {
148             throw new IOException("importFile error: " + key);
149         }
150     }
151 
152     @Override
createDocument(int deviceId, MtpObjectInfo objectInfo, ParcelFileDescriptor source)153     int createDocument(int deviceId, MtpObjectInfo objectInfo, ParcelFileDescriptor source)
154             throws IOException {
155         Assert.assertNotSame(0, objectInfo.getStorageId());
156         Assert.assertNotSame(-1, objectInfo.getStorageId());
157         Assert.assertNotSame(0, objectInfo.getParent());
158         final String key = pack(deviceId, CREATED_DOCUMENT_HANDLE);
159         if (mObjectInfos.containsKey(key)) {
160             throw new IOException();
161         }
162         final MtpObjectInfo newInfo = new MtpObjectInfo.Builder(objectInfo).
163                 setObjectHandle(CREATED_DOCUMENT_HANDLE).build();
164         mObjectInfos.put(key, newInfo);
165         if (objectInfo.getFormat() != 0x3001) {
166             try (final ParcelFileDescriptor.AutoCloseInputStream inputStream =
167                     new ParcelFileDescriptor.AutoCloseInputStream(source)) {
168                 final byte[] buffer = new byte[objectInfo.getCompressedSize()];
169                 if (inputStream.read(buffer, 0, objectInfo.getCompressedSize()) !=
170                         objectInfo.getCompressedSize()) {
171                     throw new IOException();
172                 }
173 
174                 mImportFileBytes.put(pack(deviceId, CREATED_DOCUMENT_HANDLE), buffer);
175             }
176         }
177         return CREATED_DOCUMENT_HANDLE;
178     }
179 
180     @Override
getThumbnail(int deviceId, int objectHandle)181     byte[] getThumbnail(int deviceId, int objectHandle) throws IOException {
182         final String key = pack(deviceId, objectHandle);
183         if (mThumbnailBytes.containsKey(key)) {
184             return mThumbnailBytes.get(key);
185         } else {
186             throw new IOException("getThumbnail error: " + key);
187         }
188     }
189 
190     @Override
deleteDocument(int deviceId, int objectHandle)191     void deleteDocument(int deviceId, int objectHandle) throws IOException {
192         final String key = pack(deviceId, objectHandle);
193         if (mObjectInfos.containsKey(key)) {
194             mObjectInfos.remove(key);
195         } else {
196             throw new IOException();
197         }
198     }
199 
200     @Override
getParent(int deviceId, int objectHandle)201     int getParent(int deviceId, int objectHandle) throws IOException {
202         final String key = pack(deviceId, objectHandle);
203         if (mObjectInfos.containsKey(key)) {
204             return mObjectInfos.get(key).getParent();
205         } else {
206             throw new IOException();
207         }
208     }
209 
210     @Override
getObject(int deviceId, int objectHandle, int expectedSize)211     byte[] getObject(int deviceId, int objectHandle, int expectedSize) throws IOException {
212         return mImportFileBytes.get(pack(deviceId, objectHandle));
213     }
214 
215     @Override
getPartialObject(int deviceId, int objectHandle, long offset, long size, byte[] buffer)216     long getPartialObject(int deviceId, int objectHandle, long offset, long size, byte[] buffer)
217             throws IOException {
218         final byte[] bytes = mImportFileBytes.get(pack(deviceId, objectHandle));
219         int i = 0;
220         while (i < size && i + offset < bytes.length) {
221             buffer[i] = bytes[(int) (i + offset)];
222             i++;
223         }
224         return i;
225     }
226 
227     @Override
getObjectSizeLong(int deviceId, int objectHandle, int format)228     long getObjectSizeLong(int deviceId, int objectHandle, int format) throws IOException {
229         final String key = pack(deviceId, objectHandle, format);
230         if (mObjectSizeLongs.containsKey(key)) {
231             return mObjectSizeLongs.get(key);
232         } else {
233             throw new IOException();
234         }
235     }
236 }
237