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