1 /*
2 * Copyright (c) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "camera_host_selfkiller.h"
17 #include "idevmgr_hdi.h"
18 #include "parameters.h"
19 #include "camera.h"
20 namespace OHOS::Camera {
CameraHostSelfkiller(uint8_t sleepInterval,uint32_t noCameraForExitMaxTimeSecond)21 CameraHostSelfkiller::CameraHostSelfkiller(uint8_t sleepInterval, uint32_t noCameraForExitMaxTimeSecond)
22 : sleepInterval_(sleepInterval), noCameraForExitMaxTimeSecond_(noCameraForExitMaxTimeSecond)
23 {
24 CAMERA_LOGD("Ctor, instance");
25 }
~CameraHostSelfkiller()26 CameraHostSelfkiller::~CameraHostSelfkiller()
27 {
28 CAMERA_LOGD("Dtor, instance");
29 }
30
Init(std::function<bool (void)> canBeKilledFn,std::function<void (void)> killerTimeoutCb,std::string selfKillParamName,std::string cameraServiceName)31 void CameraHostSelfkiller::Init(std::function<bool(void)> canBeKilledFn, std::function<void(void)> killerTimeoutCb,
32 std::string selfKillParamName, std::string cameraServiceName)
33 {
34 if (selfKillerThread_ != nullptr) {
35 CAMERA_LOGE("CameraHostSelfkiller::Init failed, resaon: alreay inited");
36 return;
37 }
38 killerTimeoutCb_ = killerTimeoutCb;
39 canBeKilledFn_ = canBeKilledFn;
40 selfKillParamName_ = selfKillParamName;
41 cameraServiceName_ = cameraServiceName;
42 selfKillerThreadLoopFlag_ = true;
43 selfKillerThread_ = new std::thread([this] { CameraHostSelfkillerHandler(); });
44 }
45
DeInit()46 void CameraHostSelfkiller::DeInit()
47 {
48 CAMERA_LOGD("CameraHostSelfkiller::DeInit");
49 selfKillerThreadLoopFlag_ = false;
50 if (selfKillerThread_ != nullptr && selfKillerThread_->joinable()) {
51 selfKillerThread_->join();
52 selfKillerThread_ = nullptr;
53 }
54 }
55
UnloadHdfServiceByName(const std::string & serviceName)56 void CameraHostSelfkiller::UnloadHdfServiceByName(const std::string &serviceName)
57 {
58 int32_t ret = 0;
59 CAMERA_LOGI("begin unload %{public}s", serviceName.c_str());
60 OHOS::sptr<HDI::DeviceManager::V1_0::IDeviceManager> devMgr = HDI::DeviceManager::V1_0::IDeviceManager::Get();
61 if (devMgr == nullptr) {
62 CAMERA_LOGE("get devMgr object failed");
63 return;
64 }
65 ret = devMgr->UnloadDevice(serviceName);
66 if (ret != 0) {
67 CAMERA_LOGE("%{public}s unload failed", serviceName.c_str());
68 return;
69 }
70 CAMERA_LOGI("unload %{public}s sucess", serviceName.c_str());
71 }
72
CameraHostSelfkillerHandler()73 void CameraHostSelfkiller::CameraHostSelfkillerHandler()
74 {
75 uint32_t noCameraForExitMax = noCameraForExitMaxTimeSecond_ / sleepInterval_;
76 uint32_t count = 0;
77 if (selfKillParamName_ != "") {
78 bool isEnableSelfKill = OHOS::system::GetBoolParameter(selfKillParamName_.c_str(), false);
79 if (!isEnableSelfKill) {
80 CAMERA_LOGI("%{public}s is false, no need to selfkill", selfKillParamName_.c_str());
81 return;
82 }
83 }
84
85 CAMERA_LOGI("CameraHostSelfkillerHandler Begin");
86 while (selfKillerThreadLoopFlag_) {
87 sleep(sleepInterval_);
88 if (canBeKilledFn_ == nullptr) {
89 CAMERA_LOGW("canBeKilledFn_ is nullptr, just break");
90 break;
91 }
92 if (!canBeKilledFn_()) {
93 CAMERA_LOGD("selfkill condition not matched");
94 count = 0;
95 continue;
96 }
97 CAMERA_LOGI("selfkill condition matched, timeout is %{public}us / %{public}us",
98 count * sleepInterval_,
99 noCameraForExitMaxTimeSecond_);
100 if (count++ < noCameraForExitMax) {
101 continue;
102 }
103 if (killerTimeoutCb_ != nullptr) {
104 killerTimeoutCb_();
105 }
106 if (cameraServiceName_ != "") {
107 CameraHostSelfkiller::UnloadHdfServiceByName(cameraServiceName_);
108 }
109 break;
110 }
111 }
112
WaitForBootComplete()113 void CameraHostSelfkiller::WaitForBootComplete()
114 {
115 constexpr const char *bootCompleteParamName = "bootevent.boot.completed";
116 static bool isBootComplete = false;
117 if (isBootComplete) {
118 CAMERA_LOGD("isBootComplete is true, just return");
119 return;
120 }
121 CAMERA_LOGI("Wait isBootComplete begin");
122 isBootComplete = OHOS::system::GetBoolParameter(bootCompleteParamName, false);
123 while (!isBootComplete) {
124 isBootComplete = OHOS::system::GetBoolParameter(bootCompleteParamName, false);
125 if (isBootComplete) {
126 CAMERA_LOGI("Get %{public}s true, sleep 1s and then continue", bootCompleteParamName);
127 sleep(1);
128 break;
129 }
130 CAMERA_LOGI("Get %{public}s true, sleep 1s and then continue", bootCompleteParamName);
131 sleep(1);
132 }
133 CAMERA_LOGI("Wait isBootComplete end");
134 }
135
136 } // namespace OHOS::Camera