Loading camera/Android.mk +3 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,9 @@ LOCAL_SRC_FILES:= \ ICameraRecordingProxyListener.cpp \ IProCameraUser.cpp \ IProCameraCallbacks.cpp \ camera2/ICameraDeviceUser.cpp \ camera2/ICameraDeviceCallbacks.cpp \ camera2/CaptureRequest.cpp \ ProCamera.cpp \ CameraBase.cpp \ Loading camera/Camera.cpp +15 −4 Original line number Diff line number Diff line Loading @@ -39,6 +39,9 @@ Camera::Camera(int cameraId) { } CameraTraits<Camera>::TCamConnectService CameraTraits<Camera>::fnConnectService = &ICameraService::connect; // construct a camera client from an existing camera remote sp<Camera> Camera::create(const sp<ICamera>& camera) { Loading Loading @@ -97,13 +100,13 @@ status_t Camera::unlock() } // pass the buffered IGraphicBufferProducer to the camera service status_t Camera::setPreviewTexture(const sp<IGraphicBufferProducer>& bufferProducer) status_t Camera::setPreviewTarget(const sp<IGraphicBufferProducer>& bufferProducer) { ALOGV("setPreviewTexture(%p)", bufferProducer.get()); ALOGV("setPreviewTarget(%p)", bufferProducer.get()); sp <ICamera> c = mCamera; if (c == 0) return NO_INIT; ALOGD_IF(bufferProducer == 0, "app passed NULL surface"); return c->setPreviewTexture(bufferProducer); return c->setPreviewTarget(bufferProducer); } // start preview mode Loading @@ -124,7 +127,7 @@ status_t Camera::storeMetaDataInBuffers(bool enabled) return c->storeMetaDataInBuffers(enabled); } // start recording mode, must call setPreviewDisplay first // start recording mode, must call setPreviewTarget first status_t Camera::startRecording() { ALOGV("startRecording"); Loading Loading @@ -255,6 +258,14 @@ void Camera::setPreviewCallbackFlags(int flag) mCamera->setPreviewCallbackFlag(flag); } status_t Camera::setPreviewCallbackTarget( const sp<IGraphicBufferProducer>& callbackProducer) { sp <ICamera> c = mCamera; if (c == 0) return NO_INIT; return c->setPreviewCallbackTarget(callbackProducer); } // callback from camera service void Camera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2) { Loading camera/CameraBase.cpp +8 −3 Original line number Diff line number Diff line Loading @@ -98,14 +98,19 @@ sp<TCam> CameraBase<TCam, TCamTraits>::connect(int cameraId, ALOGV("%s: connect", __FUNCTION__); sp<TCam> c = new TCam(cameraId); sp<TCamCallbacks> cl = c; status_t status = NO_ERROR; const sp<ICameraService>& cs = getCameraService(); if (cs != 0) { c->mCamera = cs->connect(cl, cameraId, clientPackageName, clientUid); TCamConnectService fnConnectService = TCamTraits::fnConnectService; status = (cs.get()->*fnConnectService)(cl, cameraId, clientPackageName, clientUid, /*out*/ c->mCamera); } if (c->mCamera != 0) { if (status == OK && c->mCamera != 0) { c->mCamera->asBinder()->linkToDeath(c); c->mStatus = NO_ERROR; } else { ALOGW("An error occurred while connecting to camera: %d", cameraId); c.clear(); } return c; Loading camera/CameraMetadata.cpp +175 −0 Original line number Diff line number Diff line Loading @@ -21,9 +21,13 @@ #include <utils/Errors.h> #include <camera/CameraMetadata.h> #include <binder/Parcel.h> namespace android { typedef Parcel::WritableBlob WritableBlob; typedef Parcel::ReadableBlob ReadableBlob; CameraMetadata::CameraMetadata() : mBuffer(NULL), mLocked(false) { } Loading Loading @@ -408,4 +412,175 @@ status_t CameraMetadata::resizeIfNeeded(size_t extraEntries, size_t extraData) { return OK; } status_t CameraMetadata::readFromParcel(const Parcel& data, camera_metadata_t** out) { status_t err = OK; camera_metadata_t* metadata = NULL; if (out) { *out = NULL; } // arg0 = metadataSize (int32) int32_t metadataSizeTmp = -1; if ((err = data.readInt32(&metadataSizeTmp)) != OK) { ALOGE("%s: Failed to read metadata size (error %d %s)", __FUNCTION__, err, strerror(-err)); return err; } const size_t metadataSize = static_cast<size_t>(metadataSizeTmp); if (metadataSize == 0) { ALOGV("%s: Read 0-sized metadata", __FUNCTION__); return OK; } // NOTE: this doesn't make sense to me. shouldnt the blob // know how big it is? why do we have to specify the size // to Parcel::readBlob ? ReadableBlob blob; // arg1 = metadata (blob) do { if ((err = data.readBlob(metadataSize, &blob)) != OK) { ALOGE("%s: Failed to read metadata blob (sized %d). Possible " " serialization bug. Error %d %s", __FUNCTION__, metadataSize, err, strerror(-err)); break; } const camera_metadata_t* tmp = reinterpret_cast<const camera_metadata_t*>(blob.data()); metadata = allocate_copy_camera_metadata_checked(tmp, metadataSize); if (metadata == NULL) { // We consider that allocation only fails if the validation // also failed, therefore the readFromParcel was a failure. err = BAD_VALUE; } } while(0); blob.release(); if (out) { ALOGV("%s: Set out metadata to %p", __FUNCTION__, metadata); *out = metadata; } else if (metadata != NULL) { ALOGV("%s: Freed camera metadata at %p", __FUNCTION__, metadata); free_camera_metadata(metadata); } return err; } status_t CameraMetadata::writeToParcel(Parcel& data, const camera_metadata_t* metadata) { status_t res = OK; // arg0 = metadataSize (int32) if (metadata == NULL) { return data.writeInt32(0); } const size_t metadataSize = get_camera_metadata_compact_size(metadata); res = data.writeInt32(static_cast<int32_t>(metadataSize)); if (res != OK) { return res; } // arg1 = metadata (blob) WritableBlob blob; do { res = data.writeBlob(metadataSize, &blob); if (res != OK) { break; } copy_camera_metadata(blob.data(), metadataSize, metadata); IF_ALOGV() { if (validate_camera_metadata_structure( (const camera_metadata_t*)blob.data(), &metadataSize) != OK) { ALOGV("%s: Failed to validate metadata %p after writing blob", __FUNCTION__, blob.data()); } else { ALOGV("%s: Metadata written to blob. Validation success", __FUNCTION__); } } // Not too big of a problem since receiving side does hard validation // Don't check the size since the compact size could be larger if (validate_camera_metadata_structure(metadata, /*size*/NULL) != OK) { ALOGW("%s: Failed to validate metadata %p before writing blob", __FUNCTION__, metadata); } } while(false); blob.release(); return res; } status_t CameraMetadata::readFromParcel(Parcel *parcel) { ALOGV("%s: parcel = %p", __FUNCTION__, parcel); status_t res = OK; if (parcel == NULL) { ALOGE("%s: parcel is null", __FUNCTION__); return BAD_VALUE; } if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return INVALID_OPERATION; } camera_metadata *buffer = NULL; // TODO: reading should return a status code, in case validation fails res = CameraMetadata::readFromParcel(*parcel, &buffer); if (res != NO_ERROR) { ALOGE("%s: Failed to read from parcel. Metadata is unchanged.", __FUNCTION__); return res; } clear(); mBuffer = buffer; return OK; } status_t CameraMetadata::writeToParcel(Parcel *parcel) const { ALOGV("%s: parcel = %p", __FUNCTION__, parcel); if (parcel == NULL) { ALOGE("%s: parcel is null", __FUNCTION__); return BAD_VALUE; } return CameraMetadata::writeToParcel(*parcel, mBuffer); } void CameraMetadata::swap(CameraMetadata& other) { if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return; } else if (other.mLocked) { ALOGE("%s: Other CameraMetadata is locked", __FUNCTION__); return; } camera_metadata* thisBuf = mBuffer; camera_metadata* otherBuf = other.mBuffer; other.mBuffer = thisBuf; mBuffer = otherBuf; } }; // namespace android camera/ICamera.cpp +32 −9 Original line number Diff line number Diff line Loading @@ -29,8 +29,9 @@ namespace android { enum { DISCONNECT = IBinder::FIRST_CALL_TRANSACTION, SET_PREVIEW_TEXTURE, SET_PREVIEW_TARGET, SET_PREVIEW_CALLBACK_FLAG, SET_PREVIEW_CALLBACK_TARGET, START_PREVIEW, STOP_PREVIEW, AUTO_FOCUS, Loading Loading @@ -65,17 +66,18 @@ public: Parcel data, reply; data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); remote()->transact(DISCONNECT, data, &reply); reply.readExceptionCode(); } // pass the buffered IGraphicBufferProducer to the camera service status_t setPreviewTexture(const sp<IGraphicBufferProducer>& bufferProducer) status_t setPreviewTarget(const sp<IGraphicBufferProducer>& bufferProducer) { ALOGV("setPreviewTexture"); ALOGV("setPreviewTarget"); Parcel data, reply; data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); sp<IBinder> b(bufferProducer->asBinder()); data.writeStrongBinder(b); remote()->transact(SET_PREVIEW_TEXTURE, data, &reply); remote()->transact(SET_PREVIEW_TARGET, data, &reply); return reply.readInt32(); } Loading @@ -90,7 +92,19 @@ public: remote()->transact(SET_PREVIEW_CALLBACK_FLAG, data, &reply); } // start preview mode, must call setPreviewDisplay first status_t setPreviewCallbackTarget( const sp<IGraphicBufferProducer>& callbackProducer) { ALOGV("setPreviewCallbackTarget"); Parcel data, reply; data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); sp<IBinder> b(callbackProducer->asBinder()); data.writeStrongBinder(b); remote()->transact(SET_PREVIEW_CALLBACK_TARGET, data, &reply); return reply.readInt32(); } // start preview mode, must call setPreviewTarget first status_t startPreview() { ALOGV("startPreview"); Loading @@ -100,7 +114,7 @@ public: return reply.readInt32(); } // start recording mode, must call setPreviewDisplay first // start recording mode, must call setPreviewTarget first status_t startRecording() { ALOGV("startRecording"); Loading Loading @@ -268,14 +282,15 @@ status_t BnCamera::onTransact( ALOGV("DISCONNECT"); CHECK_INTERFACE(ICamera, data, reply); disconnect(); reply->writeNoException(); return NO_ERROR; } break; case SET_PREVIEW_TEXTURE: { ALOGV("SET_PREVIEW_TEXTURE"); case SET_PREVIEW_TARGET: { ALOGV("SET_PREVIEW_TARGET"); CHECK_INTERFACE(ICamera, data, reply); sp<IGraphicBufferProducer> st = interface_cast<IGraphicBufferProducer>(data.readStrongBinder()); reply->writeInt32(setPreviewTexture(st)); reply->writeInt32(setPreviewTarget(st)); return NO_ERROR; } break; case SET_PREVIEW_CALLBACK_FLAG: { Loading @@ -285,6 +300,14 @@ status_t BnCamera::onTransact( setPreviewCallbackFlag(callback_flag); return NO_ERROR; } break; case SET_PREVIEW_CALLBACK_TARGET: { ALOGV("SET_PREVIEW_CALLBACK_TARGET"); CHECK_INTERFACE(ICamera, data, reply); sp<IGraphicBufferProducer> cp = interface_cast<IGraphicBufferProducer>(data.readStrongBinder()); reply->writeInt32(setPreviewCallbackTarget(cp)); return NO_ERROR; } case START_PREVIEW: { ALOGV("START_PREVIEW"); CHECK_INTERFACE(ICamera, data, reply); Loading Loading
camera/Android.mk +3 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,9 @@ LOCAL_SRC_FILES:= \ ICameraRecordingProxyListener.cpp \ IProCameraUser.cpp \ IProCameraCallbacks.cpp \ camera2/ICameraDeviceUser.cpp \ camera2/ICameraDeviceCallbacks.cpp \ camera2/CaptureRequest.cpp \ ProCamera.cpp \ CameraBase.cpp \ Loading
camera/Camera.cpp +15 −4 Original line number Diff line number Diff line Loading @@ -39,6 +39,9 @@ Camera::Camera(int cameraId) { } CameraTraits<Camera>::TCamConnectService CameraTraits<Camera>::fnConnectService = &ICameraService::connect; // construct a camera client from an existing camera remote sp<Camera> Camera::create(const sp<ICamera>& camera) { Loading Loading @@ -97,13 +100,13 @@ status_t Camera::unlock() } // pass the buffered IGraphicBufferProducer to the camera service status_t Camera::setPreviewTexture(const sp<IGraphicBufferProducer>& bufferProducer) status_t Camera::setPreviewTarget(const sp<IGraphicBufferProducer>& bufferProducer) { ALOGV("setPreviewTexture(%p)", bufferProducer.get()); ALOGV("setPreviewTarget(%p)", bufferProducer.get()); sp <ICamera> c = mCamera; if (c == 0) return NO_INIT; ALOGD_IF(bufferProducer == 0, "app passed NULL surface"); return c->setPreviewTexture(bufferProducer); return c->setPreviewTarget(bufferProducer); } // start preview mode Loading @@ -124,7 +127,7 @@ status_t Camera::storeMetaDataInBuffers(bool enabled) return c->storeMetaDataInBuffers(enabled); } // start recording mode, must call setPreviewDisplay first // start recording mode, must call setPreviewTarget first status_t Camera::startRecording() { ALOGV("startRecording"); Loading Loading @@ -255,6 +258,14 @@ void Camera::setPreviewCallbackFlags(int flag) mCamera->setPreviewCallbackFlag(flag); } status_t Camera::setPreviewCallbackTarget( const sp<IGraphicBufferProducer>& callbackProducer) { sp <ICamera> c = mCamera; if (c == 0) return NO_INIT; return c->setPreviewCallbackTarget(callbackProducer); } // callback from camera service void Camera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2) { Loading
camera/CameraBase.cpp +8 −3 Original line number Diff line number Diff line Loading @@ -98,14 +98,19 @@ sp<TCam> CameraBase<TCam, TCamTraits>::connect(int cameraId, ALOGV("%s: connect", __FUNCTION__); sp<TCam> c = new TCam(cameraId); sp<TCamCallbacks> cl = c; status_t status = NO_ERROR; const sp<ICameraService>& cs = getCameraService(); if (cs != 0) { c->mCamera = cs->connect(cl, cameraId, clientPackageName, clientUid); TCamConnectService fnConnectService = TCamTraits::fnConnectService; status = (cs.get()->*fnConnectService)(cl, cameraId, clientPackageName, clientUid, /*out*/ c->mCamera); } if (c->mCamera != 0) { if (status == OK && c->mCamera != 0) { c->mCamera->asBinder()->linkToDeath(c); c->mStatus = NO_ERROR; } else { ALOGW("An error occurred while connecting to camera: %d", cameraId); c.clear(); } return c; Loading
camera/CameraMetadata.cpp +175 −0 Original line number Diff line number Diff line Loading @@ -21,9 +21,13 @@ #include <utils/Errors.h> #include <camera/CameraMetadata.h> #include <binder/Parcel.h> namespace android { typedef Parcel::WritableBlob WritableBlob; typedef Parcel::ReadableBlob ReadableBlob; CameraMetadata::CameraMetadata() : mBuffer(NULL), mLocked(false) { } Loading Loading @@ -408,4 +412,175 @@ status_t CameraMetadata::resizeIfNeeded(size_t extraEntries, size_t extraData) { return OK; } status_t CameraMetadata::readFromParcel(const Parcel& data, camera_metadata_t** out) { status_t err = OK; camera_metadata_t* metadata = NULL; if (out) { *out = NULL; } // arg0 = metadataSize (int32) int32_t metadataSizeTmp = -1; if ((err = data.readInt32(&metadataSizeTmp)) != OK) { ALOGE("%s: Failed to read metadata size (error %d %s)", __FUNCTION__, err, strerror(-err)); return err; } const size_t metadataSize = static_cast<size_t>(metadataSizeTmp); if (metadataSize == 0) { ALOGV("%s: Read 0-sized metadata", __FUNCTION__); return OK; } // NOTE: this doesn't make sense to me. shouldnt the blob // know how big it is? why do we have to specify the size // to Parcel::readBlob ? ReadableBlob blob; // arg1 = metadata (blob) do { if ((err = data.readBlob(metadataSize, &blob)) != OK) { ALOGE("%s: Failed to read metadata blob (sized %d). Possible " " serialization bug. Error %d %s", __FUNCTION__, metadataSize, err, strerror(-err)); break; } const camera_metadata_t* tmp = reinterpret_cast<const camera_metadata_t*>(blob.data()); metadata = allocate_copy_camera_metadata_checked(tmp, metadataSize); if (metadata == NULL) { // We consider that allocation only fails if the validation // also failed, therefore the readFromParcel was a failure. err = BAD_VALUE; } } while(0); blob.release(); if (out) { ALOGV("%s: Set out metadata to %p", __FUNCTION__, metadata); *out = metadata; } else if (metadata != NULL) { ALOGV("%s: Freed camera metadata at %p", __FUNCTION__, metadata); free_camera_metadata(metadata); } return err; } status_t CameraMetadata::writeToParcel(Parcel& data, const camera_metadata_t* metadata) { status_t res = OK; // arg0 = metadataSize (int32) if (metadata == NULL) { return data.writeInt32(0); } const size_t metadataSize = get_camera_metadata_compact_size(metadata); res = data.writeInt32(static_cast<int32_t>(metadataSize)); if (res != OK) { return res; } // arg1 = metadata (blob) WritableBlob blob; do { res = data.writeBlob(metadataSize, &blob); if (res != OK) { break; } copy_camera_metadata(blob.data(), metadataSize, metadata); IF_ALOGV() { if (validate_camera_metadata_structure( (const camera_metadata_t*)blob.data(), &metadataSize) != OK) { ALOGV("%s: Failed to validate metadata %p after writing blob", __FUNCTION__, blob.data()); } else { ALOGV("%s: Metadata written to blob. Validation success", __FUNCTION__); } } // Not too big of a problem since receiving side does hard validation // Don't check the size since the compact size could be larger if (validate_camera_metadata_structure(metadata, /*size*/NULL) != OK) { ALOGW("%s: Failed to validate metadata %p before writing blob", __FUNCTION__, metadata); } } while(false); blob.release(); return res; } status_t CameraMetadata::readFromParcel(Parcel *parcel) { ALOGV("%s: parcel = %p", __FUNCTION__, parcel); status_t res = OK; if (parcel == NULL) { ALOGE("%s: parcel is null", __FUNCTION__); return BAD_VALUE; } if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return INVALID_OPERATION; } camera_metadata *buffer = NULL; // TODO: reading should return a status code, in case validation fails res = CameraMetadata::readFromParcel(*parcel, &buffer); if (res != NO_ERROR) { ALOGE("%s: Failed to read from parcel. Metadata is unchanged.", __FUNCTION__); return res; } clear(); mBuffer = buffer; return OK; } status_t CameraMetadata::writeToParcel(Parcel *parcel) const { ALOGV("%s: parcel = %p", __FUNCTION__, parcel); if (parcel == NULL) { ALOGE("%s: parcel is null", __FUNCTION__); return BAD_VALUE; } return CameraMetadata::writeToParcel(*parcel, mBuffer); } void CameraMetadata::swap(CameraMetadata& other) { if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return; } else if (other.mLocked) { ALOGE("%s: Other CameraMetadata is locked", __FUNCTION__); return; } camera_metadata* thisBuf = mBuffer; camera_metadata* otherBuf = other.mBuffer; other.mBuffer = thisBuf; mBuffer = otherBuf; } }; // namespace android
camera/ICamera.cpp +32 −9 Original line number Diff line number Diff line Loading @@ -29,8 +29,9 @@ namespace android { enum { DISCONNECT = IBinder::FIRST_CALL_TRANSACTION, SET_PREVIEW_TEXTURE, SET_PREVIEW_TARGET, SET_PREVIEW_CALLBACK_FLAG, SET_PREVIEW_CALLBACK_TARGET, START_PREVIEW, STOP_PREVIEW, AUTO_FOCUS, Loading Loading @@ -65,17 +66,18 @@ public: Parcel data, reply; data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); remote()->transact(DISCONNECT, data, &reply); reply.readExceptionCode(); } // pass the buffered IGraphicBufferProducer to the camera service status_t setPreviewTexture(const sp<IGraphicBufferProducer>& bufferProducer) status_t setPreviewTarget(const sp<IGraphicBufferProducer>& bufferProducer) { ALOGV("setPreviewTexture"); ALOGV("setPreviewTarget"); Parcel data, reply; data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); sp<IBinder> b(bufferProducer->asBinder()); data.writeStrongBinder(b); remote()->transact(SET_PREVIEW_TEXTURE, data, &reply); remote()->transact(SET_PREVIEW_TARGET, data, &reply); return reply.readInt32(); } Loading @@ -90,7 +92,19 @@ public: remote()->transact(SET_PREVIEW_CALLBACK_FLAG, data, &reply); } // start preview mode, must call setPreviewDisplay first status_t setPreviewCallbackTarget( const sp<IGraphicBufferProducer>& callbackProducer) { ALOGV("setPreviewCallbackTarget"); Parcel data, reply; data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); sp<IBinder> b(callbackProducer->asBinder()); data.writeStrongBinder(b); remote()->transact(SET_PREVIEW_CALLBACK_TARGET, data, &reply); return reply.readInt32(); } // start preview mode, must call setPreviewTarget first status_t startPreview() { ALOGV("startPreview"); Loading @@ -100,7 +114,7 @@ public: return reply.readInt32(); } // start recording mode, must call setPreviewDisplay first // start recording mode, must call setPreviewTarget first status_t startRecording() { ALOGV("startRecording"); Loading Loading @@ -268,14 +282,15 @@ status_t BnCamera::onTransact( ALOGV("DISCONNECT"); CHECK_INTERFACE(ICamera, data, reply); disconnect(); reply->writeNoException(); return NO_ERROR; } break; case SET_PREVIEW_TEXTURE: { ALOGV("SET_PREVIEW_TEXTURE"); case SET_PREVIEW_TARGET: { ALOGV("SET_PREVIEW_TARGET"); CHECK_INTERFACE(ICamera, data, reply); sp<IGraphicBufferProducer> st = interface_cast<IGraphicBufferProducer>(data.readStrongBinder()); reply->writeInt32(setPreviewTexture(st)); reply->writeInt32(setPreviewTarget(st)); return NO_ERROR; } break; case SET_PREVIEW_CALLBACK_FLAG: { Loading @@ -285,6 +300,14 @@ status_t BnCamera::onTransact( setPreviewCallbackFlag(callback_flag); return NO_ERROR; } break; case SET_PREVIEW_CALLBACK_TARGET: { ALOGV("SET_PREVIEW_CALLBACK_TARGET"); CHECK_INTERFACE(ICamera, data, reply); sp<IGraphicBufferProducer> cp = interface_cast<IGraphicBufferProducer>(data.readStrongBinder()); reply->writeInt32(setPreviewCallbackTarget(cp)); return NO_ERROR; } case START_PREVIEW: { ALOGV("START_PREVIEW"); CHECK_INTERFACE(ICamera, data, reply); Loading