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

Commit 507994d0 authored by Igor Murashkin's avatar Igor Murashkin
Browse files

Camera2: Don't promote weak IBinder ptrs to strong ones

The Binder driver does not support promoting weak pointers into strong
pointers. Occassionally the system would lock up when trying to do this
(when closing the camera app).

Bug: 7289040
Change-Id: I8bc0b5c48616bf0b7f4eed1878ad4994ee635871
parent 1daada32
Loading
Loading
Loading
Loading
+12 −10
Original line number Diff line number Diff line
@@ -227,7 +227,7 @@ void CameraService::removeClient(const sp<ICameraClient>& cameraClient) {
    Mutex::Autolock lock(mServiceLock);

    int outIndex;
    sp<Client> client = findClientUnsafe(cameraClient, outIndex);
    sp<Client> client = findClientUnsafe(cameraClient->asBinder(), outIndex);

    if (client != 0) {
        // Found our camera, clear and leave.
@@ -241,7 +241,7 @@ void CameraService::removeClient(const sp<ICameraClient>& cameraClient) {
}

sp<CameraService::Client> CameraService::findClientUnsafe(
                        const sp<ICameraClient>& cameraClient, int& outIndex) {
                        const wp<IBinder>& cameraClient, int& outIndex) {
    sp<Client> client;

    for (int i = 0; i < mNumberOfCameras; i++) {
@@ -260,7 +260,7 @@ sp<CameraService::Client> CameraService::findClientUnsafe(
            continue;
        }

        if (cameraClient->asBinder() == client->getCameraClient()->asBinder()) {
        if (cameraClient == client->getCameraClient()->asBinder()) {
            // Found our camera
            outIndex = i;
            return client;
@@ -281,8 +281,8 @@ Mutex* CameraService::getClientLockById(int cameraId) {
    return &mClientLock[cameraId];
}

/*virtual*/sp<CameraService::Client> CameraService::getClientByRemote(
                                const sp<ICameraClient>& cameraClient) {
sp<CameraService::Client> CameraService::getClientByRemote(
                                const wp<IBinder>& cameraClient) {

    // Declare this before the lock to make absolutely sure the
    // destructor won't be called with the lock held.
@@ -557,18 +557,20 @@ status_t CameraService::dump(int fd, const Vector<String16>& args) {
/*virtual*/void CameraService::binderDied(
    const wp<IBinder> &who) {

    /**
      * While tempting to promote the wp<IBinder> into a sp,
      * it's actually not supported by the binder driver
      */

    ALOGV("java clients' binder died");

    sp<IBinder> whoStrong = who.promote();
    sp<Client> cameraClient = getClientByRemote(who);

    if (whoStrong == 0) {
    if (cameraClient == 0) {
        ALOGV("java clients' binder death already cleaned up (normal case)");
        return;
    }

    sp<ICameraClient> iCamClient = interface_cast<ICameraClient>(whoStrong);

    sp<Client> cameraClient = getClientByRemote(iCamClient);
    ALOGW("Disconnecting camera client %p since the binder for it "
          "died (this pid %d)", cameraClient.get(), getCallingPid());

+2 −2
Original line number Diff line number Diff line
@@ -55,7 +55,7 @@ public:
    virtual Client*     getClientByIdUnsafe(int cameraId);
    virtual Mutex*      getClientLockById(int cameraId);

    virtual sp<Client>  getClientByRemote(const sp<ICameraClient>& cameraClient);
    virtual sp<Client>  getClientByRemote(const wp<IBinder>& cameraClient);

    virtual status_t    dump(int fd, const Vector<String16>& args);
    virtual status_t    onTransact(uint32_t code, const Parcel& data,
@@ -143,7 +143,7 @@ private:
    int                 mNumberOfCameras;

    // needs to be called with mServiceLock held
    sp<Client>          findClientUnsafe(const sp<ICameraClient>& cameraClient, int& outIndex);
    sp<Client>          findClientUnsafe(const wp<IBinder>& cameraClient, int& outIndex);

    // atomics to record whether the hardware is allocated to some client.
    volatile int32_t    mBusy[MAX_CAMERAS];