Loading services/camera/libcameraservice/CameraService.cpp +27 −0 Original line number Original line Diff line number Diff line Loading @@ -1907,6 +1907,9 @@ Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String8& } } } } // Enable/disable camera service watchdog client->setCameraServiceWatchdog(mCameraServiceWatchdogEnabled); // Set rotate-and-crop override behavior // Set rotate-and-crop override behavior if (mOverrideRotateAndCropMode != ANDROID_SCALER_ROTATE_AND_CROP_AUTO) { if (mOverrideRotateAndCropMode != ANDROID_SCALER_ROTATE_AND_CROP_AUTO) { client->setRotateAndCropOverride(mOverrideRotateAndCropMode); client->setRotateAndCropOverride(mOverrideRotateAndCropMode); Loading Loading @@ -4848,6 +4851,8 @@ status_t CameraService::shellCommand(int in, int out, int err, const Vector<Stri return handleSetCameraMute(args); return handleSetCameraMute(args); } else if (args.size() >= 2 && args[0] == String16("watch")) { } else if (args.size() >= 2 && args[0] == String16("watch")) { return handleWatchCommand(args, in, out); 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")) { } else if (args.size() == 1 && args[0] == String16("help")) { printHelp(out); printHelp(out); return OK; return OK; Loading Loading @@ -4941,6 +4946,28 @@ status_t CameraService::handleSetRotateAndCrop(const Vector<String16>& args) { return OK; 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) { status_t CameraService::handleGetRotateAndCrop(int out) { Mutex::Autolock lock(mServiceLock); Mutex::Autolock lock(mServiceLock); Loading services/camera/libcameraservice/CameraService.h +9 −0 Original line number Original line Diff line number Diff line Loading @@ -339,6 +339,9 @@ public: // Set/reset camera mute // Set/reset camera mute virtual status_t setCameraMute(bool enabled) = 0; 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 // The injection camera session to replace the internal camera // session. // session. virtual status_t injectCamera(const String8& injectedCamId, virtual status_t injectCamera(const String8& injectedCamId, Loading Loading @@ -1198,6 +1201,9 @@ private: // Handle 'watch' command as passed through 'cmd' // Handle 'watch' command as passed through 'cmd' status_t handleWatchCommand(const Vector<String16> &args, int inFd, int outFd); 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 // Enable tag monitoring of the given tags in provided clients status_t startWatchingTags(const Vector<String16> &args, int outFd); status_t startWatchingTags(const Vector<String16> &args, int outFd); Loading Loading @@ -1284,6 +1290,9 @@ private: // Current camera mute mode // Current camera mute mode bool mOverrideCameraMuteMode = false; bool mOverrideCameraMuteMode = false; // Camera Service watchdog flag bool mCameraServiceWatchdogEnabled = true; /** /** * A listener class that implements the IBinder::DeathRecipient interface * A listener class that implements the IBinder::DeathRecipient interface * for use to call back the error state injected by the external camera, and * for use to call back the error state injected by the external camera, and Loading services/camera/libcameraservice/CameraServiceWatchdog.cpp +11 −0 Original line number Original line Diff line number Diff line Loading @@ -66,6 +66,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) void CameraServiceWatchdog::stop(uint32_t tid) { { AutoMutex _l(mWatchdogLock); AutoMutex _l(mWatchdogLock); Loading services/camera/libcameraservice/CameraServiceWatchdog.h +39 −14 Original line number Original line Diff line number Diff line Loading @@ -21,10 +21,12 @@ * expected duration has exceeded. * expected duration has exceeded. * Notes on multi-threaded behaviors: * Notes on multi-threaded behaviors: * - The threadloop is blocked/paused when there are no calls being * - 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 * - The start and stop functions handle simultaneous call monitoring * and single call monitoring differently. See function documentation for * and single call monitoring differently. See function documentation for * more details. * more details. * To disable/enable: * - adb shell cmd media.camera set-cameraservice-watchdog [0/1] */ */ #pragma once #pragma once #include <chrono> #include <chrono> Loading @@ -49,15 +51,19 @@ class CameraServiceWatchdog : public Thread { public: public: explicit CameraServiceWatchdog() : mPause(true), mMaxCycles(kMaxCycles), explicit CameraServiceWatchdog() : mPause(true), mMaxCycles(kMaxCycles), mCycleLengthMs(kCycleLengthMs) {}; mCycleLengthMs(kCycleLengthMs), mEnabled(true) {}; explicit CameraServiceWatchdog (size_t maxCycles, uint32_t cycleLengthMs) : explicit CameraServiceWatchdog (size_t maxCycles, uint32_t cycleLengthMs, bool enabled) : mPause(true), mMaxCycles(maxCycles), mCycleLengthMs(cycleLengthMs) {}; mPause(true), mMaxCycles(maxCycles), mCycleLengthMs(cycleLengthMs), mEnabled(enabled) {}; virtual ~CameraServiceWatchdog() {}; virtual ~CameraServiceWatchdog() {}; virtual void requestExit(); 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 */ /** Used to wrap monitored calls in start and stop functions using custom timer values */ template<typename T> template<typename T> auto watchThread(T func, uint32_t tid, uint32_t cycles, uint32_t cycleLength) { auto watchThread(T func, uint32_t tid, uint32_t cycles, uint32_t cycleLength) { Loading @@ -66,9 +72,20 @@ public: if (cycles != mMaxCycles || cycleLength != mCycleLengthMs) { if (cycles != mMaxCycles || cycleLength != mCycleLengthMs) { // Create another instance of the watchdog to prevent disruption // Create another instance of the watchdog to prevent disruption // of timer for current monitored calls // of timer for current monitored calls // Lock for mEnabled mEnabledLock.lock(); sp<CameraServiceWatchdog> tempWatchdog = sp<CameraServiceWatchdog> tempWatchdog = new CameraServiceWatchdog(cycles, cycleLength); new CameraServiceWatchdog(cycles, cycleLength, mEnabled); tempWatchdog->run("CameraServiceWatchdog"); mEnabledLock.unlock(); status_t status = tempWatchdog->run("CameraServiceWatchdog"); if (status != OK) { ALOGE("Unable to watch thread: %s (%d)", strerror(-status), status); res = watchThread(func, tid); return res; } res = tempWatchdog->watchThread(func, tid); res = tempWatchdog->watchThread(func, tid); tempWatchdog->requestExit(); tempWatchdog->requestExit(); tempWatchdog.clear(); tempWatchdog.clear(); Loading @@ -84,10 +101,16 @@ public: /** Used to wrap monitored calls in start and stop functions using class timer values */ /** Used to wrap monitored calls in start and stop functions using class timer values */ template<typename T> template<typename T> auto watchThread(T func, uint32_t tid) { auto watchThread(T func, uint32_t tid) { decltype(func()) res; AutoMutex _l(mEnabledLock); if (mEnabled) { start(tid); start(tid); auto res = func(); res = func(); stop(tid); stop(tid); } else { res = func(); } return res; return res; } } Loading @@ -109,10 +132,12 @@ private: virtual bool threadLoop(); virtual bool threadLoop(); Mutex mWatchdogLock; // Lock for condition variable Mutex mWatchdogLock; // Lock for condition variable Mutex mEnabledLock; // Lock for enabled status Condition mWatchdogCondition; // Condition variable for stop/start 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 mMaxCycles; // Max cycles uint32_t mCycleLengthMs; // Length of time elapsed per cycle 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 std::unordered_map<uint32_t, uint32_t> tidToCycleCounterMap; // Thread Id to cycle counter map }; }; Loading services/camera/libcameraservice/api1/Camera2Client.cpp +4 −0 Original line number Original line Diff line number Diff line Loading @@ -2316,6 +2316,10 @@ int32_t Camera2Client::getGlobalAudioRestriction() { return INVALID_OPERATION; return INVALID_OPERATION; } } status_t Camera2Client::setCameraServiceWatchdog(bool enabled) { return mDevice->setCameraServiceWatchdog(enabled); } status_t Camera2Client::setRotateAndCropOverride(uint8_t rotateAndCrop) { status_t Camera2Client::setRotateAndCropOverride(uint8_t rotateAndCrop) { if (rotateAndCrop > ANDROID_SCALER_ROTATE_AND_CROP_AUTO) return BAD_VALUE; if (rotateAndCrop > ANDROID_SCALER_ROTATE_AND_CROP_AUTO) return BAD_VALUE; Loading Loading
services/camera/libcameraservice/CameraService.cpp +27 −0 Original line number Original line Diff line number Diff line Loading @@ -1907,6 +1907,9 @@ Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String8& } } } } // Enable/disable camera service watchdog client->setCameraServiceWatchdog(mCameraServiceWatchdogEnabled); // Set rotate-and-crop override behavior // Set rotate-and-crop override behavior if (mOverrideRotateAndCropMode != ANDROID_SCALER_ROTATE_AND_CROP_AUTO) { if (mOverrideRotateAndCropMode != ANDROID_SCALER_ROTATE_AND_CROP_AUTO) { client->setRotateAndCropOverride(mOverrideRotateAndCropMode); client->setRotateAndCropOverride(mOverrideRotateAndCropMode); Loading Loading @@ -4848,6 +4851,8 @@ status_t CameraService::shellCommand(int in, int out, int err, const Vector<Stri return handleSetCameraMute(args); return handleSetCameraMute(args); } else if (args.size() >= 2 && args[0] == String16("watch")) { } else if (args.size() >= 2 && args[0] == String16("watch")) { return handleWatchCommand(args, in, out); 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")) { } else if (args.size() == 1 && args[0] == String16("help")) { printHelp(out); printHelp(out); return OK; return OK; Loading Loading @@ -4941,6 +4946,28 @@ status_t CameraService::handleSetRotateAndCrop(const Vector<String16>& args) { return OK; 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) { status_t CameraService::handleGetRotateAndCrop(int out) { Mutex::Autolock lock(mServiceLock); Mutex::Autolock lock(mServiceLock); Loading
services/camera/libcameraservice/CameraService.h +9 −0 Original line number Original line Diff line number Diff line Loading @@ -339,6 +339,9 @@ public: // Set/reset camera mute // Set/reset camera mute virtual status_t setCameraMute(bool enabled) = 0; 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 // The injection camera session to replace the internal camera // session. // session. virtual status_t injectCamera(const String8& injectedCamId, virtual status_t injectCamera(const String8& injectedCamId, Loading Loading @@ -1198,6 +1201,9 @@ private: // Handle 'watch' command as passed through 'cmd' // Handle 'watch' command as passed through 'cmd' status_t handleWatchCommand(const Vector<String16> &args, int inFd, int outFd); 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 // Enable tag monitoring of the given tags in provided clients status_t startWatchingTags(const Vector<String16> &args, int outFd); status_t startWatchingTags(const Vector<String16> &args, int outFd); Loading Loading @@ -1284,6 +1290,9 @@ private: // Current camera mute mode // Current camera mute mode bool mOverrideCameraMuteMode = false; bool mOverrideCameraMuteMode = false; // Camera Service watchdog flag bool mCameraServiceWatchdogEnabled = true; /** /** * A listener class that implements the IBinder::DeathRecipient interface * A listener class that implements the IBinder::DeathRecipient interface * for use to call back the error state injected by the external camera, and * for use to call back the error state injected by the external camera, and Loading
services/camera/libcameraservice/CameraServiceWatchdog.cpp +11 −0 Original line number Original line Diff line number Diff line Loading @@ -66,6 +66,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) void CameraServiceWatchdog::stop(uint32_t tid) { { AutoMutex _l(mWatchdogLock); AutoMutex _l(mWatchdogLock); Loading
services/camera/libcameraservice/CameraServiceWatchdog.h +39 −14 Original line number Original line Diff line number Diff line Loading @@ -21,10 +21,12 @@ * expected duration has exceeded. * expected duration has exceeded. * Notes on multi-threaded behaviors: * Notes on multi-threaded behaviors: * - The threadloop is blocked/paused when there are no calls being * - 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 * - The start and stop functions handle simultaneous call monitoring * and single call monitoring differently. See function documentation for * and single call monitoring differently. See function documentation for * more details. * more details. * To disable/enable: * - adb shell cmd media.camera set-cameraservice-watchdog [0/1] */ */ #pragma once #pragma once #include <chrono> #include <chrono> Loading @@ -49,15 +51,19 @@ class CameraServiceWatchdog : public Thread { public: public: explicit CameraServiceWatchdog() : mPause(true), mMaxCycles(kMaxCycles), explicit CameraServiceWatchdog() : mPause(true), mMaxCycles(kMaxCycles), mCycleLengthMs(kCycleLengthMs) {}; mCycleLengthMs(kCycleLengthMs), mEnabled(true) {}; explicit CameraServiceWatchdog (size_t maxCycles, uint32_t cycleLengthMs) : explicit CameraServiceWatchdog (size_t maxCycles, uint32_t cycleLengthMs, bool enabled) : mPause(true), mMaxCycles(maxCycles), mCycleLengthMs(cycleLengthMs) {}; mPause(true), mMaxCycles(maxCycles), mCycleLengthMs(cycleLengthMs), mEnabled(enabled) {}; virtual ~CameraServiceWatchdog() {}; virtual ~CameraServiceWatchdog() {}; virtual void requestExit(); 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 */ /** Used to wrap monitored calls in start and stop functions using custom timer values */ template<typename T> template<typename T> auto watchThread(T func, uint32_t tid, uint32_t cycles, uint32_t cycleLength) { auto watchThread(T func, uint32_t tid, uint32_t cycles, uint32_t cycleLength) { Loading @@ -66,9 +72,20 @@ public: if (cycles != mMaxCycles || cycleLength != mCycleLengthMs) { if (cycles != mMaxCycles || cycleLength != mCycleLengthMs) { // Create another instance of the watchdog to prevent disruption // Create another instance of the watchdog to prevent disruption // of timer for current monitored calls // of timer for current monitored calls // Lock for mEnabled mEnabledLock.lock(); sp<CameraServiceWatchdog> tempWatchdog = sp<CameraServiceWatchdog> tempWatchdog = new CameraServiceWatchdog(cycles, cycleLength); new CameraServiceWatchdog(cycles, cycleLength, mEnabled); tempWatchdog->run("CameraServiceWatchdog"); mEnabledLock.unlock(); status_t status = tempWatchdog->run("CameraServiceWatchdog"); if (status != OK) { ALOGE("Unable to watch thread: %s (%d)", strerror(-status), status); res = watchThread(func, tid); return res; } res = tempWatchdog->watchThread(func, tid); res = tempWatchdog->watchThread(func, tid); tempWatchdog->requestExit(); tempWatchdog->requestExit(); tempWatchdog.clear(); tempWatchdog.clear(); Loading @@ -84,10 +101,16 @@ public: /** Used to wrap monitored calls in start and stop functions using class timer values */ /** Used to wrap monitored calls in start and stop functions using class timer values */ template<typename T> template<typename T> auto watchThread(T func, uint32_t tid) { auto watchThread(T func, uint32_t tid) { decltype(func()) res; AutoMutex _l(mEnabledLock); if (mEnabled) { start(tid); start(tid); auto res = func(); res = func(); stop(tid); stop(tid); } else { res = func(); } return res; return res; } } Loading @@ -109,10 +132,12 @@ private: virtual bool threadLoop(); virtual bool threadLoop(); Mutex mWatchdogLock; // Lock for condition variable Mutex mWatchdogLock; // Lock for condition variable Mutex mEnabledLock; // Lock for enabled status Condition mWatchdogCondition; // Condition variable for stop/start 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 mMaxCycles; // Max cycles uint32_t mCycleLengthMs; // Length of time elapsed per cycle 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 std::unordered_map<uint32_t, uint32_t> tidToCycleCounterMap; // Thread Id to cycle counter map }; }; Loading
services/camera/libcameraservice/api1/Camera2Client.cpp +4 −0 Original line number Original line Diff line number Diff line Loading @@ -2316,6 +2316,10 @@ int32_t Camera2Client::getGlobalAudioRestriction() { return INVALID_OPERATION; return INVALID_OPERATION; } } status_t Camera2Client::setCameraServiceWatchdog(bool enabled) { return mDevice->setCameraServiceWatchdog(enabled); } status_t Camera2Client::setRotateAndCropOverride(uint8_t rotateAndCrop) { status_t Camera2Client::setRotateAndCropOverride(uint8_t rotateAndCrop) { if (rotateAndCrop > ANDROID_SCALER_ROTATE_AND_CROP_AUTO) return BAD_VALUE; if (rotateAndCrop > ANDROID_SCALER_ROTATE_AND_CROP_AUTO) return BAD_VALUE; Loading