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(