diff --git a/bundle.json b/bundle.json index 0319b7bc2a54f9a032d21dfc1d2df8a4d522d426..9dab7436b6b1ab187e620fc7c4abe44f7a41ad8c 100644 --- a/bundle.json +++ b/bundle.json @@ -81,6 +81,7 @@ "inner_kits": [], "test": [ "//base/notification/ans_standard/services/ans/test/unittest:ans_unit_test", + "//base/notification/ans_standard/services/distributed/test/unittest:ans_distributed_unit_test_target", "//base/notification/ans_standard/services/test/moduletest:ans_module_test", "//base/notification/ans_standard/frameworks/ans/test/moduletest:moduletest", "//base/notification/ans_standard/frameworks/ans/native/test/unittest:ans_reminder_unit_test", diff --git a/frameworks/ans/core/BUILD.gn b/frameworks/ans/core/BUILD.gn index 8ea2b3b94c2a2c86111e93f8d4d0ee50f03aef00..ca0915aec375018307b64ba54876297b16442e83 100644 --- a/frameworks/ans/core/BUILD.gn +++ b/frameworks/ans/core/BUILD.gn @@ -27,8 +27,10 @@ config("public_ans_core_config") { "${core_path}/include", "${interfaces_path}/innerkits/ans/native/include", "${interfaces_path}/innerkits/wantAgent/include", + "//foundation/aafwk/standard/frameworks/kits/content/cpp/src/ohos/aafwk/content/", "//foundation/multimedia/image_standard/interfaces/innerkits/include", "//utils/native/base/include", + "//third_party/json/single_include", "//third_party/jsoncpp/include", ] @@ -38,6 +40,7 @@ config("public_ans_core_config") { ohos_shared_library("ans_core") { sources = [ "${core_path}/common/src/ans_log_wrapper.cpp", + "${core_path}/src/ans_image_util.cpp", "${core_path}/src/ans_manager_death_recipient.cpp", "${core_path}/src/ans_manager_proxy.cpp", "${core_path}/src/ans_manager_stub.cpp", @@ -53,6 +56,7 @@ ohos_shared_library("ans_core") { "${frameworks_path}/ans/native/src/notification_content.cpp", "${frameworks_path}/ans/native/src/notification_conversational_content.cpp", "${frameworks_path}/ans/native/src/notification_conversational_message.cpp", + "${frameworks_path}/ans/native/src/notification_distributed_options.cpp", "${frameworks_path}/ans/native/src/notification_do_not_disturb_date.cpp", "${frameworks_path}/ans/native/src/notification_helper.cpp", "${frameworks_path}/ans/native/src/notification_long_text_content.cpp", diff --git a/frameworks/ans/core/common/include/ans_const_define.h b/frameworks/ans/core/common/include/ans_const_define.h index bda3a1ffe01ad41d9d4252496668b5e299701ba0..a38245ac7c9190694121c613418c64f9055175a4 100644 --- a/frameworks/ans/core/common/include/ans_const_define.h +++ b/frameworks/ans/core/common/include/ans_const_define.h @@ -20,6 +20,8 @@ #include "uri.h" +#include "notification_constant.h" + namespace OHOS { namespace Notification { // Max active notification number @@ -44,7 +46,6 @@ const static std::vector DEFAULT_NOTIFICATION_VIBRATION = {200}; // Default path for template const static std::string DEFAULT_TEMPLATE_PATH("/system/etc/external.json"); - } // namespace Notification } // namespace OHOS diff --git a/frameworks/ans/core/common/include/ans_inner_errors.h b/frameworks/ans/core/common/include/ans_inner_errors.h index 63d35c83fc3bf07d2a8a3ba12eda12b52e13b109..c205fea2ce02ef396896a23852fe077220311745 100644 --- a/frameworks/ans/core/common/include/ans_inner_errors.h +++ b/frameworks/ans/core/common/include/ans_inner_errors.h @@ -70,6 +70,8 @@ enum ErrorCode : uint32_t { ERR_ANS_PREFERENCES_NOTIFICATION_SLOTGROUP_ID_INVALID, ERR_ANS_PREFERENCES_NOTIFICATION_SLOTGROUP_EXCEED_MAX_NUM, ERR_ANS_PREFERENCES_NOTIFICATION_READ_TEMPLATE_CONFIG_FAILED, + ERR_ANS_DISTRIBUTED_OPERATION_FAILED, + ERR_ANS_DISTRIBUTED_GET_INFO_FAILED, }; } // namespace Notification } // namespace OHOS diff --git a/frameworks/ans/core/include/ans_image_util.h b/frameworks/ans/core/include/ans_image_util.h new file mode 100644 index 0000000000000000000000000000000000000000..8478efabe385a9a7db1bdbcd40722911ac1c4cdd --- /dev/null +++ b/frameworks/ans/core/include/ans_image_util.h @@ -0,0 +1,52 @@ +/* + * 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 BASE_NOTIFICATION_ANS_STANDARD_FRAMEWORKS_ANS_CORE_INCLUDE_ANS_IMAGE_UTIL_H +#define BASE_NOTIFICATION_ANS_STANDARD_FRAMEWORKS_ANS_CORE_INCLUDE_ANS_IMAGE_UTIL_H + +#include +#include +#include "pixel_map.h" + +namespace OHOS { +namespace Notification { +class AnsImageUtil { +public: + static const std::string IMAGE_FORMAT_JPEG; + static const uint8_t IMAGE_QUALITY; + static const uint8_t SHIFT_FOUR; + static const uint8_t NUM_TEN; + static const size_t TWO_TIMES; + + static std::string PackImage( + const std::shared_ptr &pixelMap, const std::string &format = IMAGE_FORMAT_JPEG); + + static std::shared_ptr UnPackImage(const std::string &pixelMapStr); + + static bool PackImage2File( + const std::shared_ptr &pixelMap, + const std::string &outFilePath, + const std::string &format = IMAGE_FORMAT_JPEG); + + static std::shared_ptr CreatePixelMap( + const std::string &inFilePath, const std::string &format = IMAGE_FORMAT_JPEG); + + static std::string BinToHex(const std::string &strBin); + + static std::string HexToBin(const std::string &strHex); +}; +} // namespace Notification +} // namespace OHOS + +#endif // BASE_NOTIFICATION_ANS_STANDARD_FRAMEWORKS_ANS_CORE_INCLUDE_ANS_IMAGE_UTIL_H diff --git a/frameworks/ans/core/include/ans_manager_interface.h b/frameworks/ans/core/include/ans_manager_interface.h index f43d0df46fe4381aaf362a2167bc75d0f4df81fd..76a9ebc97d542c2ee1dcc73485e65921d5f7931f 100644 --- a/frameworks/ans/core/include/ans_manager_interface.h +++ b/frameworks/ans/core/include/ans_manager_interface.h @@ -111,6 +111,12 @@ public: virtual ErrCode RemoveGroupByBundle( const sptr &bundleOption, const std::string &groupName) = 0; + virtual ErrCode IsDistributedEnabled(bool &enabled) = 0; + virtual ErrCode EnableDistributed(bool enabled) = 0; + virtual ErrCode EnableDistributedByBundle(const sptr &bundleOption, bool enabled) = 0; + virtual ErrCode EnableDistributedSelf(bool enabled) = 0; + virtual ErrCode IsDistributedEnableByBundle(const sptr &bundleOption, bool &enabled) = 0; + virtual ErrCode ShellDump(const std::string &dumpOption, std::vector &dumpInfo) = 0; virtual ErrCode PublishContinuousTaskNotification(const sptr &request) = 0; virtual ErrCode CancelContinuousTaskNotification(const std::string &label, int32_t notificationId) = 0; @@ -175,6 +181,11 @@ protected: DOES_SUPPORT_DO_NOT_DISTURB_MODE, CANCEL_GROUP, REMOVE_GROUP_BY_BUNDLE, + IS_DISTRIBUTED_ENABLED, + ENABLE_DISTRIBUTED, + ENABLE_DISTRIBUTED_BY_BUNDLE, + ENABLE_DISTRIBUTED_SELF, + IS_DISTRIBUTED_ENABLED_BY_BUNDLE, SHELL_DUMP, PUBLISH_CONTINUOUS_TASK_NOTIFICATION, CANCEL_CONTINUOUS_TASK_NOTIFICATION, diff --git a/frameworks/ans/core/include/ans_manager_proxy.h b/frameworks/ans/core/include/ans_manager_proxy.h index 0c58d0b8489107f8fde0e5845d76f743aafc9931..0f590eb9fdf340178e4405f48c0eccfa0ab0f3b4 100644 --- a/frameworks/ans/core/include/ans_manager_proxy.h +++ b/frameworks/ans/core/include/ans_manager_proxy.h @@ -98,6 +98,12 @@ public: ErrCode RemoveGroupByBundle( const sptr &bundleOption, const std::string &groupName) override; + ErrCode IsDistributedEnabled(bool &enabled) override; + ErrCode EnableDistributed(bool enabled) override; + ErrCode EnableDistributedByBundle(const sptr &bundleOption, bool enabled) override; + ErrCode EnableDistributedSelf(bool enabled) override; + ErrCode IsDistributedEnableByBundle(const sptr &bundleOption, bool &enabled) override; + ErrCode ShellDump(const std::string &dumpOption, std::vector &dumpInfo) override; ErrCode PublishContinuousTaskNotification(const sptr &request) override; ErrCode CancelContinuousTaskNotification(const std::string &label, int32_t notificationId) override; diff --git a/frameworks/ans/core/include/ans_manager_stub.h b/frameworks/ans/core/include/ans_manager_stub.h index 0316ea1bd3ff31127fec68b81fe8196118d14d2c..ce61b644dc114402c1f658dde2ef0beb872588ae 100644 --- a/frameworks/ans/core/include/ans_manager_stub.h +++ b/frameworks/ans/core/include/ans_manager_stub.h @@ -103,6 +103,14 @@ public: virtual ErrCode RemoveGroupByBundle( const sptr &bundleOption, const std::string &groupName) override; + virtual ErrCode IsDistributedEnabled(bool &enabled) override; + virtual ErrCode EnableDistributed(bool enabled) override; + virtual ErrCode EnableDistributedByBundle( + const sptr &bundleOption, bool enabled) override; + virtual ErrCode EnableDistributedSelf(bool enabled) override; + virtual ErrCode IsDistributedEnableByBundle( + const sptr &bundleOption, bool &enabled) override; + virtual ErrCode ShellDump(const std::string &dumpOption, std::vector &dumpInfo) override; virtual ErrCode PublishContinuousTaskNotification(const sptr &request) override; virtual ErrCode CancelContinuousTaskNotification(const std::string &label, int32_t notificationId) override; @@ -164,6 +172,11 @@ private: ErrCode HandleGetCurrentAppSorting(MessageParcel &data, MessageParcel &reply); ErrCode HandleIsAllowedNotify(MessageParcel &data, MessageParcel &reply); ErrCode HandleIsSpecialBundleAllowedNotify(MessageParcel &data, MessageParcel &reply); + ErrCode HandleIsDistributedEnabled(MessageParcel &data, MessageParcel &reply); + ErrCode HandleEnableDistributed(MessageParcel &data, MessageParcel &reply); + ErrCode HandleEnableDistributedByBundle(MessageParcel &data, MessageParcel &reply); + ErrCode HandleEnableDistributedSelf(MessageParcel &data, MessageParcel &reply); + ErrCode HandleIsDistributedEnableByBundle(MessageParcel &data, MessageParcel &reply); ErrCode HandleShellDump(MessageParcel &data, MessageParcel &reply); ErrCode HandleCancelGroup(MessageParcel &data, MessageParcel &reply); ErrCode HandleRemoveGroupByBundle(MessageParcel &data, MessageParcel &reply); diff --git a/frameworks/ans/core/include/ans_notification.h b/frameworks/ans/core/include/ans_notification.h index 7ea2f0d6d8efbf3d82465cd79cf45855e9beb79e..0aaa4d4ab9b2a6ba016554a7b8c060755a3f4053 100644 --- a/frameworks/ans/core/include/ans_notification.h +++ b/frameworks/ans/core/include/ans_notification.h @@ -593,7 +593,7 @@ public: * @param doNotDisturbDate Indicates the do not disturb time to set. * @return Returns set do not disturb time result. */ - ErrCode SetDoNotDisturbDate(const NotificationDoNotDisturbDate & doNotDisturbDate); + ErrCode SetDoNotDisturbDate(const NotificationDoNotDisturbDate &doNotDisturbDate); /** * Obtains the do not disturb time. @@ -602,7 +602,7 @@ public: * @param doNotDisturbDate Indicates the do not disturb time to get. * @return Returns set do not disturb time result. */ - ErrCode GetDoNotDisturbDate(NotificationDoNotDisturbDate & doNotDisturbDate); + ErrCode GetDoNotDisturbDate(NotificationDoNotDisturbDate &doNotDisturbDate); /** * Obtains the flag that whether to support do not disturb mode. @@ -612,6 +612,56 @@ public: */ ErrCode DoesSupportDoNotDisturbMode(bool &doesSupport); + /** + * Check if the device supports distributed notification. + * + * @param enabled True if the device supports distributed notification; false otherwise. + * @return Returns is distributed enabled result. + */ + ErrCode IsDistributedEnabled(bool &enabled); + + /** + * Set whether the device supports distributed notifications. + * + * @param enable Specifies whether to enable the device to support distributed notification. + * The value true indicates that the device is enabled to support distributed notifications, and + * the value false indicates that the device is forbidden to support distributed notifications. + * @return Returns enable distributed result. + */ + ErrCode EnableDistributed(const bool enabled); + + /** + * Set whether an application supports distributed notifications. + * + * @param bundleOption Indicates the bundle name and uid of an application. + * @param enabled Specifies whether to enable an application to support distributed notification. + * The value true indicates that the application is enabled to support distributed notifications, + * and the value false indicates that the application is forbidden to support distributed + * notifications. + * @return Returns enable distributed by bundle result. + */ + ErrCode EnableDistributedByBundle(const NotificationBundleOption &bundleOption, const bool enabled); + + /** + * Set whether this application supports distributed notifications. + * + * @param enabled Specifies whether to enable this application to support distributed notification. + * The value true indicates that this application is enabled to support distributed notifications, + * and the value false indicates that this application is forbidden to support distributed + * notifications. + * @return Returns enable distributed self result. + */ + ErrCode EnableDistributedSelf(const bool enabled); + + /** + * Check whether an application supports distributed notifications. + * + * @param bundleOption Indicates the bundle name and uid of an application. + * @param enabled True if the application supports distributed notification; false otherwise. + * @return Returns is distributed enabled by bundle result. + */ + ErrCode IsDistributedEnableByBundle(const NotificationBundleOption &bundleOption, bool &enabled); + /** * Publishes a continuous task notification. * @param request Indicates the NotificationRequest object for setting the notification content. @@ -714,6 +764,13 @@ private: */ ErrCode CheckImageSize(const NotificationRequest &request); + /** + * Check whether the notification doesn't support distribution + * + * @return Returns true if the notification doesn't support distribution; returns false otherwise. + */ + bool IsNonDistributedNotificationType(const NotificationContent::Type &type); + private: std::mutex mutex_; sptr ansManagerProxy_; diff --git a/frameworks/ans/core/src/ans_image_util.cpp b/frameworks/ans/core/src/ans_image_util.cpp new file mode 100644 index 0000000000000000000000000000000000000000..46b212b531778d015dba9af0e0ad35cbdda343d8 --- /dev/null +++ b/frameworks/ans/core/src/ans_image_util.cpp @@ -0,0 +1,215 @@ +/* + * 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 "ans_image_util.h" +#include "ans_log_wrapper.h" +#include "image_packer.h" +#include "image_source.h" + +namespace OHOS { +namespace Notification { +const std::string AnsImageUtil::IMAGE_FORMAT_JPEG {"image/jpeg"}; +const uint8_t AnsImageUtil::IMAGE_QUALITY {100}; +const uint8_t AnsImageUtil::SHIFT_FOUR {4}; +const uint8_t AnsImageUtil::NUM_TEN {10}; +const size_t AnsImageUtil::TWO_TIMES {2}; + +std::string AnsImageUtil::PackImage(const std::shared_ptr &pixelMap, const std::string &format) +{ + if (!pixelMap || format.empty()) { + ANS_LOGW("invalid parameters"); + return {}; + } + + Media::ImagePacker imagePacker; + Media::PackOption option; + option.format = format; + option.quality = IMAGE_QUALITY; + option.numberHint = 1; + + std::set formats; + auto ret = imagePacker.GetSupportedFormats(formats); + if (ret) { + ANS_LOGE("image packer get supported format failed, ret : %{public}u", ret); + return {}; + } + + auto size = static_cast(pixelMap->GetByteCount()); + ANS_LOGI("size of pixelMap : %{public}u", size); + auto pbuf = new (std::nothrow) uint8_t [size]; + if (pbuf == nullptr) { + ANS_LOGE("create buffer failed"); + return {}; + } + + imagePacker.StartPacking(pbuf, size, option); + imagePacker.AddImage(*pixelMap); + int64_t packedSize {0}; + imagePacker.FinalizePacking(packedSize); + ANS_LOGI("packed size : %{public}" PRId64, packedSize); + + std::string pixelMapStr(reinterpret_cast(pbuf), static_cast(packedSize)); + delete [] pbuf; + pbuf = nullptr; + + return BinToHex(pixelMapStr); +} + +std::shared_ptr AnsImageUtil::UnPackImage(const std::string &pixelMapStr) +{ + if (pixelMapStr.empty()) { + return {}; + } + + auto binStr = HexToBin(pixelMapStr); + + uint32_t errorCode {0}; + Media::SourceOptions opts; + auto imageSource = Media::ImageSource::CreateImageSource( + reinterpret_cast(binStr.data()), + static_cast(binStr.length()), + opts, errorCode); + if (errorCode || !imageSource) { + ANS_LOGE("create imageSource failed"); + return {}; + } + + Media::DecodeOptions decodeOpts; + auto pixelMap = imageSource->CreatePixelMap(decodeOpts, errorCode); + if (errorCode || !pixelMap) { + ANS_LOGE("create pixelMap failed"); + return {}; + } + + return pixelMap; +} + +bool AnsImageUtil::PackImage2File( + const std::shared_ptr &pixelMap, + const std::string &outFilePath, + const std::string &format) +{ + if (!pixelMap || outFilePath.empty() || format.empty()) { + ANS_LOGW("invalid parameters"); + return false; + } + + Media::ImagePacker imagePacker; + Media::PackOption option; + option.format = format; + option.quality = IMAGE_QUALITY; + option.numberHint = 1; + + std::set formats; + auto ret = imagePacker.GetSupportedFormats(formats); + if (ret) { + ANS_LOGE("image packer get supported format failed, ret : %{public}u", ret); + return false; + } + + imagePacker.StartPacking(outFilePath, option); + imagePacker.AddImage(*pixelMap); + int64_t packedSize {0}; + imagePacker.FinalizePacking(packedSize); + ANS_LOGI("packed size : %{public}" PRId64, packedSize); + return true; +} + +std::shared_ptr AnsImageUtil::CreatePixelMap(const std::string &inFilePath, const std::string &format) +{ + if (inFilePath.empty() || format.empty()) { + ANS_LOGW("invalid parameters"); + return {}; + } + + uint32_t errorCode {0}; + Media::SourceOptions opts; + opts.formatHint = format; + auto imageSource = Media::ImageSource::CreateImageSource(inFilePath, opts, errorCode); + if (errorCode || !imageSource) { + ANS_LOGE("create imageSource failed"); + return {}; + } + + std::set formats; + auto ret = imageSource->GetSupportedFormats(formats); + if (ret) { + ANS_LOGE("image packer get supported format failed, ret : %{public}u", ret); + return {}; + } + + Media::DecodeOptions decodeOpts; + auto pixelMap = imageSource->CreatePixelMap(decodeOpts, errorCode); + if (errorCode || !pixelMap) { + ANS_LOGE("create pixelMap failed"); + return {}; + } + + return pixelMap; +} + +std::string AnsImageUtil::BinToHex(const std::string &strBin) +{ + if (strBin.empty()) { + return {}; + } + + std::string strHex; + strHex.resize(strBin.size() * TWO_TIMES); + for (size_t i = 0; i < strBin.size(); i++) { + uint8_t cTemp = strBin[i]; + for (size_t j = 0; j < TWO_TIMES; j++) { + uint8_t cCur = (cTemp & 0x0f); + if (cCur < NUM_TEN) { + cCur += '0'; + } else { + cCur += ('a' - NUM_TEN); + } + strHex[TWO_TIMES * i + 1 - j] = cCur; + cTemp >>= SHIFT_FOUR; + } + } + + return strHex; +} + +std::string AnsImageUtil::HexToBin(const std::string &strHex) +{ + if (strHex.size() % TWO_TIMES != 0) { + return {}; + } + + std::string strBin; + strBin.resize(strHex.size() / TWO_TIMES); + for (size_t i = 0; i < strBin.size(); i++) { + uint8_t cTemp = 0; + for (size_t j = 0; j < TWO_TIMES; j++) { + char cCur = strHex[TWO_TIMES * i + j]; + if (cCur >= '0' && cCur <= '9') { + cTemp = (cTemp << SHIFT_FOUR) + (cCur - '0'); + } else if (cCur >= 'a' && cCur <= 'f') { + cTemp = (cTemp << SHIFT_FOUR) + (cCur - 'a' + NUM_TEN); + } else if (cCur >= 'A' && cCur <= 'F') { + cTemp = (cTemp << SHIFT_FOUR) + (cCur - 'A' + NUM_TEN); + } else { + return {}; + } + } + strBin[i] = cTemp; + } + + return strBin; +} +} // namespace Notification +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/ans/core/src/ans_manager_proxy.cpp b/frameworks/ans/core/src/ans_manager_proxy.cpp index e06b9e28f590f91c8b4bb3a1d4a5fe6316d0e29f..9090effc1aaabaca3c1e87925433dfc7cbdf6998 100644 --- a/frameworks/ans/core/src/ans_manager_proxy.cpp +++ b/frameworks/ans/core/src/ans_manager_proxy.cpp @@ -1842,6 +1842,171 @@ ErrCode AnsManagerProxy::DoesSupportDoNotDisturbMode(bool &doesSupport) return result; } +ErrCode AnsManagerProxy::IsDistributedEnabled(bool &enabled) +{ + MessageParcel data; + if (!data.WriteInterfaceToken(AnsManagerProxy::GetDescriptor())) { + ANS_LOGW("[IsDistributedEnabled] fail: write interface token failed."); + return ERR_ANS_PARCELABLE_FAILED; + } + + MessageParcel reply; + MessageOption option = {MessageOption::TF_SYNC}; + ErrCode result = InnerTransact(IS_DISTRIBUTED_ENABLED, option, data, reply); + if (result != ERR_OK) { + ANS_LOGW("[IsDistributedEnabled] fail: transact ErrCode=%{public}d", result); + return ERR_ANS_TRANSACT_FAILED; + } + + if (!reply.ReadInt32(result)) { + ANS_LOGW("[IsDistributedEnabled] fail: read result failed."); + return ERR_ANS_PARCELABLE_FAILED; + } + + if (!reply.ReadBool(enabled)) { + ANS_LOGW("[IsDistributedEnabled] fail: read enabled failed."); + return ERR_ANS_PARCELABLE_FAILED; + } + + return result; +} + +ErrCode AnsManagerProxy::EnableDistributed(bool enabled) +{ + MessageParcel data; + if (!data.WriteInterfaceToken(AnsManagerProxy::GetDescriptor())) { + ANS_LOGW("[EnableDistributed] fail: write interface token failed."); + return ERR_ANS_PARCELABLE_FAILED; + } + + if (!data.WriteBool(enabled)) { + ANS_LOGW("[EnableDistributed] fail: write enabled failed"); + return ERR_ANS_PARCELABLE_FAILED; + } + + MessageParcel reply; + MessageOption option = {MessageOption::TF_SYNC}; + ErrCode result = InnerTransact(ENABLE_DISTRIBUTED, option, data, reply); + if (result != ERR_OK) { + ANS_LOGW("[EnableDistributed] fail: transact ErrCode=%{public}d", result); + return ERR_ANS_TRANSACT_FAILED; + } + + if (!reply.ReadInt32(result)) { + ANS_LOGW("[EnableDistributed] fail: read result failed."); + return ERR_ANS_PARCELABLE_FAILED; + } + + return result; +} + +ErrCode AnsManagerProxy::EnableDistributedByBundle(const sptr &bundleOption, bool enabled) +{ + if (bundleOption == nullptr) { + ANS_LOGW("[EnableDistributedByBundle] fail: bundle is empty."); + return ERR_ANS_INVALID_PARAM; + } + + MessageParcel data; + if (!data.WriteInterfaceToken(AnsManagerProxy::GetDescriptor())) { + ANS_LOGW("[EnableDistributedByBundle] fail: write interface token failed."); + return ERR_ANS_PARCELABLE_FAILED; + } + + if (!data.WriteParcelable(bundleOption)) { + ANS_LOGW("[EnableDistributedByBundle] fail:: write bundle failed"); + return ERR_ANS_PARCELABLE_FAILED; + } + + if (!data.WriteBool(enabled)) { + ANS_LOGW("[EnableDistributedByBundle] fail:: write enabled failed"); + return ERR_ANS_PARCELABLE_FAILED; + } + + MessageParcel reply; + MessageOption option = {MessageOption::TF_SYNC}; + ErrCode result = InnerTransact(ENABLE_DISTRIBUTED_BY_BUNDLE, option, data, reply); + if (result != ERR_OK) { + ANS_LOGW("[EnableDistributedByBundle] fail: transact ErrCode=%{public}d", result); + return ERR_ANS_TRANSACT_FAILED; + } + + if (!reply.ReadInt32(result)) { + ANS_LOGW("[EnableDistributedByBundle] fail: read result failed."); + return ERR_ANS_PARCELABLE_FAILED; + } + + return result; +} + +ErrCode AnsManagerProxy::EnableDistributedSelf(bool enabled) +{ + MessageParcel data; + if (!data.WriteInterfaceToken(AnsManagerProxy::GetDescriptor())) { + ANS_LOGW("[EnableDistributedSelf] fail: write interface token failed."); + return ERR_ANS_PARCELABLE_FAILED; + } + + if (!data.WriteBool(enabled)) { + ANS_LOGW("[EnableDistributedSelf] fail: write enabled failed"); + return ERR_ANS_PARCELABLE_FAILED; + } + + MessageParcel reply; + MessageOption option = {MessageOption::TF_SYNC}; + ErrCode result = InnerTransact(ENABLE_DISTRIBUTED_SELF, option, data, reply); + if (result != ERR_OK) { + ANS_LOGW("[EnableDistributedSelf] fail: transact ErrCode=%{public}d", result); + return ERR_ANS_TRANSACT_FAILED; + } + + if (!reply.ReadInt32(result)) { + ANS_LOGW("[EnableDistributedSelf] fail: read result failed."); + return ERR_ANS_PARCELABLE_FAILED; + } + + return result; +} + +ErrCode AnsManagerProxy::IsDistributedEnableByBundle(const sptr &bundleOption, bool &enabled) +{ + if (bundleOption == nullptr) { + ANS_LOGW("[IsDistributedEnableByBundle] fail: bundle is empty."); + return ERR_ANS_INVALID_PARAM; + } + + MessageParcel data; + if (!data.WriteInterfaceToken(AnsManagerProxy::GetDescriptor())) { + ANS_LOGW("[IsDistributedEnableByBundle] fail: write interface token failed."); + return ERR_ANS_PARCELABLE_FAILED; + } + + if (!data.WriteParcelable(bundleOption)) { + ANS_LOGW("[IsDistributedEnableByBundle] fail: write bundle failed"); + return ERR_ANS_PARCELABLE_FAILED; + } + + MessageParcel reply; + MessageOption option = {MessageOption::TF_SYNC}; + ErrCode result = InnerTransact(IS_DISTRIBUTED_ENABLED_BY_BUNDLE, option, data, reply); + if (result != ERR_OK) { + ANS_LOGW("[IsDistributedEnableByBundle] fail: transact ErrCode=%{public}d", result); + return ERR_ANS_TRANSACT_FAILED; + } + + if (!reply.ReadInt32(result)) { + ANS_LOGW("[IsDistributedEnableByBundle] fail: read result failed."); + return ERR_ANS_PARCELABLE_FAILED; + } + + if (!reply.ReadBool(enabled)) { + ANS_LOGW("[IsDistributedEnableByBundle] fail: read enabled failed."); + return ERR_ANS_PARCELABLE_FAILED; + } + + return result; +} + ErrCode AnsManagerProxy::ShellDump(const std::string &dumpOption, std::vector &dumpInfo) { MessageParcel data; diff --git a/frameworks/ans/core/src/ans_manager_stub.cpp b/frameworks/ans/core/src/ans_manager_stub.cpp index 5344287790fb5299d8ffc333d288c254958cb0f6..2c37310aae705764b97c58d5a64dacfa248222d6 100644 --- a/frameworks/ans/core/src/ans_manager_stub.cpp +++ b/frameworks/ans/core/src/ans_manager_stub.cpp @@ -186,6 +186,21 @@ const std::map bundleOption = data.ReadParcelable(); + if (bundleOption == nullptr) { + ANS_LOGW("[HandleEnableDistributedByBundle] fail: read bundle failed."); + return ERR_ANS_PARCELABLE_FAILED; + } + + bool enabled = false; + if (!data.ReadBool(enabled)) { + ANS_LOGW("[HandleEnableDistributedByBundle] fail: read enabled failed."); + return ERR_ANS_PARCELABLE_FAILED; + } + + ErrCode result = EnableDistributedByBundle(bundleOption, enabled); + if (!reply.WriteInt32(result)) { + ANS_LOGW("[HandleEnableDistributedByBundle] fail: write result failed, ErrCode=%{public}d", result); + return ERR_ANS_PARCELABLE_FAILED; + } + + return ERR_OK; +} + +ErrCode AnsManagerStub::HandleEnableDistributedSelf(MessageParcel &data, MessageParcel &reply) +{ + bool enabled = false; + if (!data.ReadBool(enabled)) { + ANS_LOGW("[HandleEnableDistributedSelf] fail: read enabled failed."); + return ERR_ANS_PARCELABLE_FAILED; + } + + ErrCode result = EnableDistributedSelf(enabled); + if (!reply.WriteInt32(result)) { + ANS_LOGW("[HandleEnableDistributedSelf] fail: write result failed, ErrCode=%{public}d", result); + return ERR_ANS_PARCELABLE_FAILED; + } + + return ERR_OK; +} + +ErrCode AnsManagerStub::HandleIsDistributedEnableByBundle(MessageParcel &data, MessageParcel &reply) +{ + sptr bundleOption = data.ReadParcelable(); + if (bundleOption == nullptr) { + ANS_LOGW("[HandleIsDistributedEnableByBundle] fail: read bundle failed."); + return ERR_ANS_PARCELABLE_FAILED; + } + + bool enabled = false; + ErrCode result = IsDistributedEnableByBundle(bundleOption, enabled); + if (!reply.WriteInt32(result)) { + ANS_LOGW("[HandleIsDistributedEnableByBundle] fail: write result failed, ErrCode=%{public}d", result); + return ERR_ANS_PARCELABLE_FAILED; + } + + if (!reply.WriteBool(enabled)) { + ANS_LOGW("[HandleIsDistributedEnableByBundle] fail: write enabled failed."); + return ERR_ANS_PARCELABLE_FAILED; + } + + return ERR_OK; +} + ErrCode AnsManagerStub::HandleShellDump(MessageParcel &data, MessageParcel &reply) { std::string dumpOption; @@ -1743,6 +1855,36 @@ ErrCode AnsManagerStub::DoesSupportDoNotDisturbMode(bool &doesSupport) return ERR_INVALID_OPERATION; } +ErrCode AnsManagerStub::IsDistributedEnabled(bool &enabled) +{ + ANS_LOGW("AnsManagerStub::IsDistributedEnabled called!"); + return ERR_INVALID_OPERATION; +} + +ErrCode AnsManagerStub::EnableDistributed(bool enabled) +{ + ANS_LOGW("AnsManagerStub::EnableDistributed called!"); + return ERR_INVALID_OPERATION; +} + +ErrCode AnsManagerStub::EnableDistributedByBundle(const sptr &bundleOption, bool enabled) +{ + ANS_LOGW("AnsManagerStub::EnableDistributedByBundle called!"); + return ERR_INVALID_OPERATION; +} + +ErrCode AnsManagerStub::EnableDistributedSelf(bool enabled) +{ + ANS_LOGW("AnsManagerStub::EnableDistributedSelf called!"); + return ERR_INVALID_OPERATION; +} + +ErrCode AnsManagerStub::IsDistributedEnableByBundle(const sptr &bundleOption, bool &enabled) +{ + ANS_LOGW("AnsManagerStub::IsDistributedEnableByBundle called!"); + return ERR_INVALID_OPERATION; +} + ErrCode AnsManagerStub::ShellDump(const std::string &dumpOption, std::vector &dumpInfo) { ANS_LOGW("AnsManagerStub::ShellDump called!"); diff --git a/frameworks/ans/core/src/ans_notification.cpp b/frameworks/ans/core/src/ans_notification.cpp index 8087f3b110c0ef6cc20a6ab200ce50f103015a16..0e32f05897b6949baecaeedadafea2b69e5282f4 100644 --- a/frameworks/ans/core/src/ans_notification.cpp +++ b/frameworks/ans/core/src/ans_notification.cpp @@ -210,6 +210,9 @@ ErrCode AnsNotification::PublishNotification(const std::string &label, const Not ANS_LOGE("Failed to create NotificationRequest ptr"); return ERR_ANS_NO_MEMORY; } + if (IsNonDistributedNotificationType(reqPtr->GetNotificationType())) { + reqPtr->SetDistributed(false); + } return ansManagerProxy_->Publish(label, reqPtr); } @@ -220,6 +223,12 @@ ErrCode AnsNotification::PublishNotification(const NotificationRequest &request, return ERR_ANS_INVALID_PARAM; } + if (!deviceId.empty() && + (IsNonDistributedNotificationType(request.GetNotificationType()))) { + ANS_LOGE("Refuse to publish the conversational and picture notification to the remote device"); + return ERR_ANS_INVALID_PARAM; + } + if (!CanPublishMediaContent(request)) { ANS_LOGE("Refuse to publish the notification because the sequence numbers actions not match those assigned to " "added action buttons."); @@ -362,6 +371,9 @@ ErrCode AnsNotification::PublishNotificationAsBundle( ANS_LOGE("Failed to create NotificationRequest ptr"); return ERR_ANS_NO_MEMORY; } + if (IsNonDistributedNotificationType(reqPtr->GetNotificationType())) { + reqPtr->SetDistributed(false); + } return ansManagerProxy_->PublishAsBundle(reqPtr, representativeBundle); } @@ -820,6 +832,23 @@ ErrCode AnsNotification::DoesSupportDoNotDisturbMode(bool &doesSupport) ErrCode AnsNotification::PublishContinuousTaskNotification(const NotificationRequest &request) { + if (request.GetContent() == nullptr || request.GetNotificationType() == NotificationContent::Type::NONE) { + ANS_LOGE("Refuse to publish the notification without valid content"); + return ERR_ANS_INVALID_PARAM; + } + + if (!CanPublishMediaContent(request)) { + ANS_LOGE("Refuse to publish the notification because the sequence numbers actions not match those assigned to " + "added action buttons."); + return ERR_ANS_INVALID_PARAM; + } + + ErrCode checkErr = CheckImageSize(request); + if (checkErr != ERR_OK) { + ANS_LOGE("The size of one picture exceeds the limit"); + return checkErr; + } + if (!GetAnsManagerProxy()) { ANS_LOGE("GetAnsManagerProxy fail."); return ERR_ANS_SERVICE_NOT_CONNECTED; @@ -827,11 +856,14 @@ ErrCode AnsNotification::PublishContinuousTaskNotification(const NotificationReq auto pReq = new (std::nothrow) NotificationRequest(request); if (pReq == nullptr) { - ANS_LOGE("create NotificationRequest failed."); + ANS_LOGE("Failed to create NotificationRequest ptr."); return ERR_ANS_NO_MEMORY; } sptr sptrReq(pReq); + if (IsNonDistributedNotificationType(sptrReq->GetNotificationType())) { + sptrReq->SetDistributed(false); + } return ansManagerProxy_->PublishContinuousTaskNotification(sptrReq); } @@ -845,6 +877,58 @@ ErrCode AnsNotification::CancelContinuousTaskNotification(const std::string &lab return ansManagerProxy_->CancelContinuousTaskNotification(label, notificationId); } +ErrCode AnsNotification::IsDistributedEnabled(bool &enabled) +{ + if (!GetAnsManagerProxy()) { + ANS_LOGE("GetAnsManagerProxy fail."); + return ERR_ANS_SERVICE_NOT_CONNECTED; + } + + return ansManagerProxy_->IsDistributedEnabled(enabled); +} + +ErrCode AnsNotification::EnableDistributed(const bool enabled) +{ + if (!GetAnsManagerProxy()) { + ANS_LOGE("GetAnsManagerProxy fail."); + return ERR_ANS_SERVICE_NOT_CONNECTED; + } + + return ansManagerProxy_->EnableDistributed(enabled); +} + +ErrCode AnsNotification::EnableDistributedByBundle(const NotificationBundleOption &bundleOption, const bool enabled) +{ + if (!GetAnsManagerProxy()) { + ANS_LOGE("GetAnsManagerProxy fail."); + return ERR_ANS_SERVICE_NOT_CONNECTED; + } + + sptr bo(new (std::nothrow) NotificationBundleOption(bundleOption)); + return ansManagerProxy_->EnableDistributedByBundle(bo, enabled); +} + +ErrCode AnsNotification::EnableDistributedSelf(const bool enabled) +{ + if (!GetAnsManagerProxy()) { + ANS_LOGE("GetAnsManagerProxy fail."); + return ERR_ANS_SERVICE_NOT_CONNECTED; + } + + return ansManagerProxy_->EnableDistributedSelf(enabled); +} + +ErrCode AnsNotification::IsDistributedEnableByBundle(const NotificationBundleOption &bundleOption, bool &enabled) +{ + if (!GetAnsManagerProxy()) { + ANS_LOGE("GetAnsManagerProxy fail."); + return ERR_ANS_SERVICE_NOT_CONNECTED; + } + + sptr bo(new (std::nothrow) NotificationBundleOption(bundleOption)); + return ansManagerProxy_->IsDistributedEnableByBundle(bo, enabled); +} + void AnsNotification::ResetAnsManagerProxy() { ANS_LOGI("enter"); @@ -1109,5 +1193,14 @@ ErrCode AnsNotification::IsSupportTemplate(const std::string &templateName, bool return ansManagerProxy_->IsSupportTemplate(templateName, support); } + +bool AnsNotification::IsNonDistributedNotificationType(const NotificationContent::Type &type) +{ + if ((type == NotificationContent::Type::CONVERSATION) || + (type == NotificationContent::Type::PICTURE)) { + return true; + } + return false; +} } // namespace Notification } // namespace OHOS \ No newline at end of file diff --git a/frameworks/ans/native/BUILD.gn b/frameworks/ans/native/BUILD.gn index 7ee17121edde5eea30e0cb8cfbdcbfb263653d94..6be024c76756a6692980329088ec6f02814cc01f 100644 --- a/frameworks/ans/native/BUILD.gn +++ b/frameworks/ans/native/BUILD.gn @@ -47,6 +47,7 @@ ohos_shared_library("ans_innerkits") { "src/notification_content.cpp", "src/notification_conversational_content.cpp", "src/notification_conversational_message.cpp", + "src/notification_distributed_options.cpp", "src/notification_do_not_disturb_date.cpp", "src/notification_helper.cpp", "src/notification_long_text_content.cpp", diff --git a/frameworks/ans/native/src/message_user.cpp b/frameworks/ans/native/src/message_user.cpp index 82a6425140a519fae6b077aa4b7cf0872bfd0623..385eafd0f6eee5a71a2cc4740d29038c64047202 100644 --- a/frameworks/ans/native/src/message_user.cpp +++ b/frameworks/ans/native/src/message_user.cpp @@ -14,13 +14,12 @@ */ #include "message_user.h" +#include "ans_image_util.h" #include "ans_log_wrapper.h" namespace OHOS { namespace Notification { - -MessageUser::MessageUser() - : uri_("") +MessageUser::MessageUser() : uri_("") {} MessageUser::~MessageUser() @@ -98,6 +97,60 @@ std::string MessageUser::Dump() const " }"; } +bool MessageUser::ToJson(nlohmann::json &jsonObject) const +{ + jsonObject["key"] = key_; + jsonObject["name"] = name_; + jsonObject["pixelMap"] = AnsImageUtil::PackImage(pixelMap_); + jsonObject["uri"] = uri_.ToString(); + jsonObject["isMachine"] = isMachine_; + jsonObject["isUserImportant"] = isUserImportant_; + + return true; +} + +MessageUser *MessageUser::FromJson(const nlohmann::json &jsonObject) +{ + if (jsonObject.is_null() or !jsonObject.is_object()) { + ANS_LOGE("Invalid JSON object"); + return nullptr; + } + + MessageUser *messageUser = new (std::nothrow) MessageUser(); + if (messageUser == nullptr) { + ANS_LOGE("Failed to create messageUse instance"); + return nullptr; + } + + const auto &jsonEnd = jsonObject.cend(); + if (jsonObject.find("key") != jsonEnd) { + messageUser->key_ = jsonObject.at("key").get(); + } + + if (jsonObject.find("name") != jsonEnd) { + messageUser->name_ = jsonObject.at("name").get(); + } + + if (jsonObject.find("pixelMap") != jsonEnd) { + auto pmStr = jsonObject.at("pixelMap").get(); + messageUser->pixelMap_ = AnsImageUtil::UnPackImage(pmStr); + } + + if (jsonObject.find("uri") != jsonEnd) { + messageUser->uri_ = Uri(jsonObject.at("uri").get()); + } + + if (jsonObject.find("isMachine") != jsonEnd) { + messageUser->isMachine_ = jsonObject.at("isMachine").get(); + } + + if (jsonObject.find("isUserImportant") != jsonEnd) { + messageUser->isUserImportant_ = jsonObject.at("isUserImportant").get(); + } + + return messageUser; +} + bool MessageUser::Marshalling(Parcel &parcel) const { if (!parcel.WriteString(key_)) { diff --git a/frameworks/ans/native/src/notification.cpp b/frameworks/ans/native/src/notification.cpp index e0ab103e8cb22e83c1ebba90fd8dec3d6aa2095a..c146e5491241b7d556159f988481d2fb8032726f 100644 --- a/frameworks/ans/native/src/notification.cpp +++ b/frameworks/ans/native/src/notification.cpp @@ -25,7 +25,14 @@ Notification::Notification() {}; Notification::Notification(const sptr &request) { request_ = request; - key_ = GenerateNotificationKey(GetUid(), GetLabel(), GetId()); + key_ = GenerateNotificationKey("", GetUid(), GetLabel(), GetId()); +} + +Notification::Notification(const std::string &deviceId, const sptr &request) +{ + deviceId_ = deviceId; + request_ = request; + key_ = GenerateNotificationKey(deviceId, GetUid(), GetLabel(), GetId()); } Notification::Notification(const Notification &other) @@ -42,6 +49,7 @@ Notification::Notification(const Notification &other) vibrationStyle_ = other.vibrationStyle_; isRemoveAllowed_ = other.isRemoveAllowed_; sourceType_ = other.sourceType_; + deviceId_ = other.deviceId_; } Notification::~Notification() @@ -182,6 +190,11 @@ NotificationConstant::SourceType Notification::GetSourceType() const return sourceType_; } +std::string Notification::GetDeviceId() const +{ + return deviceId_; +} + int32_t Notification::GetUserId() const { if (request_ == nullptr) { @@ -229,6 +242,11 @@ bool Notification::MarshallingString(Parcel &parcel) const } } + if (!parcel.WriteString(deviceId_)) { + ANS_LOGE("Can't wirte deviceId"); + return false; + } + return true; } @@ -322,6 +340,9 @@ void Notification::ReadFromParcelString(Parcel &parcel) if (enableSound_) { sound_ = std::make_shared(parcel.ReadString()); } + + // Read deviceId_ + deviceId_ = parcel.ReadString(); } void Notification::ReadFromParcelInt32(Parcel &parcel) @@ -364,7 +385,7 @@ bool Notification::ReadFromParcel(Parcel &parcel) Notification *Notification::Unmarshalling(Parcel &parcel) { - Notification *n = new Notification(); + Notification *n = new (std::nothrow) Notification(); if (n && !n->ReadFromParcel(parcel)) { ANS_LOGE("Read from parcel error"); delete n; @@ -413,12 +434,13 @@ void Notification::SetVibrationStyle(const std::vector &style) vibrationStyle_ = style; } -std::string Notification::GenerateNotificationKey(int32_t uid, const std::string &label, int32_t id) +std::string Notification::GenerateNotificationKey( + const std::string &deviceId, int32_t uid, const std::string &label, int32_t id) { const char *KEY_SPLITER = "_"; std::stringstream stream; - stream << uid << KEY_SPLITER << label << KEY_SPLITER << id; + stream << deviceId << KEY_SPLITER << uid << KEY_SPLITER << label << KEY_SPLITER << id; return stream.str(); } @@ -435,22 +457,23 @@ void Notification::SetSourceType(NotificationConstant::SourceType sourceType) std::string Notification::Dump() const { - std::string dump = "Notification{ key = " + key_ + ", ledLightColor = " + std::to_string(ledLightColor_) + - ", lockscreenVisbleness = " + std::to_string(static_cast(lockscreenVisibleness_)) + - ", isRemoveAllowed = " + (isRemoveAllowed_ ? "true" : "false") + - ", sourceType = " + std::to_string(static_cast(sourceType_)) + - ",request = "; - if (request_ == nullptr) { - dump += "nullptr"; - } else { - dump += request_->Dump(); - } - dump = dump + ",postTime = " + std::to_string(postTime_) + ",sound = " + sound_->ToString() + "vibrationStyle = "; + std::string vibrationStyle = ""; for (auto &style : vibrationStyle_) { - dump += std::to_string(style); - dump += ","; - } - return dump; + vibrationStyle += std::to_string(style); + vibrationStyle += ", "; + } + return "Notification{ " + "key = " + key_ + + ", ledLightColor = " + std::to_string(ledLightColor_) + + ", lockscreenVisbleness = " + std::to_string(static_cast(lockscreenVisibleness_)) + + ", isRemoveAllowed = " + (isRemoveAllowed_ ? "true" : "false") + + ", sourceType = " + std::to_string(static_cast(sourceType_)) + + ", deviceId = " + deviceId_ + + ", request = " + (request_ == nullptr ? "nullptr" : request_->Dump()) + + ", postTime = " + std::to_string(postTime_) + + ", sound = " + (sound_ == nullptr ? "nullptr" : sound_->ToString()) + + ", vibrationStyle = [" + vibrationStyle + "]" + + " }"; } } // namespace Notification } // namespace OHOS \ No newline at end of file diff --git a/frameworks/ans/native/src/notification_action_button.cpp b/frameworks/ans/native/src/notification_action_button.cpp index b129a547aa0dceebd3a38bd2a2ddb68cea5a59e4..ebe29e88657266ddeb22212b20312a2872b3013d 100644 --- a/frameworks/ans/native/src/notification_action_button.cpp +++ b/frameworks/ans/native/src/notification_action_button.cpp @@ -15,7 +15,10 @@ #include "notification_action_button.h" +#include "ans_image_util.h" #include "ans_log_wrapper.h" +#include "want_agent_helper.h" +#include "want_params_wrapper.h" namespace OHOS { namespace Notification { @@ -73,6 +76,11 @@ std::shared_ptr NotificationActionButton::Create(const std::shared_ptr NotificationActionButton::Create( const std::shared_ptr &actionButton) { + if (!actionButton) { + ANS_LOGW("invalid input NotificationActionButton object"); + return {}; + } + return NotificationActionButton::Create(actionButton->GetIcon(), actionButton->GetTitle(), actionButton->GetWantAgent(), @@ -224,6 +232,61 @@ std::string NotificationActionButton::Dump() " }"; } +bool NotificationActionButton::ToJson(nlohmann::json &jsonObject) const +{ + jsonObject["icon"] = AnsImageUtil::PackImage(icon_); + jsonObject["title"] = title_; + jsonObject["wantAgent"] = wantAgent_ ? WantAgent::WantAgentHelper::ToString(wantAgent_) : ""; + + std::string extrasStr; + if (extras_) { + AAFwk::WantParamWrapper wWrapper(*extras_); + extrasStr = wWrapper.ToString(); + } + jsonObject["extras"] = extrasStr; + + return true; +} + +NotificationActionButton *NotificationActionButton::FromJson(const nlohmann::json &jsonObject) +{ + if (jsonObject.is_null() or !jsonObject.is_object()) { + ANS_LOGE("Invalid JSON object"); + return nullptr; + } + + auto pButton = new (std::nothrow) NotificationActionButton(); + if (pButton == nullptr) { + ANS_LOGE("Failed to create actionButton instance"); + return nullptr; + } + + const auto &jsonEnd = jsonObject.cend(); + if (jsonObject.find("icon") != jsonEnd) { + auto iconStr = jsonObject.at("icon").get(); + pButton->icon_ = AnsImageUtil::UnPackImage(iconStr); + } + + if (jsonObject.find("title") != jsonEnd) { + pButton->title_ = jsonObject.at("title").get(); + } + + if (jsonObject.find("wantAgent") != jsonEnd) { + auto wantAgentValue = jsonObject.at("wantAgent").get(); + pButton->wantAgent_ = WantAgent::WantAgentHelper::FromString(wantAgentValue); + } + + if (jsonObject.find("extras") != jsonEnd) { + auto extrasString = jsonObject.at("extras").get(); + if (!extrasString.empty()) { + AAFwk::WantParams params = AAFwk::WantParamWrapper::ParseWantParams(extrasString); + pButton->extras_ = std::make_shared(params); + } + } + + return pButton; +} + bool NotificationActionButton::Marshalling(Parcel &parcel) const { if (!parcel.WriteString(title_)) { diff --git a/frameworks/ans/native/src/notification_basic_content.cpp b/frameworks/ans/native/src/notification_basic_content.cpp index 4942104e27005aed6c96a26185e47e50a81796ac..0ab51a5c32f1697c0341cd9549c3ad8356730fa1 100644 --- a/frameworks/ans/native/src/notification_basic_content.cpp +++ b/frameworks/ans/native/src/notification_basic_content.cpp @@ -56,6 +56,36 @@ std::string NotificationBasicContent::Dump() return "title = " + title_ + ", text = " + text_ + ", additionalText = " + additionalText_; } +bool NotificationBasicContent::ToJson(nlohmann::json &jsonObject) const +{ + jsonObject["text"] = text_; + jsonObject["title"] = title_; + jsonObject["additionalText"] = additionalText_; + + return true; +} + +void NotificationBasicContent::ReadFromJson(const nlohmann::json &jsonObject) +{ + if (jsonObject.is_null() or !jsonObject.is_object()) { + ANS_LOGE("Invalid JSON object"); + return; + } + + const auto &jsonEnd = jsonObject.cend(); + if (jsonObject.find("text") != jsonEnd) { + text_ = jsonObject.at("text").get(); + } + + if (jsonObject.find("title") != jsonEnd) { + title_ = jsonObject.at("title").get(); + } + + if (jsonObject.find("additionalText") != jsonEnd) { + additionalText_ = jsonObject.at("additionalText").get(); + } +} + bool NotificationBasicContent::Marshalling(Parcel &parcel) const { if (!parcel.WriteString(text_)) { diff --git a/frameworks/ans/native/src/notification_bundle_option.cpp b/frameworks/ans/native/src/notification_bundle_option.cpp index 402d186d8ccfe89c6f7ecb1713fe2b4b7a1f7540..7e83ebb8cd2ff6ca6809f8524c386a808f538c76 100644 --- a/frameworks/ans/native/src/notification_bundle_option.cpp +++ b/frameworks/ans/native/src/notification_bundle_option.cpp @@ -70,7 +70,7 @@ bool NotificationBundleOption::Marshalling(Parcel &parcel) const NotificationBundleOption *NotificationBundleOption::Unmarshalling(Parcel &parcel) { - auto pbundleOption = new NotificationBundleOption(); + auto pbundleOption = new (std::nothrow) NotificationBundleOption(); if ((nullptr != pbundleOption) && !pbundleOption->ReadFromParcel(parcel)) { delete pbundleOption; pbundleOption = nullptr; diff --git a/frameworks/ans/native/src/notification_content.cpp b/frameworks/ans/native/src/notification_content.cpp index f76e41ef4bd9705f7ff004dd45993d754a36ebb5..4ece6f602c8b72830126b64398653480dd75b292 100644 --- a/frameworks/ans/native/src/notification_content.cpp +++ b/frameworks/ans/native/src/notification_content.cpp @@ -112,6 +112,53 @@ std::string NotificationContent::Dump() " }"; } +bool NotificationContent::ToJson(nlohmann::json &jsonObject) const +{ + jsonObject["contentType"] = static_cast(contentType_); + + if (!content_) { + ANS_LOGE("Invalid content. Cannot convert to JSON."); + return false; + } + + nlohmann::json contentObj; + if (!NotificationJsonConverter::ConvertToJosn(content_.get(), contentObj)) { + ANS_LOGE("Cannot convert content to JSON"); + return false; + } + jsonObject["content"] = contentObj; + + return true; +} + +NotificationContent *NotificationContent::FromJson(const nlohmann::json &jsonObject) +{ + if (jsonObject.is_null() or !jsonObject.is_object()) { + ANS_LOGE("Invalid JSON object"); + return nullptr; + } + + const auto &jsonEnd = jsonObject.cend(); + if ((jsonObject.find("contentType") == jsonEnd) || (jsonObject.find("content") == jsonEnd)) { + ANS_LOGE("Incomplete NotificationContent json object. Cannot convert content from JSON."); + return nullptr; + } + + auto pContent = new (std::nothrow) NotificationContent(); + if (pContent == nullptr) { + ANS_LOGE("Failed to create NotificationContent instance"); + return nullptr; + } + + if (!ConvertJsonToContent(pContent, jsonObject)) { + delete pContent; + pContent = nullptr; + return nullptr; + } + + return pContent; +} + bool NotificationContent::Marshalling(Parcel &parcel) const { if (!parcel.WriteInt32(static_cast(contentType_))) { @@ -192,5 +239,51 @@ bool NotificationContent::ReadFromParcel(Parcel &parcel) return true; } + +bool NotificationContent::ConvertJsonToContent(NotificationContent *target, const nlohmann::json &jsonObject) +{ + if (target == nullptr) { + ANS_LOGE("Invalid input parameter"); + return false; + } + + auto contentTypeValue = jsonObject.at("contentType").get(); + target->contentType_ = static_cast(contentTypeValue); + + auto contentObj = jsonObject.at("content"); + if (contentObj.is_null()) { + ANS_LOGE("Invalid json object. Cannot convert content from JSON."); + return false; + } + + NotificationBasicContent *pBasicContent {nullptr}; + switch (target->contentType_) { + case NotificationContent::Type::BASIC_TEXT: + pBasicContent = NotificationJsonConverter::ConvertFromJosn(contentObj); + break; + case NotificationContent::Type::CONVERSATION: + pBasicContent = NotificationJsonConverter::ConvertFromJosn(contentObj); + break; + case NotificationContent::Type::LONG_TEXT: + pBasicContent = NotificationJsonConverter::ConvertFromJosn(contentObj); + break; + case NotificationContent::Type::MULTILINE: + pBasicContent = NotificationJsonConverter::ConvertFromJosn(contentObj); + break; + case NotificationContent::Type::PICTURE: + pBasicContent = NotificationJsonConverter::ConvertFromJosn(contentObj); + break; + default: + ANS_LOGE("Invalid contentType"); + break; + } + if (pBasicContent == nullptr) { + ANS_LOGE("Parse content error!"); + return false; + } + target->content_ = std::shared_ptr(pBasicContent); + + return true; +} } // namespace Notification } // namespace OHOS diff --git a/frameworks/ans/native/src/notification_conversational_content.cpp b/frameworks/ans/native/src/notification_conversational_content.cpp index 13785133251d0c40d585eceafc7661e7ad482a41..08f3599b71af42ee59cf801cb61c56a16dc69216 100644 --- a/frameworks/ans/native/src/notification_conversational_content.cpp +++ b/frameworks/ans/native/src/notification_conversational_content.cpp @@ -93,6 +93,87 @@ std::string NotificationConversationalContent::Dump() " }"; } +bool NotificationConversationalContent::ToJson(nlohmann::json &jsonObject) const +{ + if (!NotificationBasicContent::ToJson(jsonObject)) { + ANS_LOGE("Cannot convert basicContent to JSON"); + return false; + } + + nlohmann::json userObj; + if (!NotificationJsonConverter::ConvertToJosn(&messageUser_, userObj)) { + ANS_LOGE("Cannot convert messageUser to JSON"); + return false; + } + jsonObject["messageUser"] = userObj; + + jsonObject["conversationTitle"] = conversationTitle_; + jsonObject["isGroup"] = isGroup_; + + nlohmann::json msgsArr = nlohmann::json::array(); + for (auto &msg : messages_) { + if (!msg) { + continue; + } + + nlohmann::json msgObj; + if (!NotificationJsonConverter::ConvertToJosn(msg.get(), msgObj)) { + ANS_LOGE("Cannot convert conversationalMessage to JSON"); + return false; + } + msgsArr.emplace_back(msgObj); + } + jsonObject["messages"] = msgsArr; + + return true; +} + +NotificationConversationalContent *NotificationConversationalContent::FromJson(const nlohmann::json &jsonObject) +{ + if (jsonObject.is_null() or !jsonObject.is_object()) { + ANS_LOGE("Invalid JSON object"); + return nullptr; + } + + auto pContent = new (std::nothrow) NotificationConversationalContent(); + if (pContent == nullptr) { + ANS_LOGE("Failed to create conversationalContent instance"); + return nullptr; + } + + pContent->ReadFromJson(jsonObject); + + const auto &jsonEnd = jsonObject.cend(); + if (jsonObject.find("messageUser") != jsonEnd) { + auto userObj = jsonObject.at("messageUser"); + auto pUser = NotificationJsonConverter::ConvertFromJosn(userObj); + if (pUser != nullptr) { + pContent->messageUser_ = *pUser; + + delete pUser; + pUser = nullptr; + } + } + + if (jsonObject.find("messages") != jsonEnd) { + nlohmann::json msgsArr = jsonObject.at("messages"); + for (auto &msgObj : msgsArr) { + auto pMsg = NotificationJsonConverter::ConvertFromJosn(msgObj); + if (pMsg == nullptr) { + ANS_LOGE("Failed to parse message "); + + delete pContent; + pContent = nullptr; + return nullptr; + } + + pContent->messages_.emplace_back(pMsg); + } + } + + return pContent; +} + bool NotificationConversationalContent::Marshalling(Parcel &parcel) const { if (!NotificationBasicContent::Marshalling(parcel)) { diff --git a/frameworks/ans/native/src/notification_conversational_message.cpp b/frameworks/ans/native/src/notification_conversational_message.cpp index 1f385c03b81105e0d84bcae3bcde4436ce238308..520a5fbfca36af631ac6a78b337c3edc8a2b25e2 100644 --- a/frameworks/ans/native/src/notification_conversational_message.cpp +++ b/frameworks/ans/native/src/notification_conversational_message.cpp @@ -65,6 +65,71 @@ std::string NotificationConversationalMessage::Dump() " }"; } +bool NotificationConversationalMessage::ToJson(nlohmann::json &jsonObject) const +{ + jsonObject["arrivedTime"] = arrivedTime_; + jsonObject["text"] = text_; + + nlohmann::json userObj; + if (!NotificationJsonConverter::ConvertToJosn(&sender_, userObj)) { + ANS_LOGE("Cannot convert sender to JSON"); + return false; + } + jsonObject["sender"] = userObj; + + jsonObject["uri"] = uri_ ? uri_->ToString() : ""; + jsonObject["mimeType"] = mimeType_; + + return true; +} + +NotificationConversationalMessage *NotificationConversationalMessage::FromJson(const nlohmann::json &jsonObject) +{ + if (jsonObject.is_null() or !jsonObject.is_object()) { + ANS_LOGE("Invalid JSON object"); + return nullptr; + } + + auto pMessage = new (std::nothrow) NotificationConversationalMessage(); + if (pMessage == nullptr) { + ANS_LOGE("Failed to create conversationalMessage instance"); + return nullptr; + } + + const auto &jsonEnd = jsonObject.cend(); + if (jsonObject.find("arrivedTime") != jsonEnd) { + pMessage->arrivedTime_ = jsonObject.at("arrivedTime").get(); + } + + if (jsonObject.find("text") != jsonEnd) { + pMessage->text_ = jsonObject.at("text").get(); + } + + if (jsonObject.find("sender") != jsonEnd) { + auto userObj = jsonObject.at("sender"); + auto pUser = NotificationJsonConverter::ConvertFromJosn(userObj); + if (pUser != nullptr) { + pMessage->sender_ = *pUser; + + delete pUser; + pUser = nullptr; + } + } + + if (jsonObject.find("uri") != jsonEnd) { + auto uriStr = jsonObject.at("uri").get(); + if (!uriStr.empty()) { + pMessage->uri_ = std::make_shared(uriStr); + } + } + + if (jsonObject.find("mimeType") != jsonEnd) { + pMessage->mimeType_ = jsonObject.at("mimeType").get(); + } + + return pMessage; +} + bool NotificationConversationalMessage::Marshalling(Parcel &parcel) const { if (!parcel.WriteInt64(arrivedTime_)) { diff --git a/frameworks/ans/native/src/notification_distributed_options.cpp b/frameworks/ans/native/src/notification_distributed_options.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dbfb26a275de63819df7b2262afed6180f288f69 --- /dev/null +++ b/frameworks/ans/native/src/notification_distributed_options.cpp @@ -0,0 +1,163 @@ +/* + * 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 "notification_distributed_options.h" +#include "ans_log_wrapper.h" + +namespace OHOS { +namespace Notification { +NotificationDistributedOptions::NotificationDistributedOptions( + bool distribute, const std::vector &dvsDisplay, const std::vector &dvsOperate) + : isDistributed_(distribute), devicesSupportDisplay_(dvsDisplay), devicesSupportOperate_(dvsOperate) +{} + +void NotificationDistributedOptions::SetDistributed(bool distribute) +{ + isDistributed_ = distribute; +} + +bool NotificationDistributedOptions::IsDistributed() const +{ + return isDistributed_; +} + +void NotificationDistributedOptions::SetDevicesSupportDisplay(const std::vector &devices) +{ + devicesSupportDisplay_ = devices; +} + +std::vector NotificationDistributedOptions::GetDevicesSupportDisplay() const +{ + return devicesSupportDisplay_; +} + +void NotificationDistributedOptions::SetDevicesSupportOperate(const std::vector &devices) +{ + devicesSupportOperate_ = devices; +} + +std::vector NotificationDistributedOptions::GetDevicesSupportOperate() const +{ + return devicesSupportOperate_; +} + +std::string NotificationDistributedOptions::Dump() +{ + std::string devicesSupportDisplay = ""; + for (auto &device : devicesSupportDisplay_) { + devicesSupportDisplay += device; + devicesSupportDisplay += ", "; + } + + std::string devicesSupportOperate = ""; + for (auto &device : devicesSupportOperate_) { + devicesSupportOperate += device; + devicesSupportOperate += ", "; + } + + return "NotificationDistributedOptions{ " + "isDistributed = " + std::string((isDistributed_ ? "true" : "false")) + + ", devicesSupportDisplay = [" + devicesSupportDisplay + "]" + + ", devicesSupportOperate = [" + devicesSupportOperate + "]" + + " }"; +} + +bool NotificationDistributedOptions::ToJson(nlohmann::json &jsonObject) const +{ + jsonObject["isDistributed"] = isDistributed_; + jsonObject["devicesSupportDisplay"] = nlohmann::json(devicesSupportDisplay_); + jsonObject["devicesSupportOperate"] = nlohmann::json(devicesSupportOperate_); + + return true; +} + +NotificationDistributedOptions *NotificationDistributedOptions::FromJson(const nlohmann::json &jsonObject) +{ + if (jsonObject.is_null() or !jsonObject.is_object()) { + ANS_LOGE("Invalid JSON object"); + return nullptr; + } + + auto pOpt = new (std::nothrow) NotificationDistributedOptions(); + if (pOpt == nullptr) { + ANS_LOGE("Failed to create distributedOptions instance"); + return nullptr; + } + + const auto &jsonEnd = jsonObject.cend(); + if (jsonObject.find("isDistributed") != jsonEnd) { + pOpt->isDistributed_ = jsonObject.at("isDistributed").get(); + } + + if (jsonObject.find("devicesSupportDisplay") != jsonEnd) { + pOpt->devicesSupportDisplay_ = jsonObject.at("devicesSupportDisplay").get>(); + } + + if (jsonObject.find("devicesSupportOperate") != jsonEnd) { + pOpt->devicesSupportOperate_ = jsonObject.at("devicesSupportOperate").get>(); + } + + return pOpt; +} + +bool NotificationDistributedOptions::Marshalling(Parcel &parcel) const +{ + if (!parcel.WriteBool(isDistributed_)) { + ANS_LOGE("Failed to write flag isdistributed"); + return false; + } + + if (!parcel.WriteStringVector(devicesSupportDisplay_)) { + ANS_LOGE("Failed to write devicesSupportDisplay"); + return false; + } + + if (!parcel.WriteStringVector(devicesSupportOperate_)) { + ANS_LOGE("Failed to write devicesSupportOperate"); + return false; + } + + return true; +} + +NotificationDistributedOptions *NotificationDistributedOptions::Unmarshalling(Parcel &parcel) +{ + auto objptr = new (std::nothrow) NotificationDistributedOptions(); + if ((objptr != nullptr) && !objptr->ReadFromParcel(parcel)) { + delete objptr; + objptr = nullptr; + } + + return objptr; +} + +bool NotificationDistributedOptions::ReadFromParcel(Parcel &parcel) +{ + isDistributed_ = parcel.ReadBool(); + + if (!parcel.ReadStringVector(&devicesSupportDisplay_)) { + ANS_LOGE("Failed to read devicesSupportDisplay"); + return false; + } + + if (!parcel.ReadStringVector(&devicesSupportOperate_)) { + ANS_LOGE("Failed to read devicesSupportOperate"); + return false; + } + + return true; +} +} // namespace Notification +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/ans/native/src/notification_helper.cpp b/frameworks/ans/native/src/notification_helper.cpp index 7f0bc3619ef4f61cfc897b6f18716b11d9ca2606..4cf4afaa180b505c603b5d15536edbd65b6b0853 100644 --- a/frameworks/ans/native/src/notification_helper.cpp +++ b/frameworks/ans/native/src/notification_helper.cpp @@ -307,12 +307,12 @@ ErrCode NotificationHelper::RemoveGroupByBundle( return DelayedSingleton::GetInstance()->RemoveGroupByBundle(bundleOption, groupName); } -ErrCode NotificationHelper::SetDoNotDisturbDate(const NotificationDoNotDisturbDate & doNotDisturbDate) +ErrCode NotificationHelper::SetDoNotDisturbDate(const NotificationDoNotDisturbDate &doNotDisturbDate) { return DelayedSingleton::GetInstance()->SetDoNotDisturbDate(doNotDisturbDate); } -ErrCode NotificationHelper::GetDoNotDisturbDate(NotificationDoNotDisturbDate & doNotDisturbDate) +ErrCode NotificationHelper::GetDoNotDisturbDate(NotificationDoNotDisturbDate &doNotDisturbDate) { return DelayedSingleton::GetInstance()->GetDoNotDisturbDate(doNotDisturbDate); } @@ -322,6 +322,31 @@ ErrCode NotificationHelper::DoesSupportDoNotDisturbMode(bool &doesSupport) return DelayedSingleton::GetInstance()->DoesSupportDoNotDisturbMode(doesSupport); } +ErrCode NotificationHelper::IsDistributedEnabled(bool &enabled) +{ + return DelayedSingleton::GetInstance()->IsDistributedEnabled(enabled); +} + +ErrCode NotificationHelper::EnableDistributed(const bool enabled) +{ + return DelayedSingleton::GetInstance()->EnableDistributed(enabled); +} + +ErrCode NotificationHelper::EnableDistributedByBundle(const NotificationBundleOption &bundleOption, const bool enabled) +{ + return DelayedSingleton::GetInstance()->EnableDistributedByBundle(bundleOption, enabled); +} + +ErrCode NotificationHelper::EnableDistributedSelf(const bool enabled) +{ + return DelayedSingleton::GetInstance()->EnableDistributedSelf(enabled); +} + +ErrCode NotificationHelper::IsDistributedEnableByBundle(const NotificationBundleOption &bundleOption, bool &enabled) +{ + return DelayedSingleton::GetInstance()->IsDistributedEnableByBundle(bundleOption, enabled); +} + ErrCode NotificationHelper::PublishContinuousTaskNotification(const NotificationRequest &request) { return DelayedSingleton::GetInstance()->PublishContinuousTaskNotification(request); diff --git a/frameworks/ans/native/src/notification_long_text_content.cpp b/frameworks/ans/native/src/notification_long_text_content.cpp index 0e242feee4ceb9b0e14be01d4338ddb2018b0a23..7abf07403844dd0f3b79f89f40dcbecb15c5a522 100644 --- a/frameworks/ans/native/src/notification_long_text_content.cpp +++ b/frameworks/ans/native/src/notification_long_text_content.cpp @@ -71,6 +71,51 @@ std::string NotificationLongTextContent::Dump() " }"; } +bool NotificationLongTextContent::ToJson(nlohmann::json &jsonObject) const +{ + if (!NotificationBasicContent::ToJson(jsonObject)) { + ANS_LOGE("Cannot convert basicContent to JSON"); + return false; + } + + jsonObject["longText"] = longText_; + jsonObject["expandedTitle"] = expandedTitle_; + jsonObject["briefText"] = briefText_; + + return true; +} + +NotificationLongTextContent *NotificationLongTextContent::FromJson(const nlohmann::json &jsonObject) +{ + if (jsonObject.is_null() or !jsonObject.is_object()) { + ANS_LOGE("Invalid JSON object"); + return nullptr; + } + + auto pContent = new (std::nothrow) NotificationLongTextContent(); + if (pContent == nullptr) { + ANS_LOGE("Failed to create longTextContent instance"); + return nullptr; + } + + pContent->ReadFromJson(jsonObject); + + const auto &jsonEnd = jsonObject.cend(); + if (jsonObject.find("longText") != jsonEnd) { + pContent->longText_ = jsonObject.at("longText").get(); + } + + if (jsonObject.find("expandedTitle") != jsonEnd) { + pContent->expandedTitle_ = jsonObject.at("expandedTitle").get(); + } + + if (jsonObject.find("briefText") != jsonEnd) { + pContent->briefText_ = jsonObject.at("briefText").get(); + } + + return pContent; +} + bool NotificationLongTextContent::Marshalling(Parcel &parcel) const { if (!NotificationBasicContent::Marshalling(parcel)) { diff --git a/frameworks/ans/native/src/notification_media_content.cpp b/frameworks/ans/native/src/notification_media_content.cpp index 6c3862c5093989afd79c0a7d74b524b3e8504ccd..d65672e0ce0b02d5a6b8f61e659cd6fcea9c8672 100644 --- a/frameworks/ans/native/src/notification_media_content.cpp +++ b/frameworks/ans/native/src/notification_media_content.cpp @@ -52,6 +52,41 @@ std::string NotificationMediaContent::Dump() " }"; } +bool NotificationMediaContent::ToJson(nlohmann::json &jsonObject) const +{ + if (!NotificationBasicContent::ToJson(jsonObject)) { + ANS_LOGE("Cannot convert basicContent to JSON"); + return false; + } + + jsonObject["sequenceNumbers"] = nlohmann::json(sequenceNumbers_); + + return true; +} + +NotificationMediaContent *NotificationMediaContent::FromJson(const nlohmann::json &jsonObject) +{ + if (jsonObject.is_null() or !jsonObject.is_object()) { + ANS_LOGE("Invalid JSON object"); + return nullptr; + } + + auto pContent = new (std::nothrow) NotificationMediaContent(); + if (pContent == nullptr) { + ANS_LOGE("Failed to create mediaContent instance"); + return nullptr; + } + + pContent->ReadFromJson(jsonObject); + + const auto& jsonEnd = jsonObject.cend(); + if (jsonObject.find("sequenceNumbers") != jsonEnd) { + pContent->sequenceNumbers_ = jsonObject.at("sequenceNumbers").get>(); + } + + return pContent; +} + bool NotificationMediaContent::Marshalling(Parcel &parcel) const { if (!NotificationBasicContent::Marshalling(parcel)) { diff --git a/frameworks/ans/native/src/notification_multiline_content.cpp b/frameworks/ans/native/src/notification_multiline_content.cpp index 299ac9059e2af53ae64b75ce67effa7293cad68f..ef11f4f1dfbfbf9bf6ba6f30a4bd6cf98b6d47cc 100644 --- a/frameworks/ans/native/src/notification_multiline_content.cpp +++ b/frameworks/ans/native/src/notification_multiline_content.cpp @@ -72,6 +72,51 @@ std::string NotificationMultiLineContent::Dump() " }"; } +bool NotificationMultiLineContent::ToJson(nlohmann::json &jsonObject) const +{ + if (!NotificationBasicContent::ToJson(jsonObject)) { + ANS_LOGE("Cannot convert basicContent to JSON"); + return false; + } + + jsonObject["expandedTitle"] = expandedTitle_; + jsonObject["briefText"] = briefText_; + jsonObject["allLines"] = nlohmann::json(allLines_); + + return true; +} + +NotificationMultiLineContent *NotificationMultiLineContent::FromJson(const nlohmann::json &jsonObject) +{ + if (jsonObject.is_null() or !jsonObject.is_object()) { + ANS_LOGE("Invalid JSON object"); + return nullptr; + } + + auto pContent = new (std::nothrow) NotificationMultiLineContent(); + if (pContent == nullptr) { + ANS_LOGE("Failed to create multiLineContent instance"); + return nullptr; + } + + pContent->ReadFromJson(jsonObject); + + const auto &jsonEnd = jsonObject.cend(); + if (jsonObject.find("expandedTitle") != jsonEnd) { + pContent->expandedTitle_ = jsonObject.at("expandedTitle").get(); + } + + if (jsonObject.find("briefText") != jsonEnd) { + pContent->briefText_ = jsonObject.at("briefText").get(); + } + + if (jsonObject.find("allLines") != jsonEnd) { + pContent->allLines_ = jsonObject.at("allLines").get>(); + } + + return pContent; +} + bool NotificationMultiLineContent::Marshalling(Parcel &parcel) const { if (!NotificationBasicContent::Marshalling(parcel)) { diff --git a/frameworks/ans/native/src/notification_normal_content.cpp b/frameworks/ans/native/src/notification_normal_content.cpp index d6743d14f15ee25fa9f1c5563d5a2b8be0ed7e0e..a65c134721fe9b0ebcfb532ec3f6e9600836537c 100644 --- a/frameworks/ans/native/src/notification_normal_content.cpp +++ b/frameworks/ans/native/src/notification_normal_content.cpp @@ -14,6 +14,7 @@ */ #include "notification_normal_content.h" +#include "ans_log_wrapper.h" namespace OHOS { namespace Notification { @@ -22,6 +23,29 @@ std::string NotificationNormalContent::Dump() return "NotificationNormalContent{ " + NotificationBasicContent::Dump() + " }"; } +bool NotificationNormalContent::ToJson(nlohmann::json &jsonObject) const +{ + return NotificationBasicContent::ToJson(jsonObject); +} + +NotificationNormalContent *NotificationNormalContent::FromJson(const nlohmann::json &jsonObject) +{ + if (jsonObject.is_null() or !jsonObject.is_object()) { + ANS_LOGE("Invalid JSON object"); + return nullptr; + } + + auto pContent = new (std::nothrow) NotificationNormalContent(); + if (pContent == nullptr) { + ANS_LOGE("Failed to create normalContent instance"); + return nullptr; + } + + pContent->ReadFromJson(jsonObject); + + return pContent; +} + bool NotificationNormalContent::Marshalling(Parcel &parcel) const { return NotificationBasicContent::Marshalling(parcel); diff --git a/frameworks/ans/native/src/notification_picture_content.cpp b/frameworks/ans/native/src/notification_picture_content.cpp index d7e65d4b05c639913c9451e477d519da98018d76..e683c5397689f19c65d7ffe5ee6a6092a31506f7 100644 --- a/frameworks/ans/native/src/notification_picture_content.cpp +++ b/frameworks/ans/native/src/notification_picture_content.cpp @@ -14,6 +14,7 @@ */ #include "notification_picture_content.h" +#include "ans_image_util.h" #include "ans_log_wrapper.h" namespace OHOS { @@ -57,6 +58,52 @@ std::string NotificationPictureContent::Dump() " }"; } +bool NotificationPictureContent::ToJson(nlohmann::json &jsonObject) const +{ + if (!NotificationBasicContent::ToJson(jsonObject)) { + ANS_LOGE("Cannot convert basicContent to JSON"); + return false; + } + + jsonObject["expandedTitle"] = expandedTitle_; + jsonObject["briefText"] = briefText_; + jsonObject["bigPicture"] = AnsImageUtil::PackImage(bigPicture_); + + return true; +} + +NotificationPictureContent *NotificationPictureContent::FromJson(const nlohmann::json &jsonObject) +{ + if (jsonObject.is_null() or !jsonObject.is_object()) { + ANS_LOGE("Invalid JSON object"); + return nullptr; + } + + auto pContent = new (std::nothrow) NotificationPictureContent(); + if (pContent == nullptr) { + ANS_LOGE("Failed to create pictureContent instance"); + return nullptr; + } + + pContent->ReadFromJson(jsonObject); + + const auto &jsonEnd = jsonObject.cend(); + if (jsonObject.find("expandedTitle") != jsonEnd) { + pContent->expandedTitle_ = jsonObject.at("expandedTitle").get(); + } + + if (jsonObject.find("briefText") != jsonEnd) { + pContent->briefText_ = jsonObject.at("briefText").get(); + } + + if (jsonObject.find("bigPicture") != jsonEnd) { + auto picStr = jsonObject.at("bigPicture").get(); + pContent->bigPicture_ = AnsImageUtil::UnPackImage(picStr); + } + + return pContent; +} + bool NotificationPictureContent::Marshalling(Parcel &parcel) const { if (!NotificationBasicContent::Marshalling(parcel)) { diff --git a/frameworks/ans/native/src/notification_request.cpp b/frameworks/ans/native/src/notification_request.cpp index 10343c0864f591bbc276bd5876ca9e7641074b98..29d6657aa8d70481a06bc93402cd0811129876b5 100644 --- a/frameworks/ans/native/src/notification_request.cpp +++ b/frameworks/ans/native/src/notification_request.cpp @@ -15,7 +15,10 @@ #include "notification_request.h" +#include "ans_image_util.h" #include "ans_log_wrapper.h" +#include "want_agent_helper.h" +#include "want_params_wrapper.h" namespace OHOS { namespace Notification { @@ -57,124 +60,14 @@ NotificationRequest::NotificationRequest(const std::shared_ptrnotificationId_ = other.notificationId_; - this->color_ = other.color_; - this->badgeNumber_ = other.badgeNumber_; - this->progressValue_ = other.progressValue_; - this->progressMax_ = other.progressMax_; - this->createTime_ = other.createTime_; - this->deliveryTime_ = other.deliveryTime_; - this->autoDeletedTime_ = other.autoDeletedTime_; - - this->creatorPid_ = other.creatorPid_; - this->creatorUid_ = other.creatorUid_; - - this->slotType_ = other.slotType_; - this->settingsText_ = other.settingsText_; - this->creatorBundleName_ = other.creatorBundleName_; - this->ownerBundleName_ = other.ownerBundleName_; - this->groupName_ = other.groupName_; - this->statusBarText_ = other.statusBarText_; - this->label_ = other.label_; - this->shortcutId_ = other.shortcutId_; - this->sortingKey_ = other.sortingKey_; - this->classification_ = other.classification_; - - this->groupAlertType_ = other.groupAlertType_; - this->visiblenessType_ = other.visiblenessType_; - this->badgeStyle_ = other.badgeStyle_; - this->notificationContentType_ = other.notificationContentType_; - - this->showDeliveryTime_ = other.showDeliveryTime_; - this->tapDismissed_ = other.tapDismissed_; - this->colorEnabled_ = other.colorEnabled_; - this->alertOneTime_ = other.alertOneTime_; - this->showStopwatch_ = other.showStopwatch_; - this->isCountdown_ = other.isCountdown_; - this->inProgress_ = other.inProgress_; - this->groupOverview_ = other.groupOverview_; - this->progressIndeterminate_ = other.progressIndeterminate_; - this->unremovable_ = other.unremovable_; - this->floatingIcon_ = other.floatingIcon_; - this->onlyLocal_ = other.onlyLocal_; - this->permitted_ = other.permitted_; - - this->context_ = other.context_; - this->wantAgent_ = other.wantAgent_; - this->removalWantAgent_ = other.removalWantAgent_; - this->maxScreenWantAgent_ = other.maxScreenWantAgent_; - this->additionalParams_ = other.additionalParams_; - this->littleIcon_ = other.littleIcon_; - this->bigIcon_ = other.bigIcon_; - this->notificationContent_ = other.notificationContent_; - this->publicNotification_ = other.publicNotification_; - - this->actionButtons_ = other.actionButtons_; - this->messageUsers_ = other.messageUsers_; - this->userInputHistory_ = other.userInputHistory_; - - this->notificationTemplate_ = other.notificationTemplate_; + CopyBase(other); + CopyOther(other); } NotificationRequest &NotificationRequest::operator=(const NotificationRequest &other) { - this->notificationId_ = other.notificationId_; - this->color_ = other.color_; - this->badgeNumber_ = other.badgeNumber_; - this->progressValue_ = other.progressValue_; - this->progressMax_ = other.progressMax_; - this->createTime_ = other.createTime_; - this->deliveryTime_ = other.deliveryTime_; - this->autoDeletedTime_ = other.autoDeletedTime_; - - this->creatorPid_ = other.creatorPid_; - this->creatorUid_ = other.creatorUid_; - - this->slotType_ = other.slotType_; - this->settingsText_ = other.settingsText_; - this->creatorBundleName_ = other.creatorBundleName_; - this->ownerBundleName_ = other.ownerBundleName_; - this->groupName_ = other.groupName_; - this->statusBarText_ = other.statusBarText_; - this->label_ = other.label_; - this->shortcutId_ = other.shortcutId_; - this->sortingKey_ = other.sortingKey_; - this->classification_ = other.classification_; - - this->groupAlertType_ = other.groupAlertType_; - this->visiblenessType_ = other.visiblenessType_; - this->badgeStyle_ = other.badgeStyle_; - this->notificationContentType_ = other.notificationContentType_; - - this->showDeliveryTime_ = other.showDeliveryTime_; - this->tapDismissed_ = other.tapDismissed_; - this->colorEnabled_ = other.colorEnabled_; - this->alertOneTime_ = other.alertOneTime_; - this->showStopwatch_ = other.showStopwatch_; - this->isCountdown_ = other.isCountdown_; - this->inProgress_ = other.inProgress_; - this->groupOverview_ = other.groupOverview_; - this->progressIndeterminate_ = other.progressIndeterminate_; - this->unremovable_ = other.unremovable_; - this->floatingIcon_ = other.floatingIcon_; - this->onlyLocal_ = other.onlyLocal_; - this->permitted_ = other.permitted_; - - this->context_ = other.context_; - this->wantAgent_ = other.wantAgent_; - this->removalWantAgent_ = other.removalWantAgent_; - this->maxScreenWantAgent_ = other.maxScreenWantAgent_; - this->additionalParams_ = other.additionalParams_; - this->littleIcon_ = other.littleIcon_; - this->bigIcon_ = other.bigIcon_; - this->notificationContent_ = other.notificationContent_; - this->publicNotification_ = other.publicNotification_; - - this->actionButtons_ = other.actionButtons_; - this->messageUsers_ = other.messageUsers_; - this->userInputHistory_ = other.userInputHistory_; - - this->notificationTemplate_ = other.notificationTemplate_; + CopyBase(other); + CopyOther(other); return *this; } @@ -719,6 +612,26 @@ std::string NotificationRequest::GetLabel() const return label_; } +void NotificationRequest::SetDistributed(bool distribute) +{ + distributedOptions_.SetDistributed(distribute); +} + +void NotificationRequest::SetDevicesSupportDisplay(const std::vector &devices) +{ + distributedOptions_.SetDevicesSupportDisplay(devices); +} + +void NotificationRequest::SetDevicesSupportOperate(const std::vector &devices) +{ + distributedOptions_.SetDevicesSupportOperate(devices); +} + +NotificationDistributedOptions NotificationRequest::GetNotificationDistributedOptions() const +{ + return distributedOptions_; +} + void NotificationRequest::SetCreatorUserId(int32_t userId) { creatorUserId_ = userId; @@ -773,9 +686,108 @@ std::string NotificationRequest::Dump() ", actionButtons = " + (!actionButtons_.empty() ? actionButtons_.at(0)->Dump() : "empty") + ", messageUsers = " + (!messageUsers_.empty() ? messageUsers_.at(0)->Dump() : "empty") + ", userInputHistory = " + (!userInputHistory_.empty() ? userInputHistory_.at(0) : "empty") + + ", distributedOptions = " + distributedOptions_.Dump() + " }"; } +bool NotificationRequest::ToJson(nlohmann::json &jsonObject) const +{ + jsonObject["version"] = 1; + + jsonObject["id"] = notificationId_; + jsonObject["color"] = color_; + jsonObject["deliveryTime"] = deliveryTime_; + jsonObject["autoDeletedTime"] = autoDeletedTime_; + + jsonObject["creatorBundleName"] = creatorBundleName_; + jsonObject["ownerBundleName"] = ownerBundleName_; + jsonObject["groupName"] = groupName_; + jsonObject["label"] = label_; + jsonObject["classification"] = classification_; + + jsonObject["slotType"] = static_cast(slotType_); + jsonObject["badgeIconStyle"] = static_cast(badgeStyle_); + + jsonObject["showDeliveryTime"] = showDeliveryTime_; + jsonObject["tapDismissed"] = tapDismissed_; + jsonObject["colorEnabled"] = colorEnabled_; + jsonObject["isOngoing"] = inProgress_; + jsonObject["isAlertOnce"] = alertOneTime_; + jsonObject["isStopwatch"] = showStopwatch_; + jsonObject["isCountdown"] = isCountdown_; + jsonObject["isUnremovable"] = unremovable_; + jsonObject["isFloatingIcon"] = floatingIcon_; + + if (!ConvertObjectsToJson(jsonObject)) { + ANS_LOGE("Cannot convert objects to JSON"); + return false; + } + + return true; +} + +NotificationRequest *NotificationRequest::FromJson(const nlohmann::json &jsonObject) +{ + if (jsonObject.is_null() or !jsonObject.is_object()) { + ANS_LOGE("Invalid JSON object"); + return nullptr; + } + + auto pRequest = new (std::nothrow) NotificationRequest(); + if (pRequest == nullptr) { + ANS_LOGE("Failed to create request instance"); + return nullptr; + } + + const auto &jsonEnd = jsonObject.cend(); + if (jsonObject.find("version") != jsonEnd) { + jsonObject.at("version").get(); + } + + ConvertJsonToNum(pRequest, jsonObject); + + ConvertJsonToString(pRequest, jsonObject); + + ConvertJsonToEnum(pRequest, jsonObject); + + ConvertJsonToBool(pRequest, jsonObject); + + if (jsonObject.find("wantAgent") != jsonEnd) { + auto wantAgentValue = jsonObject.at("wantAgent").get(); + pRequest->wantAgent_ = WantAgent::WantAgentHelper::FromString(wantAgentValue); + } + + if (!ConvertJsonToNotificationContent(pRequest, jsonObject)) { + delete pRequest; + pRequest = nullptr; + return nullptr; + } + + if (!ConvertJsonToNotificationActionButton(pRequest, jsonObject)) { + delete pRequest; + pRequest = nullptr; + return nullptr; + } + + if (jsonObject.find("extraInfo") != jsonEnd) { + auto extraInfoStr = jsonObject.at("extraInfo").get(); + if (!extraInfoStr.empty()) { + AAFwk::WantParams params = AAFwk::WantParamWrapper::ParseWantParams(extraInfoStr); + pRequest->additionalParams_ = std::make_shared(params); + } + } + + ConvertJsonToPixelMap(pRequest, jsonObject); + + if (!ConvertJsonToNotificationDistributedOptions(pRequest, jsonObject)) { + delete pRequest; + pRequest = nullptr; + return nullptr; + } + + return pRequest; +} + bool NotificationRequest::Marshalling(Parcel &parcel) const { // write int @@ -1105,6 +1117,11 @@ bool NotificationRequest::Marshalling(Parcel &parcel) const return false; } + if (!parcel.WriteParcelable(&distributedOptions_)) { + ANS_LOGE("Failed to write distributedOptions"); + return false; + } + valid = notificationTemplate_ ? true : false; if (!parcel.WriteBool(valid)) { ANS_LOGE("Failed to write the flag which indicate whether publicNotification is null"); @@ -1312,6 +1329,13 @@ bool NotificationRequest::ReadFromParcel(Parcel &parcel) return false; } + auto pOpt = parcel.ReadParcelable(); + if (pOpt == nullptr) { + ANS_LOGE("Failed to read distributedOptions"); + return false; + } + distributedOptions_ = *pOpt; + valid = parcel.ReadBool(); if (valid) { notificationTemplate_ = std::shared_ptr(parcel.ReadParcelable()); @@ -1342,5 +1366,340 @@ std::shared_ptr NotificationRequest::GetTemplate() const { return notificationTemplate_; } + +void NotificationRequest::CopyBase(const NotificationRequest &other) +{ + this->notificationId_ = other.notificationId_; + this->color_ = other.color_; + this->badgeNumber_ = other.badgeNumber_; + this->progressValue_ = other.progressValue_; + this->progressMax_ = other.progressMax_; + this->createTime_ = other.createTime_; + this->deliveryTime_ = other.deliveryTime_; + this->autoDeletedTime_ = other.autoDeletedTime_; + + this->creatorPid_ = other.creatorPid_; + this->creatorUid_ = other.creatorUid_; + + this->slotType_ = other.slotType_; + this->settingsText_ = other.settingsText_; + this->creatorBundleName_ = other.creatorBundleName_; + this->ownerBundleName_ = other.ownerBundleName_; + this->groupName_ = other.groupName_; + this->statusBarText_ = other.statusBarText_; + this->label_ = other.label_; + this->shortcutId_ = other.shortcutId_; + this->sortingKey_ = other.sortingKey_; + this->classification_ = other.classification_; + + this->groupAlertType_ = other.groupAlertType_; + this->visiblenessType_ = other.visiblenessType_; + this->badgeStyle_ = other.badgeStyle_; + this->notificationContentType_ = other.notificationContentType_; +} + +void NotificationRequest::CopyOther(const NotificationRequest &other) +{ + this->showDeliveryTime_ = other.showDeliveryTime_; + this->tapDismissed_ = other.tapDismissed_; + this->colorEnabled_ = other.colorEnabled_; + this->alertOneTime_ = other.alertOneTime_; + this->showStopwatch_ = other.showStopwatch_; + this->isCountdown_ = other.isCountdown_; + this->inProgress_ = other.inProgress_; + this->groupOverview_ = other.groupOverview_; + this->progressIndeterminate_ = other.progressIndeterminate_; + this->unremovable_ = other.unremovable_; + this->floatingIcon_ = other.floatingIcon_; + this->onlyLocal_ = other.onlyLocal_; + this->permitted_ = other.permitted_; + + this->context_ = other.context_; + this->wantAgent_ = other.wantAgent_; + this->removalWantAgent_ = other.removalWantAgent_; + this->maxScreenWantAgent_ = other.maxScreenWantAgent_; + this->additionalParams_ = other.additionalParams_; + this->littleIcon_ = other.littleIcon_; + this->bigIcon_ = other.bigIcon_; + this->notificationContent_ = other.notificationContent_; + this->publicNotification_ = other.publicNotification_; + + this->actionButtons_ = other.actionButtons_; + this->messageUsers_ = other.messageUsers_; + this->userInputHistory_ = other.userInputHistory_; + + this->distributedOptions_ = other.distributedOptions_; + + this->notificationTemplate_ = other.notificationTemplate_; +} + +bool NotificationRequest::ConvertObjectsToJson(nlohmann::json &jsonObject) const +{ + jsonObject["wantAgent"] = wantAgent_ ? WantAgent::WantAgentHelper::ToString(wantAgent_) : ""; + + nlohmann::json contentObj; + if (notificationContent_) { + if (!NotificationJsonConverter::ConvertToJosn(notificationContent_.get(), contentObj)) { + ANS_LOGE("Cannot convert notificationContent to JSON"); + return false; + } + } + jsonObject["content"] = contentObj; + + nlohmann::json buttonsArr = nlohmann::json::array(); + for (auto &btn : actionButtons_) { + if (!btn) { + continue; + } + + nlohmann::json btnObj; + if (!NotificationJsonConverter::ConvertToJosn(btn.get(), btnObj)) { + ANS_LOGE("Cannot convert actionButton to JSON"); + return false; + } + + buttonsArr.emplace_back(btnObj); + } + jsonObject["actionButtons"] = buttonsArr; + + std::string extraInfoStr; + if (additionalParams_) { + AAFwk::WantParamWrapper wWrapper(*additionalParams_); + extraInfoStr = wWrapper.ToString(); + } + jsonObject["extraInfo"] = extraInfoStr; + + jsonObject["smallIcon"] = AnsImageUtil::PackImage(littleIcon_); + jsonObject["largeIcon"] = AnsImageUtil::PackImage(bigIcon_); + + nlohmann::json optObj; + if (!NotificationJsonConverter::ConvertToJosn(&distributedOptions_, optObj)) { + ANS_LOGE("Cannot convert distributedOptions to JSON"); + return false; + } + jsonObject["distributedOptions"] = optObj; + + return true; +} + +void NotificationRequest::ConvertJsonToNum(NotificationRequest *target, const nlohmann::json &jsonObject) +{ + if (target == nullptr) { + ANS_LOGE("Invalid input parameter"); + return; + } + + const auto &jsonEnd = jsonObject.cend(); + + if (jsonObject.find("id") != jsonEnd) { + target->notificationId_ = jsonObject.at("id").get(); + } + + if (jsonObject.find("color") != jsonEnd) { + target->color_ = jsonObject.at("color").get(); + } + + if (jsonObject.find("deliveryTime") != jsonEnd) { + target->deliveryTime_ = jsonObject.at("deliveryTime").get(); + } + + if (jsonObject.find("autoDeletedTime") != jsonEnd) { + target->autoDeletedTime_ = jsonObject.at("autoDeletedTime").get(); + } +} + +void NotificationRequest::ConvertJsonToString(NotificationRequest *target, const nlohmann::json &jsonObject) +{ + if (target == nullptr) { + ANS_LOGE("Invalid input parameter"); + return; + } + + const auto &jsonEnd = jsonObject.cend(); + + if (jsonObject.find("creatorBundleName") != jsonEnd) { + target->creatorBundleName_ = jsonObject.at("creatorBundleName").get(); + } + + if (jsonObject.find("ownerBundleName") != jsonEnd) { + target->ownerBundleName_ = jsonObject.at("ownerBundleName").get(); + } + + if (jsonObject.find("groupName") != jsonEnd) { + target->groupName_ = jsonObject.at("groupName").get(); + } + + if (jsonObject.find("label") != jsonEnd) { + target->label_ = jsonObject.at("label").get(); + } + + if (jsonObject.find("classification") != jsonEnd) { + target->classification_ = jsonObject.at("classification").get(); + } +} + +void NotificationRequest::ConvertJsonToEnum(NotificationRequest *target, const nlohmann::json &jsonObject) +{ + if (target == nullptr) { + ANS_LOGE("Invalid input parameter"); + return; + } + + const auto &jsonEnd = jsonObject.cend(); + + if (jsonObject.find("slotType") != jsonEnd) { + auto slotTypeValue = jsonObject.at("slotType").get(); + target->slotType_ = static_cast(slotTypeValue); + } + + if (jsonObject.find("badgeIconStyle") != jsonEnd) { + auto badgeStyleValue = jsonObject.at("badgeIconStyle").get(); + target->badgeStyle_ = static_cast(badgeStyleValue); + } +} + +void NotificationRequest::ConvertJsonToBool(NotificationRequest *target, const nlohmann::json &jsonObject) +{ + if (target == nullptr) { + ANS_LOGE("Invalid input parameter"); + return; + } + + const auto &jsonEnd = jsonObject.cend(); + + if (jsonObject.find("showDeliveryTime") != jsonEnd) { + target->showDeliveryTime_ = jsonObject.at("showDeliveryTime").get(); + } + + if (jsonObject.find("tapDismissed") != jsonEnd) { + target->tapDismissed_ = jsonObject.at("tapDismissed").get(); + } + + if (jsonObject.find("colorEnabled") != jsonEnd) { + target->colorEnabled_ = jsonObject.at("colorEnabled").get(); + } + + if (jsonObject.find("isOngoing") != jsonEnd) { + target->inProgress_ = jsonObject.at("isOngoing").get(); + } + + if (jsonObject.find("isAlertOnce") != jsonEnd) { + target->alertOneTime_ = jsonObject.at("isAlertOnce").get(); + } + + if (jsonObject.find("isStopwatch") != jsonEnd) { + target->showStopwatch_ = jsonObject.at("isStopwatch").get(); + } + + if (jsonObject.find("isCountdown") != jsonEnd) { + target->isCountdown_ = jsonObject.at("isCountdown").get(); + } + + if (jsonObject.find("isUnremovable") != jsonEnd) { + target->unremovable_ = jsonObject.at("isUnremovable").get(); + } + + if (jsonObject.find("isFloatingIcon") != jsonEnd) { + target->floatingIcon_ = jsonObject.at("isFloatingIcon").get(); + } +} + +void NotificationRequest::ConvertJsonToPixelMap(NotificationRequest *target, const nlohmann::json &jsonObject) +{ + if (target == nullptr) { + ANS_LOGE("Invalid input parameter"); + return; + } + + const auto &jsonEnd = jsonObject.cend(); + + if (jsonObject.find("smallIcon") != jsonEnd) { + auto littleIconStr = jsonObject.at("smallIcon").get(); + target->littleIcon_ = AnsImageUtil::UnPackImage(littleIconStr); + } + + if (jsonObject.find("largeIcon") != jsonEnd) { + auto bigIconStr = jsonObject.at("largeIcon").get(); + target->bigIcon_ = AnsImageUtil::UnPackImage(bigIconStr); + } +} + +bool NotificationRequest::ConvertJsonToNotificationContent( + NotificationRequest *target, const nlohmann::json &jsonObject) +{ + if (target == nullptr) { + ANS_LOGE("Invalid input parameter"); + return false; + } + + const auto &jsonEnd = jsonObject.cend(); + + if (jsonObject.find("content") != jsonEnd) { + auto contentObj = jsonObject.at("content"); + if (!contentObj.is_null()) { + auto pContent = NotificationJsonConverter::ConvertFromJosn(contentObj); + if (pContent == nullptr) { + ANS_LOGE("Failed to parse notification content!"); + return false; + } + + target->notificationContent_ = std::shared_ptr(pContent); + } + } + + return true; +} + +bool NotificationRequest::ConvertJsonToNotificationActionButton( + NotificationRequest *target, const nlohmann::json &jsonObject) +{ + if (target == nullptr) { + ANS_LOGE("Invalid input parameter"); + return false; + } + + const auto &jsonEnd = jsonObject.cend(); + + if (jsonObject.find("actionButtons") != jsonEnd) { + auto buttonArr = jsonObject.at("actionButtons"); + for (auto &btnObj : buttonArr) { + auto pBtn = NotificationJsonConverter::ConvertFromJosn(btnObj); + if (pBtn == nullptr) { + ANS_LOGE("Failed to parse actionButton!"); + return false; + } + + target->actionButtons_.emplace_back(pBtn); + } + } + + return true; +} + +bool NotificationRequest::ConvertJsonToNotificationDistributedOptions( + NotificationRequest *target, const nlohmann::json &jsonObject) +{ + if (target == nullptr) { + ANS_LOGE("Invalid input parameter"); + return false; + } + + const auto &jsonEnd = jsonObject.cend(); + + if (jsonObject.find("distributedOptions") != jsonEnd) { + auto optObj = jsonObject.at("distributedOptions"); + if (!optObj.is_null()) { + auto pOpt = NotificationJsonConverter::ConvertFromJosn(optObj); + if (pOpt == nullptr) { + ANS_LOGE("Failed to parse distributedOptions!"); + return false; + } + + target->distributedOptions_ = *pOpt; + } + } + + return true; +} } // namespace Notification } // namespace OHOS diff --git a/frameworks/ans/native/src/notification_sorting.cpp b/frameworks/ans/native/src/notification_sorting.cpp index 4e0c41015f60b7b94d92d801b7b086ded7a1ba3f..575141dbfcc0bb35b50f9c2811763e30f8cbcfef 100644 --- a/frameworks/ans/native/src/notification_sorting.cpp +++ b/frameworks/ans/native/src/notification_sorting.cpp @@ -40,7 +40,7 @@ NotificationSorting::NotificationSorting(const NotificationSorting &sorting) void NotificationSorting::SetSlot(const sptr &slot) { if (slot == nullptr) { - slot_ = new NotificationSlot(NotificationConstant::SlotType::OTHER); + slot_ = new (std::nothrow) NotificationSlot(NotificationConstant::SlotType::OTHER); return; } slot_ = slot; diff --git a/frameworks/ans/native/src/notification_subscriber.cpp b/frameworks/ans/native/src/notification_subscriber.cpp index d1be62359901128265d0e182c3480a520e1ed6fb..291bc9ac75f5d2d7c86af8fa8254fb1baf452d13 100644 --- a/frameworks/ans/native/src/notification_subscriber.cpp +++ b/frameworks/ans/native/src/notification_subscriber.cpp @@ -22,7 +22,7 @@ namespace OHOS { namespace Notification { NotificationSubscriber::NotificationSubscriber() { - impl_ = new SubscriberImpl(*this); + impl_ = new (std::nothrow) SubscriberImpl(*this); }; NotificationSubscriber::~NotificationSubscriber() @@ -35,7 +35,7 @@ const sptr NotificationSubscriber::GetIm NotificationSubscriber::SubscriberImpl::SubscriberImpl(NotificationSubscriber &subscriber) : subscriber_(subscriber) { - recipient_ = new DeathRecipient(*this); + recipient_ = new (std::nothrow) DeathRecipient(*this); }; void NotificationSubscriber::SubscriberImpl::OnConnected() diff --git a/frameworks/ans/native/src/notification_user_input.cpp b/frameworks/ans/native/src/notification_user_input.cpp index eb0387fd661b9797bdb14faaa9ea160907ec76fd..335b874677583678352e16a364ed1216e31dfc5e 100644 --- a/frameworks/ans/native/src/notification_user_input.cpp +++ b/frameworks/ans/native/src/notification_user_input.cpp @@ -16,6 +16,7 @@ #include "notification_user_input.h" #include "ans_log_wrapper.h" +#include "want_params_wrapper.h" namespace OHOS { namespace Notification { @@ -227,6 +228,74 @@ std::string NotificationUserInput::Dump() " }"; } +bool NotificationUserInput::ToJson(nlohmann::json &jsonObject) const +{ + jsonObject["inputKey"] = inputKey_; + jsonObject["tag"] = tag_; + jsonObject["options"] = nlohmann::json(options_); + jsonObject["permitFreeFormInput"] = permitFreeFormInput_; + jsonObject["permitMimeTypes"] = nlohmann::json(permitMimeTypes_); + jsonObject["editType"] = static_cast(editType_); + std::string additionalDataStr; + if (additionalData_) { + AAFwk::WantParamWrapper wWrapper(*additionalData_); + additionalDataStr = wWrapper.ToString(); + } + jsonObject["additionalData"] = additionalDataStr; + + return true; +} + +NotificationUserInput *NotificationUserInput::FromJson(const nlohmann::json &jsonObject) +{ + if (jsonObject.is_null() or !jsonObject.is_object()) { + ANS_LOGE("Invalid JSON object"); + return nullptr; + } + + auto pUserInput = new (std::nothrow) NotificationUserInput(); + if (pUserInput == nullptr) { + ANS_LOGE("Failed to create userInput instance"); + return nullptr; + } + + const auto &jsonEnd = jsonObject.cend(); + if (jsonObject.find("inputKey") != jsonEnd) { + pUserInput->inputKey_ = jsonObject.at("inputKey").get(); + } + + if (jsonObject.find("tag") != jsonEnd) { + pUserInput->tag_ = jsonObject.at("tag").get(); + } + + if (jsonObject.find("options") != jsonEnd) { + pUserInput->options_ = jsonObject.at("options").get>(); + } + + if (jsonObject.find("permitFreeFormInput") != jsonEnd) { + pUserInput->permitFreeFormInput_ = jsonObject.at("permitFreeFormInput").get(); + } + + if (jsonObject.find("permitMimeTypes") != jsonEnd) { + pUserInput->permitMimeTypes_ = jsonObject.at("permitMimeTypes").get>(); + } + + if (jsonObject.find("additionalData") != jsonEnd) { + auto additionalDataString = jsonObject.at("additionalData").get(); + if (!additionalDataString.empty()) { + AAFwk::WantParams params = AAFwk::WantParamWrapper::ParseWantParams(additionalDataString); + pUserInput->additionalData_ = std::make_shared(params); + } + } + + if (jsonObject.find("editType") != jsonEnd) { + auto editTypeValue = jsonObject.at("editType").get(); + pUserInput->editType_ = static_cast(editTypeValue); + } + + return pUserInput; +} + bool NotificationUserInput::Marshalling(Parcel &parcel) const { if (!parcel.WriteString(inputKey_)) { @@ -337,4 +406,4 @@ bool NotificationUserInput::ReadFromParcel(Parcel &parcel) return true; } } // namespace Notification -} // namespace OHOS +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/ans/test/moduletest/BUILD.gn b/frameworks/ans/test/moduletest/BUILD.gn index ed922f4a379c8c41736b486cbcba7c756a01681d..a003ec2edd045b94c1d9dc56e587b523546615f6 100644 --- a/frameworks/ans/test/moduletest/BUILD.gn +++ b/frameworks/ans/test/moduletest/BUILD.gn @@ -53,7 +53,7 @@ ohos_moduletest("ans_fw_module_test") { "//base/notification/ans_standard/interfaces/innerkits/ans/native/test/moduletest/mock/include", "//foundation/distributedschedule/samgr/services/samgr/native/include", "//foundation/communication/ipc/interfaces/innerkits/libdbinder/include", - "//base/notification/ces_standard/cesfwk/interfaces/innerkits/native/include", + "//base/notification/ces_standard/interfaces/innerkits/native/include", "//base/notification/ans_standard/interfaces/innerkits/ans/native/include", "//base/notification/ans_standard/interfaces/innerkits/wantagent/include", "${core_path}/common/include", @@ -69,17 +69,14 @@ ohos_moduletest("ans_fw_module_test") { ] sources = [ - "//base/notification/ans_standard/frameworks/ans/core/src/ans_manager_proxy.cpp", - "//base/notification/ans_standard/frameworks/ans/core/src/ans_manager_stub.cpp", - "//base/notification/ans_standard/frameworks/ans/core/src/ans_notification.cpp", - "//base/notification/ans_standard/frameworks/ans/core/src/ans_subscriber_proxy.cpp", - "//base/notification/ans_standard/frameworks/ans/core/src/ans_subscriber_stub.cpp", - "//base/notification/ans_standard/frameworks/ans/native/src/notification.cpp", "ans_fw_module_test.cpp", "mock/blob.cpp", "mock/distributed_kv_data_manager.cpp", "mock/mock_bundle_manager.cpp", "mock/mock_bundle_mgr_proxy.cpp", + "mock/mock_change_notification.cpp", + "mock/mock_common_event_data.cpp", + "mock/mock_common_event_manager.cpp", "mock/mock_ipc.cpp", "mock/mock_single_kv_store.cpp", ] @@ -100,10 +97,15 @@ ohos_moduletest("ans_fw_module_test") { "//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy:samgr_proxy", "//foundation/multimedia/image_standard/interfaces/innerkits:image_native", "//third_party/googletest:gtest_main", - "//third_party/jsoncpp:jsoncpp", "//utils/native/base:utils", ] + defines = [] + if (distributed_notification_supported) { + defines += [ "DISTRIBUTED_NOTIFICATION_SUPPORTED" ] + deps += [ "${services_path}/distributed:libans_distributed" ] + } + external_deps = [ "aafwk_standard:want", "appexecfwk_standard:appexecfwk_base", @@ -124,9 +126,14 @@ ohos_moduletest("ans_innerkits_module_publish_test") { module_out_path = module_output_path include_dirs = [ "include", + "${core_path}/include", "${interfaces_path}/ans/native/include", "${frameworks_path}/ans/core/common/include", "${frameworks_path}/ans/core/include", + "//foundation/appexecfwk/standard/interfaces/innerkits/libeventhandler/include", + "//foundation/appexecfwk/standard/libs/libeventhandler/src", + "//foundation/communication/ipc/interfaces/innerkits/ipc_core/include", + "//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy/include", "//utils/native/base/include", "//utils/system/safwk/native/include", "//base/notification/ans_standard/services/ans/include", @@ -135,24 +142,22 @@ ohos_moduletest("ans_innerkits_module_publish_test") { "//foundation/communication/ipc/ipc/native/src/core/include", "//foundation/communication/ipc/utils/include", "//foundation/communication/ipc/ipc/softbus_temp", + "//base/notification/ans_standard/interfaces/innerkits/ans/native/test/moduletest/mock/include", "//foundation/distributedschedule/samgr/services/samgr/native/include", "//foundation/communication/ipc/interfaces/innerkits/libdbinder/include", - "//base/notification/ces_standard/cesfwk/interfaces/innerkits/native/include", + "//base/notification/ces_standard/interfaces/innerkits/native/include", + "//base/notification/ans_standard/interfaces/innerkits/ans/native/include", + "//base/notification/ans_standard/interfaces/innerkits/wantagent/include", "${core_path}/common/include", "${core_path}/include", "${interfaces_path}/innerkits/ans/native/include", "${interfaces_path}/innerkits/wantAgent/include", "//utils/native/base/include", + "//third_party/jsoncpp/include", "//base/notification/ans_standard/frameworks/ans/test/moduletest/mock/include", - "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/include/autils", - "//foundation/distributeddatamgr/distributeddatamgr/frameworks/innerkitsimpl/distributeddatafwk/include", - "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/include/log", - "//foundation/communication/ipc/interfaces/innerkits/ipc_core/include", - "//foundation/distributeddatamgr/distributeddatamgr/interfaces/innerkits/distributeddata/include", - "//foundation/distributeddatamgr/distributeddatamgr/frameworks/innerkitsimpl/distributeddatafwk/src", - "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/include/dfx", - "//foundation/multimedia/image_standard/interfaces/innerkits/include", - "//developtools/bytrace_standard/interfaces/innerkits/native/include", + "//foundation/distributeddatamgr/distributeddatamgr/interfaces/innerkits/distributeddata/include/", + "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/include/autils/", + "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/include/log/", ] sources = [ @@ -161,12 +166,17 @@ ohos_moduletest("ans_innerkits_module_publish_test") { "mock/distributed_kv_data_manager.cpp", "mock/mock_bundle_manager.cpp", "mock/mock_bundle_mgr_proxy.cpp", + "mock/mock_change_notification.cpp", + "mock/mock_common_event_data.cpp", + "mock/mock_common_event_manager.cpp", "mock/mock_ipc.cpp", "mock/mock_single_kv_store.cpp", ] configs = [ "//utils/native/base:utils_config" ] + ldflags = [ "-Wl,-rpath=/system/lib/module/multimedia/" ] + deps = [ "${frameworks_path}/ans/core:ans_core", "${frameworks_path}/ans/native:ans_innerkits", @@ -186,6 +196,12 @@ ohos_moduletest("ans_innerkits_module_publish_test") { "//utils/native/base:utils", ] + defines = [] + if (distributed_notification_supported) { + defines += [ "DISTRIBUTED_NOTIFICATION_SUPPORTED" ] + deps += [ "${services_path}/distributed:libans_distributed" ] + } + external_deps = [ "aafwk_standard:want", "appexecfwk_standard:appexecfwk_base", @@ -206,9 +222,14 @@ ohos_moduletest("ans_innerkits_module_slot_test") { module_out_path = module_output_path include_dirs = [ "include", + "${core_path}/include", "${interfaces_path}/ans/native/include", "${frameworks_path}/ans/core/common/include", "${frameworks_path}/ans/core/include", + "//foundation/appexecfwk/standard/interfaces/innerkits/libeventhandler/include", + "//foundation/appexecfwk/standard/libs/libeventhandler/src", + "//foundation/communication/ipc/interfaces/innerkits/ipc_core/include", + "//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy/include", "//utils/native/base/include", "//utils/system/safwk/native/include", "//base/notification/ans_standard/services/ans/include", @@ -217,23 +238,22 @@ ohos_moduletest("ans_innerkits_module_slot_test") { "//foundation/communication/ipc/ipc/native/src/core/include", "//foundation/communication/ipc/utils/include", "//foundation/communication/ipc/ipc/softbus_temp", + "//base/notification/ans_standard/interfaces/innerkits/ans/native/test/moduletest/mock/include", "//foundation/distributedschedule/samgr/services/samgr/native/include", "//foundation/communication/ipc/interfaces/innerkits/libdbinder/include", - "//base/notification/ces_standard/cesfwk/interfaces/innerkits/native/include", + "//base/notification/ces_standard/interfaces/innerkits/native/include", + "//base/notification/ans_standard/interfaces/innerkits/ans/native/include", + "//base/notification/ans_standard/interfaces/innerkits/wantagent/include", "${core_path}/common/include", "${core_path}/include", "${interfaces_path}/innerkits/ans/native/include", "${interfaces_path}/innerkits/wantAgent/include", "//utils/native/base/include", + "//third_party/jsoncpp/include", "//base/notification/ans_standard/frameworks/ans/test/moduletest/mock/include", - "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/include/autils", - "//foundation/distributeddatamgr/distributeddatamgr/frameworks/innerkitsimpl/distributeddatafwk/include", - "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/include/log", - "//foundation/communication/ipc/interfaces/innerkits/ipc_core/include", - "//foundation/distributeddatamgr/distributeddatamgr/interfaces/innerkits/distributeddata/include", - "//foundation/distributeddatamgr/distributeddatamgr/frameworks/innerkitsimpl/distributeddatafwk/src", - "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/include/dfx", - "//developtools/bytrace_standard/interfaces/innerkits/native/include", + "//foundation/distributeddatamgr/distributeddatamgr/interfaces/innerkits/distributeddata/include/", + "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/include/autils/", + "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/include/log/", ] sources = [ @@ -242,6 +262,9 @@ ohos_moduletest("ans_innerkits_module_slot_test") { "mock/distributed_kv_data_manager.cpp", "mock/mock_bundle_manager.cpp", "mock/mock_bundle_mgr_proxy.cpp", + "mock/mock_change_notification.cpp", + "mock/mock_common_event_data.cpp", + "mock/mock_common_event_manager.cpp", "mock/mock_ipc.cpp", "mock/mock_single_kv_store.cpp", ] @@ -260,10 +283,17 @@ ohos_moduletest("ans_innerkits_module_slot_test") { "//foundation/distributedschedule/dmsfwk/interfaces/innerkits/uri:zuri", "//foundation/distributedschedule/safwk/interfaces/innerkits/safwk:system_ability_fwk", "//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy:samgr_proxy", + "//foundation/multimedia/image_standard/interfaces/innerkits:image_native", "//third_party/googletest:gtest_main", "//utils/native/base:utils", ] + defines = [] + if (distributed_notification_supported) { + defines += [ "DISTRIBUTED_NOTIFICATION_SUPPORTED" ] + deps += [ "${services_path}/distributed:libans_distributed" ] + } + external_deps = [ "aafwk_standard:want", "appexecfwk_standard:appexecfwk_base", @@ -284,9 +314,14 @@ ohos_moduletest("ans_innerkits_module_setting_test") { module_out_path = module_output_path include_dirs = [ "include", + "${core_path}/include", "${interfaces_path}/ans/native/include", "${frameworks_path}/ans/core/common/include", "${frameworks_path}/ans/core/include", + "//foundation/appexecfwk/standard/interfaces/innerkits/libeventhandler/include", + "//foundation/appexecfwk/standard/libs/libeventhandler/src", + "//foundation/communication/ipc/interfaces/innerkits/ipc_core/include", + "//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy/include", "//utils/native/base/include", "//utils/system/safwk/native/include", "//base/notification/ans_standard/services/ans/include", @@ -295,23 +330,22 @@ ohos_moduletest("ans_innerkits_module_setting_test") { "//foundation/communication/ipc/ipc/native/src/core/include", "//foundation/communication/ipc/utils/include", "//foundation/communication/ipc/ipc/softbus_temp", + "//base/notification/ans_standard/interfaces/innerkits/ans/native/test/moduletest/mock/include", "//foundation/distributedschedule/samgr/services/samgr/native/include", "//foundation/communication/ipc/interfaces/innerkits/libdbinder/include", - "//base/notification/ces_standard/cesfwk/interfaces/innerkits/native/include", + "//base/notification/ces_standard/interfaces/innerkits/native/include", + "//base/notification/ans_standard/interfaces/innerkits/ans/native/include", + "//base/notification/ans_standard/interfaces/innerkits/wantagent/include", "${core_path}/common/include", "${core_path}/include", "${interfaces_path}/innerkits/ans/native/include", "${interfaces_path}/innerkits/wantAgent/include", "//utils/native/base/include", + "//third_party/jsoncpp/include", "//base/notification/ans_standard/frameworks/ans/test/moduletest/mock/include", - "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/include/autils", - "//foundation/distributeddatamgr/distributeddatamgr/frameworks/innerkitsimpl/distributeddatafwk/include", - "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/include/log", - "//foundation/communication/ipc/interfaces/innerkits/ipc_core/include", - "//foundation/distributeddatamgr/distributeddatamgr/interfaces/innerkits/distributeddata/include", - "//foundation/distributeddatamgr/distributeddatamgr/frameworks/innerkitsimpl/distributeddatafwk/src", - "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/include/dfx", - "//developtools/bytrace_standard/interfaces/innerkits/native/include", + "//foundation/distributeddatamgr/distributeddatamgr/interfaces/innerkits/distributeddata/include/", + "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/include/autils/", + "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/include/log/", ] sources = [ @@ -320,6 +354,9 @@ ohos_moduletest("ans_innerkits_module_setting_test") { "mock/distributed_kv_data_manager.cpp", "mock/mock_bundle_manager.cpp", "mock/mock_bundle_mgr_proxy.cpp", + "mock/mock_change_notification.cpp", + "mock/mock_common_event_data.cpp", + "mock/mock_common_event_manager.cpp", "mock/mock_ipc.cpp", "mock/mock_single_kv_store.cpp", ] @@ -338,10 +375,17 @@ ohos_moduletest("ans_innerkits_module_setting_test") { "//foundation/distributedschedule/dmsfwk/interfaces/innerkits/uri:zuri", "//foundation/distributedschedule/safwk/interfaces/innerkits/safwk:system_ability_fwk", "//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy:samgr_proxy", + "//foundation/multimedia/image_standard/interfaces/innerkits:image_native", "//third_party/googletest:gtest_main", "//utils/native/base:utils", ] + defines = [] + if (distributed_notification_supported) { + defines += [ "DISTRIBUTED_NOTIFICATION_SUPPORTED" ] + deps += [ "${services_path}/distributed:libans_distributed" ] + } + external_deps = [ "aafwk_standard:want", "appexecfwk_standard:appexecfwk_base", diff --git a/frameworks/ans/test/moduletest/ans_fw_module_test.cpp b/frameworks/ans/test/moduletest/ans_fw_module_test.cpp index 741f7d59fcaa9c66aa277ab658ed0a7264f876eb..34930d206d6a4ade08dc4626161035e6e509a143 100644 --- a/frameworks/ans/test/moduletest/ans_fw_module_test.cpp +++ b/frameworks/ans/test/moduletest/ans_fw_module_test.cpp @@ -26,9 +26,12 @@ #include "ans_const_define.h" #include "ans_inner_errors.h" #include "ans_manager_proxy.h" +#include "common_event_manager.h" +#include "common_event_support.h" #include "if_system_ability_manager.h" #include "iservice_registry.h" #include "mock_ipc_skeleton.h" +#include "mock_single_kv_store.h" #include "notification_content.h" #include "notification_helper.h" #include "notification_long_text_content.h" @@ -48,6 +51,11 @@ const std::string NOTIFICATION_LABEL_2 = "Label2"; const std::string AN_NOT_EXIST_KEY = "AN_NOT_EXIST_KEY"; const std::string KEY_SPLITER = "_"; +const std::string KVSTORE_APP_ID = "advanced_notification_service"; +const std::string KVSTORE_NOTIFICATION_STORE_ID = "distributed_notification"; +const std::string KVSTORE_PREFERENCES_STORE_ID = "distributed_preferences"; +const std::string KVSTORE_SCREEN_STATUS_STORE_ID = "distributed_screen_status"; + constexpr int UID = 1; constexpr int CANCEL_REASON_DELETE = 2; constexpr int APP_CANCEL_REASON_DELETE = 8; @@ -326,6 +334,86 @@ public: { std::this_thread::sleep_for(std::chrono::seconds(1)); } + + const std::string DELIMITER = "|"; + const std::string LOCAL_DEVICE_ID = ""; + const std::string REMOTE_DEVICE_ID = ""; + inline std::string GenerateDistributedKey(const NotificationRequest &req, const std::string &deviceId) + { + return std::string() + .append(deviceId) + .append(DELIMITER) + .append(APP_NAME) + .append(DELIMITER) + .append(req.GetLabel()) + .append(DELIMITER) + .append(ToString(req.GetNotificationId())); + } + + bool GetRequestInDistributedEntryList( + NotificationRequest &req, std::vector &entries, DistributedKv::Entry &outEntry) + { + std::string localDistributedKey = GenerateDistributedKey(req, LOCAL_DEVICE_ID); + for (auto entry : entries) { + if (entry.key.ToString() == localDistributedKey) { + outEntry = entry; + return true; + } + } + return false; + } + + bool GetRequestInNotificationList(NotificationRequest &req, + std::vector> ¬ificationList, std::shared_ptr &outNotification) + { + for (auto notification : notificationList) { + if (notification->GetNotificationRequest().GetNotificationId() == req.GetNotificationId() && + notification->GetNotificationRequest().GetLabel() == req.GetLabel()) { + outNotification = notification; + return true; + } + } + return false; + } + + NotificationRequest CreateDistributedRequest(std::string label) + { + int32_t notificationId = 1; + auto normalContent = std::make_shared(); + auto content = std::make_shared(normalContent); + NotificationRequest request(notificationId); + request.SetLabel(label); + request.SetContent(content); + request.SetDistributed(true); + std::vector devices = {""}; + request.SetDevicesSupportDisplay(devices); + return request; + } + + void PublishCommonEventScreenStatus(bool isScreenOn) + { + EventFwk::Want want; + EventFwk::CommonEventData data; + if (isScreenOn) { + data.SetWant(want.SetAction(EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_ON)); + } else { + data.SetWant(want.SetAction(EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_OFF)); + } + + EventFwk::CommonEventManager::PublishCommonEvent(data); + } + + void SetDistributedScreenStatus(bool isScreenOn) + { + DistributedKv::AppId appId = {.appId = KVSTORE_APP_ID}; + DistributedKv::StoreId storeId = {.storeId = KVSTORE_NOTIFICATION_STORE_ID}; + std::shared_ptr pointer = + DistributedKv::AnsTestSingleKvStore::GetMockKvStorePointer( + {KVSTORE_APP_ID}, {KVSTORE_SCREEN_STATUS_STORE_ID}); + DistributedKv::Key key("" + DELIMITER + "screen_status"); + DistributedKv::Value value(isScreenOn ? "on" : "off"); + pointer->Put(key, value); + } }; class EventParser { @@ -550,7 +638,7 @@ HWTEST_F(AnsFWModuleTest, ANS_FW_MT_FlowControl_00100, Function | MediumTest | L int32_t notificationIdInt = i; if (i < MAX_ACTIVE_NUM_PERSECOND) { std::stringstream stream; - stream << UID << KEY_SPLITER << notificationLabel << KEY_SPLITER << notificationIdInt; + stream << KEY_SPLITER << UID << KEY_SPLITER << notificationLabel << KEY_SPLITER << notificationIdInt; std::string notificationKey = stream.str(); NotificationSorting sorting; EXPECT_EQ(eventParser.GetOnConsumedReq()[i]->GetLabel().c_str(), notificationLabel); @@ -606,7 +694,7 @@ HWTEST_F(AnsFWModuleTest, ANS_FW_MT_RemoveNotificaitonsByKey_00100, Function | M EXPECT_EQ(eventParser.GetOnConsumedReq()[0]->GetLabel().c_str(), NOTIFICATION_LABEL_0); EXPECT_EQ(eventParser.GetOnConsumedReq()[0]->GetId(), 0); std::stringstream stream; - stream << UID << KEY_SPLITER << NOTIFICATION_LABEL_0 << KEY_SPLITER << 0; + stream << KEY_SPLITER << UID << KEY_SPLITER << NOTIFICATION_LABEL_0 << KEY_SPLITER << 0; std::string notificationKey = stream.str(); NotificationSorting sorting; EXPECT_EQ(eventParser.GetOnCanceledReq()[0]->GetKey(), notificationKey); @@ -879,7 +967,7 @@ HWTEST_F(AnsFWModuleTest, ANS_FW_MT_CancelNotificationById_00100, Function | Med EXPECT_EQ(eventParser.GetOnConsumedReq()[0]->GetLabel().c_str(), NOTIFICATION_LABEL_0); EXPECT_EQ(eventParser.GetOnConsumedReq()[0]->GetId(), 1); std::stringstream stream; - stream << UID << KEY_SPLITER << NOTIFICATION_LABEL_0 << KEY_SPLITER << 1; + stream << KEY_SPLITER << UID << KEY_SPLITER << NOTIFICATION_LABEL_0 << KEY_SPLITER << 1; std::string notificationKey = stream.str(); NotificationSorting sorting; EXPECT_EQ(eventParser.GetOnCanceledReq()[0]->GetKey(), notificationKey); @@ -974,7 +1062,7 @@ HWTEST_F(AnsFWModuleTest, ANS_FW_MT_CancelAllNotifications_00100, Function | Med EXPECT_EQ(eventParser.GetOnConsumedReq()[0]->GetLabel().c_str(), NOTIFICATION_LABEL_0); EXPECT_EQ(eventParser.GetOnConsumedReq()[0]->GetId(), 0); std::stringstream stream0; - stream0 << UID << KEY_SPLITER << NOTIFICATION_LABEL_0 << KEY_SPLITER << 0; + stream0 << KEY_SPLITER << UID << KEY_SPLITER << NOTIFICATION_LABEL_0 << KEY_SPLITER << 0; std::string notificationKey0 = stream0.str(); NotificationSorting sorting0; EXPECT_EQ(eventParser.GetOnCanceledReq()[0]->GetKey(), notificationKey0); @@ -986,7 +1074,7 @@ HWTEST_F(AnsFWModuleTest, ANS_FW_MT_CancelAllNotifications_00100, Function | Med EXPECT_EQ(eventParser.GetOnConsumedReq()[1]->GetLabel().c_str(), NOTIFICATION_LABEL_1); EXPECT_EQ(eventParser.GetOnConsumedReq()[1]->GetId(), 1); std::stringstream stream1; - stream1 << UID << KEY_SPLITER << NOTIFICATION_LABEL_1 << KEY_SPLITER << 1; + stream1 << KEY_SPLITER << UID << KEY_SPLITER << NOTIFICATION_LABEL_1 << KEY_SPLITER << 1; std::string notificationKey1 = stream1.str(); NotificationSorting sorting1; EXPECT_EQ(eventParser.GetOnCanceledReq()[1]->GetKey(), notificationKey1); @@ -1546,6 +1634,368 @@ HWTEST_F(AnsFWModuleTest, ANS_Interface_MT_DoNotDisturb_07000, Function | Medium EXPECT_EQ(srcDate.GetDoNotDisturbType(), disDate.GetDoNotDisturbType()); } +/** + * + * @tc.number : ANS_FW_MT_DistributedNotification_SetEnable_00100 + * @tc.name : DistributedNotification_SetEnable_00100 + * @tc.desc : Set distributed notification enable. + */ +HWTEST_F(AnsFWModuleTest, DistributedNotification_SetEnable_00100, Function | MediumTest | Level1) +{ + ANS_LOGI("%{public}s", test_info_->name()); + bool enable; + + ASSERT_EQ(NotificationHelper::EnableDistributed(false), ERR_OK); + ASSERT_EQ(NotificationHelper::IsDistributedEnabled(enable), ERR_OK); + ASSERT_EQ(enable, false); + + ASSERT_EQ(NotificationHelper::EnableDistributed(true), ERR_OK); + ASSERT_EQ(NotificationHelper::IsDistributedEnabled(enable), ERR_OK); + ASSERT_EQ(enable, true); +} + +#ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED +/** + * + * @tc.number : ANS_FW_MT_DistributedNotification_SetEnableByBundle_00100 + * @tc.name : DistributedNotification_SetEnableByBundle_00100 + * @tc.desc : Set distributed notification enable by bundle. + */ +HWTEST_F(AnsFWModuleTest, DistributedNotification_SetEnableByBundle_00100, Function | MediumTest | Level1) +{ + ANS_LOGI("%{public}s", test_info_->name()); + bool enable; + NotificationBundleOption bundleOption(APP_NAME, UID); + + ASSERT_EQ(NotificationHelper::EnableDistributedByBundle(bundleOption, false), ERR_OK); + ASSERT_EQ(NotificationHelper::IsDistributedEnableByBundle(bundleOption, enable), ERR_OK); + ASSERT_EQ(enable, false); + + ASSERT_EQ(NotificationHelper::EnableDistributedByBundle(bundleOption, true), ERR_OK); + ASSERT_EQ(NotificationHelper::IsDistributedEnableByBundle(bundleOption, enable), ERR_OK); + ASSERT_EQ(enable, true); + + ASSERT_EQ(NotificationHelper::EnableDistributedSelf(false), ERR_OK); + ASSERT_EQ(NotificationHelper::IsDistributedEnableByBundle(bundleOption, enable), ERR_OK); + ASSERT_EQ(enable, false); + + ASSERT_EQ(NotificationHelper::EnableDistributedSelf(true), ERR_OK); + ASSERT_EQ(NotificationHelper::IsDistributedEnableByBundle(bundleOption, enable), ERR_OK); + ASSERT_EQ(enable, true); +} + +/** + * + * @tc.number : ANS_FW_MT_DistributedNotification_Publish_00100 + * @tc.name : DistributedNotification_Publish_00100 + * @tc.desc : publish a notification to distributed kvstore. + */ +HWTEST_F(AnsFWModuleTest, DistributedNotification_Publish_00100, Function | MediumTest | Level1) +{ + ANS_LOGI("%{public}s", test_info_->name()); + NotificationRequest request = CreateDistributedRequest(test_info_->name()); + + DistributedKv::AppId appId = {.appId = KVSTORE_APP_ID}; + DistributedKv::StoreId storeId = {.storeId = KVSTORE_NOTIFICATION_STORE_ID}; + std::shared_ptr pointer = + DistributedKv::AnsTestSingleKvStore::GetMockKvStorePointer(appId, storeId); + std::vector entries; + + ASSERT_EQ(NotificationHelper::PublishNotification(request), ERR_OK); + ASSERT_EQ(pointer->GetEntries(DistributedKv::Key(""), entries), DistributedKv::Status::SUCCESS); + DistributedKv::Entry outEntry; + ASSERT_EQ(GetRequestInDistributedEntryList(request, entries, outEntry), true); + SleepForFC(); +} + +/** + * + * @tc.number : ANS_FW_MT_DistributedNotification_Publish_00200 + * @tc.name : DistributedNotification_Publish_00200 + * @tc.desc : publish a local notification not use distributed kvstore. + */ +HWTEST_F(AnsFWModuleTest, DistributedNotification_Publish_00200, Function | MediumTest | Level1) +{ + ANS_LOGI("%{public}s", test_info_->name()); + NotificationRequest request = CreateDistributedRequest(test_info_->name()); + request.SetDistributed(false); + + DistributedKv::AppId appId = {.appId = KVSTORE_APP_ID}; + DistributedKv::StoreId storeId = {.storeId = KVSTORE_NOTIFICATION_STORE_ID}; + std::shared_ptr pointer = + DistributedKv::AnsTestSingleKvStore::GetMockKvStorePointer(appId, storeId); + std::vector entries; + + ASSERT_EQ(NotificationHelper::PublishNotification(request), ERR_OK); + ASSERT_EQ(pointer->GetEntries(DistributedKv::Key(""), entries), DistributedKv::Status::SUCCESS); + DistributedKv::Entry outEntry; + ASSERT_EQ(GetRequestInDistributedEntryList(request, entries, outEntry), false); + SleepForFC(); +} + +/** + * + * @tc.number : ANS_FW_MT_DistributedNotification_Cancel_00100 + * @tc.name : DistributedNotification_Cancel_00100 + * @tc.desc : cancel a notification to distributed kvstore ,use CancelNotification(label, id). + */ +HWTEST_F(AnsFWModuleTest, DistributedNotification_Cancel_00100, Function | MediumTest | Level1) +{ + ANS_LOGI("%{public}s", test_info_->name()); + NotificationRequest request = CreateDistributedRequest(test_info_->name()); + + DistributedKv::AppId appId = {.appId = KVSTORE_APP_ID}; + DistributedKv::StoreId storeId = {.storeId = KVSTORE_NOTIFICATION_STORE_ID}; + std::shared_ptr pointer = + DistributedKv::AnsTestSingleKvStore::GetMockKvStorePointer(appId, storeId); + std::vector entries; + + ASSERT_EQ(NotificationHelper::PublishNotification(request), ERR_OK); + ASSERT_EQ(pointer->GetEntries(DistributedKv::Key(""), entries), DistributedKv::Status::SUCCESS); + DistributedKv::Entry outEntry; + ASSERT_EQ(GetRequestInDistributedEntryList(request, entries, outEntry), true); + + ASSERT_EQ(NotificationHelper::CancelNotification(request.GetLabel(), request.GetNotificationId()), ERR_OK); + ASSERT_EQ(pointer->GetEntries(DistributedKv::Key(""), entries), DistributedKv::Status::SUCCESS); + ASSERT_EQ(GetRequestInDistributedEntryList(request, entries, outEntry), false); + SleepForFC(); +} + +/** + * + * @tc.number : ANS_FW_MT_DistributedNotification_Cancel_00200 + * @tc.name : DistributedNotification_Cancel_00200 + * @tc.desc : cancel a notification to distributed kvstore ,use CancelAllNotifications(). + */ +HWTEST_F(AnsFWModuleTest, DistributedNotification_Cancel_00200, Function | MediumTest | Level1) +{ + ANS_LOGI("%{public}s", test_info_->name()); + NotificationRequest request = CreateDistributedRequest(test_info_->name()); + + DistributedKv::AppId appId = {.appId = KVSTORE_APP_ID}; + DistributedKv::StoreId storeId = {.storeId = KVSTORE_NOTIFICATION_STORE_ID}; + std::shared_ptr pointer = + DistributedKv::AnsTestSingleKvStore::GetMockKvStorePointer(appId, storeId); + std::vector entries; + + ASSERT_EQ(NotificationHelper::PublishNotification(request), ERR_OK); + ASSERT_EQ(pointer->GetEntries(DistributedKv::Key(""), entries), DistributedKv::Status::SUCCESS); + DistributedKv::Entry outEntry; + ASSERT_EQ(GetRequestInDistributedEntryList(request, entries, outEntry), true); + + request.SetNotificationId(request.GetNotificationId() + 1); + ASSERT_EQ(NotificationHelper::PublishNotification(request), ERR_OK); + ASSERT_EQ(pointer->GetEntries(DistributedKv::Key(""), entries), DistributedKv::Status::SUCCESS); + ASSERT_EQ(GetRequestInDistributedEntryList(request, entries, outEntry), true); + + ASSERT_EQ(NotificationHelper::CancelAllNotifications(), ERR_OK); + ASSERT_EQ(pointer->GetEntries(DistributedKv::Key(""), entries), DistributedKv::Status::SUCCESS); + ASSERT_EQ(entries.size(), std::size_t(0)); + SleepForFC(); +} + +/** + * + * @tc.number : ANS_FW_MT_DistributedNotification_Remove_00100 + * @tc.name : DistributedNotification_Remove_00100 + * @tc.desc : remove a notification to distributed kvstore ,use RemoveNotification(bundleOption, id, label). + */ +HWTEST_F(AnsFWModuleTest, DistributedNotification_Remove_00100, Function | MediumTest | Level1) +{ + ANS_LOGI("%{public}s", test_info_->name()); + NotificationRequest request = CreateDistributedRequest(test_info_->name()); + + DistributedKv::AppId appId = {.appId = KVSTORE_APP_ID}; + DistributedKv::StoreId storeId = {.storeId = KVSTORE_NOTIFICATION_STORE_ID}; + std::shared_ptr pointer = + DistributedKv::AnsTestSingleKvStore::GetMockKvStorePointer(appId, storeId); + std::vector entries; + + ASSERT_EQ(NotificationHelper::PublishNotification(request), ERR_OK); + ASSERT_EQ(pointer->GetEntries(DistributedKv::Key(""), entries), DistributedKv::Status::SUCCESS); + DistributedKv::Entry outEntry; + ASSERT_EQ(GetRequestInDistributedEntryList(request, entries, outEntry), true); + + NotificationBundleOption bundleOption(APP_NAME, UID); + ASSERT_EQ( + NotificationHelper::RemoveNotification(bundleOption, request.GetNotificationId(), request.GetLabel()), ERR_OK); + ASSERT_EQ(pointer->GetEntries(DistributedKv::Key(""), entries), DistributedKv::Status::SUCCESS); + ASSERT_EQ(GetRequestInDistributedEntryList(request, entries, outEntry), false); + SleepForFC(); +} + +/** + * + * @tc.number : ANS_FW_MT_DistributedNotification_Remove_00200 + * @tc.name : DistributedNotification_Remove_00200 + * @tc.desc : remove a notification to distributed kvstore ,use RemoveNotifications(). + */ +HWTEST_F(AnsFWModuleTest, DistributedNotification_Remove_00200, Function | MediumTest | Level1) +{ + ANS_LOGI("%{public}s", test_info_->name()); + NotificationRequest request = CreateDistributedRequest(test_info_->name()); + + DistributedKv::AppId appId = {.appId = KVSTORE_APP_ID}; + DistributedKv::StoreId storeId = {.storeId = KVSTORE_NOTIFICATION_STORE_ID}; + std::shared_ptr pointer = + DistributedKv::AnsTestSingleKvStore::GetMockKvStorePointer(appId, storeId); + std::vector entries; + + ASSERT_EQ(NotificationHelper::PublishNotification(request), ERR_OK); + ASSERT_EQ(pointer->GetEntries(DistributedKv::Key(""), entries), DistributedKv::Status::SUCCESS); + DistributedKv::Entry outEntry; + ASSERT_EQ(GetRequestInDistributedEntryList(request, entries, outEntry), true); + + request.SetNotificationId(request.GetNotificationId() + 1); + ASSERT_EQ(NotificationHelper::PublishNotification(request), ERR_OK); + ASSERT_EQ(pointer->GetEntries(DistributedKv::Key(""), entries), DistributedKv::Status::SUCCESS); + ASSERT_EQ(GetRequestInDistributedEntryList(request, entries, outEntry), true); + + ASSERT_EQ(NotificationHelper::RemoveNotifications(), ERR_OK); + ASSERT_EQ(pointer->GetEntries(DistributedKv::Key(""), entries), DistributedKv::Status::SUCCESS); + ASSERT_EQ(entries.size(), std::size_t(0)); + SleepForFC(); +} + +/** + * + * @tc.number : ANS_FW_MT_DistributedNotification_Remove_00300 + * @tc.name : DistributedNotification_Remove_00300 + * @tc.desc : remove a notification to distributed kvstore ,use RemoveNotificationsByBundle(bundleOption). + */ +HWTEST_F(AnsFWModuleTest, DistributedNotification_Remove_00300, Function | MediumTest | Level1) +{ + ANS_LOGI("%{public}s", test_info_->name()); + NotificationRequest request = CreateDistributedRequest(test_info_->name()); + + DistributedKv::AppId appId = {.appId = KVSTORE_APP_ID}; + DistributedKv::StoreId storeId = {.storeId = KVSTORE_NOTIFICATION_STORE_ID}; + std::shared_ptr pointer = + DistributedKv::AnsTestSingleKvStore::GetMockKvStorePointer(appId, storeId); + std::vector entries; + + ASSERT_EQ(NotificationHelper::PublishNotification(request), ERR_OK); + ASSERT_EQ(pointer->GetEntries(DistributedKv::Key(""), entries), DistributedKv::Status::SUCCESS); + DistributedKv::Entry outEntry; + ASSERT_EQ(GetRequestInDistributedEntryList(request, entries, outEntry), true); + + request.SetNotificationId(request.GetNotificationId() + 1); + ASSERT_EQ(NotificationHelper::PublishNotification(request), ERR_OK); + ASSERT_EQ(pointer->GetEntries(DistributedKv::Key(""), entries), DistributedKv::Status::SUCCESS); + ASSERT_EQ(GetRequestInDistributedEntryList(request, entries, outEntry), true); + + NotificationBundleOption bundleOption(APP_NAME, UID); + ASSERT_EQ(NotificationHelper::RemoveNotificationsByBundle(bundleOption), ERR_OK); + ASSERT_EQ(pointer->GetEntries(DistributedKv::Key(""), entries), DistributedKv::Status::SUCCESS); + ASSERT_EQ(entries.size(), std::size_t(0)); + SleepForFC(); +} + +/** + * + * @tc.number : ANS_FW_MT_DistributedNotification_Subscribe_00100 + * @tc.name : DistributedNotification_Subscribe_00100 + * @tc.desc : distributed kvstore callback data insert/update/delete. + */ +HWTEST_F(AnsFWModuleTest, DistributedNotification_Subscribe_00100, Function | MediumTest | Level1) +{ + ANS_LOGI("%{public}s", test_info_->name()); + NotificationRequest request = CreateDistributedRequest(test_info_->name()); + std::string jsonString; + NotificationJsonConverter::ConvertToJosnString(&request, jsonString); + + DistributedKv::AppId appId = {.appId = KVSTORE_APP_ID}; + DistributedKv::StoreId storeId = {.storeId = KVSTORE_NOTIFICATION_STORE_ID}; + std::shared_ptr pointer = + DistributedKv::AnsTestSingleKvStore::GetMockKvStorePointer(appId, storeId); + std::vector entries; + + TestAnsSubscriber subscriber; + ASSERT_EQ(NotificationHelper::SubscribeNotification(subscriber), ERR_OK); + + DistributedKv::Key key(GenerateDistributedKey(request, REMOTE_DEVICE_ID)); + DistributedKv::Value value(jsonString); + pointer->InsertDataToDoCallback(key, value); + SleepForFC(); + + EventParser parser1; + parser1.Parse(subscriber.GetEvents()); + auto notificationList = parser1.GetOnConsumedReq(); + EXPECT_NE(notificationList.size(), std::size_t(0)); + std::shared_ptr outNotification; + EXPECT_EQ(GetRequestInNotificationList(request, notificationList, outNotification), true); + subscriber.ClearEvents(); + + pointer->UpdateDataToDoCallback(key, value); + SleepForFC(); + + EventParser parser2; + parser2.Parse(subscriber.GetEvents()); + notificationList = parser2.GetOnConsumedReq(); + EXPECT_NE(notificationList.size(), std::size_t(0)); + EXPECT_EQ(GetRequestInNotificationList(request, notificationList, outNotification), true); + subscriber.ClearEvents(); + + pointer->DeleteDataToDoCallback(key); + SleepForFC(); + + EventParser parser3; + parser3.Parse(subscriber.GetEvents()); + notificationList = parser3.GetOnCanceledReq(); + EXPECT_NE(notificationList.size(), std::size_t(0)); + EXPECT_EQ(GetRequestInNotificationList(request, notificationList, outNotification), true); + subscriber.ClearEvents(); + ASSERT_EQ(NotificationHelper::UnSubscribeNotification(subscriber), ERR_OK); + + SleepForFC(); +} + +/** + * + * @tc.number : ANS_FW_MT_DistributedNotification_Subscribe_00200 + * @tc.name : DistributedNotification_Subscribe_00200 + * @tc.desc : distributed kvstore callback data, delete notification after OnConsumed. + */ +HWTEST_F(AnsFWModuleTest, DistributedNotification_Subscribe_00200, Function | MediumTest | Level1) +{ + ANS_LOGI("%{public}s", test_info_->name()); + NotificationRequest request = CreateDistributedRequest(test_info_->name()); + request.SetOwnerBundleName(APP_NAME); + request.SetCreatorBundleName(APP_NAME); + std::string jsonString; + NotificationJsonConverter::ConvertToJosnString(&request, jsonString); + + DistributedKv::AppId appId = {.appId = KVSTORE_APP_ID}; + DistributedKv::StoreId storeId = {.storeId = KVSTORE_NOTIFICATION_STORE_ID}; + std::shared_ptr pointer = + DistributedKv::AnsTestSingleKvStore::GetMockKvStorePointer(appId, storeId); + std::vector entries; + + TestAnsSubscriber subscriber; + ASSERT_EQ(NotificationHelper::SubscribeNotification(subscriber), ERR_OK); + + DistributedKv::Key key(GenerateDistributedKey(request, REMOTE_DEVICE_ID)); + DistributedKv::Value value(jsonString); + pointer->InsertDataToDoCallback(key, value); + SleepForFC(); + + EventParser parser1; + parser1.Parse(subscriber.GetEvents()); + auto notificationList = parser1.GetOnConsumedReq(); + EXPECT_NE(notificationList.size(), std::size_t(0)); + std::shared_ptr outNotification; + EXPECT_EQ(GetRequestInNotificationList(request, notificationList, outNotification), true); + + EXPECT_EQ(NotificationHelper::RemoveNotifications(), ERR_OK); + + EXPECT_EQ(pointer->GetEntries(DistributedKv::Key(""), entries), DistributedKv::Status::SUCCESS); + EXPECT_EQ(entries.size(), std::size_t(0)); + subscriber.ClearEvents(); + ASSERT_EQ(NotificationHelper::UnSubscribeNotification(subscriber), ERR_OK); + SleepForFC(); +} +#endif + HWTEST_F(AnsFWModuleTest, ANS_Interface_MT_PulbishContinuousTask_07100, Function | MediumTest | Level1) { IPCSkeleton::SetCallingUid(SYSTEM_SERVICE_UID); @@ -1800,4 +2250,4 @@ HWTEST_F(AnsFWModuleTest, ANS_Interface_MT_PulbishContinuousTask_07800, Function IPCSkeleton::SetCallingUid(1); } } // namespace Notification -} // namespace OHOS +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/ans/test/moduletest/ans_innerkits_module_publish_test.cpp b/frameworks/ans/test/moduletest/ans_innerkits_module_publish_test.cpp index 5f3f3428fb1b9d841dac9326f1812f2f4d1a7e1c..56cf177a8cf0ac0366f4725fb92b188de97d8719 100644 --- a/frameworks/ans/test/moduletest/ans_innerkits_module_publish_test.cpp +++ b/frameworks/ans/test/moduletest/ans_innerkits_module_publish_test.cpp @@ -23,6 +23,7 @@ #include "if_system_ability_manager.h" #include "iservice_registry.h" #include "notification_helper.h" +#include "notification_json_convert.h" #include "mock_bundle_manager.h" #include "mock_ipc_skeleton.h" #include "system_ability_definition.h" @@ -394,6 +395,7 @@ public: void WaitOnSubscribeResult(); void WaitOnConsumed(); void WaitOnUnsubscribeResult(); + void CheckJsonConverter(const NotificationRequest *request); }; void AnsInterfaceModulePublishTest::SetUpTestCase() @@ -470,6 +472,42 @@ void AnsInterfaceModulePublishTest::WaitOnUnsubscribeResult() } } +void AnsInterfaceModulePublishTest::CheckJsonConverter(const NotificationRequest *request) +{ + nlohmann::json jsonObject; + auto ret0 = NotificationJsonConverter::ConvertToJosn(request, jsonObject); + EXPECT_EQ(ret0, true); + GTEST_LOG_(INFO) << "ANS_Interface_MT_Publish_08000::ConvertToJosn object dump ==========>" << jsonObject.dump(); + + std::string jsonString; + auto ret1 = NotificationJsonConverter::ConvertToJosnString(request, jsonString); + GTEST_LOG_(INFO) << "ANS_Interface_MT_Publish_08000::ConvertToJosnString ret1 ==========>" + << (ret1 ? "true" : "false"); + EXPECT_EQ(ret1, true); + GTEST_LOG_(INFO) << "ANS_Interface_MT_Publish_08000::ConvertToJosnString string ==========>" << jsonString; + + GTEST_LOG_(INFO) << "ANS_Interface_MT_Publish_08000::convert Json sleep start ==========>"; + sleep(SLEEP_TIME); + GTEST_LOG_(INFO) << "ANS_Interface_MT_Publish_08000::convert Json sleep end ==========>"; + + auto pRequest1 = NotificationJsonConverter::ConvertFromJosn(jsonObject); + EXPECT_NE(pRequest1, nullptr); + GTEST_LOG_(INFO) << "ANS_Interface_MT_Publish_08000::ConvertFromJosn jsonObject dump request ==========>" + << pRequest1->Dump(); + + auto pRequest2 = NotificationJsonConverter::ConvertFromJosnString(jsonString); + EXPECT_NE(pRequest2, nullptr); + GTEST_LOG_(INFO) << "ANS_Interface_MT_Publish_08000::ConvertFromJosnString jsonString dump request ==========>" + << pRequest2->Dump(); + + nlohmann::json jsonObject2; + auto ret2 = NotificationJsonConverter::ConvertToJosn(pRequest1, jsonObject2); + GTEST_LOG_(INFO) << "ANS_Interface_MT_Publish_08000::ConvertToJosn ret2 ==========>" << (ret2 ? "true" : "false"); + EXPECT_EQ(ret2, true); + GTEST_LOG_(INFO) << "ANS_Interface_MT_Publish_08000::FromJson -> ToJson object dump ==========>" + << jsonObject2.dump(); +} + /** * @tc.number : ANS_Interface_MT_Publish_00100 * @tc.name : Publish_00100 @@ -1220,5 +1258,76 @@ HWTEST_F(AnsInterfaceModulePublishTest, ANS_Interface_MT_Publish_04000, Function EXPECT_EQ(0, NotificationHelper::UnSubscribeNotification(subscriber, info)); WaitOnUnsubscribeResult(); } + +/** + * @tc.number : ANS_Interface_MT_Publish_08000 + * @tc.name : Publish_08000 + * @tc.desc : . + * @tc.expected : . + */ +HWTEST_F(AnsInterfaceModulePublishTest, ANS_Interface_MT_Publish_08000, Function | MediumTest | Level1) +{ + GTEST_LOG_(INFO) << "ANS_Interface_MT_Publish_08000::convert Json start ############==========>"; + + NotificationRequest req; + std::shared_ptr normalContent = std::make_shared(); + EXPECT_NE(normalContent, nullptr); + normalContent->SetTitle("normal_title"); + normalContent->SetText("normal_text"); + normalContent->SetAdditionalText("normal_additional_text"); + GTEST_LOG_(INFO) << "ANS_Interface_MT_Publish_00800::normalContent::" << normalContent->Dump(); + + std::shared_ptr content = std::make_shared(normalContent); + EXPECT_NE(content, nullptr); + + req.SetNotificationId(8000); + req.SetContent(content); + req.SetSlotType(NotificationConstant::CONTENT_INFORMATION); + req.SetClassification(NotificationRequest::CLASSIFICATION_ALARM); + req.SetLabel("label"); + req.SetOwnerBundleName("owner"); + + auto wAgent1 = std::make_shared(); + req.SetWantAgent(wAgent1); + + auto wAgent2 = std::make_shared(); + std::shared_ptr dummyIcon; + auto ab1 = NotificationActionButton::Create(dummyIcon, "ab1_title", wAgent2); + + auto spUserInput3 = NotificationUserInput::Create("uikey3"); + auto spUserInput2 = NotificationUserInput::Create("uikey2"); + ab1->AddNotificationUserInput(spUserInput3); + ab1->AddNotificationUserInput(spUserInput2); + + auto spOnlyUserInput1 = NotificationUserInput::Create("uionlykey1"); + spOnlyUserInput1->SetPermitFreeFormInput(false); + spOnlyUserInput1->SetPermitMimeTypes("uionly", true); + auto spOnlyUserInput4 = NotificationUserInput::Create("uionlykey4"); + spOnlyUserInput4->SetPermitFreeFormInput(false); + spOnlyUserInput4->SetPermitMimeTypes("uionly", true); + + ab1->AddMimeTypeOnlyUserInput(spOnlyUserInput1); + ab1->AddMimeTypeOnlyUserInput(spOnlyUserInput4); + + std::shared_ptr dummyWantAgent; + auto ab2 = NotificationActionButton::Create(dummyIcon, "ab2_title", dummyWantAgent); + + req.AddActionButton(ab1); + req.AddActionButton(ab2); + + std::vector history {"uihistory3", "uihistory2", "uihistory1"}; + req.SetNotificationUserInputHistory(history); + + auto msgUser1 = std::make_shared(); + msgUser1->SetKey("msgUser1_key"); + msgUser1->SetName("msgUser1_name"); + auto msgUser2 = std::make_shared(); + msgUser2->SetKey("msgUser2_key"); + msgUser2->SetName("msgUser2_name"); + req.AddMessageUser(msgUser2); + req.AddMessageUser(msgUser1); + + CheckJsonConverter(&req); +} } // namespace Notification } // namespace OHOS \ No newline at end of file diff --git a/frameworks/ans/test/moduletest/mock/distributed_kv_data_manager.cpp b/frameworks/ans/test/moduletest/mock/distributed_kv_data_manager.cpp index a223023419e97b69fc8f937e22dd52c81e14b98c..86852f17a1a58df0149187febf1c8e2ed2198395 100644 --- a/frameworks/ans/test/moduletest/mock/distributed_kv_data_manager.cpp +++ b/frameworks/ans/test/moduletest/mock/distributed_kv_data_manager.cpp @@ -33,6 +33,7 @@ Status DistributedKvDataManager::GetSingleKvStore(const Options &options, const { std::string storeIdTmp = Constant::TrimCopy(storeId.storeId); kvStore = std::make_shared(); + AnsTestSingleKvStore::InsertMockKvStore(appId, storeId, kvStore); return Status::SUCCESS; } @@ -48,6 +49,28 @@ Status DistributedKvDataManager::CloseKvStore(const AppId &appId, std::shared_pt Status DistributedKvDataManager::DeleteKvStore(const AppId &appId, const StoreId &storeId) { + AnsTestSingleKvStore::RemoveMockKvStore(appId, storeId); + return Status::SUCCESS; +} + +Status DistributedKvDataManager::GetLocalDevice(DeviceInfo &localDevice) +{ + localDevice.deviceId = ""; + localDevice.deviceName = ""; + localDevice.deviceType = ""; + return Status::SUCCESS; +} + +Status DistributedKvDataManager::GetDeviceList(std::vector &deviceInfoList, DeviceFilterStrategy strategy) +{ + DeviceInfo remoteDevice = { + .deviceId = "", + .deviceName = "", + .deviceType = "", + }; + deviceInfoList.clear(); + deviceInfoList.push_back(remoteDevice); + return Status::SUCCESS; } diff --git a/frameworks/ans/test/moduletest/mock/include/mock_single_kv_store.h b/frameworks/ans/test/moduletest/mock/include/mock_single_kv_store.h index 0194762d93be4089ca4cf8eb7141d4a2a7a8606f..e71772fb8e2cb3de0a86c3d2b20e7c58ed5744e6 100644 --- a/frameworks/ans/test/moduletest/mock/include/mock_single_kv_store.h +++ b/frameworks/ans/test/moduletest/mock/include/mock_single_kv_store.h @@ -17,6 +17,7 @@ #define ANS_MOCK_SINGLE_KV_STORE_H #include +#include #include #include "kvstore.h" @@ -106,8 +107,30 @@ public: Status ReleaseKvStoreSnapshot(std::shared_ptr &snapshot) override; Status Clear() override; + +public: + static void InsertMockKvStore(AppId appId, StoreId storeId, std::shared_ptr store); + static void RemoveMockKvStore(AppId appId, StoreId storeId); + static std::shared_ptr GetMockKvStorePointer(AppId appId, StoreId storeId); + struct Compare { + bool operator()(const Key &a, const Key &b) const + { + return a.Compare(b) == -1; + } + }; + + void InsertDataToDoCallback(const Key &key, const Value &value); + void UpdateDataToDoCallback(const Key &key, const Value &value); + void DeleteDataToDoCallback(const Key &key); + protected: KVSTORE_API virtual Status Control(KvControlCmd cmd, const KvParam &inputParam, KvParam &output) override; + +private: + static std::mutex mutex_; + static std::map, std::shared_ptr> kvStoreMap_; + std::shared_ptr observer_; + std::map kvstore_; }; } // namespace DistributedKv } // namespace OHOS diff --git a/frameworks/ans/test/moduletest/mock/mock_change_notification.cpp b/frameworks/ans/test/moduletest/mock/mock_change_notification.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c255d13cb3e20870fa5235f574b302c93d0db4ce --- /dev/null +++ b/frameworks/ans/test/moduletest/mock/mock_change_notification.cpp @@ -0,0 +1,62 @@ +/* + * 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 "change_notification.h" + +namespace OHOS { +namespace DistributedKv { +ChangeNotification::ChangeNotification(std::vector &&insertEntries, std::vector &&updateEntries, + std::vector &&deleteEntries, const std::string &deviceId, const bool isClear) + : insertEntries_(insertEntries), + updateEntries_(updateEntries), + deleteEntries_(deleteEntries), + deviceId_(deviceId), + isClear_(isClear) +{} + +ChangeNotification::~ChangeNotification() +{} + +const std::vector &ChangeNotification::GetInsertEntries() const +{ + return this->insertEntries_; +} + +const std::vector &ChangeNotification::GetUpdateEntries() const +{ + return this->updateEntries_; +} + +const std::vector &ChangeNotification::GetDeleteEntries() const +{ + return this->deleteEntries_; +} + +const std::string &ChangeNotification::GetDeviceId() const +{ + return this->deviceId_; +} + +bool ChangeNotification::IsClear() const +{ + return this->isClear_; +} + +bool ChangeNotification::Marshalling(Parcel &parcel) const +{ + return true; +} +} // namespace DistributedKv +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/ans/test/moduletest/mock/mock_common_event_data.cpp b/frameworks/ans/test/moduletest/mock/mock_common_event_data.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c03942bed7a21621bf1439552cf38c1299224839 --- /dev/null +++ b/frameworks/ans/test/moduletest/mock/mock_common_event_data.cpp @@ -0,0 +1,36 @@ +/* + * 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 "common_event_data.h" + +namespace OHOS { +namespace EventFwk { +CommonEventData::CommonEventData() +{} + +CommonEventData::~CommonEventData() +{} + +void CommonEventData::SetWant(const Want &want) +{ + want_ = want; +} + +bool CommonEventData::Marshalling(Parcel &parcel) const +{ + return true; +} +} // namespace EventFwk +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/ans/test/moduletest/mock/mock_common_event_manager.cpp b/frameworks/ans/test/moduletest/mock/mock_common_event_manager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..852a174701b3097ab9bd30184aef77cef82abe86 --- /dev/null +++ b/frameworks/ans/test/moduletest/mock/mock_common_event_manager.cpp @@ -0,0 +1,61 @@ +/* + * 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 "common_event_manager.h" + +#include + +namespace OHOS { +namespace EventFwk { +namespace { +std::list> subscriberList; +} +bool CommonEventManager::PublishCommonEvent(const CommonEventData &data) +{ + for (auto subscriber : subscriberList) { + subscriber->OnReceiveEvent(data); + } + return true; +} + +bool CommonEventManager::PublishCommonEvent(const CommonEventData &data, const CommonEventPublishInfo &publishInfo) +{ + return true; +} + +bool CommonEventManager::PublishCommonEvent(const CommonEventData &data, const CommonEventPublishInfo &publishInfo, + const std::shared_ptr &subscriber) +{ + return true; +} + +bool CommonEventManager::SubscribeCommonEvent(const std::shared_ptr &subscriber) +{ + subscriberList.push_back(subscriber); + return true; +} + +bool CommonEventManager::UnSubscribeCommonEvent(const std::shared_ptr &subscriber) +{ + subscriberList.remove(subscriber); + return true; +} + +bool CommonEventManager::GetStickyCommonEvent(const std::string &event, CommonEventData &commonEventData) +{ + return true; +} +} // namespace EventFwk +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/ans/test/moduletest/mock/mock_single_kv_store.cpp b/frameworks/ans/test/moduletest/mock/mock_single_kv_store.cpp index 3f6d34b42d608986da4bfe80f1b132c3f945d069..d09801b062d04c4df2ad1133ba00de60b41c2197 100644 --- a/frameworks/ans/test/moduletest/mock/mock_single_kv_store.cpp +++ b/frameworks/ans/test/moduletest/mock/mock_single_kv_store.cpp @@ -14,12 +14,103 @@ */ #include "mock_single_kv_store.h" + #include "types.h" namespace OHOS { namespace DistributedKv { +std::mutex AnsTestSingleKvStore::mutex_; +std::map, std::shared_ptr> AnsTestSingleKvStore::kvStoreMap_; + +void AnsTestSingleKvStore::InsertMockKvStore(AppId appId, StoreId storeId, std::shared_ptr store) +{ + std::lock_guard lock(mutex_); + + kvStoreMap_[std::pair(appId.appId, storeId.storeId)] = store; +} + +void AnsTestSingleKvStore::RemoveMockKvStore(AppId appId, StoreId storeId) +{ + kvStoreMap_.erase(std::pair(appId.appId, storeId.storeId)); +} + +std::shared_ptr AnsTestSingleKvStore::GetMockKvStorePointer(AppId appId, StoreId storeId) +{ + for (auto kvstore : kvStoreMap_) { + if (kvstore.first == std::pair(appId.appId, storeId.storeId)) { + return std::static_pointer_cast(kvstore.second); + } + } + + return nullptr; +} + +void AnsTestSingleKvStore::InsertDataToDoCallback(const Key &key, const Value &value) +{ + Put(key, value); + if (observer_ != nullptr) { + Entry entry; + entry.key = key; + entry.value = value; + std::vector insertEntries; + std::vector updateEntries; + std::vector deleteEntries; + insertEntries.push_back(entry); + ChangeNotification change( + std::move(insertEntries), std::move(updateEntries), std::move(deleteEntries), "", false); + observer_->OnChange(change); + } +} + +void AnsTestSingleKvStore::UpdateDataToDoCallback(const Key &key, const Value &value) +{ + Put(key, value); + if (observer_ != nullptr) { + Entry entry; + entry.key = key; + entry.value = value; + std::vector insertEntries; + std::vector updateEntries; + std::vector deleteEntries; + updateEntries.push_back(entry); + ChangeNotification change( + std::move(insertEntries), std::move(updateEntries), std::move(deleteEntries), "", false); + observer_->OnChange(change); + } +} + +void AnsTestSingleKvStore::DeleteDataToDoCallback(const Key &key) +{ + Value value; + Get(key, value); + Delete(key); + if (observer_ != nullptr) { + Entry entry; + entry.key = key; + entry.value = value; + std::vector insertEntries; + std::vector updateEntries; + std::vector deleteEntries; + deleteEntries.push_back(entry); + ChangeNotification change( + std::move(insertEntries), std::move(updateEntries), std::move(deleteEntries), "", false); + observer_->OnChange(change); + } +} + Status AnsTestSingleKvStore::GetEntries(const Key &prefixKey, std::vector &entries) const { + entries.clear(); + + for (auto iter : kvstore_) { + if (iter.first.StartsWith(prefixKey)) { + Entry entry; + entry.key = iter.first; + entry.value = iter.second; + entries.push_back(entry); + } + } + return Status::SUCCESS; } @@ -38,14 +129,14 @@ Status AnsTestSingleKvStore::GetResultSet(const Key &prefixKey, std::shared_ptr< return Status::SUCCESS; } -Status AnsTestSingleKvStore::GetResultSetWithQuery(const std::string &query, - std::shared_ptr &resultSet) const +Status AnsTestSingleKvStore::GetResultSetWithQuery( + const std::string &query, std::shared_ptr &resultSet) const { return Status::SUCCESS; } -Status AnsTestSingleKvStore::GetResultSetWithQuery(const DataQuery &query, - std::shared_ptr &resultSet) const +Status AnsTestSingleKvStore::GetResultSetWithQuery( + const DataQuery &query, std::shared_ptr &resultSet) const { return Status::SUCCESS; } @@ -73,6 +164,8 @@ Status AnsTestSingleKvStore::Sync( Status AnsTestSingleKvStore::RemoveDeviceData(const std::string &device) { + kvstore_.clear(); + return Status::SUCCESS; } @@ -85,26 +178,41 @@ StoreId AnsTestSingleKvStore::GetStoreId() const Status AnsTestSingleKvStore::Delete(const Key &key) { - return Status::SUCCESS; + if (kvstore_.erase(key) != 0) { + return Status::SUCCESS; + } + + return Status::KEY_NOT_FOUND; } Status AnsTestSingleKvStore::Put(const Key &key, const Value &value) { + kvstore_[key] = value; + return Status::SUCCESS; } Status AnsTestSingleKvStore::Get(const Key &key, Value &value) { - return Status::SUCCESS; + for (auto iter : kvstore_) { + if (iter.first == key) { + value = iter.second; + return Status::SUCCESS; + } + } + + return Status::KEY_NOT_FOUND; } Status AnsTestSingleKvStore::SubscribeKvStore(SubscribeType subscribeType, std::shared_ptr observer) { + observer_ = observer; return Status::SUCCESS; } Status AnsTestSingleKvStore::UnSubscribeKvStore(SubscribeType subscribeType, std::shared_ptr observer) { + observer_ = nullptr; return Status::SUCCESS; } @@ -190,8 +298,8 @@ Status AnsTestSingleKvStore::UnSubscribeWithQuery(const std::vector return Status::SUCCESS; } -Status AnsTestSingleKvStore::GetKvStoreSnapshot(std::shared_ptr observer, - std::shared_ptr &snapshot) const +Status AnsTestSingleKvStore::GetKvStoreSnapshot( + std::shared_ptr observer, std::shared_ptr &snapshot) const { return Status::NOT_SUPPORT; } diff --git a/frameworks/wantagent/BUILD.gn b/frameworks/wantagent/BUILD.gn index 8ca30778c44628ffa5d4bcad43b5890311b4a524..54be266712af53d3cfaf30fb2abd4e7e4d66dae3 100644 --- a/frameworks/wantagent/BUILD.gn +++ b/frameworks/wantagent/BUILD.gn @@ -27,6 +27,7 @@ config("wantagent_innerkits_public_config") { "//foundation/aafwk/standard/frameworks/kits/ability/native/include", "//foundation/aafwk/standard/interfaces/innerkits/ability_manager/include", "//foundation/aafwk/standard/interfaces/innerkits/want/include", + "//foundation/aafwk/standard/frameworks/kits/content/cpp/src/ohos/aafwk/content/", "//foundation/aafwk/standard/interfaces/innerkits/want/include/ohos/aafwk/content", "//foundation/aafwk/standard/services/abilitymgr/include", "//foundation/appexecfwk/standard/interfaces/innerkits/appexecfwk_core/include/appmgr", diff --git a/frameworks/wantagent/src/pending_want.cpp b/frameworks/wantagent/src/pending_want.cpp index 56e1e4c96fa40537b8e1e6fe640bddff59e27ea6..5781cdec6b28155c0769083e3e811a8a9ffb6a70 100644 --- a/frameworks/wantagent/src/pending_want.cpp +++ b/frameworks/wantagent/src/pending_want.cpp @@ -408,4 +408,11 @@ PendingWant *PendingWant::Unmarshalling(Parcel &parcel) return pendingWant; } + +std::shared_ptr PendingWant::GetWantSenderInfo(const sptr &target) +{ + std::shared_ptr info = std::make_shared(); + int ret = AbilityManagerClient::GetInstance()->GetWantSenderInfo(target, info); + return ret ? nullptr : info; +} } // namespace OHOS::Notification::WantAgent diff --git a/frameworks/wantagent/src/want_agent_helper.cpp b/frameworks/wantagent/src/want_agent_helper.cpp index ba702512b1a7cae381256934525f19cb97f0d792..7f3d0cb13f8ae6bb9e7cb12f65186eb86eb8fd10 100644 --- a/frameworks/wantagent/src/want_agent_helper.cpp +++ b/frameworks/wantagent/src/want_agent_helper.cpp @@ -19,6 +19,7 @@ #include "hilog_wrapper.h" #include "pending_want.h" #include "want_agent_log_wrapper.h" +#include "want_params_wrapper.h" #include "want_sender_info.h" #include "want_sender_interface.h" @@ -338,4 +339,101 @@ void WantAgentHelper::UnregisterCancelListener( pendingWant->UnregisterCancelListener(cancelListener, pendingWant->GetTarget()); } + +std::string WantAgentHelper::ToString(const std::shared_ptr &agent) +{ + if (agent == nullptr) { + WANT_AGENT_LOGE("WantAgentHelper::ToString WantAgent invalid input param."); + return ""; + } + + std::shared_ptr pendingWant = agent->GetPendingWant(); + if (pendingWant == nullptr) { + WANT_AGENT_LOGE("WantAgentHelper::ToString PendingWant invalid input param."); + return ""; + } + + std::shared_ptr info = pendingWant->GetWantSenderInfo(pendingWant->GetTarget()); + if (info == nullptr) { + WANT_AGENT_LOGE("WantAgentHelper::ToString WantSenderInfo invalid input param."); + return ""; + } + nlohmann::json jsonObject; + jsonObject["requestCode"] = (*info.get()).requestCode; + jsonObject["operationType"] = (*info.get()).type; + jsonObject["flags"] = (*info.get()).flags; + + nlohmann::json wants = nlohmann::json::array(); + for (auto &wantInfo : (*info.get()).allWants) { + wants.emplace_back(wantInfo.want.ToString()); + } + jsonObject["wants"] = wants; + + if ((*info.get()).allWants.size() > 0) { + nlohmann::json paramsObj; + AAFwk::WantParamWrapper wWrapper((*info.get()).allWants[0].want.GetParams()); + paramsObj["extraInfoValue"] = wWrapper.ToString(); + jsonObject["extraInfo"] = paramsObj; + } + + return jsonObject.dump(); +} + +std::shared_ptr WantAgentHelper::FromString(const std::string &jsonString) +{ + if (jsonString.empty()) { + return nullptr; + } + nlohmann::json jsonObject = nlohmann::json::parse(jsonString); + + int requestCode = -1; + if (jsonObject.contains("requestCode")) { + requestCode = jsonObject.at("requestCode").get(); + } + + WantAgentConstant::OperationType operationType = WantAgentConstant::OperationType::UNKNOWN_TYPE; + if (jsonObject.contains("operationType")) { + operationType = static_cast(jsonObject.at("operationType").get()); + } + + int flags = -1; + std::vector flagsVec = {}; + if (jsonObject.contains("flags")) { + flags = jsonObject.at("flags").get(); + } + if (flags | FLAG_ONE_SHOT) { + flagsVec.emplace_back(WantAgentConstant::Flags::ONE_TIME_FLAG); + } else if (flags | FLAG_NO_CREATE) { + flagsVec.emplace_back(WantAgentConstant::Flags::NO_BUILD_FLAG); + } else if (flags | FLAG_CANCEL_CURRENT) { + flagsVec.emplace_back(WantAgentConstant::Flags::CANCEL_PRESENT_FLAG); + } else if (flags | FLAG_UPDATE_CURRENT) { + flagsVec.emplace_back(WantAgentConstant::Flags::UPDATE_PRESENT_FLAG); + } else if (flags | FLAG_IMMUTABLE) { + flagsVec.emplace_back(WantAgentConstant::Flags::CONSTANT_FLAG); + } + + std::vector> wants = {}; + if (jsonObject.contains("wants")) { + for (auto &wantObj : jsonObject.at("wants")) { + auto wantString = wantObj.get(); + wants.emplace_back(std::make_shared(*Want::FromString(wantString))); + } + } + + std::shared_ptr extraInfo = nullptr; + if (jsonObject.contains("extraInfo")) { + auto extraInfoObj = jsonObject.at("extraInfo"); + if (extraInfoObj.contains("extraInfoValue")) { + auto pwWrapper = AAFwk::WantParamWrapper::Parse(extraInfoObj.at("extraInfoValue").get()); + AAFwk::WantParams params; + if (pwWrapper->GetValue(params) == ERR_OK) { + extraInfo = std::make_shared(params); + } + } + } + WantAgentInfo info(requestCode, operationType, flagsVec, wants, extraInfo); + + return GetWantAgent(info); +} } // namespace OHOS::Notification::WantAgent \ No newline at end of file diff --git a/interfaces/innerkits/ans/native/include/message_user.h b/interfaces/innerkits/ans/native/include/message_user.h index 7c8dbda6a2b8bd162ef56a7850b3a31f1543c5b0..93bb564c461307f199882e29daa466fbdea647a7 100644 --- a/interfaces/innerkits/ans/native/include/message_user.h +++ b/interfaces/innerkits/ans/native/include/message_user.h @@ -15,14 +15,14 @@ #ifndef BASE_NOTIFICATION_ANS_STANDARD_KITS_NATIVE_INCLUDE_MESSAGE_USER_H #define BASE_NOTIFICATION_ANS_STANDARD_KITS_NATIVE_INCLUDE_MESSAGE_USER_H -#include +#include "notification_json_convert.h" #include "pixel_map.h" #include "parcel.h" #include "uri.h" namespace OHOS { namespace Notification { -class MessageUser final : public Parcelable { +class MessageUser final : public Parcelable, public NotificationJsonConvertionBase { public: /** * A constructor used to construct MessageUser @@ -124,6 +124,19 @@ public: */ std::string Dump() const; + /** + * Converts a MessageUser object into a Json. + * @param jsonObject Indicates the Json object. + */ + bool ToJson(nlohmann::json &jsonObject) const override; + + /** + * Creates a MessageUser object from a Json. + * @param jsonObject Indicates the Json object. + * @return the MessageUser. + */ + static MessageUser *FromJson(const nlohmann::json &jsonObject); + /** * Marshals a MessageUser object into a Parcel. * diff --git a/interfaces/innerkits/ans/native/include/notification.h b/interfaces/innerkits/ans/native/include/notification.h index 1d40d79d768e427e7d7fd3bdccc1d6b7cc89d8c8..5ad3ea065b20ff90157851f740b013c411c668e0 100644 --- a/interfaces/innerkits/ans/native/include/notification.h +++ b/interfaces/innerkits/ans/native/include/notification.h @@ -31,6 +31,14 @@ public: */ Notification(const sptr &request); + /** + * A constructor used to create a Notification instance by existing NotificationRequest object. + * + * @param deviceId the device id. + * @param request the existing NotificationRequest object. + */ + Notification(const std::string &deviceId, const sptr &request); + /** * @brief A constructor used to create a Notification instance by copying parameters from an existing one. * @@ -189,6 +197,13 @@ public: */ NotificationConstant::SourceType GetSourceType() const; + /** + * @brief Gets the device id of the notification source. + * + * @return Return the device id. + */ + std::string GetDeviceId() const; + /** * @brief Obtains the UserId of the notification creator. * @@ -231,9 +246,10 @@ private: void SetPostTime(const int64_t &time); void SetSound(const Uri &sound); void SetVibrationStyle(const std::vector &style); + std::string GenerateNotificationKey( + const std::string &deviceId, int32_t uid, const std::string &label, int32_t id); void SetRemoveAllowed(bool removeAllowed); void SetSourceType(NotificationConstant::SourceType sourceType); - std::string GenerateNotificationKey(int32_t uid, const std::string &label, int32_t id); bool ReadFromParcel(Parcel &parcel); void ReadFromParcelBool(Parcel &parcel); void ReadFromParcelString(Parcel &parcel); @@ -252,6 +268,7 @@ private: bool enableViration_ {false}; bool isRemoveAllowed_ {true}; std::string key_ {""}; + std::string deviceId_ {""}; int32_t ledLightColor_ {0}; NotificationConstant::VisiblenessType lockscreenVisibleness_ {NotificationConstant::VisiblenessType::NO_OVERRIDE}; NotificationConstant::SourceType sourceType_ {NotificationConstant::SourceType::TYPE_NORMAL}; diff --git a/interfaces/innerkits/ans/native/include/notification_action_button.h b/interfaces/innerkits/ans/native/include/notification_action_button.h index a1a0f9a7bc00ae40e748f61b478cdd89beba0005..1979223958dd132c33fd6447cc2726ccf8212c30 100644 --- a/interfaces/innerkits/ans/native/include/notification_action_button.h +++ b/interfaces/innerkits/ans/native/include/notification_action_button.h @@ -17,6 +17,7 @@ #define BASE_NOTIFICATION_ANS_STANDARD_KITS_NATIVE_INCLUDE_NOTIFICATION_ACTION_BUTTON_H #include "notification_constant.h" +#include "notification_json_convert.h" #include "notification_user_input.h" #include "parcel.h" #include "pixel_map.h" @@ -24,7 +25,7 @@ namespace OHOS { namespace Notification { -class NotificationActionButton : public Parcelable { +class NotificationActionButton : public Parcelable, public NotificationJsonConvertionBase { public: /** * A static function used to create a NotificationActionButton instance with the input parameters passed. @@ -172,6 +173,19 @@ public: */ std::string Dump(); + /** + * Converts a NotificationActionButton object into a Json. + * @param jsonObject Indicates the Json object. + */ + bool ToJson(nlohmann::json &jsonObject) const override; + + /** + * Creates a NotificationActionButton object from a Json. + * @param jsonObject Indicates the Json object. + * @return the NotificationActionButton. + */ + static NotificationActionButton *FromJson(const nlohmann::json &jsonObject); + /** * Marshal a object into a Parcel. * @param parcel the object into the parcel diff --git a/interfaces/innerkits/ans/native/include/notification_basic_content.h b/interfaces/innerkits/ans/native/include/notification_basic_content.h index c1431546697e83a004948cab225b29ec5abb6d33..65ccd08bb9656714fd3206562091063c917794be 100644 --- a/interfaces/innerkits/ans/native/include/notification_basic_content.h +++ b/interfaces/innerkits/ans/native/include/notification_basic_content.h @@ -16,12 +16,12 @@ #ifndef BASE_NOTIFICATION_ANS_STANDARD_KITS_NATIVE_INCLUDE_NOTIFICATION_BASIC_CONTENT_H #define BASE_NOTIFICATION_ANS_STANDARD_KITS_NATIVE_INCLUDE_NOTIFICATION_BASIC_CONTENT_H -#include +#include "notification_json_convert.h" #include "parcel.h" namespace OHOS { namespace Notification { -class NotificationBasicContent : public Parcelable { +class NotificationBasicContent : public Parcelable, public NotificationJsonConvertionBase { public: /** * Default deconstructor used to deconstruct. @@ -72,6 +72,12 @@ public: */ virtual std::string Dump(); + /** + * Converts a NotificationBasicContent object into a Json. + * @param jsonObject Indicates the Json object. + */ + virtual bool ToJson(nlohmann::json &jsonObject) const override; + /** * Marshal a object into a Parcel. * @param parcel the object into the parcel @@ -91,6 +97,12 @@ protected: */ virtual bool ReadFromParcel(Parcel &parcel); + /** + * Creates a NotificationBasicContent object from a Json. + * @param jsonObject Indicates the Json object. + */ + void ReadFromJson(const nlohmann::json &jsonObject); + protected: std::string text_ {}; std::string title_ {}; diff --git a/interfaces/innerkits/ans/native/include/notification_content.h b/interfaces/innerkits/ans/native/include/notification_content.h index 9d5ebdabb133cfc98799668afa9063be6be36894..0923b9ea0401cc786f58d0faed4b2975f5019bce 100644 --- a/interfaces/innerkits/ans/native/include/notification_content.h +++ b/interfaces/innerkits/ans/native/include/notification_content.h @@ -18,6 +18,7 @@ #include "notification_basic_content.h" #include "notification_conversational_content.h" +#include "notification_json_convert.h" #include "notification_long_text_content.h" #include "notification_media_content.h" #include "notification_multiline_content.h" @@ -27,7 +28,7 @@ namespace OHOS { namespace Notification { -class NotificationContent : public Parcelable { +class NotificationContent : public Parcelable, public NotificationJsonConvertionBase { public: enum class Type { /** @@ -145,6 +146,19 @@ public: */ std::string Dump(); + /** + * Converts a NotificationContent object into a Json. + * @param jsonObject Indicates the Json object. + */ + bool ToJson(nlohmann::json &jsonObject) const override; + + /** + * Creates a NotificationContent object from a Json. + * @param jsonObject Indicates the Json object. + * @return the NotificationContent. + */ + static NotificationContent *FromJson(const nlohmann::json &jsonObject); + /** * Marshal a object into a Parcel. * @param parcel the object into the parcel @@ -170,6 +184,8 @@ private: */ bool ReadFromParcel(Parcel &parcel); + static bool ConvertJsonToContent(NotificationContent *target, const nlohmann::json &jsonObject); + private: NotificationContent::Type contentType_ {NotificationContent::Type::NONE}; std::shared_ptr content_ {}; diff --git a/interfaces/innerkits/ans/native/include/notification_conversational_content.h b/interfaces/innerkits/ans/native/include/notification_conversational_content.h index e35265131c2559c4ba95dfd5dd633b6700a970a1..999497416e064b5b24bb771f006b7936eb2c036b 100644 --- a/interfaces/innerkits/ans/native/include/notification_conversational_content.h +++ b/interfaces/innerkits/ans/native/include/notification_conversational_content.h @@ -19,6 +19,7 @@ #include "message_user.h" #include "notification_basic_content.h" #include "notification_conversational_message.h" +#include "notification_json_convert.h" #include "parcel.h" namespace OHOS { @@ -104,6 +105,19 @@ public: */ std::string Dump() override; + /** + * Converts a NotificationConversationalContent object into a Json. + * @param jsonObject Indicates the Json object. + */ + virtual bool ToJson(nlohmann::json &jsonObject) const override; + + /** + * Creates a NotificationConversationalContent object from a Json. + * @param jsonObject Indicates the Json object. + * @return the NotificationConversationalContent. + */ + static NotificationConversationalContent *FromJson(const nlohmann::json &jsonObject); + /** * Marshal a object into a Parcel. * @param parcel the object into the parcel diff --git a/interfaces/innerkits/ans/native/include/notification_conversational_message.h b/interfaces/innerkits/ans/native/include/notification_conversational_message.h index d46aacca2f42ffa6cb771aa65145af92d01b1981..b32fe9f654eccd4066ed3ec74290e8d1e446476e 100644 --- a/interfaces/innerkits/ans/native/include/notification_conversational_message.h +++ b/interfaces/innerkits/ans/native/include/notification_conversational_message.h @@ -17,12 +17,13 @@ #define BASE_NOTIFICATION_ANS_STANDARD_KITS_NATIVE_INCLUDE_NOTIFICATION_CONVERSATIONAL_MESSAGE_H #include "message_user.h" +#include "notification_json_convert.h" #include "parcel.h" #include "uri.h" namespace OHOS { namespace Notification { -class NotificationConversationalMessage : public Parcelable { +class NotificationConversationalMessage : public Parcelable, public NotificationJsonConvertionBase { public: /** * A constructor used to create a NotificationConversationalMessage instance with the input parameters passed. @@ -81,6 +82,19 @@ public: */ std::string Dump(); + /** + * Converts a NotificationConversationalMessage object into a Json. + * @param jsonObject Indicates the Json object. + */ + bool ToJson(nlohmann::json &jsonObject) const override; + + /** + * Creates a NotificationConversationalMessage object from a Json. + * @param jsonObject Indicates the Json object. + * @return the NotificationConversationalMessage. + */ + static NotificationConversationalMessage *FromJson(const nlohmann::json &jsonObject); + /** * Marshal a object into a Parcel. * @param parcel the object into the parcel diff --git a/interfaces/innerkits/ans/native/include/notification_distributed_options.h b/interfaces/innerkits/ans/native/include/notification_distributed_options.h new file mode 100644 index 0000000000000000000000000000000000000000..56d9e65029dc002407362e75c07e88cdc12d21f3 --- /dev/null +++ b/interfaces/innerkits/ans/native/include/notification_distributed_options.h @@ -0,0 +1,127 @@ +/* + * 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 BASE_NOTIFICATION_ANS_STANDARD_NATIVE_INCLUDE_NOTIFICATION_DISTRIBUTED_OPTIONS_H +#define BASE_NOTIFICATION_ANS_STANDARD_NATIVE_INCLUDE_NOTIFICATION_DISTRIBUTED_OPTIONS_H + +#include "notification_json_convert.h" +#include "parcel.h" + +namespace OHOS { +namespace Notification { +class NotificationDistributedOptions : public Parcelable, public NotificationJsonConvertionBase { +public: + /** + * Default constructor used to create a NotificationDistributedOptions instance. + */ + NotificationDistributedOptions() = default; + + /** + * Constructor used to create a NotificationDistributedOptions instance. + * @param distribute Specifies whether a notification is distributed. + * @param dvsDisplay The devices that support display. + * @param dvsOperate The devices that support operate. + */ + NotificationDistributedOptions( + bool distribute, const std::vector &dvsDisplay, const std::vector &dvsOperate); + + /** + * Default deconstructor used to deconstruct. + */ + ~NotificationDistributedOptions() = default; + + /** + * Sets whether a notification is distributed. + * @param distribute Specifies whether a notification is distributed. + */ + void SetDistributed(bool distribute); + + /** + * Checks whether a notification is distributed. + * @return true if the notification is distributed; returns false otherwise. + */ + bool IsDistributed() const; + + /** + * Sets devices that support display. + * @param devices The devices that support display. + */ + void SetDevicesSupportDisplay(const std::vector &devices); + + /** + * Obtains the devices that support display. + * @return the devices that support display. + */ + std::vector GetDevicesSupportDisplay() const; + + /** + * Sets devices that support operate. + * @param devices The devices that support operate. + */ + void SetDevicesSupportOperate(const std::vector &devices); + + /** + * Obtains the devices that support operate. + * @return the devices that support operate. + */ + std::vector GetDevicesSupportOperate() const; + + /** + * Returns a string representation of the object. + * @return a string representation of the object. + */ + std::string Dump(); + + /** + * Converts a NotificationDistributedOptions object into a Json. + * @param jsonObject Indicates the Json object. + */ + bool ToJson(nlohmann::json &jsonObject) const override; + + /** + * Creates a NotificationDistributedOptions object from a Json. + * @param jsonObject Indicates the Json object. + * @return the NotificationDistributedOptions. + */ + static NotificationDistributedOptions *FromJson(const nlohmann::json &jsonObject); + + /** + * Marshal a object into a Parcel. + * @param parcel the object into the parcel + */ + virtual bool Marshalling(Parcel &parcel) const override; + + /** + * Unmarshal object from a Parcel. + * @return the NotificationDistributedOptions + */ + static NotificationDistributedOptions *Unmarshalling(Parcel &parcel); + +private: + /** + * Read a NotificationDistributedOptions object from a Parcel. + * @param parcel the parcel + */ + bool ReadFromParcel(Parcel &parcel); + +private: + bool isDistributed_ {true}; + std::vector devicesSupportDisplay_ {}; + std::vector devicesSupportOperate_ {}; +}; +} // namespace Notification +} // namespace OHOS + +#endif // BASE_NOTIFICATION_ANS_STANDARD_NATIVE_INCLUDE_NOTIFICATION_DISTRIBUTED_OPTIONS_H \ No newline at end of file diff --git a/interfaces/innerkits/ans/native/include/notification_helper.h b/interfaces/innerkits/ans/native/include/notification_helper.h index fcf245989ab8c6eecea90106322d5863464f746b..28a20eb13c8206a9515062850b5de3ffd8276292 100644 --- a/interfaces/innerkits/ans/native/include/notification_helper.h +++ b/interfaces/innerkits/ans/native/include/notification_helper.h @@ -594,7 +594,7 @@ public: * @param doNotDisturbDate Indicates the do not disturb time to set. * @return Returns set do not disturb time result. */ - static ErrCode SetDoNotDisturbDate(const NotificationDoNotDisturbDate & doNotDisturbDate); + static ErrCode SetDoNotDisturbDate(const NotificationDoNotDisturbDate &doNotDisturbDate); /** * Obtains the do not disturb time. @@ -603,7 +603,7 @@ public: * @param doNotDisturbDate Indicates the do not disturb time to get. * @return Returns set do not disturb time result. */ - static ErrCode GetDoNotDisturbDate(NotificationDoNotDisturbDate & doNotDisturbDate); + static ErrCode GetDoNotDisturbDate(NotificationDoNotDisturbDate &doNotDisturbDate); /** * Obtains the flag that whether to support do not disturb mode. @@ -613,6 +613,56 @@ public: */ static ErrCode DoesSupportDoNotDisturbMode(bool &doesSupport); + /** + * Check if the device supports distributed notification. + * + * @param enabled True if the device supports distributed notification; false otherwise. + * @return Returns is distributed enabled result. + */ + static ErrCode IsDistributedEnabled(bool &enabled); + + /** + * Set whether the device supports distributed notifications. + * + * @param enable Specifies whether to enable the device to support distributed notification. + * The value true indicates that the device is enabled to support distributed notifications, and + * the value false indicates that the device is forbidden to support distributed notifications. + * @return Returns enable distributed result. + */ + static ErrCode EnableDistributed(const bool enabled); + + /** + * Set whether an application supports distributed notifications. + * + * @param bundleOption Indicates the bundle name and uid of an application. + * @param enabled Specifies whether to enable an application to support distributed notification. + * The value true indicates that the application is enabled to support distributed notifications, + * and the value false indicates that the application is forbidden to support distributed + * notifications. + * @return Returns enable distributed by bundle result. + */ + static ErrCode EnableDistributedByBundle(const NotificationBundleOption &bundleOption, const bool enabled); + + /** + * Set whether this application supports distributed notifications. + * + * @param enabled Specifies whether to enable this application to support distributed notification. + * The value true indicates that this application is enabled to support distributed notifications, + * and the value false indicates that this application is forbidden to support distributed + * notifications. + * @return Returns enable distributed self result. + */ + static ErrCode EnableDistributedSelf(const bool enabled); + + /** + * Check whether an application supports distributed notifications. + * + * @param bundleOption Indicates the bundle name and uid of an application. + * @param enabled True if the application supports distributed notification; false otherwise. + * @return Returns is distributed enabled by bundle result. + */ + static ErrCode IsDistributedEnableByBundle(const NotificationBundleOption &bundleOption, bool &enabled); + /** * Publishes a continuous task notification. * @param request Indicates the NotificationRequest object for setting the notification content. diff --git a/interfaces/innerkits/ans/native/include/notification_json_convert.h b/interfaces/innerkits/ans/native/include/notification_json_convert.h new file mode 100644 index 0000000000000000000000000000000000000000..2a6fb1683bcc312619b78acd7ee8851049432dd2 --- /dev/null +++ b/interfaces/innerkits/ans/native/include/notification_json_convert.h @@ -0,0 +1,97 @@ +/* + * 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 BASE_NOTIFICATION_ANS_STANDARD_NOTIFICATION_JSON_CONVERT_H +#define BASE_NOTIFICATION_ANS_STANDARD_NOTIFICATION_JSON_CONVERT_H + +#include +#include "ans_log_wrapper.h" +#include "nlohmann/json.hpp" + +namespace OHOS { +namespace Notification { +class NotificationJsonConvertionBase { +public: + /** + * Default deconstructor used to deconstruct. + */ + virtual ~NotificationJsonConvertionBase() = default; + + virtual bool ToJson(nlohmann::json &jsonObject) const = 0; +}; + +class NotificationJsonConverter { +public: + /** + * Convert NotificationJsonConvertionBase object to json object. + */ + static bool ConvertToJosn(const NotificationJsonConvertionBase *convertionBase, nlohmann::json &jsonObject) + { + if (convertionBase == nullptr) { + ANS_LOGE("Converter : Invalid base object"); + return false; + } + + return convertionBase->ToJson(jsonObject); + } + + static bool ConvertToJosnString(const NotificationJsonConvertionBase *convertionBase, std::string &jsonString) + { + if (convertionBase == nullptr) { + ANS_LOGE("Converter : Invalid base object"); + return false; + } + + nlohmann::json jsonObject; + if (!convertionBase->ToJson(jsonObject)) { + ANS_LOGE("Converter : Cannot convert to JSON object"); + return false; + } + jsonString = jsonObject.dump(); + + return true; + } + + template + static T *ConvertFromJosn(const nlohmann::json &jsonObject) + { + if (jsonObject.is_null() or !jsonObject.is_object()) { + ANS_LOGE("Converter : Invalid JSON object"); + return nullptr; + } + + return T::FromJson(jsonObject); + } + + template + static T *ConvertFromJosnString(const std::string &jsonString) + { + if (jsonString.empty()) { + ANS_LOGE("Converter : Invalid JSON string"); + return nullptr; + } + + auto jsonObject = nlohmann::json::parse(jsonString); + if (jsonObject.is_null() or !jsonObject.is_object()) { + ANS_LOGE("Converter : Invalid JSON object"); + return nullptr; + } + + return T::FromJson(jsonObject); + } +}; +} // namespace Notification +} // namespace OHOS + +#endif // BASE_NOTIFICATION_ANS_STANDARD_NOTIFICATION_JSON_CONVERT_H diff --git a/interfaces/innerkits/ans/native/include/notification_long_text_content.h b/interfaces/innerkits/ans/native/include/notification_long_text_content.h index c6ffcb67094d159821bb27cf0af427ee6ea3f0b3..85d50017f84f8e10d128657851d052742b5bbabd 100644 --- a/interfaces/innerkits/ans/native/include/notification_long_text_content.h +++ b/interfaces/innerkits/ans/native/include/notification_long_text_content.h @@ -86,6 +86,19 @@ public: */ std::string Dump() override; + /** + * Converts a NotificationLongTextContent object into a Json. + * @param jsonObject Indicates the Json object. + */ + bool ToJson(nlohmann::json &jsonObject) const override; + + /** + * Creates a NotificationLongTextContent object from a Json. + * @param jsonObject Indicates the Json object. + * @return the NotificationLongTextContent. + */ + static NotificationLongTextContent *FromJson(const nlohmann::json &jsonObject); + /** * Marshal a object into a Parcel. * @param parcel the object into the parcel diff --git a/interfaces/innerkits/ans/native/include/notification_media_content.h b/interfaces/innerkits/ans/native/include/notification_media_content.h index 54d90d2c9d13e4d4a3505389827b66ed4a28a170..5044fa89b3206b7065a85fb4e9d0d288523773fd 100644 --- a/interfaces/innerkits/ans/native/include/notification_media_content.h +++ b/interfaces/innerkits/ans/native/include/notification_media_content.h @@ -76,6 +76,19 @@ public: */ std::string Dump() override; + /** + * Converts a NotificationMediaContent object into a Json. + * @param jsonObject Indicates the Json object. + */ + virtual bool ToJson(nlohmann::json &jsonObject) const override; + + /** + * Creates a NotificationMediaContent object from a Json. + * @param jsonObject Indicates the Json object. + * @return the NotificationMediaContent. + */ + static NotificationMediaContent *FromJson(const nlohmann::json &jsonObject); + /** * Marshal a object into a Parcel. * @param parcel the object into the parcel diff --git a/interfaces/innerkits/ans/native/include/notification_multiline_content.h b/interfaces/innerkits/ans/native/include/notification_multiline_content.h index a3d216fbeb95c05c4a681eb1efa08bc6c42a49e6..7f0e91655289d225592102ec49b8f7aab7f5eeef 100644 --- a/interfaces/innerkits/ans/native/include/notification_multiline_content.h +++ b/interfaces/innerkits/ans/native/include/notification_multiline_content.h @@ -83,6 +83,19 @@ public: */ std::string Dump() override; + /** + * Converts a NotificationMultiLineContent object into a Json. + * @param jsonObject Indicates the Json object. + */ + virtual bool ToJson(nlohmann::json &jsonObject) const override; + + /** + * Creates a NotificationMultiLineContent object from a Json. + * @param jsonObject Indicates the Json object. + * @return the NotificationMultiLineContent. + */ + static NotificationMultiLineContent *FromJson(const nlohmann::json &jsonObject); + /** * Marshal a object into a Parcel. * @param parcel the object into the parcel diff --git a/interfaces/innerkits/ans/native/include/notification_normal_content.h b/interfaces/innerkits/ans/native/include/notification_normal_content.h index cae7525ec99581b5b94497e9710d54d22421037e..6bd04ae5760fe620eef0b390e610229eb6da2403 100644 --- a/interfaces/innerkits/ans/native/include/notification_normal_content.h +++ b/interfaces/innerkits/ans/native/include/notification_normal_content.h @@ -39,6 +39,19 @@ public: */ std::string Dump() override; + /** + * Converts a NotificationNormalContent object into a Json. + * @param jsonObject Indicates the Json object. + */ + bool ToJson(nlohmann::json &jsonObject) const override; + + /** + * Creates a NotificationNormalContent object from a Json. + * @param jsonObject Indicates the Json object. + * @return the NotificationNormalContent. + */ + static NotificationNormalContent *FromJson(const nlohmann::json &jsonObject); + /** * Marshal a object into a Parcel. * @param parcel the object into the parcel diff --git a/interfaces/innerkits/ans/native/include/notification_picture_content.h b/interfaces/innerkits/ans/native/include/notification_picture_content.h index df45286fef25a82c062a089df7612ff49cef20bf..8ed0dc54b0824b45ae92a1c2dbbd0453f8c51366 100644 --- a/interfaces/innerkits/ans/native/include/notification_picture_content.h +++ b/interfaces/innerkits/ans/native/include/notification_picture_content.h @@ -82,6 +82,19 @@ public: */ std::string Dump() override; + /** + * Converts a NotificationPictureContent object into a Json. + * @param jsonObject Indicates the Json object. + */ + virtual bool ToJson(nlohmann::json &jsonObject) const override; + + /** + * Creates a NotificationPictureContent object from a Json. + * @param jsonObject Indicates the Json object. + * @return the NotificationPictureContent. + */ + static NotificationPictureContent *FromJson(const nlohmann::json &jsonObject); + /** * Marshal a object into a Parcel. * @param parcel the object into the parcel diff --git a/interfaces/innerkits/ans/native/include/notification_request.h b/interfaces/innerkits/ans/native/include/notification_request.h index f5efaff822a3a626cde897cb90617fab38a5b1aa..c7f59f8e3790574b99132acd95facad6d6dff207 100644 --- a/interfaces/innerkits/ans/native/include/notification_request.h +++ b/interfaces/innerkits/ans/native/include/notification_request.h @@ -20,6 +20,8 @@ #include "message_user.h" #include "notification_action_button.h" #include "notification_content.h" +#include "notification_distributed_options.h" +#include "notification_json_convert.h" #include "notification_template.h" #include "ohos/aafwk/content/want_params.h" #include "parcel.h" @@ -28,7 +30,7 @@ namespace OHOS { namespace Notification { -class NotificationRequest : public Parcelable { +class NotificationRequest : public Parcelable, public NotificationJsonConvertionBase { public: enum class BadgeStyle { /** @@ -843,6 +845,30 @@ public: */ std::string GetLabel() const; + /** + * Sets whether this notification is distributed. + * @param distribute Specifies whether a notification is displayed as a floating icon on top of the screen. + */ + void SetDistributed(bool distribute); + + /** + * Sets devices that support display. + * @param devices The devices that support display. + */ + void SetDevicesSupportDisplay(const std::vector &devices); + + /** + * Sets devices that support operate. + * @param devices The devices that support operate. + */ + void SetDevicesSupportOperate(const std::vector &devices); + + /** + * Obtains the distributed Options. + * @return the distributed Options. + */ + NotificationDistributedOptions GetNotificationDistributedOptions() const; + /** * Sets the UserId of the notification creator. * @param userId the UserId of the notification creator. @@ -861,6 +887,19 @@ public: */ std::string Dump(); + /** + * Converts a NotificationRequest object into a Json. + * @param jsonObject Indicates the Json object. + */ + bool ToJson(nlohmann::json &jsonObject) const override; + + /** + * Creates a NotificationRequest object from a Json. + * @param jsonObject Indicates the Json object. + * @return the NotificationRequest. + */ + static NotificationRequest *FromJson(const nlohmann::json &jsonObject); + /** * Marshal a NotificationRequest object into a Parcel. * @param parcel the object into the parcel @@ -914,6 +953,21 @@ private: */ int64_t GetNowSysTime(); + void CopyBase(const NotificationRequest &other); + void CopyOther(const NotificationRequest &other); + + bool ConvertObjectsToJson(nlohmann::json &jsonObject) const; + + static void ConvertJsonToNum(NotificationRequest *target, const nlohmann::json &jsonObject); + static void ConvertJsonToString(NotificationRequest *target, const nlohmann::json &jsonObject); + static void ConvertJsonToEnum(NotificationRequest *target, const nlohmann::json &jsonObject); + static void ConvertJsonToBool(NotificationRequest *target, const nlohmann::json &jsonObject); + static void ConvertJsonToPixelMap(NotificationRequest *target, const nlohmann::json &jsonObject); + static bool ConvertJsonToNotificationContent(NotificationRequest *target, const nlohmann::json &jsonObject); + static bool ConvertJsonToNotificationActionButton(NotificationRequest *target, const nlohmann::json &jsonObject); + static bool ConvertJsonToNotificationDistributedOptions( + NotificationRequest *target, const nlohmann::json &jsonObject); + private: int32_t notificationId_ {0}; uint32_t color_ {NotificationRequest::COLOR_DEFAULT}; @@ -971,6 +1025,9 @@ private: std::vector> actionButtons_ {}; std::vector> messageUsers_ {}; std::vector userInputHistory_ {}; + + NotificationDistributedOptions distributedOptions_; + std::shared_ptr notificationTemplate_ {}; }; } // namespace Notification diff --git a/interfaces/innerkits/ans/native/include/notification_sorting.h b/interfaces/innerkits/ans/native/include/notification_sorting.h index cc02e7447e2a2aa7593d478f7feb1562ad496230..ca38d5bb09ccea4d0923959d94e70de2bc0aa396 100644 --- a/interfaces/innerkits/ans/native/include/notification_sorting.h +++ b/interfaces/innerkits/ans/native/include/notification_sorting.h @@ -171,7 +171,7 @@ private: bool isHiddenNotification_ {}; std::string groupKeyOverride_ {}; int32_t visiblenessOverride_ {}; - sptr slot_ = new NotificationSlot(NotificationConstant::SlotType::OTHER); + sptr slot_ = new (std::nothrow) NotificationSlot(NotificationConstant::SlotType::OTHER); friend class AdvancedNotificationService; }; diff --git a/interfaces/innerkits/ans/native/include/notification_user_input.h b/interfaces/innerkits/ans/native/include/notification_user_input.h index e432cd2e0768d74a8f02ab4164786747caece9b3..2e68134dcd223b881947c9a6d78c73872d89f8cf 100644 --- a/interfaces/innerkits/ans/native/include/notification_user_input.h +++ b/interfaces/innerkits/ans/native/include/notification_user_input.h @@ -17,13 +17,14 @@ #define BASE_NOTIFICATION_ANS_STANDARD_KITS_NATIVE_INCLUDE_NOTIFICATION_USER_INPUT_H #include "notification_constant.h" +#include "notification_json_convert.h" #include "parcel.h" #include "uri.h" #include "want.h" namespace OHOS { namespace Notification { -class NotificationUserInput : public Parcelable { +class NotificationUserInput : public Parcelable, public NotificationJsonConvertionBase { public: /** * Sets the input source of this NotificationUserInput object. @@ -213,6 +214,19 @@ public: */ std::string Dump(); + /** + * Converts a NotificationUserInput object into a Json. + * @param jsonObject Indicates the Json object. + */ + bool ToJson(nlohmann::json &jsonObject) const override; + + /** + * Creates a NotificationUserInput object from a Json. + * @param jsonObject Indicates the Json object. + * @return the NotificationUserInput. + */ + static NotificationUserInput *FromJson(const nlohmann::json &jsonObject); + /** * Marshal a object into a Parcel. * @param parcel the object into the parcel diff --git a/interfaces/innerkits/wantagent/include/pending_want.h b/interfaces/innerkits/wantagent/include/pending_want.h index 1db00b77371e1da6b914b40802f47b1fddb5a791..4f034279f0a0c4086373f13c8e8bafa4ce37683f 100644 --- a/interfaces/innerkits/wantagent/include/pending_want.h +++ b/interfaces/innerkits/wantagent/include/pending_want.h @@ -247,6 +247,8 @@ public: std::shared_ptr GetWant(const sptr &target); + std::shared_ptr GetWantSenderInfo(const sptr &target); + private: std::mutex lock_object; sptr target_; diff --git a/interfaces/innerkits/wantagent/include/want_agent_helper.h b/interfaces/innerkits/wantagent/include/want_agent_helper.h index 7f3027fcf9def508e20cecbaf1bbb978d84a4209..56e554f2dd697717c6b9cd23d0e3ebb6a6a8171f 100644 --- a/interfaces/innerkits/wantagent/include/want_agent_helper.h +++ b/interfaces/innerkits/wantagent/include/want_agent_helper.h @@ -22,6 +22,7 @@ #include "completed_callback.h" #include "completed_dispatcher.h" #include "event_handler.h" +#include "nlohmann/json.hpp" #include "trigger_info.h" #include "want.h" #include "want_agent.h" @@ -162,7 +163,23 @@ public: */ static void UnregisterCancelListener( const std::shared_ptr &cancelListener, const std::shared_ptr &agent); - + + /** + * Convert WantAgentInfo object to json string. + * + * @param jsonObject Json object. + * @return WantAgentInfo object's json string. + */ + static std::string ToString(const std::shared_ptr &agent); + + /** + * Convert json string to WantAgentInfo object. + * + * @param jsonString Json string. + * @return WantAgentInfo object. + */ + static std::shared_ptr FromString(const std::string &jsonString); + private: WantAgentHelper(); virtual ~WantAgentHelper() = default; diff --git a/interfaces/kits/napi/ans/BUILD.gn b/interfaces/kits/napi/ans/BUILD.gn index 3bd0904973996400cfa42fb2ea78f73df334b3f3..90ada22d6193b906888ed972a220609ec4414107 100644 --- a/interfaces/kits/napi/ans/BUILD.gn +++ b/interfaces/kits/napi/ans/BUILD.gn @@ -39,6 +39,7 @@ ohos_shared_library("notification") { "include", "//third_party/node/src", "//third_party/libuv/include", + "//third_party/json/single_include", "//third_party/jsoncpp/include", ] @@ -50,6 +51,7 @@ ohos_shared_library("notification") { "src/common.cpp", "src/constant.cpp", "src/display_badge.cpp", + "src/distributed.cpp", "src/disturb_mode.cpp", "src/enable_notification.cpp", "src/get_active.cpp", diff --git a/interfaces/kits/napi/ans/include/common.h b/interfaces/kits/napi/ans/include/common.h index 4f202eb0b9dca4f7197d267afee50ceff382fa4e..5cfe78720e1bc024b8d4cc43381a8190c420fbef 100644 --- a/interfaces/kits/napi/ans/include/common.h +++ b/interfaces/kits/napi/ans/include/common.h @@ -119,11 +119,6 @@ struct NotificationSubscribeInfo { bool hasSubscribeInfo = false; }; -struct BundleOption { - std::string bundle {}; - int uid {}; -}; - struct NotificationKey { int id {}; std::string label {}; @@ -186,6 +181,9 @@ public: static napi_value SetNotificationRequestByCustom( const napi_env &env, const OHOS::Notification::NotificationRequest *request, napi_value &result); + static napi_value SetNotificationByDistributedOptions( + const napi_env &env, const OHOS::Notification::Notification *notification, napi_value &result); + static napi_value SetNotificationSortingMap( const napi_env &env, const std::shared_ptr &sortingMap, napi_value &result); @@ -328,6 +326,15 @@ public: static napi_value GetNotificationLargeIcon( const napi_env &env, const napi_value &value, NotificationRequest &request); + static napi_value GetNotificationRequestDistributedOptions( + const napi_env &env, const napi_value &value, NotificationRequest &request); + static napi_value GetNotificationIsDistributed( + const napi_env &env, const napi_value &value, NotificationRequest &request); + static napi_value GetNotificationSupportDisplayDevices( + const napi_env &env, const napi_value &value, NotificationRequest &request); + static napi_value GetNotificationSupportOperateDevices( + const napi_env &env, const napi_value &value, NotificationRequest &request); + static napi_value GetNotificationContentType(const napi_env &env, const napi_value &result, int32_t &type); static napi_value GetNotificationBasicContent( const napi_env &env, const napi_value &result, NotificationRequest &request); diff --git a/interfaces/kits/napi/ans/include/distributed.h b/interfaces/kits/napi/ans/include/distributed.h new file mode 100644 index 0000000000000000000000000000000000000000..2beab5b76992627fde0907fdb05265687e34ac9d --- /dev/null +++ b/interfaces/kits/napi/ans/include/distributed.h @@ -0,0 +1,33 @@ +/* + * 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 BASE_NOTIFICATION_ANS_STANDARD_KITS_NAPI_INCLUDE_DISTRIBUTED_H +#define BASE_NOTIFICATION_ANS_STANDARD_KITS_NAPI_INCLUDE_DISTRIBUTED_H + +#include "common.h" + +namespace OHOS { +namespace NotificationNapi { +using namespace OHOS::Notification; + +napi_value IsDistributedEnabled(napi_env env, napi_callback_info info); +napi_value EnableDistributed(napi_env env, napi_callback_info info); +napi_value EnableDistributedByBundle(napi_env env, napi_callback_info info); +napi_value EnableDistributedSelf(napi_env env, napi_callback_info info); +napi_value IsDistributedEnableByBundle(napi_env env, napi_callback_info info); +} // namespace NotificationNapi +} // namespace OHOS + +#endif // BASE_NOTIFICATION_ANS_STANDARD_KITS_NAPI_INCLUDE_DISTRIBUTED_H \ No newline at end of file diff --git a/interfaces/kits/napi/ans/src/common.cpp b/interfaces/kits/napi/ans/src/common.cpp index 2864281d6a025a9f0b488091ac35f251e96bfb0e..8849e7e610c21a8354a5f2d4239725b9725944f1 100644 --- a/interfaces/kits/napi/ans/src/common.cpp +++ b/interfaces/kits/napi/ans/src/common.cpp @@ -162,6 +162,52 @@ napi_value Common::ParseParaOnlyCallback(const napi_env &env, const napi_callbac return Common::NapiGetNull(env); } +napi_value Common::SetNotificationByDistributedOptions( + const napi_env &env, const OHOS::Notification::Notification *notification, napi_value &result) +{ + ANS_LOGI("enter"); + if (notification == nullptr) { + ANS_LOGE("notification is nullptr"); + return NapiGetBoolean(env, false); + } + + NotificationDistributedOptions options = notification->GetNotificationRequest().GetNotificationDistributedOptions(); + napi_value value = nullptr; + // isDistributed?: boolean + napi_get_boolean(env, options.IsDistributed(), &value); + napi_set_named_property(env, result, "isDistributed", value); + + // supportDisplayDevices?: Array + int count = 0; + napi_value arrSupportDisplayDevices = nullptr; + napi_create_array(env, &arrSupportDisplayDevices); + std::vector displayDevices = options.GetDevicesSupportDisplay(); + for (auto vec : displayDevices) { + napi_value vecValue = nullptr; + ANS_LOGI("supportDisplayDevices = %{public}s", vec.c_str()); + napi_create_string_utf8(env, vec.c_str(), NAPI_AUTO_LENGTH, &vecValue); + napi_set_element(env, arrSupportDisplayDevices, count, vecValue); + count ++; + } + napi_set_named_property(env, result, "supportDisplayDevices", arrSupportDisplayDevices); + + // supportOperateDevices?: Array + count = 0; + napi_value arrSupportOperateDevices = nullptr; + napi_create_array(env, &arrSupportOperateDevices); + std::vector operateDevices = options.GetDevicesSupportOperate(); + for (auto vec : operateDevices) { + napi_value vecValue = nullptr; + ANS_LOGI("supportOperateDevices = %{public}s", vec.c_str()); + napi_create_string_utf8(env, vec.c_str(), NAPI_AUTO_LENGTH, &vecValue); + napi_set_element(env, arrSupportOperateDevices, count, vecValue); + count ++; + } + napi_set_named_property(env, result, "supportOperateDevices", arrSupportOperateDevices); + + return NapiGetBoolean(env, true); +} + napi_value Common::SetNotification( const napi_env &env, const OHOS::Notification::Notification *notification, napi_value &result) { @@ -197,6 +243,14 @@ napi_value Common::SetNotification( napi_create_int32(env, notification->GetPid(), &value); napi_set_named_property(env, result, "creatorPid", value); + // distributedOption?:DistributedOptions + napi_value distributedResult = nullptr; + napi_create_object(env, &distributedResult); + if (!SetNotificationByDistributedOptions(env, notification, distributedResult)) { + return NapiGetBoolean(env, false); + } + napi_set_named_property(env, result, "distributedOption", distributedResult); + // readonly isRemoveAllowed?: boolean napi_get_boolean(env, notification->IsRemoveAllowed(), &value); napi_set_named_property(env, result, "isRemoveAllowed", value); @@ -209,6 +263,10 @@ napi_value Common::SetNotification( napi_create_int32(env, (int32_t)sourceType, &value); napi_set_named_property(env, result, "source", value); + // readonly deviceId?: string + napi_create_string_utf8(env, notification->GetDeviceId().c_str(), NAPI_AUTO_LENGTH, &value); + napi_set_named_property(env, result, "deviceId", value); + return NapiGetBoolean(env, true); } @@ -1420,6 +1478,10 @@ napi_value Common::GetNotificationRequestByCustom( if (GetNotificationLargeIcon(env, value, request) == nullptr) { return nullptr; } + // distributedOption?:DistributedOptions + if (GetNotificationRequestDistributedOptions(env, value, request) == nullptr) { + return nullptr; + } // template?: NotificationTemplate if (GetNotificationTemplate(env, value, request) == nullptr) { return nullptr; @@ -2461,6 +2523,127 @@ napi_value Common::GetNotificationLargeIcon(const napi_env &env, const napi_valu return NapiGetNull(env); } +napi_value Common::GetNotificationRequestDistributedOptions(const napi_env &env, + const napi_value &value, NotificationRequest &request) +{ + ANS_LOGI("enter"); + napi_valuetype valuetype = napi_undefined; + napi_value result = nullptr; + bool hasProperty = false; + + // distributedOption?: DistributedOptions + NAPI_CALL(env, napi_has_named_property(env, value, "distributedOption", &hasProperty)); + if (hasProperty) { + napi_get_named_property(env, value, "distributedOption", &result); + NAPI_CALL(env, napi_typeof(env, result, &valuetype)); + NAPI_ASSERT(env, valuetype == napi_object, "Wrong argument type. Object expected."); + + // isDistributed?: boolean + if (GetNotificationIsDistributed(env, result, request) == nullptr) { + return nullptr; + } + + // supportDisplayDevices?: Array + if (GetNotificationSupportDisplayDevices(env, result, request) == nullptr) { + return nullptr; + } + + // supportOperateDevices?: Array + if (GetNotificationSupportOperateDevices(env, result, request) == nullptr) { + return nullptr; + } + } + + return NapiGetNull(env); +} + +napi_value Common::GetNotificationIsDistributed( + const napi_env &env, const napi_value &value, NotificationRequest &request) +{ + ANS_LOGI("enter"); + + napi_valuetype valuetype = napi_undefined; + napi_value result = nullptr; + bool hasProperty = false; + bool isDistributed = false; + + NAPI_CALL(env, napi_has_named_property(env, value, "isDistributed", &hasProperty)); + if (hasProperty) { + napi_get_named_property(env, value, "isDistributed", &result); + NAPI_CALL(env, napi_typeof(env, result, &valuetype)); + NAPI_ASSERT(env, valuetype == napi_boolean, "Wrong argument type. Bool expected."); + napi_get_value_bool(env, result, &isDistributed); + request.SetDistributed(isDistributed); + } + + return NapiGetNull(env); +} + +napi_value Common::GetNotificationSupportDisplayDevices( + const napi_env &env, const napi_value &value, NotificationRequest &request) +{ + ANS_LOGI("enter"); + + bool isArray = false; + napi_valuetype valuetype = napi_undefined; + napi_value supportDisplayDevices = nullptr; + char str[STR_MAX_SIZE] = {0}; + size_t strLen = 0; + uint32_t length = 0; + + napi_get_named_property(env, value, "supportDisplayDevices", &supportDisplayDevices); + napi_is_array(env, supportDisplayDevices, &isArray); + NAPI_ASSERT(env, isArray, "Property supportDisplayDevices is expected to be an array."); + + napi_get_array_length(env, supportDisplayDevices, &length); + NAPI_ASSERT(env, length > 0, "The array is empty."); + std::vector devices; + for (size_t i = 0; i < length; i++) { + napi_value line = nullptr; + napi_get_element(env, supportDisplayDevices, i, &line); + NAPI_CALL(env, napi_typeof(env, line, &valuetype)); + NAPI_ASSERT(env, valuetype == napi_string, "Wrong argument type. String expected."); + NAPI_CALL(env, napi_get_value_string_utf8(env, line, str, STR_MAX_SIZE - 1, &strLen)); + devices.emplace_back(str); + ANS_LOGI("supportDisplayDevices = %{public}s", str); + } + request.SetDevicesSupportDisplay(devices); + return NapiGetNull(env); +} + +napi_value Common::GetNotificationSupportOperateDevices( + const napi_env &env, const napi_value &value, NotificationRequest &request) +{ + ANS_LOGI("enter"); + + bool isArray = false; + napi_valuetype valuetype = napi_undefined; + napi_value supportOperateDevices = nullptr; + char str[STR_MAX_SIZE] = {0}; + size_t strLen = 0; + uint32_t length = 0; + + napi_get_named_property(env, value, "supportOperateDevices", &supportOperateDevices); + napi_is_array(env, supportOperateDevices, &isArray); + NAPI_ASSERT(env, isArray, "Property supportOperateDevices is expected to be an array."); + + napi_get_array_length(env, supportOperateDevices, &length); + NAPI_ASSERT(env, length > 0, "The array is empty."); + std::vector devices; + for (size_t i = 0; i < length; i++) { + napi_value line = nullptr; + napi_get_element(env, supportOperateDevices, i, &line); + NAPI_CALL(env, napi_typeof(env, line, &valuetype)); + NAPI_ASSERT(env, valuetype == napi_string, "Wrong argument type. String expected."); + NAPI_CALL(env, napi_get_value_string_utf8(env, line, str, STR_MAX_SIZE - 1, &strLen)); + devices.emplace_back(str); + ANS_LOGI("supportOperateDevices = %{public}s", str); + } + request.SetDevicesSupportOperate(devices); + + return NapiGetNull(env); +} + napi_value Common::GetNotificationContentType(const napi_env &env, const napi_value &result, int32_t &type) { ANS_LOGI("enter"); diff --git a/interfaces/kits/napi/ans/src/display_badge.cpp b/interfaces/kits/napi/ans/src/display_badge.cpp index 737e6403c428bb2ff5e34b26e04d6fa8ad50eeb3..3484b24e96db82e73b3525b078b89f5719060ca0 100644 --- a/interfaces/kits/napi/ans/src/display_badge.cpp +++ b/interfaces/kits/napi/ans/src/display_badge.cpp @@ -20,6 +20,7 @@ namespace NotificationNapi { const int ENABLE_BADGE_DISPLAYED_MAX_PARA = 3; const int ENABLE_BADGE_DISPLAYED_MIN_PARA = 2; const int IS_DISPLAY_BADGE_MAX_PARA = 2; +const int IS_DISPLAY_BADGE_MIN_PARA = 1; struct EnableBadgeParams { NotificationBundleOption option; @@ -91,10 +92,7 @@ napi_value ParseParameters(const napi_env &env, const napi_callback_info &info, napi_value argv[IS_DISPLAY_BADGE_MAX_PARA] = {nullptr}; napi_value thisVar = nullptr; NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL)); - - if (argc == 0) { - return Common::NapiGetNull(env); - } + NAPI_ASSERT(env, argc >= IS_DISPLAY_BADGE_MIN_PARA, "Wrong number of arguments"); // argv[0]: bundle / callback napi_valuetype valuetype = napi_undefined; diff --git a/interfaces/kits/napi/ans/src/distributed.cpp b/interfaces/kits/napi/ans/src/distributed.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5739891f18a8b905c2e091edbe93ae8172835fce --- /dev/null +++ b/interfaces/kits/napi/ans/src/distributed.cpp @@ -0,0 +1,489 @@ +/* + * 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 "distributed.h" + +namespace OHOS { +namespace NotificationNapi { +const int ENABLED_MAX_PARA = 2; +const int ENABLED_MIN_PARA = 1; +const int ENABLED_BUNDLE_MAX_PARA = 3; +const int ENABLED_BUNDLE_MIN_PARA = 2; +const int IS_ENABLED_BUNDLE_MAX_PARA = 2; +const int IS_ENABLED_BUNDLE_MIN_PARA = 1; + +struct AsyncCallbackInfoIsEnabled { + napi_env env = nullptr; + napi_async_work asyncWork = nullptr; + CallbackPromiseInfo info; + bool enable = false; +}; + +struct EnabledParams { + napi_ref callback = nullptr; + bool enable = false; +}; + +struct AsyncCallbackInfoEnabled { + napi_env env = nullptr; + napi_async_work asyncWork = nullptr; + CallbackPromiseInfo info; + EnabledParams params; +}; + +struct EnabledByBundleParams { + NotificationBundleOption option; + napi_ref callback = nullptr; + bool enable = false; +}; + +struct AsyncCallbackInfoEnabledByBundle { + napi_env env = nullptr; + napi_async_work asyncWork = nullptr; + CallbackPromiseInfo info; + EnabledByBundleParams params; +}; + +struct IsEnabledByBundleParams { + NotificationBundleOption option; + napi_ref callback = nullptr; +}; + +struct AsyncCallbackInfoIsEnabledByBundle { + napi_env env = nullptr; + napi_async_work asyncWork = nullptr; + CallbackPromiseInfo info; + IsEnabledByBundleParams params; + bool enable = false; +}; + +napi_value ParseParameters(const napi_env &env, const napi_callback_info &info, EnabledParams ¶ms) +{ + ANS_LOGI("enter"); + + size_t argc = ENABLED_MAX_PARA; + napi_value argv[ENABLED_MAX_PARA] = {nullptr}; + napi_value thisVar = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL)); + NAPI_ASSERT(env, argc >= ENABLED_MIN_PARA, "Wrong number of arguments"); + napi_valuetype valuetype = napi_undefined; + + // argv[0]: enable + NAPI_CALL(env, napi_typeof(env, argv[PARAM0], &valuetype)); + NAPI_ASSERT(env, valuetype == napi_boolean, "Wrong argument type. Bool expected."); + napi_get_value_bool(env, argv[PARAM0], ¶ms.enable); + + // argv[1]:callback + if (argc >= ENABLED_MAX_PARA) { + NAPI_CALL(env, napi_typeof(env, argv[PARAM1], &valuetype)); + NAPI_ASSERT(env, valuetype == napi_function, "Wrong argument type. Function expected."); + napi_create_reference(env, argv[PARAM1], 1, ¶ms.callback); + } + + return Common::NapiGetNull(env); +} + +napi_value ParseParameters(const napi_env &env, const napi_callback_info &info, EnabledByBundleParams ¶ms) +{ + ANS_LOGI("enter"); + + size_t argc = ENABLED_BUNDLE_MAX_PARA; + napi_value argv[ENABLED_BUNDLE_MAX_PARA] = {nullptr}; + napi_value thisVar = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL)); + NAPI_ASSERT(env, argc >= ENABLED_BUNDLE_MIN_PARA, "Wrong number of arguments"); + + // argv[0]: bundle + napi_valuetype valuetype = napi_undefined; + NAPI_CALL(env, napi_typeof(env, argv[PARAM0], &valuetype)); + NAPI_ASSERT(env, valuetype == napi_object, "Wrong argument type. Object expected."); + auto retValue = Common::GetBundleOption(env, argv[PARAM0], params.option); + if (retValue == nullptr) { + ANS_LOGE("GetBundleOption failed."); + return nullptr; + } + + // argv[1]: enable + NAPI_CALL(env, napi_typeof(env, argv[PARAM1], &valuetype)); + NAPI_ASSERT(env, valuetype == napi_boolean, "Wrong argument type. Bool expected."); + napi_get_value_bool(env, argv[PARAM1], ¶ms.enable); + + // argv[2]:callback + if (argc >= ENABLED_BUNDLE_MAX_PARA) { + napi_valuetype valuetype = napi_undefined; + NAPI_CALL(env, napi_typeof(env, argv[PARAM2], &valuetype)); + NAPI_ASSERT(env, valuetype == napi_function, "Wrong argument type. Function expected."); + napi_create_reference(env, argv[PARAM2], 1, ¶ms.callback); + } + + return Common::NapiGetNull(env); +} + +napi_value ParseParameters(const napi_env &env, const napi_callback_info &info, IsEnabledByBundleParams ¶ms) +{ + ANS_LOGI("enter"); + + size_t argc = IS_ENABLED_BUNDLE_MAX_PARA; + napi_value argv[IS_ENABLED_BUNDLE_MAX_PARA] = {nullptr}; + napi_value thisVar = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL)); + NAPI_ASSERT(env, argc >= IS_ENABLED_BUNDLE_MIN_PARA, "Wrong number of arguments"); + + // argv[0]: bundle + napi_valuetype valuetype = napi_undefined; + NAPI_CALL(env, napi_typeof(env, argv[PARAM0], &valuetype)); + NAPI_ASSERT(env, valuetype == napi_object, "Wrong argument type. Object expected."); + auto retValue = Common::GetBundleOption(env, argv[PARAM0], params.option); + if (retValue == nullptr) { + ANS_LOGE("GetBundleOption failed."); + return nullptr; + } + + // argv[1]:callback + if (argc >= IS_ENABLED_BUNDLE_MAX_PARA) { + napi_valuetype valuetype = napi_undefined; + NAPI_CALL(env, napi_typeof(env, argv[PARAM1], &valuetype)); + NAPI_ASSERT(env, valuetype == napi_function, "Wrong argument type. Function expected."); + napi_create_reference(env, argv[PARAM1], 1, ¶ms.callback); + } + + return Common::NapiGetNull(env); +} + +void AsyncCompleteCallbackIsDistributedEnabled(napi_env env, napi_status status, void *data) +{ + ANS_LOGI("enter"); + if (!data) { + ANS_LOGE("Invalid async callback data"); + return; + } + ANS_LOGI("IsDistributedEnabled napi_create_async_work end"); + AsyncCallbackInfoIsEnabled *asynccallbackinfo = (AsyncCallbackInfoIsEnabled *)data; + napi_value result = nullptr; + if (asynccallbackinfo->info.errorCode != ERR_OK) { + result = Common::NapiGetNull(env); + } else { + napi_get_boolean(env, asynccallbackinfo->enable, &result); + } + + Common::ReturnCallbackPromise(env, asynccallbackinfo->info, result); + + if (asynccallbackinfo->info.callback != nullptr) { + napi_delete_reference(env, asynccallbackinfo->info.callback); + } + + napi_delete_async_work(env, asynccallbackinfo->asyncWork); + if (asynccallbackinfo) { + delete asynccallbackinfo; + asynccallbackinfo = nullptr; + } +} + +napi_value IsDistributedEnabled(napi_env env, napi_callback_info info) +{ + ANS_LOGI("enter"); + + napi_ref callback = nullptr; + if (Common::ParseParaOnlyCallback(env, info, callback) == nullptr) { + return Common::NapiGetUndefined(env); + } + + AsyncCallbackInfoIsEnabled *asynccallbackinfo = + new (std::nothrow) AsyncCallbackInfoIsEnabled {.env = env, .asyncWork = nullptr}; + if (!asynccallbackinfo) { + return Common::JSParaError(env, callback); + } + napi_value promise = nullptr; + Common::PaddingCallbackPromiseInfo(env, callback, asynccallbackinfo->info, promise); + + napi_value resourceName = nullptr; + napi_create_string_latin1(env, "isDistributedEnabled", NAPI_AUTO_LENGTH, &resourceName); + // Asynchronous function call + napi_create_async_work( + env, + nullptr, + resourceName, + [](napi_env env, void *data) { + ANS_LOGI("IsDistributedEnabled napi_create_async_work start"); + AsyncCallbackInfoIsEnabled *asynccallbackinfo = (AsyncCallbackInfoIsEnabled *)data; + + asynccallbackinfo->info.errorCode = + NotificationHelper::IsDistributedEnabled(asynccallbackinfo->enable); + ANS_LOGI("IsDistributedEnabled enable = %{public}d", asynccallbackinfo->enable); + }, + AsyncCompleteCallbackIsDistributedEnabled, + (void *)asynccallbackinfo, + &asynccallbackinfo->asyncWork); + + NAPI_CALL(env, napi_queue_async_work(env, asynccallbackinfo->asyncWork)); + + if (asynccallbackinfo->info.isCallback) { + return Common::NapiGetNull(env); + } else { + return promise; + } +} + +napi_value EnableDistributed(napi_env env, napi_callback_info info) +{ + ANS_LOGI("enter"); + + EnabledParams params {}; + if (ParseParameters(env, info, params) == nullptr) { + return Common::NapiGetUndefined(env); + } + + AsyncCallbackInfoEnabled *asynccallbackinfo = + new (std::nothrow) AsyncCallbackInfoEnabled {.env = env, .asyncWork = nullptr, .params = params}; + if (!asynccallbackinfo) { + return Common::JSParaError(env, params.callback); + } + napi_value promise = nullptr; + Common::PaddingCallbackPromiseInfo(env, params.callback, asynccallbackinfo->info, promise); + + napi_value resourceName = nullptr; + napi_create_string_latin1(env, "enableDistributed", NAPI_AUTO_LENGTH, &resourceName); + // Asynchronous function call + napi_create_async_work( + env, + nullptr, + resourceName, + [](napi_env env, void *data) { + ANS_LOGI("EnableDistributed napi_create_async_work start"); + AsyncCallbackInfoEnabled *asynccallbackinfo = (AsyncCallbackInfoEnabled *)data; + + asynccallbackinfo->info.errorCode = + NotificationHelper::EnableDistributed(asynccallbackinfo->params.enable); + }, + [](napi_env env, napi_status status, void *data) { + ANS_LOGI("EnableDistributed napi_create_async_work end"); + AsyncCallbackInfoEnabled *asynccallbackinfo = (AsyncCallbackInfoEnabled *)data; + + Common::ReturnCallbackPromise(env, asynccallbackinfo->info, Common::NapiGetNull(env)); + + if (asynccallbackinfo->info.callback != nullptr) { + napi_delete_reference(env, asynccallbackinfo->info.callback); + } + + napi_delete_async_work(env, asynccallbackinfo->asyncWork); + if (asynccallbackinfo) { + delete asynccallbackinfo; + asynccallbackinfo = nullptr; + } + }, + (void *)asynccallbackinfo, + &asynccallbackinfo->asyncWork); + + NAPI_CALL(env, napi_queue_async_work(env, asynccallbackinfo->asyncWork)); + + if (asynccallbackinfo->info.isCallback) { + return Common::NapiGetNull(env); + } else { + return promise; + } +} + +napi_value EnableDistributedByBundle(napi_env env, napi_callback_info info) +{ + ANS_LOGI("enter"); + + EnabledByBundleParams params {}; + if (ParseParameters(env, info, params) == nullptr) { + return Common::NapiGetUndefined(env); + } + + AsyncCallbackInfoEnabledByBundle *asynccallbackinfo = + new (std::nothrow) AsyncCallbackInfoEnabledByBundle {.env = env, .asyncWork = nullptr, .params = params}; + if (!asynccallbackinfo) { + return Common::JSParaError(env, params.callback); + } + napi_value promise = nullptr; + Common::PaddingCallbackPromiseInfo(env, params.callback, asynccallbackinfo->info, promise); + + napi_value resourceName = nullptr; + napi_create_string_latin1(env, "enableDistributedByBundle", NAPI_AUTO_LENGTH, &resourceName); + // Asynchronous function call + napi_create_async_work( + env, + nullptr, + resourceName, + [](napi_env env, void *data) { + ANS_LOGI("EnableDistributedByBundle napi_create_async_work start"); + AsyncCallbackInfoEnabledByBundle *asynccallbackinfo = (AsyncCallbackInfoEnabledByBundle *)data; + + asynccallbackinfo->info.errorCode = NotificationHelper::EnableDistributedByBundle( + asynccallbackinfo->params.option, asynccallbackinfo->params.enable); + }, + [](napi_env env, napi_status status, void *data) { + ANS_LOGI("EnableDistributedByBundle napi_create_async_work end"); + AsyncCallbackInfoEnabledByBundle *asynccallbackinfo = (AsyncCallbackInfoEnabledByBundle *)data; + + Common::ReturnCallbackPromise(env, asynccallbackinfo->info, Common::NapiGetNull(env)); + + if (asynccallbackinfo->info.callback != nullptr) { + napi_delete_reference(env, asynccallbackinfo->info.callback); + } + + napi_delete_async_work(env, asynccallbackinfo->asyncWork); + if (asynccallbackinfo) { + delete asynccallbackinfo; + asynccallbackinfo = nullptr; + } + }, + (void *)asynccallbackinfo, + &asynccallbackinfo->asyncWork); + + NAPI_CALL(env, napi_queue_async_work(env, asynccallbackinfo->asyncWork)); + + if (asynccallbackinfo->info.isCallback) { + return Common::NapiGetNull(env); + } else { + return promise; + } +} + +napi_value EnableDistributedSelf(napi_env env, napi_callback_info info) +{ + ANS_LOGI("enter"); + + EnabledParams params {}; + if (ParseParameters(env, info, params) == nullptr) { + return Common::NapiGetUndefined(env); + } + + AsyncCallbackInfoEnabled *asynccallbackinfo = + new (std::nothrow) AsyncCallbackInfoEnabled {.env = env, .asyncWork = nullptr, .params = params}; + if (!asynccallbackinfo) { + return Common::JSParaError(env, params.callback); + } + napi_value promise = nullptr; + Common::PaddingCallbackPromiseInfo(env, params.callback, asynccallbackinfo->info, promise); + + napi_value resourceName = nullptr; + napi_create_string_latin1(env, "enableDistributedSelf", NAPI_AUTO_LENGTH, &resourceName); + // Asynchronous function call + napi_create_async_work( + env, + nullptr, + resourceName, + [](napi_env env, void *data) { + ANS_LOGI("EnableDistributedSelf napi_create_async_work start"); + AsyncCallbackInfoEnabled *asynccallbackinfo = (AsyncCallbackInfoEnabled *)data; + + asynccallbackinfo->info.errorCode = + NotificationHelper::EnableDistributedSelf(asynccallbackinfo->params.enable); + ANS_LOGI("EnableDistributedSelf enable = %{public}d", asynccallbackinfo->params.enable); + }, + [](napi_env env, napi_status status, void *data) { + ANS_LOGI("EnableDistributedSelf napi_create_async_work end"); + AsyncCallbackInfoEnabled *asynccallbackinfo = (AsyncCallbackInfoEnabled *)data; + + Common::ReturnCallbackPromise(env, asynccallbackinfo->info, Common::NapiGetNull(env)); + + if (asynccallbackinfo->info.callback != nullptr) { + napi_delete_reference(env, asynccallbackinfo->info.callback); + } + + napi_delete_async_work(env, asynccallbackinfo->asyncWork); + if (asynccallbackinfo) { + delete asynccallbackinfo; + asynccallbackinfo = nullptr; + } + }, + (void *)asynccallbackinfo, + &asynccallbackinfo->asyncWork); + + NAPI_CALL(env, napi_queue_async_work(env, asynccallbackinfo->asyncWork)); + + if (asynccallbackinfo->info.isCallback) { + return Common::NapiGetNull(env); + } else { + return promise; + } +} + +void AsyncCompleteCallbackIsDistributedEnableByBundle(napi_env env, napi_status status, void *data) +{ + ANS_LOGI("enter"); + if (!data) { + ANS_LOGE("Invalid async callback data"); + return; + } + ANS_LOGI("IsDistributedEnableByBundle napi_create_async_work end"); + AsyncCallbackInfoIsEnabledByBundle *asynccallbackinfo = (AsyncCallbackInfoIsEnabledByBundle *)data; + napi_value result = nullptr; + if (asynccallbackinfo->info.errorCode != ERR_OK) { + result = Common::NapiGetNull(env); + } else { + napi_get_boolean(env, asynccallbackinfo->enable, &result); + } + Common::ReturnCallbackPromise(env, asynccallbackinfo->info, result); + + if (asynccallbackinfo->info.callback != nullptr) { + napi_delete_reference(env, asynccallbackinfo->info.callback); + } + + napi_delete_async_work(env, asynccallbackinfo->asyncWork); + if (asynccallbackinfo) { + delete asynccallbackinfo; + asynccallbackinfo = nullptr; + } +} + +napi_value IsDistributedEnableByBundle(napi_env env, napi_callback_info info) +{ + ANS_LOGI("enter"); + + IsEnabledByBundleParams params {}; + if (ParseParameters(env, info, params) == nullptr) { + return Common::NapiGetUndefined(env); + } + + AsyncCallbackInfoIsEnabledByBundle *asynccallbackinfo = + new (std::nothrow) AsyncCallbackInfoIsEnabledByBundle {.env = env, .asyncWork = nullptr, .params = params}; + if (!asynccallbackinfo) { + return Common::JSParaError(env, params.callback); + } + napi_value promise = nullptr; + Common::PaddingCallbackPromiseInfo(env, params.callback, asynccallbackinfo->info, promise); + + napi_value resourceName = nullptr; + napi_create_string_latin1(env, "isDistributedEnableByBundle", NAPI_AUTO_LENGTH, &resourceName); + // Asynchronous function call + napi_create_async_work( + env, + nullptr, + resourceName, + [](napi_env env, void *data) { + ANS_LOGI("IsDistributedEnableByBundle napi_create_async_work start"); + AsyncCallbackInfoIsEnabledByBundle *asynccallbackinfo = (AsyncCallbackInfoIsEnabledByBundle *)data; + + asynccallbackinfo->info.errorCode = NotificationHelper::IsDistributedEnableByBundle( + asynccallbackinfo->params.option, asynccallbackinfo->enable); + }, + AsyncCompleteCallbackIsDistributedEnableByBundle, + (void *)asynccallbackinfo, + &asynccallbackinfo->asyncWork); + + NAPI_CALL(env, napi_queue_async_work(env, asynccallbackinfo->asyncWork)); + + if (asynccallbackinfo->info.isCallback) { + return Common::NapiGetNull(env); + } else { + return promise; + } +} +} // namespace NotificationNapi +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/napi/ans/src/disturb_mode.cpp b/interfaces/kits/napi/ans/src/disturb_mode.cpp index a27ba1940d3b8f06ff74268e7dbb6485e8fefcfe..8ad364e5de996e8331b39b76c9a7f59745bd8a83 100644 --- a/interfaces/kits/napi/ans/src/disturb_mode.cpp +++ b/interfaces/kits/napi/ans/src/disturb_mode.cpp @@ -44,7 +44,7 @@ struct AsyncCallbackInfoSupportDoNotDisturb { napi_env env = nullptr; napi_async_work asyncWork = nullptr; napi_ref callback = nullptr; - bool disturbMode = false; + bool isSupported = false; CallbackPromiseInfo info; }; @@ -155,6 +155,8 @@ napi_value SetDoNotDisturbDate(napi_env env, napi_callback_info info) ANS_LOGI("SetDoNotDisturbDate napi_create_async_work start"); AsyncCallbackInfoSetDoNotDisturb *asynccallbackinfo = (AsyncCallbackInfoSetDoNotDisturb *)data; asynccallbackinfo->info.errorCode = NotificationHelper::SetDoNotDisturbDate(asynccallbackinfo->params.date); + ANS_LOGI("SetDoNotDisturbDate date=%{public}s errorCode=%{public}d", + asynccallbackinfo->params.date.Dump().c_str(), asynccallbackinfo->info.errorCode); }, [](napi_env env, napi_status status, void *data) { ANS_LOGI("SetDoNotDisturbDate napi_create_async_work end"); @@ -240,6 +242,8 @@ napi_value GetDoNotDisturbDate(napi_env env, napi_callback_info info) ANS_LOGI("GetDoNotDisturbDate napi_create_async_work start"); AsyncCallbackInfoGetDoNotDisturb *asynccallbackinfo = (AsyncCallbackInfoGetDoNotDisturb *)data; asynccallbackinfo->info.errorCode = NotificationHelper::GetDoNotDisturbDate(asynccallbackinfo->date); + ANS_LOGI("GetDoNotDisturbDate errorCode=%{public}d date=%{public}s", + asynccallbackinfo->info.errorCode, asynccallbackinfo->date.Dump().c_str()); }, AsyncCompleteCallbackGetDoNotDisturbDate, (void *)asynccallbackinfo, @@ -283,16 +287,16 @@ napi_value SupportDoNotDisturbMode(napi_env env, napi_callback_info info) ANS_LOGI("SupportDoNotDisturbMode napi_create_async_work start"); AsyncCallbackInfoSupportDoNotDisturb *asynccallbackinfo = (AsyncCallbackInfoSupportDoNotDisturb *)data; asynccallbackinfo->info.errorCode = - NotificationHelper::DoesSupportDoNotDisturbMode(asynccallbackinfo->disturbMode); - ANS_LOGI("asynccallbackinfo->disturbMode = %{public}d", asynccallbackinfo->disturbMode); - ANS_LOGI("asynccallbackinfo->info.errorCode = %{public}d", asynccallbackinfo->info.errorCode); + NotificationHelper::DoesSupportDoNotDisturbMode(asynccallbackinfo->isSupported); + ANS_LOGI("SupportDoNotDisturbMode errorCode=%{public}d isSupported=%{public}d", + asynccallbackinfo->info.errorCode, asynccallbackinfo->isSupported); }, [](napi_env env, napi_status status, void *data) { ANS_LOGI("SupportDoNotDisturbMode napi_create_async_work end"); AsyncCallbackInfoSupportDoNotDisturb *asynccallbackinfo = (AsyncCallbackInfoSupportDoNotDisturb *)data; napi_value result = nullptr; - napi_get_boolean(env, asynccallbackinfo->disturbMode, &result); + napi_get_boolean(env, asynccallbackinfo->isSupported, &result); Common::ReturnCallbackPromise(env, asynccallbackinfo->info, result); if (asynccallbackinfo->info.callback != nullptr) { diff --git a/interfaces/kits/napi/ans/src/init.cpp b/interfaces/kits/napi/ans/src/init.cpp index c3cfdbb1dde94e05f1778a11ba77a023fb062dfd..fa8ed523b6dc0bbf3f665af487192d29ac5464e5 100644 --- a/interfaces/kits/napi/ans/src/init.cpp +++ b/interfaces/kits/napi/ans/src/init.cpp @@ -18,6 +18,7 @@ #include "cancel.h" #include "constant.h" #include "display_badge.h" +#include "distributed.h" #include "disturb_mode.h" #include "enable_notification.h" #include "get_active.h" @@ -68,6 +69,11 @@ napi_value NotificationInit(napi_env env, napi_value exports) DECLARE_NAPI_FUNCTION("getDoNotDisturbDate", GetDoNotDisturbDate), DECLARE_NAPI_FUNCTION("supportDoNotDisturbMode", SupportDoNotDisturbMode), DECLARE_NAPI_FUNCTION("isSupportTemplate", IsSupportTemplate), + DECLARE_NAPI_FUNCTION("isDistributedEnabled", IsDistributedEnabled), + DECLARE_NAPI_FUNCTION("enableDistributed", EnableDistributed), + DECLARE_NAPI_FUNCTION("enableDistributedByBundle", EnableDistributedByBundle), + DECLARE_NAPI_FUNCTION("enableDistributedSelf", EnableDistributedSelf), + DECLARE_NAPI_FUNCTION("isDistributedEnableByBundle", IsDistributedEnableByBundle), }; NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc)); diff --git a/notification.gni b/notification.gni index 3039d020827e631a2fed299cc2c5ce895915e019..efde1d98556e515e53d4f54ef01acf046dc215c2 100644 --- a/notification.gni +++ b/notification.gni @@ -42,3 +42,5 @@ ans_standard_external_deps = [ "safwk:system_ability_fwk", "samgr_standard:samgr_proxy", ] + +distributed_notification_supported = true diff --git a/services/BUILD.gn b/services/BUILD.gn index 14494d7b40075d79c1ada3e30d41f720d08f87f2..6f1abec6e964b1fe3e4c1c9fef18287d26c62866 100644 --- a/services/BUILD.gn +++ b/services/BUILD.gn @@ -11,6 +11,12 @@ # See the License for the specific language governing permissions and # limitations under the License. +import("//base/notification/ans_standard/notification.gni") + group("services_target") { deps = [ "ans:ans_targets" ] + + if (distributed_notification_supported) { + deps += [ "distributed:libans_distributed" ] + } } diff --git a/services/ans/BUILD.gn b/services/ans/BUILD.gn index e38cb70e8d4cbddf776dd18de17590966710ee27..7694c78b15a20a262c7db9c4ee594773c9e1107c 100644 --- a/services/ans/BUILD.gn +++ b/services/ans/BUILD.gn @@ -57,6 +57,8 @@ ohos_shared_library("libans") { "//utils/native/base:utils_config", ] + defines = [] + deps = [ "${core_path}:ans_core", "${frameworks_path}/ans/native:ans_innerkits", @@ -72,6 +74,12 @@ ohos_shared_library("libans") { cflags = [ "-DCONFIG_DUAL_FRAMEWORK" ] } + if (distributed_notification_supported) { + defines += [ "DISTRIBUTED_NOTIFICATION_SUPPORTED" ] + deps += [ "${services_path}/distributed:libans_distributed" ] + include_dirs += [ "${services_path}/distributed/include" ] + } + external_deps = [ "distributeddatamgr:distributeddata_inner", "multimedia_image_standard:image_native", diff --git a/services/ans/include/advanced_notification_service.h b/services/ans/include/advanced_notification_service.h index 6d0397203218fc1913a1337ade42ab81f3469b32..e1fb967dc201372fdf656d8c03e6acce59231110 100644 --- a/services/ans/include/advanced_notification_service.h +++ b/services/ans/include/advanced_notification_service.h @@ -25,6 +25,7 @@ #include "event_runner.h" #include "refbase.h" +#include "ans_const_define.h" #include "ans_manager_stub.h" #include "distributed_kv_data_manager.h" #include "distributed_kvstore_death_recipient.h" @@ -105,6 +106,12 @@ public: ErrCode RemoveGroupByBundle( const sptr &bundleOption, const std::string &groupName) override; + ErrCode IsDistributedEnabled(bool &enabled) override; + ErrCode EnableDistributed(bool enabled) override; + ErrCode EnableDistributedByBundle(const sptr &bundleOption, bool enabled) override; + ErrCode EnableDistributedSelf(bool enabled) override; + ErrCode IsDistributedEnableByBundle(const sptr &bundleOption, bool &enabled) override; + ErrCode ShellDump(const std::string &dumpOption, std::vector &dumpInfo) override; ErrCode PublishContinuousTaskNotification(const sptr &request) override; ErrCode CancelContinuousTaskNotification(const std::string &label, int32_t notificationId) override; @@ -116,6 +123,10 @@ public: // SystemEvent void OnBundleRemoved(const sptr &bundleOption); +#ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED + void OnScreenOn(); + void OnScreenOff(); +#endif // Distributed KvStore void OnDistributedKvStoreDeathRecipient(); @@ -134,6 +145,7 @@ private: void AddToNotificationList(const std::shared_ptr &record); void UpdateInNotificationList(const std::shared_ptr &record); + ErrCode AssignToNotificationList(const std::shared_ptr &record); ErrCode RemoveFromNotificationList(const sptr &bundleOption, const std::string &label, int notificationId, sptr ¬ification, bool isCancel = false); ErrCode RemoveFromNotificationList(const std::string &key, sptr ¬ification, bool isCancel = false); @@ -161,6 +173,20 @@ private: ErrCode PrepereContinuousTaskNotificationRequest(const sptr &request, const int &uid); bool GetActiveUserId(int& userId); +#ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED + std::vector GetLocalNotificationKeys(const sptr &bundleOption); + ErrCode DoDistributedPublish( + const sptr bundleOption, const std::shared_ptr record); + ErrCode DoDistributedDelete(const std::string deviceId, const sptr notification); + std::string GetNotificationDeviceId(const std::string &key); + void OnDistributedPublish( + const std::string &deviceId, const std::string &bundleName, sptr &request); + void OnDistributedUpdate( + const std::string &deviceId, const std::string &bundleName, sptr &request); + void OnDistributedDelete( + const std::string &deviceId, const std::string &bundleName, const std::string &label, int32_t id); +#endif + private: static sptr instance_; static std::mutex instanceMutex_; diff --git a/services/ans/include/bundle_manager_helper.h b/services/ans/include/bundle_manager_helper.h index ab4fb0ca9dc8035007ed18eb6323f721f79fed59..f753d91d0a4cef60d1ec22ad8b76c9e98e07f873 100644 --- a/services/ans/include/bundle_manager_helper.h +++ b/services/ans/include/bundle_manager_helper.h @@ -33,7 +33,7 @@ class BundleManagerHelper : public DelayedSingleton { public: std::string GetBundleNameByUid(int uid); bool IsSystemApp(int uid); - int GetDefaultUidByBundleName(const std::string& bundle); + int GetDefaultUidByBundleName(const std::string &bundle); private: void Connect(); diff --git a/services/ans/include/notification_record.h b/services/ans/include/notification_record.h index 12b541336f369db98f29252d16180808d07cf519..9939e09a63b7893c21d4a45810ca4b6b0ee0002b 100644 --- a/services/ans/include/notification_record.h +++ b/services/ans/include/notification_record.h @@ -18,6 +18,8 @@ #include "refbase.h" +#include + #include "notification.h" #include "notification_bundle_option.h" #include "notification_request.h" @@ -30,6 +32,9 @@ struct NotificationRecord { sptr request; sptr notification; sptr slot; +#ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED + std::string deviceId; +#endif // DISTRIBUTED_NOTIFICATION_SUPPORTED }; } // namespace Notification } // namespace OHOS diff --git a/services/ans/include/system_event_observer.h b/services/ans/include/system_event_observer.h index 8e4be393ced9195a474136d928a9035ae3b60dcb..382959c4f802efe02da74dfd433497a4131c8777 100644 --- a/services/ans/include/system_event_observer.h +++ b/services/ans/include/system_event_observer.h @@ -28,7 +28,7 @@ namespace OHOS { namespace Notification { class SystemEventObserver { public: - SystemEventObserver(const ISystemEvent& callbacks); + SystemEventObserver(const ISystemEvent &callbacks); ~SystemEventObserver(); private: diff --git a/services/ans/src/advanced_notification_service.cpp b/services/ans/src/advanced_notification_service.cpp index 8f2af8f4f510f264566a89a6dd1eea852766609d..95ae995b2e72840a580d8cafc0de30df113da888 100644 --- a/services/ans/src/advanced_notification_service.cpp +++ b/services/ans/src/advanced_notification_service.cpp @@ -34,6 +34,11 @@ #include "permission_filter.h" #include "reminder_data_manager.h" +#ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED +#include "distributed_notification_manager.h" +#include "distributed_preferences.h" +#endif + namespace OHOS { namespace Notification { namespace { @@ -196,6 +201,28 @@ AdvancedNotificationService::AdvancedNotificationService() systemEventObserver_ = std::make_shared(iSystemEvent); dataManager_.RegisterKvStoreServiceDeathRecipient(distributedKvStoreDeathRecipient_); + +#ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED + DistributedNotificationManager::IDistributedCallback distributedCallback = { + .OnPublish = std::bind(&AdvancedNotificationService::OnDistributedPublish, + this, + std::placeholders::_1, + std::placeholders::_2, + std::placeholders::_3), + .OnUpdate = std::bind(&AdvancedNotificationService::OnDistributedUpdate, + this, + std::placeholders::_1, + std::placeholders::_2, + std::placeholders::_3), + .OnDelete = std::bind(&AdvancedNotificationService::OnDistributedDelete, + this, + std::placeholders::_1, + std::placeholders::_2, + std::placeholders::_3, + std::placeholders::_4), + }; + DistributedNotificationManager::GetInstance()->RegisterCallback(distributedCallback); +#endif } AdvancedNotificationService::~AdvancedNotificationService() @@ -203,6 +230,9 @@ AdvancedNotificationService::~AdvancedNotificationService() dataManager_.UnRegisterKvStoreServiceDeathRecipient(distributedKvStoreDeathRecipient_); StopFilters(); +#ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED + DistributedNotificationManager::GetInstance()->UngegisterCallback(); +#endif } sptr AdvancedNotificationService::GenerateBundleOption() @@ -235,6 +265,22 @@ sptr AdvancedNotificationService::GenerateValidBundleO return validBundleOption; } +ErrCode AdvancedNotificationService::AssignToNotificationList(const std::shared_ptr &record) +{ + ErrCode result = ERR_OK; + if (!IsNotificationExists(record->notification->GetKey())) { + result = FlowControl(record); + } else { + if (record->request->IsAlertOneTime()) { + record->notification->SetEnableLight(false); + record->notification->SetEnableSound(false); + record->notification->SetEnableViration(false); + } + UpdateInNotificationList(record); + } + return result; +} + ErrCode AdvancedNotificationService::PrepareNotificationInfo( const sptr &request, sptr &bundleOption) { @@ -262,6 +308,7 @@ ErrCode AdvancedNotificationService::PublishPreparedNotification( record->request = request; record->notification = new Notification(request); record->bundleOption = bundleOption; + ErrCode result = ERR_OK; handler_->PostSyncTask(std::bind([&]() { result = AssignValidNotificationSlot(record); @@ -276,22 +323,16 @@ ErrCode AdvancedNotificationService::PublishPreparedNotification( return; } - if (!IsNotificationExists(record->notification->GetKey())) { - result = FlowControl(record); - if (result != ERR_OK) { - return; - } - } else { - if (record->request->IsAlertOneTime()) { - record->notification->SetEnableLight(false); - record->notification->SetEnableSound(false); - record->notification->SetEnableViration(false); - } - UpdateInNotificationList(record); + result = AssignToNotificationList(record); + if (result != ERR_OK) { + return; } UpdateRecentNotification(record->notification, false, 0); sptr sortingMap = GenerateSortingMap(); NotificationSubscriberManager::GetInstance()->NotifyConsumed(record->notification, sortingMap); +#ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED + DoDistributedPublish(bundleOption, record); +#endif })); return result; } @@ -418,6 +459,9 @@ ErrCode AdvancedNotificationService::Cancel(int notificationId, const std::strin UpdateRecentNotification(notification, true, reason); sptr sortingMap = GenerateSortingMap(); NotificationSubscriberManager::GetInstance()->NotifyCanceled(notification, sortingMap, reason); +#ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED + DoDistributedDelete("", notification); +#endif } })); return result; @@ -439,6 +483,9 @@ ErrCode AdvancedNotificationService::CancelAll() std::vector keys = GetNotificationKeys(bundleOption); for (auto key : keys) { +#ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED + std::string deviceId = GetNotificationDeviceId(key); +#endif result = RemoveFromNotificationList(key, notification, true); if (result != ERR_OK) { continue; @@ -449,6 +496,9 @@ ErrCode AdvancedNotificationService::CancelAll() UpdateRecentNotification(notification, true, reason); sptr sortingMap = GenerateSortingMap(); NotificationSubscriberManager::GetInstance()->NotifyCanceled(notification, sortingMap, reason); +#ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED + DoDistributedDelete(deviceId, notification); +#endif } } @@ -465,6 +515,10 @@ ErrCode AdvancedNotificationService::AddSlots(const std::vector bundleOption = GenerateBundleOption(); if (bundleOption == nullptr) { return ERR_ANS_INVALID_BUNDLE; @@ -730,10 +784,17 @@ ErrCode AdvancedNotificationService::Delete(const std::string &key) return ERR_ANS_NON_SYSTEM_APP; } + if (!CheckPermission(GetClientBundleName())) { + return ERR_ANS_PERMISSION_DENIED; + } + ErrCode result = ERR_OK; handler_->PostSyncTask(std::bind([&]() { sptr notification = nullptr; +#ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED + std::string deviceId = GetNotificationDeviceId(key); +#endif result = RemoveFromNotificationList(key, notification); if (result != ERR_OK) { return; @@ -744,6 +805,9 @@ ErrCode AdvancedNotificationService::Delete(const std::string &key) UpdateRecentNotification(notification, true, reason); sptr sortingMap = GenerateSortingMap(); NotificationSubscriberManager::GetInstance()->NotifyCanceled(notification, sortingMap, reason); +#ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED + DoDistributedDelete(deviceId, notification); +#endif } })); @@ -758,6 +822,10 @@ ErrCode AdvancedNotificationService::DeleteByBundle(const sptr bundle = GenerateValidBundleOption(bundleOption); if (bundle == nullptr) { return ERR_ANS_INVALID_BUNDLE; @@ -767,6 +835,9 @@ ErrCode AdvancedNotificationService::DeleteByBundle(const sptrPostSyncTask(std::bind([&]() { std::vector keys = GetNotificationKeys(bundle); for (auto key : keys) { +#ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED + std::string deviceId = GetNotificationDeviceId(key); +#endif sptr notification = nullptr; result = RemoveFromNotificationList(key, notification); @@ -779,6 +850,9 @@ ErrCode AdvancedNotificationService::DeleteByBundle(const sptr sortingMap = GenerateSortingMap(); NotificationSubscriberManager::GetInstance()->NotifyCanceled(notification, sortingMap, reason); +#ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED + DoDistributedDelete(deviceId, notification); +#endif } } @@ -796,12 +870,19 @@ ErrCode AdvancedNotificationService::DeleteAll() return ERR_ANS_NON_SYSTEM_APP; } + if (!CheckPermission(GetClientBundleName())) { + return ERR_ANS_PERMISSION_DENIED; + } + ErrCode result = ERR_OK; handler_->PostSyncTask(std::bind([&]() { int activeUserId = SUBSCRIBE_USER_INIT; (void)GetActiveUserId(activeUserId); std::vector keys = GetNotificationKeys(nullptr); for (auto key : keys) { +#ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED + std::string deviceId = GetNotificationDeviceId(key); +#endif sptr notification = nullptr; result = RemoveFromNotificationListForDeleteAll(key, notification); @@ -814,6 +895,9 @@ ErrCode AdvancedNotificationService::DeleteAll() UpdateRecentNotification(notification, true, reason); sptr sortingMap = GenerateSortingMap(); NotificationSubscriberManager::GetInstance()->NotifyCanceled(notification, sortingMap, reason); +#ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED + DoDistributedDelete(deviceId, notification); +#endif } } @@ -905,6 +989,10 @@ ErrCode AdvancedNotificationService::UpdateSlotGroups( return ERR_ANS_NON_SYSTEM_APP; } + if (!CheckPermission(GetClientBundleName())) { + return ERR_ANS_PERMISSION_DENIED; + } + sptr bundle = GenerateValidBundleOption(bundleOption); if (bundle == nullptr) { return ERR_ANS_INVALID_BUNDLE; @@ -934,6 +1022,10 @@ ErrCode AdvancedNotificationService::SetShowBadgeEnabledForBundle( return ERR_ANS_NON_SYSTEM_APP; } + if (!CheckPermission(GetClientBundleName())) { + return ERR_ANS_PERMISSION_DENIED; + } + sptr bundle = GenerateValidBundleOption(bundleOption); if (bundle == nullptr) { return ERR_ANS_INVALID_BUNDLE; @@ -954,6 +1046,10 @@ ErrCode AdvancedNotificationService::GetShowBadgeEnabledForBundle( return ERR_ANS_NON_SYSTEM_APP; } + if (!CheckPermission(GetClientBundleName())) { + return ERR_ANS_PERMISSION_DENIED; + } + sptr bundle = GenerateValidBundleOption(bundleOption); if (bundle == nullptr) { return ERR_ANS_INVALID_BUNDLE; @@ -997,9 +1093,14 @@ ErrCode AdvancedNotificationService::RemoveFromNotificationList(const sptrnotification->IsRemoveAllowed()) { continue; } - if (((record->bundleOption->GetBundleName() == bundleOption->GetBundleName()) && - (record->bundleOption->GetUid() == bundleOption->GetUid())) && - (record->notification->GetLabel() == label) && (record->notification->GetId() == notificationId)) { + if ((record->bundleOption->GetBundleName() == bundleOption->GetBundleName()) && + (record->bundleOption->GetUid() == bundleOption->GetUid()) && + (record->notification->GetLabel() == label) && + (record->notification->GetId() == notificationId) +#ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED + && record->deviceId.empty() +#endif + ) { if (!isCancel && record->request->IsUnremovable()) { return ERR_ANS_NOTIFICATION_IS_UNREMOVABLE; } @@ -1057,10 +1158,6 @@ ErrCode AdvancedNotificationService::Subscribe( { ANS_LOGD("%{public}s", __FUNCTION__); - if (subscriber == nullptr) { - return ERR_ANS_INVALID_PARAM; - } - if (!IsSystemApp()) { ANS_LOGE("Client is not a system app"); return ERR_ANS_NON_SYSTEM_APP; @@ -1070,6 +1167,10 @@ ErrCode AdvancedNotificationService::Subscribe( return ERR_ANS_PERMISSION_DENIED; } + if (subscriber == nullptr) { + return ERR_ANS_INVALID_PARAM; + } + return NotificationSubscriberManager::GetInstance()->AddSubscriber(subscriber, info); } @@ -1078,17 +1179,17 @@ ErrCode AdvancedNotificationService::Unsubscribe( { ANS_LOGD("%{public}s", __FUNCTION__); - if (subscriber == nullptr) { - return ERR_ANS_INVALID_PARAM; + if (!IsSystemApp()) { + ANS_LOGE("Client is not a system app"); + return ERR_ANS_NON_SYSTEM_APP; } if (!CheckPermission(GetClientBundleName())) { return ERR_ANS_PERMISSION_DENIED; } - if (!IsSystemApp()) { - ANS_LOGE("Client is not a system app"); - return ERR_ANS_NON_SYSTEM_APP; + if (subscriber == nullptr) { + return ERR_ANS_INVALID_PARAM; } return NotificationSubscriberManager::GetInstance()->RemoveSubscriber(subscriber, info); @@ -1185,6 +1286,10 @@ ErrCode AdvancedNotificationService::GetSpecialActiveNotifications( return ERR_ANS_NON_SYSTEM_APP; } + if (!CheckPermission(GetClientBundleName())) { + return ERR_ANS_PERMISSION_DENIED; + } + ErrCode result = ERR_OK; handler_->PostSyncTask(std::bind([&]() { for (auto record : notificationList_) { @@ -1204,6 +1309,10 @@ ErrCode AdvancedNotificationService::SetNotificationsEnabledForAllBundles(const return ERR_ANS_NON_SYSTEM_APP; } + if (!CheckPermission(GetClientBundleName())) { + return ERR_ANS_PERMISSION_DENIED; + } + ErrCode result = ERR_OK; sptr bundleOption = GenerateBundleOption(); if (bundleOption == nullptr) { @@ -1259,6 +1368,10 @@ ErrCode AdvancedNotificationService::IsAllowedNotify(bool &allowed) return ERR_ANS_NON_SYSTEM_APP; } + if (!CheckPermission(GetClientBundleName())) { + return ERR_ANS_PERMISSION_DENIED; + } + ErrCode result = ERR_OK; sptr bundleOption = GenerateBundleOption(); if (bundleOption == nullptr) { @@ -1293,6 +1406,9 @@ ErrCode AdvancedNotificationService::IsSpecialBundleAllowedNotify( if (!IsSystemApp()) { return ERR_ANS_NON_SYSTEM_APP; } + if (!CheckPermission(GetClientBundleName())) { + return ERR_ANS_PERMISSION_DENIED; + } targetBundle = GenerateValidBundleOption(bundleOption); } } @@ -1473,6 +1589,11 @@ ErrCode AdvancedNotificationService::ActiveNotificationDump(std::vectordeviceId.empty()) { + continue; + } +#endif stream.clear(); stream << "\tBundleName: " << record->notification->GetBundleName() << "\n"; @@ -1651,8 +1772,11 @@ void AdvancedNotificationService::OnBundleRemoved(const sptr keys = GetLocalNotificationKeys(bundleOption); +#else std::vector keys = GetNotificationKeys(bundleOption); +#endif for (auto key : keys) { sptr notification = nullptr; result = RemoveFromNotificationList(key, notification, true); @@ -1665,6 +1789,9 @@ void AdvancedNotificationService::OnBundleRemoved(const sptr sortingMap = GenerateSortingMap(); NotificationSubscriberManager::GetInstance()->NotifyCanceled(notification, sortingMap, reason); +#ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED + DoDistributedDelete("", notification); +#endif } } })); @@ -1673,8 +1800,12 @@ void AdvancedNotificationService::OnBundleRemoved(const sptrPostTask( - std::bind([&]() { NotificationPreferences::GetInstance().OnDistributedKvStoreDeathRecipient(); })); + handler_->PostTask(std::bind([&]() { + NotificationPreferences::GetInstance().OnDistributedKvStoreDeathRecipient(); +#ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED + DistributedNotificationManager::GetInstance()->OnDistributedKvStoreDeathRecipient(); +#endif + })); } ErrCode AdvancedNotificationService::RemoveAllSlots() @@ -1743,15 +1874,23 @@ ErrCode AdvancedNotificationService::RemoveNotification( handler_->PostSyncTask(std::bind([&]() { sptr notification = nullptr; - +#ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED + std::string deviceId; +#endif for (auto record : notificationList_) { if ((record->bundleOption->GetBundleName() == bundle->GetBundleName()) && (record->bundleOption->GetUid() == bundleOption->GetUid()) && +#ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED + (record->deviceId.empty()) && +#endif (record->notification->GetId() == notificationId) && (record->notification->GetLabel() == label)) { if (record->request->IsUnremovable()) { result = ERR_ANS_NOTIFICATION_IS_UNREMOVABLE; break; } +#ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED + deviceId = record->deviceId; +#endif notification = record->notification; notificationList_.remove(record); result = ERR_OK; @@ -1764,6 +1903,9 @@ ErrCode AdvancedNotificationService::RemoveNotification( UpdateRecentNotification(notification, true, reason); sptr sortingMap = GenerateSortingMap(); NotificationSubscriberManager::GetInstance()->NotifyCanceled(notification, sortingMap, reason); +#ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED + DoDistributedDelete(deviceId, notification); +#endif } })); @@ -1795,7 +1937,11 @@ ErrCode AdvancedNotificationService::RemoveAllNotifications(const sptrbundleOption->GetBundleName() == bundleOption->GetBundleName()) && - (record->bundleOption->GetUid() == bundleOption->GetUid()) && !record->request->IsUnremovable()) { + (record->bundleOption->GetUid() == bundleOption->GetUid()) && +#ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED + record->deviceId.empty() && +#endif + !record->request->IsUnremovable()) { removeList.push_back(record); } } @@ -1807,6 +1953,9 @@ ErrCode AdvancedNotificationService::RemoveAllNotifications(const sptrnotification, true, reason); sptr sortingMap = GenerateSortingMap(); NotificationSubscriberManager::GetInstance()->NotifyCanceled(record->notification, sortingMap, reason); +#ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED + DoDistributedDelete(record->deviceId, record->notification); +#endif } } })); @@ -1822,6 +1971,10 @@ ErrCode AdvancedNotificationService::GetSlotNumAsBundle(const sptr bundle = GenerateValidBundleOption(bundleOption); if (bundle == nullptr) { return ERR_ANS_INVALID_BUNDLE; @@ -1858,6 +2011,9 @@ ErrCode AdvancedNotificationService::CancelGroup(const std::string &groupName) for (auto record : notificationList_) { if ((record->bundleOption->GetBundleName() == bundleOption->GetBundleName()) && (record->bundleOption->GetUid() == bundleOption->GetUid()) && +#ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED + record->deviceId.empty() && +#endif (record->request->GetGroupName() == groupName)) { removeList.push_back(record); } @@ -1871,6 +2027,9 @@ ErrCode AdvancedNotificationService::CancelGroup(const std::string &groupName) UpdateRecentNotification(record->notification, true, reason); sptr sortingMap = GenerateSortingMap(); NotificationSubscriberManager::GetInstance()->NotifyCanceled(record->notification, sortingMap, reason); +#ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED + DoDistributedDelete(record->deviceId, record->notification); +#endif } } })); @@ -1887,6 +2046,10 @@ ErrCode AdvancedNotificationService::RemoveGroupByBundle( return ERR_ANS_NON_SYSTEM_APP; } + if (!CheckPermission(GetClientBundleName())) { + return ERR_ANS_PERMISSION_DENIED; + } + if (bundleOption == nullptr || groupName.empty()) { return ERR_ANS_INVALID_PARAM; } @@ -1901,6 +2064,9 @@ ErrCode AdvancedNotificationService::RemoveGroupByBundle( for (auto record : notificationList_) { if ((record->bundleOption->GetBundleName() == bundle->GetBundleName()) && (record->bundleOption->GetUid() == bundle->GetUid()) && !record->request->IsUnremovable() && +#ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED + record->deviceId.empty() && +#endif (record->request->GetGroupName() == groupName)) { removeList.push_back(record); } @@ -1914,6 +2080,9 @@ ErrCode AdvancedNotificationService::RemoveGroupByBundle( UpdateRecentNotification(record->notification, true, reason); sptr sortingMap = GenerateSortingMap(); NotificationSubscriberManager::GetInstance()->NotifyCanceled(record->notification, sortingMap, reason); +#ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED + DoDistributedDelete(record->deviceId, record->notification); +#endif } } })); @@ -2011,6 +2180,10 @@ ErrCode AdvancedNotificationService::SetDoNotDisturbDate(const sptr bundleOption = GenerateBundleOption(); if (bundleOption == nullptr) { @@ -2096,6 +2277,15 @@ ErrCode AdvancedNotificationService::GetDoNotDisturbDate(sptrPostSyncTask(std::bind([&]() { + result = DistributedPreferences::GetInstance()->GetDistributedEnable(enabled); + if (result != ERR_OK) { + result = ERR_OK; + enabled = false; + } + })); + return result; +#else + return ERR_INVALID_OPERATION; +#endif +} + +ErrCode AdvancedNotificationService::EnableDistributed(bool enabled) +{ + ANS_LOGD("%{public}s", __FUNCTION__); + +#ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED + if (!IsSystemApp()) { + return ERR_ANS_NON_SYSTEM_APP; + } + + if (!CheckPermission(GetClientBundleName())) { + return ERR_ANS_PERMISSION_DENIED; + } + + ErrCode result = ERR_OK; + handler_->PostSyncTask( + std::bind([&]() { result = DistributedPreferences::GetInstance()->SetDistributedEnable(enabled); })); + return result; +#else + return ERR_INVALID_OPERATION; +#endif +} + +ErrCode AdvancedNotificationService::EnableDistributedByBundle( + const sptr &bundleOption, bool enabled) +{ + ANS_LOGD("%{public}s", __FUNCTION__); + +#ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED + if (!IsSystemApp()) { + return ERR_ANS_NON_SYSTEM_APP; + } + + if (!CheckPermission(GetClientBundleName())) { + return ERR_ANS_PERMISSION_DENIED; + } + + ErrCode result = ERR_OK; + handler_->PostSyncTask(std::bind([&]() { + result = DistributedPreferences::GetInstance()->SetDistributedBundleEnable(bundleOption, enabled); + if (result != ERR_OK) { + result = ERR_OK; + enabled = false; + } + })); + return result; +#else + return ERR_INVALID_OPERATION; +#endif +} + +ErrCode AdvancedNotificationService::EnableDistributedSelf(const bool enabled) +{ + ANS_LOGD("%{public}s", __FUNCTION__); +#ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED + sptr bundleOption = GenerateBundleOption(); + if (bundleOption == nullptr) { + return ERR_ANS_INVALID_BUNDLE; + } + + ErrCode result = ERR_OK; + handler_->PostSyncTask(std::bind( + [&]() { result = DistributedPreferences::GetInstance()->SetDistributedBundleEnable(bundleOption, enabled); })); + return result; +#else + return ERR_INVALID_OPERATION; +#endif +} + +ErrCode AdvancedNotificationService::IsDistributedEnableByBundle( + const sptr &bundleOption, bool &enabled) +{ + ANS_LOGD("%{public}s", __FUNCTION__); + +#ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED + if (!IsSystemApp()) { + return ERR_ANS_NON_SYSTEM_APP; + } + + if (!CheckPermission(GetClientBundleName())) { + return ERR_ANS_PERMISSION_DENIED; + } + + ErrCode result = ERR_OK; + handler_->PostSyncTask(std::bind([&]() { + result = DistributedPreferences::GetInstance()->GetDistributedBundleEnable(bundleOption, enabled); + if (result != ERR_OK) { + result = ERR_OK; + enabled = false; + } + })); + return result; +#else + return ERR_INVALID_OPERATION; +#endif +} + +#ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED +std::vector AdvancedNotificationService::GetLocalNotificationKeys( + const sptr &bundleOption) +{ + std::vector keys; + + for (auto record : notificationList_) { + if ((bundleOption != nullptr) && (record->bundleOption->GetBundleName() != bundleOption->GetBundleName()) && + (record->bundleOption->GetUid() != bundleOption->GetUid()) && record->deviceId.empty()) { + continue; + } + keys.push_back(record->notification->GetKey()); + } + + return keys; +} + +std::string AdvancedNotificationService::GetNotificationDeviceId(const std::string &key) +{ + for (auto record : notificationList_) { + if (record->notification->GetKey() == key) { + return record->deviceId; + } + } + return std::string(); +} + +ErrCode AdvancedNotificationService::DoDistributedPublish( + const sptr bundleOption, const std::shared_ptr record) +{ + if (!record->request->GetNotificationDistributedOptions().IsDistributed()) { + return ERR_OK; + } + + ErrCode result; + bool distributedEnable = false; + result = DistributedPreferences::GetInstance()->GetDistributedEnable(distributedEnable); + if (result != ERR_OK || !distributedEnable) { + return result; + } + + bool bundleDistributedEnable = false; + result = DistributedPreferences::GetInstance()->GetDistributedBundleEnable(bundleOption, bundleDistributedEnable); + if (result != ERR_OK || !bundleDistributedEnable) { + return result; + } + + return DistributedNotificationManager::GetInstance()->Publish(record->notification->GetBundleName(), + record->notification->GetLabel(), + record->notification->GetId(), + record->request); +} + +ErrCode AdvancedNotificationService::DoDistributedDelete( + const std::string deviceId, const sptr notification) +{ + if (!notification->GetNotificationRequest().GetNotificationDistributedOptions().IsDistributed()) { + return ERR_OK; + } + if (deviceId.empty()) { + return DistributedNotificationManager::GetInstance()->Delete( + notification->GetBundleName(), notification->GetLabel(), notification->GetId()); + } else { + return DistributedNotificationManager::GetInstance()->DeleteRemoteNotification( + deviceId, notification->GetBundleName(), notification->GetLabel(), notification->GetId()); + } + + return ERR_OK; +} + +inline bool CheckDistributedNotificationType(const sptr &request) +{ + DistributedDatabase::DeviceInfo localDeviceInfo; + DistributedNotificationManager::GetInstance()->GetLocalDeviceInfo(localDeviceInfo); + auto deviceTypeList = request->GetNotificationDistributedOptions().GetDevicesSupportDisplay(); + for (auto device : deviceTypeList) { + if (device == localDeviceInfo.deviceType) { + return true; + } + } + return false; +} + +void AdvancedNotificationService::OnDistributedPublish( + const std::string &deviceId, const std::string &bundleName, sptr &request) +{ + ANS_LOGD("%{public}s", __FUNCTION__); + + request->SetCreatorUid(BundleManagerHelper::GetInstance()->GetDefaultUidByBundleName(bundleName)); + + handler_->PostTask(std::bind([this, deviceId, bundleName, request]() { + if (!CheckDistributedNotificationType(request)) { + ANS_LOGD("device type not support display."); + return; + } + + sptr bundleOption = + GenerateValidBundleOption(new NotificationBundleOption(bundleName, 0)); + if (bundleOption == nullptr) { + return; + } + std::shared_ptr record = std::make_shared(); + if (record == nullptr) { + return; + } + record->request = request; + record->notification = new Notification(deviceId, request); + record->bundleOption = bundleOption; + record->deviceId = deviceId; + + ErrCode result = AssignValidNotificationSlot(record); + if (result != ERR_OK) { + ANS_LOGE("Can not assign valid slot!"); + return; + } + + result = Filter(record); + if (result != ERR_OK) { + ANS_LOGE("Reject by filters: %{public}d", result); + return; + } + + result = FlowControl(record); + if (result != ERR_OK) { + return; + } + + UpdateRecentNotification(record->notification, false, 0); + sptr sortingMap = GenerateSortingMap(); + NotificationSubscriberManager::GetInstance()->NotifyConsumed(record->notification, sortingMap); + })); +} + +void AdvancedNotificationService::OnDistributedUpdate( + const std::string &deviceId, const std::string &bundleName, sptr &request) +{ + ANS_LOGD("%{public}s", __FUNCTION__); + + request->SetCreatorUid(BundleManagerHelper::GetInstance()->GetDefaultUidByBundleName(bundleName)); + + handler_->PostTask(std::bind([this, deviceId, bundleName, request]() { + if (!CheckDistributedNotificationType(request)) { + ANS_LOGD("device type not support display."); + return; + } + sptr bundleOption = + GenerateValidBundleOption(new NotificationBundleOption(bundleName, 0)); + if (bundleOption == nullptr) { + return; + } + std::shared_ptr record = std::make_shared(); + if (record == nullptr) { + return; + } + record->request = request; + record->notification = new Notification(deviceId, request); + record->bundleOption = bundleOption; + record->deviceId = deviceId; + + ErrCode result = AssignValidNotificationSlot(record); + if (result != ERR_OK) { + ANS_LOGE("Can not assign valid slot!"); + return; + } + + result = Filter(record); + if (result != ERR_OK) { + ANS_LOGE("Reject by filters: %{public}d", result); + return; + } + + if (IsNotificationExists(record->notification->GetKey())) { + if (record->request->IsAlertOneTime()) { + record->notification->SetEnableLight(false); + record->notification->SetEnableSound(false); + record->notification->SetEnableViration(false); + } + UpdateInNotificationList(record); + } + + UpdateRecentNotification(record->notification, false, 0); + sptr sortingMap = GenerateSortingMap(); + NotificationSubscriberManager::GetInstance()->NotifyConsumed(record->notification, sortingMap); + })); +} + +void AdvancedNotificationService::OnDistributedDelete( + const std::string &deviceId, const std::string &bundleName, const std::string &label, int32_t id) +{ + ANS_LOGD("%{public}s", __FUNCTION__); + handler_->PostTask(std::bind([this, deviceId, bundleName, label, id]() { + sptr bundleOption = + GenerateValidBundleOption(new NotificationBundleOption(bundleName, 0)); + if (bundleOption == nullptr) { + return; + } + + std::string recordDeviceId; + DistributedDatabase::DeviceInfo localDeviceInfo; + if (DistributedNotificationManager::GetInstance()->GetLocalDeviceInfo(localDeviceInfo) == ERR_OK && + deviceId == localDeviceInfo.deviceId) { + recordDeviceId = ""; + } else { + recordDeviceId = deviceId; + } + + sptr notification = nullptr; + for (auto record : notificationList_) { + if ((record->deviceId == recordDeviceId) && + (record->bundleOption->GetBundleName() == bundleOption->GetBundleName()) && + (record->bundleOption->GetUid() == bundleOption->GetUid()) && + (record->notification->GetLabel() == label) && (record->notification->GetId() == id)) { + notification = record->notification; + notificationList_.remove(record); + break; + } + } + + if (notification != nullptr) { + int reason = NotificationConstant::APP_CANCEL_REASON_OTHER; + UpdateRecentNotification(notification, true, reason); + sptr sortingMap = GenerateSortingMap(); + NotificationSubscriberManager::GetInstance()->NotifyCanceled(notification, sortingMap, reason); + } + })); +} +#endif + ErrCode AdvancedNotificationService::PrepereContinuousTaskNotificationRequest( const sptr &request, const int &uid) { @@ -2146,4 +2678,4 @@ bool AdvancedNotificationService::GetActiveUserId(int& userId) return false; } } // namespace Notification -} // namespace OHOS +} // namespace OHOS \ No newline at end of file diff --git a/services/ans/src/bundle_manager_helper.cpp b/services/ans/src/bundle_manager_helper.cpp index c5485263ed049c10847aa02809d38b7f4c22995d..f57a45200f33450c176c90e2c9d0e027660c9bcd 100644 --- a/services/ans/src/bundle_manager_helper.cpp +++ b/services/ans/src/bundle_manager_helper.cpp @@ -100,7 +100,7 @@ void BundleManagerHelper::Disconnect() } } -int BundleManagerHelper::GetDefaultUidByBundleName(const std::string& bundle) +int BundleManagerHelper::GetDefaultUidByBundleName(const std::string &bundle) { int uid = -1; diff --git a/services/ans/src/notification_preferences_database.cpp b/services/ans/src/notification_preferences_database.cpp index 3359c9ccc9c44c6bc39e9e886261ce7aafdbb294..966e69a71df7ae695dfc6e972522edebabc6e7b8 100644 --- a/services/ans/src/notification_preferences_database.cpp +++ b/services/ans/src/notification_preferences_database.cpp @@ -145,7 +145,7 @@ OHOS::DistributedKv::Status NotificationPreferencesDatabase::GetKvStore() OHOS::DistributedKv::Options options = { .createIfMissing = true, .encrypt = false, - .autoSync = true, + .autoSync = false, .kvStoreType = OHOS::DistributedKv::KvStoreType::SINGLE_VERSION, }; auto status = dataManager_.GetSingleKvStore(options, appId_, storeId_, kvStorePtr_); @@ -1312,6 +1312,7 @@ std::string NotificationPreferencesDatabase::GenerateBundleLablel( { return bundleInfo.GetBundleName().append(std::to_string(bundleInfo.GetBundleUid())); } + void NotificationPreferencesDatabase::GetDoNotDisturbType(NotificationPreferencesInfo &info, int userId) { std::string key = @@ -1407,6 +1408,5 @@ void NotificationPreferencesDatabase::GetEnableAllNotification(NotificationPrefe } }); } - } // namespace Notification } // namespace OHOS \ No newline at end of file diff --git a/services/ans/src/notification_subscriber_manager.cpp b/services/ans/src/notification_subscriber_manager.cpp index f6a4e947c2f578b2369c47671205cb5bb2e2cf40..9c2dcda42f0910ae86181600d4605aa12c984f9a 100644 --- a/services/ans/src/notification_subscriber_manager.cpp +++ b/services/ans/src/notification_subscriber_manager.cpp @@ -99,7 +99,6 @@ void NotificationSubscriberManager::NotifyConsumed( ANS_LOGE("handler is nullptr"); return; } - AppExecFwk::EventHandler::Callback NotifyConsumedFunc = std::bind(&NotificationSubscriberManager::NotifyConsumedInner, this, notification, notificationMap); diff --git a/services/ans/test/unittest/BUILD.gn b/services/ans/test/unittest/BUILD.gn index d29b10ee98212b72f64be5c305b387912281fa2c..faab50da095aa52251afe7ee55c0a175be2f9795 100644 --- a/services/ans/test/unittest/BUILD.gn +++ b/services/ans/test/unittest/BUILD.gn @@ -45,6 +45,8 @@ ohos_unittest("ans_unit_test") { "//developtools/bytrace_standard/interfaces/innerkits/native/include", ] + defines = [] + sources = [ "${services_path}/ans/src/advanced_notification_service.cpp", "${services_path}/ans/src/advanced_notification_service_ability.cpp", @@ -91,6 +93,12 @@ ohos_unittest("ans_unit_test") { "//utils/native/base:utils", ] + if (distributed_notification_supported) { + defines += [ "DISTRIBUTED_NOTIFICATION_SUPPORTED" ] + deps += [ "${services_path}/distributed:libans_distributed" ] + include_dirs += [ "${services_path}/distributed/include" ] + } + external_deps = [ "aafwk_standard:want", "appexecfwk_standard:appexecfwk_base", diff --git a/services/ans/test/unittest/advanced_notification_service_test.cpp b/services/ans/test/unittest/advanced_notification_service_test.cpp index f4693c9fd3d1882d55fbdac263e631d80283c6d4..441a16cfd72bcff86cbcda95678a0bbb4288d751 100644 --- a/services/ans/test/unittest/advanced_notification_service_test.cpp +++ b/services/ans/test/unittest/advanced_notification_service_test.cpp @@ -35,7 +35,6 @@ using namespace OHOS::Media; namespace OHOS { namespace Notification { - class AdvancedNotificationServiceTest : public testing::Test { public: static void SetUpTestCase(); diff --git a/services/distributed/BUILD.gn b/services/distributed/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..757c4c4f73ce8f60dad03d4ebad0afe34f807c15 --- /dev/null +++ b/services/distributed/BUILD.gn @@ -0,0 +1,58 @@ +# Copyright (c) 2021 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. + +import("//base/notification/ans_standard/notification.gni") +import("//build/ohos.gni") + +config("ans_distributed_config") { + include_dirs = [ + "${services_path}/distributed/include", + "//utils/native/base/include", + ] +} + +ohos_shared_library("libans_distributed") { + sources = [ + "src/distributed_database.cpp", + "src/distributed_database_callback.cpp", + "src/distributed_device_callback.cpp", + "src/distributed_flow_control.cpp", + "src/distributed_notification_manager.cpp", + "src/distributed_preferences.cpp", + "src/distributed_preferences_database.cpp", + "src/distributed_preferences_info.cpp", + ] + + include_dirs = [ "include" ] + + configs = [ + ":ans_distributed_config", + "${core_path}:public_ans_core_config", + "${frameworks_path}/ans/native:ans_innerkits_public_config", + ] + + deps = [ "${core_path}:ans_core" ] + + external_deps = [ + "aafwk_standard:want", + "appexecfwk_standard:libeventhandler", + "distributeddatamgr:distributeddata_inner", + "dmsfwk_standard:zuri", + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_core", + "utils_base:utils", + ] + + subsystem_name = "notification" + part_name = "ans_standard" +} diff --git a/services/distributed/include/distributed_database.h b/services/distributed/include/distributed_database.h new file mode 100644 index 0000000000000000000000000000000000000000..6286769a00ce929d2d378975bb0a5148bc771d2d --- /dev/null +++ b/services/distributed/include/distributed_database.h @@ -0,0 +1,71 @@ +/* + * 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 BASE_NOTIFICATION_ANS_STANDARD_SERVICES_DISTRIBUTED_INCLUDE_DISTRIBUTED_DATABASE_H +#define BASE_NOTIFICATION_ANS_STANDARD_SERVICES_DISTRIBUTED_INCLUDE_DISTRIBUTED_DATABASE_H + +#include +#include +#include +#include + +#include "distributed_kv_data_manager.h" +#include "singleton.h" + +#include "distributed_database_callback.h" +#include "distributed_device_callback.h" +#include "distributed_flow_control.h" + +namespace OHOS { +namespace Notification { +class DistributedDatabase : private DistributedFlowControl { +public: + using Entry = DistributedKv::Entry; + using DeviceInfo = DistributedKv::DeviceInfo; + DistributedDatabase( + std::shared_ptr databaseCb, std::shared_ptr deviceCb); + ~DistributedDatabase(); + + bool PutToDistributedDB(const std::string &key, const std::string &value); + bool GetFromDistributedDB(const std::string &key, std::string &value); + bool GetEntriesFromDistributedDB(const std::string &prefixKey, std::vector &entries); + bool DeleteToDistributedDB(const std::string &key); + bool ClearDataByDevice(const std::string &deviceId); + bool GetLocalDeviceId(std::string &deviceId); + bool GetLocalDeviceInfo(DeviceInfo &localInfo); + bool GetDeviceInfoList(std::vector &deviceList); + bool RecreateDistributedDB(); + +private: + void GetKvDataManager(void); + bool CheckKvDataManager(void); + void GetKvStore(void); + bool CheckKvStore(void); + +private: + std::mutex mutex_; + std::unique_ptr kvDataManager_; + std::shared_ptr kvStore_; + std::shared_ptr databaseCb_; + std::shared_ptr deviceCb_; + + std::string localDeviceId_; + + DISALLOW_COPY_AND_MOVE(DistributedDatabase); +}; +} // namespace Notification +} // namespace OHOS + +#endif /* BASE_NOTIFICATION_ANS_STANDARD_SERVICES_DISTRIBUTED_INCLUDE_DISTRIBUTED_DATABASE_H */ \ No newline at end of file diff --git a/services/distributed/include/distributed_database_callback.h b/services/distributed/include/distributed_database_callback.h new file mode 100644 index 0000000000000000000000000000000000000000..672b55617faa0e51359b599f86ec7175aaaff824 --- /dev/null +++ b/services/distributed/include/distributed_database_callback.h @@ -0,0 +1,45 @@ +/* + * 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 BASE_NOTIFICATION_ANS_STANDARD_SERVICES_DISTRIBUTED_INCLUDE_DISTRIBUTED_DATABASE_CALLBACK_H +#define BASE_NOTIFICATION_ANS_STANDARD_SERVICES_DISTRIBUTED_INCLUDE_DISTRIBUTED_DATABASE_CALLBACK_H + +#include + +#include "kvstore_observer.h" + +namespace OHOS { +namespace Notification { +class DistributedDatabaseCallback : public DistributedKv::KvStoreObserver { +public: + struct IDatabaseChange { + std::function OnInsert; + std::function OnUpdate; + std::function OnDelete; + }; + explicit DistributedDatabaseCallback(const IDatabaseChange &callback); + ~DistributedDatabaseCallback(); +private: + void OnChange(const DistributedKv::ChangeNotification &changeNotification, + std::shared_ptr snapshot) override; + void OnChange(const DistributedKv::ChangeNotification &changeNotification) override; + +private: + IDatabaseChange callback_; +}; +} // namespace Notification +} // namespace OHOS + +#endif /* BASE_NOTIFICATION_ANS_STANDARD_SERVICES_DISTRIBUTED_INCLUDE_DISTRIBUTED_DATABASE_CALLBACK_H */ \ No newline at end of file diff --git a/services/distributed/include/distributed_device_callback.h b/services/distributed/include/distributed_device_callback.h new file mode 100644 index 0000000000000000000000000000000000000000..33000b45604becf489bb938bade6d95f8339346f --- /dev/null +++ b/services/distributed/include/distributed_device_callback.h @@ -0,0 +1,45 @@ +/* + * 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 BASE_NOTIFICATION_ANS_STANDARD_SERVICES_DISTRIBUTED_INCLUDE_DISTRIBUTED_DEVICE_CALLBACK_H +#define BASE_NOTIFICATION_ANS_STANDARD_SERVICES_DISTRIBUTED_INCLUDE_DISTRIBUTED_DEVICE_CALLBACK_H + +#include + +#include "device_status_change_listener.h" + +namespace OHOS { +namespace Notification { +class DistributedDeviceCallback : public DistributedKv::DeviceStatusChangeListener { +public: + struct IDeviceChange { + std::function OnConnected; + std::function OnDisconnected; + }; + explicit DistributedDeviceCallback(const IDeviceChange &callback); + ~DistributedDeviceCallback(); + +private: + void OnDeviceChanged( + const DistributedKv::DeviceInfo &info, const DistributedKv::DeviceChangeType &type) const override; + DistributedKv::DeviceFilterStrategy GetFilterStrategy() const override; + +private: + IDeviceChange callback_; +}; +} // namespace Notification +} // namespace OHOS + +#endif /* BASE_NOTIFICATION_ANS_STANDARD_SERVICES_DISTRIBUTED_INCLUDE_DISTRIBUTED_DEVICE_CALLBACK_H */ \ No newline at end of file diff --git a/services/distributed/include/distributed_flow_control.h b/services/distributed/include/distributed_flow_control.h new file mode 100644 index 0000000000000000000000000000000000000000..435381491d58798e95af0b2718034071acecc74e --- /dev/null +++ b/services/distributed/include/distributed_flow_control.h @@ -0,0 +1,52 @@ +/* + * 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 BASE_NOTIFICATION_ANS_STANDARD_SERVICES_DISTRIBUTED_INCLUDE_DISTRIBUTED_FLOW_CONTROL_H +#define BASE_NOTIFICATION_ANS_STANDARD_SERVICES_DISTRIBUTED_INCLUDE_DISTRIBUTED_FLOW_CONTROL_H + +#include +#include + +namespace OHOS { +namespace Notification { +class DistributedFlowControl { +public: + DistributedFlowControl(int kvManagerSecondMaxinum = KVMANAGER_MAXINUM_PER_SECOND, + int kvManagerMinuteMaxinum = KVMANAGER_MAXINUM_PER_MINUTE, + int kvStoreSecondMaxinum = KVSTORE_MAXINUM_PER_SECOND, + int kvStoreMinuteMaxinum = KVSTORE_MAXINUM_PER_MINUTE); + bool KvManagerFlowControl(void); + bool KvStoreFlowControl(void); + void KvManagerFlowControlClear(void); + void KvStoreFlowControlClear(void); + +protected: + static const int KVMANAGER_MAXINUM_PER_SECOND = 50; + static const int KVMANAGER_MAXINUM_PER_MINUTE = 500; + static const int KVSTORE_MAXINUM_PER_SECOND = 1000; + static const int KVSTORE_MAXINUM_PER_MINUTE = 10000; + +private: + int kvManagerSecondMaxinum_; + int kvManagerMinuteMaxinum_; + int kvStoreSecondMaxinum_; + int kvStoreMinuteMaxinum_; + std::list kvDataManagerTimestampList_; + std::list kvStoreTimestampList_; +}; +} // namespace Notification +} // namespace OHOS + +#endif /* BASE_NOTIFICATION_ANS_STANDARD_SERVICES_DISTRIBUTED_INCLUDE_DISTRIBUTED_FLOW_CONTROL_H */ \ No newline at end of file diff --git a/services/distributed/include/distributed_notification_manager.h b/services/distributed/include/distributed_notification_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..edcc0a973a0436d4b231befbd1b239f26c6bfa0d --- /dev/null +++ b/services/distributed/include/distributed_notification_manager.h @@ -0,0 +1,104 @@ +/* + * 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 BASE_NOTIFICATION_ANS_STANDARD_SERVICES_DISTRIBUTED_INCLUDE_DISTRIBUTED_NOTIFICATION_MANAGER_H +#define BASE_NOTIFICATION_ANS_STANDARD_SERVICES_DISTRIBUTED_INCLUDE_DISTRIBUTED_NOTIFICATION_MANAGER_H + +#include + +#include "singleton.h" + +#include "event_handler.h" +#include "event_runner.h" + +#include "distributed_database.h" +#include "distributed_database_callback.h" +#include "distributed_device_callback.h" +#include "notification_request.h" + +namespace OHOS { +namespace Notification { +class DistributedNotificationManager : public DelayedSingleton { +public: + struct IDistributedCallback { + std::function &request)> + OnPublish; + std::function &request)> + OnUpdate; + std::function + OnDelete; + }; + + ErrCode Publish( + const std::string &bundleName, const std::string &label, int32_t id, const sptr &request); + ErrCode Update( + const std::string &bundleName, const std::string &label, int32_t id, const sptr &request); + ErrCode Delete(const std::string &bundleName, const std::string &label, int32_t id); + ErrCode DeleteRemoteNotification( + const std::string &deviceId, const std::string &bundleName, const std::string &label, int32_t id); + ErrCode RegisterCallback(const IDistributedCallback &callback); + ErrCode UngegisterCallback(void); + ErrCode GetCurrentDistributedNotification(std::vector> &requestList); + ErrCode GetLocalDeviceInfo(DistributedDatabase::DeviceInfo &deviceInfo); + ErrCode OnDistributedKvStoreDeathRecipient(); + +private: + void OnDatabaseInsert(const std::string &deviceId, const std::string &key, const std::string &value); + void OnDatabaseUpdate(const std::string &deviceId, const std::string &key, const std::string &value); + void OnDatabaseDelete(const std::string &deviceId, const std::string &key, const std::string &value); + void OnDeviceConnected(const std::string &deviceId); + void OnDeviceDisconnected(const std::string &deviceId); + +private: + struct ResolveKey { + std::string deviceId; + std::string bundleName; + std::string label; + int32_t id = 0; + }; + + void GenerateDistributedKey(const std::string &deviceId, const std::string &bundleName, const std::string &label, + int32_t id, std::string &key); + bool GenerateLocalDistributedKey( + const std::string &bundleName, const std::string &label, int32_t id, std::string &key); + bool ResolveDistributedKey(const std::string &key, ResolveKey &resolveKey); + bool GetDeviceIdFromKey(const std::string &key, std::string &deviceId); + bool CheckDeviceId(const std::string &deviceId, const std::string &key); + + bool PublishCallback( + const std::string &deviceId, const std::string &bundleName, sptr &request); + bool UpdateCallback(const std::string &deviceId, const std::string &bundleName, sptr &request); + bool DeleteCallback( + const std::string &deviceId, const std::string &bundleName, const std::string &label, int32_t id); + +private: + std::shared_ptr runner_ = nullptr; + std::shared_ptr handler_ = nullptr; + std::shared_ptr database_ = nullptr; + + std::shared_ptr databaseCb_; + std::shared_ptr deviceCb_; + IDistributedCallback callback_ = {0}; + + DECLARE_DELAYED_SINGLETON(DistributedNotificationManager); + DISALLOW_COPY_AND_MOVE(DistributedNotificationManager); +}; +} // namespace Notification +} // namespace OHOS + +#endif // BASE_NOTIFICATION_ANS_STANDARD_SERVICES_DISTRIBUTED_INCLUDE_DISTRIBUTED_NOTIFICATION_MANAGER_H \ No newline at end of file diff --git a/services/distributed/include/distributed_preferences.h b/services/distributed/include/distributed_preferences.h new file mode 100644 index 0000000000000000000000000000000000000000..c86dbc2a8ed28e0a13b177ed4e918619259cdf06 --- /dev/null +++ b/services/distributed/include/distributed_preferences.h @@ -0,0 +1,60 @@ +/* + * 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 BASE_NOTIFICATION_ANS_STANDARD_SERVICES_DISTRIBUTED_INCLUDE_DISTRIBUTED_PREFERENCES_H +#define BASE_NOTIFICATION_ANS_STANDARD_SERVICES_DISTRIBUTED_INCLUDE_DISTRIBUTED_PREFERENCES_H + +#include +#include + +#include "singleton.h" +#include "refbase.h" + +#include "ans_inner_errors.h" +#include "distributed_preferences_database.h" +#include "distributed_preferences_info.h" +#include "notification_bundle_option.h" + +namespace OHOS { +namespace Notification { +class DistributedPreferences : public DelayedSingleton { +public: + ErrCode SetDistributedEnable(bool isEnable); + ErrCode GetDistributedEnable(bool &isEnable); + ErrCode SetDistributedBundleEnable(const sptr &bundleOption, bool isEnable); + ErrCode GetDistributedBundleEnable(const sptr &bundleOption, bool &isEnable); + ErrCode ClearDataInRestoreFactorySettings(); + +private: + struct ResolveKey { + bool isMainKey = false; + std::string bundleName; + int32_t uid = 0; + }; + bool InitDistributedAllInfo(void); + void GetDistributedMainKey(std::string &key); + void GetDistributedBundleKey(const sptr &bundleOption, std::string &key); + bool ResolveDistributedKey(const std::string &key, ResolveKey &resolveKey); + +private: + std::unique_ptr preferencesInfo_ = nullptr; + std::unique_ptr database_ = nullptr; + + DECLARE_DELAYED_SINGLETON(DistributedPreferences); + DISALLOW_COPY_AND_MOVE(DistributedPreferences); +}; +} // namespace Notification +} // namespace OHOS +#endif /* BASE_NOTIFICATION_ANS_STANDARD_SERVICES_DISTRIBUTED_INCLUDE_DISTRIBUTED_PREFERENCES_H */ diff --git a/services/distributed/include/distributed_preferences_database.h b/services/distributed/include/distributed_preferences_database.h new file mode 100644 index 0000000000000000000000000000000000000000..74f6c210c1f8f216c44da769ffef48ff44803ec0 --- /dev/null +++ b/services/distributed/include/distributed_preferences_database.h @@ -0,0 +1,60 @@ +/* + * 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 BASE_NOTIFICATION_ANS_STANDARD_SERVICES_DISTRIBUTED_INCLUDE_DISTRIBUTED_PREFERENCES_DATABASE_H +#define BASE_NOTIFICATION_ANS_STANDARD_SERVICES_DISTRIBUTED_INCLUDE_DISTRIBUTED_PREFERENCES_DATABASE_H + +#include +#include +#include + +#include "distributed_kv_data_manager.h" +#include "singleton.h" + +#include "distributed_database_callback.h" +#include "distributed_device_callback.h" +#include "distributed_flow_control.h" + +namespace OHOS { +namespace Notification { +class DistributedPreferencesDatabase : private DistributedFlowControl { +public: + using Entry = DistributedKv::Entry; + + DistributedPreferencesDatabase(); + ~DistributedPreferencesDatabase(); + + bool PutToDistributedDB(const std::string &key, const std::string &value); + bool GetFromDistributedDB(const std::string &key, std::string &value); + bool GetEntriesFromDistributedDB(const std::string &prefixKey, std::vector &entries); + bool ClearDatabase(void); + +private: + void GetKvDataManager(void); + bool CheckKvDataManager(void); + void GetKvStore(void); + bool CheckKvStore(void); + +private: + std::mutex mutex_; + std::unique_ptr kvDataManager_; + std::shared_ptr kvStore_; + + DISALLOW_COPY_AND_MOVE(DistributedPreferencesDatabase); +}; +} // namespace Notification +} // namespace OHOS + +#endif /* BASE_NOTIFICATION_ANS_STANDARD_SERVICES_DISTRIBUTED_INCLUDE_DISTRIBUTED_DATABASE_H */ \ No newline at end of file diff --git a/services/distributed/include/distributed_preferences_info.h b/services/distributed/include/distributed_preferences_info.h new file mode 100644 index 0000000000000000000000000000000000000000..860e08871a4eb5abb8ad6963820f8c619247ffd7 --- /dev/null +++ b/services/distributed/include/distributed_preferences_info.h @@ -0,0 +1,40 @@ +/* + * 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 BASE_NOTIFICATION_ANS_STANDARD_SERVICES_DISTRIBUTED_INCLUDE_DISTRIBUTED_PREFERENCES_INFO_H +#define BASE_NOTIFICATION_ANS_STANDARD_SERVICES_DISTRIBUTED_INCLUDE_DISTRIBUTED_PREFERENCES_INFO_H + +#include +#include + +namespace OHOS { +namespace Notification { +class DistributedPreferencesInfo { +public: + DistributedPreferencesInfo(); + ~DistributedPreferencesInfo(); + void SetDistributedEnable(bool enable); + bool GetDistributedEnable(void); + void SetDistributedBundleEnable(const std::string &bundleName, int32_t uid, bool enable); + bool GetDistributedBundleEnable(const std::string &bundleName, int32_t uid); + +private: + bool distributedEnable_ = true; + std::map, bool> bundleEnable_; +}; +} // namespace Notification +} // namespace OHOS + +#endif /* BASE_NOTIFICATION_ANS_STANDARD_SERVICES_DISTRIBUTED_INCLUDE_DISTRIBUTED_PREFERENCES_INFO_H */ \ No newline at end of file diff --git a/services/distributed/src/distributed_database.cpp b/services/distributed/src/distributed_database.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4b60727714d2f98101373a90123b666f4bdbf5ca --- /dev/null +++ b/services/distributed/src/distributed_database.cpp @@ -0,0 +1,322 @@ +/* + * 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 "distributed_database.h" + +#include "ans_log_wrapper.h" + +namespace OHOS { +namespace Notification { +namespace { +const std::string APP_ID = "advanced_notification_service"; +const std::string STORE_ID = "distributed_notification"; +} // namespace + +DistributedDatabase::DistributedDatabase( + std::shared_ptr databaseCb, std::shared_ptr deviceCb) + : DistributedFlowControl(), databaseCb_(databaseCb), deviceCb_(deviceCb) +{ + GetKvDataManager(); + GetKvStore(); +} + +DistributedDatabase::~DistributedDatabase() +{} + +void DistributedDatabase::GetKvDataManager(void) +{ + kvDataManager_ = std::make_unique(); + if (kvDataManager_ != nullptr) { + DistributedKv::Status status = kvDataManager_->StartWatchDeviceChange(deviceCb_); + if (status != DistributedKv::Status::SUCCESS) { + ANS_LOGW("kvDataManager StartWatchDeviceChange failed ret = 0x%{public}x", status); + kvDataManager_.reset(); + } + } + + KvManagerFlowControlClear(); +} + +bool DistributedDatabase::CheckKvDataManager(void) +{ + if (kvDataManager_ == nullptr) { + GetKvDataManager(); + } + if (kvDataManager_ == nullptr) { + ANS_LOGE("kvDataManager is nullptr."); + return false; + } + return true; +} + +void DistributedDatabase::GetKvStore(void) +{ + if (!CheckKvDataManager()) { + return; + } + + DistributedKv::Options options; + options.createIfMissing = true; + options.autoSync = true; + options.kvStoreType = DistributedKv::KvStoreType::SINGLE_VERSION; + DistributedKv::AppId appId = {.appId = APP_ID}; + DistributedKv::StoreId storeId = {.storeId = STORE_ID}; + DistributedKv::Status status = kvDataManager_->GetSingleKvStore(options, appId, storeId, kvStore_); + if (status != DistributedKv::Status::SUCCESS) { + ANS_LOGE("kvDataManager GetSingleKvStore failed ret = 0x%{public}x", status); + kvStore_.reset(); + kvDataManager_->StopWatchDeviceChange(deviceCb_); + kvDataManager_.reset(); + return; + } + + if (kvStore_ != nullptr) { + status = kvStore_->SubscribeKvStore(DistributedKv::SubscribeType::SUBSCRIBE_TYPE_REMOTE, databaseCb_); + if (status != DistributedKv::Status::SUCCESS) { + ANS_LOGE("kvStore SubscribeKvStore failed ret = 0x%{public}x", status); + kvStore_.reset(); + } + } + + KvStoreFlowControlClear(); +} + +bool DistributedDatabase::CheckKvStore(void) +{ + if (kvStore_ == nullptr) { + GetKvStore(); + } + if (kvStore_ == nullptr) { + ANS_LOGE("kvStore is nullptr."); + return false; + } + return true; +} + +bool DistributedDatabase::PutToDistributedDB(const std::string &key, const std::string &value) +{ + std::lock_guard lock(mutex_); + + if (!CheckKvStore()) { + return false; + } + + if (!KvStoreFlowControl()) { + ANS_LOGE("KvStore flow control."); + return false; + } + + DistributedKv::Key kvStoreKey(key); + DistributedKv::Value kvStoreValue(value); + DistributedKv::Status status = kvStore_->Put(kvStoreKey, kvStoreValue); + if (status != DistributedKv::Status::SUCCESS) { + ANS_LOGE("kvStore Put() failed ret = 0x%{public}x", status); + return false; + } + + return true; +} + +bool DistributedDatabase::GetFromDistributedDB(const std::string &key, std::string &value) +{ + std::lock_guard lock(mutex_); + + if (!CheckKvStore()) { + return false; + } + + if (!KvStoreFlowControl()) { + ANS_LOGE("KvStore flow control."); + return false; + } + + DistributedKv::Key kvStoreKey(key); + DistributedKv::Value kvStoreValue; + DistributedKv::Status status = kvStore_->Get(kvStoreKey, kvStoreValue); + if (status != DistributedKv::Status::SUCCESS) { + ANS_LOGE("kvStore Get() failed ret = 0x%{public}x", status); + return false; + } + + value = kvStoreValue.ToString(); + + return true; +} + +bool DistributedDatabase::GetEntriesFromDistributedDB(const std::string &prefixKey, std::vector &entries) +{ + std::lock_guard lock(mutex_); + + if (!CheckKvStore()) { + return false; + } + + if (!KvStoreFlowControl()) { + ANS_LOGE("KvStore flow control."); + return false; + } + + DistributedKv::Key kvStoreKey(prefixKey); + DistributedKv::Status status = kvStore_->GetEntries(kvStoreKey, entries); + if (status != DistributedKv::Status::SUCCESS) { + ANS_LOGE("kvStore GetEntries() failed ret = 0x%{public}x", status); + return false; + } + + return true; +} + +bool DistributedDatabase::DeleteToDistributedDB(const std::string &key) +{ + std::lock_guard lock(mutex_); + + if (!CheckKvStore()) { + return false; + } + + if (!KvStoreFlowControl()) { + ANS_LOGE("KvStore flow control."); + return false; + } + + DistributedKv::Key kvStoreKey(key); + DistributedKv::Status status = kvStore_->Delete(kvStoreKey); + if (status != DistributedKv::Status::SUCCESS) { + ANS_LOGE("kvStore Delete() failed ret = 0x%{public}x", status); + return false; + } + + return true; +} + +bool DistributedDatabase::ClearDataByDevice(const std::string &deviceId) +{ + std::lock_guard lock(mutex_); + + if (!CheckKvStore()) { + return false; + } + + if (!KvStoreFlowControl()) { + ANS_LOGE("KvStore flow control."); + return false; + } + + DistributedKv::Status status = kvStore_->RemoveDeviceData(deviceId); + if (status != DistributedKv::Status::SUCCESS) { + ANS_LOGE("kvStore RemoveDeviceData() failed ret = 0x%{public}x", status); + return false; + } + + return true; +} + +bool DistributedDatabase::GetLocalDeviceId(std::string &deviceId) +{ + std::lock_guard lock(mutex_); + if (!CheckKvDataManager()) { + return false; + } + + if (KvManagerFlowControl()) { + DistributedKv::DeviceInfo deviceInfo; + DistributedKv::Status status = kvDataManager_->GetLocalDevice(deviceInfo); + if (status != DistributedKv::Status::SUCCESS) { + ANS_LOGE("kvDataManager GetLocalDevice() failed ret = 0x%{public}x", status); + return false; + } + + localDeviceId_ = deviceInfo.deviceId; + } + + if (localDeviceId_.empty()) { + return false; + } + + deviceId = localDeviceId_; + + return true; +} + +bool DistributedDatabase::GetLocalDeviceInfo(DeviceInfo &localInfo) +{ + std::lock_guard lock(mutex_); + if (!CheckKvDataManager()) { + return false; + } + + if (!KvManagerFlowControl()) { + ANS_LOGE("KvManager flow control."); + return false; + } + + DistributedKv::Status status = kvDataManager_->GetLocalDevice(localInfo); + if (status != DistributedKv::Status::SUCCESS) { + ANS_LOGE("kvDataManager GetLocalDevice() failed ret = 0x%{public}x", status); + return false; + } + + return true; +} + +bool DistributedDatabase::GetDeviceInfoList(std::vector &deviceList) +{ + std::lock_guard lock(mutex_); + if (!CheckKvDataManager()) { + return false; + } + + if (!KvManagerFlowControl()) { + ANS_LOGE("KvManager flow control."); + return false; + } + + DistributedKv::Status status = + kvDataManager_->GetDeviceList(deviceList, DistributedKv::DeviceFilterStrategy::NO_FILTER); + if (status != DistributedKv::Status::SUCCESS) { + ANS_LOGE("kvDataManager GetDeviceList() failed ret = 0x%{public}x", status); + return false; + } + + return true; +} + +bool DistributedDatabase::RecreateDistributedDB() +{ + std::lock_guard lock(mutex_); + if (!CheckKvDataManager()) { + return false; + } + + if (!KvManagerFlowControl()) { + ANS_LOGE("KvManager flow control."); + return false; + } + + kvStore_.reset(); + + DistributedKv::AppId appId = {.appId = APP_ID}; + DistributedKv::StoreId storeId = {.storeId = STORE_ID}; + DistributedKv::Status status = kvDataManager_->DeleteKvStore(appId, storeId); + if (status != DistributedKv::Status::SUCCESS) { + ANS_LOGE("kvDataManager DeleteKvStore() failed ret = 0x%{public}x", status); + return false; + } + + GetKvStore(); + return true; +} +} // namespace Notification +} // namespace OHOS \ No newline at end of file diff --git a/services/distributed/src/distributed_database_callback.cpp b/services/distributed/src/distributed_database_callback.cpp new file mode 100644 index 0000000000000000000000000000000000000000..53bab4807e9034fde3c293f43d2a7a85b3eee165 --- /dev/null +++ b/services/distributed/src/distributed_database_callback.cpp @@ -0,0 +1,64 @@ +/* + * 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 "distributed_database_callback.h" + +#include "ans_log_wrapper.h" + +namespace OHOS { +namespace Notification { +DistributedDatabaseCallback::DistributedDatabaseCallback(const IDatabaseChange &callback) : callback_(callback) +{} + +DistributedDatabaseCallback::~DistributedDatabaseCallback() +{} + +void DistributedDatabaseCallback::OnChange(const DistributedKv::ChangeNotification &changeNotification, + std::shared_ptr snapshot) +{ + ANS_LOGI("%{public}s start", __FUNCTION__); + return; +} +void DistributedDatabaseCallback::OnChange(const DistributedKv::ChangeNotification &changeNotification) +{ + ANS_LOGI("%{public}s start", __FUNCTION__); + // const std::vector entryList; + + if (callback_.OnInsert) { + const std::vector &entryList = changeNotification.GetInsertEntries(); + ANS_LOGI("GetInsertEntries count %{public}zu", entryList.size()); + for (auto entry : entryList) { + callback_.OnInsert(changeNotification.GetDeviceId(), entry.key.ToString(), entry.value.ToString()); + } + } + + if (callback_.OnUpdate) { + const std::vector &entryList = changeNotification.GetUpdateEntries(); + ANS_LOGI("GetUpdateEntries count %{public}zu", entryList.size()); + for (auto entry : entryList) { + callback_.OnUpdate(changeNotification.GetDeviceId(), entry.key.ToString(), entry.value.ToString()); + } + } + + if (callback_.OnDelete) { + const std::vector &entryList = changeNotification.GetDeleteEntries(); + ANS_LOGI("GetDeleteEntries count %{public}zu", entryList.size()); + for (auto entry : entryList) { + callback_.OnDelete(changeNotification.GetDeviceId(), entry.key.ToString(), entry.value.ToString()); + } + } +} +} // namespace Notification +} // namespace OHOS \ No newline at end of file diff --git a/services/distributed/src/distributed_device_callback.cpp b/services/distributed/src/distributed_device_callback.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6a556ec8a0b1cb420f1215a39d02aa21f8944cb4 --- /dev/null +++ b/services/distributed/src/distributed_device_callback.cpp @@ -0,0 +1,50 @@ +/* + * 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 "distributed_device_callback.h" + +#include "ans_log_wrapper.h" + +namespace OHOS { +namespace Notification { +DistributedDeviceCallback::DistributedDeviceCallback(const IDeviceChange &callback) : callback_(callback) +{} +DistributedDeviceCallback::~DistributedDeviceCallback() +{} + +void DistributedDeviceCallback::OnDeviceChanged( + const DistributedKv::DeviceInfo &info, const DistributedKv::DeviceChangeType &type) const +{ + ANS_LOGI("%{public}s start", __FUNCTION__); + if (type == DistributedKv::DeviceChangeType::DEVICE_ONLINE) { + ANS_LOGI("device %{public}s is ONLINE", info.deviceId.c_str()); + if (callback_.OnConnected) { + callback_.OnConnected(info.deviceId); + } + } + + if (type == DistributedKv::DeviceChangeType::DEVICE_OFFLINE) { + ANS_LOGI("device %{public}s is OFFLINE", info.deviceId.c_str()); + if (callback_.OnDisconnected) { + callback_.OnDisconnected(info.deviceId); + } + } +} +DistributedKv::DeviceFilterStrategy DistributedDeviceCallback::GetFilterStrategy() const +{ + return DistributedKv::DeviceFilterStrategy::NO_FILTER; +} +} // namespace Notification +} // namespace OHOS \ No newline at end of file diff --git a/services/distributed/src/distributed_flow_control.cpp b/services/distributed/src/distributed_flow_control.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fabe5b589777f392bc4f4ac568a45253657f65a7 --- /dev/null +++ b/services/distributed/src/distributed_flow_control.cpp @@ -0,0 +1,94 @@ +/* + * 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 "distributed_flow_control.h" + +namespace OHOS { +namespace Notification { +DistributedFlowControl::DistributedFlowControl( + int kvManagerSecondMaxinum, int kvManagerMinuteMaxinum, int kvStoreSecondMaxinum, int kvStoreMinuteMaxinum) + : kvManagerSecondMaxinum_(kvManagerSecondMaxinum), + kvManagerMinuteMaxinum_(kvManagerMinuteMaxinum), + kvStoreSecondMaxinum_(kvStoreSecondMaxinum), + kvStoreMinuteMaxinum_(kvStoreMinuteMaxinum) +{} + +bool DistributedFlowControl::KvManagerFlowControl(void) +{ + std::chrono::system_clock::time_point now = std::chrono::system_clock::now(); + kvDataManagerTimestampList_.remove_if([&](const std::chrono::system_clock::time_point &value) -> bool { + return now - value > std::chrono::minutes(1); + }); + + int listSize = kvStoreTimestampList_.size(); + if (listSize >= kvManagerMinuteMaxinum_) { + return false; + } + + int count = 0; + for (auto value : kvDataManagerTimestampList_) { + if (now - value > std::chrono::seconds(1)) { + if (count >= kvManagerSecondMaxinum_) { + return false; + } else { + break; + } + } + count++; + } + + kvDataManagerTimestampList_.push_front(now); + return true; +} + +bool DistributedFlowControl::KvStoreFlowControl(void) +{ + std::chrono::system_clock::time_point now = std::chrono::system_clock::now(); + kvStoreTimestampList_.remove_if([&](const std::chrono::system_clock::time_point &value) -> bool { + return now - value > std::chrono::minutes(1); + }); + + int listSize = kvStoreTimestampList_.size(); + if (listSize >= kvStoreMinuteMaxinum_) { + return false; + } + + int count = 0; + for (auto value : kvStoreTimestampList_) { + if (now - value > std::chrono::seconds(1)) { + if (count >= kvStoreSecondMaxinum_) { + return false; + } else { + break; + } + } + count++; + } + + kvStoreTimestampList_.push_front(now); + return true; +} + +void DistributedFlowControl::KvManagerFlowControlClear(void) +{ + kvDataManagerTimestampList_.clear(); +} + +void DistributedFlowControl::KvStoreFlowControlClear(void) +{ + kvStoreTimestampList_.clear(); +} +} // namespace Notification +} // namespace OHOS diff --git a/services/distributed/src/distributed_notification_manager.cpp b/services/distributed/src/distributed_notification_manager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..be2dba32af65c19d111c4783ef1904f6560a2528 --- /dev/null +++ b/services/distributed/src/distributed_notification_manager.cpp @@ -0,0 +1,424 @@ +/* + * 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 "distributed_notification_manager.h" + +#include + +#include "ans_inner_errors.h" +#include "ans_log_wrapper.h" + +namespace OHOS { +namespace Notification { +namespace { +const std::string DELIMITER = "|"; +} // namespace + +DistributedNotificationManager::DistributedNotificationManager() +{ + runner_ = OHOS::AppExecFwk::EventRunner::Create(); + handler_ = std::make_shared(runner_); + + DistributedDatabaseCallback::IDatabaseChange databaseCallback = { + .OnInsert = std::bind(&DistributedNotificationManager::OnDatabaseInsert, + this, + std::placeholders::_1, + std::placeholders::_2, + std::placeholders::_3), + .OnUpdate = std::bind(&DistributedNotificationManager::OnDatabaseUpdate, + this, + std::placeholders::_1, + std::placeholders::_2, + std::placeholders::_3), + .OnDelete = std::bind(&DistributedNotificationManager::OnDatabaseDelete, + this, + std::placeholders::_1, + std::placeholders::_2, + std::placeholders::_3), + }; + databaseCb_ = std::make_shared(databaseCallback); + + DistributedDeviceCallback::IDeviceChange deviceCallback = { + .OnConnected = std::bind(&DistributedNotificationManager::OnDeviceConnected, this, std::placeholders::_1), + .OnDisconnected = std::bind(&DistributedNotificationManager::OnDeviceDisconnected, this, std::placeholders::_1), + }; + deviceCb_ = std::make_shared(deviceCallback); + + database_ = std::make_shared(databaseCb_, deviceCb_); + if (database_ == nullptr) { + ANS_LOGE("database_ is nullptr."); + return; + } + database_->RecreateDistributedDB(); +} + +DistributedNotificationManager::~DistributedNotificationManager() +{ + handler_->PostSyncTask(std::bind([&]() { callback_ = {}; }), AppExecFwk::EventHandler::Priority::HIGH); +} + +void DistributedNotificationManager::GenerateDistributedKey( + const std::string &deviceId, const std::string &bundleName, const std::string &label, int32_t id, std::string &key) +{ + key = deviceId + DELIMITER + bundleName + DELIMITER + label + DELIMITER + ToString(id); +} + +bool DistributedNotificationManager::GenerateLocalDistributedKey( + const std::string &bundleName, const std::string &label, int32_t id, std::string &key) +{ + std::string deviceId; + if (!database_->GetLocalDeviceId(deviceId)) { + return false; + } + + GenerateDistributedKey(deviceId, bundleName, label, id, key); + return true; +} + +bool DistributedNotificationManager::ResolveDistributedKey(const std::string &key, ResolveKey &resolveKey) +{ + std::size_t deviceIdPosition = 0; + std::size_t deviceIdEndPosition = key.find(DELIMITER, deviceIdPosition); + if (deviceIdEndPosition == std::string::npos) { + return false; + } + std::size_t bundleNamePosition = deviceIdEndPosition + DELIMITER.size(); + std::size_t bundleNameEndPosition = key.find(DELIMITER, bundleNamePosition); + if (bundleNameEndPosition == std::string::npos) { + return false; + } + std::size_t labelPosition = bundleNameEndPosition + DELIMITER.size(); + std::size_t labelEndPosition = key.find_last_of(DELIMITER) - DELIMITER.size() + 1; + if (labelEndPosition < labelPosition) { + return false; + } + std::size_t idPosition = key.find_last_of(DELIMITER) + DELIMITER.size(); + + resolveKey.deviceId = key.substr(deviceIdPosition, deviceIdEndPosition - deviceIdPosition); + resolveKey.bundleName = key.substr(bundleNamePosition, bundleNameEndPosition - bundleNamePosition); + resolveKey.label = key.substr(labelPosition, labelEndPosition - labelPosition); + resolveKey.id = atoi(&key[idPosition]); + + return true; +} + +bool DistributedNotificationManager::CheckDeviceId(const std::string &deviceId, const std::string &key) +{ + ResolveKey resolveKey; + if (!ResolveDistributedKey(key, resolveKey)) { + ANS_LOGE("key <%{public}s> is invalid.", key.c_str()); + return false; + } + + return deviceId == resolveKey.deviceId; +} + +void DistributedNotificationManager::OnDatabaseInsert( + const std::string &deviceId, const std::string &key, const std::string &value) +{ + ANS_LOGD("%{public}s", __FUNCTION__); + handler_->PostTask(std::bind([=]() { + if (!CheckDeviceId(deviceId, key)) { + ANS_LOGW("device id are not the same. deviceId:%{public}s key:%{public}s", deviceId.c_str(), key.c_str()); + } + + ResolveKey resolveKey; + if (!ResolveDistributedKey(key, resolveKey)) { + ANS_LOGE("key <%{public}s> is invalid.", key.c_str()); + return; + } + + sptr request = + NotificationJsonConverter::ConvertFromJosnString(value); + if (request == nullptr) { + ANS_LOGE("convert json to request failed. key:%{public}s", key.c_str()); + return; + } + + PublishCallback(resolveKey.deviceId, resolveKey.bundleName, request); + })); +} + +void DistributedNotificationManager::OnDatabaseUpdate( + const std::string &deviceId, const std::string &key, const std::string &value) +{ + ANS_LOGD("%{public}s", __FUNCTION__); + handler_->PostTask(std::bind([=]() { + if (!CheckDeviceId(deviceId, key)) { + ANS_LOGW("device id are not the same. deviceId:%{public}s key:%{public}s", deviceId.c_str(), key.c_str()); + } + + ResolveKey resolveKey; + if (!ResolveDistributedKey(key, resolveKey)) { + ANS_LOGE("key <%{public}s> is invalid.", key.c_str()); + return; + } + + sptr request = + NotificationJsonConverter::ConvertFromJosnString(value); + if (request == nullptr) { + ANS_LOGE("convert json to request failed. key:%{public}s", key.c_str()); + return; + } + + UpdateCallback(resolveKey.deviceId, resolveKey.bundleName, request); + })); +} + +void DistributedNotificationManager::OnDatabaseDelete( + const std::string &deviceId, const std::string &key, const std::string &value) +{ + ANS_LOGD("%{public}s", __FUNCTION__); + handler_->PostTask(std::bind([=]() { + if (!CheckDeviceId(deviceId, key)) { + ANS_LOGW("device id are not the same. deviceId:%{public}s key:%{public}s", deviceId.c_str(), key.c_str()); + } + + ResolveKey resolveKey; + if (!ResolveDistributedKey(key, resolveKey)) { + ANS_LOGE("key <%{public}s> is invalid.", key.c_str()); + return; + } + + DeleteCallback(resolveKey.deviceId, resolveKey.bundleName, resolveKey.label, resolveKey.id); + })); +} + +void DistributedNotificationManager::OnDeviceConnected(const std::string &deviceId) +{ + ANS_LOGD("%{public}s", __FUNCTION__); + handler_->PostTask(std::bind([=]() {})); + return; +} + +void DistributedNotificationManager::OnDeviceDisconnected(const std::string &deviceId) +{ + ANS_LOGD("%{public}s", __FUNCTION__); + + handler_->PostTask(std::bind([=]() { + std::string prefixKey = deviceId + DELIMITER; + std::vector entries; + if (!database_->GetEntriesFromDistributedDB(prefixKey, entries)) { + ANS_LOGE("GetEntriesFromDistributedDB failed."); + return; + } + + for (auto index : entries) { + ResolveKey resolveKey; + if (!ResolveDistributedKey(index.key.ToString(), resolveKey)) { + ANS_LOGE("key <%{public}s> is invalid.", index.key.ToString().c_str()); + continue; + } + + DeleteCallback(resolveKey.deviceId, resolveKey.bundleName, resolveKey.label, resolveKey.id); + } + + database_->ClearDataByDevice(deviceId); + + std::vector deviceList; + if (database_->GetDeviceInfoList(deviceList) == ERR_OK && deviceList.empty()) { + database_->RecreateDistributedDB(); + } + })); + return; +} + +bool DistributedNotificationManager::PublishCallback( + const std::string &deviceId, const std::string &bundleName, sptr &request) +{ + ANS_LOGI("callback_.OnPublish start."); + if (callback_.OnPublish) { + callback_.OnPublish(deviceId, bundleName, request); + } + ANS_LOGI("callback_.OnPublish end."); + + return true; +} + +bool DistributedNotificationManager::UpdateCallback( + const std::string &deviceId, const std::string &bundleName, sptr &request) +{ + ANS_LOGI("callback_.OnUpdate start."); + if (callback_.OnUpdate) { + callback_.OnUpdate(deviceId, bundleName, request); + } + ANS_LOGI("callback_.OnUpdate end."); + + return true; +} + +bool DistributedNotificationManager::DeleteCallback( + const std::string &deviceId, const std::string &bundleName, const std::string &label, int32_t id) +{ + ANS_LOGI("callback_.OnDelete start."); + if (callback_.OnDelete) { + callback_.OnDelete(deviceId, bundleName, label, id); + } + ANS_LOGI("callback_.OnDelete end."); + + return true; +} + +ErrCode DistributedNotificationManager::Publish( + const std::string &bundleName, const std::string &label, int32_t id, const sptr &request) +{ + ANS_LOGI("%{public}s start", __FUNCTION__); + std::string key; + if (!GenerateLocalDistributedKey(bundleName, label, id, key)) { + ANS_LOGE("Generate distributed key failed."); + return ERR_ANS_DISTRIBUTED_GET_INFO_FAILED; + } + + std::string value; + if (!NotificationJsonConverter::ConvertToJosnString(request, value)) { + ANS_LOGE("convert request to json failed. key:%{public}s", key.c_str()); + return ERR_ANS_DISTRIBUTED_OPERATION_FAILED; + } + + if (!database_->PutToDistributedDB(key, value)) { + ANS_LOGE("put to distributed DB failed. key:%{public}s", key.c_str()); + return ERR_ANS_DISTRIBUTED_OPERATION_FAILED; + } + + return ERR_OK; +} + +ErrCode DistributedNotificationManager::Update( + const std::string &bundleName, const std::string &label, int32_t id, const sptr &request) +{ + ANS_LOGI("%{public}s start", __FUNCTION__); + std::string key; + if (!GenerateLocalDistributedKey(bundleName, label, id, key)) { + ANS_LOGE("Generate distributed key failed."); + return ERR_ANS_DISTRIBUTED_GET_INFO_FAILED; + } + + std::string value; + if (!NotificationJsonConverter::ConvertToJosnString(request, value)) { + ANS_LOGE("convert request to json failed. key:%{public}s", key.c_str()); + return ERR_ANS_DISTRIBUTED_OPERATION_FAILED; + } + + if (!database_->PutToDistributedDB(key, value)) { + ANS_LOGE("put to distributed DB failed. key:%{public}s", key.c_str()); + return ERR_ANS_DISTRIBUTED_OPERATION_FAILED; + } + return ERR_OK; +} + +ErrCode DistributedNotificationManager::Delete(const std::string &bundleName, const std::string &label, int32_t id) +{ + ANS_LOGI("%{public}s start", __FUNCTION__); + std::string key; + if (!GenerateLocalDistributedKey(bundleName, label, id, key)) { + ANS_LOGE("Generate distributed key failed."); + return ERR_ANS_DISTRIBUTED_GET_INFO_FAILED; + } + + if (!database_->DeleteToDistributedDB(key)) { + ANS_LOGE("delete to distributed DB failed. key:%{public}s", key.c_str()); + return ERR_ANS_DISTRIBUTED_OPERATION_FAILED; + } + return ERR_OK; +} + +ErrCode DistributedNotificationManager::DeleteRemoteNotification( + const std::string &deviceId, const std::string &bundleName, const std::string &label, int32_t id) +{ + ANS_LOGI("%{public}s start", __FUNCTION__); + + std::string key; + GenerateDistributedKey(deviceId, bundleName, label, id, key); + + if (!database_->DeleteToDistributedDB(key)) { + ANS_LOGE("delete to distributed DB failed. key:%{public}s", key.c_str()); + return ERR_ANS_DISTRIBUTED_OPERATION_FAILED; + } + return ERR_OK; +} + +ErrCode DistributedNotificationManager::RegisterCallback(const IDistributedCallback &callback) +{ + ANS_LOGI("%{public}s start", __FUNCTION__); + handler_->PostSyncTask(std::bind([&]() { callback_ = callback; }), AppExecFwk::EventHandler::Priority::HIGH); + return ERR_OK; +} + +ErrCode DistributedNotificationManager::UngegisterCallback(void) +{ + ANS_LOGI("%{public}s start", __FUNCTION__); + handler_->PostSyncTask(std::bind([&]() { callback_ = {}; }), AppExecFwk::EventHandler::Priority::HIGH); + return ERR_OK; +} + +ErrCode DistributedNotificationManager::GetCurrentDistributedNotification( + std::vector> &requestList) +{ + ANS_LOGI("%{public}s start", __FUNCTION__); + std::string prefixKey = ""; + std::vector entries; + if (!database_->GetEntriesFromDistributedDB(prefixKey, entries)) { + ANS_LOGE("GetEntriesFromDistributedDB failed."); + return ERR_ANS_DISTRIBUTED_OPERATION_FAILED; + } + + for (auto index : entries) { + ResolveKey resolveKey; + if (!ResolveDistributedKey(index.key.ToString(), resolveKey)) { + ANS_LOGE("key <%{public}s> is invalid.", index.key.ToString().c_str()); + continue; + } + + sptr request = + NotificationJsonConverter::ConvertFromJosnString(index.value.ToString()); + if (request == nullptr) { + ANS_LOGE("convert json to request failed. key:%{public}s", index.key.ToString().c_str()); + continue; + } + + PublishCallback(resolveKey.deviceId, resolveKey.bundleName, request); + } + + return ERR_OK; +} + +ErrCode DistributedNotificationManager::GetLocalDeviceInfo(DistributedDatabase::DeviceInfo &deviceInfo) +{ + ANS_LOGI("%{public}s start", __FUNCTION__); + + if (!database_->GetLocalDeviceInfo(deviceInfo)) { + return ERR_ANS_DISTRIBUTED_OPERATION_FAILED; + } + + return ERR_OK; +} + +ErrCode DistributedNotificationManager::OnDistributedKvStoreDeathRecipient() +{ + ANS_LOGI("%{public}s start", __FUNCTION__); + + database_ = std::make_shared(databaseCb_, deviceCb_); + if (database_ == nullptr) { + ANS_LOGE("database_ is nullptr."); + return ERR_ANS_NO_MEMORY; + } + if (!database_->RecreateDistributedDB()) { + ANS_LOGE("RecreateDistributedDB failed."); + return ERR_ANS_DISTRIBUTED_OPERATION_FAILED; + } + return ERR_OK; +} +} // namespace Notification +} // namespace OHOS \ No newline at end of file diff --git a/services/distributed/src/distributed_preferences.cpp b/services/distributed/src/distributed_preferences.cpp new file mode 100644 index 0000000000000000000000000000000000000000..767ee909a58409b29d58d54899edcd184884e3b2 --- /dev/null +++ b/services/distributed/src/distributed_preferences.cpp @@ -0,0 +1,195 @@ +/* + * 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 "distributed_preferences.h" + +#include + +#include "ans_log_wrapper.h" + +namespace OHOS { +namespace Notification { +namespace { +const std::string DISTRIBUTED_LABEL = "distributed"; +const std::string DELIMITER = "|"; +const std::string MAIN_LABEL = "ans_main"; +const std::string BUNDLE_LABEL = "bundle"; +} // namespace + +inline bool GetBoolFromString(const std::string &str) +{ + return static_cast(atoi(str.data())); +} + +DistributedPreferences::DistributedPreferences() +{ + database_ = std::make_unique(); + + preferencesInfo_ = std::make_unique(); + InitDistributedAllInfo(); +} + +DistributedPreferences::~DistributedPreferences() +{} + +bool DistributedPreferences::InitDistributedAllInfo(void) +{ + std::vector entries; + if (!database_->GetEntriesFromDistributedDB(DISTRIBUTED_LABEL, entries)) { + return false; + } + + for (auto entry : entries) { + ResolveKey resolveKey; + if (!ResolveDistributedKey(entry.key.ToString(), resolveKey)) { + ANS_LOGE("key <%{public}s> is invalid.", entry.key.ToString().c_str()); + continue; + } + + if (resolveKey.isMainKey) { + int value = atoi(entry.value.ToString().data()); + preferencesInfo_->SetDistributedEnable(static_cast(value)); + } else { + preferencesInfo_->SetDistributedBundleEnable( + resolveKey.bundleName, resolveKey.uid, GetBoolFromString(entry.value.ToString())); + } + } + + return true; +} + +void DistributedPreferences::GetDistributedMainKey(std::string &key) +{ + key = DISTRIBUTED_LABEL + DELIMITER + MAIN_LABEL + DELIMITER; +} + +void DistributedPreferences::GetDistributedBundleKey( + const sptr &bundleOption, std::string &key) +{ + key = DISTRIBUTED_LABEL + DELIMITER + BUNDLE_LABEL + DELIMITER + bundleOption->GetBundleName() + DELIMITER + + std::to_string(bundleOption->GetUid()); +} + +bool DistributedPreferences::ResolveDistributedKey(const std::string &key, ResolveKey &resolveKey) +{ + std::size_t distributedLabelPosition = 0; + std::size_t distributedLabelEndPosition = key.find(DELIMITER, distributedLabelPosition); + if (distributedLabelEndPosition == std::string::npos) { + return false; + } + std::size_t typeLabelPosition = distributedLabelEndPosition + DELIMITER.size(); + std::size_t typeLabelEndPosition = key.find(DELIMITER, typeLabelPosition); + if (typeLabelPosition == std::string::npos) { + return false; + } + + if (key.substr(typeLabelPosition, typeLabelEndPosition - typeLabelPosition).compare(MAIN_LABEL) == 0) { + resolveKey.isMainKey = true; + return true; + } + + std::size_t bundleNamePosition = typeLabelEndPosition + DELIMITER.size(); + std::size_t bundleNameEndPosition = key.find(DELIMITER, bundleNamePosition); + if (bundleNameEndPosition == std::string::npos) { + return false; + } + + std::size_t uidPosition = key.find_last_of(DELIMITER) + DELIMITER.size(); + if (uidPosition < bundleNameEndPosition) { + return false; + } + + resolveKey.isMainKey = false; + resolveKey.bundleName = key.substr(bundleNamePosition, bundleNameEndPosition - bundleNamePosition); + resolveKey.uid = atoi(&key[uidPosition]); + + return true; +} + +ErrCode DistributedPreferences::SetDistributedEnable(bool isEnable) +{ + ANS_LOGI("%{public}s start", __FUNCTION__); + std::string key; + GetDistributedMainKey(key); + + if (!database_->PutToDistributedDB(key, std::to_string(isEnable))) { + ANS_LOGE("put to distributed DB failed. key:%{public}s", key.c_str()); + return ERR_ANS_DISTRIBUTED_OPERATION_FAILED; + } + + preferencesInfo_->SetDistributedEnable(isEnable); + + return ERR_OK; +} + +ErrCode DistributedPreferences::GetDistributedEnable(bool &isEnable) +{ + ANS_LOGI("%{public}s start", __FUNCTION__); + + isEnable = preferencesInfo_->GetDistributedEnable(); + + return ERR_OK; +} + +ErrCode DistributedPreferences::SetDistributedBundleEnable( + const sptr &bundleOption, bool isEnable) +{ + ANS_LOGI("%{public}s start", __FUNCTION__); + if (bundleOption == nullptr) { + ANS_LOGE("bundleOption is nullptr."); + return ERR_ANS_INVALID_PARAM; + } + + std::string key; + GetDistributedBundleKey(bundleOption, key); + + if (!database_->PutToDistributedDB(key, std::to_string(isEnable))) { + ANS_LOGE("put to distributed DB failed. key:%{public}s", key.c_str()); + return ERR_ANS_DISTRIBUTED_OPERATION_FAILED; + } + + preferencesInfo_->SetDistributedBundleEnable(bundleOption->GetBundleName(), bundleOption->GetUid(), isEnable); + + return ERR_OK; +} + +ErrCode DistributedPreferences::GetDistributedBundleEnable( + const sptr &bundleOption, bool &isEnable) +{ + ANS_LOGI("%{public}s start", __FUNCTION__); + if (bundleOption == nullptr) { + ANS_LOGE("bundleOption is nullptr."); + return ERR_ANS_INVALID_PARAM; + } + + isEnable = preferencesInfo_->GetDistributedBundleEnable(bundleOption->GetBundleName(), bundleOption->GetUid()); + + return ERR_OK; +} + +ErrCode DistributedPreferences::ClearDataInRestoreFactorySettings() +{ + if (!database_->ClearDatabase()) { + return ERR_ANS_DISTRIBUTED_OPERATION_FAILED; + } + + SetDistributedEnable(false); + + preferencesInfo_ = std::make_unique(); + + return ERR_OK; +} +} // namespace Notification +} // namespace OHOS \ No newline at end of file diff --git a/services/distributed/src/distributed_preferences_database.cpp b/services/distributed/src/distributed_preferences_database.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9da4c0a75b97afe2f129bcf0c023d46babed9fb6 --- /dev/null +++ b/services/distributed/src/distributed_preferences_database.cpp @@ -0,0 +1,192 @@ +/* + * 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 "distributed_preferences_database.h" + +#include "ans_log_wrapper.h" + +namespace OHOS { +namespace Notification { +namespace { +const std::string APP_ID = "advanced_notification_service"; +const std::string STORE_ID = "distributed_preferences"; +} // namespace + +DistributedPreferencesDatabase::DistributedPreferencesDatabase() : DistributedFlowControl() +{ + GetKvDataManager(); + GetKvStore(); +} + +DistributedPreferencesDatabase::~DistributedPreferencesDatabase() +{} + +void DistributedPreferencesDatabase::GetKvDataManager(void) +{ + kvDataManager_ = std::make_unique(); + + KvManagerFlowControlClear(); +} + +bool DistributedPreferencesDatabase::CheckKvDataManager(void) +{ + if (kvDataManager_ == nullptr) { + GetKvDataManager(); + } + if (kvDataManager_ == nullptr) { + return false; + } + return true; +} + +void DistributedPreferencesDatabase::GetKvStore(void) +{ + if (!CheckKvDataManager()) { + return; + } + + DistributedKv::Status status; + DistributedKv::Options options; + options.createIfMissing = true; + options.autoSync = false; + options.kvStoreType = DistributedKv::KvStoreType::SINGLE_VERSION; + + DistributedKv::AppId appId = {.appId = APP_ID}; + DistributedKv::StoreId storeId = {.storeId = STORE_ID}; + status = kvDataManager_->GetSingleKvStore(options, appId, storeId, kvStore_); + if (status != DistributedKv::Status::SUCCESS) { + ANS_LOGE("kvDataManager GetSingleKvStore failed ret = 0x%{public}x", status); + kvStore_.reset(); + kvDataManager_.reset(); + } + + KvStoreFlowControlClear(); +} + +bool DistributedPreferencesDatabase::CheckKvStore(void) +{ + if (kvStore_ == nullptr) { + GetKvStore(); + } + if (kvStore_ == nullptr) { + return false; + } + return true; +} + +bool DistributedPreferencesDatabase::PutToDistributedDB(const std::string &key, const std::string &value) +{ + std::lock_guard lock(mutex_); + + if (!CheckKvStore()) { + return false; + } + + if (!KvStoreFlowControl()) { + ANS_LOGE("kvStore flow control."); + return false; + } + + DistributedKv::Key kvStoreKey(key); + DistributedKv::Value kvStoreValue(value); + DistributedKv::Status status = kvStore_->Put(kvStoreKey, kvStoreValue); + if (status != DistributedKv::Status::SUCCESS) { + ANS_LOGE("kvStore Put() failed ret = 0x%{public}x", status); + return false; + } + + return true; +} + +bool DistributedPreferencesDatabase::GetFromDistributedDB(const std::string &key, std::string &value) +{ + std::lock_guard lock(mutex_); + + if (!CheckKvStore()) { + return false; + } + + if (!KvStoreFlowControl()) { + ANS_LOGE("kvStore flow control."); + return false; + } + + DistributedKv::Key kvStoreKey(key); + DistributedKv::Value kvStoreValue; + DistributedKv::Status status = kvStore_->Get(kvStoreKey, kvStoreValue); + if (status != DistributedKv::Status::SUCCESS) { + ANS_LOGE("kvStore Get() failed ret = 0x%{public}x", status); + return false; + } + + value = kvStoreValue.ToString(); + + return true; +} + +bool DistributedPreferencesDatabase::GetEntriesFromDistributedDB( + const std::string &prefixKey, std::vector &entries) +{ + std::lock_guard lock(mutex_); + + if (!CheckKvStore()) { + return false; + } + + if (!KvStoreFlowControl()) { + ANS_LOGE("kvStore flow control."); + return false; + } + + DistributedKv::Key kvStoreKey(prefixKey); + DistributedKv::Status status = kvStore_->GetEntries(kvStoreKey, entries); + if (status != DistributedKv::Status::SUCCESS) { + ANS_LOGE("kvStore GetEntries() failed ret = 0x%{public}x", status); + return false; + } + + return true; +} + +bool DistributedPreferencesDatabase::ClearDatabase(void) +{ + std::lock_guard lock(mutex_); + + if (!CheckKvDataManager()) { + return false; + } + + if (!KvManagerFlowControl()) { + ANS_LOGE("kvDataManager flow control."); + return false; + } + + DistributedKv::AppId appId = {.appId = APP_ID}; + DistributedKv::StoreId storeId = {.storeId = STORE_ID}; + DistributedKv::Status status = kvDataManager_->CloseKvStore(appId, storeId); + if (status != DistributedKv::Status::SUCCESS) { + ANS_LOGE("kvDataManager CloseKvStore() failed ret = 0x%{public}x", status); + return false; + } + + status = kvDataManager_->DeleteKvStore(appId, storeId); + if (status != DistributedKv::Status::SUCCESS) { + ANS_LOGE("kvDataManager DeleteKvStore() failed ret = 0x%{public}x", status); + return false; + } + return true; +} +} // namespace Notification +} // namespace OHOS \ No newline at end of file diff --git a/services/distributed/src/distributed_preferences_info.cpp b/services/distributed/src/distributed_preferences_info.cpp new file mode 100644 index 0000000000000000000000000000000000000000..11f2d28b70c2508ced0e9bde3f0ab0b5d7fd6211 --- /dev/null +++ b/services/distributed/src/distributed_preferences_info.cpp @@ -0,0 +1,54 @@ +/* + * 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 "distributed_preferences_info.h" + +#include "ans_log_wrapper.h" + +namespace OHOS { +namespace Notification { +DistributedPreferencesInfo::DistributedPreferencesInfo() +{} + +DistributedPreferencesInfo::~DistributedPreferencesInfo() +{} + +void DistributedPreferencesInfo::SetDistributedEnable(bool enable) +{ + distributedEnable_ = enable; +} + +bool DistributedPreferencesInfo::GetDistributedEnable(void) +{ + return distributedEnable_; +} + +void DistributedPreferencesInfo::SetDistributedBundleEnable(const std::string &bundleName, int32_t uid, bool enable) +{ + bundleEnable_[std::make_pair(bundleName, uid)] = enable; +} + +bool DistributedPreferencesInfo::GetDistributedBundleEnable(const std::string &bundleName, int32_t uid) +{ + auto iter = bundleEnable_.find(std::make_pair(bundleName, uid)); + if (iter == bundleEnable_.end()) { + ANS_LOGW("bundle %{public}s(%{public}d) not found.", bundleName.c_str(), uid); + return true; + } + + return iter->second; +} +} // namespace Notification +} // namespace OHOS \ No newline at end of file diff --git a/services/distributed/test/unittest/BUILD.gn b/services/distributed/test/unittest/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..1a3e4b479579686cb399375a7d1bd0a714757112 --- /dev/null +++ b/services/distributed/test/unittest/BUILD.gn @@ -0,0 +1,79 @@ +# Copyright (c) 2021 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. + +import("//base/notification/ans_standard/notification.gni") +import("//build/ohos.gni") +import("//build/test.gni") + +group("ans_distributed_unit_test_target") { + testonly = true + deps = [] + + if (distributed_notification_supported) { + deps += [ ":ans_distributed_unit_test" ] + } +} + +ohos_unittest("ans_distributed_unit_test") { + module_out_path = "ans_standard/unittest" + include_dirs = [ + "/${services_path}/distributed/include", + "//base/hiviewdfx/hilog/interfaces/native/innerkits/include", + "//base/hiviewdfx/hitrace/interfaces/native/innerkits/include", + "//foundation/aafwk/standard/interfaces/innerkits/base/include", + "//foundation/appexecfwk/standard/interfaces/innerkits/appexecfwk_base/include", + "//foundation/appexecfwk/standard/libs/libeventhandler/src", + "//foundation/communication/ipc/interfaces/innerkits/ipc_core/include", + "//foundation/distributeddatamgr/distributeddatamgr/interfaces/innerkits/distributeddata/include", + "//foundation/distributedschedule/dmsfwk/services/dtbschedmgr/include", + "//utils/native/base/include", + ] + + sources = [ + "${services_path}/distributed/src/distributed_database.cpp", + "${services_path}/distributed/src/distributed_database_callback.cpp", + "${services_path}/distributed/src/distributed_device_callback.cpp", + "${services_path}/distributed/src/distributed_flow_control.cpp", + "${services_path}/distributed/src/distributed_notification_manager.cpp", + "${services_path}/distributed/src/distributed_preferences.cpp", + "${services_path}/distributed/src/distributed_preferences_database.cpp", + "${services_path}/distributed/src/distributed_preferences_info.cpp", + "${services_path}/distributed/test/unittest/distributed_database_test.cpp", + "${services_path}/distributed/test/unittest/distributed_notification_manager_test.cpp", + "${services_path}/distributed/test/unittest/distributed_preferences_test.cpp", + "${services_path}/distributed/test/unittest/mock/ans_test_single_kv_store.cpp", + "${services_path}/distributed/test/unittest/mock/mock_blob.cpp", + "${services_path}/distributed/test/unittest/mock/mock_change_notification.cpp", + "${services_path}/distributed/test/unittest/mock/mock_distributed_kv_data_manager.cpp", + "${services_path}/distributed/test/unittest/mock/mock_event_handler.cpp", + "${services_path}/distributed/test/unittest/mock/mock_event_runner.cpp", + "${services_path}/distributed/test/unittest/mock/mock_inner_event.cpp", + ] + + configs = [ + "${services_path}/distributed/:ans_distributed_config", + "${core_path}:public_ans_core_config", + "${frameworks_path}/ans/native:ans_innerkits_public_config", + ] + + deps = [ + "${core_path}:ans_core", + "//third_party/googletest:gtest_main", + "//utils/native/base:utils", + ] + + external_deps = [ "hiviewdfx_hilog_native:libhilog" ] + + subsystem_name = "notification" + part_name = "ans_standard" +} diff --git a/services/distributed/test/unittest/distributed_database_test.cpp b/services/distributed/test/unittest/distributed_database_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f94a86995b037121c46699b1fb0f8f63033e66d5 --- /dev/null +++ b/services/distributed/test/unittest/distributed_database_test.cpp @@ -0,0 +1,193 @@ +/* + * 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 + +#include "gtest/gtest.h" + +#include "distributed_database.h" + +using namespace testing::ext; +namespace OHOS { +namespace Notification { +class DistributedDatabaseTest : public testing::Test { +public: + void SetUp() override; + void TearDown() override; + +public: + virtual void OnInsert(const std::string &deviceId, const std::string &key, const std::string &value); + virtual void OnUpdate(const std::string &deviceId, const std::string &key, const std::string &value); + virtual void OnDelete(const std::string &deviceId, const std::string &key, const std::string &value); + virtual void OnConnected(const std::string &deviceId); + virtual void OnDisconnected(const std::string &deviceId); + +protected: + std::shared_ptr database_; + std::shared_ptr databaseCallback_; + std::shared_ptr deviceCallback_; +}; + +void DistributedDatabaseTest::SetUp() +{ + DistributedDatabaseCallback::IDatabaseChange databaseCallback = { + .OnInsert = std::bind(&DistributedDatabaseTest::OnInsert, + this, + std::placeholders::_1, + std::placeholders::_2, + std::placeholders::_3), + .OnUpdate = std::bind(&DistributedDatabaseTest::OnUpdate, + this, + std::placeholders::_1, + std::placeholders::_2, + std::placeholders::_3), + .OnDelete = std::bind(&DistributedDatabaseTest::OnDelete, + this, + std::placeholders::_1, + std::placeholders::_2, + std::placeholders::_3), + }; + DistributedDeviceCallback::IDeviceChange deviceCallback = { + .OnConnected = std::bind(&DistributedDatabaseTest::OnConnected, this, std::placeholders::_1), + .OnDisconnected = std::bind(&DistributedDatabaseTest::OnDisconnected, this, std::placeholders::_1), + }; + + databaseCallback_ = std::make_shared(databaseCallback); + deviceCallback_ = std::make_shared(deviceCallback); + database_ = std::make_shared(databaseCallback_, deviceCallback_); +} + +void DistributedDatabaseTest::TearDown() +{ + database_ = nullptr; + databaseCallback_ = nullptr; + deviceCallback_ = nullptr; +} + +void DistributedDatabaseTest::OnInsert(const std::string &deviceId, const std::string &key, const std::string &value) +{} + +void DistributedDatabaseTest::OnUpdate(const std::string &deviceId, const std::string &key, const std::string &value) +{} + +void DistributedDatabaseTest::OnDelete(const std::string &deviceId, const std::string &key, const std::string &value) +{} + +void DistributedDatabaseTest::OnConnected(const std::string &deviceId) +{} + +void DistributedDatabaseTest::OnDisconnected(const std::string &deviceId) +{} + +/** + * @tc.name : DistributedDatabase_PutToDistributedDB_00100 + * @tc.number : PutToDistributedDB_00100 + * @tc.desc : Put a key-value. + */ +HWTEST_F(DistributedDatabaseTest, PutToDistributedDB_00100, Function | SmallTest | Level1) +{ + std::string key(""); + std::string value(""); + + EXPECT_EQ(database_->PutToDistributedDB(key, value), true); +} + +/** + * @tc.name : DistributedDatabase_GetFromDistributedDB_00100 + * @tc.number : GetFromDistributedDB_00100 + * @tc.desc : Get value by its key. + */ +HWTEST_F(DistributedDatabaseTest, GetFromDistributedDB_00100, Function | SmallTest | Level1) +{ + std::string key(""); + std::string value; + + EXPECT_EQ(database_->GetFromDistributedDB(key, value), true); +} + +/** + * @tc.name : DistributedDatabase_GetFromDistributedDB_00200 + * @tc.number : GetFromDistributedDB_00200 + * @tc.desc : Get all entries which key start with prefixKey. + */ +HWTEST_F(DistributedDatabaseTest, GetFromDistributedDB_00200, Function | SmallTest | Level1) +{ + std::string prifixKey("<"); + std::vector entries; + + EXPECT_EQ(database_->GetEntriesFromDistributedDB(prifixKey, entries), true); +} + +/** + * @tc.name : DistributedDatabase_DeleteToDistributedDB_00100 + * @tc.number : DeleteToDistributedDB_00100 + * @tc.desc : Delete a key-value with its key. + */ +HWTEST_F(DistributedDatabaseTest, DeleteToDistributedDB_00100, Function | SmallTest | Level1) +{ + std::string key(""); + + EXPECT_EQ(database_->DeleteToDistributedDB(key), true); +} + +/** + * @tc.name : DistributedDatabase_ClearDataByDevice_00100 + * @tc.number : ClearDataByDevice_00100 + * @tc.desc : Remove the device data from remote. + */ +HWTEST_F(DistributedDatabaseTest, ClearDataByDevice_00100, Function | SmallTest | Level1) +{ + std::string deviceId(""); + + EXPECT_EQ(database_->ClearDataByDevice(deviceId), true); +} + +/** + * @tc.name : DistributedDatabase_GetLocalDeviceId_00100 + * @tc.number : GetLocalDeviceId_00100 + * @tc.desc : Get local device id. + */ +HWTEST_F(DistributedDatabaseTest, GetLocalDeviceId_00100, Function | SmallTest | Level1) +{ + std::string deviceId; + + EXPECT_EQ(database_->GetLocalDeviceId(deviceId), true); +} + +/** + * @tc.name : DistributedDatabase_GetLocalDeviceInfo_00100 + * @tc.number : GetLocalDeviceInfo_00100 + * @tc.desc : Get local device infomation. + */ +HWTEST_F(DistributedDatabaseTest, GetLocalDeviceInfo_00100, Function | SmallTest | Level1) +{ + DistributedDatabase::DeviceInfo deviceInfo; + + EXPECT_EQ(database_->GetLocalDeviceInfo(deviceInfo), true); +} + +/** + * @tc.name : DistributedDatabase_GetDeviceInfoList_00100 + * @tc.number : GetDeviceInfoList_00100 + * @tc.desc : Get infomations for all devices. + */ +HWTEST_F(DistributedDatabaseTest, GetDeviceInfoList_00100, Function | SmallTest | Level1) +{ + std::vector deviceInfos; + + EXPECT_EQ(database_->GetDeviceInfoList(deviceInfos), true); +} +} // namespace Notification +} // namespace OHOS \ No newline at end of file diff --git a/services/distributed/test/unittest/distributed_notification_manager_test.cpp b/services/distributed/test/unittest/distributed_notification_manager_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c6cac5a4cf871d27f50b2b6dd7ace51a1b93ca8d --- /dev/null +++ b/services/distributed/test/unittest/distributed_notification_manager_test.cpp @@ -0,0 +1,184 @@ +/* + * 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 + +#include "gtest/gtest.h" + +#include "distributed_notification_manager.h" + +using namespace testing::ext; +namespace OHOS { +namespace Notification { +class DistributedNotificationManagerTest : public testing::Test { +public: + void SetUp() override; + void TearDown() override; + +public: + virtual void OnPublish( + const std::string &deviceId, const std::string &bundleName, sptr &request) {}; + virtual void OnUpdate( + const std::string &deviceId, const std::string &bundleName, sptr &request) {}; + virtual void OnDelete( + const std::string &deviceId, const std::string &bundleName, const std::string &label, int32_t id) {}; + +protected: + std::shared_ptr distributedManager_; +}; + +void DistributedNotificationManagerTest::SetUp() +{ + distributedManager_ = DistributedNotificationManager::GetInstance(); +} + +void DistributedNotificationManagerTest::TearDown() +{ + distributedManager_ = nullptr; + DistributedNotificationManager::DestroyInstance(); +} + +/** + * @tc.name : Distributed_Publish_00100 + * @tc.number : Distributed_Publish_00100 + * @tc.desc : Publish a local notification to remote used distributed. + */ +HWTEST_F(DistributedNotificationManagerTest, Distributed_Publish_00100, Function | SmallTest | Level1) +{ + sptr request = new NotificationRequest(1000); + request->SetLabel("