Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5bf2560c authored by The Android Open Source Project's avatar The Android Open Source Project
Browse files

Merge commit 'b2059ff3' into HEAD

parents eb76f318 b2059ff3
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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 \

+15 −4
Original line number Diff line number Diff line
@@ -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)
{
@@ -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
@@ -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");
@@ -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)
{
+8 −3
Original line number Diff line number Diff line
@@ -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;
+175 −0
Original line number Diff line number Diff line
@@ -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) {
}
@@ -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
+32 −9
Original line number Diff line number Diff line
@@ -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,
@@ -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();
    }

@@ -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");
@@ -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");
@@ -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: {
@@ -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