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 "camera/CameraMetadata.h" 28 29 namespace android { 30 31 enum { 32 DISCONNECT = IBinder::FIRST_CALL_TRANSACTION, 33 CONNECT, 34 EXCLUSIVE_TRY_LOCK, 35 EXCLUSIVE_LOCK, 36 EXCLUSIVE_UNLOCK, 37 HAS_EXCLUSIVE_LOCK, 38 SUBMIT_REQUEST, 39 CANCEL_REQUEST, 40 DELETE_STREAM, 41 CREATE_STREAM, 42 CREATE_DEFAULT_REQUEST, 43 GET_CAMERA_INFO, 44 }; 45 46 class BpProCameraUser: public BpInterface<IProCameraUser> 47 { 48 public: 49 BpProCameraUser(const sp<IBinder>& impl) 50 : BpInterface<IProCameraUser>(impl) 51 { 52 } 53 54 // disconnect from camera service 55 void disconnect() 56 { 57 ALOGV("disconnect"); 58 Parcel data, reply; 59 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor()); 60 remote()->transact(DISCONNECT, data, &reply); 61 reply.readExceptionCode(); 62 } 63 64 virtual status_t connect(const sp<IProCameraCallbacks>& cameraClient) 65 { 66 Parcel data, reply; 67 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor()); 68 data.writeStrongBinder(cameraClient->asBinder()); 69 remote()->transact(CONNECT, data, &reply); 70 return reply.readInt32(); 71 } 72 73 /* Shared ProCameraUser */ 74 75 virtual status_t exclusiveTryLock() 76 { 77 Parcel data, reply; 78 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor()); 79 remote()->transact(EXCLUSIVE_TRY_LOCK, data, &reply); 80 return reply.readInt32(); 81 } 82 virtual status_t exclusiveLock() 83 { 84 Parcel data, reply; 85 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor()); 86 remote()->transact(EXCLUSIVE_LOCK, data, &reply); 87 return reply.readInt32(); 88 } 89 90 virtual status_t exclusiveUnlock() 91 { 92 Parcel data, reply; 93 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor()); 94 remote()->transact(EXCLUSIVE_UNLOCK, data, &reply); 95 return reply.readInt32(); 96 } 97 98 virtual bool hasExclusiveLock() 99 { 100 Parcel data, reply; 101 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor()); 102 remote()->transact(HAS_EXCLUSIVE_LOCK, data, &reply); 103 return !!reply.readInt32(); 104 } 105 106 virtual int submitRequest(camera_metadata_t* metadata, bool streaming) 107 { 108 109 Parcel data, reply; 110 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor()); 111 112 // arg0+arg1 113 CameraMetadata::writeToParcel(data, metadata); 114 115 // arg2 = streaming (bool) 116 data.writeInt32(streaming); 117 118 remote()->transact(SUBMIT_REQUEST, data, &reply); 119 return reply.readInt32(); 120 } 121 122 virtual status_t cancelRequest(int requestId) 123 { 124 Parcel data, reply; 125 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor()); 126 data.writeInt32(requestId); 127 128 remote()->transact(CANCEL_REQUEST, data, &reply); 129 return reply.readInt32(); 130 } 131 132 virtual status_t deleteStream(int streamId) 133 { 134 Parcel data, reply; 135 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor()); 136 data.writeInt32(streamId); 137 138 remote()->transact(DELETE_STREAM, data, &reply); 139 return reply.readInt32(); 140 } 141 142 virtual status_t createStream(int width, int height, int format, 143 const sp<IGraphicBufferProducer>& bufferProducer, 144 /*out*/ 145 int* streamId) 146 { 147 Parcel data, reply; 148 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor()); 149 data.writeInt32(width); 150 data.writeInt32(height); 151 data.writeInt32(format); 152 153 sp<IBinder> b(bufferProducer->asBinder()); 154 data.writeStrongBinder(b); 155 156 remote()->transact(CREATE_STREAM, data, &reply); 157 158 int sId = reply.readInt32(); 159 if (streamId) { 160 *streamId = sId; 161 } 162 return reply.readInt32(); 163 } 164 165 // Create a request object from a template. 166 virtual status_t createDefaultRequest(int templateId, 167 /*out*/ 168 camera_metadata** request) 169 { 170 Parcel data, reply; 171 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor()); 172 data.writeInt32(templateId); 173 remote()->transact(CREATE_DEFAULT_REQUEST, data, &reply); 174 CameraMetadata::readFromParcel(reply, /*out*/request); 175 return reply.readInt32(); 176 } 177 178 179 virtual status_t getCameraInfo(int cameraId, camera_metadata** info) 180 { 181 Parcel data, reply; 182 data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor()); 183 data.writeInt32(cameraId); 184 remote()->transact(GET_CAMERA_INFO, data, &reply); 185 CameraMetadata::readFromParcel(reply, /*out*/info); 186 return reply.readInt32(); 187 } 188 189 190 private: 191 192 193 }; 194 195 IMPLEMENT_META_INTERFACE(ProCameraUser, "android.hardware.IProCameraUser"); 196 197 // ---------------------------------------------------------------------- 198 199 status_t BnProCameraUser::onTransact( 200 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 201 { 202 switch(code) { 203 case DISCONNECT: { 204 ALOGV("DISCONNECT"); 205 CHECK_INTERFACE(IProCameraUser, data, reply); 206 disconnect(); 207 reply->writeNoException(); 208 return NO_ERROR; 209 } break; 210 case CONNECT: { 211 CHECK_INTERFACE(IProCameraUser, data, reply); 212 sp<IProCameraCallbacks> cameraClient = 213 interface_cast<IProCameraCallbacks>(data.readStrongBinder()); 214 reply->writeInt32(connect(cameraClient)); 215 return NO_ERROR; 216 } break; 217 218 /* Shared ProCameraUser */ 219 case EXCLUSIVE_TRY_LOCK: { 220 CHECK_INTERFACE(IProCameraUser, data, reply); 221 reply->writeInt32(exclusiveTryLock()); 222 return NO_ERROR; 223 } break; 224 case EXCLUSIVE_LOCK: { 225 CHECK_INTERFACE(IProCameraUser, data, reply); 226 reply->writeInt32(exclusiveLock()); 227 return NO_ERROR; 228 } break; 229 case EXCLUSIVE_UNLOCK: { 230 CHECK_INTERFACE(IProCameraUser, data, reply); 231 reply->writeInt32(exclusiveUnlock()); 232 return NO_ERROR; 233 } break; 234 case HAS_EXCLUSIVE_LOCK: { 235 CHECK_INTERFACE(IProCameraUser, data, reply); 236 reply->writeInt32(hasExclusiveLock()); 237 return NO_ERROR; 238 } break; 239 case SUBMIT_REQUEST: { 240 CHECK_INTERFACE(IProCameraUser, data, reply); 241 camera_metadata_t* metadata; 242 CameraMetadata::readFromParcel(data, /*out*/&metadata); 243 244 // arg2 = streaming (bool) 245 bool streaming = data.readInt32(); 246 247 // return code: requestId (int32) 248 reply->writeInt32(submitRequest(metadata, streaming)); 249 250 return NO_ERROR; 251 } break; 252 case CANCEL_REQUEST: { 253 CHECK_INTERFACE(IProCameraUser, data, reply); 254 int requestId = data.readInt32(); 255 reply->writeInt32(cancelRequest(requestId)); 256 return NO_ERROR; 257 } break; 258 case DELETE_STREAM: { 259 CHECK_INTERFACE(IProCameraUser, data, reply); 260 int streamId = data.readInt32(); 261 reply->writeInt32(deleteStream(streamId)); 262 return NO_ERROR; 263 } break; 264 case CREATE_STREAM: { 265 CHECK_INTERFACE(IProCameraUser, data, reply); 266 int width, height, format; 267 268 width = data.readInt32(); 269 height = data.readInt32(); 270 format = data.readInt32(); 271 272 sp<IGraphicBufferProducer> bp = 273 interface_cast<IGraphicBufferProducer>(data.readStrongBinder()); 274 275 int streamId = -1; 276 status_t ret; 277 ret = createStream(width, height, format, bp, &streamId); 278 279 reply->writeInt32(streamId); 280 reply->writeInt32(ret); 281 282 return NO_ERROR; 283 } break; 284 285 case CREATE_DEFAULT_REQUEST: { 286 CHECK_INTERFACE(IProCameraUser, data, reply); 287 288 int templateId = data.readInt32(); 289 290 camera_metadata_t* request = NULL; 291 status_t ret; 292 ret = createDefaultRequest(templateId, &request); 293 294 CameraMetadata::writeToParcel(*reply, request); 295 reply->writeInt32(ret); 296 297 free_camera_metadata(request); 298 299 return NO_ERROR; 300 } break; 301 case GET_CAMERA_INFO: { 302 CHECK_INTERFACE(IProCameraUser, data, reply); 303 304 int cameraId = data.readInt32(); 305 306 camera_metadata_t* info = NULL; 307 status_t ret; 308 ret = getCameraInfo(cameraId, &info); 309 310 CameraMetadata::writeToParcel(*reply, info); 311 reply->writeInt32(ret); 312 313 free_camera_metadata(info); 314 315 return NO_ERROR; 316 } break; 317 default: 318 return BBinder::onTransact(code, data, reply, flags); 319 } 320 } 321 322 // ---------------------------------------------------------------------------- 323 324 }; // namespace android 325