Home | History | Annotate | Download | only in camera
      1 /*
      2 **
      3 ** Copyright 2013, The Android Open Source Project
      4 **
      5 ** Licensed under the Apache License, Version 2.0 (the "License");
      6 ** you may not use this file except in compliance with the License.
      7 ** You may obtain a copy of the License at
      8 **
      9 **     http://www.apache.org/licenses/LICENSE-2.0
     10 **
     11 ** Unless required by applicable law or agreed to in writing, software
     12 ** distributed under the License is distributed on an "AS IS" BASIS,
     13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14 ** See the License for the specific language governing permissions and
     15 ** limitations under the License.
     16 */
     17 
     18 // #define LOG_NDEBUG 0
     19 #define LOG_TAG "IProCameraUser"
     20 #include <utils/Log.h>
     21 #include <stdint.h>
     22 #include <sys/types.h>
     23 #include <binder/Parcel.h>
     24 #include <camera/IProCameraUser.h>
     25 #include <gui/IGraphicBufferProducer.h>
     26 #include <gui/Surface.h>
     27 #include "camera/CameraMetadata.h"
     28 
     29 namespace android {
     30 
     31 enum {
     32     DISCONNECT = IBinder::FIRST_CALL_TRANSACTION,
     33     CONNECT,
     34     EXCLUSIVE_TRY_LOCK,
     35     EXCLUSIVE_LOCK,
     36     EXCLUSIVE_UNLOCK,
     37     HAS_EXCLUSIVE_LOCK,
     38     SUBMIT_REQUEST,
     39     CANCEL_REQUEST,
     40     DELETE_STREAM,
     41     CREATE_STREAM,
     42     CREATE_DEFAULT_REQUEST,
     43     GET_CAMERA_INFO,
     44 };
     45 
     46 class BpProCameraUser: public BpInterface<IProCameraUser>
     47 {
     48 public:
     49     BpProCameraUser(const sp<IBinder>& impl)
     50         : BpInterface<IProCameraUser>(impl)
     51     {
     52     }
     53 
     54     // disconnect from camera service
     55     void disconnect()
     56     {
     57         ALOGV("disconnect");
     58         Parcel data, reply;
     59         data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
     60         remote()->transact(DISCONNECT, data, &reply);
     61         reply.readExceptionCode();
     62     }
     63 
     64     virtual status_t connect(const sp<IProCameraCallbacks>& cameraClient)
     65     {
     66         Parcel data, reply;
     67         data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
     68         data.writeStrongBinder(cameraClient->asBinder());
     69         remote()->transact(CONNECT, data, &reply);
     70         return reply.readInt32();
     71     }
     72 
     73     /* Shared ProCameraUser */
     74 
     75     virtual status_t exclusiveTryLock()
     76     {
     77         Parcel data, reply;
     78         data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
     79         remote()->transact(EXCLUSIVE_TRY_LOCK, data, &reply);
     80         return reply.readInt32();
     81     }
     82     virtual status_t exclusiveLock()
     83     {
     84         Parcel data, reply;
     85         data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
     86         remote()->transact(EXCLUSIVE_LOCK, data, &reply);
     87         return reply.readInt32();
     88     }
     89 
     90     virtual status_t exclusiveUnlock()
     91     {
     92         Parcel data, reply;
     93         data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
     94         remote()->transact(EXCLUSIVE_UNLOCK, data, &reply);
     95         return reply.readInt32();
     96     }
     97 
     98     virtual bool hasExclusiveLock()
     99     {
    100         Parcel data, reply;
    101         data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
    102         remote()->transact(HAS_EXCLUSIVE_LOCK, data, &reply);
    103         return !!reply.readInt32();
    104     }
    105 
    106     virtual int submitRequest(camera_metadata_t* metadata, bool streaming)
    107     {
    108 
    109         Parcel data, reply;
    110         data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
    111 
    112         // arg0+arg1
    113         CameraMetadata::writeToParcel(data, metadata);
    114 
    115         // arg2 = streaming (bool)
    116         data.writeInt32(streaming);
    117 
    118         remote()->transact(SUBMIT_REQUEST, data, &reply);
    119         return reply.readInt32();
    120     }
    121 
    122     virtual status_t cancelRequest(int requestId)
    123     {
    124         Parcel data, reply;
    125         data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
    126         data.writeInt32(requestId);
    127 
    128         remote()->transact(CANCEL_REQUEST, data, &reply);
    129         return reply.readInt32();
    130     }
    131 
    132     virtual status_t deleteStream(int streamId)
    133     {
    134         Parcel data, reply;
    135         data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
    136         data.writeInt32(streamId);
    137 
    138         remote()->transact(DELETE_STREAM, data, &reply);
    139         return reply.readInt32();
    140     }
    141 
    142     virtual status_t createStream(int width, int height, int format,
    143                           const sp<IGraphicBufferProducer>& bufferProducer,
    144                           /*out*/
    145                           int* streamId)
    146     {
    147         Parcel data, reply;
    148         data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
    149         data.writeInt32(width);
    150         data.writeInt32(height);
    151         data.writeInt32(format);
    152 
    153         sp<IBinder> b(bufferProducer->asBinder());
    154         data.writeStrongBinder(b);
    155 
    156         remote()->transact(CREATE_STREAM, data, &reply);
    157 
    158         int sId = reply.readInt32();
    159         if (streamId) {
    160             *streamId = sId;
    161         }
    162         return reply.readInt32();
    163     }
    164 
    165     // Create a request object from a template.
    166     virtual status_t createDefaultRequest(int templateId,
    167                                  /*out*/
    168                                   camera_metadata** request)
    169     {
    170         Parcel data, reply;
    171         data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
    172         data.writeInt32(templateId);
    173         remote()->transact(CREATE_DEFAULT_REQUEST, data, &reply);
    174         CameraMetadata::readFromParcel(reply, /*out*/request);
    175         return reply.readInt32();
    176     }
    177 
    178 
    179     virtual status_t getCameraInfo(int cameraId, camera_metadata** info)
    180     {
    181         Parcel data, reply;
    182         data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor());
    183         data.writeInt32(cameraId);
    184         remote()->transact(GET_CAMERA_INFO, data, &reply);
    185         CameraMetadata::readFromParcel(reply, /*out*/info);
    186         return reply.readInt32();
    187     }
    188 
    189 
    190 private:
    191 
    192 
    193 };
    194 
    195 IMPLEMENT_META_INTERFACE(ProCameraUser, "android.hardware.IProCameraUser");
    196 
    197 // ----------------------------------------------------------------------
    198 
    199 status_t BnProCameraUser::onTransact(
    200     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
    201 {
    202     switch(code) {
    203         case DISCONNECT: {
    204             ALOGV("DISCONNECT");
    205             CHECK_INTERFACE(IProCameraUser, data, reply);
    206             disconnect();
    207             reply->writeNoException();
    208             return NO_ERROR;
    209         } break;
    210         case CONNECT: {
    211             CHECK_INTERFACE(IProCameraUser, data, reply);
    212             sp<IProCameraCallbacks> cameraClient =
    213                    interface_cast<IProCameraCallbacks>(data.readStrongBinder());
    214             reply->writeInt32(connect(cameraClient));
    215             return NO_ERROR;
    216         } break;
    217 
    218         /* Shared ProCameraUser */
    219         case EXCLUSIVE_TRY_LOCK: {
    220             CHECK_INTERFACE(IProCameraUser, data, reply);
    221             reply->writeInt32(exclusiveTryLock());
    222             return NO_ERROR;
    223         } break;
    224         case EXCLUSIVE_LOCK: {
    225             CHECK_INTERFACE(IProCameraUser, data, reply);
    226             reply->writeInt32(exclusiveLock());
    227             return NO_ERROR;
    228         } break;
    229         case EXCLUSIVE_UNLOCK: {
    230             CHECK_INTERFACE(IProCameraUser, data, reply);
    231             reply->writeInt32(exclusiveUnlock());
    232             return NO_ERROR;
    233         } break;
    234         case HAS_EXCLUSIVE_LOCK: {
    235             CHECK_INTERFACE(IProCameraUser, data, reply);
    236             reply->writeInt32(hasExclusiveLock());
    237             return NO_ERROR;
    238         } break;
    239         case SUBMIT_REQUEST: {
    240             CHECK_INTERFACE(IProCameraUser, data, reply);
    241             camera_metadata_t* metadata;
    242             CameraMetadata::readFromParcel(data, /*out*/&metadata);
    243 
    244             // arg2 = streaming (bool)
    245             bool streaming = data.readInt32();
    246 
    247             // return code: requestId (int32)
    248             reply->writeInt32(submitRequest(metadata, streaming));
    249 
    250             return NO_ERROR;
    251         } break;
    252         case CANCEL_REQUEST: {
    253             CHECK_INTERFACE(IProCameraUser, data, reply);
    254             int requestId = data.readInt32();
    255             reply->writeInt32(cancelRequest(requestId));
    256             return NO_ERROR;
    257         } break;
    258         case DELETE_STREAM: {
    259             CHECK_INTERFACE(IProCameraUser, data, reply);
    260             int streamId = data.readInt32();
    261             reply->writeInt32(deleteStream(streamId));
    262             return NO_ERROR;
    263         } break;
    264         case CREATE_STREAM: {
    265             CHECK_INTERFACE(IProCameraUser, data, reply);
    266             int width, height, format;
    267 
    268             width = data.readInt32();
    269             height = data.readInt32();
    270             format = data.readInt32();
    271 
    272             sp<IGraphicBufferProducer> bp =
    273                interface_cast<IGraphicBufferProducer>(data.readStrongBinder());
    274 
    275             int streamId = -1;
    276             status_t ret;
    277             ret = createStream(width, height, format, bp, &streamId);
    278 
    279             reply->writeInt32(streamId);
    280             reply->writeInt32(ret);
    281 
    282             return NO_ERROR;
    283         } break;
    284 
    285         case CREATE_DEFAULT_REQUEST: {
    286             CHECK_INTERFACE(IProCameraUser, data, reply);
    287 
    288             int templateId = data.readInt32();
    289 
    290             camera_metadata_t* request = NULL;
    291             status_t ret;
    292             ret = createDefaultRequest(templateId, &request);
    293 
    294             CameraMetadata::writeToParcel(*reply, request);
    295             reply->writeInt32(ret);
    296 
    297             free_camera_metadata(request);
    298 
    299             return NO_ERROR;
    300         } break;
    301         case GET_CAMERA_INFO: {
    302             CHECK_INTERFACE(IProCameraUser, data, reply);
    303 
    304             int cameraId = data.readInt32();
    305 
    306             camera_metadata_t* info = NULL;
    307             status_t ret;
    308             ret = getCameraInfo(cameraId, &info);
    309 
    310             CameraMetadata::writeToParcel(*reply, info);
    311             reply->writeInt32(ret);
    312 
    313             free_camera_metadata(info);
    314 
    315             return NO_ERROR;
    316         } break;
    317         default:
    318             return BBinder::onTransact(code, data, reply, flags);
    319     }
    320 }
    321 
    322 // ----------------------------------------------------------------------------
    323 
    324 }; // namespace android
    325