Home | History | Annotate | Download | only in mtp
      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 
     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 
     45     TestMtpManager(Context context) {
     46         super(context);
     47     }
     48 
     49     void addValidDevice(MtpDeviceRecord device) {
     50         mDevices.put(device.deviceId, device);
     51     }
     52 
     53     void setObjectHandles(int deviceId, int storageId, int parentHandle, int[] objectHandles) {
     54         mObjectHandles.put(pack(deviceId, storageId, parentHandle), objectHandles);
     55     }
     56 
     57     void setObjectInfo(int deviceId, MtpObjectInfo objectInfo) {
     58         mObjectInfos.put(pack(deviceId, objectInfo.getObjectHandle()), objectInfo);
     59     }
     60 
     61     void setImportFileBytes(int deviceId, int objectHandle, byte[] bytes) {
     62         mImportFileBytes.put(pack(deviceId, objectHandle), bytes);
     63     }
     64 
     65     byte[] getImportFileBytes(int deviceId, int objectHandle) {
     66         return mImportFileBytes.get(pack(deviceId, objectHandle));
     67     }
     68 
     69     void setThumbnail(int deviceId, int objectHandle, byte[] bytes) {
     70         mThumbnailBytes.put(pack(deviceId, objectHandle), bytes);
     71     }
     72 
     73     void setObjectSizeLong(int deviceId, int objectHandle, int format, long value) {
     74         mObjectSizeLongs.put(pack(deviceId, objectHandle, format), value);
     75     }
     76 
     77     @Override
     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
     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
    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
    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
    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
    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
    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
    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
    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
    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
    211     byte[] getObject(int deviceId, int objectHandle, int expectedSize) throws IOException {
    212         return mImportFileBytes.get(pack(deviceId, objectHandle));
    213     }
    214 
    215     @Override
    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
    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