TestMtpManager.java revision f578fa275a535016f5322c88ad7a92e517d04a12
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;
25e5323b7493f2bc1537d7e6b2d4595d69fd01d72eDaichi Hironoimport java.util.Arrays;
2609109567e9816d20f51b5ce0175751116836635fDaichi Hironoimport java.util.HashMap;
2709109567e9816d20f51b5ce0175751116836635fDaichi Hironoimport java.util.Map;
2809109567e9816d20f51b5ce0175751116836635fDaichi Hirono
296ee4a1c1247e2a1d3032bcd432f843cbb7227dccDaichi Hironopublic class TestMtpManager extends MtpManager {
30b80a3cfd05fc7492dd59b7f8d4337eb5e29088c2Tomasz Mikolajewski    public static final int CREATED_DOCUMENT_HANDLE = 1000;
31b80a3cfd05fc7492dd59b7f8d4337eb5e29088c2Tomasz Mikolajewski
326baa16e9109046661fef8dcc25b8754ac68bcdaeDaichi Hirono    protected static String pack(int... args) {
33e5323b7493f2bc1537d7e6b2d4595d69fd01d72eDaichi Hirono        return Arrays.toString(args);
34e5323b7493f2bc1537d7e6b2d4595d69fd01d72eDaichi Hirono    }
35e5323b7493f2bc1537d7e6b2d4595d69fd01d72eDaichi Hirono
3620754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono    private final SparseArray<MtpDeviceRecord> mDevices = new SparseArray<>();
37bb430fa930fa0d0700e46e7b4881de2a252223ddTomasz Mikolajewski    private final Map<String, MtpObjectInfo> mObjectInfos = new HashMap<>();
38124d060bc980c7555616ff9d07a4dc3b8f3cd341Daichi Hirono    private final Map<String, int[]> mObjectHandles = new HashMap<>();
39124d060bc980c7555616ff9d07a4dc3b8f3cd341Daichi Hirono    private final Map<String, byte[]> mThumbnailBytes = new HashMap<>();
40124d060bc980c7555616ff9d07a4dc3b8f3cd341Daichi Hirono    private final Map<String, byte[]> mImportFileBytes = new HashMap<>();
4109109567e9816d20f51b5ce0175751116836635fDaichi Hirono
426ee4a1c1247e2a1d3032bcd432f843cbb7227dccDaichi Hirono    TestMtpManager(Context context) {
4309109567e9816d20f51b5ce0175751116836635fDaichi Hirono        super(context);
4409109567e9816d20f51b5ce0175751116836635fDaichi Hirono    }
4509109567e9816d20f51b5ce0175751116836635fDaichi Hirono
4620754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono    void addValidDevice(MtpDeviceRecord device) {
4720754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono        mDevices.put(device.deviceId, device);
4809109567e9816d20f51b5ce0175751116836635fDaichi Hirono    }
4909109567e9816d20f51b5ce0175751116836635fDaichi Hirono
50bb430fa930fa0d0700e46e7b4881de2a252223ddTomasz Mikolajewski    void setObjectHandles(int deviceId, int storageId, int parentHandle, int[] objectHandles) {
51bb430fa930fa0d0700e46e7b4881de2a252223ddTomasz Mikolajewski        mObjectHandles.put(pack(deviceId, storageId, parentHandle), objectHandles);
52124d060bc980c7555616ff9d07a4dc3b8f3cd341Daichi Hirono    }
53124d060bc980c7555616ff9d07a4dc3b8f3cd341Daichi Hirono
54bb430fa930fa0d0700e46e7b4881de2a252223ddTomasz Mikolajewski    void setObjectInfo(int deviceId, MtpObjectInfo objectInfo) {
55bb430fa930fa0d0700e46e7b4881de2a252223ddTomasz Mikolajewski        mObjectInfos.put(pack(deviceId, objectInfo.getObjectHandle()), objectInfo);
56e5323b7493f2bc1537d7e6b2d4595d69fd01d72eDaichi Hirono    }
57e5323b7493f2bc1537d7e6b2d4595d69fd01d72eDaichi Hirono
5852652ac7a5f479f7f5e24f78778203bd88c0c4f4Tomasz Mikolajewski    void setImportFileBytes(int deviceId, int objectHandle, byte[] bytes) {
5952652ac7a5f479f7f5e24f78778203bd88c0c4f4Tomasz Mikolajewski        mImportFileBytes.put(pack(deviceId, objectHandle), bytes);
608ba419119d50a031160cab54bef6899bd0051ea9Daichi Hirono    }
618ba419119d50a031160cab54bef6899bd0051ea9Daichi Hirono
62b80a3cfd05fc7492dd59b7f8d4337eb5e29088c2Tomasz Mikolajewski    byte[] getImportFileBytes(int deviceId, int objectHandle) {
63b80a3cfd05fc7492dd59b7f8d4337eb5e29088c2Tomasz Mikolajewski        return mImportFileBytes.get(pack(deviceId, objectHandle));
64b80a3cfd05fc7492dd59b7f8d4337eb5e29088c2Tomasz Mikolajewski    }
65b80a3cfd05fc7492dd59b7f8d4337eb5e29088c2Tomasz Mikolajewski
663faa43a4a6f270e2e1e2ec55b77508084af16757Daichi Hirono    void setThumbnail(int deviceId, int objectHandle, byte[] bytes) {
673faa43a4a6f270e2e1e2ec55b77508084af16757Daichi Hirono        mThumbnailBytes.put(pack(deviceId, objectHandle), bytes);
683faa43a4a6f270e2e1e2ec55b77508084af16757Daichi Hirono    }
693faa43a4a6f270e2e1e2ec55b77508084af16757Daichi Hirono
7009109567e9816d20f51b5ce0175751116836635fDaichi Hirono    @Override
7120754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono    MtpDeviceRecord[] getDevices() {
7220754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono        final MtpDeviceRecord[] result = new MtpDeviceRecord[mDevices.size()];
7320754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono        for (int i = 0; i < mDevices.size(); i++) {
7420754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono            final MtpDeviceRecord device = mDevices.valueAt(i);
7520754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono            if (device.opened) {
7620754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono                result[i] = device;
7720754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono            } else {
7820754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono                result[i] = new MtpDeviceRecord(
79ebd24051599280443435606cab220de33b9356adDaichi Hirono                        device.deviceId, device.name, device.deviceKey, device.opened,
80ebd24051599280443435606cab220de33b9356adDaichi Hirono                        new MtpRoot[0], null, null);
8120754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono            }
8209109567e9816d20f51b5ce0175751116836635fDaichi Hirono        }
8320754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono        return result;
8409109567e9816d20f51b5ce0175751116836635fDaichi Hirono    }
8509109567e9816d20f51b5ce0175751116836635fDaichi Hirono
8609109567e9816d20f51b5ce0175751116836635fDaichi Hirono    @Override
8720754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono    void openDevice(int deviceId) throws IOException {
8820754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono        final MtpDeviceRecord device = mDevices.get(deviceId);
8920754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono        if (device == null || device.opened) {
9009109567e9816d20f51b5ce0175751116836635fDaichi Hirono            throw new IOException();
9109109567e9816d20f51b5ce0175751116836635fDaichi Hirono        }
9220754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono        mDevices.put(
9320754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono                deviceId,
94ebd24051599280443435606cab220de33b9356adDaichi Hirono                new MtpDeviceRecord(
95ebd24051599280443435606cab220de33b9356adDaichi Hirono                        device.deviceId, device.name, device.deviceKey, true, device.roots, null,
96ebd24051599280443435606cab220de33b9356adDaichi Hirono                        null));
9709109567e9816d20f51b5ce0175751116836635fDaichi Hirono    }
9809109567e9816d20f51b5ce0175751116836635fDaichi Hirono
9909109567e9816d20f51b5ce0175751116836635fDaichi Hirono    @Override
10020754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono    void closeDevice(int deviceId) throws IOException {
10120754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono        final MtpDeviceRecord device = mDevices.get(deviceId);
10220754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono        if (device == null || !device.opened) {
10320754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono            throw new IOException();
10409109567e9816d20f51b5ce0175751116836635fDaichi Hirono        }
10520754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono        mDevices.put(
10620754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono                deviceId,
107ebd24051599280443435606cab220de33b9356adDaichi Hirono                new MtpDeviceRecord(device.deviceId, device.name, device.deviceKey, false,
108ebd24051599280443435606cab220de33b9356adDaichi Hirono                        device.roots, null, null));
10909109567e9816d20f51b5ce0175751116836635fDaichi Hirono    }
11009109567e9816d20f51b5ce0175751116836635fDaichi Hirono
11109109567e9816d20f51b5ce0175751116836635fDaichi Hirono    @Override
112bb430fa930fa0d0700e46e7b4881de2a252223ddTomasz Mikolajewski    MtpObjectInfo getObjectInfo(int deviceId, int objectHandle) throws IOException {
113124d060bc980c7555616ff9d07a4dc3b8f3cd341Daichi Hirono        final String key = pack(deviceId, objectHandle);
114bb430fa930fa0d0700e46e7b4881de2a252223ddTomasz Mikolajewski        if (mObjectInfos.containsKey(key)) {
115bb430fa930fa0d0700e46e7b4881de2a252223ddTomasz Mikolajewski            return mObjectInfos.get(key);
116124d060bc980c7555616ff9d07a4dc3b8f3cd341Daichi Hirono        } else {
117bb430fa930fa0d0700e46e7b4881de2a252223ddTomasz Mikolajewski            throw new IOException("getObjectInfo error: " + key);
118124d060bc980c7555616ff9d07a4dc3b8f3cd341Daichi Hirono        }
119124d060bc980c7555616ff9d07a4dc3b8f3cd341Daichi Hirono    }
120124d060bc980c7555616ff9d07a4dc3b8f3cd341Daichi Hirono
121124d060bc980c7555616ff9d07a4dc3b8f3cd341Daichi Hirono    @Override
122124d060bc980c7555616ff9d07a4dc3b8f3cd341Daichi Hirono    int[] getObjectHandles(int deviceId, int storageId, int parentObjectHandle) throws IOException {
123124d060bc980c7555616ff9d07a4dc3b8f3cd341Daichi Hirono        final String key = pack(deviceId, storageId, parentObjectHandle);
124124d060bc980c7555616ff9d07a4dc3b8f3cd341Daichi Hirono        if (mObjectHandles.containsKey(key)) {
125124d060bc980c7555616ff9d07a4dc3b8f3cd341Daichi Hirono            return mObjectHandles.get(key);
126124d060bc980c7555616ff9d07a4dc3b8f3cd341Daichi Hirono        } else {
127124d060bc980c7555616ff9d07a4dc3b8f3cd341Daichi Hirono            throw new IOException("getObjectHandles error: " + key);
128124d060bc980c7555616ff9d07a4dc3b8f3cd341Daichi Hirono        }
129e5323b7493f2bc1537d7e6b2d4595d69fd01d72eDaichi Hirono    }
130e5323b7493f2bc1537d7e6b2d4595d69fd01d72eDaichi Hirono
131e5323b7493f2bc1537d7e6b2d4595d69fd01d72eDaichi Hirono    @Override
132b80a3cfd05fc7492dd59b7f8d4337eb5e29088c2Tomasz Mikolajewski    void importFile(int deviceId, int objectHandle, ParcelFileDescriptor target)
133b80a3cfd05fc7492dd59b7f8d4337eb5e29088c2Tomasz Mikolajewski            throws IOException {
134b80a3cfd05fc7492dd59b7f8d4337eb5e29088c2Tomasz Mikolajewski        final String key = pack(deviceId, objectHandle);
13552652ac7a5f479f7f5e24f78778203bd88c0c4f4Tomasz Mikolajewski        if (mImportFileBytes.containsKey(key)) {
13652652ac7a5f479f7f5e24f78778203bd88c0c4f4Tomasz Mikolajewski            try (final ParcelFileDescriptor.AutoCloseOutputStream outputStream =
13752652ac7a5f479f7f5e24f78778203bd88c0c4f4Tomasz Mikolajewski                    new ParcelFileDescriptor.AutoCloseOutputStream(target)) {
13852652ac7a5f479f7f5e24f78778203bd88c0c4f4Tomasz Mikolajewski                outputStream.write(mImportFileBytes.get(key));
13952652ac7a5f479f7f5e24f78778203bd88c0c4f4Tomasz Mikolajewski            }
1408ba419119d50a031160cab54bef6899bd0051ea9Daichi Hirono        } else {
14152652ac7a5f479f7f5e24f78778203bd88c0c4f4Tomasz Mikolajewski            throw new IOException("importFile error: " + key);
1428ba419119d50a031160cab54bef6899bd0051ea9Daichi Hirono        }
1438ba419119d50a031160cab54bef6899bd0051ea9Daichi Hirono    }
1448ba419119d50a031160cab54bef6899bd0051ea9Daichi Hirono
1458ba419119d50a031160cab54bef6899bd0051ea9Daichi Hirono    @Override
146df544176b10f536969de1ed143b0ba57123fcb93Tomasz Mikolajewski    int createDocument(int deviceId, MtpObjectInfo objectInfo, ParcelFileDescriptor source)
147b80a3cfd05fc7492dd59b7f8d4337eb5e29088c2Tomasz Mikolajewski            throws IOException {
148df544176b10f536969de1ed143b0ba57123fcb93Tomasz Mikolajewski        final String key = pack(deviceId, CREATED_DOCUMENT_HANDLE);
149df544176b10f536969de1ed143b0ba57123fcb93Tomasz Mikolajewski        if (mObjectInfos.containsKey(key)) {
150b80a3cfd05fc7492dd59b7f8d4337eb5e29088c2Tomasz Mikolajewski            throw new IOException();
151b80a3cfd05fc7492dd59b7f8d4337eb5e29088c2Tomasz Mikolajewski        }
152f578fa275a535016f5322c88ad7a92e517d04a12Daichi Hirono        final MtpObjectInfo newInfo = new MtpObjectInfo.Builder(objectInfo).
153f578fa275a535016f5322c88ad7a92e517d04a12Daichi Hirono                setObjectHandle(CREATED_DOCUMENT_HANDLE).build();
154f578fa275a535016f5322c88ad7a92e517d04a12Daichi Hirono        mObjectInfos.put(key, newInfo);
155df544176b10f536969de1ed143b0ba57123fcb93Tomasz Mikolajewski        if (objectInfo.getFormat() != 0x3001) {
156df544176b10f536969de1ed143b0ba57123fcb93Tomasz Mikolajewski            try (final ParcelFileDescriptor.AutoCloseInputStream inputStream =
157df544176b10f536969de1ed143b0ba57123fcb93Tomasz Mikolajewski                    new ParcelFileDescriptor.AutoCloseInputStream(source)) {
158df544176b10f536969de1ed143b0ba57123fcb93Tomasz Mikolajewski                final byte[] buffer = new byte[objectInfo.getCompressedSize()];
159df544176b10f536969de1ed143b0ba57123fcb93Tomasz Mikolajewski                if (inputStream.read(buffer, 0, objectInfo.getCompressedSize()) !=
160df544176b10f536969de1ed143b0ba57123fcb93Tomasz Mikolajewski                        objectInfo.getCompressedSize()) {
161df544176b10f536969de1ed143b0ba57123fcb93Tomasz Mikolajewski                    throw new IOException();
162df544176b10f536969de1ed143b0ba57123fcb93Tomasz Mikolajewski                }
163df544176b10f536969de1ed143b0ba57123fcb93Tomasz Mikolajewski
164df544176b10f536969de1ed143b0ba57123fcb93Tomasz Mikolajewski                mImportFileBytes.put(pack(deviceId, CREATED_DOCUMENT_HANDLE), buffer);
165df544176b10f536969de1ed143b0ba57123fcb93Tomasz Mikolajewski            }
166b80a3cfd05fc7492dd59b7f8d4337eb5e29088c2Tomasz Mikolajewski        }
167df544176b10f536969de1ed143b0ba57123fcb93Tomasz Mikolajewski        return CREATED_DOCUMENT_HANDLE;
168b80a3cfd05fc7492dd59b7f8d4337eb5e29088c2Tomasz Mikolajewski    }
169b80a3cfd05fc7492dd59b7f8d4337eb5e29088c2Tomasz Mikolajewski
170b80a3cfd05fc7492dd59b7f8d4337eb5e29088c2Tomasz Mikolajewski    @Override
1713faa43a4a6f270e2e1e2ec55b77508084af16757Daichi Hirono    byte[] getThumbnail(int deviceId, int objectHandle) throws IOException {
1723faa43a4a6f270e2e1e2ec55b77508084af16757Daichi Hirono        final String key = pack(deviceId, objectHandle);
1733faa43a4a6f270e2e1e2ec55b77508084af16757Daichi Hirono        if (mThumbnailBytes.containsKey(key)) {
1743faa43a4a6f270e2e1e2ec55b77508084af16757Daichi Hirono            return mThumbnailBytes.get(key);
1753faa43a4a6f270e2e1e2ec55b77508084af16757Daichi Hirono        } else {
1763faa43a4a6f270e2e1e2ec55b77508084af16757Daichi Hirono            throw new IOException("getThumbnail error: " + key);
1773faa43a4a6f270e2e1e2ec55b77508084af16757Daichi Hirono        }
1783faa43a4a6f270e2e1e2ec55b77508084af16757Daichi Hirono    }
1793faa43a4a6f270e2e1e2ec55b77508084af16757Daichi Hirono
1803faa43a4a6f270e2e1e2ec55b77508084af16757Daichi Hirono    @Override
1815fecc6cf032bbbc2616dd2342a50656bf2857832Daichi Hirono    void deleteDocument(int deviceId, int objectHandle) throws IOException {
1825fecc6cf032bbbc2616dd2342a50656bf2857832Daichi Hirono        final String key = pack(deviceId, objectHandle);
183bb430fa930fa0d0700e46e7b4881de2a252223ddTomasz Mikolajewski        if (mObjectInfos.containsKey(key)) {
184bb430fa930fa0d0700e46e7b4881de2a252223ddTomasz Mikolajewski            mObjectInfos.remove(key);
1855fecc6cf032bbbc2616dd2342a50656bf2857832Daichi Hirono        } else {
1865fecc6cf032bbbc2616dd2342a50656bf2857832Daichi Hirono            throw new IOException();
1875fecc6cf032bbbc2616dd2342a50656bf2857832Daichi Hirono        }
1885fecc6cf032bbbc2616dd2342a50656bf2857832Daichi Hirono    }
1895fecc6cf032bbbc2616dd2342a50656bf2857832Daichi Hirono
1905fecc6cf032bbbc2616dd2342a50656bf2857832Daichi Hirono    @Override
191ab65d363bbff29b3d46a5b0a5e73b8ed20140287Tomasz Mikolajewski    int getParent(int deviceId, int objectHandle) throws IOException {
1925fecc6cf032bbbc2616dd2342a50656bf2857832Daichi Hirono        final String key = pack(deviceId, objectHandle);
193ab65d363bbff29b3d46a5b0a5e73b8ed20140287Tomasz Mikolajewski        if (mObjectInfos.containsKey(key)) {
194ab65d363bbff29b3d46a5b0a5e73b8ed20140287Tomasz Mikolajewski            return mObjectInfos.get(key).getParent();
1955fecc6cf032bbbc2616dd2342a50656bf2857832Daichi Hirono        } else {
1965fecc6cf032bbbc2616dd2342a50656bf2857832Daichi Hirono            throw new IOException();
1975fecc6cf032bbbc2616dd2342a50656bf2857832Daichi Hirono        }
1985fecc6cf032bbbc2616dd2342a50656bf2857832Daichi Hirono    }
1995fecc6cf032bbbc2616dd2342a50656bf2857832Daichi Hirono
2005fecc6cf032bbbc2616dd2342a50656bf2857832Daichi Hirono    @Override
20109109567e9816d20f51b5ce0175751116836635fDaichi Hirono    int[] getOpenedDeviceIds() {
20220754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono        final int[] result = new int[mDevices.size()];
20320754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono        int count = 0;
20420754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono        for (int i = 0; i < mDevices.size(); i++) {
20520754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono            final MtpDeviceRecord device = mDevices.valueAt(i);
20620754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono            if (device.opened) {
20720754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono                result[count++] = device.deviceId;
20820754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono            }
20909109567e9816d20f51b5ce0175751116836635fDaichi Hirono        }
21020754c5a112e418c11cc88176283db2c4bf2efd6Daichi Hirono        return Arrays.copyOf(result, count);
211b3fe72bfb288a509a953e5586264ca1c4460d2dfDaichi Hirono    }
212cc9a7d78d519aa25b4afbc96afd401be75696ddaDaichi Hirono
213cc9a7d78d519aa25b4afbc96afd401be75696ddaDaichi Hirono    @Override
214cc9a7d78d519aa25b4afbc96afd401be75696ddaDaichi Hirono    byte[] getObject(int deviceId, int objectHandle, int expectedSize) throws IOException {
215cc9a7d78d519aa25b4afbc96afd401be75696ddaDaichi Hirono        return mImportFileBytes.get(pack(deviceId, objectHandle));
216cc9a7d78d519aa25b4afbc96afd401be75696ddaDaichi Hirono    }
217b36b15586a5d3d0de590773ce4392fa3a82af66aDaichi Hirono
218b36b15586a5d3d0de590773ce4392fa3a82af66aDaichi Hirono    @Override
219b36b15586a5d3d0de590773ce4392fa3a82af66aDaichi Hirono    long getPartialObject(int deviceId, int objectHandle, long offset, long size, byte[] buffer)
220b36b15586a5d3d0de590773ce4392fa3a82af66aDaichi Hirono            throws IOException {
221b36b15586a5d3d0de590773ce4392fa3a82af66aDaichi Hirono        final byte[] bytes = mImportFileBytes.get(pack(deviceId, objectHandle));
222b36b15586a5d3d0de590773ce4392fa3a82af66aDaichi Hirono        int i = 0;
223b36b15586a5d3d0de590773ce4392fa3a82af66aDaichi Hirono        while (i < size && i + offset < bytes.length) {
224b36b15586a5d3d0de590773ce4392fa3a82af66aDaichi Hirono            buffer[i] = bytes[(int) (i + offset)];
225b36b15586a5d3d0de590773ce4392fa3a82af66aDaichi Hirono            i++;
226b36b15586a5d3d0de590773ce4392fa3a82af66aDaichi Hirono        }
227b36b15586a5d3d0de590773ce4392fa3a82af66aDaichi Hirono        return i;
228b36b15586a5d3d0de590773ce4392fa3a82af66aDaichi Hirono    }
22909109567e9816d20f51b5ce0175751116836635fDaichi Hirono}
230