diff --git a/interfaces/inner_api/notification_local_activity_button.h b/interfaces/inner_api/notification_local_activity_button.h new file mode 100644 index 0000000000000000000000000000000000000000..71aeec80ffe5a054a438239175f822475cb071db --- /dev/null +++ b/interfaces/inner_api/notification_local_activity_button.h @@ -0,0 +1,107 @@ +/* + * 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. + */ + +#ifndef BASE_NOTIFICATION_DISTRIBUTED_NOTIFICATION_SERVICE_INTERFACES_INNER_API_LOCAL_ACTIVITY_BUTTON_H +#define BASE_NOTIFICATION_DISTRIBUTED_NOTIFICATION_SERVICE_INTERFACES_INNER_API_LOCAL_ACTIVITY_BUTTON_H + +#include "base/notification/distributed_notification_service/interfaces/inner_api/notification_button_option.h" +#include "foundation/multimedia/image_framework/interfaces/innerkits/include/pixel_map.h" +#include "message_user.h" +#include "notification_json_convert.h" +#include "parcel.h" +#include "uri.h" +#include + +namespace OHOS { +namespace Notification { +class NotificationLocalActivityButton : public Parcelable, public NotificationJsonConvertionBase { +public: + NotificationLocalActivityButton() = default; + ~NotificationLocalActivityButton() = default; + + /** + * @brief Obtains the button option. + * + * @return Returns the button option vector. + */ + std::vector> GetAllButtonOption() const; + + void addSingleButtonOption(std::shared_ptr &buttonOption); + + /** + * @brief Obtains the button icon. + * + * @return Returns the button icon. + */ + std::vector> GetAllButtonIcon() const; + + void addSingleButtonIcon(std::shared_ptr &icon); + + + /** + * @brief Returns a string representation of the object. + * + * @return Returns a string representation of the object. + */ + std::string Dump(); + + /** + * @brief Converts a NotificationLocalActivityButton object into a Json. + * + * @param jsonObject Indicates the Json object. + * @return Returns true if succeed; returns false otherwise. + */ + bool ToJson(nlohmann::json &jsonObject) const override; + + /** + * @brief Creates a NotificationLocalActivityButton object from a Json. + * + * @param jsonObject Indicates the Json object. + * @return Returns the NotificationLocalActivityButton. + */ + static NotificationLocalActivityButton *FromJson(const nlohmann::json &jsonObject); + + /** + * @brief Marshal a object into a Parcel. + * + * @param parcel Indicates the object into the parcel. + * @return Returns true if succeed; returns false otherwise. + */ + virtual bool Marshalling(Parcel &parcel) const override; + + /** + * @brief Unmarshal object from a Parcel. + * + * @param parcel Indicates the parcel object. + * @return Returns the NotificationLocalActivityButton. + */ + static NotificationLocalActivityButton *Unmarshalling(Parcel &parcel); + +private: + /** + * @brief Read a NotificationLocalActivityButton object from a Parcel. + * + * @param parcel Indicates the parcel object. + * @return Returns true if succeed; returns false otherwise. + */ + bool ReadFromParcel(Parcel &parcel); + + std::vector> buttonOptions_ {}; + std::vector> buttonIcons_ {}; +}; +} // namespace Notification +} // namespace OHOS + +#endif // BASE_NOTIFICATION_DISTRIBUTED_NOTIFICATION_SERVICE_INTERFACES_INNER_API_LOCAL_ACTIVITY_BUTTON_H \ No newline at end of file diff --git a/interfaces/inner_api/notification_local_activity_content.h b/interfaces/inner_api/notification_local_activity_content.h new file mode 100644 index 0000000000000000000000000000000000000000..8fb08b5fe5eb042612ded3dacdf8d9efb1983867 --- /dev/null +++ b/interfaces/inner_api/notification_local_activity_content.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2021-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_DISTRIBUTED_NOTIFICATION_SERVICE_INTERFACES_INNER_API_LOCAL_ACTIVITY_CONTENT_H +#define BASE_NOTIFICATION_DISTRIBUTED_NOTIFICATION_SERVICE_INTERFACES_INNER_API_LOCAL_ACTIVITY_CONTENT_H + +#include "base/notification/distributed_notification_service/interfaces/inner_api/notification_capsule.h" +#include "base/notification/distributed_notification_service/interfaces/inner_api/notification_progress.h" +#include "base/notification/distributed_notification_service/interfaces/inner_api/notification_local_activity_button.h" +#include "message_user.h" +#include "notification_basic_content.h" +#include "notification_conversational_message.h" +#include "notification_json_convert.h" +#include "parcel.h" + +namespace OHOS { +namespace Notification { +class NotificationLocalActivityContent : public NotificationBasicContent { +public: + NotificationLocalActivityContent() = default; + ~NotificationLocalActivityContent() = default; + + /** + * @brief Returns a string representation of the object. + * + * @return Returns a string representation of the object. + */ + std::string Dump() override; + + /** + * @brief Converts a NotificationLocalActivityContent object into a Json. + * + * @param jsonObject Indicates the Json object. + * @return Returns true if succeed; returns false otherwise. + */ + virtual bool ToJson(nlohmann::json &jsonObject) const override; + + /** + * @brief Creates a NotificationLocalActivityContent object from a Json. + * + * @param jsonObject Indicates the Json object. + * @return Returns the NotificationLocalActivityContent. + */ + static NotificationLocalActivityContent *FromJson(const nlohmann::json &jsonObject); + + /** + * @brief Marshal a object into a Parcel. + * + * @param parcel Indicates the object into the parcel. + * @return Returns true if succeed; returns false otherwise. + */ + virtual bool Marshalling(Parcel &parcel) const override; + + /** + * @brief Unmarshal object from a Parcel. + * + * @param parcel Indicates the parcel object. + * @return Returns the NotificationLocalActivityContent. + */ + static NotificationLocalActivityContent *Unmarshalling(Parcel &parcel); + +protected: + /** + * @brief Read a NotificationLocalActivityContent object from a Parcel. + * + * @param parcel Indicates the parcel object. + * @return Returns true if succeed; returns false otherwise. + */ + bool ReadFromParcel(Parcel &parcel) override; + +private: + + int32_t type_ {0}; + NotificationCapsule capsule_ {}; + NotificationLocalActivityButton button_ {}; + NotificationProgress progress_ {}; +}; +} // namespace Notification +} // namespace OHOS + +#endif // BASE_NOTIFICATION_DISTRIBUTED_NOTIFICATION_SERVICE_INTERFACES_INNER_API_CONVERSATIONAL_CONTENT_H \ No newline at end of file diff --git a/interfaces/inner_api/notification_local_activity_subscriber.h b/interfaces/inner_api/notification_local_activity_subscriber.h new file mode 100644 index 0000000000000000000000000000000000000000..7039be1390ba1c300ef98d61f5bad995da789200 --- /dev/null +++ b/interfaces/inner_api/notification_local_activity_subscriber.h @@ -0,0 +1,100 @@ +/* + * 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. + */ + +#ifndef BASE_NOTIFICATION_DISTRIBUTED_NOTIFICATION_SERVICE_INTERFACES_INNER_API_NOTIFICATION_LOCAL_ACTIVITY_SUBSCRIBER_H +#define BASE_NOTIFICATION_DISTRIBUTED_NOTIFICATION_SERVICE_INTERFACES_INNER_API_NOTIFICATION_LOCAL_ACTIVITY_SUBSCRIBER_H + +#include "ans_manager_interface.h" +#include "ans_subscriber_stub.h" +#include "ans_subscriber_local_activity_stub.h" +#include "notification_request.h" +#include "notification_sorting.h" +#include "notification_sorting_map.h" + +namespace OHOS { +namespace Notification { +class NotificationLocalActivitySubscriber { +public: + NotificationLocalActivitySubscriber(); + + virtual ~NotificationLocalActivitySubscriber(); + + /** + * @brief Called back when the subscriber is connected to the Advanced Notification Service (ANS). + **/ + virtual void OnConnected() = 0; + + /** + * @brief Called back when the subscriber is disconnected from the ANS. + **/ + virtual void OnDisconnected() = 0; + + /** + * @brief Called back when the subscriber button is clicked. + **/ + + virtual void OnResponse(int32_t notificationId, const sptr &buttonOption) = 0; + + /** + * @brief Called back when connection to the ANS has died. + **/ + virtual void OnDied() = 0; + +private: + class SubscriberLocalActivityImpl final : public AnsSubscriberLocalActivityStub { + public: + class DeathRecipient final : public IRemoteObject::DeathRecipient { + public: + DeathRecipient(SubscriberLocalActivityImpl &subscriberImpl); + + ~DeathRecipient(); + + void OnRemoteDied(const wptr &object) override; + + private: + SubscriberLocalActivityImpl &subscriberImpl_; + }; + + public: + SubscriberLocalActivityImpl(NotificationLocalActivitySubscriber &subscriber); + ~SubscriberLocalActivityImpl() {}; + + void OnConnected() override; + + void OnDisconnected() override; + + void OnResponse(int32_t notificationId, const sptr &buttonOption) override; + + bool GetAnsManagerProxy(); + + public: + NotificationLocalActivitySubscriber &subscriber_; + sptr recipient_ {nullptr}; + sptr proxy_ {nullptr}; + std::mutex mutex_ {}; + }; + +private: + const sptr GetImpl() const; + +private: + sptr impl_ = nullptr; + + friend class AnsNotification; +}; +} // namespace Notification +} // namespace OHOS + +#endif // BASE_NOTIFICATION_DISTRIBUTED_NOTIFICATION_SERVICE_INTERFACES_INNER_API_NOTIFICATION_LOCAL_ACTIVITY_SUBSCRIBER_H \ No newline at end of file diff --git a/interfaces/inner_api/notification_progress.h b/interfaces/inner_api/notification_progress.h new file mode 100644 index 0000000000000000000000000000000000000000..b5e77763651616c21e0adfdfef4bb64fcdf40881 --- /dev/null +++ b/interfaces/inner_api/notification_progress.h @@ -0,0 +1,113 @@ +/* + * 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. + */ + +#ifndef BASE_NOTIFICATION_DISTRIBUTED_NOTIFICATION_SERVICE_INTERFACES_INNER_API_PROGRESS_H +#define BASE_NOTIFICATION_DISTRIBUTED_NOTIFICATION_SERVICE_INTERFACES_INNER_API_PROGRESS_H + +#include "notification_json_convert.h" +#include "parcel.h" +#include + +namespace OHOS { +namespace Notification { +class NotificationProgress : public Parcelable, public NotificationJsonConvertionBase { +public: + NotificationProgress() = default; + ~NotificationProgress() = default; + + /** + * @brief Obtains the maxValue. + * + * @return Returns the message content. + */ + int32_t GetMaxValue() const; + + void SetMaxValue(int32_t maxValue); + + /** + * @brief Obtains the currnetValue. + * + * @return Returns the currnetValue. + */ + int32_t GetCurrentValue() const; + + void SetCurrentValue(int32_t curValue); + + /** + * @brief Obtains the isPercentage. + * + * @return Returns the isPercentage. + */ + int32_t GetIsPercentage() const; + + void SetIsPercentage(int32_t isPercentage); + + /** + * @brief Returns a string representation of the object. + * + * @return Returns a string representation of the object. + */ + std::string Dump(); + + /** + * @brief Converts a NotificationProgress object into a Json. + * + * @param jsonObject Indicates the Json object. + * @return Returns true if succeed; returns false otherwise. + */ + bool ToJson(nlohmann::json &jsonObject) const override; + + /** + * @brief Creates a NotificationProgress object from a Json. + * + * @param jsonObject Indicates the Json object. + * @return Returns the NotificationProgress. + */ + static NotificationProgress *FromJson(const nlohmann::json &jsonObject); + + /** + * @brief Marshal a object into a Parcel. + * + * @param parcel Indicates the object into the parcel. + * @return Returns true if succeed; returns false otherwise. + */ + virtual bool Marshalling(Parcel &parcel) const override; + + /** + * @brief Unmarshal object from a Parcel. + * + * @param parcel Indicates the parcel object. + * @return Returns the NotificationProgress. + */ + static NotificationProgress *Unmarshalling(Parcel &parcel); + +private: + /** + * @brief Read a NotificationProgress object from a Parcel. + * + * @param parcel Indicates the parcel object. + * @return Returns true if succeed; returns false otherwise. + */ + bool ReadFromParcel(Parcel &parcel); + +private: + int32_t maxValue_ {0}; + int32_t currentValue_ {0}; + int32_t isPercentage_ {0}; +}; +} // namespace Notification +} // namespace OHOS + +#endif // BASE_NOTIFICATION_DISTRIBUTED_NOTIFICATION_SERVICE_INTERFACES_INNER_API_PROGRESS_H \ No newline at end of file diff --git a/services/ans/BUILD.gn b/services/ans/BUILD.gn index edc6d381abdb228c4ab2da819810d0a849e4f315..e7b654248d2f3b7b7d86d8e9680985e16fb36452 100644 --- a/services/ans/BUILD.gn +++ b/services/ans/BUILD.gn @@ -50,6 +50,7 @@ ohos_shared_library("libans") { "src/bundle_manager_helper.cpp", "src/event_report.cpp", "src/notification_dialog.cpp", + "src/notification_local_activity_subscriber_manager.cpp", "src/notification_preferences.cpp", "src/notification_preferences_database.cpp", "src/notification_preferences_info.cpp", diff --git a/services/ans/include/notification_local_activity_subscriber_manager.h b/services/ans/include/notification_local_activity_subscriber_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..533f0a50e04ede3364a4f2b7cec3a47363f7f89a --- /dev/null +++ b/services/ans/include/notification_local_activity_subscriber_manager.h @@ -0,0 +1,112 @@ +/* + * 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. + */ + +#ifndef BASE_NOTIFICATION_DISTRIBUTED_NOTIFICATION_SERVICE_SERVICES_INCLUDE_NOTIFICATION_LOCAL_ACTIVITY_SUBSCRIBER_LOCAL_ACTIVITY_MANAGER_H +#define BASE_NOTIFICATION_DISTRIBUTED_NOTIFICATION_SERVICE_SERVICES_INCLUDE_NOTIFICATION_LOCAL_ACTIVITY_SUBSCRIBER_LOCAL_ACTIVITY_MANAGER_H + +#include +#include +#include + +#include "errors.h" +#include "event_handler.h" +#include "event_runner.h" +#include "ffrt.h" +#include "nocopyable.h" +#include "refbase.h" +#include "singleton.h" + +#include "ans_subscriber_local_activity_interface.h" +#include "notification_bundle_option.h" +#include "notification_constant.h" +#include "notification_request.h" +#include "notification_sorting_map.h" +#include "notification_subscribe_info.h" + +namespace OHOS { +namespace Notification { +class NotificationLocalActivitySubscriberManager : public DelayedSingleton { +public: + /** + * @brief Add a subscriber. + * + * @param subscriber Indicates the AnsSubscriberLocalActivityInterface object. + * @param subscribeInfo Indicates the NotificationSubscribeInfo object. + * @return Indicates the result code. + */ + ErrCode AddLocalActivitySubscriber(const sptr &subscriber, + const sptr &subscribeInfo); + + /** + * @brief Remove a subscriber. + * + * @param subscriber Indicates the AnsSubscriberLocalActivityInterface object. + * @param subscribeInfo Indicates the NotificationSubscribeInfo object. + * @return Indicates the result code. + */ + ErrCode RemoveLocalActivitySubscriber( + const sptr &subscriber, const sptr &subscribeInfo); + + + /** + * @brief Notify the subscriber which button has been clicked. + * + * @param notification Indicates the Notification object. + * @param buttonOption Indicates the buttonOption object. + */ + void NotifyTriggerResponse(const sptr ¬ification, const sptr &buttonOption); + + /** + * @brief Obtains the death event. + * + * @param object Indicates the death object. + */ + void OnRemoteDied(const wptr &object); + + /** + * @brief Reset ffrt queue + */ + void ResetFfrtQueue(); + +private: + struct LocalActivitySubscriberRecord; + + std::shared_ptr FindSubscriberRecord(const wptr &object); + std::shared_ptr FindSubscriberRecord(const sptr &subscriber); + std::shared_ptr CreateSubscriberRecord(const sptr &subscriber); + + ErrCode AddSubscriberInner( + const sptr &subscriber, const sptr &subscribeInfo); + ErrCode RemoveSubscriberInner( + const sptr &subscriber, const sptr &subscribeInfo); + + void NotifyTriggerResponseInner(const sptr ¬ification, const sptr &buttonOption); + bool IsSystemUser(int32_t userId); + +private: + std::list> buttonRecordList_ {}; + std::shared_ptr runner_ {}; + std::shared_ptr handler_ {}; + sptr ansSubscriberProxy_ {}; + sptr recipient_ {}; + std::shared_ptr notificationButtonQueue_ = nullptr; + + DECLARE_DELAYED_SINGLETON(NotificationLocalActivitySubscriberManager); + DISALLOW_COPY_AND_MOVE(NotificationLocalActivitySubscriberManager); +}; +} // namespace Notification +} // namespace OHOS + +#endif // BASE_NOTIFICATION_DISTRIBUTED_NOTIFICATION_SERVICE_SERVICES_INCLUDE_NOTIFICATION_LOCAL_ACTIVITY_SUBSCRIBER_LOCAL_ACTIVITY_MANAGER_H \ No newline at end of file diff --git a/services/ans/src/notification_local_activity_subscriber_manager.cpp b/services/ans/src/notification_local_activity_subscriber_manager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6b3f3326dafc0aa711d27257b1a75c1fa515b777 --- /dev/null +++ b/services/ans/src/notification_local_activity_subscriber_manager.cpp @@ -0,0 +1,283 @@ +/* + * Copyright (c) 2021-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_local_activity_subscriber_manager.h" + +#include +#include +#include + +#include "ans_const_define.h" +#include "ans_inner_errors.h" +#include "ans_log_wrapper.h" +#include "ans_watchdog.h" +#include "hitrace_meter.h" +#include "ipc_skeleton.h" +#include "notification_button_option.h" +#include "os_account_manager.h" +#include "remote_death_recipient.h" +#include "bundle_manager_helper.h" + +namespace OHOS { +namespace Notification { +struct NotificationLocalActivitySubscriberManager::LocalActivitySubscriberRecord { + sptr subscriber {nullptr}; + std::string bundleName {}; + int32_t userId {SUBSCRIBE_USER_INIT}; +}; + +NotificationLocalActivitySubscriberManager::NotificationLocalActivitySubscriberManager() +{ + ANS_LOGI("constructor"); + notificationButtonQueue_ = std::make_shared("NotificationLocalActivityMgr"); + recipient_ = new (std::nothrow) + RemoteDeathRecipient(std::bind(&NotificationLocalActivitySubscriberManager::OnRemoteDied, this, std::placeholders::_1)); + if (recipient_ == nullptr) { + ANS_LOGE("Failed to create RemoteDeathRecipient instance"); + } +} + +NotificationLocalActivitySubscriberManager::~NotificationLocalActivitySubscriberManager() +{ + ANS_LOGI("deconstructor"); + buttonRecordList_.clear(); +} + +void NotificationLocalActivitySubscriberManager::ResetFfrtQueue() +{ + if (notificationButtonQueue_ != nullptr) { + notificationButtonQueue_.reset(); + } +} + +ErrCode NotificationLocalActivitySubscriberManager::AddLocalActivitySubscriber( + const sptr &subscriber, const sptr &subscribeInfo) +{ + HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__); + if (subscriber == nullptr) { + ANS_LOGE("subscriber is null."); + return ERR_ANS_INVALID_PARAM; + } + + sptr subInfo = subscribeInfo; + if (subInfo == nullptr) { + subInfo = new (std::nothrow) NotificationSubscribeInfo(); + if (subInfo == nullptr) { + ANS_LOGE("Failed to create NotificationSubscribeInfo ptr."); + return ERR_ANS_NO_MEMORY; + } + } + + if (subInfo->GetAppUserId() == SUBSCRIBE_USER_INIT) { + int32_t userId = SUBSCRIBE_USER_INIT; + int32_t callingUid = IPCSkeleton::GetCallingUid(); + ErrCode ret = OHOS::AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(callingUid, userId); + if (ret != ERR_OK) { + ANS_LOGD("Get userId failed, callingUid = <%{public}d>", callingUid); + return ERR_ANS_INVALID_PARAM; + } + + ANS_LOGD("Get userId succeeded, callingUid = <%{public}d> userId = <%{public}d>", callingUid, userId); + subInfo->AddAppUserId(userId); + } + + ErrCode result = ERR_ANS_TASK_ERR; + if (notificationButtonQueue_ == nullptr) { + ANS_LOGE("queue is nullptr"); + return result; + } + ANS_LOGE("ffrt start!"); + ffrt::task_handle handler = notificationButtonQueue_->submit_h(std::bind([this, &subscriber, &subInfo, &result]() { + ANS_LOGE("ffrt enter!"); + result = this->AddSubscriberInner(subscriber, subInfo); + })); + notificationButtonQueue_->wait(handler); + ANS_LOGE("ffrt end!"); + return result; +} + +ErrCode NotificationLocalActivitySubscriberManager::RemoveLocalActivitySubscriber( + const sptr &subscriber, const sptr &subscribeInfo) +{ + HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__); + if (subscriber == nullptr) { + ANS_LOGE("subscriber is null."); + return ERR_ANS_INVALID_PARAM; + } + + ErrCode result = ERR_ANS_TASK_ERR; + if (notificationButtonQueue_ == nullptr) { + ANS_LOGE("queue is nullptr"); + return result; + } + ANS_LOGE("ffrt start!"); + ffrt::task_handle handler = notificationButtonQueue_->submit_h(std::bind([this, &subscriber, + &subscribeInfo, &result]() { + ANS_LOGE("ffrt enter!"); + result = this->RemoveSubscriberInner(subscriber, subscribeInfo); + })); + notificationButtonQueue_->wait(handler); + ANS_LOGE("ffrt end!"); + return result; +} + +void NotificationLocalActivitySubscriberManager::NotifyTriggerResponse(const sptr ¬ification, + const sptr &buttonOption) +{ + HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__); + if (notificationButtonQueue_ == nullptr) { + ANS_LOGE("queue is nullptr"); + return; + } + AppExecFwk::EventHandler::Callback NotifyTriggerResponseFunc = + std::bind(&NotificationLocalActivitySubscriberManager::NotifyTriggerResponseInner, this, notification, buttonOption); + + ANS_LOGE("ffrt start!"); + notificationButtonQueue_->submit(NotifyTriggerResponseFunc); + ANS_LOGE("ffrt end!"); +} + +void NotificationLocalActivitySubscriberManager::OnRemoteDied(const wptr &object) +{ + ANS_LOGI("OnRemoteDied"); + if (notificationButtonQueue_ == nullptr) { + ANS_LOGE("queue is nullptr"); + return; + } + ffrt::task_handle handler = notificationButtonQueue_->submit_h(std::bind([this, object]() { + ANS_LOGE("ffrt enter!"); + std::shared_ptr record = FindSubscriberRecord(object); + if (record != nullptr) { + ANS_LOGW("subscriber removed."); + buttonRecordList_.remove(record); + } + })); + ANS_LOGE("ffrt start!"); + notificationButtonQueue_->wait(handler); + ANS_LOGE("ffrt end!"); +} + +std::shared_ptr NotificationLocalActivitySubscriberManager::FindSubscriberRecord( + const wptr &object) +{ + auto iter = buttonRecordList_.begin(); + + for (; iter != buttonRecordList_.end(); iter++) { + if ((*iter)->subscriber->AsObject() == object) { + return (*iter); + } + } + return nullptr; +} + +std::shared_ptr NotificationLocalActivitySubscriberManager::FindSubscriberRecord( + const sptr &subscriber) +{ + auto iter = buttonRecordList_.begin(); + + for (; iter != buttonRecordList_.end(); iter++) { + if ((*iter)->subscriber->AsObject() == subscriber->AsObject()) { + return (*iter); + } + } + return nullptr; +} + +std::shared_ptr NotificationLocalActivitySubscriberManager::CreateSubscriberRecord( + const sptr &subscriber) +{ + std::shared_ptr record = std::make_shared(); + // set bundleName and uid + int32_t callingUid = IPCSkeleton::GetCallingUid(); + std::string bundle; + std::shared_ptr bundleManager = BundleManagerHelper::GetInstance(); + if (bundleManager != nullptr) { + bundle = bundleManager->GetBundleNameByUid(callingUid); + } + + if (record != nullptr) { + record->subscriber = subscriber; + record->bundleName = bundle; + record->userId = callingUid; + } + return record; +} + + +ErrCode NotificationLocalActivitySubscriberManager::AddSubscriberInner( + const sptr &subscriber, const sptr &subscribeInfo) +{ + HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__); + std::shared_ptr record = FindSubscriberRecord(subscriber); + if (record == nullptr) { + record = CreateSubscriberRecord(subscriber); + if (record == nullptr) { + ANS_LOGE("CreateSubscriberRecord failed."); + return ERR_ANS_NO_MEMORY; + } + buttonRecordList_.push_back(record); + + record->subscriber->AsObject()->AddDeathRecipient(recipient_); + + record->subscriber->OnConnected(); + ANS_LOGI("subscriber is connected."); + } + + return ERR_OK; +} + +ErrCode NotificationLocalActivitySubscriberManager::RemoveSubscriberInner( + const sptr &subscriber, const sptr &subscribeInfo) +{ + HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__); + std::shared_ptr record = FindSubscriberRecord(subscriber); + + if (record == nullptr) { + ANS_LOGE("subscriber not found."); + return ERR_ANS_INVALID_PARAM; + } + + record->subscriber->AsObject()->RemoveDeathRecipient(recipient_); + + buttonRecordList_.remove(record); + + record->subscriber->OnDisconnected(); + ANS_LOGI("subscriber is disconnected."); + + return ERR_OK; +} + +void NotificationLocalActivitySubscriberManager::NotifyTriggerResponseInner(const sptr ¬ification, const sptr &buttonOption) +{ + ANS_LOGE("ffrt enter!"); + HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__); + ANS_LOGD("%{public}s notification->GetUserId <%{public}d>", __FUNCTION__, notification->GetUserId()); + int32_t sendUserId = notification->GetUserId(); + for (auto record : buttonRecordList_) { + ANS_LOGD("%{public}s record->userId = <%{public}d>", __FUNCTION__, record->userId); + auto bundleName = notification->GetBundleName(); + if (record->bundleName == bundleName && record->userId == sendUserId) { + record->subscriber->OnResponse(notification->GetId(), buttonOption); + } + } +} + +bool NotificationLocalActivitySubscriberManager::IsSystemUser(int32_t userId) +{ + return ((userId >= SUBSCRIBE_USER_SYSTEM_BEGIN) && (userId <= SUBSCRIBE_USER_SYSTEM_END)); +} + +} // namespace Notification +} // namespace OHOS