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

Commit aeb20dc9 authored by Ravneet's avatar Ravneet
Browse files

Add disable/enable camera service watchdog feature

- Allows the camera service watchdog to be enabled and disabled
- Usage: adb shell cmd media.camera set-cameraservice-watchdog [0/1]

Test: Manual
Bug: 62296107
Change-Id: I528ca819cc2be03006c77e869adf8f5fa99128d6
parent a32bd3bd
Loading
Loading
Loading
Loading
+27 −0
Original line number Diff line number Diff line
@@ -1883,6 +1883,9 @@ Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String8&
            }
        }

        // Enable/disable camera service watchdog
        client->setCameraServiceWatchdog(mCameraServiceWatchdogEnabled);

        // Set rotate-and-crop override behavior
        if (mOverrideRotateAndCropMode != ANDROID_SCALER_ROTATE_AND_CROP_AUTO) {
            client->setRotateAndCropOverride(mOverrideRotateAndCropMode);
@@ -4802,6 +4805,8 @@ status_t CameraService::shellCommand(int in, int out, int err, const Vector<Stri
        return handleSetCameraMute(args);
    } else if (args.size() >= 2 && args[0] == String16("watch")) {
        return handleWatchCommand(args, in, out);
    } else if (args.size() >= 2 && args[0] == String16("set-watchdog")) {
        return handleSetCameraServiceWatchdog(args);
    } else if (args.size() == 1 && args[0] == String16("help")) {
        printHelp(out);
        return OK;
@@ -4895,6 +4900,28 @@ status_t CameraService::handleSetRotateAndCrop(const Vector<String16>& args) {
    return OK;
}

status_t CameraService::handleSetCameraServiceWatchdog(const Vector<String16>& args) {
    int enableWatchdog = atoi(String8(args[1]));

    if (enableWatchdog < 0 || enableWatchdog > 1) return BAD_VALUE;

    Mutex::Autolock lock(mServiceLock);

    mCameraServiceWatchdogEnabled = enableWatchdog;

    const auto clients = mActiveClientManager.getAll();
    for (auto& current : clients) {
        if (current != nullptr) {
            const auto basicClient = current->getValue();
            if (basicClient.get() != nullptr) {
                basicClient->setCameraServiceWatchdog(enableWatchdog);
            }
        }
    }

    return OK;
}

status_t CameraService::handleGetRotateAndCrop(int out) {
    Mutex::Autolock lock(mServiceLock);

+9 −0
Original line number Diff line number Diff line
@@ -338,6 +338,9 @@ public:
        // Set/reset camera mute
        virtual status_t setCameraMute(bool enabled) = 0;

        // Set Camera service watchdog
        virtual status_t setCameraServiceWatchdog(bool enabled) = 0;

        // The injection camera session to replace the internal camera
        // session.
        virtual status_t injectCamera(const String8& injectedCamId,
@@ -1190,6 +1193,9 @@ private:
    // Handle 'watch' command as passed through 'cmd'
    status_t handleWatchCommand(const Vector<String16> &args, int inFd, int outFd);

    // Set the camera service watchdog
    status_t handleSetCameraServiceWatchdog(const Vector<String16>& args);

    // Enable tag monitoring of the given tags in provided clients
    status_t startWatchingTags(const Vector<String16> &args, int outFd);

@@ -1275,6 +1281,9 @@ private:
    // Current camera mute mode
    bool mOverrideCameraMuteMode = false;

    // Camera Service watchdog flag
    bool mCameraServiceWatchdogEnabled = true;

    /**
     * A listener class that implements the IBinder::DeathRecipient interface
     * for use to call back the error state injected by the external camera, and
+11 −0
Original line number Diff line number Diff line
@@ -64,6 +64,17 @@ void CameraServiceWatchdog::requestExit()
    }
}

void CameraServiceWatchdog::setEnabled(bool enable)
{
    AutoMutex _l(mEnabledLock);

    if (enable) {
        mEnabled = true;
    } else {
        mEnabled = false;
    }
}

void CameraServiceWatchdog::stop(uint32_t tid)
{
    AutoMutex _l(mWatchdogLock);
+32 −13
Original line number Diff line number Diff line
@@ -21,10 +21,12 @@
 * expected duration has exceeded.
 * Notes on multi-threaded behaviors:
 *    - The threadloop is blocked/paused when there are no calls being
 *   monitored.
 *   monitored (when the TID cycle to counter map is empty).
 *   - The start and stop functions handle simultaneous call monitoring
 *   and single call monitoring differently. See function documentation for
 *   more details.
 * To disable/enable:
 *   - adb shell cmd media.camera set-cameraservice-watchdog [0/1]
 */

#include <chrono>
@@ -49,15 +51,19 @@ class CameraServiceWatchdog : public Thread {

public:
    explicit CameraServiceWatchdog() : mPause(true), mMaxCycles(kMaxCycles),
            mCycleLengthMs(kCycleLengthMs) {};
            mCycleLengthMs(kCycleLengthMs), mEnabled(true) {};

    explicit CameraServiceWatchdog (size_t maxCycles, uint32_t cycleLengthMs) :
            mPause(true), mMaxCycles(maxCycles), mCycleLengthMs(cycleLengthMs) {};
    explicit CameraServiceWatchdog (size_t maxCycles, uint32_t cycleLengthMs, bool enabled) :
            mPause(true), mMaxCycles(maxCycles), mCycleLengthMs(cycleLengthMs), mEnabled(enabled)
                    {};

    virtual ~CameraServiceWatchdog() {};

    virtual void requestExit();

    /** Enables/disables the watchdog */
    void setEnabled(bool enable);

    /** Used to wrap monitored calls in start and stop functions using custom timer values */
    template<typename T>
    auto watchThread(T func, uint32_t tid, uint32_t cycles, uint32_t cycleLength) {
@@ -66,8 +72,13 @@ public:
        if (cycles != mMaxCycles || cycleLength != mCycleLengthMs) {
            // Create another instance of the watchdog to prevent disruption
            // of timer for current monitored calls

            // Lock for mEnabled
            mEnabledLock.lock();
            sp<CameraServiceWatchdog> tempWatchdog =
                    new CameraServiceWatchdog(cycles, cycleLength);
                    new CameraServiceWatchdog(cycles, cycleLength, mEnabled);
            mEnabledLock.unlock();

            tempWatchdog->run("CameraServiceWatchdog");
            res = tempWatchdog->watchThread(func, tid);
            tempWatchdog->requestExit();
@@ -84,11 +95,17 @@ public:
    /** Used to wrap monitored calls in start and stop functions using class timer values */
    template<typename T>
    auto watchThread(T func, uint32_t tid) {
        AutoMutex _l(mEnabledLock);

        auto res = NULL;

        if (mEnabled) {
            start(tid);
            res = func();
            stop(tid);
        } else {
            res = func();
        }

        return res;
    }
@@ -110,10 +127,12 @@ private:
    virtual bool    threadLoop();

    Mutex           mWatchdogLock;      // Lock for condition variable
    Mutex           mEnabledLock;       // Lock for enabled status
    Condition       mWatchdogCondition; // Condition variable for stop/start
    bool            mPause;               // True if thread is currently paused
    bool            mPause;             // True if tid map is empty
    uint32_t        mMaxCycles;         // Max cycles
    uint32_t        mCycleLengthMs;     // Length of time elapsed per cycle
    bool            mEnabled;           // True if watchdog is enabled

    std::unordered_map<uint32_t, uint32_t> tidToCycleCounterMap; // Thread Id to cycle counter map
};
+4 −0
Original line number Diff line number Diff line
@@ -2294,6 +2294,10 @@ int32_t Camera2Client::getGlobalAudioRestriction() {
    return INVALID_OPERATION;
}

status_t Camera2Client::setCameraServiceWatchdog(bool enabled) {
    return mDevice->setCameraServiceWatchdog(enabled);
}

status_t Camera2Client::setRotateAndCropOverride(uint8_t rotateAndCrop) {
    if (rotateAndCrop > ANDROID_SCALER_ROTATE_AND_CROP_AUTO) return BAD_VALUE;

Loading