xref: /aosp_15_r20/frameworks/av/services/camera/libcameraservice/CameraServiceWatchdog.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker  * Copyright (C) 2022 The Android Open Source Project
3*ec779b8eSAndroid Build Coastguard Worker  *
4*ec779b8eSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*ec779b8eSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*ec779b8eSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*ec779b8eSAndroid Build Coastguard Worker  *
8*ec779b8eSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*ec779b8eSAndroid Build Coastguard Worker  *
10*ec779b8eSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*ec779b8eSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*ec779b8eSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*ec779b8eSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*ec779b8eSAndroid Build Coastguard Worker  * limitations under the License.
15*ec779b8eSAndroid Build Coastguard Worker  */
16*ec779b8eSAndroid Build Coastguard Worker 
17*ec779b8eSAndroid Build Coastguard Worker #define LOG_TAG "CameraServiceWatchdog"
18*ec779b8eSAndroid Build Coastguard Worker 
19*ec779b8eSAndroid Build Coastguard Worker #include "CameraServiceWatchdog.h"
20*ec779b8eSAndroid Build Coastguard Worker #include "com_android_internal_camera_flags.h"
21*ec779b8eSAndroid Build Coastguard Worker #include "android/set_abort_message.h"
22*ec779b8eSAndroid Build Coastguard Worker #include "utils/CameraServiceProxyWrapper.h"
23*ec779b8eSAndroid Build Coastguard Worker 
24*ec779b8eSAndroid Build Coastguard Worker namespace android {
25*ec779b8eSAndroid Build Coastguard Worker 
26*ec779b8eSAndroid Build Coastguard Worker namespace flags = com::android::internal::camera::flags;
27*ec779b8eSAndroid Build Coastguard Worker 
threadLoop()28*ec779b8eSAndroid Build Coastguard Worker bool CameraServiceWatchdog::threadLoop()
29*ec779b8eSAndroid Build Coastguard Worker {
30*ec779b8eSAndroid Build Coastguard Worker     {
31*ec779b8eSAndroid Build Coastguard Worker         AutoMutex _l(mWatchdogLock);
32*ec779b8eSAndroid Build Coastguard Worker 
33*ec779b8eSAndroid Build Coastguard Worker         while (mPause) {
34*ec779b8eSAndroid Build Coastguard Worker             mWatchdogCondition.wait(mWatchdogLock);
35*ec779b8eSAndroid Build Coastguard Worker         }
36*ec779b8eSAndroid Build Coastguard Worker     }
37*ec779b8eSAndroid Build Coastguard Worker 
38*ec779b8eSAndroid Build Coastguard Worker     std::this_thread::sleep_for(std::chrono::milliseconds(mCycleLengthMs));
39*ec779b8eSAndroid Build Coastguard Worker 
40*ec779b8eSAndroid Build Coastguard Worker     {
41*ec779b8eSAndroid Build Coastguard Worker         AutoMutex _l(mWatchdogLock);
42*ec779b8eSAndroid Build Coastguard Worker 
43*ec779b8eSAndroid Build Coastguard Worker         for (auto it = mTidMap.begin(); it != mTidMap.end(); it++) {
44*ec779b8eSAndroid Build Coastguard Worker             uint32_t currentThreadId = it->first;
45*ec779b8eSAndroid Build Coastguard Worker 
46*ec779b8eSAndroid Build Coastguard Worker             mTidMap[currentThreadId].cycles++;
47*ec779b8eSAndroid Build Coastguard Worker 
48*ec779b8eSAndroid Build Coastguard Worker             if (mTidMap[currentThreadId].cycles >= mMaxCycles) {
49*ec779b8eSAndroid Build Coastguard Worker                 std::string abortMessage = getAbortMessage(mTidMap[currentThreadId].functionName);
50*ec779b8eSAndroid Build Coastguard Worker                 android_set_abort_message(abortMessage.c_str());
51*ec779b8eSAndroid Build Coastguard Worker                 ALOGW("CameraServiceWatchdog triggering abort for pid: %d tid: %d", getpid(),
52*ec779b8eSAndroid Build Coastguard Worker                         currentThreadId);
53*ec779b8eSAndroid Build Coastguard Worker                 mCameraServiceProxyWrapper->logClose(mCameraId, 0 /*latencyMs*/,
54*ec779b8eSAndroid Build Coastguard Worker                         true /*deviceError*/);
55*ec779b8eSAndroid Build Coastguard Worker                 // We use abort here so we can get a tombstone for better
56*ec779b8eSAndroid Build Coastguard Worker                 // debugging.
57*ec779b8eSAndroid Build Coastguard Worker                 if (flags::enable_hal_abort_from_cameraservicewatchdog()) {
58*ec779b8eSAndroid Build Coastguard Worker                     for (pid_t pid : mProviderPids) {
59*ec779b8eSAndroid Build Coastguard Worker                         kill(pid, SIGABRT);
60*ec779b8eSAndroid Build Coastguard Worker                     }
61*ec779b8eSAndroid Build Coastguard Worker                 }
62*ec779b8eSAndroid Build Coastguard Worker 
63*ec779b8eSAndroid Build Coastguard Worker                 abort();
64*ec779b8eSAndroid Build Coastguard Worker             }
65*ec779b8eSAndroid Build Coastguard Worker         }
66*ec779b8eSAndroid Build Coastguard Worker     }
67*ec779b8eSAndroid Build Coastguard Worker 
68*ec779b8eSAndroid Build Coastguard Worker     return true;
69*ec779b8eSAndroid Build Coastguard Worker }
70*ec779b8eSAndroid Build Coastguard Worker 
getAbortMessage(const std::string & functionName)71*ec779b8eSAndroid Build Coastguard Worker std::string CameraServiceWatchdog::getAbortMessage(const std::string& functionName) {
72*ec779b8eSAndroid Build Coastguard Worker     std::string res = "CameraServiceWatchdog triggering abort during "
73*ec779b8eSAndroid Build Coastguard Worker             + functionName;
74*ec779b8eSAndroid Build Coastguard Worker     return res;
75*ec779b8eSAndroid Build Coastguard Worker }
76*ec779b8eSAndroid Build Coastguard Worker 
requestExit()77*ec779b8eSAndroid Build Coastguard Worker void CameraServiceWatchdog::requestExit()
78*ec779b8eSAndroid Build Coastguard Worker {
79*ec779b8eSAndroid Build Coastguard Worker     Thread::requestExit();
80*ec779b8eSAndroid Build Coastguard Worker 
81*ec779b8eSAndroid Build Coastguard Worker     AutoMutex _l(mWatchdogLock);
82*ec779b8eSAndroid Build Coastguard Worker 
83*ec779b8eSAndroid Build Coastguard Worker     mTidMap.clear();
84*ec779b8eSAndroid Build Coastguard Worker 
85*ec779b8eSAndroid Build Coastguard Worker     if (mPause) {
86*ec779b8eSAndroid Build Coastguard Worker         mPause = false;
87*ec779b8eSAndroid Build Coastguard Worker         mWatchdogCondition.signal();
88*ec779b8eSAndroid Build Coastguard Worker     }
89*ec779b8eSAndroid Build Coastguard Worker }
90*ec779b8eSAndroid Build Coastguard Worker 
setEnabled(bool enable)91*ec779b8eSAndroid Build Coastguard Worker void CameraServiceWatchdog::setEnabled(bool enable)
92*ec779b8eSAndroid Build Coastguard Worker {
93*ec779b8eSAndroid Build Coastguard Worker     AutoMutex _l(mEnabledLock);
94*ec779b8eSAndroid Build Coastguard Worker 
95*ec779b8eSAndroid Build Coastguard Worker     if (enable) {
96*ec779b8eSAndroid Build Coastguard Worker         mEnabled = true;
97*ec779b8eSAndroid Build Coastguard Worker     } else {
98*ec779b8eSAndroid Build Coastguard Worker         mEnabled = false;
99*ec779b8eSAndroid Build Coastguard Worker     }
100*ec779b8eSAndroid Build Coastguard Worker }
101*ec779b8eSAndroid Build Coastguard Worker 
stop(uint32_t tid)102*ec779b8eSAndroid Build Coastguard Worker void CameraServiceWatchdog::stop(uint32_t tid)
103*ec779b8eSAndroid Build Coastguard Worker {
104*ec779b8eSAndroid Build Coastguard Worker     AutoMutex _l(mWatchdogLock);
105*ec779b8eSAndroid Build Coastguard Worker 
106*ec779b8eSAndroid Build Coastguard Worker     mTidMap.erase(tid);
107*ec779b8eSAndroid Build Coastguard Worker 
108*ec779b8eSAndroid Build Coastguard Worker     if (mTidMap.empty()) {
109*ec779b8eSAndroid Build Coastguard Worker         mPause = true;
110*ec779b8eSAndroid Build Coastguard Worker     }
111*ec779b8eSAndroid Build Coastguard Worker }
112*ec779b8eSAndroid Build Coastguard Worker 
start(uint32_t tid,const char * functionName)113*ec779b8eSAndroid Build Coastguard Worker void CameraServiceWatchdog::start(uint32_t tid, const char* functionName)
114*ec779b8eSAndroid Build Coastguard Worker {
115*ec779b8eSAndroid Build Coastguard Worker     AutoMutex _l(mWatchdogLock);
116*ec779b8eSAndroid Build Coastguard Worker 
117*ec779b8eSAndroid Build Coastguard Worker     MonitoredFunction monitoredFunction = {};
118*ec779b8eSAndroid Build Coastguard Worker     monitoredFunction.cycles = 0;
119*ec779b8eSAndroid Build Coastguard Worker     monitoredFunction.functionName = functionName;
120*ec779b8eSAndroid Build Coastguard Worker     mTidMap[tid] = monitoredFunction;
121*ec779b8eSAndroid Build Coastguard Worker 
122*ec779b8eSAndroid Build Coastguard Worker     if (mPause) {
123*ec779b8eSAndroid Build Coastguard Worker         mPause = false;
124*ec779b8eSAndroid Build Coastguard Worker         mWatchdogCondition.signal();
125*ec779b8eSAndroid Build Coastguard Worker     }
126*ec779b8eSAndroid Build Coastguard Worker }
127*ec779b8eSAndroid Build Coastguard Worker 
128*ec779b8eSAndroid Build Coastguard Worker }   // namespace android
129