From 6a27a4245724aee865d33d1d8fd12fd01f68dba7 Mon Sep 17 00:00:00 2001 From: h00514358 Date: Sat, 27 Aug 2022 17:00:31 +0800 Subject: [PATCH 1/2] Modify the limit of the number of parameters Signed-off-by: h00514358 Change-Id: I93b927c092bd75b24c58249639b413506452d0d5 --- .../miscdevice_service/src/miscdevice_dump.cpp | 17 +++++++++++++++++ .../src/miscdevice_service.cpp | 5 ++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/services/miscdevice_service/src/miscdevice_dump.cpp b/services/miscdevice_service/src/miscdevice_dump.cpp index 3975816..f40a8a1 100644 --- a/services/miscdevice_service/src/miscdevice_dump.cpp +++ b/services/miscdevice_service/src/miscdevice_dump.cpp @@ -34,10 +34,27 @@ constexpr uint32_t BASE_YEAR = 1900; constexpr uint32_t BASE_MON = 1; constexpr int32_t INVALID_PID = -1; constexpr int32_t INVALID_UID = -1; +constexpr int32_t MAX_DUMP_PARAMETERS = 32; } // namespace void MiscdeviceDump::ParseCommand(int32_t fd, const std::vector& args) { + int32_t count = 0; + for (const auto &str : args) { + if (str.find("--") == 0) { + ++count; + continue; + } + if (str.find("-") == 0) { + count += str.size() - 1; + continue; + } + } + if (count > MAX_DUMP_PARAMETERS) { + MISC_HILOGE("cmd param number not more than 32"); + dprintf(fd, "cmd param number not more than 32\n"); + return; + } int32_t optionIndex = 0; struct option dumpOptions[] = { {"record", no_argument, 0, 'r'}, diff --git a/services/miscdevice_service/src/miscdevice_service.cpp b/services/miscdevice_service/src/miscdevice_service.cpp index fc6fa19..f8420f2 100644 --- a/services/miscdevice_service/src/miscdevice_service.cpp +++ b/services/miscdevice_service/src/miscdevice_service.cpp @@ -29,7 +29,6 @@ constexpr HiLogLabel LABEL = { LOG_CORE, MISC_LOG_DOMAIN, "MiscdeviceService" }; constexpr int32_t MIN_VIBRATOR_TIME = 0; constexpr int32_t MAX_VIBRATOR_TIME = 1800000; constexpr int32_t DEFAULT_VIBRATOR_ID = 123; -constexpr int32_t MAX_DUMP_PARAMETERS = 32; } // namespace bool MiscdeviceService::ready_ = false; @@ -416,8 +415,8 @@ void MiscdeviceService::VibratorEffectThread::UpdateVibratorEffectData(const std int32_t MiscdeviceService::Dump(int32_t fd, const std::vector &args) { CALL_LOG_ENTER; - if (fd < 0 || args.size() > MAX_DUMP_PARAMETERS) { - MISC_HILOGE("fd is invalid or wrong number of parameters"); + if (fd < 0) { + MISC_HILOGE("Invalid fd"); return DUMP_PARAM_ERR; } if (args.empty()) { -- Gitee From 75e74ff15e7217c53074d309b6cafbe607828ce1 Mon Sep 17 00:00:00 2001 From: h00514358 Date: Sat, 27 Aug 2022 17:12:21 +0800 Subject: [PATCH 2/2] Support motor priority management requirements Signed-off-by: h00514358 Change-Id: If1fdd2ca5d45cca7dbb2b247440ba0d96022d61c --- services/miscdevice_service/BUILD.gn | 16 +- .../config/vibration_priority_config.json | 31 ++++ .../include/vibration_priority_manager.h | 88 +++++++++ .../include/vibrator_infos.h | 38 ++++ .../include/vibrator_thread.h | 44 +++++ .../src/vibration_priority_manager.cpp | 105 +++++++++++ .../src/vibrator_thread.cpp | 80 +++++++++ utils/BUILD.gn | 4 + utils/include/miscdevice_json_parser.h | 46 +++++ utils/include/sensors_errors.h | 7 + utils/src/miscdevice_json_parser.cpp | 167 ++++++++++++++++++ 11 files changed, 625 insertions(+), 1 deletion(-) create mode 100755 services/miscdevice_service/config/vibration_priority_config.json create mode 100755 services/miscdevice_service/include/vibration_priority_manager.h create mode 100755 services/miscdevice_service/include/vibrator_infos.h create mode 100755 services/miscdevice_service/include/vibrator_thread.h create mode 100755 services/miscdevice_service/src/vibration_priority_manager.cpp create mode 100755 services/miscdevice_service/src/vibrator_thread.cpp create mode 100755 utils/include/miscdevice_json_parser.h create mode 100755 utils/src/miscdevice_json_parser.cpp diff --git a/services/miscdevice_service/BUILD.gn b/services/miscdevice_service/BUILD.gn index 728b6d9..6ea5d65 100644 --- a/services/miscdevice_service/BUILD.gn +++ b/services/miscdevice_service/BUILD.gn @@ -22,6 +22,8 @@ ohos_shared_library("libmiscdevice_service") { "src/miscdevice_dump.cpp", "src/miscdevice_service.cpp", "src/miscdevice_service_stub.cpp", + "src/vibration_priority_manager.cpp", + "src/vibrator_thread.cpp", ] include_dirs = [ @@ -32,6 +34,7 @@ ohos_shared_library("libmiscdevice_service") { "$SUBSYSTEM_DIR/miscdevice/utils/include", "hdi_connection/adpter/include", "hdi_connection/interface/include", + "//third_party/cJSON", ] cflags = [ "-Wno-error=inconsistent-missing-override" ] @@ -53,6 +56,17 @@ ohos_shared_library("libmiscdevice_service") { subsystem_name = "sensors" } +ohos_prebuilt_etc("vibration_config") { + source = "config/vibration_priority_config.json" + install_enable = true + install_images = [ "vendor" ] + module_install_dir = "etc/vibrator" + part_name = "miscdevice" +} + group("miscdevice_service_target") { - deps = [ ":libmiscdevice_service" ] + deps = [ + ":libmiscdevice_service", + ":vibration_config", + ] } diff --git a/services/miscdevice_service/config/vibration_priority_config.json b/services/miscdevice_service/config/vibration_priority_config.json new file mode 100755 index 0000000..bc58d96 --- /dev/null +++ b/services/miscdevice_service/config/vibration_priority_config.json @@ -0,0 +1,31 @@ +{ + "privilegePkgs": [], + "trustLists": { + "globalSettings": { + "byPassUsages": [], + "byPassPkgs": [], + "filterUsages": [], + "filterPkgs": [] + }, + "lowPowerMode": { + "byPassUsages": [], + "byPassPkgs": [], + "filterUsages": [], + "filterPkgs": [] + }, + "specialForeground": { + "calling": { + "byPassUsages": [], + "byPassPkgs": [], + "filterUsages": [], + "filterPkgs": [] + }, + "camera": { + "byPassUsages": [], + "byPassPkgs": [], + "filterUsages": [], + "filterPkgs": [] + } + } + } +} \ No newline at end of file diff --git a/services/miscdevice_service/include/vibration_priority_manager.h b/services/miscdevice_service/include/vibration_priority_manager.h new file mode 100755 index 0000000..0e51c1d --- /dev/null +++ b/services/miscdevice_service/include/vibration_priority_manager.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef VIBRATION_PRIORITY_MANAGER_H +#define VIBRATION_PRIORITY_MANAGER_H +#include +#include +#include +#include + +#include "miscdevice_json_parser.h" +#include "singleton.h" +#include "vibrator_infos.h" +#include "vibrator_thread.h" +namespace OHOS { +namespace Sensors { + +typedef enum { + VIBRATION = 0, + IGNORE_FOR_BACKGROUND = 1, + IGNORE_FOR_LOW_POWER = 2, + IGNORE_FOR_GLOBAL_SETTINGS = 3, + IGNORE_FOR_RINGTONE = 4, + IGNORE_FOR_REPEAT = 5, + IGNORE_FOR_ALARM = 6, + IGNORE_FOR_UNKNOWN = 7, +} VibrateStatus; + +typedef enum { + USAGE_UNKNOWN = 0, /**< Vibration is used for unknown, lowest priority */ + USAGE_ALARM = 1, /**< Vibration is used for alarm */ + USAGE_RING = 2, /**< Vibration is used for ring */ + USAGE_NOTIFICATION = 3, /**< Vibration is used for notification */ + USAGE_COMMUNICATION = 4, /**< Vibration is used for communication */ + USAGE_TOUCH = 5, /**< Vibration is used for touch */ + USAGE_MEDIA = 6, /**< Vibration is used for media */ + USAGE_PHYSICAL_FEEDBACK = 7, /**< Vibration is used for physical feedback */ + USAGE_SIMULATE_REALITY = 8, /**< Vibration is used for simulate reality */ + USAGE_MAX = 9, +} VibrateUsage; + +typedef struct { + std::vector byPassUsages; + std::vector byPassPkgs; + std::vector filterUsages; + std::vector filterPkgs; +} PriorityItem; + +typedef struct { + PriorityItem calling; + PriorityItem camera; +} SpecialForeground; + +typedef struct { + std::vector privilegePkgs; + PriorityItem globalSettings; + PriorityItem lowPowerMode; + SpecialForeground specialForeground; +} PriorityConfig; + +class VibrationPriorityManager : public Singleton { +public: + VibrationPriorityManager(); + VibrateStatus ShouldIgnoreVibrate(VibrateInfo vibrateInfo, std::shared_ptr vibratorThread); + +private: + int32_t LoadPriorityConfig(const std::string &configPath); + int32_t ParserPriorityItem(cJSON *json, const std::string& key, PriorityItem& item); + PriorityConfig PriorityConfig_; + std::unique_ptr jsonParser_; + DISALLOW_COPY_AND_MOVE(VibrationPriorityManager); +}; + +} // namespace Sensors +} // namespace OHOS +#endif // VIBRATION_PRIORITY_MANAGER_H \ No newline at end of file diff --git a/services/miscdevice_service/include/vibrator_infos.h b/services/miscdevice_service/include/vibrator_infos.h new file mode 100755 index 0000000..6260194 --- /dev/null +++ b/services/miscdevice_service/include/vibrator_infos.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef VIBRATOR_INFOS_H +#define VIBRATOR_INFOS_H +#include +#include +namespace OHOS { +namespace Sensors { +static std::unordered_map VibratorEffectMap = { + {"haptic.clock.timer", 2000}, + {"haptic.default.effect", 804} +}; + +typedef struct { + std::string mode; + std::string packageName; + int32_t pid; + uint32_t usage; + uint32_t duration; + std::string effect; + uint32_t count; +} VibrateInfo; +} // namespace Sensors +} // namespace OHOS +#endif // VIBRATOR_INFOS_H \ No newline at end of file diff --git a/services/miscdevice_service/include/vibrator_thread.h b/services/miscdevice_service/include/vibrator_thread.h new file mode 100755 index 0000000..c2d093f --- /dev/null +++ b/services/miscdevice_service/include/vibrator_thread.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef VIBRATOR_THREAD_H +#define VIBRATOR_THREAD_H + +#include +#include +#include +#include "thread_ex.h" +#include "vibrator_infos.h" + +namespace OHOS { +namespace Sensors { +class VibratorThread : public Thread { +public: + void UpdateVibratorEffect(VibrateInfo vibrateInfo); + VibrateInfo GetCurrentVibrateInfo() const; + void SetReadyStatus(bool status); + static std::condition_variable conditionVar_; + +protected: + virtual bool Run(); + +private: + VibrateInfo currentVibration_; + static std::mutex conditionVarMutex_; + bool ready_; +}; +} // namespace Sensors +} // namespace OHOS +#endif // VIBRATOR_THREAD_H \ No newline at end of file diff --git a/services/miscdevice_service/src/vibration_priority_manager.cpp b/services/miscdevice_service/src/vibration_priority_manager.cpp new file mode 100755 index 0000000..c09aac1 --- /dev/null +++ b/services/miscdevice_service/src/vibration_priority_manager.cpp @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "vibration_priority_manager.h" + +#include "sensors_errors.h" + +namespace OHOS { +namespace Sensors { +using namespace OHOS::HiviewDFX; +namespace { +constexpr HiLogLabel LABEL = { LOG_CORE, MISC_LOG_DOMAIN, "VibrationPriorityManager" }; +const std::string CONFIG_PATH = "/vendor/etc/sensors/vibration_priority_config.json"; +} // namespace + +VibrationPriorityManager::VibrationPriorityManager() +{ + int32_t ret = LoadPriorityConfig(CONFIG_PATH); + if (ret != SUCCESS) { + MISC_HILOGE("lod priority config fail"); + } +} + +VibrateStatus VibrationPriorityManager::ShouldIgnoreVibrate(VibrateInfo vibrateInfo, + std::shared_ptr vibratorThread) +{ + std::vector privilegePkgs = PriorityConfig_.privilegePkgs; + if (std::find(privilegePkgs.begin(), privilegePkgs.end(), vibrateInfo.packageName) != privilegePkgs.end()) { + MISC_HILOGD("privilege application, can vibrate"); + return VIBRATION; + } + if ((vibratorThread == nullptr) || (!vibratorThread->IsRunning())) { + MISC_HILOGD("can vibrate"); + return VIBRATION; + } + if (vibrateInfo.mode == "preset" && (vibrateInfo.count > 1)) { + MISC_HILOGD("can vibrate, loop priority is high"); + return VIBRATION; + } + const VibrateInfo info = vibratorThread->GetCurrentVibrateInfo(); + if (info.usage == 1) { + MISC_HILOGD("vibration is ignored for alarm"); + return IGNORE_FOR_ALARM; + } + if (info.mode == "preset" && (info.count > 1)) { + MISC_HILOGD("vibration is ignored for repeat"); + return IGNORE_FOR_REPEAT; + } + if ((info.usage != vibrateInfo.usage) && (vibrateInfo.usage == USAGE_UNKNOWN)) { + MISC_HILOGD("vibration is ignored, unknown has a low priority"); + return IGNORE_FOR_UNKNOWN; + } + return VIBRATION; +} + +int32_t VibrationPriorityManager::LoadPriorityConfig(const std::string &configPath) +{ + jsonParser_ = std::make_unique(configPath); + cJSON* cJson = jsonParser_->GetJsonData(); + int32_t ret = jsonParser_->ParseJsonArray(cJson, "privilegePkgs", PriorityConfig_.privilegePkgs); + CHKCR((ret == SUCCESS), ERROR, "parse privilegePkgs fail"); + + cJSON* trustLists = jsonParser_->GetObjectItem(cJson, "trustLists"); + ret = ParserPriorityItem(trustLists, "globalSettings", PriorityConfig_.globalSettings); + CHKCR((ret == SUCCESS), ERROR, "parse globalSettings fail"); + + ret = ParserPriorityItem(trustLists, "lowPowerMode", PriorityConfig_.lowPowerMode); + CHKCR((ret == SUCCESS), ERROR, "parse lowPowerMode fail"); + + cJSON* specialForeground = jsonParser_->GetObjectItem(trustLists, "specialForeground"); + ret = ParserPriorityItem(specialForeground, "calling", PriorityConfig_.specialForeground.calling); + CHKCR((ret == SUCCESS), ERROR, "parse calling fail"); + ret = ParserPriorityItem(specialForeground, "camera", PriorityConfig_.specialForeground.camera); + CHKCR((ret == SUCCESS), ERROR, "parse camera fail"); + return SUCCESS; +} + +int32_t VibrationPriorityManager::ParserPriorityItem(cJSON *json, const std::string& key, + PriorityItem& item) +{ + cJSON* cJson = jsonParser_->GetObjectItem(json, key); + int32_t ret = jsonParser_->ParseJsonArray(cJson, "byPassUsages", item.byPassUsages); + CHKCR((ret == SUCCESS), ERROR, "parse byPassUsages fail"); + ret = jsonParser_->ParseJsonArray(cJson, "byPassPkgs", item.byPassPkgs); + CHKCR((ret == SUCCESS), ERROR, "parse byPassPkgs fail"); + ret = jsonParser_->ParseJsonArray(cJson, "filterUsages", item.filterUsages); + CHKCR((ret == SUCCESS), ERROR, "parse filterUsages fail"); + ret = jsonParser_->ParseJsonArray(cJson, "filterPkgs", item.filterPkgs); + CHKCR((ret == SUCCESS), ERROR, "parse filterPkgs fail"); + return SUCCESS; +} +} // namespace Sensors +} // namespace OHOS \ No newline at end of file diff --git a/services/miscdevice_service/src/vibrator_thread.cpp b/services/miscdevice_service/src/vibrator_thread.cpp new file mode 100755 index 0000000..0fb7ac1 --- /dev/null +++ b/services/miscdevice_service/src/vibrator_thread.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "vibrator_thread.h" + +#include "sensors_errors.h" +#include "vibrator_hdi_connection.h" + +namespace OHOS { +namespace Sensors { +using namespace OHOS::HiviewDFX; +namespace { +constexpr HiLogLabel LABEL = { LOG_CORE, MISC_LOG_DOMAIN, "VibratorThread" }; +} // namespace + +std::mutex VibratorThread::conditionVarMutex_; +std::condition_variable VibratorThread::conditionVar_; + +bool VibratorThread::Run() +{ + if (currentVibration_.mode == "time") { + std::unique_lock lck(conditionVarMutex_); + int32_t ret = VibratorHdiConnection::GetInstance().StartOnce(currentVibration_.duration); + if (ret != ERR_OK) { + MISC_HILOGE("StartOnce fail, duration: %{public}d, pid: %{public}d", + currentVibration_.duration, currentVibration_.pid); + return false; + } + conditionVar_.wait_for(lck, std::chrono::milliseconds(currentVibration_.duration)); + if (ready_) { + MISC_HILOGD("stop vibration"); + } + VibratorHdiConnection::GetInstance().Stop(IVibratorHdiConnection::VIBRATOR_STOP_MODE_TIME); + } else if (currentVibration_.mode == "preset") { + for (uint32_t i = 0; i < currentVibration_.count; ++i) { + std::unique_lock lck(conditionVarMutex_); + std::string effect = currentVibration_.effect; + int32_t ret = VibratorHdiConnection::GetInstance().Start(effect); + if (ret != ERR_OK) { + MISC_HILOGE("vibrate effect %{public}s failed, pid: %{public}d", effect.c_str(), currentVibration_.pid); + return false; + } + conditionVar_.wait_for(lck, std::chrono::milliseconds(currentVibration_.duration)); + if (ready_) { + MISC_HILOGD("stop vibration"); + } + VibratorHdiConnection::GetInstance().Stop(IVibratorHdiConnection::VIBRATOR_STOP_MODE_PRESET); + } + } + return false; +} + +void VibratorThread::UpdateVibratorEffect(VibrateInfo info) +{ + currentVibration_ = info; +} + +VibrateInfo VibratorThread::GetCurrentVibrateInfo() const +{ + return currentVibration_; +} + +void VibratorThread::SetReadyStatus(bool status) +{ + ready_ = status; +} +} // namespace Sensors +} // namespace OHOS diff --git a/utils/BUILD.gn b/utils/BUILD.gn index 43a9ae0..d54902d 100644 --- a/utils/BUILD.gn +++ b/utils/BUILD.gn @@ -15,6 +15,7 @@ import("//build/ohos.gni") ohos_shared_library("libmiscdevice_utils") { sources = [ "src/miscdevice_common.cpp", + "src/miscdevice_json_parser.cpp", "src/permission_util.cpp", ] @@ -22,8 +23,11 @@ ohos_shared_library("libmiscdevice_utils") { "include", "//commonlibrary/c_utils/base/include", "//utils/system/safwk/native/include", + "//third_party/cJSON", ] + deps = [ "//third_party/cJSON:cjson_static" ] + external_deps = [ "access_token:libaccesstoken_sdk", "c_utils:utils", diff --git a/utils/include/miscdevice_json_parser.h b/utils/include/miscdevice_json_parser.h new file mode 100755 index 0000000..20806cc --- /dev/null +++ b/utils/include/miscdevice_json_parser.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MISCDEVICE_JSON_PARSER_H +#define MISCDEVICE_JSON_PARSER_H +#include +#include + +#include "cJSON.h" + +namespace OHOS { +namespace Sensors { + +class MiscdeviceJsonParser { +public: + explicit MiscdeviceJsonParser(const std::string &filePath); + ~MiscdeviceJsonParser(); + int32_t ParseJsonArray(cJSON *json, const std::string& key, std::vector& vals) const; + cJSON* GetJsonData() const; + cJSON* GetObjectItem(cJSON *json, const std::string& key) const; + +private: + cJSON* cJson_ = nullptr; + std::string filePath_; + std::string ReadJsonFile(); + bool IsValidPath(const std::string &path); + bool CheckFileExtendName(const std::string& filePath, const std::string& checkExtension); + bool IsFileExists(const std::string& fileName); + std::string ReadFile(const std::string &filePath); + int32_t GetFileSize(const std::string& filePath); +}; +} // namespace Sensors +} // namespace OHOS +#endif // MISCDEVICE_JSON_PARSER_H \ No newline at end of file diff --git a/utils/include/sensors_errors.h b/utils/include/sensors_errors.h index 1493362..a14ec92 100644 --- a/utils/include/sensors_errors.h +++ b/utils/include/sensors_errors.h @@ -241,6 +241,13 @@ private: } \ } while (0) +#define CHKCR(cond, r, errDesc) \ + do { \ + if (!(cond)) { \ + MISC_HILOGE("%{public}s, errCode:%{public}d", #errDesc, r); \ + return r; \ + } \ + } while (0) #endif } // namespace Sensors } // namespace OHOS diff --git a/utils/src/miscdevice_json_parser.cpp b/utils/src/miscdevice_json_parser.cpp new file mode 100755 index 0000000..4db7ab9 --- /dev/null +++ b/utils/src/miscdevice_json_parser.cpp @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "miscdevice_json_parser.h" + +#include +#include + +#include "permission_util.h" +#include "sensors_errors.h" + +namespace OHOS { +namespace Sensors { +using namespace OHOS::HiviewDFX; +namespace { +constexpr HiLogLabel LABEL = { LOG_CORE, MISC_LOG_DOMAIN, "MiscdeviceJsonParser" }; +const std::string CONFIG_DIR = "/vendor/etc/sensors/"; +constexpr int32_t FILE_SIZE_MAX = 0x5000; +constexpr int32_t READ_DATA_BUFF_SIZE = 256; +constexpr int32_t INVALID_FILE_SIZE = -1; +} // namespace + +MiscdeviceJsonParser::MiscdeviceJsonParser(const std::string &filePath) +{ + filePath_ = filePath; + std::string jsonStr = ReadJsonFile(); + if (jsonStr == "") { + MISC_HILOGE("read json file fail"); + return; + } + cJson_ = cJSON_Parse(jsonStr.c_str()); +} + +MiscdeviceJsonParser::~MiscdeviceJsonParser() { + CHKPV(cJson_); + delete cJson_; + cJson_ = nullptr; +}; + +cJSON* MiscdeviceJsonParser::GetJsonData() const +{ + return cJson_; +} + +std::string MiscdeviceJsonParser::ReadJsonFile() +{ + if (filePath_.empty()) { + MISC_HILOGE("path is empty"); + return ""; + } + char realPath[PATH_MAX] = {}; + if (realpath(filePath_.c_str(), realPath) == nullptr) { + MISC_HILOGE("path is error"); + return ""; + } + if (!IsValidPath(realPath)) { + MISC_HILOGE("path is invalid"); + return ""; + } + return ReadFile(filePath_); +} + +cJSON* MiscdeviceJsonParser::GetObjectItem(cJSON *json, const std::string& key) const +{ + if (!cJSON_IsObject(json)) { + MISC_HILOGE("The json is not object"); + return nullptr; + } + if (!cJSON_HasObjectItem(json, key.c_str())) { + MISC_HILOGE("The json is not data:%{public}s", key.c_str()); + return nullptr; + } + return cJSON_GetObjectItem(json, key.c_str()); +} + +int32_t MiscdeviceJsonParser::ParseJsonArray(cJSON *json, const std::string& key, + std::vector& vals) const +{ + cJSON* jsonArray = GetObjectItem(json, key); + if (!cJSON_IsArray(jsonArray)) { + MISC_HILOGE("The value of %{public}s is not array", key.c_str()); + return ERROR; + } + int32_t jsonArraySize = cJSON_GetArraySize(jsonArray); + for (int32_t i = 0; i < jsonArraySize; ++i) { + cJSON* val = cJSON_GetArrayItem(jsonArray, i); + if (cJSON_IsString(val)) { + vals.push_back(val->valuestring); + } + } + return SUCCESS; +} + +int32_t MiscdeviceJsonParser::GetFileSize(const std::string& filePath) +{ + struct stat statbuf = {0}; + if (stat(filePath.c_str(), &statbuf) != 0) { + MISC_HILOGE("get file size error"); + return INVALID_FILE_SIZE; + } + return statbuf.st_size; +} + +bool MiscdeviceJsonParser::IsValidPath(const std::string &filePath) +{ + if (filePath.compare(0, CONFIG_DIR.size(), CONFIG_DIR) != 0) { + MISC_HILOGE("filePath dir is invalid"); + return false; + } + if (!CheckFileExtendName(filePath, ".json")) { + MISC_HILOGE("Unable to parse files other than json format"); + return false; + } + if (!IsFileExists(filePath)) { + MISC_HILOGE("file not exist"); + return false; + } + int32_t fileSize = GetFileSize(filePath); + if ((fileSize <= 0) || (fileSize > FILE_SIZE_MAX)) { + MISC_HILOGE("file size out of read range"); + return false; + } + return true; +} + +bool MiscdeviceJsonParser::CheckFileExtendName(const std::string& filePath, const std::string& checkExtension) +{ + std::string::size_type pos = filePath.find_last_of('.'); + if (pos == std::string::npos) { + MISC_HILOGE("file is not find extension"); + return false; + } + return (filePath.substr(pos + 1, filePath.npos) == checkExtension); +} + +bool MiscdeviceJsonParser::IsFileExists(const std::string& fileName) +{ + return (access(fileName.c_str(), F_OK) == 0); +} + +std::string MiscdeviceJsonParser::ReadFile(const std::string &filePath) +{ + FILE* fp = fopen(filePath.c_str(), "r"); + CHKPS(fp); + std::string dataStr; + char buf[READ_DATA_BUFF_SIZE] = {}; + while (fgets(buf, sizeof(buf), fp) != nullptr) { + dataStr += buf; + } + if (fclose(fp) != 0) { + MISC_HILOGW("close file failed"); + } + return dataStr; +} +} // namespace Sensors +} // namespace OHOS \ No newline at end of file -- Gitee