• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_rotate_param_manager.h"
17 
18 #include <iostream>
19 #include <fstream>
20 #include <filesystem>
21 #include <common_event_data.h>
22 #include <common_event_manager.h>
23 #include <common_event_support.h>
24 #include "common_event_subscriber.h"
25 #include "camera_util.h"
26 #include "camera_log.h"
27 
28 namespace OHOS {
29 namespace CameraStandard {
30 
31 namespace {
32 static int32_t RETRY_SUBSCRIBER = 3;
33 static const int8_t DECIMAL = 10;
34 const bool NEED_PARAM_VERIFY = true;
35 const std::string CONFIG_FILE_NAME = "camera_rotate_strategy.xml";
36 const std::string CAMERA_CFG_PATH = "/sys_prod/etc/camera/" + CONFIG_FILE_NAME;
37 const std::string EVENT_INFO_TYPE = "type";
38 const std::string EVENT_INFO_SUBTYPE = "subtype";
39 const std::string RECEIVE_UPDATE_PERMISSION = "ohos.permission.RECEIVE_UPDATE_MESSAGE";
40 const std::string CONFIG_UPDATED_ACTION = "usual.event.DUE_SA_CFG_UPDATED";
41 const std::string CONFIG_TYPE = "camera";
42 
43 const char* XML_CAMERA_STRATEGY = "strategy";
44 const char* XML_CAMERA_BUDLE_NAME = "bundleName";
45 const char* XML_CAMERA_WIDE_VALUE = "wideValue";
46 const char* XML_CAMERA_ROTATE_DEGREE = "rotateDegree";
47 const char* XML_CAMERA_FPS = "fps";
48 }
49 // LCOV_EXCL_START
GetInstance()50 CameraRoateParamManager& CameraRoateParamManager::GetInstance()
51 {
52     static CameraRoateParamManager instance;
53     return instance;
54 }
55 
InitParam()56 void CameraRoateParamManager::InitParam()
57 {
58     MEDIA_INFO_LOG("InitParam");
59     if (paramReader == nullptr) {
60         paramReader = std::make_shared<CameraRoateParamReader>();
61     }
62     if (paramReader != nullptr) {
63         std::string cloudVersion = paramReader->GetPathVersion(); // 云推版本号
64         std::vector<std::string> cloudVersionNum;
65         CHECK_RETURN_ELOG(!paramReader->VersionStrToNumber(cloudVersion, cloudVersionNum),
66             "VersionStrToNumber error , pathVersion is invalid");
67         std::string localVersion = LoadVersion(); // 本地参数版本号/system/etc/camera/version.txt
68         std::vector<std::string> localVersionNum;
69         CHECK_RETURN_ELOG(!paramReader->VersionStrToNumber(localVersion, localVersionNum),
70             "VersionStrToNumber error , currentVersion is invalid");
71         MEDIA_INFO_LOG(
72             "currentVersion: %{public}s pathVersion :%{public}s", localVersion.c_str(), cloudVersion.c_str());
73         if (paramReader->CompareVersion(localVersionNum, cloudVersionNum)) {
74             ReloadParam();
75         }
76     }
77     LoadParamStr(); // 读取本地配置
78 };
79 
ReloadParam()80 void CameraRoateParamManager::ReloadParam()
81 {
82     MEDIA_DEBUG_LOG("called");
83     CHECK_RETURN_ELOG(paramReader == nullptr, "paramReader is nullptr");
84     std::string path = paramReader->GetConfigFilePath();
85     MEDIA_INFO_LOG("GetConfigFilePath, path: %{public}s ", path.c_str());
86     // 判断是路径是否在下载路径, 下载路径需要增加安全校验
87     if (NEED_PARAM_VERIFY && path.find(PARAM_UPDATE_ABS_PATH) != std::string::npos) {
88         VerifyCloudFile(PARAM_SERVICE_INSTALL_PATH + CAMERA_ROTATE_CFG_DIR);
89     }
90 };
91 
VerifyCloudFile(const std::string & prePath)92 void CameraRoateParamManager::VerifyCloudFile(const std::string& prePath)
93 {
94     CHECK_RETURN_ELOG(paramReader == nullptr, "paramReader is nullptr");
95     // 校验参数签名是否合法
96     std::string certFile = prePath + "/CERT.ENC"; // 获取签名文件
97     std::string verifyFile = prePath + "/CERT.SF"; // 获取待验证的文件
98     std::string manifestFile = prePath + "/MANIFEST.MF"; // 文件列表文件
99     std::lock_guard<std::mutex> lock(mutxVerify);
100     CHECK_RETURN_ELOG(!paramReader->VerifyCertSfFile(certFile, verifyFile, manifestFile),
101         " VerifyCertSfFile  error , param is invalid");
102     std::string cfgDir = PARAM_SERVICE_INSTALL_PATH + CAMERA_ROTATE_CFG_DIR;
103     // 校验参数文件是否合法
104     CHECK_RETURN_ELOG(
105         !paramReader->VerifyParamFile(cfgDir, VERSION_FILE_NAME), "verify version file error , param is invalid");
106     CHECK_RETURN_ELOG(
107         !paramReader->VerifyParamFile(cfgDir, CONFIG_FILE_NAME), "verify param file error , param is invalid");
108     // 拷贝参数到本地
109     CopyFileToLocal();
110 }
111 
CopyFileToLocal()112 void CameraRoateParamManager::CopyFileToLocal()
113 {
114     if (!DoCopy(PARAM_SERVICE_INSTALL_PATH + CAMERA_ROTATE_CFG_DIR + VERSION_FILE_NAME,
115         CAMERA_SERVICE_ABS_PATH + VERSION_FILE_NAME)) {
116         MEDIA_ERR_LOG("version.txt copy to local error");
117         return;
118     }
119     if (!DoCopy(PARAM_SERVICE_INSTALL_PATH + CAMERA_ROTATE_CFG_DIR + CONFIG_FILE_NAME,
120         CAMERA_SERVICE_ABS_PATH + CONFIG_FILE_NAME)) {
121         MEDIA_ERR_LOG("ofbs_config.json copy to local error");
122         return;
123     }
124     MEDIA_INFO_LOG("CopyFileToLocal success");
125 }
126 
DoCopy(const std::string & src,const std::string & des)127 bool CameraRoateParamManager::DoCopy(const std::string& src, const std::string& des)
128 {
129     CHECK_RETURN_RET_ELOG(!CheckPathExist(src.c_str()), false, "srcPath is invalid");
130     if (CheckPathExist(des.c_str())) {
131         MEDIA_INFO_LOG("des has file");
132         CHECK_RETURN_RET_ELOG(!RemoveFile(des), false, "rm des file error");
133     }
134     std::filesystem::path sPath(src);
135     std::filesystem::path dPath(des);
136     std::error_code errNo;
137     const auto copyOptions = std::filesystem::copy_options::overwrite_existing |
138         std::filesystem::copy_options::recursive |
139         std::filesystem::copy_options::skip_symlinks;
140     std::filesystem::copy(sPath, dPath, copyOptions, errNo);
141     // if has some error in copy, record errno
142     CHECK_RETURN_RET_ELOG(errNo.value(), false, "copy failed errno:%{public}d", errNo.value());
143     MEDIA_INFO_LOG("copy success");
144     return true;
145 }
146 
LoadVersion()147 std::string CameraRoateParamManager::LoadVersion()
148 {
149     CHECK_RETURN_RET_ELOG(paramReader == nullptr, "", "paramReader is nullptr");
150     std::string filePath = CAMERA_SERVICE_ABS_PATH + VERSION_FILE_NAME; // 优先沙箱找
151     std::ifstream file(filePath);
152     if (!file.good()) {
153         return paramReader->GetVersionInfoStr(ABS_CONTENT_FILE_PATH + VERSION_FILE_NAME); // 服务配置路径
154     }
155     return paramReader->GetVersionInfoStr(filePath);
156 }
157 
LoadParamStr()158 void CameraRoateParamManager::LoadParamStr()
159 {
160     std::string filePath = CAMERA_SERVICE_ABS_PATH + CONFIG_FILE_NAME;
161     std::ifstream file(filePath);
162     if (!file.good()) {
163         LoadConfiguration(CAMERA_CFG_PATH);
164         return;
165     }
166     LoadConfiguration(filePath);
167 }
168 
LoadConfiguration(const std::string & filepath)169 bool CameraRoateParamManager::LoadConfiguration(const std::string &filepath)
170 {
171     curNode_ = CameraXmlNode::Create();
172     int32_t ret = curNode_->Config(filepath.c_str(), nullptr, 0);
173     CHECK_RETURN_RET_ELOG(ret != CAMERA_OK, false, "Not found camera_rotate_strategy.xml!");
174     {
175         std::lock_guard<std::mutex> lock(strategyInfosMutex_);
176         cameraRotateStrategyInfos_.clear();
177     }
178     bool result = ParseInternal(curNode_->GetCopyNode());
179     CHECK_RETURN_RET_ELOG(!result, false, "Camera rotate strategy xml parse failed.");
180     Destroy();
181     return true;
182 }
183 
Destroy()184 void CameraRoateParamManager::Destroy()
185 {
186     curNode_->FreeDoc();
187     curNode_->CleanUpParser();
188 }
189 
ParseInternal(std::shared_ptr<CameraXmlNode> curNode)190 bool CameraRoateParamManager::ParseInternal(std::shared_ptr<CameraXmlNode> curNode)
191 {
192     for (; curNode->IsNodeValid(); curNode->MoveToNext()) {
193         if (!curNode->IsElementNode()) {
194             continue;
195         }
196         if (curNode->CompareName(XML_CAMERA_STRATEGY)) {
197             ParserStrategyInfo(curNode->GetCopyNode());
198         } else {
199             ParseInternal(curNode->GetChildrenNode());
200         }
201     }
202     return true;
203 }
204 
ParserStrategyInfo(std::shared_ptr<CameraXmlNode> curNode)205 void CameraRoateParamManager::ParserStrategyInfo(std::shared_ptr<CameraXmlNode> curNode)
206 {
207     std::lock_guard<std::mutex> lock(strategyInfosMutex_);
208     if (curNode->IsNodeValid() && curNode->IsElementNode()) {
209         CameraRotateStrategyInfo info = {};
210         curNode->GetProp(XML_CAMERA_BUDLE_NAME, info.bundleName);
211 
212         std::string pValue;
213         float wideValue = -1.0;
214         curNode->GetProp(XML_CAMERA_WIDE_VALUE, pValue);
215         char* endPtr;
216         wideValue = std::strtof(pValue.c_str(), &endPtr);
217         if (*endPtr != '\0' || pValue.empty()) {
218             wideValue = -1.0;
219         }
220         info.wideValue = wideValue;
221         endPtr = nullptr;
222 
223         int rotateDegree = -1;
224         curNode->GetProp(XML_CAMERA_ROTATE_DEGREE, pValue);
225         long result = strtol(pValue.c_str(), &endPtr, DECIMAL);
226 
227         if (*endPtr != '\0' || pValue.empty()) {
228             rotateDegree = -1;
229         } else {
230             rotateDegree = static_cast<int16_t>(result);
231         }
232         info.rotateDegree = rotateDegree;
233 
234         int16_t fps = -1;
235         curNode->GetProp(XML_CAMERA_FPS, pValue);
236         endPtr = nullptr;
237         result = strtol(pValue.c_str(), &endPtr, DECIMAL);
238 
239         if (*endPtr != '\0' || pValue.empty()) {
240             fps = -1;
241         } else {
242             fps = static_cast<int16_t>(result);
243         }
244         info.fps = fps;
245         cameraRotateStrategyInfos_.push_back(info);
246         MEDIA_INFO_LOG("ParserStrategyInfo: bundleName:%{public}s, wideValue:%{public}f, "
247             "rotateDegree:%{public}d, fps:%{public}d",
248             info.bundleName.c_str(), info.wideValue, info.rotateDegree, info.fps);
249     }
250 }
251 
InitDefaultConfig()252 void CameraRoateParamManager::InitDefaultConfig()
253 {
254     totalFeatureSwitch = 1;
255     cameraRotateStrategyInfos_.clear();
256 }
257 
GetCameraRotateStrategyInfos()258 std::vector<CameraRotateStrategyInfo> CameraRoateParamManager::GetCameraRotateStrategyInfos()
259 {
260     return cameraRotateStrategyInfos_;
261 }
262 
SubscriberEvent()263 void CameraRoateParamManager::SubscriberEvent()
264 {
265     MEDIA_INFO_LOG("SubscriberEvent start.");
266     // 可以添加多个事件监听
267     handleEventFunc_["usual.event.DUE_SA_CFG_UPDATED"] = &CameraRoateParamManager::HandleParamUpdate;
268     for (auto it = handleEventFunc_.begin(); it != handleEventFunc_.end(); ++it) {
269         MEDIA_INFO_LOG("Add event: %{public}s", it->first.c_str());
270         eventHandles_.emplace(it->first, std::bind(it->second, this, std::placeholders::_1));
271     }
272     CHECK_RETURN_ELOG(subscriber_, "Common Event is already subscribered!");
273     EventFwk::MatchingSkills matchingSkills;
274     for (auto &event : handleEventFunc_) {
275         MEDIA_INFO_LOG("Add event: %{public}s", event.first.c_str());
276         matchingSkills.AddEvent(event.first);
277     }
278     EventFwk::CommonEventSubscribeInfo subscribeInfo(matchingSkills);
279     subscribeInfo.SetPermission(RECEIVE_UPDATE_PERMISSION);
280     subscriber_ = std::make_shared<ParamCommonEventSubscriber>(subscribeInfo, *this);
281 
282     int32_t retry = RETRY_SUBSCRIBER;
283     do {
284         bool subscribeResult = EventFwk::CommonEventManager::SubscribeCommonEvent(subscriber_);
285         if (subscribeResult) {
286             MEDIA_INFO_LOG("SubscriberEvent success.");
287             return;
288         } else {
289             MEDIA_ERR_LOG("SubscriberEvent failed, retry %{public}d", retry);
290             retry--;
291             sleep(1);
292         }
293     } while (retry);
294     MEDIA_INFO_LOG("SubscriberEvent failed.");
295 }
296 
UnSubscriberEvent()297 void CameraRoateParamManager::UnSubscriberEvent()
298 {
299     MEDIA_INFO_LOG("UnSubscriberEvent start.");
300     eventHandles_.clear();
301     handleEventFunc_.clear();
302     if (subscriber_) {
303         bool subscribeResult = EventFwk::CommonEventManager::UnSubscribeCommonEvent(subscriber_);
304         MEDIA_INFO_LOG("subscribeResult = %{public}d", subscribeResult);
305         subscriber_ = nullptr;
306     }
307     MEDIA_INFO_LOG("UnSubscriberEvent end.");
308 }
309 
OnReceiveEvent(const AAFwk::Want & want)310 void CameraRoateParamManager::OnReceiveEvent(const AAFwk::Want &want)
311 {
312     std::string action = want.GetAction();
313     auto it = eventHandles_.find(action);
314     if (it == eventHandles_.end()) {
315         MEDIA_INFO_LOG("Ignore event: %{public}s", action.c_str());
316         return;
317     }
318     MEDIA_INFO_LOG("Handle event: %{public}s", action.c_str());
319     it->second(want);
320 }
321 
HandleParamUpdate(const AAFwk::Want & want) const322 void CameraRoateParamManager::HandleParamUpdate(const AAFwk::Want &want) const
323 {
324     std::string action = want.GetAction();
325     std::string type = want.GetStringParam(EVENT_INFO_TYPE);
326     std::string subtype = want.GetStringParam(EVENT_INFO_SUBTYPE);
327     MEDIA_INFO_LOG("recive param update event: %{public}s ,%{public}s ,%{public}s ", action.c_str(), type.c_str(),
328         subtype.c_str());
329     if (action != CONFIG_UPDATED_ACTION || type != CONFIG_TYPE) {
330         MEDIA_ERR_LOG("invalid param update info: %{public}s, %{public}s, %{public}s",
331             action.c_str(), type.c_str(), subtype.c_str());
332         return;
333     }
334     CameraRoateParamManager::GetInstance().InitParam();
335 }
336 // LCOV_EXCL_STOP
337 }
338 }
339