IProCameraUser.cpp revision 7cf9a7e7d19579565e0f9dba8be9c107f2dbf548
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 <system/camera_metadata.h> 28 29namespace android { 30 31typedef Parcel::WritableBlob WritableBlob; 32typedef Parcel::ReadableBlob ReadableBlob; 33 34enum { 35 DISCONNECT = IBinder::FIRST_CALL_TRANSACTION, 36 CONNECT, 37 EXCLUSIVE_TRY_LOCK, 38 EXCLUSIVE_LOCK, 39 EXCLUSIVE_UNLOCK, 40 HAS_EXCLUSIVE_LOCK, 41 SUBMIT_REQUEST, 42 CANCEL_REQUEST, 43 DELETE_STREAM, 44 CREATE_STREAM, 45 CREATE_DEFAULT_REQUEST, 46 GET_CAMERA_INFO, 47}; 48 49/** 50 * Caller becomes the owner of the new metadata 51 * 'const Parcel' doesnt prevent us from calling the read functions. 52 * which is interesting since it changes the internal state 53 */ 54void readMetadata(const Parcel& data, camera_metadata_t** out) { 55 camera_metadata_t* metadata; 56 57 // arg0 = metadataSize (int32) 58 size_t metadataSize = static_cast<size_t>(data.readInt32()); 59 60 if (metadataSize == 0) { 61 if (out) { 62 *out = NULL; 63 } 64 return; 65 } 66 67 // NOTE: this doesn't make sense to me. shouldnt the blob 68 // know how big it is? why do we have to specify the size 69 // to Parcel::readBlob ? 70 71 ReadableBlob blob; 72 // arg1 = metadata (blob) 73 { 74 data.readBlob(metadataSize, &blob); 75 const camera_metadata_t* tmp = 76 reinterpret_cast<const camera_metadata_t*>(blob.data()); 77 size_t entry_capacity = get_camera_metadata_entry_capacity(tmp); 78 size_t data_capacity = get_camera_metadata_data_capacity(tmp); 79 80 metadata = allocate_camera_metadata(entry_capacity, data_capacity); 81 copy_camera_metadata(metadata, metadataSize, tmp); 82 } 83 blob.release(); 84 85 if (out) { 86 *out = metadata; 87 } else { 88 free_camera_metadata(metadata); 89 } 90} 91 92/** 93 * Caller retains ownership of metadata 94 * - Write 2 (int32 + blob) args in the current position 95 */ 96void writeMetadata(Parcel& data, camera_metadata_t* metadata) { 97 // arg0 = metadataSize (int32) 98 size_t metadataSize; 99 100 if (metadata == NULL) { 101 data.writeInt32(0); 102 return; 103 } 104 105 metadataSize = get_camera_metadata_compact_size(metadata); 106 data.writeInt32(static_cast<int32_t>(metadataSize)); 107 108 // arg1 = metadata (blob) 109 WritableBlob blob; 110 { 111 data.writeBlob(metadataSize, &blob); 112 copy_camera_metadata(blob.data(), metadataSize, metadata); 113 } 114 blob.release(); 115} 116 117class BpProCameraUser: public BpInterface<IProCameraUser> 118{ 119public: 120 BpProCameraUser(const sp<IBinder>& impl) 121 : BpInterface<IProCameraUser>(impl) 122 { 123 } 124 125 // disconnect from camera service 126 void disconnect() 127 { 128 ALOGV("disconnect"); 129 Parcel data, reply; 130 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor()); 131 remote()->transact(DISCONNECT, data, &reply); 132 } 133 134 virtual status_t connect(const sp<IProCameraCallbacks>& cameraClient) 135 { 136 Parcel data, reply; 137 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor()); 138 data.writeStrongBinder(cameraClient->asBinder()); 139 remote()->transact(CONNECT, data, &reply); 140 return reply.readInt32(); 141 } 142 143 /* Shared ProCameraUser */ 144 145 virtual status_t exclusiveTryLock() 146 { 147 Parcel data, reply; 148 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor()); 149 remote()->transact(EXCLUSIVE_TRY_LOCK, data, &reply); 150 return reply.readInt32(); 151 } 152 virtual status_t exclusiveLock() 153 { 154 Parcel data, reply; 155 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor()); 156 remote()->transact(EXCLUSIVE_LOCK, data, &reply); 157 return reply.readInt32(); 158 } 159 160 virtual status_t exclusiveUnlock() 161 { 162 Parcel data, reply; 163 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor()); 164 remote()->transact(EXCLUSIVE_UNLOCK, data, &reply); 165 return reply.readInt32(); 166 } 167 168 virtual bool hasExclusiveLock() 169 { 170 Parcel data, reply; 171 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor()); 172 remote()->transact(HAS_EXCLUSIVE_LOCK, data, &reply); 173 return !!reply.readInt32(); 174 } 175 176 virtual int submitRequest(camera_metadata_t* metadata, bool streaming) 177 { 178 179 Parcel data, reply; 180 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor()); 181 182 // arg0+arg1 183 writeMetadata(data, metadata); 184 185 // arg2 = streaming (bool) 186 data.writeInt32(streaming); 187 188 remote()->transact(SUBMIT_REQUEST, data, &reply); 189 return reply.readInt32(); 190 } 191 192 virtual status_t cancelRequest(int requestId) 193 { 194 Parcel data, reply; 195 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor()); 196 data.writeInt32(requestId); 197 198 remote()->transact(CANCEL_REQUEST, data, &reply); 199 return reply.readInt32(); 200 } 201 202 virtual status_t deleteStream(int streamId) 203 { 204 Parcel data, reply; 205 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor()); 206 data.writeInt32(streamId); 207 208 remote()->transact(DELETE_STREAM, data, &reply); 209 return reply.readInt32(); 210 } 211 212 virtual status_t createStream(int width, int height, int format, 213 const sp<IGraphicBufferProducer>& bufferProducer, 214 /*out*/ 215 int* streamId) 216 { 217 Parcel data, reply; 218 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor()); 219 data.writeInt32(width); 220 data.writeInt32(height); 221 data.writeInt32(format); 222 223 sp<IBinder> b(bufferProducer->asBinder()); 224 data.writeStrongBinder(b); 225 226 remote()->transact(CREATE_STREAM, data, &reply); 227 228 int sId = reply.readInt32(); 229 if (streamId) { 230 *streamId = sId; 231 } 232 return reply.readInt32(); 233 } 234 235 // Create a request object from a template. 236 virtual status_t createDefaultRequest(int templateId, 237 /*out*/ 238 camera_metadata** request) 239 { 240 Parcel data, reply; 241 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor()); 242 data.writeInt32(templateId); 243 remote()->transact(CREATE_DEFAULT_REQUEST, data, &reply); 244 readMetadata(reply, /*out*/request); 245 return reply.readInt32(); 246 } 247 248 249 virtual status_t getCameraInfo(int cameraId, camera_metadata** info) 250 { 251 Parcel data, reply; 252 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor()); 253 data.writeInt32(cameraId); 254 remote()->transact(GET_CAMERA_INFO, data, &reply); 255 readMetadata(reply, /*out*/info); 256 return reply.readInt32(); 257 } 258 259 260private: 261 262 263}; 264 265IMPLEMENT_META_INTERFACE(ProCameraUser, "android.hardware.IProCameraUser"); 266 267// ---------------------------------------------------------------------- 268 269status_t BnProCameraUser::onTransact( 270 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 271{ 272 switch(code) { 273 case DISCONNECT: { 274 ALOGV("DISCONNECT"); 275 CHECK_INTERFACE(IProCameraUser, data, reply); 276 disconnect(); 277 return NO_ERROR; 278 } break; 279 case CONNECT: { 280 CHECK_INTERFACE(IProCameraUser, data, reply); 281 sp<IProCameraCallbacks> cameraClient = 282 interface_cast<IProCameraCallbacks>(data.readStrongBinder()); 283 reply->writeInt32(connect(cameraClient)); 284 return NO_ERROR; 285 } break; 286 287 /* Shared ProCameraUser */ 288 case EXCLUSIVE_TRY_LOCK: { 289 CHECK_INTERFACE(IProCameraUser, data, reply); 290 reply->writeInt32(exclusiveTryLock()); 291 return NO_ERROR; 292 } break; 293 case EXCLUSIVE_LOCK: { 294 CHECK_INTERFACE(IProCameraUser, data, reply); 295 reply->writeInt32(exclusiveLock()); 296 return NO_ERROR; 297 } break; 298 case EXCLUSIVE_UNLOCK: { 299 CHECK_INTERFACE(IProCameraUser, data, reply); 300 reply->writeInt32(exclusiveUnlock()); 301 return NO_ERROR; 302 } break; 303 case HAS_EXCLUSIVE_LOCK: { 304 CHECK_INTERFACE(IProCameraUser, data, reply); 305 reply->writeInt32(hasExclusiveLock()); 306 return NO_ERROR; 307 } break; 308 case SUBMIT_REQUEST: { 309 CHECK_INTERFACE(IProCameraUser, data, reply); 310 camera_metadata_t* metadata; 311 readMetadata(data, /*out*/&metadata); 312 313 // arg2 = streaming (bool) 314 bool streaming = data.readInt32(); 315 316 // return code: requestId (int32) 317 reply->writeInt32(submitRequest(metadata, streaming)); 318 319 return NO_ERROR; 320 } break; 321 case CANCEL_REQUEST: { 322 CHECK_INTERFACE(IProCameraUser, data, reply); 323 int requestId = data.readInt32(); 324 reply->writeInt32(cancelRequest(requestId)); 325 return NO_ERROR; 326 } break; 327 case DELETE_STREAM: { 328 CHECK_INTERFACE(IProCameraUser, data, reply); 329 int streamId = data.readInt32(); 330 reply->writeInt32(deleteStream(streamId)); 331 return NO_ERROR; 332 } break; 333 case CREATE_STREAM: { 334 CHECK_INTERFACE(IProCameraUser, data, reply); 335 int width, height, format; 336 337 width = data.readInt32(); 338 height = data.readInt32(); 339 format = data.readInt32(); 340 341 sp<IGraphicBufferProducer> bp = 342 interface_cast<IGraphicBufferProducer>(data.readStrongBinder()); 343 344 int streamId = -1; 345 status_t ret; 346 ret = createStream(width, height, format, bp, &streamId); 347 348 reply->writeInt32(streamId); 349 reply->writeInt32(ret); 350 351 return NO_ERROR; 352 } break; 353 354 case CREATE_DEFAULT_REQUEST: { 355 CHECK_INTERFACE(IProCameraUser, data, reply); 356 357 int templateId = data.readInt32(); 358 359 camera_metadata_t* request = NULL; 360 status_t ret; 361 ret = createDefaultRequest(templateId, &request); 362 363 writeMetadata(*reply, request); 364 reply->writeInt32(ret); 365 366 free_camera_metadata(request); 367 368 return NO_ERROR; 369 } break; 370 case GET_CAMERA_INFO: { 371 CHECK_INTERFACE(IProCameraUser, data, reply); 372 373 int cameraId = data.readInt32(); 374 375 camera_metadata_t* info = NULL; 376 status_t ret; 377 ret = getCameraInfo(cameraId, &info); 378 379 writeMetadata(*reply, info); 380 reply->writeInt32(ret); 381 382 free_camera_metadata(info); 383 384 return NO_ERROR; 385 } break; 386 default: 387 return BBinder::onTransact(code, data, reply, flags); 388 } 389} 390 391// ---------------------------------------------------------------------------- 392 393}; // namespace android 394