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

Commit 23307f73 authored by Zhijun He's avatar Zhijun He Committed by Android (Google) Code Review
Browse files

Merge "cameraservice: Implement HAL1 and higher HAL API coexistence"

parents 884989c6 b10cdadf
Loading
Loading
Loading
Loading
+26 −0
Original line number Diff line number Diff line
@@ -77,6 +77,32 @@ sp<Camera> Camera::connect(int cameraId, const String16& clientPackageName,
    return CameraBaseT::connect(cameraId, clientPackageName, clientUid);
}

status_t Camera::connectLegacy(int cameraId, int halVersion,
        const String16& clientPackageName,
        int clientUid,
        sp<Camera>& camera)
{
    ALOGV("%s: connect legacy camera device", __FUNCTION__);
    sp<Camera> c = new Camera(cameraId);
    sp<ICameraClient> cl = c;
    status_t status = NO_ERROR;
    const sp<ICameraService>& cs = CameraBaseT::getCameraService();

    if (cs != 0) {
        status = cs.get()->connectLegacy(cl, cameraId, halVersion, clientPackageName,
                                        clientUid, /*out*/c->mCamera);
    }
    if (status == OK && c->mCamera != 0) {
        c->mCamera->asBinder()->linkToDeath(c);
        c->mStatus = NO_ERROR;
        camera = c;
    } else {
        ALOGW("An error occurred while connecting to camera: %d", cameraId);
        c.clear();
    }
    return status;
}

status_t Camera::reconnect()
{
    ALOGV("reconnect");
+44 −0
Original line number Diff line number Diff line
@@ -186,6 +186,29 @@ public:
        return status;
    }

    // connect to camera service (android.hardware.Camera)
    virtual status_t connectLegacy(const sp<ICameraClient>& cameraClient, int cameraId,
                             int halVersion,
                             const String16 &clientPackageName, int clientUid,
                             /*out*/sp<ICamera>& device)
    {
        Parcel data, reply;
        data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
        data.writeStrongBinder(cameraClient->asBinder());
        data.writeInt32(cameraId);
        data.writeInt32(halVersion);
        data.writeString16(clientPackageName);
        data.writeInt32(clientUid);
        remote()->transact(BnCameraService::CONNECT_LEGACY, data, &reply);

        if (readExceptionCode(reply)) return -EPROTO;
        status_t status = reply.readInt32();
        if (reply.readInt32() != 0) {
            device = interface_cast<ICamera>(reply.readStrongBinder());
        }
        return status;
    }

    // connect to camera service (pro client)
    virtual status_t connectPro(const sp<IProCameraCallbacks>& cameraCb, int cameraId,
                                const String16 &clientPackageName, int clientUid,
@@ -446,6 +469,27 @@ status_t BnCameraService::onTransact(
            reply->writeInt32(supportsCameraApi(cameraId, apiVersion));
            return NO_ERROR;
        } break;
        case CONNECT_LEGACY: {
            CHECK_INTERFACE(ICameraService, data, reply);
            sp<ICameraClient> cameraClient =
                    interface_cast<ICameraClient>(data.readStrongBinder());
            int32_t cameraId = data.readInt32();
            int32_t halVersion = data.readInt32();
            const String16 clientName = data.readString16();
            int32_t clientUid = data.readInt32();
            sp<ICamera> camera;
            status_t status = connectLegacy(cameraClient, cameraId, halVersion,
                    clientName, clientUid, /*out*/camera);
            reply->writeNoException();
            reply->writeInt32(status);
            if (camera != NULL) {
                reply->writeInt32(1);
                reply->writeStrongBinder(camera->asBinder());
            } else {
                reply->writeInt32(0);
            }
            return NO_ERROR;
        } break;
        default:
            return BBinder::onTransact(code, data, reply, flags);
    }
+4 −0
Original line number Diff line number Diff line
@@ -74,6 +74,10 @@ public:
                                const String16& clientPackageName,
                                int clientUid);

    static  status_t  connectLegacy(int cameraId, int halVersion,
                                     const String16& clientPackageName,
                                     int clientUid, sp<Camera>& camera);

            virtual     ~Camera();

            status_t    reconnect();
+17 −0
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ public:
        GET_CAMERA_VENDOR_TAG_DESCRIPTOR,
        GET_LEGACY_PARAMETERS,
        SUPPORTS_CAMERA_API,
        CONNECT_LEGACY,
    };

    enum {
@@ -63,6 +64,10 @@ public:
        API_VERSION_2 = 2,
    };

    enum {
        CAMERA_HAL_API_VERSION_UNSPECIFIED = -1
      };

public:
    DECLARE_META_INTERFACE(CameraService);

@@ -125,6 +130,18 @@ public:
     */
    virtual status_t supportsCameraApi(
            int cameraId, int apiVersion) = 0;

    /**
     * Connect the device as a legacy device for a given HAL version.
     * For halVersion, use CAMERA_API_DEVICE_VERSION_* for a particular
     * version, or CAMERA_HAL_API_VERSION_UNSPECIFIED for a service-selected version.
     */
    virtual status_t connectLegacy(const sp<ICameraClient>& cameraClient,
            int cameraId, int halVersion,
            const String16& clientPackageName,
            int clientUid,
            /*out*/
            sp<ICamera>& device) = 0;
};

// ----------------------------------------------------------------------------
+102 −23
Original line number Diff line number Diff line
@@ -659,7 +659,8 @@ status_t CameraService::connectHelperLocked(const sp<ICameraClient>& cameraClien
                                      int clientUid,
                                      int callingPid,
                                      /*out*/
                                      sp<Client>& client) {
                                      sp<Client>& client,
                                      int halVersion) {

    int facing = -1;
    int deviceVersion = getDeviceVersion(cameraId, &facing);
@@ -672,6 +673,9 @@ status_t CameraService::connectHelperLocked(const sp<ICameraClient>& cameraClien
                     cameraId);
    }

    if (halVersion < 0 || halVersion == deviceVersion) {
        // Default path: HAL version is unspecified by caller, create CameraClient
        // based on device version reported by the HAL.
        switch(deviceVersion) {
          case CAMERA_DEVICE_API_VERSION_1_0:
            client = new CameraClient(this, cameraClient,
@@ -695,6 +699,23 @@ status_t CameraService::connectHelperLocked(const sp<ICameraClient>& cameraClien
            ALOGE("Unknown camera device HAL version: %d", deviceVersion);
            return INVALID_OPERATION;
        }
    } else {
        // A particular HAL version is requested by caller. Create CameraClient
        // based on the requested HAL version.
        if (deviceVersion > CAMERA_DEVICE_API_VERSION_1_0 &&
            halVersion == CAMERA_DEVICE_API_VERSION_1_0) {
            // Only support higher HAL version device opened as HAL1.0 device.
            client = new CameraClient(this, cameraClient,
                    clientPackageName, cameraId,
                    facing, callingPid, clientUid, getpid());
        } else {
            // Other combinations (e.g. HAL3.x open as HAL2.x) are not supported yet.
            ALOGE("Invalid camera HAL version %x: HAL %x device can only be"
                    " opened as HAL %x device", halVersion, deviceVersion,
                    CAMERA_DEVICE_API_VERSION_1_0);
            return INVALID_OPERATION;
        }
    }

    status_t status = connectFinishUnsafe(client, client->getRemote());
    if (status != OK) {
@@ -762,6 +783,63 @@ status_t CameraService::connect(
    return OK;
}

status_t CameraService::connectLegacy(
        const sp<ICameraClient>& cameraClient,
        int cameraId, int halVersion,
        const String16& clientPackageName,
        int clientUid,
        /*out*/
        sp<ICamera>& device) {

    if (mModule->common.module_api_version < CAMERA_MODULE_API_VERSION_2_3) {
        ALOGE("%s: camera HAL module version %x doesn't support connecting to legacy HAL devices!",
                __FUNCTION__, mModule->common.module_api_version);
        return INVALID_OPERATION;
    }

    String8 clientName8(clientPackageName);
    int callingPid = getCallingPid();

    LOG1("CameraService::connect legacy E (pid %d \"%s\", id %d)", callingPid,
            clientName8.string(), cameraId);

    status_t status = validateConnect(cameraId, /*inout*/clientUid);
    if (status != OK) {
        return status;
    }

    sp<Client> client;
    {
        Mutex::Autolock lock(mServiceLock);
        sp<BasicClient> clientTmp;
        if (!canConnectUnsafe(cameraId, clientPackageName,
                              cameraClient->asBinder(),
                              /*out*/clientTmp)) {
            return -EBUSY;
        } else if (client.get() != NULL) {
            device = static_cast<Client*>(clientTmp.get());
            return OK;
        }

        status = connectHelperLocked(cameraClient,
                                     cameraId,
                                     clientPackageName,
                                     clientUid,
                                     callingPid,
                                     client,
                                     halVersion);
        if (status != OK) {
            return status;
        }

    }
    // important: release the mutex here so the client can call back
    //    into the service from its destructor (can be at the end of the call)

    device = client;
    return OK;
}

status_t CameraService::connectFinishUnsafe(const sp<BasicClient>& client,
                                            const sp<IBinder>& remoteCallback) {
    status_t status = client->initialize(mModule);
@@ -1196,6 +1274,7 @@ status_t CameraService::onTransact(
        case BnCameraService::CONNECT:
        case BnCameraService::CONNECT_PRO:
        case BnCameraService::CONNECT_DEVICE:
        case BnCameraService::CONNECT_LEGACY:
            const int pid = getCallingPid();
            const int self_pid = getpid();
            if (pid != self_pid) {
Loading