| Mathias Agopian | 3cf6135 | 2010-02-09 17:46:37 -0800 | [diff] [blame] | 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 |  | 
| Igor Murashkin | bef3f23 | 2013-05-30 17:47:38 -0700 | [diff] [blame] | 18 | #define LOG_TAG "BpCameraService" | 
 | 19 | #include <utils/Log.h> | 
 | 20 |  | 
| Mathias Agopian | 3cf6135 | 2010-02-09 17:46:37 -0800 | [diff] [blame] | 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> | 
| Igor Murashkin | bfc9915 | 2013-02-27 12:55:20 -0800 | [diff] [blame] | 29 | #include <camera/ICameraServiceListener.h> | 
| Igor Murashkin | c073ba5 | 2013-02-26 14:32:34 -0800 | [diff] [blame] | 30 | #include <camera/IProCameraUser.h> | 
 | 31 | #include <camera/IProCameraCallbacks.h> | 
 | 32 | #include <camera/ICamera.h> | 
 | 33 | #include <camera/ICameraClient.h> | 
| Eino-Ville Talvala | 7b82efe | 2013-07-25 17:12:35 -0700 | [diff] [blame^] | 34 | #include <camera/camera2/ICameraDeviceUser.h> | 
 | 35 | #include <camera/camera2/ICameraDeviceCallbacks.h> | 
| Mathias Agopian | 3cf6135 | 2010-02-09 17:46:37 -0800 | [diff] [blame] | 36 |  | 
 | 37 | namespace android { | 
 | 38 |  | 
| Igor Murashkin | bef3f23 | 2013-05-30 17:47:38 -0700 | [diff] [blame] | 39 | namespace { | 
 | 40 |  | 
 | 41 | enum { | 
 | 42 |     EX_SECURITY = -1, | 
 | 43 |     EX_BAD_PARCELABLE = -2, | 
 | 44 |     EX_ILLEGAL_ARGUMENT = -3, | 
 | 45 |     EX_NULL_POINTER = -4, | 
 | 46 |     EX_ILLEGAL_STATE = -5, | 
 | 47 |     EX_HAS_REPLY_HEADER = -128,  // special; see below | 
 | 48 | }; | 
 | 49 |  | 
 | 50 | static bool readExceptionCode(Parcel& reply) { | 
 | 51 |     int32_t exceptionCode = reply.readExceptionCode(); | 
 | 52 |  | 
 | 53 |     if (exceptionCode != 0) { | 
 | 54 |         const char* errorMsg; | 
 | 55 |         switch(exceptionCode) { | 
 | 56 |             case EX_SECURITY: | 
 | 57 |                 errorMsg = "Security"; | 
 | 58 |                 break; | 
 | 59 |             case EX_BAD_PARCELABLE: | 
 | 60 |                 errorMsg = "BadParcelable"; | 
 | 61 |                 break; | 
 | 62 |             case EX_NULL_POINTER: | 
 | 63 |                 errorMsg = "NullPointer"; | 
 | 64 |                 break; | 
 | 65 |             case EX_ILLEGAL_STATE: | 
 | 66 |                 errorMsg = "IllegalState"; | 
 | 67 |                 break; | 
 | 68 |             // Binder should be handling this code inside Parcel::readException | 
 | 69 |             // but lets have a to-string here anyway just in case. | 
 | 70 |             case EX_HAS_REPLY_HEADER: | 
 | 71 |                 errorMsg = "HasReplyHeader"; | 
 | 72 |                 break; | 
 | 73 |             default: | 
 | 74 |                 errorMsg = "Unknown"; | 
 | 75 |         } | 
 | 76 |  | 
 | 77 |         ALOGE("Binder transmission error %s (%d)", errorMsg, exceptionCode); | 
 | 78 |         return true; | 
 | 79 |     } | 
 | 80 |  | 
 | 81 |     return false; | 
 | 82 | } | 
 | 83 |  | 
 | 84 | }; | 
 | 85 |  | 
| Mathias Agopian | 3cf6135 | 2010-02-09 17:46:37 -0800 | [diff] [blame] | 86 | class BpCameraService: public BpInterface<ICameraService> | 
 | 87 | { | 
 | 88 | public: | 
 | 89 |     BpCameraService(const sp<IBinder>& impl) | 
 | 90 |         : BpInterface<ICameraService>(impl) | 
 | 91 |     { | 
 | 92 |     } | 
 | 93 |  | 
| Chih-Chung Chang | 35a055b | 2010-05-06 16:36:58 +0800 | [diff] [blame] | 94 |     // get number of cameras available | 
 | 95 |     virtual int32_t getNumberOfCameras() | 
 | 96 |     { | 
 | 97 |         Parcel data, reply; | 
 | 98 |         data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); | 
 | 99 |         remote()->transact(BnCameraService::GET_NUMBER_OF_CAMERAS, data, &reply); | 
| Igor Murashkin | bef3f23 | 2013-05-30 17:47:38 -0700 | [diff] [blame] | 100 |  | 
 | 101 |         if (readExceptionCode(reply)) return 0; | 
| Chih-Chung Chang | 35a055b | 2010-05-06 16:36:58 +0800 | [diff] [blame] | 102 |         return reply.readInt32(); | 
 | 103 |     } | 
 | 104 |  | 
| Chih-Chung Chang | ddbdb35 | 2010-06-10 13:32:16 +0800 | [diff] [blame] | 105 |     // get information about a camera | 
 | 106 |     virtual status_t getCameraInfo(int cameraId, | 
 | 107 |                                    struct CameraInfo* cameraInfo) { | 
 | 108 |         Parcel data, reply; | 
 | 109 |         data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); | 
 | 110 |         data.writeInt32(cameraId); | 
 | 111 |         remote()->transact(BnCameraService::GET_CAMERA_INFO, data, &reply); | 
| Igor Murashkin | bef3f23 | 2013-05-30 17:47:38 -0700 | [diff] [blame] | 112 |  | 
 | 113 |         if (readExceptionCode(reply)) return -EPROTO; | 
 | 114 |         status_t result = reply.readInt32(); | 
 | 115 |         if (reply.readInt32() != 0) { | 
 | 116 |             cameraInfo->facing = reply.readInt32(); | 
 | 117 |             cameraInfo->orientation = reply.readInt32(); | 
 | 118 |         } | 
 | 119 |         return result; | 
| Chih-Chung Chang | ddbdb35 | 2010-06-10 13:32:16 +0800 | [diff] [blame] | 120 |     } | 
 | 121 |  | 
| Igor Murashkin | e7ee763 | 2013-06-11 18:10:18 -0700 | [diff] [blame] | 122 |     // connect to camera service (android.hardware.Camera) | 
| Eino-Ville Talvala | ceb388d | 2013-02-19 10:40:14 -0800 | [diff] [blame] | 123 |     virtual sp<ICamera> connect(const sp<ICameraClient>& cameraClient, int cameraId, | 
 | 124 |                                 const String16 &clientPackageName, int clientUid) | 
| Mathias Agopian | 3cf6135 | 2010-02-09 17:46:37 -0800 | [diff] [blame] | 125 |     { | 
 | 126 |         Parcel data, reply; | 
 | 127 |         data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); | 
 | 128 |         data.writeStrongBinder(cameraClient->asBinder()); | 
| Chih-Chung Chang | 35a055b | 2010-05-06 16:36:58 +0800 | [diff] [blame] | 129 |         data.writeInt32(cameraId); | 
| Eino-Ville Talvala | ceb388d | 2013-02-19 10:40:14 -0800 | [diff] [blame] | 130 |         data.writeString16(clientPackageName); | 
 | 131 |         data.writeInt32(clientUid); | 
| Mathias Agopian | 3cf6135 | 2010-02-09 17:46:37 -0800 | [diff] [blame] | 132 |         remote()->transact(BnCameraService::CONNECT, data, &reply); | 
| Igor Murashkin | bef3f23 | 2013-05-30 17:47:38 -0700 | [diff] [blame] | 133 |  | 
 | 134 |         if (readExceptionCode(reply)) return NULL; | 
| Mathias Agopian | 3cf6135 | 2010-02-09 17:46:37 -0800 | [diff] [blame] | 135 |         return interface_cast<ICamera>(reply.readStrongBinder()); | 
 | 136 |     } | 
| Igor Murashkin | 634a515 | 2013-02-20 17:15:11 -0800 | [diff] [blame] | 137 |  | 
 | 138 |     // connect to camera service (pro client) | 
| Igor Murashkin | c073ba5 | 2013-02-26 14:32:34 -0800 | [diff] [blame] | 139 |     virtual sp<IProCameraUser> connect(const sp<IProCameraCallbacks>& cameraCb, int cameraId, | 
 | 140 |                                        const String16 &clientPackageName, int clientUid) | 
| Igor Murashkin | 634a515 | 2013-02-20 17:15:11 -0800 | [diff] [blame] | 141 |     { | 
 | 142 |         Parcel data, reply; | 
 | 143 |         data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); | 
 | 144 |         data.writeStrongBinder(cameraCb->asBinder()); | 
 | 145 |         data.writeInt32(cameraId); | 
| Igor Murashkin | c073ba5 | 2013-02-26 14:32:34 -0800 | [diff] [blame] | 146 |         data.writeString16(clientPackageName); | 
 | 147 |         data.writeInt32(clientUid); | 
| Igor Murashkin | 634a515 | 2013-02-20 17:15:11 -0800 | [diff] [blame] | 148 |         remote()->transact(BnCameraService::CONNECT_PRO, data, &reply); | 
| Igor Murashkin | bef3f23 | 2013-05-30 17:47:38 -0700 | [diff] [blame] | 149 |  | 
 | 150 |         if (readExceptionCode(reply)) return NULL; | 
| Igor Murashkin | 634a515 | 2013-02-20 17:15:11 -0800 | [diff] [blame] | 151 |         return interface_cast<IProCameraUser>(reply.readStrongBinder()); | 
 | 152 |     } | 
| Igor Murashkin | bfc9915 | 2013-02-27 12:55:20 -0800 | [diff] [blame] | 153 |  | 
| Eino-Ville Talvala | 7b82efe | 2013-07-25 17:12:35 -0700 | [diff] [blame^] | 154 |     // connect to camera service (android.hardware.camera2.CameraDevice) | 
| Igor Murashkin | e7ee763 | 2013-06-11 18:10:18 -0700 | [diff] [blame] | 155 |     virtual sp<ICameraDeviceUser> connect( | 
 | 156 |             const sp<ICameraDeviceCallbacks>& cameraCb, | 
 | 157 |             int cameraId, | 
 | 158 |             const String16& clientPackageName, | 
 | 159 |             int clientUid) | 
 | 160 |     { | 
 | 161 |         Parcel data, reply; | 
 | 162 |         data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); | 
 | 163 |         data.writeStrongBinder(cameraCb->asBinder()); | 
 | 164 |         data.writeInt32(cameraId); | 
 | 165 |         data.writeString16(clientPackageName); | 
 | 166 |         data.writeInt32(clientUid); | 
 | 167 |         remote()->transact(BnCameraService::CONNECT_DEVICE, data, &reply); | 
 | 168 |  | 
 | 169 |         if (readExceptionCode(reply)) return NULL; | 
 | 170 |         return interface_cast<ICameraDeviceUser>(reply.readStrongBinder()); | 
 | 171 |     } | 
 | 172 |  | 
| Igor Murashkin | bfc9915 | 2013-02-27 12:55:20 -0800 | [diff] [blame] | 173 |     virtual status_t addListener(const sp<ICameraServiceListener>& listener) | 
 | 174 |     { | 
 | 175 |         Parcel data, reply; | 
 | 176 |         data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); | 
 | 177 |         data.writeStrongBinder(listener->asBinder()); | 
 | 178 |         remote()->transact(BnCameraService::ADD_LISTENER, data, &reply); | 
| Igor Murashkin | bef3f23 | 2013-05-30 17:47:38 -0700 | [diff] [blame] | 179 |  | 
 | 180 |         if (readExceptionCode(reply)) return -EPROTO; | 
| Igor Murashkin | bfc9915 | 2013-02-27 12:55:20 -0800 | [diff] [blame] | 181 |         return reply.readInt32(); | 
 | 182 |     } | 
 | 183 |  | 
 | 184 |     virtual status_t removeListener(const sp<ICameraServiceListener>& listener) | 
 | 185 |     { | 
 | 186 |         Parcel data, reply; | 
 | 187 |         data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); | 
 | 188 |         data.writeStrongBinder(listener->asBinder()); | 
 | 189 |         remote()->transact(BnCameraService::REMOVE_LISTENER, data, &reply); | 
| Igor Murashkin | bef3f23 | 2013-05-30 17:47:38 -0700 | [diff] [blame] | 190 |  | 
 | 191 |         if (readExceptionCode(reply)) return -EPROTO; | 
| Igor Murashkin | bfc9915 | 2013-02-27 12:55:20 -0800 | [diff] [blame] | 192 |         return reply.readInt32(); | 
 | 193 |     } | 
| Mathias Agopian | 3cf6135 | 2010-02-09 17:46:37 -0800 | [diff] [blame] | 194 | }; | 
 | 195 |  | 
 | 196 | IMPLEMENT_META_INTERFACE(CameraService, "android.hardware.ICameraService"); | 
 | 197 |  | 
 | 198 | // ---------------------------------------------------------------------- | 
 | 199 |  | 
 | 200 | status_t BnCameraService::onTransact( | 
 | 201 |     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) | 
 | 202 | { | 
 | 203 |     switch(code) { | 
| Chih-Chung Chang | 35a055b | 2010-05-06 16:36:58 +0800 | [diff] [blame] | 204 |         case GET_NUMBER_OF_CAMERAS: { | 
 | 205 |             CHECK_INTERFACE(ICameraService, data, reply); | 
| Igor Murashkin | bef3f23 | 2013-05-30 17:47:38 -0700 | [diff] [blame] | 206 |             reply->writeNoException(); | 
| Chih-Chung Chang | 35a055b | 2010-05-06 16:36:58 +0800 | [diff] [blame] | 207 |             reply->writeInt32(getNumberOfCameras()); | 
 | 208 |             return NO_ERROR; | 
 | 209 |         } break; | 
| Chih-Chung Chang | ddbdb35 | 2010-06-10 13:32:16 +0800 | [diff] [blame] | 210 |         case GET_CAMERA_INFO: { | 
 | 211 |             CHECK_INTERFACE(ICameraService, data, reply); | 
| Igor Murashkin | bef3f23 | 2013-05-30 17:47:38 -0700 | [diff] [blame] | 212 |             CameraInfo cameraInfo = CameraInfo(); | 
| Chih-Chung Chang | ddbdb35 | 2010-06-10 13:32:16 +0800 | [diff] [blame] | 213 |             memset(&cameraInfo, 0, sizeof(cameraInfo)); | 
 | 214 |             status_t result = getCameraInfo(data.readInt32(), &cameraInfo); | 
| Igor Murashkin | bef3f23 | 2013-05-30 17:47:38 -0700 | [diff] [blame] | 215 |             reply->writeNoException(); | 
 | 216 |             reply->writeInt32(result); | 
 | 217 |  | 
 | 218 |             // Fake a parcelable object here | 
 | 219 |             reply->writeInt32(1); // means the parcelable is included | 
| Chih-Chung Chang | ddbdb35 | 2010-06-10 13:32:16 +0800 | [diff] [blame] | 220 |             reply->writeInt32(cameraInfo.facing); | 
 | 221 |             reply->writeInt32(cameraInfo.orientation); | 
| Chih-Chung Chang | ddbdb35 | 2010-06-10 13:32:16 +0800 | [diff] [blame] | 222 |             return NO_ERROR; | 
 | 223 |         } break; | 
| Mathias Agopian | 3cf6135 | 2010-02-09 17:46:37 -0800 | [diff] [blame] | 224 |         case CONNECT: { | 
 | 225 |             CHECK_INTERFACE(ICameraService, data, reply); | 
| Eino-Ville Talvala | ceb388d | 2013-02-19 10:40:14 -0800 | [diff] [blame] | 226 |             sp<ICameraClient> cameraClient = | 
 | 227 |                     interface_cast<ICameraClient>(data.readStrongBinder()); | 
 | 228 |             int32_t cameraId = data.readInt32(); | 
 | 229 |             const String16 clientName = data.readString16(); | 
 | 230 |             int32_t clientUid = data.readInt32(); | 
 | 231 |             sp<ICamera> camera = connect(cameraClient, cameraId, | 
 | 232 |                     clientName, clientUid); | 
| Igor Murashkin | bef3f23 | 2013-05-30 17:47:38 -0700 | [diff] [blame] | 233 |             reply->writeNoException(); | 
| Mathias Agopian | 3cf6135 | 2010-02-09 17:46:37 -0800 | [diff] [blame] | 234 |             reply->writeStrongBinder(camera->asBinder()); | 
 | 235 |             return NO_ERROR; | 
 | 236 |         } break; | 
| Igor Murashkin | 634a515 | 2013-02-20 17:15:11 -0800 | [diff] [blame] | 237 |         case CONNECT_PRO: { | 
 | 238 |             CHECK_INTERFACE(ICameraService, data, reply); | 
| Igor Murashkin | bef3f23 | 2013-05-30 17:47:38 -0700 | [diff] [blame] | 239 |             sp<IProCameraCallbacks> cameraClient = | 
 | 240 |                 interface_cast<IProCameraCallbacks>(data.readStrongBinder()); | 
| Igor Murashkin | c073ba5 | 2013-02-26 14:32:34 -0800 | [diff] [blame] | 241 |             int32_t cameraId = data.readInt32(); | 
 | 242 |             const String16 clientName = data.readString16(); | 
 | 243 |             int32_t clientUid = data.readInt32(); | 
 | 244 |             sp<IProCameraUser> camera = connect(cameraClient, cameraId, | 
 | 245 |                                                 clientName, clientUid); | 
| Igor Murashkin | bef3f23 | 2013-05-30 17:47:38 -0700 | [diff] [blame] | 246 |             reply->writeNoException(); | 
| Igor Murashkin | 634a515 | 2013-02-20 17:15:11 -0800 | [diff] [blame] | 247 |             reply->writeStrongBinder(camera->asBinder()); | 
 | 248 |             return NO_ERROR; | 
 | 249 |         } break; | 
| Igor Murashkin | e7ee763 | 2013-06-11 18:10:18 -0700 | [diff] [blame] | 250 |         case CONNECT_DEVICE: { | 
 | 251 |             CHECK_INTERFACE(ICameraService, data, reply); | 
 | 252 |             sp<ICameraDeviceCallbacks> cameraClient = | 
 | 253 |                 interface_cast<ICameraDeviceCallbacks>(data.readStrongBinder()); | 
 | 254 |             int32_t cameraId = data.readInt32(); | 
 | 255 |             const String16 clientName = data.readString16(); | 
 | 256 |             int32_t clientUid = data.readInt32(); | 
 | 257 |             sp<ICameraDeviceUser> camera = connect(cameraClient, cameraId, | 
 | 258 |                                                 clientName, clientUid); | 
 | 259 |             reply->writeNoException(); | 
 | 260 |             reply->writeStrongBinder(camera->asBinder()); | 
 | 261 |             return NO_ERROR; | 
 | 262 |         } break; | 
| Igor Murashkin | bfc9915 | 2013-02-27 12:55:20 -0800 | [diff] [blame] | 263 |         case ADD_LISTENER: { | 
 | 264 |             CHECK_INTERFACE(ICameraService, data, reply); | 
 | 265 |             sp<ICameraServiceListener> listener = | 
 | 266 |                 interface_cast<ICameraServiceListener>(data.readStrongBinder()); | 
| Igor Murashkin | bef3f23 | 2013-05-30 17:47:38 -0700 | [diff] [blame] | 267 |             reply->writeNoException(); | 
| Igor Murashkin | bfc9915 | 2013-02-27 12:55:20 -0800 | [diff] [blame] | 268 |             reply->writeInt32(addListener(listener)); | 
 | 269 |             return NO_ERROR; | 
 | 270 |         } break; | 
 | 271 |         case REMOVE_LISTENER: { | 
 | 272 |             CHECK_INTERFACE(ICameraService, data, reply); | 
 | 273 |             sp<ICameraServiceListener> listener = | 
 | 274 |                 interface_cast<ICameraServiceListener>(data.readStrongBinder()); | 
| Igor Murashkin | bef3f23 | 2013-05-30 17:47:38 -0700 | [diff] [blame] | 275 |             reply->writeNoException(); | 
| Igor Murashkin | bfc9915 | 2013-02-27 12:55:20 -0800 | [diff] [blame] | 276 |             reply->writeInt32(removeListener(listener)); | 
 | 277 |             return NO_ERROR; | 
 | 278 |         } break; | 
| Mathias Agopian | 3cf6135 | 2010-02-09 17:46:37 -0800 | [diff] [blame] | 279 |         default: | 
 | 280 |             return BBinder::onTransact(code, data, reply, flags); | 
 | 281 |     } | 
 | 282 | } | 
 | 283 |  | 
 | 284 | // ---------------------------------------------------------------------------- | 
 | 285 |  | 
 | 286 | }; // namespace android |