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
diff --git a/services/camera/libcameraservice/CameraServiceWatchdog.cpp b/services/camera/libcameraservice/CameraServiceWatchdog.cpp
index 1c1bd24..ad1a84f 100644
--- a/services/camera/libcameraservice/CameraServiceWatchdog.cpp
+++ b/services/camera/libcameraservice/CameraServiceWatchdog.cpp
@@ -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 @@
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();
}
}
diff --git a/services/camera/libcameraservice/CameraServiceWatchdog.h b/services/camera/libcameraservice/CameraServiceWatchdog.h
index 165dece..691a274 100644
--- a/services/camera/libcameraservice/CameraServiceWatchdog.h
+++ b/services/camera/libcameraservice/CameraServiceWatchdog.h
@@ -30,6 +30,7 @@
*/
#pragma once
#include <chrono>
+#include <set>
#include <thread>
#include <time.h>
#include <utils/Thread.h>
@@ -57,16 +58,17 @@
};
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 @@
// 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 @@
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
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.cpp b/services/camera/libcameraservice/common/CameraProviderManager.cpp
index 2440c37..26864fc 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.cpp
+++ b/services/camera/libcameraservice/common/CameraProviderManager.cpp
@@ -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 @@
}
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 @@
}
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 @@
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 @@
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(),
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.h b/services/camera/libcameraservice/common/CameraProviderManager.h
index 4a64b44..b686a58 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.h
+++ b/services/camera/libcameraservice/common/CameraProviderManager.h
@@ -431,6 +431,11 @@
// 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 @@
// 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(
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 11891e9..0cb9b1d 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -133,7 +133,7 @@
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 @@
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 @@
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;
}
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index e5ccbae..3cfe3c9 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -726,7 +726,7 @@
*
* Must be called with mLock and mInterfaceLock held.
*/
- status_t initializeCommonLocked();
+ status_t initializeCommonLocked(sp<CameraProviderManager> manager);
/**
* Update capture request list so that each batch size honors the batch_size_max report from
diff --git a/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.cpp b/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.cpp
index 57297bc..868b7ef 100644
--- a/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.cpp
+++ b/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.cpp
@@ -349,7 +349,7 @@
readoutSupported.data.u8[0] == ANDROID_SENSOR_READOUT_TIMESTAMP_HARDWARE;
}
- return initializeCommonLocked();
+ return initializeCommonLocked(manager);
}
::ndk::ScopedAStatus AidlCamera3Device::AidlCameraDeviceCallbacks::processCaptureResult(
diff --git a/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.cpp b/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.cpp
index 09299e6..f507df9 100644
--- a/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.cpp
+++ b/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.cpp
@@ -303,7 +303,7 @@
}
mNeedFixupMonochromeTags = (isMonochrome && deviceVersion < CAMERA_DEVICE_API_VERSION_3_5);
- return initializeCommonLocked();
+ return initializeCommonLocked(manager);
}
hardware::Return<void> HidlCamera3Device::requestStreamBuffers(