Home | History | Annotate | Download | only in integration
      1 /*
      2  * Copyright (C) 2013 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.mediaframeworktest.integration;
     18 
     19 import android.hardware.CameraInfo;
     20 import android.hardware.ICamera;
     21 import android.hardware.ICameraClient;
     22 import android.hardware.ICameraService;
     23 import android.hardware.ICameraServiceListener;
     24 import android.hardware.camera2.ICameraDeviceCallbacks;
     25 import android.hardware.camera2.ICameraDeviceUser;
     26 import android.hardware.camera2.impl.CameraMetadataNative;
     27 import android.hardware.camera2.impl.CaptureResultExtras;
     28 import android.hardware.camera2.impl.PhysicalCaptureResultInfo;
     29 import android.os.Binder;
     30 import android.os.IBinder;
     31 import android.os.RemoteException;
     32 import android.os.ServiceSpecificException;
     33 import android.test.AndroidTestCase;
     34 import android.test.suitebuilder.annotation.SmallTest;
     35 import android.util.Log;
     36 
     37 /**
     38  * <p>
     39  * Junit / Instrumentation test case for the camera2 api
     40  * </p>
     41  * <p>
     42  * To run only tests in this class:
     43  * </p>
     44  *
     45  * <pre>
     46  * adb shell am instrument \
     47  *   -e class com.android.mediaframeworktest.integration.CameraBinderTest \
     48  *   -w com.android.mediaframeworktest/.MediaFrameworkIntegrationTestRunner
     49  * </pre>
     50  */
     51 public class CameraBinderTest extends AndroidTestCase {
     52     private static final int MAX_PARAMETERS_LENGTH = 100;
     53 
     54     static String TAG = "CameraBinderTest";
     55 
     56     // From ICameraService.h
     57     private static final int API_VERSION_1 = 1;
     58     private static final int API_VERSION_2 = 2;
     59 
     60     private static final int CAMERA_TYPE_BACKWARD_COMPATIBLE = 0;
     61     private static final int CAMERA_TYPE_ALL = 1;
     62 
     63     protected CameraBinderTestUtils mUtils;
     64 
     65     public CameraBinderTest() {
     66     }
     67 
     68     @Override
     69     protected void setUp() throws Exception {
     70         super.setUp();
     71 
     72         mUtils = new CameraBinderTestUtils(getContext());
     73     }
     74 
     75     @SmallTest
     76     public void testNumberOfCameras() throws Exception {
     77 
     78         int numCameras = mUtils.getCameraService().getNumberOfCameras(CAMERA_TYPE_ALL);
     79         assertTrue("At least this many cameras: " + mUtils.getGuessedNumCameras(),
     80                 numCameras >= mUtils.getGuessedNumCameras());
     81         Log.v(TAG, "Number of cameras " + numCameras);
     82     }
     83 
     84     @SmallTest
     85     public void testCameraInfo() throws Exception {
     86         for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) {
     87 
     88             CameraInfo info = mUtils.getCameraService().getCameraInfo(cameraId);
     89             assertTrue("Facing was not set for camera " + cameraId, info.info.facing != -1);
     90             assertTrue("Orientation was not set for camera " + cameraId,
     91                     info.info.orientation != -1);
     92 
     93             Log.v(TAG, "Camera " + cameraId + " info: facing " + info.info.facing
     94                     + ", orientation " + info.info.orientation);
     95         }
     96     }
     97 
     98     @SmallTest
     99     public void testGetLegacyParameters() throws Exception {
    100         for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) {
    101 
    102             String parameters = mUtils.getCameraService().getLegacyParameters(cameraId);
    103             assertNotNull(parameters);
    104             assertTrue("Parameters should have at least one character in it",
    105                     parameters.length() > 0);
    106 
    107             int end = parameters.length();
    108             if (end > MAX_PARAMETERS_LENGTH) {
    109                 end = MAX_PARAMETERS_LENGTH;
    110             }
    111 
    112             Log.v(TAG, "Camera " + cameraId + " parameters: " + parameters.substring(0, end));
    113         }
    114     }
    115 
    116     /** The camera2 api is only supported on HAL3.2+ devices */
    117     @SmallTest
    118     public void testSupportsCamera2Api() throws Exception {
    119         for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) {
    120             boolean supports = mUtils.getCameraService().supportsCameraApi(
    121                 String.valueOf(cameraId), API_VERSION_2);
    122 
    123             Log.v(TAG, "Camera " + cameraId + " supports api2: " + supports);
    124         }
    125     }
    126 
    127     /** The camera1 api is supported on *all* devices regardless of HAL version */
    128     @SmallTest
    129     public void testSupportsCamera1Api() throws Exception {
    130         for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) {
    131 
    132             boolean supports = mUtils.getCameraService().supportsCameraApi(
    133                 String.valueOf(cameraId), API_VERSION_1);
    134             assertTrue(
    135                     "Camera service returned false when queried if it supports camera1 api " +
    136                     " for camera ID " + cameraId, supports);
    137         }
    138     }
    139 
    140     static abstract class DummyBase extends Binder implements android.os.IInterface {
    141         @Override
    142         public IBinder asBinder() {
    143             return this;
    144         }
    145     }
    146 
    147     static class DummyCameraClient extends DummyBase implements ICameraClient {
    148     }
    149 
    150     @SmallTest
    151     public void testConnect() throws Exception {
    152         for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) {
    153 
    154             ICameraClient dummyCallbacks = new DummyCameraClient();
    155 
    156             String clientPackageName = getContext().getPackageName();
    157 
    158             ICamera cameraUser = mUtils.getCameraService()
    159                     .connect(dummyCallbacks, cameraId, clientPackageName,
    160                             ICameraService.USE_CALLING_UID,
    161                             ICameraService.USE_CALLING_PID);
    162             assertNotNull(String.format("Camera %s was null", cameraId), cameraUser);
    163 
    164             Log.v(TAG, String.format("Camera %s connected", cameraId));
    165 
    166             cameraUser.disconnect();
    167         }
    168     }
    169 
    170     @SmallTest
    171     public void testConnectLegacy() throws Exception {
    172         final int CAMERA_HAL_API_VERSION_1_0 = 0x100;
    173         for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) {
    174             ICamera cameraUser = null;
    175             ICameraClient dummyCallbacks = new DummyCameraClient();
    176 
    177             String clientPackageName = getContext().getPackageName();
    178 
    179             try {
    180                 cameraUser = mUtils.getCameraService()
    181                         .connectLegacy(dummyCallbacks, cameraId, CAMERA_HAL_API_VERSION_1_0,
    182                                 clientPackageName,
    183                                 ICameraService.USE_CALLING_UID);
    184                 assertNotNull(String.format("Camera %s was null", cameraId), cameraUser);
    185 
    186                 Log.v(TAG, String.format("Camera %s connected as HAL1 legacy device", cameraId));
    187             } catch (RuntimeException e) {
    188                 // Not all camera device support openLegacy.
    189                 Log.i(TAG, "Unable to open camera as HAL1 legacy camera device " + e);
    190             } finally {
    191                 if (cameraUser != null) {
    192                     cameraUser.disconnect();
    193                 }
    194             }
    195         }
    196     }
    197 
    198     static class DummyCameraDeviceCallbacks extends ICameraDeviceCallbacks.Stub {
    199 
    200         /*
    201          * (non-Javadoc)
    202          * @see
    203          * android.hardware.camera2.ICameraDeviceCallbacks#onCameraError(int,
    204          * android.hardware.camera2.CaptureResultExtras)
    205          */
    206         @Override
    207         public void onDeviceError(int errorCode, CaptureResultExtras resultExtras)
    208                 throws RemoteException {
    209             // TODO Auto-generated method stub
    210 
    211         }
    212 
    213         /*
    214          * (non-Javadoc)
    215          * @see
    216          * android.hardware.camera2.ICameraDeviceCallbacks#onCaptureStarted(
    217          * android.hardware.camera2.CaptureResultExtras, long)
    218          */
    219         @Override
    220         public void onCaptureStarted(CaptureResultExtras resultExtras, long timestamp)
    221                 throws RemoteException {
    222             // TODO Auto-generated method stub
    223 
    224         }
    225 
    226         /*
    227          * (non-Javadoc)
    228          * @see
    229          * android.hardware.camera2.ICameraDeviceCallbacks#onResultReceived(
    230          * android.hardware.camera2.impl.CameraMetadataNative,
    231          * android.hardware.camera2.CaptureResultExtras)
    232          */
    233         @Override
    234         public void onResultReceived(CameraMetadataNative result, CaptureResultExtras resultExtras,
    235                 PhysicalCaptureResultInfo physicalResults[]) throws RemoteException {
    236             // TODO Auto-generated method stub
    237 
    238         }
    239 
    240         /*
    241          * (non-Javadoc)
    242          * @see android.hardware.camera2.ICameraDeviceCallbacks#onCameraIdle()
    243          */
    244         @Override
    245         public void onDeviceIdle() throws RemoteException {
    246             // TODO Auto-generated method stub
    247 
    248         }
    249 
    250         /*
    251          * (non-Javadoc)
    252          * @see android.hardware.camera2.ICameraDeviceCallbacks#onPrepared()
    253          */
    254         @Override
    255         public void onPrepared(int streamId) throws RemoteException {
    256             // TODO Auto-generated method stub
    257 
    258         }
    259 
    260         /*
    261          * (non-Javadoc)
    262          * @see android.hardware.camera2.ICameraDeviceCallbacks#onRequestQueueEmpty()
    263          */
    264         @Override
    265         public void onRequestQueueEmpty() throws RemoteException {
    266             // TODO Auto-generated method stub
    267 
    268         }
    269 
    270         /*
    271          * (non-Javadoc)
    272          * @see android.hardware.camera2.ICameraDeviceCallbacks#onRepeatingRequestError()
    273          */
    274         @Override
    275         public void onRepeatingRequestError(long lastFrameNumber, int repeatingRequestId) {
    276             // TODO Auto-generated method stub
    277         }
    278     }
    279 
    280     @SmallTest
    281     public void testConnectDevice() throws Exception {
    282         for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) {
    283 
    284             ICameraDeviceCallbacks dummyCallbacks = new DummyCameraDeviceCallbacks();
    285 
    286             String clientPackageName = getContext().getPackageName();
    287 
    288             ICameraDeviceUser cameraUser =
    289                     mUtils.getCameraService().connectDevice(
    290                         dummyCallbacks, String.valueOf(cameraId),
    291                         clientPackageName,
    292                         ICameraService.USE_CALLING_UID);
    293             assertNotNull(String.format("Camera %s was null", cameraId), cameraUser);
    294 
    295             Log.v(TAG, String.format("Camera %s connected", cameraId));
    296 
    297             cameraUser.disconnect();
    298         }
    299     }
    300 
    301     static class DummyCameraServiceListener extends ICameraServiceListener.Stub {
    302         @Override
    303         public void onStatusChanged(int status, String cameraId)
    304                 throws RemoteException {
    305             Log.v(TAG, String.format("Camera %s has status changed to 0x%x", cameraId, status));
    306         }
    307         public void onTorchStatusChanged(int status, String cameraId)
    308                 throws RemoteException {
    309             Log.v(TAG, String.format("Camera %s has torch status changed to 0x%x",
    310                     cameraId, status));
    311         }
    312     }
    313 
    314     /**
    315      * <pre>
    316      * adb shell am instrument \
    317      *   -e class 'com.android.mediaframeworktest.integration.CameraBinderTest#testAddRemoveListeners' \
    318      *   -w com.android.mediaframeworktest/.MediaFrameworkIntegrationTestRunner
    319      * </pre>
    320      */
    321     @SmallTest
    322     public void testAddRemoveListeners() throws Exception {
    323         for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) {
    324 
    325             ICameraServiceListener listener = new DummyCameraServiceListener();
    326 
    327             try {
    328                 mUtils.getCameraService().removeListener(listener);
    329                 fail("Listener was removed before added");
    330             } catch (ServiceSpecificException e) {
    331                 assertEquals("Listener was removed before added",
    332                         e.errorCode, ICameraService.ERROR_ILLEGAL_ARGUMENT);
    333             }
    334 
    335             mUtils.getCameraService().addListener(listener);
    336 
    337             try {
    338                 mUtils.getCameraService().addListener(listener);
    339                 fail("Listener was wrongly added again");
    340             } catch (ServiceSpecificException e) {
    341                 assertEquals("Listener was wrongly added again",
    342                         e.errorCode, ICameraService.ERROR_ALREADY_EXISTS);
    343             }
    344 
    345             mUtils.getCameraService().removeListener(listener);
    346 
    347             try {
    348                 mUtils.getCameraService().removeListener(listener);
    349                 fail("Listener was wrongly removed twice");
    350             } catch (ServiceSpecificException e) {
    351                 assertEquals("Listener was wrongly removed twice",
    352                         e.errorCode, ICameraService.ERROR_ILLEGAL_ARGUMENT);
    353             }
    354         }
    355     }
    356 }
    357