IProCameraUser.cpp revision 76f8b43909817179b317880202360863b8f976d0
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}; 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 requestStream(int streamId) 203 { 204 Parcel data, reply; 205 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor()); 206 data.writeInt32(streamId); 207 208 remote()->transact(REQUEST_STREAM, data, &reply); 209 return reply.readInt32(); 210 } 211 virtual status_t cancelStream(int streamId) 212 { 213 Parcel data, reply; 214 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor()); 215 data.writeInt32(streamId); 216 217 remote()->transact(CANCEL_STREAM, data, &reply); 218 return reply.readInt32(); 219 } 220 221 virtual status_t createStream(int width, int height, int format, 222 const sp<IGraphicBufferProducer>& bufferProducer, 223 /*out*/ 224 int* streamId) 225 { 226 Parcel data, reply; 227 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor()); 228 data.writeInt32(width); 229 data.writeInt32(height); 230 data.writeInt32(format); 231 232 sp<IBinder> b(bufferProducer->asBinder()); 233 data.writeStrongBinder(b); 234 235 remote()->transact(CREATE_STREAM, data, &reply); 236 237 int sId = reply.readInt32(); 238 if (streamId) { 239 *streamId = sId; 240 } 241 return reply.readInt32(); 242 } 243 244 // Create a request object from a template. 245 virtual status_t createDefaultRequest(int templateId, 246 /*out*/ 247 camera_metadata** request) 248 { 249 Parcel data, reply; 250 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor()); 251 data.writeInt32(templateId); 252 remote()->transact(CREATE_DEFAULT_REQUEST, data, &reply); 253 readMetadata(reply, /*out*/request); 254 return reply.readInt32(); 255 } 256 257 258private: 259 260 261}; 262 263IMPLEMENT_META_INTERFACE(ProCameraUser, "android.hardware.IProCameraUser"); 264 265// ---------------------------------------------------------------------- 266 267status_t BnProCameraUser::onTransact( 268 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 269{ 270 switch(code) { 271 case DISCONNECT: { 272 ALOGV("DISCONNECT"); 273 CHECK_INTERFACE(IProCameraUser, data, reply); 274 disconnect(); 275 return NO_ERROR; 276 } break; 277 case CONNECT: { 278 CHECK_INTERFACE(IProCameraUser, data, reply); 279 sp<IProCameraCallbacks> cameraClient = 280 interface_cast<IProCameraCallbacks>(data.readStrongBinder()); 281 reply->writeInt32(connect(cameraClient)); 282 return NO_ERROR; 283 } break; 284 285 /* Shared ProCameraUser */ 286 case EXCLUSIVE_TRY_LOCK: { 287 CHECK_INTERFACE(IProCameraUser, data, reply); 288 reply->writeInt32(exclusiveTryLock()); 289 return NO_ERROR; 290 } break; 291 case EXCLUSIVE_LOCK: { 292 CHECK_INTERFACE(IProCameraUser, data, reply); 293 reply->writeInt32(exclusiveLock()); 294 return NO_ERROR; 295 } break; 296 case EXCLUSIVE_UNLOCK: { 297 CHECK_INTERFACE(IProCameraUser, data, reply); 298 reply->writeInt32(exclusiveUnlock()); 299 return NO_ERROR; 300 } break; 301 case HAS_EXCLUSIVE_LOCK: { 302 CHECK_INTERFACE(IProCameraUser, data, reply); 303 reply->writeInt32(hasExclusiveLock()); 304 return NO_ERROR; 305 } break; 306 case SUBMIT_REQUEST: { 307 CHECK_INTERFACE(IProCameraUser, data, reply); 308 camera_metadata_t* metadata; 309 readMetadata(data, /*out*/&metadata); 310 311 // arg2 = streaming (bool) 312 bool streaming = data.readInt32(); 313 314 // return code: requestId (int32) 315 reply->writeInt32(submitRequest(metadata, streaming)); 316 317 return NO_ERROR; 318 } break; 319 case CANCEL_REQUEST: { 320 CHECK_INTERFACE(IProCameraUser, data, reply); 321 int requestId = data.readInt32(); 322 reply->writeInt32(cancelRequest(requestId)); 323 return NO_ERROR; 324 } break; 325 case REQUEST_STREAM: { 326 CHECK_INTERFACE(IProCameraUser, data, reply); 327 int streamId = data.readInt32(); 328 reply->writeInt32(requestStream(streamId)); 329 return NO_ERROR; 330 } break; 331 case CANCEL_STREAM: { 332 CHECK_INTERFACE(IProCameraUser, data, reply); 333 int streamId = data.readInt32(); 334 reply->writeInt32(cancelStream(streamId)); 335 return NO_ERROR; 336 } break; 337 case CREATE_STREAM: { 338 CHECK_INTERFACE(IProCameraUser, data, reply); 339 int width, height, format; 340 341 width = data.readInt32(); 342 height = data.readInt32(); 343 format = data.readInt32(); 344 345 sp<IGraphicBufferProducer> bp = 346 interface_cast<IGraphicBufferProducer>(data.readStrongBinder()); 347 348 int streamId = -1; 349 status_t ret; 350 ret = createStream(width, height, format, bp, &streamId); 351 352 reply->writeInt32(streamId); 353 reply->writeInt32(ret); 354 355 return NO_ERROR; 356 } break; 357 358 case CREATE_DEFAULT_REQUEST: { 359 CHECK_INTERFACE(IProCameraUser, data, reply); 360 361 int templateId = data.readInt32(); 362 363 camera_metadata_t* request = NULL; 364 status_t ret; 365 ret = createDefaultRequest(templateId, &request); 366 367 writeMetadata(*reply, request); 368 reply->writeInt32(ret); 369 370 return NO_ERROR; 371 } break; 372 default: 373 return BBinder::onTransact(code, data, reply, flags); 374 } 375} 376 377// ---------------------------------------------------------------------------- 378 379}; // namespace android 380