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