Home | History | Annotate | Download | only in camera
      1 /*
      2 **
      3 ** Copyright 2008, 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_TAG "BpCameraService"
     19 #include <utils/Log.h>
     20 
     21 #include <stdint.h>
     22 #include <sys/types.h>
     23 
     24 #include <binder/Parcel.h>
     25 #include <binder/IPCThreadState.h>
     26 #include <binder/IServiceManager.h>
     27 
     28 #include <camera/ICameraService.h>
     29 #include <camera/ICameraServiceListener.h>
     30 #include <camera/IProCameraUser.h>
     31 #include <camera/IProCameraCallbacks.h>
     32 #include <camera/ICamera.h>
     33 #include <camera/ICameraClient.h>
     34 #include <camera/camera2/ICameraDeviceUser.h>
     35 #include <camera/camera2/ICameraDeviceCallbacks.h>
     36 #include <camera/CameraMetadata.h>
     37 
     38 namespace android {
     39 
     40 namespace {
     41 
     42 enum {
     43     EX_SECURITY = -1,
     44     EX_BAD_PARCELABLE = -2,
     45     EX_ILLEGAL_ARGUMENT = -3,
     46     EX_NULL_POINTER = -4,
     47     EX_ILLEGAL_STATE = -5,
     48     EX_HAS_REPLY_HEADER = -128,  // special; see below
     49 };
     50 
     51 static bool readExceptionCode(Parcel& reply) {
     52     int32_t exceptionCode = reply.readExceptionCode();
     53 
     54     if (exceptionCode != 0) {
     55         const char* errorMsg;
     56         switch(exceptionCode) {
     57             case EX_SECURITY:
     58                 errorMsg = "Security";
     59                 break;
     60             case EX_BAD_PARCELABLE:
     61                 errorMsg = "BadParcelable";
     62                 break;
     63             case EX_NULL_POINTER:
     64                 errorMsg = "NullPointer";
     65                 break;
     66             case EX_ILLEGAL_STATE:
     67                 errorMsg = "IllegalState";
     68                 break;
     69             // Binder should be handling this code inside Parcel::readException
     70             // but lets have a to-string here anyway just in case.
     71             case EX_HAS_REPLY_HEADER:
     72                 errorMsg = "HasReplyHeader";
     73                 break;
     74             default:
     75                 errorMsg = "Unknown";
     76         }
     77 
     78         ALOGE("Binder transmission error %s (%d)", errorMsg, exceptionCode);
     79         return true;
     80     }
     81 
     82     return false;
     83 }
     84 
     85 };
     86 
     87 class BpCameraService: public BpInterface<ICameraService>
     88 {
     89 public:
     90     BpCameraService(const sp<IBinder>& impl)
     91         : BpInterface<ICameraService>(impl)
     92     {
     93     }
     94 
     95     // get number of cameras available
     96     virtual int32_t getNumberOfCameras()
     97     {
     98         Parcel data, reply;
     99         data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
    100         remote()->transact(BnCameraService::GET_NUMBER_OF_CAMERAS, data, &reply);
    101 
    102         if (readExceptionCode(reply)) return 0;
    103         return reply.readInt32();
    104     }
    105 
    106     // get information about a camera
    107     virtual status_t getCameraInfo(int cameraId,
    108                                    struct CameraInfo* cameraInfo) {
    109         Parcel data, reply;
    110         data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
    111         data.writeInt32(cameraId);
    112         remote()->transact(BnCameraService::GET_CAMERA_INFO, data, &reply);
    113 
    114         if (readExceptionCode(reply)) return -EPROTO;
    115         status_t result = reply.readInt32();
    116         if (reply.readInt32() != 0) {
    117             cameraInfo->facing = reply.readInt32();
    118             cameraInfo->orientation = reply.readInt32();
    119         }
    120         return result;
    121     }
    122 
    123     // get camera characteristics (static metadata)
    124     virtual status_t getCameraCharacteristics(int cameraId,
    125                                               CameraMetadata* cameraInfo) {
    126         Parcel data, reply;
    127         data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
    128         data.writeInt32(cameraId);
    129         remote()->transact(BnCameraService::GET_CAMERA_CHARACTERISTICS, data, &reply);
    130 
    131         if (readExceptionCode(reply)) return -EPROTO;
    132         status_t result = reply.readInt32();
    133 
    134         CameraMetadata out;
    135         if (reply.readInt32() != 0) {
    136             out.readFromParcel(&reply);
    137         }
    138 
    139         if (cameraInfo != NULL) {
    140             cameraInfo->swap(out);
    141         }
    142 
    143         return result;
    144     }
    145 
    146     // connect to camera service (android.hardware.Camera)
    147     virtual status_t connect(const sp<ICameraClient>& cameraClient, int cameraId,
    148                              const String16 &clientPackageName, int clientUid,
    149                              /*out*/
    150                              sp<ICamera>& device)
    151     {
    152         Parcel data, reply;
    153         data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
    154         data.writeStrongBinder(cameraClient->asBinder());
    155         data.writeInt32(cameraId);
    156         data.writeString16(clientPackageName);
    157         data.writeInt32(clientUid);
    158         remote()->transact(BnCameraService::CONNECT, data, &reply);
    159 
    160         if (readExceptionCode(reply)) return -EPROTO;
    161         status_t status = reply.readInt32();
    162         if (reply.readInt32() != 0) {
    163             device = interface_cast<ICamera>(reply.readStrongBinder());
    164         }
    165         return status;
    166     }
    167 
    168     // connect to camera service (pro client)
    169     virtual status_t connectPro(const sp<IProCameraCallbacks>& cameraCb, int cameraId,
    170                                 const String16 &clientPackageName, int clientUid,
    171                                 /*out*/
    172                                 sp<IProCameraUser>& device)
    173     {
    174         Parcel data, reply;
    175         data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
    176         data.writeStrongBinder(cameraCb->asBinder());
    177         data.writeInt32(cameraId);
    178         data.writeString16(clientPackageName);
    179         data.writeInt32(clientUid);
    180         remote()->transact(BnCameraService::CONNECT_PRO, data, &reply);
    181 
    182         if (readExceptionCode(reply)) return -EPROTO;
    183         status_t status = reply.readInt32();
    184         if (reply.readInt32() != 0) {
    185             device = interface_cast<IProCameraUser>(reply.readStrongBinder());
    186         }
    187         return status;
    188     }
    189 
    190     // connect to camera service (android.hardware.camera2.CameraDevice)
    191     virtual status_t connectDevice(
    192             const sp<ICameraDeviceCallbacks>& cameraCb,
    193             int cameraId,
    194             const String16& clientPackageName,
    195             int clientUid,
    196             /*out*/
    197             sp<ICameraDeviceUser>& device)
    198     {
    199         Parcel data, reply;
    200         data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
    201         data.writeStrongBinder(cameraCb->asBinder());
    202         data.writeInt32(cameraId);
    203         data.writeString16(clientPackageName);
    204         data.writeInt32(clientUid);
    205         remote()->transact(BnCameraService::CONNECT_DEVICE, data, &reply);
    206 
    207         if (readExceptionCode(reply)) return -EPROTO;
    208         status_t status = reply.readInt32();
    209         if (reply.readInt32() != 0) {
    210             device = interface_cast<ICameraDeviceUser>(reply.readStrongBinder());
    211         }
    212         return status;
    213     }
    214 
    215     virtual status_t addListener(const sp<ICameraServiceListener>& listener)
    216     {
    217         Parcel data, reply;
    218         data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
    219         data.writeStrongBinder(listener->asBinder());
    220         remote()->transact(BnCameraService::ADD_LISTENER, data, &reply);
    221 
    222         if (readExceptionCode(reply)) return -EPROTO;
    223         return reply.readInt32();
    224     }
    225 
    226     virtual status_t removeListener(const sp<ICameraServiceListener>& listener)
    227     {
    228         Parcel data, reply;
    229         data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
    230         data.writeStrongBinder(listener->asBinder());
    231         remote()->transact(BnCameraService::REMOVE_LISTENER, data, &reply);
    232 
    233         if (readExceptionCode(reply)) return -EPROTO;
    234         return reply.readInt32();
    235     }
    236 };
    237 
    238 IMPLEMENT_META_INTERFACE(CameraService, "android.hardware.ICameraService");
    239 
    240 // ----------------------------------------------------------------------
    241 
    242 status_t BnCameraService::onTransact(
    243     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
    244 {
    245     switch(code) {
    246         case GET_NUMBER_OF_CAMERAS: {
    247             CHECK_INTERFACE(ICameraService, data, reply);
    248             reply->writeNoException();
    249             reply->writeInt32(getNumberOfCameras());
    250             return NO_ERROR;
    251         } break;
    252         case GET_CAMERA_INFO: {
    253             CHECK_INTERFACE(ICameraService, data, reply);
    254             CameraInfo cameraInfo = CameraInfo();
    255             memset(&cameraInfo, 0, sizeof(cameraInfo));
    256             status_t result = getCameraInfo(data.readInt32(), &cameraInfo);
    257             reply->writeNoException();
    258             reply->writeInt32(result);
    259 
    260             // Fake a parcelable object here
    261             reply->writeInt32(1); // means the parcelable is included
    262             reply->writeInt32(cameraInfo.facing);
    263             reply->writeInt32(cameraInfo.orientation);
    264             return NO_ERROR;
    265         } break;
    266         case GET_CAMERA_CHARACTERISTICS: {
    267             CHECK_INTERFACE(ICameraService, data, reply);
    268             CameraMetadata info;
    269             status_t result = getCameraCharacteristics(data.readInt32(), &info);
    270             reply->writeNoException();
    271             reply->writeInt32(result);
    272 
    273             // out-variables are after exception and return value
    274             reply->writeInt32(1); // means the parcelable is included
    275             info.writeToParcel(reply);
    276             return NO_ERROR;
    277         } break;
    278         case CONNECT: {
    279             CHECK_INTERFACE(ICameraService, data, reply);
    280             sp<ICameraClient> cameraClient =
    281                     interface_cast<ICameraClient>(data.readStrongBinder());
    282             int32_t cameraId = data.readInt32();
    283             const String16 clientName = data.readString16();
    284             int32_t clientUid = data.readInt32();
    285             sp<ICamera> camera;
    286             status_t status = connect(cameraClient, cameraId,
    287                     clientName, clientUid, /*out*/ camera);
    288             reply->writeNoException();
    289             reply->writeInt32(status);
    290             if (camera != NULL) {
    291                 reply->writeInt32(1);
    292                 reply->writeStrongBinder(camera->asBinder());
    293             } else {
    294                 reply->writeInt32(0);
    295             }
    296             return NO_ERROR;
    297         } break;
    298         case CONNECT_PRO: {
    299             CHECK_INTERFACE(ICameraService, data, reply);
    300             sp<IProCameraCallbacks> cameraClient =
    301                 interface_cast<IProCameraCallbacks>(data.readStrongBinder());
    302             int32_t cameraId = data.readInt32();
    303             const String16 clientName = data.readString16();
    304             int32_t clientUid = data.readInt32();
    305             sp<IProCameraUser> camera;
    306             status_t status = connectPro(cameraClient, cameraId,
    307                     clientName, clientUid, /*out*/ camera);
    308             reply->writeNoException();
    309             reply->writeInt32(status);
    310             if (camera != NULL) {
    311                 reply->writeInt32(1);
    312                 reply->writeStrongBinder(camera->asBinder());
    313             } else {
    314                 reply->writeInt32(0);
    315             }
    316             return NO_ERROR;
    317         } break;
    318         case CONNECT_DEVICE: {
    319             CHECK_INTERFACE(ICameraService, data, reply);
    320             sp<ICameraDeviceCallbacks> cameraClient =
    321                 interface_cast<ICameraDeviceCallbacks>(data.readStrongBinder());
    322             int32_t cameraId = data.readInt32();
    323             const String16 clientName = data.readString16();
    324             int32_t clientUid = data.readInt32();
    325             sp<ICameraDeviceUser> camera;
    326             status_t status = connectDevice(cameraClient, cameraId,
    327                     clientName, clientUid, /*out*/ camera);
    328             reply->writeNoException();
    329             reply->writeInt32(status);
    330             if (camera != NULL) {
    331                 reply->writeInt32(1);
    332                 reply->writeStrongBinder(camera->asBinder());
    333             } else {
    334                 reply->writeInt32(0);
    335             }
    336             return NO_ERROR;
    337         } break;
    338         case ADD_LISTENER: {
    339             CHECK_INTERFACE(ICameraService, data, reply);
    340             sp<ICameraServiceListener> listener =
    341                 interface_cast<ICameraServiceListener>(data.readStrongBinder());
    342             reply->writeNoException();
    343             reply->writeInt32(addListener(listener));
    344             return NO_ERROR;
    345         } break;
    346         case REMOVE_LISTENER: {
    347             CHECK_INTERFACE(ICameraService, data, reply);
    348             sp<ICameraServiceListener> listener =
    349                 interface_cast<ICameraServiceListener>(data.readStrongBinder());
    350             reply->writeNoException();
    351             reply->writeInt32(removeListener(listener));
    352             return NO_ERROR;
    353         } break;
    354         default:
    355             return BBinder::onTransact(code, data, reply, flags);
    356     }
    357 }
    358 
    359 // ----------------------------------------------------------------------------
    360 
    361 }; // namespace android
    362