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 
     30 public 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