109109567e9816d20f51b5ce0175751116836635fDaichi Hirono/*
209109567e9816d20f51b5ce0175751116836635fDaichi Hirono * Copyright (C) 2015 The Android Open Source Project
309109567e9816d20f51b5ce0175751116836635fDaichi Hirono *
409109567e9816d20f51b5ce0175751116836635fDaichi Hirono * Licensed under the Apache License, Version 2.0 (the "License");
509109567e9816d20f51b5ce0175751116836635fDaichi Hirono * you may not use this file except in compliance with the License.
609109567e9816d20f51b5ce0175751116836635fDaichi Hirono * You may obtain a copy of the License at
709109567e9816d20f51b5ce0175751116836635fDaichi Hirono *
809109567e9816d20f51b5ce0175751116836635fDaichi Hirono *      http://www.apache.org/licenses/LICENSE-2.0
909109567e9816d20f51b5ce0175751116836635fDaichi Hirono *
1009109567e9816d20f51b5ce0175751116836635fDaichi Hirono * Unless required by applicable law or agreed to in writing, software
1109109567e9816d20f51b5ce0175751116836635fDaichi Hirono * distributed under the License is distributed on an "AS IS" BASIS,
1209109567e9816d20f51b5ce0175751116836635fDaichi Hirono * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1309109567e9816d20f51b5ce0175751116836635fDaichi Hirono * See the License for the specific language governing permissions and
1409109567e9816d20f51b5ce0175751116836635fDaichi Hirono * limitations under the License.
1509109567e9816d20f51b5ce0175751116836635fDaichi Hirono */
1609109567e9816d20f51b5ce0175751116836635fDaichi Hirono
1709109567e9816d20f51b5ce0175751116836635fDaichi Hironopackage com.android.mtp;
1809109567e9816d20f51b5ce0175751116836635fDaichi Hirono
1909109567e9816d20f51b5ce0175751116836635fDaichi Hironoimport android.content.Context;
20b80a3cfd05fc7492dd59b7f8d4337eb5e29088c2Tomasz Mikolajewskiimport android.mtp.MtpObjectInfo;
2152652ac7a5f479f7f5e24f78778203bd88c0c4f4Tomasz Mikolajewskiimport android.os.ParcelFileDescriptor;
2220754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hironoimport android.util.SparseArray;
2309109567e9816d20f51b5ce0175751116836635fDaichi Hirono
2409109567e9816d20f51b5ce0175751116836635fDaichi Hironoimport java.io.IOException;
250f32537e40ee2662d4f0b7b625ee280ca9c02066Daichi Hironoimport java.util.ArrayList;
26e5323b7493f2bc1537d7e6b2d4595d69fd01d72eDaichi Hironoimport java.util.Arrays;
2709109567e9816d20f51b5ce0175751116836635fDaichi Hironoimport java.util.HashMap;
2809109567e9816d20f51b5ce0175751116836635fDaichi Hironoimport java.util.Map;
2935b2ec551f670562a779925fe152307f20ad67cdDaichi Hironoimport junit.framework.Assert;
3009109567e9816d20f51b5ce0175751116836635fDaichi Hirono
316ee4a1c1247e2a1d3032bcd432f843cbb7227dccDaichi Hironopublic class TestMtpManager extends MtpManager {
32b80a3cfd05fc7492dd59b7f8d4337eb5e29088c2Tomasz Mikolajewski    public static final int CREATED_DOCUMENT_HANDLE = 1000;
33b80a3cfd05fc7492dd59b7f8d4337eb5e29088c2Tomasz Mikolajewski
346baa16e9109046661fef8dcc25b8754ac68bcdaeDaichi Hirono    protected static String pack(int... args) {
35e5323b7493f2bc1537d7e6b2d4595d69fd01d72eDaichi Hirono        return Arrays.toString(args);
36e5323b7493f2bc1537d7e6b2d4595d69fd01d72eDaichi Hirono    }
37e5323b7493f2bc1537d7e6b2d4595d69fd01d72eDaichi Hirono
3820754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono    private final SparseArray<MtpDeviceRecord> mDevices = new SparseArray<>();
39bb430fa930fa0d0700e46e7b4881de2a252223ddTomasz Mikolajewski    private final Map<String, MtpObjectInfo> mObjectInfos = new HashMap<>();
40124d060bc980c7555616ff9d07a4dc3b8f3cd341Daichi Hirono    private final Map<String, int[]> mObjectHandles = new HashMap<>();
41124d060bc980c7555616ff9d07a4dc3b8f3cd341Daichi Hirono    private final Map<String, byte[]> mThumbnailBytes = new HashMap<>();
42124d060bc980c7555616ff9d07a4dc3b8f3cd341Daichi Hirono    private final Map<String, byte[]> mImportFileBytes = new HashMap<>();
4364111e08d905525c7f4fe27e69953eb71bd62511Daichi Hirono    private final Map<String, Long> mObjectSizeLongs = new HashMap<>();
4409109567e9816d20f51b5ce0175751116836635fDaichi Hirono
456ee4a1c1247e2a1d3032bcd432f843cbb7227dccDaichi Hirono    TestMtpManager(Context context) {
4609109567e9816d20f51b5ce0175751116836635fDaichi Hirono        super(context);
4709109567e9816d20f51b5ce0175751116836635fDaichi Hirono    }
4809109567e9816d20f51b5ce0175751116836635fDaichi Hirono
4920754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono    void addValidDevice(MtpDeviceRecord device) {
5020754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono        mDevices.put(device.deviceId, device);
5109109567e9816d20f51b5ce0175751116836635fDaichi Hirono    }
5209109567e9816d20f51b5ce0175751116836635fDaichi Hirono
53bb430fa930fa0d0700e46e7b4881de2a252223ddTomasz Mikolajewski    void setObjectHandles(int deviceId, int storageId, int parentHandle, int[] objectHandles) {
54bb430fa930fa0d0700e46e7b4881de2a252223ddTomasz Mikolajewski        mObjectHandles.put(pack(deviceId, storageId, parentHandle), objectHandles);
55124d060bc980c7555616ff9d07a4dc3b8f3cd341Daichi Hirono    }
56124d060bc980c7555616ff9d07a4dc3b8f3cd341Daichi Hirono
57bb430fa930fa0d0700e46e7b4881de2a252223ddTomasz Mikolajewski    void setObjectInfo(int deviceId, MtpObjectInfo objectInfo) {
58bb430fa930fa0d0700e46e7b4881de2a252223ddTomasz Mikolajewski        mObjectInfos.put(pack(deviceId, objectInfo.getObjectHandle()), objectInfo);
59e5323b7493f2bc1537d7e6b2d4595d69fd01d72eDaichi Hirono    }
60e5323b7493f2bc1537d7e6b2d4595d69fd01d72eDaichi Hirono
6152652ac7a5f479f7f5e24f78778203bd88c0c4f4Tomasz Mikolajewski    void setImportFileBytes(int deviceId, int objectHandle, byte[] bytes) {
6252652ac7a5f479f7f5e24f78778203bd88c0c4f4Tomasz Mikolajewski        mImportFileBytes.put(pack(deviceId, objectHandle), bytes);
638ba419119d50a031160cab54bef6899bd0051ea9Daichi Hirono    }
648ba419119d50a031160cab54bef6899bd0051ea9Daichi Hirono
65b80a3cfd05fc7492dd59b7f8d4337eb5e29088c2Tomasz Mikolajewski    byte[] getImportFileBytes(int deviceId, int objectHandle) {
66b80a3cfd05fc7492dd59b7f8d4337eb5e29088c2Tomasz Mikolajewski        return mImportFileBytes.get(pack(deviceId, objectHandle));
67b80a3cfd05fc7492dd59b7f8d4337eb5e29088c2Tomasz Mikolajewski    }
68b80a3cfd05fc7492dd59b7f8d4337eb5e29088c2Tomasz Mikolajewski
693faa43a4a6f270e2e1e2ec55b77508084af16757Daichi Hirono    void setThumbnail(int deviceId, int objectHandle, byte[] bytes) {
703faa43a4a6f270e2e1e2ec55b77508084af16757Daichi Hirono        mThumbnailBytes.put(pack(deviceId, objectHandle), bytes);
713faa43a4a6f270e2e1e2ec55b77508084af16757Daichi Hirono    }
723faa43a4a6f270e2e1e2ec55b77508084af16757Daichi Hirono
7364111e08d905525c7f4fe27e69953eb71bd62511Daichi Hirono    void setObjectSizeLong(int deviceId, int objectHandle, int format, long value) {
7464111e08d905525c7f4fe27e69953eb71bd62511Daichi Hirono        mObjectSizeLongs.put(pack(deviceId, objectHandle, format), value);
7564111e08d905525c7f4fe27e69953eb71bd62511Daichi Hirono    }
7664111e08d905525c7f4fe27e69953eb71bd62511Daichi Hirono
7709109567e9816d20f51b5ce0175751116836635fDaichi Hirono    @Override
78f20e49ecb954ffc3cb93499cb789a567125998ceDaichi Hirono    synchronized MtpDeviceRecord[] getDevices() {
7920754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono        final MtpDeviceRecord[] result = new MtpDeviceRecord[mDevices.size()];
8020754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono        for (int i = 0; i < mDevices.size(); i++) {
8120754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono            final MtpDeviceRecord device = mDevices.valueAt(i);
8220754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono            if (device.opened) {
8320754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono                result[i] = device;
8420754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono            } else {
8520754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono                result[i] = new MtpDeviceRecord(
86ebd24051599280443435606cab220de33b9356adDaichi Hirono                        device.deviceId, device.name, device.deviceKey, device.opened,
87ebd24051599280443435606cab220de33b9356adDaichi Hirono                        new MtpRoot[0], null, null);
8820754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono            }
8909109567e9816d20f51b5ce0175751116836635fDaichi Hirono        }
9020754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono        return result;
9109109567e9816d20f51b5ce0175751116836635fDaichi Hirono    }
9209109567e9816d20f51b5ce0175751116836635fDaichi Hirono
9309109567e9816d20f51b5ce0175751116836635fDaichi Hirono    @Override
94f20e49ecb954ffc3cb93499cb789a567125998ceDaichi Hirono    synchronized MtpDeviceRecord openDevice(int deviceId) throws IOException {
9520754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono        final MtpDeviceRecord device = mDevices.get(deviceId);
964e94b8deaa646f176bad9b80d5924ce64142743eDaichi Hirono        if (device == null) {
9709109567e9816d20f51b5ce0175751116836635fDaichi Hirono            throw new IOException();
9809109567e9816d20f51b5ce0175751116836635fDaichi Hirono        }
990f32537e40ee2662d4f0b7b625ee280ca9c02066Daichi Hirono        final MtpDeviceRecord record = new MtpDeviceRecord(
1000f32537e40ee2662d4f0b7b625ee280ca9c02066Daichi Hirono                device.deviceId, device.name, device.deviceKey, true, device.roots,
1010f32537e40ee2662d4f0b7b625ee280ca9c02066Daichi Hirono                device.operationsSupported, device.eventsSupported);
1020f32537e40ee2662d4f0b7b625ee280ca9c02066Daichi Hirono        mDevices.put(deviceId, record);
1030f32537e40ee2662d4f0b7b625ee280ca9c02066Daichi Hirono        return record;
10409109567e9816d20f51b5ce0175751116836635fDaichi Hirono    }
10509109567e9816d20f51b5ce0175751116836635fDaichi Hirono
10609109567e9816d20f51b5ce0175751116836635fDaichi Hirono    @Override
107f20e49ecb954ffc3cb93499cb789a567125998ceDaichi Hirono    synchronized void closeDevice(int deviceId) throws IOException {
10820754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono        final MtpDeviceRecord device = mDevices.get(deviceId);
1094e94b8deaa646f176bad9b80d5924ce64142743eDaichi Hirono        if (device == null) {
11020754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono            throw new IOException();
11109109567e9816d20f51b5ce0175751116836635fDaichi Hirono        }
11220754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono        mDevices.put(
11320754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono                deviceId,
114ebd24051599280443435606cab220de33b9356adDaichi Hirono                new MtpDeviceRecord(device.deviceId, device.name, device.deviceKey, false,
11537a655aac1d61ce2fe346531f78cbcfbf51388e9Daichi Hirono                        device.roots, device.operationsSupported, device.eventsSupported));
11609109567e9816d20f51b5ce0175751116836635fDaichi Hirono    }
11709109567e9816d20f51b5ce0175751116836635fDaichi Hirono
11809109567e9816d20f51b5ce0175751116836635fDaichi Hirono    @Override
119bb430fa930fa0d0700e46e7b4881de2a252223ddTomasz Mikolajewski    MtpObjectInfo getObjectInfo(int deviceId, int objectHandle) throws IOException {
120124d060bc980c7555616ff9d07a4dc3b8f3cd341Daichi Hirono        final String key = pack(deviceId, objectHandle);
121bb430fa930fa0d0700e46e7b4881de2a252223ddTomasz Mikolajewski        if (mObjectInfos.containsKey(key)) {
122bb430fa930fa0d0700e46e7b4881de2a252223ddTomasz Mikolajewski            return mObjectInfos.get(key);
123124d060bc980c7555616ff9d07a4dc3b8f3cd341Daichi Hirono        } else {
124bb430fa930fa0d0700e46e7b4881de2a252223ddTomasz Mikolajewski            throw new IOException("getObjectInfo error: " + key);
125124d060bc980c7555616ff9d07a4dc3b8f3cd341Daichi Hirono        }
126124d060bc980c7555616ff9d07a4dc3b8f3cd341Daichi Hirono    }
127124d060bc980c7555616ff9d07a4dc3b8f3cd341Daichi Hirono
128124d060bc980c7555616ff9d07a4dc3b8f3cd341Daichi Hirono    @Override
129124d060bc980c7555616ff9d07a4dc3b8f3cd341Daichi Hirono    int[] getObjectHandles(int deviceId, int storageId, int parentObjectHandle) throws IOException {
130124d060bc980c7555616ff9d07a4dc3b8f3cd341Daichi Hirono        final String key = pack(deviceId, storageId, parentObjectHandle);
131124d060bc980c7555616ff9d07a4dc3b8f3cd341Daichi Hirono        if (mObjectHandles.containsKey(key)) {
132124d060bc980c7555616ff9d07a4dc3b8f3cd341Daichi Hirono            return mObjectHandles.get(key);
133124d060bc980c7555616ff9d07a4dc3b8f3cd341Daichi Hirono        } else {
134124d060bc980c7555616ff9d07a4dc3b8f3cd341Daichi Hirono            throw new IOException("getObjectHandles error: " + key);
135124d060bc980c7555616ff9d07a4dc3b8f3cd341Daichi Hirono        }
136e5323b7493f2bc1537d7e6b2d4595d69fd01d72eDaichi Hirono    }
137e5323b7493f2bc1537d7e6b2d4595d69fd01d72eDaichi Hirono
138e5323b7493f2bc1537d7e6b2d4595d69fd01d72eDaichi Hirono    @Override
139b80a3cfd05fc7492dd59b7f8d4337eb5e29088c2Tomasz Mikolajewski    void importFile(int deviceId, int objectHandle, ParcelFileDescriptor target)
140b80a3cfd05fc7492dd59b7f8d4337eb5e29088c2Tomasz Mikolajewski            throws IOException {
141b80a3cfd05fc7492dd59b7f8d4337eb5e29088c2Tomasz Mikolajewski        final String key = pack(deviceId, objectHandle);
14252652ac7a5f479f7f5e24f78778203bd88c0c4f4Tomasz Mikolajewski        if (mImportFileBytes.containsKey(key)) {
14352652ac7a5f479f7f5e24f78778203bd88c0c4f4Tomasz Mikolajewski            try (final ParcelFileDescriptor.AutoCloseOutputStream outputStream =
14452652ac7a5f479f7f5e24f78778203bd88c0c4f4Tomasz Mikolajewski                    new ParcelFileDescriptor.AutoCloseOutputStream(target)) {
14552652ac7a5f479f7f5e24f78778203bd88c0c4f4Tomasz Mikolajewski                outputStream.write(mImportFileBytes.get(key));
14652652ac7a5f479f7f5e24f78778203bd88c0c4f4Tomasz Mikolajewski            }
1478ba419119d50a031160cab54bef6899bd0051ea9Daichi Hirono        } else {
14852652ac7a5f479f7f5e24f78778203bd88c0c4f4Tomasz Mikolajewski            throw new IOException("importFile error: " + key);
1498ba419119d50a031160cab54bef6899bd0051ea9Daichi Hirono        }
1508ba419119d50a031160cab54bef6899bd0051ea9Daichi Hirono    }
1518ba419119d50a031160cab54bef6899bd0051ea9Daichi Hirono
1528ba419119d50a031160cab54bef6899bd0051ea9Daichi Hirono    @Override
153df544176b10f536969de1ed143b0ba57123fcb93Tomasz Mikolajewski    int createDocument(int deviceId, MtpObjectInfo objectInfo, ParcelFileDescriptor source)
154b80a3cfd05fc7492dd59b7f8d4337eb5e29088c2Tomasz Mikolajewski            throws IOException {
15535b2ec551f670562a779925fe152307f20ad67cdDaichi Hirono        Assert.assertNotSame(0, objectInfo.getStorageId());
15635b2ec551f670562a779925fe152307f20ad67cdDaichi Hirono        Assert.assertNotSame(-1, objectInfo.getStorageId());
15735b2ec551f670562a779925fe152307f20ad67cdDaichi Hirono        Assert.assertNotSame(0, objectInfo.getParent());
158df544176b10f536969de1ed143b0ba57123fcb93Tomasz Mikolajewski        final String key = pack(deviceId, CREATED_DOCUMENT_HANDLE);
159df544176b10f536969de1ed143b0ba57123fcb93Tomasz Mikolajewski        if (mObjectInfos.containsKey(key)) {
160b80a3cfd05fc7492dd59b7f8d4337eb5e29088c2Tomasz Mikolajewski            throw new IOException();
161b80a3cfd05fc7492dd59b7f8d4337eb5e29088c2Tomasz Mikolajewski        }
162f578fa275a535016f5322c88ad7a92e517d04a12Daichi Hirono        final MtpObjectInfo newInfo = new MtpObjectInfo.Builder(objectInfo).
163f578fa275a535016f5322c88ad7a92e517d04a12Daichi Hirono                setObjectHandle(CREATED_DOCUMENT_HANDLE).build();
164f578fa275a535016f5322c88ad7a92e517d04a12Daichi Hirono        mObjectInfos.put(key, newInfo);
165df544176b10f536969de1ed143b0ba57123fcb93Tomasz Mikolajewski        if (objectInfo.getFormat() != 0x3001) {
166df544176b10f536969de1ed143b0ba57123fcb93Tomasz Mikolajewski            try (final ParcelFileDescriptor.AutoCloseInputStream inputStream =
167df544176b10f536969de1ed143b0ba57123fcb93Tomasz Mikolajewski                    new ParcelFileDescriptor.AutoCloseInputStream(source)) {
168df544176b10f536969de1ed143b0ba57123fcb93Tomasz Mikolajewski                final byte[] buffer = new byte[objectInfo.getCompressedSize()];
169df544176b10f536969de1ed143b0ba57123fcb93Tomasz Mikolajewski                if (inputStream.read(buffer, 0, objectInfo.getCompressedSize()) !=
170df544176b10f536969de1ed143b0ba57123fcb93Tomasz Mikolajewski                        objectInfo.getCompressedSize()) {
171df544176b10f536969de1ed143b0ba57123fcb93Tomasz Mikolajewski                    throw new IOException();
172df544176b10f536969de1ed143b0ba57123fcb93Tomasz Mikolajewski                }
173df544176b10f536969de1ed143b0ba57123fcb93Tomasz Mikolajewski
174df544176b10f536969de1ed143b0ba57123fcb93Tomasz Mikolajewski                mImportFileBytes.put(pack(deviceId, CREATED_DOCUMENT_HANDLE), buffer);
175df544176b10f536969de1ed143b0ba57123fcb93Tomasz Mikolajewski            }
176b80a3cfd05fc7492dd59b7f8d4337eb5e29088c2Tomasz Mikolajewski        }
177df544176b10f536969de1ed143b0ba57123fcb93Tomasz Mikolajewski        return CREATED_DOCUMENT_HANDLE;
178b80a3cfd05fc7492dd59b7f8d4337eb5e29088c2Tomasz Mikolajewski    }
179b80a3cfd05fc7492dd59b7f8d4337eb5e29088c2Tomasz Mikolajewski
180b80a3cfd05fc7492dd59b7f8d4337eb5e29088c2Tomasz Mikolajewski    @Override
1813faa43a4a6f270e2e1e2ec55b77508084af16757Daichi Hirono    byte[] getThumbnail(int deviceId, int objectHandle) throws IOException {
1823faa43a4a6f270e2e1e2ec55b77508084af16757Daichi Hirono        final String key = pack(deviceId, objectHandle);
1833faa43a4a6f270e2e1e2ec55b77508084af16757Daichi Hirono        if (mThumbnailBytes.containsKey(key)) {
1843faa43a4a6f270e2e1e2ec55b77508084af16757Daichi Hirono            return mThumbnailBytes.get(key);
1853faa43a4a6f270e2e1e2ec55b77508084af16757Daichi Hirono        } else {
1863faa43a4a6f270e2e1e2ec55b77508084af16757Daichi Hirono            throw new IOException("getThumbnail error: " + key);
1873faa43a4a6f270e2e1e2ec55b77508084af16757Daichi Hirono        }
1883faa43a4a6f270e2e1e2ec55b77508084af16757Daichi Hirono    }
1893faa43a4a6f270e2e1e2ec55b77508084af16757Daichi Hirono
1903faa43a4a6f270e2e1e2ec55b77508084af16757Daichi Hirono    @Override
1915fecc6cf032bbbc2616dd2342a50656bf2857832Daichi Hirono    void deleteDocument(int deviceId, int objectHandle) throws IOException {
1925fecc6cf032bbbc2616dd2342a50656bf2857832Daichi Hirono        final String key = pack(deviceId, objectHandle);
193bb430fa930fa0d0700e46e7b4881de2a252223ddTomasz Mikolajewski        if (mObjectInfos.containsKey(key)) {
194bb430fa930fa0d0700e46e7b4881de2a252223ddTomasz Mikolajewski            mObjectInfos.remove(key);
1955fecc6cf032bbbc2616dd2342a50656bf2857832Daichi Hirono        } else {
1965fecc6cf032bbbc2616dd2342a50656bf2857832Daichi Hirono            throw new IOException();
1975fecc6cf032bbbc2616dd2342a50656bf2857832Daichi Hirono        }
1985fecc6cf032bbbc2616dd2342a50656bf2857832Daichi Hirono    }
1995fecc6cf032bbbc2616dd2342a50656bf2857832Daichi Hirono
2005fecc6cf032bbbc2616dd2342a50656bf2857832Daichi Hirono    @Override
201ab65d363bbff29b3d46a5b0a5e73b8ed20140287Tomasz Mikolajewski    int getParent(int deviceId, int objectHandle) throws IOException {
2025fecc6cf032bbbc2616dd2342a50656bf2857832Daichi Hirono        final String key = pack(deviceId, objectHandle);
203ab65d363bbff29b3d46a5b0a5e73b8ed20140287Tomasz Mikolajewski        if (mObjectInfos.containsKey(key)) {
204ab65d363bbff29b3d46a5b0a5e73b8ed20140287Tomasz Mikolajewski            return mObjectInfos.get(key).getParent();
2055fecc6cf032bbbc2616dd2342a50656bf2857832Daichi Hirono        } else {
2065fecc6cf032bbbc2616dd2342a50656bf2857832Daichi Hirono            throw new IOException();
2075fecc6cf032bbbc2616dd2342a50656bf2857832Daichi Hirono        }
2085fecc6cf032bbbc2616dd2342a50656bf2857832Daichi Hirono    }
2095fecc6cf032bbbc2616dd2342a50656bf2857832Daichi Hirono
2105fecc6cf032bbbc2616dd2342a50656bf2857832Daichi Hirono    @Override
211cc9a7d78d519aa25b4afbc96afd401be75696ddaDaichi Hirono    byte[] getObject(int deviceId, int objectHandle, int expectedSize) throws IOException {
212cc9a7d78d519aa25b4afbc96afd401be75696ddaDaichi Hirono        return mImportFileBytes.get(pack(deviceId, objectHandle));
213cc9a7d78d519aa25b4afbc96afd401be75696ddaDaichi Hirono    }
214b36b15586a5d3d0de590773ce4392fa3a82af66aDaichi Hirono
215b36b15586a5d3d0de590773ce4392fa3a82af66aDaichi Hirono    @Override
216b36b15586a5d3d0de590773ce4392fa3a82af66aDaichi Hirono    long getPartialObject(int deviceId, int objectHandle, long offset, long size, byte[] buffer)
217b36b15586a5d3d0de590773ce4392fa3a82af66aDaichi Hirono            throws IOException {
218b36b15586a5d3d0de590773ce4392fa3a82af66aDaichi Hirono        final byte[] bytes = mImportFileBytes.get(pack(deviceId, objectHandle));
219b36b15586a5d3d0de590773ce4392fa3a82af66aDaichi Hirono        int i = 0;
220b36b15586a5d3d0de590773ce4392fa3a82af66aDaichi Hirono        while (i < size && i + offset < bytes.length) {
221b36b15586a5d3d0de590773ce4392fa3a82af66aDaichi Hirono            buffer[i] = bytes[(int) (i + offset)];
222b36b15586a5d3d0de590773ce4392fa3a82af66aDaichi Hirono            i++;
223b36b15586a5d3d0de590773ce4392fa3a82af66aDaichi Hirono        }
224b36b15586a5d3d0de590773ce4392fa3a82af66aDaichi Hirono        return i;
225b36b15586a5d3d0de590773ce4392fa3a82af66aDaichi Hirono    }
22664111e08d905525c7f4fe27e69953eb71bd62511Daichi Hirono
22764111e08d905525c7f4fe27e69953eb71bd62511Daichi Hirono    @Override
22864111e08d905525c7f4fe27e69953eb71bd62511Daichi Hirono    long getObjectSizeLong(int deviceId, int objectHandle, int format) throws IOException {
22964111e08d905525c7f4fe27e69953eb71bd62511Daichi Hirono        final String key = pack(deviceId, objectHandle, format);
23064111e08d905525c7f4fe27e69953eb71bd62511Daichi Hirono        if (mObjectSizeLongs.containsKey(key)) {
23164111e08d905525c7f4fe27e69953eb71bd62511Daichi Hirono            return mObjectSizeLongs.get(key);
23264111e08d905525c7f4fe27e69953eb71bd62511Daichi Hirono        } else {
23364111e08d905525c7f4fe27e69953eb71bd62511Daichi Hirono            throw new IOException();
23464111e08d905525c7f4fe27e69953eb71bd62511Daichi Hirono        }
23564111e08d905525c7f4fe27e69953eb71bd62511Daichi Hirono    }
23609109567e9816d20f51b5ce0175751116836635fDaichi Hirono}
237