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

Commit 94f79a96 authored by Jayant Chowdhary's avatar Jayant Chowdhary
Browse files

cameraserver: Implement AIDL wrapper class for HIDL ICameraServiceListener.



Bug: 110364143

Test: (build) mm -j64

Change-Id: Ibf1da18d0fac5ddaab5da8df52c4183b3aaadbfc
Signed-off-by: default avatarJayant Chowdhary <jchowdhary@google.com>
parent be543d41
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ cc_library_shared {
        "device3/DistortionMapper.cpp",
        "gui/RingBufferConsumer.cpp",
        "utils/CameraThreadState.cpp",
        "hidl/AidlCameraServiceListener.cpp",
        "hidl/HidlCameraService.cpp",
        "hidl/Convert.cpp",
        "utils/CameraTraces.cpp",
+54 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <hidl/AidlCameraServiceListener.h>
#include <hidl/Convert.h>

namespace android {
namespace frameworks {
namespace cameraservice {
namespace service {
namespace V2_0 {
namespace implementation {

using hardware::cameraservice::utils::conversion::convertToHidlCameraDeviceStatus;

binder::Status H2BCameraServiceListener::onStatusChanged(
    int32_t status, const ::android::String16& cameraId) {
  HCameraDeviceStatus hCameraDeviceStatus = convertToHidlCameraDeviceStatus(status);
  CameraStatusAndId cameraStatusAndId;
  cameraStatusAndId.deviceStatus = hCameraDeviceStatus;
  cameraStatusAndId.cameraId = String8(cameraId).string();
  auto ret = mBase->onStatusChanged(cameraStatusAndId);
  if (!ret.isOk()) {
      ALOGE("%s OnStatusChanged callback failed due to %s",__FUNCTION__,
            ret.description().c_str());
  }
  return binder::Status::ok();
}

::android::binder::Status H2BCameraServiceListener::onTorchStatusChanged(
    int32_t, const ::android::String16&) {
  // We don't implement onTorchStatusChanged
  return binder::Status::ok();
}

} // implementation
} // V2_0
} // common
} // cameraservice
} // frameworks
} // android
+60 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <mutex>
#include <thread>

#include <android/frameworks/cameraservice/common/2.0/types.h>
#include <android/frameworks/cameraservice/service/2.0/ICameraServiceListener.h>
#include <android/frameworks/cameraservice/device/2.0/types.h>
#include <android/hardware/BnCameraServiceListener.h>
#include <android/hardware/BpCameraServiceListener.h>

#include <hidl/Status.h>
#include <hidl/CameraHybridInterface.h>

namespace android {
namespace frameworks {
namespace cameraservice {
namespace service {
namespace V2_0 {
namespace implementation {

using hardware::BnCameraServiceListener;
using hardware::BpCameraServiceListener;
using camerahybrid::H2BConverter;
using HCameraDeviceStatus = frameworks::cameraservice::service::V2_0::CameraDeviceStatus;
typedef frameworks::cameraservice::service::V2_0::ICameraServiceListener HCameraServiceListener;

struct H2BCameraServiceListener :
    public H2BConverter<HCameraServiceListener, ICameraServiceListener, BnCameraServiceListener> {
    H2BCameraServiceListener(const sp<HalInterface>& base) : CBase(base) { }

    ~H2BCameraServiceListener() { }

    virtual ::android::binder::Status onStatusChanged(int32_t status,
                                                      const ::android::String16& cameraId) override;

    virtual ::android::binder::Status onTorchStatusChanged(
        int32_t status, const ::android::String16& cameraId) override;
};

} // implementation
} // V2_0
} // service
} // cameraservice
} // frameworks
} // android
+138 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ANDROID_CAMERA_HYBRIDINTERFACE_H
#define ANDROID_CAMERA_HYBRIDINTERFACE_H

#include <vector>
#include <mutex>

#include <binder/Parcel.h>
#include <hidl/HidlSupport.h>

namespace android {
namespace camerahybrid {
typedef ::android::hidl::base::V1_0::IBase HInterface;

template <
        typename HINTERFACE,
        typename INTERFACE,
        typename BNINTERFACE >
class H2BConverter : public BNINTERFACE {
public:
    typedef H2BConverter<HINTERFACE, INTERFACE, BNINTERFACE> CBase; // Converter Base
    typedef INTERFACE BaseInterface;
    typedef HINTERFACE HalInterface;

    H2BConverter(const sp<HalInterface>& base) : mBase(base) {}
    virtual sp<HalInterface> getHalInterface() { return mBase; }
    virtual status_t linkToDeath(
            const sp<IBinder::DeathRecipient>& recipient,
            void* cookie = nullptr,
            uint32_t flags = 0);
    virtual status_t unlinkToDeath(
            const wp<IBinder::DeathRecipient>& recipient,
            void* cookie = nullptr,
            uint32_t flags = 0,
            wp<IBinder::DeathRecipient>* outRecipient = nullptr);

protected:
    sp<HalInterface> mBase;
    struct Obituary : public hardware::hidl_death_recipient {
        wp<IBinder::DeathRecipient> recipient;
        void* cookie;
        uint32_t flags;
        wp<IBinder> who;
        Obituary(
                const wp<IBinder::DeathRecipient>& r,
                void* c, uint32_t f,
                const wp<IBinder>& w) :
            recipient(r), cookie(c), flags(f), who(w) {
        }
        Obituary(const Obituary& o) :
            recipient(o.recipient),
            cookie(o.cookie),
            flags(o.flags),
            who(o.who) {
        }
        Obituary& operator=(const Obituary& o) {
            recipient = o.recipient;
            cookie = o.cookie;
            flags = o.flags;
            who = o.who;
            return *this;
        }
        void serviceDied(uint64_t, const wp<HInterface>&) override {
            sp<IBinder::DeathRecipient> dr = recipient.promote();
            if (dr != nullptr) {
                dr->binderDied(who);
            }
        }
    };
    std::mutex mObituariesLock;
    std::vector<sp<Obituary> > mObituaries;
};

template <
        typename HINTERFACE,
        typename INTERFACE,
        typename BNINTERFACE>
status_t H2BConverter<HINTERFACE, INTERFACE, BNINTERFACE>::
        linkToDeath(
        const sp<IBinder::DeathRecipient>& recipient,
        void* cookie, uint32_t flags) {
    LOG_ALWAYS_FATAL_IF(recipient == nullptr,
            "linkToDeath(): recipient must be non-nullptr");
    {
        std::lock_guard<std::mutex> lock(mObituariesLock);
        mObituaries.push_back(new Obituary(recipient, cookie, flags, this));
        if (!mBase->linkToDeath(mObituaries.back(), 0)) {
           return DEAD_OBJECT;
        }
    }
    return NO_ERROR;
}

template <
        typename HINTERFACE,
        typename INTERFACE,
        typename BNINTERFACE>
status_t H2BConverter<HINTERFACE, INTERFACE, BNINTERFACE>::
        unlinkToDeath(
        const wp<IBinder::DeathRecipient>& recipient,
        void* cookie, uint32_t flags,
        wp<IBinder::DeathRecipient>* outRecipient) {
    std::lock_guard<std::mutex> lock(mObituariesLock);
    for (auto i = mObituaries.begin(); i != mObituaries.end(); ++i) {
        if ((flags = (*i)->flags) && (
                (recipient == (*i)->recipient) ||
                ((recipient == nullptr) && (cookie == (*i)->cookie)))) {
            if (outRecipient != nullptr) {
                *outRecipient = (*i)->recipient;
            }
            bool success = mBase->unlinkToDeath(*i);
            mObituaries.erase(i);
            return success ? NO_ERROR : DEAD_OBJECT;
        }
    }
    return NAME_NOT_FOUND;
}

} // namespace camerahybrid
} // namespace android

#endif // ANDROID_CAMERA_HYBRIDINTERFACE_H
+79 −4
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include <hidl/Convert.h>

#include <hidl/HidlCameraService.h>
#include <hidl/AidlCameraServiceListener.h>

#include <hidl/HidlTransportSupport.h>

@@ -33,6 +34,7 @@ using hardware::cameraservice::utils::conversion::convertToHidl;
using hardware::cameraservice::utils::conversion::B2HStatus;
using hardware::Void;

using service::V2_0::implementation::H2BCameraServiceListener;
using HCameraMetadataType = android::frameworks::cameraservice::common::V2_0::CameraMetadataType;
using HVendorTag = android::frameworks::cameraservice::common::V2_0::VendorTag;
using HVendorTagSection = android::frameworks::cameraservice::common::V2_0::VendorTagSection;
@@ -85,12 +87,74 @@ Return<void> HidlCameraService::connectDevice(const sp<HCameraDeviceCallback>& h
    return Void();
}

void HidlCameraService::addToListenerCacheLocked(sp<HCameraServiceListener> hListener,
                                                 sp<hardware::ICameraServiceListener> csListener) {
        mListeners.emplace_back(std::make_pair(hListener, csListener));
}

sp<hardware::ICameraServiceListener>
HidlCameraService::searchListenerCacheLocked(sp<HCameraServiceListener> hListener,
                                             bool shouldRemove) {
    // Go through the mListeners list and compare the listener with the HIDL
    // listener registered.
    auto it = mListeners.begin();
    sp<ICameraServiceListener> csListener = nullptr;
    for (;it != mListeners.end(); it++) {
        if (hardware::interfacesEqual(it->first, hListener)) {
            break;
        }
    }
    if (it != mListeners.end()) {
        csListener = it->second;
        if (shouldRemove) {
          mListeners.erase(it);
        }
    }
    return csListener;
}

Return<void> HidlCameraService::addListener(const sp<HCameraServiceListener>& hCsListener,
                                            addListener_cb _hidl_cb) {
    // To silence Wunused-parameter.
    (void)hCsListener;
    (void)_hidl_cb;

    if (mAidlICameraService == nullptr) {
        _hidl_cb(HStatus::UNKNOWN_ERROR, {});
        return Void();
    }
    if (hCsListener == nullptr) {
        ALOGE("%s listener must not be NULL", __FUNCTION__);
        _hidl_cb(HStatus::ILLEGAL_ARGUMENT, {});
        return Void();
    }
    sp<hardware::ICameraServiceListener> csListener = nullptr;
    // Check the cache for previously registered callbacks
    {
        Mutex::Autolock l(mListenerListLock);
        csListener = searchListenerCacheLocked(hCsListener);
        if (csListener == nullptr) {
            // Wrap an hCsListener with AidlCameraServiceListener and pass it to
            // CameraService.
            csListener = new H2BCameraServiceListener(hCsListener);
            // Add to cache
            addToListenerCacheLocked(hCsListener, csListener);
        } else {
            ALOGE("%s: Trying to add a listener %p already registered",
                  __FUNCTION__, hCsListener.get());
            _hidl_cb(HStatus::ILLEGAL_ARGUMENT, {});
            return Void();
        }
    }
    std::vector<hardware::CameraStatus> cameraStatusAndIds{};
    binder::Status serviceRet = mAidlICameraService->addListener(csListener, &cameraStatusAndIds);
    HStatus status = HStatus::NO_ERROR;
    if (!serviceRet.isOk()) {
      ALOGE("%s: Unable to add camera device status listener", __FUNCTION__);
      status = B2HStatus(serviceRet);
      _hidl_cb(status, {});
      return Void();
    }
    hidl_vec<HCameraStatusAndId> hCameraStatusAndIds;
    //Convert cameraStatusAndIds to HIDL and call callback
    convertToHidl(cameraStatusAndIds, &hCameraStatusAndIds);
    _hidl_cb(status, hCameraStatusAndIds);
    return Void();
}

@@ -99,6 +163,17 @@ Return<HStatus> HidlCameraService::removeListener(const sp<HCameraServiceListene
        ALOGE("%s listener must not be NULL", __FUNCTION__);
        return HStatus::ILLEGAL_ARGUMENT;
    }
    sp<ICameraServiceListener> csListener = nullptr;
    {
        Mutex::Autolock l(mListenerListLock);
        csListener = searchListenerCacheLocked(hCsListener, /*removeIfFound*/true);
    }
    if (csListener != nullptr) {
          mAidlICameraService->removeListener(csListener);
    } else {
        ALOGE("%s Removing unregistered listener %p", __FUNCTION__, hCsListener.get());
        return HStatus::ILLEGAL_ARGUMENT;
    }
    return HStatus::NO_ERROR;
}

Loading