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

Commit 7f7ab67a authored by Ravneet Dhanjal's avatar Ravneet Dhanjal
Browse files

cameraserver: Abort camera HAL when cameraservicewatchdog fires

- Abort the camera HAL from the cameraserver when the watchdog
fires to enable creation of a HAL tombstone for debugging

Bug: 349652177
Flag: com.android.internal.camera.flags.enable_hal_abort_from_cameraservicewatchdog
Test: Camera CTS test; Manual triggering of cameraservicewatchdog to
check for creation of HAL tombstone

Change-Id: I134d44e42b6d8ba7583193a39313b8bc08fc980b
parent ecc7ff83
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -17,11 +17,14 @@
#define LOG_TAG "CameraServiceWatchdog"

#include "CameraServiceWatchdog.h"
#include "com_android_internal_camera_flags.h"
#include "android/set_abort_message.h"
#include "utils/CameraServiceProxyWrapper.h"

namespace android {

namespace flags = com::android::internal::camera::flags;

bool CameraServiceWatchdog::threadLoop()
{
    {
@@ -51,6 +54,12 @@ bool CameraServiceWatchdog::threadLoop()
                        true /*deviceError*/);
                // We use abort here so we can get a tombstone for better
                // debugging.
                if (flags::enable_hal_abort_from_cameraservicewatchdog()) {
                    for (pid_t pid : mProviderPids) {
                        kill(pid, SIGABRT);
                    }
                }

                abort();
            }
        }
+10 −6
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@
 */
#pragma once
#include <chrono>
#include <set>
#include <thread>
#include <time.h>
#include <utils/Thread.h>
@@ -57,16 +58,17 @@ struct MonitoredFunction {
};

public:
    explicit CameraServiceWatchdog(const std::string &cameraId,

    explicit CameraServiceWatchdog(const std::set<pid_t> &pids, const std::string &cameraId,
            std::shared_ptr<CameraServiceProxyWrapper> cameraServiceProxyWrapper) :
                    mCameraId(cameraId), mPause(true), mMaxCycles(kMaxCycles),
                    mProviderPids(pids), mCameraId(cameraId), mPause(true), mMaxCycles(kMaxCycles),
                    mCycleLengthMs(kCycleLengthMs), mEnabled(true),
                    mCameraServiceProxyWrapper(cameraServiceProxyWrapper) {};

    explicit CameraServiceWatchdog (const std::string &cameraId, size_t maxCycles,
            uint32_t cycleLengthMs, bool enabled,
    explicit CameraServiceWatchdog (const std::set<pid_t> &pids, const std::string &cameraId,
            size_t maxCycles, uint32_t cycleLengthMs, bool enabled,
            std::shared_ptr<CameraServiceProxyWrapper> cameraServiceProxyWrapper) :
                    mCameraId(cameraId), mPause(true), mMaxCycles(maxCycles),
                    mProviderPids(pids), mCameraId(cameraId), mPause(true), mMaxCycles(maxCycles),
                    mCycleLengthMs(cycleLengthMs), mEnabled(enabled),
                    mCameraServiceProxyWrapper(cameraServiceProxyWrapper) {};

@@ -90,7 +92,8 @@ public:
            // Lock for mEnabled
            mEnabledLock.lock();
            sp<CameraServiceWatchdog> tempWatchdog = new CameraServiceWatchdog(
                    mCameraId, cycles, cycleLength, mEnabled, mCameraServiceProxyWrapper);
                    mProviderPids, mCameraId, cycles, cycleLength, mEnabled,
                    mCameraServiceProxyWrapper);
            mEnabledLock.unlock();

            status_t status = tempWatchdog->run("CameraServiceWatchdog");
@@ -150,6 +153,7 @@ private:
    Mutex           mWatchdogLock;      // Lock for condition variable
    Mutex           mEnabledLock;       // Lock for enabled status
    Condition       mWatchdogCondition; // Condition variable for stop/start
    std::set<pid_t> mProviderPids;      // Process ID set of camera providers
    std::string     mCameraId;          // Camera Id the watchdog belongs to
    bool            mPause;             // True if tid map is empty
    uint32_t        mMaxCycles;         // Max cycles
+52 −2
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@
#include <inttypes.h>
#include <android_companion_virtualdevice_flags.h>
#include <android_companion_virtualdevice_build_flags.h>
#include <android/binder_libbinder.h>
#include <android/binder_manager.h>
#include <android/hidl/manager/1.2/IServiceManager.h>
#include <hidl/ServiceManagement.h>
@@ -2135,7 +2136,19 @@ status_t CameraProviderManager::tryToInitializeAidlProviderLocked(
    }

    AidlProviderInfo *aidlProviderInfo = static_cast<AidlProviderInfo *>(providerInfo.get());
    return aidlProviderInfo->initializeAidlProvider(interface, mDeviceState);
    status_t res = aidlProviderInfo->initializeAidlProvider(interface, mDeviceState);

    if (flags::enable_hal_abort_from_cameraservicewatchdog()) {
        pid_t pid = 0;

        if (AIBinder_toPlatformBinder(interface->asBinder().get())->getDebugPid(&pid) == OK
                && res == OK) {
            std::lock_guard<std::mutex> lock(mProviderPidMapLock);
            mProviderPidMap[providerInfo->mProviderInstance] = pid;
        }
    }

    return res;
}

status_t CameraProviderManager::tryToInitializeHidlProviderLocked(
@@ -2152,7 +2165,23 @@ status_t CameraProviderManager::tryToInitializeHidlProviderLocked(
    }

    HidlProviderInfo *hidlProviderInfo = static_cast<HidlProviderInfo *>(providerInfo.get());
    return hidlProviderInfo->initializeHidlProvider(interface, mDeviceState);
    status_t res = hidlProviderInfo->initializeHidlProvider(interface, mDeviceState);

    if (flags::enable_hal_abort_from_cameraservicewatchdog()) {
        pid_t pid = 0;

        auto ret = interface->getDebugInfo([&pid](
                const ::android::hidl::base::V1_0::DebugInfo& info) {
            pid = info.pid;
        });

        if (ret.isOk() && res == OK) {
            std::lock_guard<std::mutex> lock(mProviderPidMapLock);
            mProviderPidMap[providerInfo->mProviderInstance] = pid;
        }
    }

    return res;
}

status_t CameraProviderManager::addAidlProviderLocked(const std::string& newProvider) {
@@ -2264,6 +2293,13 @@ status_t CameraProviderManager::removeProvider(const std::string& provider) {
        ALOGW("%s: Camera provider HAL with name '%s' is not registered", __FUNCTION__,
                provider.c_str());
    } else {
        if (flags::enable_hal_abort_from_cameraservicewatchdog()) {
            {
                std::lock_guard<std::mutex> pidLock(mProviderPidMapLock);
                mProviderPidMap.erase(provider);
            }
        }

        // Check if there are any newer camera instances from the same provider and try to
        // initialize.
        for (const auto& providerInfo : mProviders) {
@@ -2451,6 +2487,20 @@ bool CameraProviderManager::ProviderInfo::isExternalLazyHAL() const {
    return kEnableLazyHal && (providerName == kExternalProviderName);
}

std::set<pid_t> CameraProviderManager::getProviderPids() {
    std::set<pid_t> pids;

    if (flags::enable_hal_abort_from_cameraservicewatchdog()) {
        std::lock_guard<std::mutex> lock(mProviderPidMapLock);

        std::transform(mProviderPidMap.begin(), mProviderPidMap.end(),
                    std::inserter(pids, pids.begin()),
                    [](std::pair<const std::string, pid_t>& entry) { return entry.second; });
    }

    return pids;
}

status_t CameraProviderManager::ProviderInfo::dump(int fd, const Vector<String16>&) const {
    dprintf(fd, "== Camera Provider HAL %s (v2.%d, %s) static info: %zu devices: ==\n",
            mProviderInstance.c_str(),
+8 −0
Original line number Diff line number Diff line
@@ -431,6 +431,11 @@ public:
    // LocalRegistrationCallback::onServiceRegistration
    virtual void onServiceRegistration(const String16& name, const sp<IBinder> &binder) override;

    /*
     * Return list of provider pid
     */
    std::set<pid_t> getProviderPids();

    /**
     * Dump out information about available providers and devices
     */
@@ -914,6 +919,9 @@ private:
    // Provider names of AIDL providers with retrieved binders.
    std::set<std::string> mAidlProviderWithBinders;

    std::mutex mProviderPidMapLock;
    std::map<std::string, pid_t> mProviderPidMap;

    static const char* deviceStatusToString(
        const hardware::camera::common::V1_0::CameraDeviceStatus&);
    static const char* torchStatusToString(
+4 −6
Original line number Diff line number Diff line
@@ -133,7 +133,7 @@ const std::string& Camera3Device::getId() const {
    return mId;
}

status_t Camera3Device::initializeCommonLocked() {
status_t Camera3Device::initializeCommonLocked(sp<CameraProviderManager> manager) {

    /** Start up status tracker thread */
    mStatusTracker = new StatusTracker(this);
@@ -251,7 +251,8 @@ status_t Camera3Device::initializeCommonLocked() {
    mInjectionMethods = createCamera3DeviceInjectionMethods(this);

    /** Start watchdog thread */
    mCameraServiceWatchdog = new CameraServiceWatchdog(mId, mCameraServiceProxyWrapper);
    mCameraServiceWatchdog = new CameraServiceWatchdog(
            manager->getProviderPids(), mId, mCameraServiceProxyWrapper);
    res = mCameraServiceWatchdog->run("CameraServiceWatchdog");
    if (res != OK) {
        SET_ERR_L("Unable to start camera service watchdog thread: %s (%d)",
@@ -1835,10 +1836,7 @@ status_t Camera3Device::flush(int64_t *frameNumber) {
        mSessionStatsBuilder.stopCounter();
    }

    // Calculate expected duration for flush with additional buffer time in ms for watchdog
    uint64_t maxExpectedDuration = ns2ms(getExpectedInFlightDuration() + kBaseGetBufferWait);
    status_t res = mCameraServiceWatchdog->WATCH_CUSTOM_TIMER(mRequestThread->flush(),
            maxExpectedDuration / kCycleLengthMs, kCycleLengthMs);
    status_t res = mCameraServiceWatchdog->WATCH(mRequestThread->flush());

    return res;
}
Loading