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