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