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.hardware.usb.UsbDevice;
     21 import android.hardware.usb.UsbManager;
     22 import android.mtp.MtpConstants;
     23 import android.mtp.MtpEvent;
     24 import android.mtp.MtpObjectInfo;
     25 import android.os.CancellationSignal;
     26 import android.os.OperationCanceledException;
     27 import android.os.ParcelFileDescriptor;
     28 import android.os.SystemClock;
     29 import android.test.InstrumentationTestCase;
     30 
     31 import java.io.IOException;
     32 import java.util.Arrays;
     33 import java.util.concurrent.Callable;
     34 import java.util.concurrent.FutureTask;
     35 import java.util.concurrent.TimeUnit;
     36 
     37 @RealDeviceTest
     38 public class MtpManagerTest extends InstrumentationTestCase {
     39     private static final int TIMEOUT_MS = 1000;
     40     UsbManager mUsbManager;
     41     MtpManager mManager;
     42     UsbDevice mUsbDevice;
     43 
     44     @Override
     45     public void setUp() throws Exception {
     46         mUsbManager = getContext().getSystemService(UsbManager.class);
     47         mManager = new MtpManager(getContext());
     48         mUsbDevice = TestUtil.setupMtpDevice(getInstrumentation(), mUsbManager, mManager);
     49     }
     50 
     51     @Override
     52     public void tearDown() throws IOException {
     53         mManager.closeDevice(mUsbDevice.getDeviceId());
     54     }
     55 
     56     @Override
     57     public TestResultInstrumentation getInstrumentation() {
     58         return (TestResultInstrumentation) super.getInstrumentation();
     59     }
     60 
     61     public void testCancelEvent() throws Exception {
     62         final CancellationSignal signal = new CancellationSignal();
     63         final FutureTask<Boolean> future = new FutureTask<Boolean>(
     64                 new Callable<Boolean>() {
     65                     @Override
     66                     public Boolean call() throws IOException {
     67                         try {
     68                             while (true) {
     69                                 mManager.readEvent(mUsbDevice.getDeviceId(), signal);
     70                             }
     71                         } catch (OperationCanceledException exception) {
     72                             return true;
     73                         }
     74                     }
     75                 });
     76         final Thread thread = new Thread(future);
     77         thread.start();
     78         SystemClock.sleep(TIMEOUT_MS);
     79         signal.cancel();
     80         assertTrue(future.get(TIMEOUT_MS, TimeUnit.MILLISECONDS));
     81     }
     82 
     83     public void testOperationsSupported() {
     84         final MtpDeviceRecord[] records = mManager.getDevices();
     85         assertEquals(1, records.length);
     86         assertNotNull(records[0].operationsSupported);
     87         getInstrumentation().show(Arrays.toString(records[0].operationsSupported));
     88     }
     89 
     90     public void testEventsSupported() {
     91         final MtpDeviceRecord[] records = mManager.getDevices();
     92         assertEquals(1, records.length);
     93         assertNotNull(records[0].eventsSupported);
     94         getInstrumentation().show(Arrays.toString(records[0].eventsSupported));
     95     }
     96 
     97     public void testDeviceKey() {
     98         final MtpDeviceRecord[] records = mManager.getDevices();
     99         assertEquals(1, records.length);
    100         assertNotNull(records[0].deviceKey);
    101         getInstrumentation().show("deviceKey: " + records[0].deviceKey);
    102     }
    103 
    104     public void testEventObjectAdded() throws Exception {
    105         while (true) {
    106             getInstrumentation().show("Please take a photo by using connected MTP device.");
    107             final CancellationSignal signal = new CancellationSignal();
    108             MtpEvent event = mManager.readEvent(mUsbDevice.getDeviceId(), signal);
    109             if (event.getEventCode() != MtpEvent.EVENT_OBJECT_ADDED) {
    110                 continue;
    111             }
    112             assertTrue(event.getObjectHandle() != 0);
    113             break;
    114         }
    115     }
    116 
    117     public void testCreateDocumentAndGetPartialObject() throws Exception {
    118         int storageId = 0;
    119         for (final MtpDeviceRecord record : mManager.getDevices()) {
    120             if (record.deviceId == mUsbDevice.getDeviceId()) {
    121                 storageId = record.roots[0].mStorageId;
    122                 break;
    123             }
    124         }
    125         assertTrue("Valid storage not found.", storageId != 0);
    126 
    127         final String testFileName = "MtpManagerTest_testFile.txt";
    128         for (final int handle : mManager.getObjectHandles(
    129                 mUsbDevice.getDeviceId(), storageId, MtpManager.OBJECT_HANDLE_ROOT_CHILDREN)) {
    130             if (mManager.getObjectInfo(mUsbDevice.getDeviceId(), handle)
    131                     .getName().equals(testFileName)) {
    132                 mManager.deleteDocument(mUsbDevice.getDeviceId(), handle);
    133                 break;
    134             }
    135         }
    136 
    137         final ParcelFileDescriptor[] fds = ParcelFileDescriptor.createPipe();
    138         final byte[] expectedBytes = "Hello Android!".getBytes("ascii");
    139         try (final ParcelFileDescriptor.AutoCloseOutputStream stream =
    140                 new ParcelFileDescriptor.AutoCloseOutputStream(fds[1])) {
    141             stream.write(expectedBytes);
    142         }
    143         final int objectHandle = mManager.createDocument(
    144                 mUsbDevice.getDeviceId(),
    145                 new MtpObjectInfo.Builder()
    146                         .setStorageId(storageId)
    147                         .setName(testFileName)
    148                         .setCompressedSize(expectedBytes.length)
    149                         .setFormat(MtpConstants.FORMAT_TEXT)
    150                         .build(),
    151                 fds[0]);
    152         final byte[] bytes = new byte[100];
    153         assertEquals(5, mManager.getPartialObject(
    154                 mUsbDevice.getDeviceId(), objectHandle, 0, 5, bytes));
    155         assertEquals("Hello", new String(bytes, 0, 5, "ascii"));
    156         assertEquals(8, mManager.getPartialObject(
    157                 mUsbDevice.getDeviceId(), objectHandle, 6, 100, bytes));
    158         assertEquals("Android!", new String(bytes, 0, 8, "ascii"));
    159     }
    160 
    161     private Context getContext() {
    162         return getInstrumentation().getContext();
    163     }
    164 }
    165