diff --git a/adapter/native/idl/BUILD.gn b/adapter/native/idl/BUILD.gn index a9f48846a49057d3cb27499f0296d0187ede081c..7331f59ba11556aad6758d9e927afef56e248492 100644 --- a/adapter/native/idl/BUILD.gn +++ b/adapter/native/idl/BUILD.gn @@ -20,6 +20,7 @@ config("sys_event_impl_config") { ".", "include", "//foundation/systemabilitymgr/safwk/services/safwk/include", + "//foundation/ability/ability_runtime/interfaces/kits/native/appkit/ability_runtime/context", ] } @@ -30,22 +31,28 @@ ohos_source_set("sys_event_impl_client") { ] sources = [ + "src/file_util.cpp", "src/hisysevent_delegate.cpp", "src/hisysevent_listener_proxy.cpp", "src/hisysevent_query_proxy.cpp", ] - deps = [ "//third_party/jsoncpp:jsoncpp" ] + deps = [ + "//foundation/ability/ability_runtime/frameworks/native/appkit:app_context", + "//third_party/jsoncpp:jsoncpp", + ] all_dependent_configs = [ ":sys_event_impl_config" ] public_configs = [ "//base/hiviewdfx/hisysevent/interfaces/native/innerkits/hisysevent_manager:hisyseventmanager_config" ] external_deps = [ + "bundle_framework:appexecfwk_core", "c_utils:utils", "hilog_native:libhilog", "ipc:ipc_core", "samgr:samgr_proxy", + "storage_service:storage_manager_acl", ] part_name = "hisysevent_native" diff --git a/adapter/native/idl/include/file_util.h b/adapter/native/idl/include/file_util.h new file mode 100644 index 0000000000000000000000000000000000000000..9e9478e6f259b5a372025db1b3406b3dc09a1061 --- /dev/null +++ b/adapter/native/idl/include/file_util.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2023 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 OHOS_HIVIEWDFX_FILE_UTILS_H +#define OHOS_HIVIEWDFX_FILE_UTILS_H + +#include +#include +#include + +namespace OHOS { +namespace HiviewDFX { +namespace FileUtil { +bool IsFileExists(const std::string& file); +bool IsFile(const std::string& file); +bool IsDirectory(const std::string& dir); +bool RemoveFile(const std::string& file); +bool RemoveDirectory(const std::string& dir); +bool ForceCreateDirectory(const std::string& dir); +std::string GetFilePathByDir(const std::string& dir, const std::string& fileName); +int CopyFile(const std::string &src, const std::string &des); +bool IsLegalPath(const std::string& path); +} // namespace FileUtil +} // namespace HiviewDFX +} // namespace OHOS + +#endif // OHOS_HIVIEWDFX_FILE_UTILS_H \ No newline at end of file diff --git a/adapter/native/idl/include/hisysevent_delegate.h b/adapter/native/idl/include/hisysevent_delegate.h index 7f0a4ae93e47e24abcf815964ad66956032cd13f..c909d5343554051f21862037bfe06f66a10d574c 100644 --- a/adapter/native/idl/include/hisysevent_delegate.h +++ b/adapter/native/idl/include/hisysevent_delegate.h @@ -47,6 +47,9 @@ public: const std::shared_ptr callback) const; int32_t SetDebugMode(const std::shared_ptr listener, const bool mode); + int64_t Export(const struct QueryArg& arg, const std::vector& rules) const; + int64_t Subscribe(const std::vector& rules) const; + int32_t Unsubscribe() const; private: void ConvertListenerRule(const std::vector& rules, @@ -54,6 +57,8 @@ private: void ConvertQueryRule(const std::vector& rules, std::vector& sysRules) const; sptr GetSysEventService() const; + bool CreateHiviewDir() const; + bool SetDirPermission() const; private: sptr spListenerCallBack = nullptr; diff --git a/adapter/native/idl/include/isys_event_service.h b/adapter/native/idl/include/isys_event_service.h index b09b2fd731939d4592699d6f7a38e411a3c50f8d..849e9947da3fb77612fbe75d3f5d629583b67770 100644 --- a/adapter/native/idl/include/isys_event_service.h +++ b/adapter/native/idl/include/isys_event_service.h @@ -35,12 +35,18 @@ public: virtual int32_t Query(const QueryArgument& queryArgument, const std::vector& rules, const sptr& callback) = 0; virtual int32_t SetDebugMode(const sptr& callback, bool mode) = 0; + virtual int64_t AddSubscriber(const std::vector &rules) = 0; + virtual int32_t RemoveSubscriber() = 0; + virtual int64_t Export(const QueryArgument &queryArgument, const std::vector &rules) = 0; enum { ADD_SYS_EVENT_LISTENER = 0, REMOVE_SYS_EVENT_LISTENER, QUERY_SYS_EVENT, - SET_DEBUG_MODE + SET_DEBUG_MODE, + ADD_SYS_EVENT_SUBSCRIBER, + REMOVE_SYS_EVENT_SUBSCRIBER, + EXPORT_SYS_EVENT }; public: diff --git a/adapter/native/idl/include/ret_code.h b/adapter/native/idl/include/ret_code.h index 3c5d5d656f73f89db37e2ce577c6ea9f1b368e7e..b18716e44092f801ee62911abc7d6a59a3025a33 100644 --- a/adapter/native/idl/include/ret_code.h +++ b/adapter/native/idl/include/ret_code.h @@ -44,6 +44,10 @@ static constexpr int32_t ERR_TOO_MANY_CONCURRENT_QUERIES = -28; static constexpr int32_t ERR_QUERY_OVER_TIME = -29; static constexpr int32_t ERR_QUERY_OVER_LIMIT = -30; static constexpr int32_t ERR_QUERY_TOO_FREQUENTLY = -31; + +static constexpr int32_t ERR_TOO_MANY_EVENTS = -32; +static constexpr int32_t ERR_EXPORT_FREQUENCY_OVER_LIMIT = -33; + } // namespace HiviewDFX } // namespace OHOS diff --git a/adapter/native/idl/include/sys_event_service_proxy.h b/adapter/native/idl/include/sys_event_service_proxy.h index c1973e33083a9d8e9e72b03df89f1ebfb2abc547..4003723c828f8d8e3019feb82e7ada6c2393c94d 100644 --- a/adapter/native/idl/include/sys_event_service_proxy.h +++ b/adapter/native/idl/include/sys_event_service_proxy.h @@ -16,6 +16,8 @@ #ifndef OHOS_HIVIEWDFX_SYS_EVENT_SERVICE_PROXY_H #define OHOS_HIVIEWDFX_SYS_EVENT_SERVICE_PROXY_H +#include + #include "iremote_proxy.h" #include "isys_event_service.h" #include "query_argument.h" @@ -34,6 +36,9 @@ public: int32_t Query(const QueryArgument& queryArgument, const std::vector& rules, const sptr& callback); int32_t SetDebugMode(const sptr& callback, bool mode); + int64_t AddSubscriber(const std::vector &rules); + int32_t RemoveSubscriber(); + int64_t Export(const QueryArgument &queryArgument, const std::vector &rules); private: static inline BrokerDelegator delegator_; diff --git a/adapter/native/idl/include/sys_event_service_stub.h b/adapter/native/idl/include/sys_event_service_stub.h index 8eda9f4b49b43a855dd1ad831f4fe7459b63a682..c1f0386cf130f97e0d5960c5bf4da92643c3567b 100644 --- a/adapter/native/idl/include/sys_event_service_stub.h +++ b/adapter/native/idl/include/sys_event_service_stub.h @@ -39,6 +39,12 @@ private: MessageParcel& reply, MessageOption& option); int32_t HandleSetDebugMode(MessageParcel& data, MessageParcel& reply, MessageOption& option); + int32_t HandleAddSubscriber(MessageParcel& data, + MessageParcel& reply, MessageOption& option); + int32_t HandleRemoveSubscriber(MessageParcel& data, + MessageParcel& reply, MessageOption& option); + int32_t HandleExportEvent(MessageParcel& data, + MessageParcel& reply, MessageOption& option); }; } // namespace HiviewDFX } // namespace OHOS diff --git a/adapter/native/idl/src/file_util.cpp b/adapter/native/idl/src/file_util.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0c43885ade2b0f1b023bec33a0f0389d1f67fc8c --- /dev/null +++ b/adapter/native/idl/src/file_util.cpp @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2023 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 "file_util.h" + +#include +#include +#include +#include +#include +#include + +namespace OHOS { +namespace HiviewDFX { +namespace FileUtil { +namespace { +const char PATH_DELIMITER = '/'; +} +bool IsFileExists(const std::string& file) +{ + return access(file.c_str(), F_OK) == 0; +} + +bool IsFile(const std::string& file) +{ + struct stat statBuf {}; + return lstat(file.c_str(), &statBuf) == 0 ? S_ISREG(statBuf.st_mode) : false; +} + +bool IsDirectory(const std::string& dir) +{ + struct stat statBuf {}; + return lstat(dir.c_str(), &statBuf) == 0 ? S_ISDIR(statBuf.st_mode) : false; +} + +bool RemoveFile(const std::string& file) +{ + return !IsFileExists(file) || (remove(file.c_str()) == 0); +} + +bool RemoveDirectory(const std::string& dir) +{ + return !IsFileExists(dir) || (rmdir(dir.c_str()) == 0); +} + +bool ForceCreateDirectory(const std::string& dir) +{ + std::string::size_type index = 0; + do { + std::string subPath; + index = dir.find('/', index + 1); // (index + 1) means the next char traversed + if (index == std::string::npos) { + subPath = dir; + } else { + subPath = dir.substr(0, index); + } + + if (!IsFileExists(subPath) && mkdir(subPath.c_str(), S_IRWXU) != 0) { + return false; + } + } while (index != std::string::npos); + return IsFileExists(dir); +} + +std::string GetFilePathByDir(const std::string& dir, const std::string& fileName) +{ + if (dir.empty()) { + return fileName; + } + std::string filePath = dir; + if (filePath.back() != '/') { + filePath.push_back(PATH_DELIMITER); + } + filePath.append(fileName); + return filePath; +} + +int CopyFile(const std::string &src, const std::string &des) +{ + std::ifstream fin(src, std::ios::binary); + std::ofstream fout(des, std::ios::binary); + if (!fin.is_open()) { + return -1; + } + if (!fout.is_open()) { + return -1; + } + fout << fin.rdbuf(); + if (fout.fail()) { + fout.clear(); + } + fout.flush(); + return 0; +} + +bool IsLegalPath(const std::string& path) +{ + if (path.find("./") != std::string::npos || + path.find("../") != std::string::npos) { + return false; + } + return true; +} +} // namespace FileUtil +} // namespace HiviewDFX +} // namespace OHOS diff --git a/adapter/native/idl/src/hisysevent_delegate.cpp b/adapter/native/idl/src/hisysevent_delegate.cpp index 66d1c1117ec07d49116f2da1780591e12664201b..8663eb2b7991fb12d1671e91c8b83c2b1ba9dce3 100644 --- a/adapter/native/idl/src/hisysevent_delegate.cpp +++ b/adapter/native/idl/src/hisysevent_delegate.cpp @@ -15,6 +15,11 @@ #include "hisysevent_delegate.h" +#include + +#include "application_context.h" +#include "context.h" +#include "file_util.h" #include "hilog/log.h" #include "hisysevent_listener_proxy.h" #include "hisysevent_query_proxy.h" @@ -23,14 +28,24 @@ #include "iservice_registry.h" #include "query_argument.h" #include "ret_code.h" +#include "storage_acl.h" #include "sys_event_service_proxy.h" #include "system_ability_definition.h" using namespace std; +using namespace OHOS::StorageDaemon; namespace OHOS { namespace HiviewDFX { -static constexpr HiLogLabel LABEL = { LOG_CORE, 0xD002D08, "HiView-HiSysEventDelegate" }; + +namespace { +constexpr HiLogLabel LABEL = { LOG_CORE, 0xD002D08, "HiView-HiSysEventDelegate" }; +const std::string HIVIEW_DIR = "/hiview/"; +const std::string EVENT_DIR = "/event/"; +const std::string PARENT_DIR_PERMISSION = "g:1201:x"; +const std::string SUB_DIR_PERMISSION = "g:1201:rwx"; +constexpr int ACL_SUCC = 0; +} int32_t HiSysEventDelegate::AddListener(const std::shared_ptr listener, const std::vector& rules) @@ -102,6 +117,67 @@ int32_t HiSysEventDelegate::Query(const struct QueryArg& arg, return sysEventService.Query(queryArgument, hospRules, spCallBack); } +int64_t HiSysEventDelegate::Export(const struct QueryArg& arg, const std::vector& rules) const +{ + auto service = GetSysEventService(); + if (service == nullptr) { + HiLog::Error(LABEL, "Fail to get service."); + return ERR_SYS_EVENT_SERVICE_NOT_FOUND; + } + auto res = CreateHiviewDir(); + if (!res) { + HiLog::Error(LABEL, "Fail to create hiview dir."); + return ERR_SYS_EVENT_SERVICE_NOT_FOUND; + } + res = SetDirPermission(); + if (!res) { + HiLog::Error(LABEL, "Fail to set ACL permission."); + return ERR_SYS_EVENT_SERVICE_NOT_FOUND; + } + std::vector hospRules; + ConvertQueryRule(rules, hospRules); + SysEventServiceProxy sysEventService(service); + QueryArgument queryArgument(arg.beginTime, arg.endTime, arg.maxEvents, arg.fromSeq, arg.toSeq); + return sysEventService.Export(queryArgument, hospRules); +} + +int64_t HiSysEventDelegate::Subscribe(const std::vector& rules) const +{ + auto service = GetSysEventService(); + if (service == nullptr) { + HiLog::Error(LABEL, "Fail to get service."); + return ERR_SYS_EVENT_SERVICE_NOT_FOUND; + } + + auto res = CreateHiviewDir(); + if (!res) { + HiLog::Error(LABEL, "Fail to create hiview dir."); + return ERR_SYS_EVENT_SERVICE_NOT_FOUND; + } + res = SetDirPermission(); + if (!res) { + HiLog::Error(LABEL, "Fail to set ACL permission."); + return ERR_SYS_EVENT_SERVICE_NOT_FOUND; + } + + std::vector hospRules; + ConvertQueryRule(rules, hospRules); + + SysEventServiceProxy sysEventService(service); + return sysEventService.AddSubscriber(hospRules); +} + +int32_t HiSysEventDelegate::Unsubscribe() const +{ + auto service = GetSysEventService(); + if (service == nullptr) { + HiLog::Error(LABEL, "Fail to get service."); + return ERR_SYS_EVENT_SERVICE_NOT_FOUND; + } + SysEventServiceProxy sysEventService(service); + return sysEventService.RemoveSubscriber(); +} + HiSysEventDelegate::~HiSysEventDelegate() { HiLog::Info(LABEL, "HiSysEventDelegate destructor"); @@ -145,5 +221,73 @@ sptr HiSysEventDelegate::GetSysEventService() const } return sam->CheckSystemAbility(DFX_SYS_EVENT_SERVICE_ABILITY_ID); } + +bool HiSysEventDelegate::CreateHiviewDir() const +{ + std::shared_ptr context = + OHOS::AbilityRuntime::Context::GetApplicationContext(); + if (context == nullptr) { + HiLog::Error(LABEL, "GetHiViewDir Context is null."); + return false; + } + if (context->GetCacheDir().empty()) { + HiLog::Error(LABEL, "GetHiViewDir The files dir obtained from context is empty."); + return false; + } + std::string eventDirPath = context->GetCacheDir() + HIVIEW_DIR + EVENT_DIR; + if (FileUtil::IsFileExists(eventDirPath)) { + return true; + } + if (!FileUtil::ForceCreateDirectory(eventDirPath)) { + HiLog::Error(LABEL, "failed to create event dir, errno=%{public}d.", errno); + return false; + } + return true; +} + +bool HiSysEventDelegate::SetDirPermission() const +{ + std::shared_ptr context = + OHOS::AbilityRuntime::Context::GetApplicationContext(); + if (context == nullptr) { + HiLog::Error(LABEL, "GetHiViewDir Context is null."); + return false; + } + if (context->GetCacheDir().empty()) { + HiLog::Error(LABEL, "GetHiViewDir The files dir obtained from context is empty."); + return false; + } + std::string baseDirPath = context->GetBaseDir(); + std::string cacheDirPath = context->GetCacheDir(); + std::string hiviewDirPath = context->GetCacheDir() + HIVIEW_DIR; + std::string eventDirPath = context->GetCacheDir() + HIVIEW_DIR + EVENT_DIR; + + int aclBaseRet = AclSetAccess(baseDirPath, PARENT_DIR_PERMISSION); + if (aclBaseRet != ACL_SUCC) { + HiLog::Error(LABEL, "Set ACL failed , baseDirPath= %{public}s ret = %{public}d!!!!", + baseDirPath.c_str(), aclBaseRet); + return false; + } + int aclCacheRet = AclSetAccess(cacheDirPath, PARENT_DIR_PERMISSION); + if (aclCacheRet != ACL_SUCC) { + HiLog::Error(LABEL, "Set ACL failed , cacheDirPath= %{public}s ret = %{public}d!!!!", + cacheDirPath.c_str(), aclCacheRet); + return false; + } + int aclHiviewRet = AclSetAccess(hiviewDirPath, PARENT_DIR_PERMISSION); + if (aclHiviewRet != ACL_SUCC) { + HiLog::Error(LABEL, "Set ACL failed , hiviewDirPath= %{public}s ret = %{public}d!!!!", + hiviewDirPath.c_str(), aclHiviewRet); + return false; + } + int aclRet = AclSetAccess(eventDirPath, SUB_DIR_PERMISSION); + if (aclRet != ACL_SUCC) { + HiLog::Error(LABEL, "Set ACL failed , eventDirPath= %{public}s ret = %{public}d!!!!", + eventDirPath.c_str(), aclRet); + return false; + } + return true; +} + } // namespace HiviewDFX } // namespace OHOS diff --git a/adapter/native/idl/src/sys_event_service_proxy.cpp b/adapter/native/idl/src/sys_event_service_proxy.cpp index 45be04d5347540c79978fbf1ef4f0ea49c4d5233..578b972c6de5813d87105015c30892e2892e597e 100644 --- a/adapter/native/idl/src/sys_event_service_proxy.cpp +++ b/adapter/native/idl/src/sys_event_service_proxy.cpp @@ -188,6 +188,105 @@ int32_t SysEventServiceProxy::SetDebugMode(const sptr& callba } return result; } + +int64_t SysEventServiceProxy::AddSubscriber(const std::vector &rules) +{ + auto remote = Remote(); + if (remote == nullptr) { + HiLog::Error(LABEL, "SysEventService Remote is NULL."); + return ERR_REMOTE_SERVICE_IS_NULL; + } + MessageParcel data; + if (!data.WriteInterfaceToken(SysEventServiceProxy::GetDescriptor())) { + HiLog::Error(LABEL, "write descriptor failed."); + return ERR_CAN_NOT_WRITE_DESCRIPTOR; + } + bool ret = WriteVectorToParcel(data, rules); + if (!ret) { + HiLog::Error(LABEL, "parcel write rules failed."); + return ERR_CAN_NOT_WRITE_PARCEL; + } + MessageParcel reply; + MessageOption option; + int32_t res = remote->SendRequest(ADD_SYS_EVENT_SUBSCRIBER, data, reply, option); + if (res != ERR_OK) { + HiLog::Error(LABEL, "send request failed, error is %{public}d.", res); + return ERR_CAN_NOT_SEND_REQ; + } + int64_t result; + ret = reply.ReadInt64(result); + if (!ret) { + HiLog::Error(LABEL, "parcel read result failed."); + return ERR_CAN_NOT_READ_PARCEL; + } + return result; +} + +int32_t SysEventServiceProxy::RemoveSubscriber() +{ + auto remote = Remote(); + if (remote == nullptr) { + HiLog::Error(LABEL, "SysEventService Remote is NULL."); + return ERR_REMOTE_SERVICE_IS_NULL; + } + MessageParcel data; + if (!data.WriteInterfaceToken(SysEventServiceProxy::GetDescriptor())) { + HiLog::Error(LABEL, "write descriptor failed."); + return ERR_CAN_NOT_WRITE_DESCRIPTOR; + } + MessageParcel reply; + MessageOption option; + int32_t res = remote->SendRequest(REMOVE_SYS_EVENT_SUBSCRIBER, data, reply, option); + if (res != ERR_OK) { + HiLog::Error(LABEL, "send request failed, error is %{public}d.", res); + return ERR_CAN_NOT_SEND_REQ; + } + int32_t result; + auto ret = reply.ReadInt32(result); + if (!ret) { + HiLog::Error(LABEL, "parcel read result failed."); + return ERR_CAN_NOT_READ_PARCEL; + } + return result; +} + +int64_t SysEventServiceProxy::Export(const QueryArgument &queryArgument, const std::vector &rules) +{ + auto remote = Remote(); + if (remote == nullptr) { + HiLog::Error(LABEL, "SysEventService Remote is NULL."); + return ERR_REMOTE_SERVICE_IS_NULL; + } + MessageParcel data; + if (!data.WriteInterfaceToken(SysEventServiceProxy::GetDescriptor())) { + HiLog::Error(LABEL, "write descriptor failed."); + return ERR_CAN_NOT_WRITE_DESCRIPTOR; + } + if (!data.WriteParcelable(&queryArgument)) { + HiLog::Error(LABEL, "parcel write export arguments failed."); + return ERR_CAN_NOT_WRITE_PARCEL; + } + bool ret = WriteVectorToParcel(data, rules); + if (!ret) { + HiLog::Error(LABEL, "parcel write export rules failed."); + return ERR_CAN_NOT_WRITE_PARCEL; + } + MessageParcel reply; + MessageOption option; + int32_t res = remote->SendRequest(EXPORT_SYS_EVENT, data, reply, option); + if (res != ERR_OK) { + HiLog::Error(LABEL, "send request failed, error is %{public}d.", res); + return ERR_CAN_NOT_SEND_REQ; + } + int64_t result; + ret = reply.ReadInt64(result); + if (!ret) { + HiLog::Error(LABEL, "parcel read result failed."); + return ERR_CAN_NOT_READ_PARCEL; + } + return result; +} + } // namespace HiviewDFX } // namespace OHOS diff --git a/adapter/native/idl/src/sys_event_service_stub.cpp b/adapter/native/idl/src/sys_event_service_stub.cpp index bfd7bea562b4ebf5459c21bcddffa0c9873b16e3..f7951ada8f8b4eb90372265a2a7659fd0deed272 100644 --- a/adapter/native/idl/src/sys_event_service_stub.cpp +++ b/adapter/native/idl/src/sys_event_service_stub.cpp @@ -115,6 +115,57 @@ int32_t SysEventServiceStub::HandleSetDebugMode(MessageParcel& data, return ERR_OK; } +int32_t SysEventServiceStub::HandleAddSubscriber(MessageParcel &data, + MessageParcel &reply, MessageOption &option) +{ + std::vector queryRules; + auto ret = ReadVectorFromParcel(data, queryRules); + if (!ret) { + HiLog::Error(LABEL, "parcel read export rules failed."); + return ERR_FLATTEN_OBJECT; + } + ret = reply.WriteInt64(AddSubscriber(queryRules)); + if (!ret) { + HiLog::Error(LABEL, "write return-value of AddSubscriber failed."); + return ERR_FLATTEN_OBJECT; + } + return ERR_OK; +} + +int32_t SysEventServiceStub::HandleRemoveSubscriber( + MessageParcel &data, MessageParcel &reply, MessageOption &option) +{ + auto ret = reply.WriteInt32(RemoveSubscriber()); + if (!ret) { + HiLog::Error(LABEL, "write return-value of RemoveSubscriber failed."); + return ERR_FLATTEN_OBJECT; + } + return ERR_OK; +} + +int32_t SysEventServiceStub::HandleExportEvent(MessageParcel& data, + MessageParcel& reply, MessageOption& option) +{ + QueryArgument *queryArgument = data.ReadParcelable(); + if (queryArgument == nullptr) { + HiLog::Error(LABEL, "parcel read export arguments failed."); + return ERR_FLATTEN_OBJECT; + } + std::vector queryRules; + auto ret = ReadVectorFromParcel(data, queryRules); + if (!ret) { + HiLog::Error(LABEL, "parcel read export rules failed."); + return ERR_FLATTEN_OBJECT; + } + ret = reply.WriteInt64(Export(*queryArgument, queryRules)); + delete queryArgument; + if (!ret) { + HiLog::Error(LABEL, "parcel write return-value of ExportSysEvent failed."); + return ERR_FLATTEN_OBJECT; + } + return ERR_OK; +} + int32_t SysEventServiceStub::OnRemoteRequest(uint32_t code, MessageParcel& data, MessageParcel& reply, MessageOption& option) { @@ -137,6 +188,15 @@ int32_t SysEventServiceStub::OnRemoteRequest(uint32_t code, MessageParcel& data, case SET_DEBUG_MODE: { return HandleSetDebugMode(data, reply, option); } + case ADD_SYS_EVENT_SUBSCRIBER: { + return HandleAddSubscriber(data, reply, option); + } + case REMOVE_SYS_EVENT_SUBSCRIBER: { + return HandleRemoveSubscriber(data, reply, option); + } + case EXPORT_SYS_EVENT: { + return HandleExportEvent(data, reply, option); + } default: return IPCObjectStub::OnRemoteRequest(code, data, reply, option); } diff --git a/bundle.json b/bundle.json index 1e2564a1998d24a5e65895937062088850464033..73fee17ae355a3889848c8b418d9e1193bd67711 100644 --- a/bundle.json +++ b/bundle.json @@ -22,6 +22,7 @@ "ram": "", "deps": { "components": [ + "bundle_framework", "c_utils", "hilog_native", "hitrace_native", diff --git a/interfaces/js/kits/napi/include/ret_def.h b/interfaces/js/kits/napi/include/ret_def.h index 2566f5911cef23e3072214586df2339e0073094c..340fabcaa6249fb2734aa300c5acffb9d67c4679 100644 --- a/interfaces/js/kits/napi/include/ret_def.h +++ b/interfaces/js/kits/napi/include/ret_def.h @@ -48,6 +48,7 @@ constexpr int32_t ERR_QUERY_RULE_COUNT_OVER_LIMIT = 11200301; constexpr int32_t ERR_INVALID_QUERY_RULE = 11200302; constexpr int32_t ERR_CONCURRENT_QUERY_COUNT_OVER_LIMIT = 11200303; constexpr int32_t ERR_QUERY_TOO_FREQUENTLY = 11200304; +constexpr int32_t ERR_REMOVE_SUBSCRIBE = 11200305; } namespace NapiInnerError { @@ -56,6 +57,7 @@ constexpr int32_t ERR_INVALID_EVENT_NAME_IN_QUERY_RULE = 112003002; } static constexpr int32_t NAPI_SUCCESS = 0; +static constexpr int32_t DB_FAILED = -1; static constexpr int32_t ERR_INVALID_PARAM_COUNT = -100; static constexpr int32_t ERR_NAPI_PARSED_FAILED = -101; diff --git a/interfaces/js/kits/napi/src/napi_hisysevent_js.cpp b/interfaces/js/kits/napi/src/napi_hisysevent_js.cpp index 9c0e20affdf6fec977d77b4da563cb467f9a8fb2..0a3265c65d4d9a8b70418cb6dafb86daedb38b91 100644 --- a/interfaces/js/kits/napi/src/napi_hisysevent_js.cpp +++ b/interfaces/js/kits/napi/src/napi_hisysevent_js.cpp @@ -44,8 +44,14 @@ constexpr size_t REMOVE_LISTENER_LISTENER_PARAM_INDEX = 0; constexpr size_t QUERY_QUERY_ARG_PARAM_INDEX = 0; constexpr size_t QUERY_RULE_ARRAY_PARAM_INDEX = 1; constexpr size_t QUERY_QUERIER_PARAM_INDEX = 2; +constexpr size_t EXPORT_FUNC_MAX_PARAM_NUM = 2; +constexpr size_t EXPORT_QUERY_ARG_PARAM_INDEX = 0; +constexpr size_t EXPORT_RULE_ARRAY_PARAM_INDEX = 1; +constexpr size_t SUBSCRIBE_FUNC_MAX_PARAM_NUM = 1; +constexpr size_t SUBSCRIBE_RULE_ARRAY_PARAM_INDEX = 0; constexpr long long DEFAULT_TIME_STAMP = -1; constexpr int DEFAULT_EVENT_COUNT = 1000; +constexpr int TIME_STAMP_LENGTH = 13; using NAPI_LISTENER_PAIR = std::pair>; using NAPI_QUERIER_PAIR = std::pair>; std::unordered_map listeners; @@ -230,6 +236,102 @@ static napi_value Query(napi_env env, napi_callback_info info) return nullptr; } +static napi_value ExportSysEvents(napi_env env, napi_callback_info info) +{ + if (!NapiHiSysEventUtil::IsSystemAppCall()) { + NapiHiSysEventUtil::ThrowSystemAppPermissionError(env); + return nullptr; + } + size_t paramNum = EXPORT_FUNC_MAX_PARAM_NUM; + napi_value params[EXPORT_FUNC_MAX_PARAM_NUM] = {0}; + napi_value thisArg = nullptr; + void* data = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, ¶mNum, params, &thisArg, &data)); + if (paramNum < EXPORT_FUNC_MAX_PARAM_NUM) { + std::unordered_map paramError = { + {EXPORT_QUERY_ARG_PARAM_INDEX, "queryArg"}, + {EXPORT_RULE_ARRAY_PARAM_INDEX, "rules"}, + }; + HiLog::Error(LABEL, "count of parameters is less than %{public}zu.", EXPORT_FUNC_MAX_PARAM_NUM); + NapiHiSysEventUtil::ThrowParamMandatoryError(env, paramError.at(paramNum)); + return nullptr; + } + QueryArg queryArg = { DEFAULT_TIME_STAMP, DEFAULT_TIME_STAMP, DEFAULT_EVENT_COUNT }; + if (auto ret = NapiHiSysEventUtil::ParseQueryArg(env, params[EXPORT_QUERY_ARG_PARAM_INDEX], queryArg); + ret != SUCCESS) { + HiLog::Error(LABEL, "failed to parse query arg, result code is %{public}d.", ret); + return nullptr; + } + std::vector rules; + if (auto ret = NapiHiSysEventUtil::ParseQueryRules(env, params[EXPORT_RULE_ARRAY_PARAM_INDEX], rules); + ret != SUCCESS) { + HiLog::Error(LABEL, "failed to parse query rules, result code is %{public}d.", ret); + return nullptr; + } + auto ret = HiSysEventBaseManager::Export(queryArg, rules); + if (std::to_string(ret).length() < TIME_STAMP_LENGTH) { + HiLog::Error(LABEL, "failed to export event, result code is %{public}lld.", ret); + int32_t retCode = static_cast(ret); + NapiHiSysEventUtil::ThrowErrorByRet(env, retCode); + return nullptr; + } + napi_value result = nullptr; + NapiHiSysEventUtil::CreateInt64Value(env, ret, result); + return result; +} + +static napi_value Subscribe(napi_env env, napi_callback_info info) +{ + if (!NapiHiSysEventUtil::IsSystemAppCall()) { + NapiHiSysEventUtil::ThrowSystemAppPermissionError(env); + return nullptr; + } + size_t paramNum = SUBSCRIBE_FUNC_MAX_PARAM_NUM; + napi_value params[SUBSCRIBE_FUNC_MAX_PARAM_NUM] = {0}; + napi_value thisArg = nullptr; + void* data = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, ¶mNum, params, &thisArg, &data)); + if (paramNum < SUBSCRIBE_FUNC_MAX_PARAM_NUM) { + HiLog::Error(LABEL, "count of parameters is less than %{public}zu.", SUBSCRIBE_FUNC_MAX_PARAM_NUM); + NapiHiSysEventUtil::ThrowParamMandatoryError(env, "rules"); + return nullptr; + } + std::vector rules; + if (auto ret = NapiHiSysEventUtil::ParseQueryRules(env, params[SUBSCRIBE_RULE_ARRAY_PARAM_INDEX], rules); + ret != SUCCESS) { + HiLog::Error(LABEL, "failed to parse query rules, result code is %{public}d.", ret); + return nullptr; + } + auto ret = HiSysEventBaseManager::Subscribe(rules); + if (std::to_string(ret).length() < TIME_STAMP_LENGTH) { + HiLog::Error(LABEL, "failed to subscribe event, result code is %{public}lld.", ret); + int32_t retCode = static_cast(ret); + NapiHiSysEventUtil::ThrowErrorByRet(env, retCode); + return nullptr; + } + napi_value result = nullptr; + NapiHiSysEventUtil::CreateInt64Value(env, ret, result); + return result; +} + +static napi_value Unsubscribe(napi_env env, napi_callback_info info) +{ + if (!NapiHiSysEventUtil::IsSystemAppCall()) { + NapiHiSysEventUtil::ThrowSystemAppPermissionError(env); + return nullptr; + } + auto ret = HiSysEventBaseManager::Unsubscribe(); + if (ret != NAPI_SUCCESS) { + HiLog::Error(LABEL, "failed to unsubscribe, result code is %{public}d.", ret); + int32_t retCode = static_cast(ret); + if (ret == DB_FAILED) { + retCode = NapiError::ERR_REMOVE_SUBSCRIBE; + } + NapiHiSysEventUtil::ThrowErrorByRet(env, retCode); + } + return nullptr; +} + EXTERN_C_START static napi_value Init(napi_env env, napi_value exports) { @@ -238,6 +340,9 @@ static napi_value Init(napi_env env, napi_value exports) DECLARE_NAPI_FUNCTION("addWatcher", AddWatcher), DECLARE_NAPI_FUNCTION("removeWatcher", RemoveWatcher), DECLARE_NAPI_FUNCTION("query", Query), + DECLARE_NAPI_FUNCTION("exportSysEvents", ExportSysEvents), + DECLARE_NAPI_FUNCTION("subscribe", Subscribe), + DECLARE_NAPI_FUNCTION("unsubscribe", Unsubscribe), }; NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(napi_property_descriptor), desc)); diff --git a/interfaces/js/kits/napi/src/napi_hisysevent_util.cpp b/interfaces/js/kits/napi/src/napi_hisysevent_util.cpp index 5d30c6e83dca23c27e3624d1d2093f5b9c13e3f9..fd31c0f4f9246c0d908a753338dc396111b802d5 100644 --- a/interfaces/js/kits/napi/src/napi_hisysevent_util.cpp +++ b/interfaces/js/kits/napi/src/napi_hisysevent_util.cpp @@ -938,6 +938,12 @@ std::pair NapiHiSysEventUtil::GetErrorDetailByRet(napi_env {ERR_QUERY_RULE_INVALID, {NapiError::ERR_INVALID_QUERY_RULE, "Query rule is invalid"}}, {NapiInnerError::ERR_INVALID_EVENT_NAME_IN_QUERY_RULE, {NapiError::ERR_INVALID_QUERY_RULE, "Query rule is invalid"}}, + // export + {ERR_EXPORT_FREQUENCY_OVER_LIMIT, {NapiError::ERR_QUERY_TOO_FREQUENTLY, "Export frequency is over limit."}}, + // add subscriber + {ERR_TOO_MANY_EVENTS, {NapiError::ERR_WATCHER_COUNT_OVER_LIMIT, "Count of events is over limit"}}, + // remove subscriber + {NapiError::ERR_REMOVE_SUBSCRIBE, {NapiError::ERR_REMOVE_SUBSCRIBE, "unsubscribe failed"}}, }; return errMap.find(retCode) == errMap.end() ? std::make_pair(NapiError::ERR_ENV_ABNORMAL, "environment is abnormal") : errMap.at(retCode); diff --git a/interfaces/native/innerkits/hisysevent_manager/hisysevent_base_manager.cpp b/interfaces/native/innerkits/hisysevent_manager/hisysevent_base_manager.cpp index 175c6a92672cfc5ae421964c7474e49b623ad2fb..e419f0d3e30dff0fdfdce69062eea099b7531325 100644 --- a/interfaces/native/innerkits/hisysevent_manager/hisysevent_base_manager.cpp +++ b/interfaces/native/innerkits/hisysevent_manager/hisysevent_base_manager.cpp @@ -68,5 +68,33 @@ int32_t HiSysEventBaseManager::SetDebugMode(std::shared_ptrlistenerProxy->SetDebugMode(listener, mode); } + +int64_t HiSysEventBaseManager::Export(struct QueryArg& arg, std::vector& rules) +{ + auto proxy = std::make_unique(); + if (proxy != nullptr) { + return proxy->Export(arg, rules); + } + return ERR_LISTENER_NOT_EXIST; +} + +int64_t HiSysEventBaseManager::Subscribe(std::vector& rules) +{ + auto proxy = std::make_unique(); + if (proxy != nullptr) { + return proxy->Subscribe(rules); + } + return ERR_LISTENER_NOT_EXIST; +} + +int32_t HiSysEventBaseManager::Unsubscribe() +{ + auto proxy = std::make_unique(); + if (proxy != nullptr) { + return proxy->Unsubscribe(); + } + return ERR_LISTENER_NOT_EXIST; +} + } // namespace HiviewDFX } // namespace OHOS diff --git a/interfaces/native/innerkits/hisysevent_manager/include/hisysevent_base_manager.h b/interfaces/native/innerkits/hisysevent_manager/include/hisysevent_base_manager.h index 8b6599896c33959da02b2b84f4b044c40140a864..0713de2b317a918b9e375852505009aa49ba69d2 100644 --- a/interfaces/native/innerkits/hisysevent_manager/include/hisysevent_base_manager.h +++ b/interfaces/native/innerkits/hisysevent_manager/include/hisysevent_base_manager.h @@ -37,6 +37,9 @@ public: static int32_t Query(struct QueryArg& arg, std::vector& rules, std::shared_ptr callback); static int32_t SetDebugMode(std::shared_ptr listener, bool mode); + static int64_t Export(struct QueryArg& arg, std::vector& rules); + static int64_t Subscribe(std::vector& rules); + static int32_t Unsubscribe(); }; } // namespace HiviewDFX } // namespace OHOS diff --git a/test/moduletest/common/hisysevent_adapter_native_test.cpp b/test/moduletest/common/hisysevent_adapter_native_test.cpp index 83b5f9279e7834974652d82573b88965301ecbe9..f7b174f138d1d87b56c0a159e6d5dfa397ff9158 100644 --- a/test/moduletest/common/hisysevent_adapter_native_test.cpp +++ b/test/moduletest/common/hisysevent_adapter_native_test.cpp @@ -54,6 +54,8 @@ using namespace OHOS::HiviewDFX; namespace { constexpr char ASH_MEM_NAME[] = "TestSharedMemory"; constexpr int32_t ASH_MEM_SIZE = 1024 * 2; // 2K +constexpr int64_t CURRENT_TIME = 20170810130952; // 2017-08-10-13:09:52 +constexpr int32_t TIME_STAMP_LENGTH = 10; // timeStamp length sptr GetAshmem() { @@ -124,13 +126,31 @@ public: return 0; } + int64_t AddSubscriber(const std::vector &rules) + { + return CURRENT_TIME; + } + + int32_t RemoveSubscriber() + { + return 0; + } + + int64_t Export(const QueryArgument &queryArgument, const std::vector &rules) + { + return CURRENT_TIME; + } + public: enum Code { DEFAULT = -1, ADD_SYS_EVENT_LISTENER = 0, REMOVE_SYS_EVENT_LISTENER, QUERY_SYS_EVENT, - SET_DEBUG_MODE + SET_DEBUG_MODE, + ADD_SYS_EVENT_SUBSCRIBER, + REMOVE_SYS_EVENT_SUBSCRIBER, + EXPORT_SYS_EVENT }; }; } @@ -282,12 +302,12 @@ HWTEST_F(HiSysEventAdapterNativeTest, TestSysEventCallback, TestSize.Level1) } /** - * @tc.name: TestSysEventService + * @tc.name: TestSysEventService001 * @tc.desc: SysEventServiceProxy/Stub test * @tc.type: FUNC * @tc.require: issueI62WJT */ -HWTEST_F(HiSysEventAdapterNativeTest, TestSysEventService, TestSize.Level1) +HWTEST_F(HiSysEventAdapterNativeTest, TestSysEventService001, TestSize.Level1) { SysEventServiceStub* sysEventServiceStub = new(std::nothrow) SysEventServiceStubTest(); MessageParcel data, reply; @@ -327,6 +347,41 @@ HWTEST_F(HiSysEventAdapterNativeTest, TestSysEventService, TestSize.Level1) ASSERT_TRUE(ret == 0); } +/** + * @tc.name: TestSysEventService002 + * @tc.desc: SysEventServiceProxy/Stub test + * @tc.type: FUNC + * @tc.require: SR000I1G43 + */ +HWTEST_F(HiSysEventAdapterNativeTest, TestSysEventService002, TestSize.Level1) +{ + SysEventServiceStub* sysEventServiceStub = new(std::nothrow) SysEventServiceStubTest(); + MessageParcel data, reply; + MessageOption option; + sysEventServiceStub->OnRemoteRequest(SysEventServiceStubTest::Code::ADD_SYS_EVENT_SUBSCRIBER, data, reply, option); + ASSERT_TRUE(true); + sysEventServiceStub->OnRemoteRequest(SysEventServiceStubTest::Code::REMOVE_SYS_EVENT_SUBSCRIBER, + data, reply, option); + ASSERT_TRUE(true); + sysEventServiceStub->OnRemoteRequest(SysEventServiceStubTest::Code::EXPORT_SYS_EVENT, data, reply, option); + ASSERT_TRUE(true); + const sptr& impl(sysEventServiceStub); + SysEventServiceProxy proxy(impl); + std::vector queryRules; + std::vector eventNames { "EVENT_NAME1", "EVENT_NAME2" }; + OHOS::HiviewDFX::SysEventQueryRule queryRule("DOMAIN", eventNames); + queryRules.emplace_back(queryRule); + auto ret = proxy.AddSubscriber(queryRules); + ASSERT_TRUE(std::to_string(ret).length() > TIME_STAMP_LENGTH); + ret = proxy.RemoveSubscriber(); + ASSERT_TRUE(ret == 0); + long long defaultTimeStap = -1; + int queryCount = 10; + OHOS::HiviewDFX::QueryArgument args(defaultTimeStap, defaultTimeStap, queryCount); + ret = proxy.Export(args, queryRules); + ASSERT_TRUE(std::to_string(ret).length() > TIME_STAMP_LENGTH); +} + /** * @tc.name: MarshallingTAndUnmarshallingTest * @tc.desc: Unmarshalling test