1 /*
2 * Copyright (c) 2025-2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "advanced_notification_service.h"
17
18 #include "ans_permission_def.h"
19 #include "access_token_helper.h"
20 #include "ans_log_wrapper.h"
21 #include "ans_trace_wrapper.h"
22 #include "ans_inner_errors.h"
23 #include "errors.h"
24 #include "ipc_skeleton.h"
25
26 #include "notification_bundle_option.h"
27 #include "notification_constant.h"
28 #include "notification_local_live_view_subscriber_manager.h"
29 #include "live_publish_process.h"
30
31 namespace OHOS {
32 namespace Notification {
TriggerLocalLiveView(const sptr<NotificationBundleOption> & bundleOption,const int32_t notificationId,const sptr<NotificationButtonOption> & buttonOption)33 ErrCode AdvancedNotificationService::TriggerLocalLiveView(const sptr<NotificationBundleOption> &bundleOption,
34 const int32_t notificationId, const sptr<NotificationButtonOption> &buttonOption)
35 {
36 NOTIFICATION_HITRACE(HITRACE_TAG_NOTIFICATION);
37 ANS_LOGD("%{public}s", __FUNCTION__);
38
39 bool isSubsystem = AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID());
40 if (!isSubsystem && !AccessTokenHelper::IsSystemApp()) {
41 return ERR_ANS_NON_SYSTEM_APP;
42 }
43
44 if (!AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_CONTROLLER)) {
45 ANS_LOGD("AccessTokenHelper::CheckPermission is bogus.");
46 return ERR_ANS_PERMISSION_DENIED;
47 }
48
49 sptr<NotificationBundleOption> bundle = GenerateValidBundleOption(bundleOption);
50 if (bundle == nullptr) {
51 return ERR_ANS_INVALID_BUNDLE;
52 }
53
54 ErrCode result = ERR_ANS_NOTIFICATION_NOT_EXISTS;
55 ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([&]() {
56 ANS_LOGD("ffrt enter!");
57 sptr<Notification> notification = nullptr;
58 result = GetNotificationById(bundle, notificationId, notification);
59 if (notification != nullptr) {
60 NotificationLocalLiveViewSubscriberManager::GetInstance()->NotifyTriggerResponse(notification,
61 buttonOption);
62 }
63 }));
64 notificationSvrQueue_->wait(handler);
65 return result;
66 }
67
GetNotificationById(const sptr<NotificationBundleOption> & bundle,const int32_t notificationId,sptr<Notification> & notification)68 ErrCode AdvancedNotificationService::GetNotificationById(const sptr<NotificationBundleOption> &bundle,
69 const int32_t notificationId, sptr<Notification> ¬ification)
70 {
71 if (bundle == nullptr) {
72 return ERR_ANS_INVALID_BUNDLE;
73 }
74 for (auto record : notificationList_) {
75 if (record->request->GetAgentBundle() != nullptr) {
76 if ((record->request->GetAgentBundle()->GetBundleName() == bundle->GetBundleName()) &&
77 (record->request->GetAgentBundle()->GetUid() == bundle->GetUid()) &&
78 (record->notification->GetId() == notificationId)) {
79 notification = record->notification;
80 return ERR_OK;
81 }
82 } else {
83 if ((record->bundleOption->GetBundleName() == bundle->GetBundleName()) &&
84 (record->bundleOption->GetUid() == bundle->GetUid()) &&
85 (record->notification->GetId() == notificationId)) {
86 notification = record->notification;
87 return ERR_OK;
88 }
89 }
90 }
91 return ERR_ANS_NOTIFICATION_NOT_EXISTS;
92 }
93
SubscribeLocalLiveView(const sptr<IAnsSubscriberLocalLiveView> & subscriber,const bool isNative)94 ErrCode AdvancedNotificationService::SubscribeLocalLiveView(
95 const sptr<IAnsSubscriberLocalLiveView> &subscriber, const bool isNative)
96 {
97 return SubscribeLocalLiveView(subscriber, nullptr, isNative);
98 }
99
SubscribeLocalLiveView(const sptr<IAnsSubscriberLocalLiveView> & subscriber,const sptr<NotificationSubscribeInfo> & info,const bool isNative)100 ErrCode AdvancedNotificationService::SubscribeLocalLiveView(
101 const sptr<IAnsSubscriberLocalLiveView> &subscriber,
102 const sptr<NotificationSubscribeInfo> &info, const bool isNative)
103 {
104 NOTIFICATION_HITRACE(HITRACE_TAG_NOTIFICATION);
105 ANS_LOGD("%{public}s, isNative: %{public}d", __FUNCTION__, isNative);
106
107 ErrCode errCode = ERR_OK;
108 do {
109 if (!isNative) {
110 bool isSubsystem = AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID());
111 if (!isSubsystem && !AccessTokenHelper::IsSystemApp()) {
112 ANS_LOGE("Client is not a system app or subsystem.");
113 errCode = ERR_ANS_NON_SYSTEM_APP;
114 break;
115 }
116 }
117
118 if (subscriber == nullptr) {
119 errCode = ERR_ANS_INVALID_PARAM;
120 break;
121 }
122
123 errCode = NotificationLocalLiveViewSubscriberManager::GetInstance()->AddLocalLiveViewSubscriber(
124 subscriber, info);
125 if (errCode != ERR_OK) {
126 break;
127 }
128 } while (0);
129 if (errCode == ERR_OK) {
130 int32_t callingUid = IPCSkeleton::GetCallingUid();
131 ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([&]() {
132 LivePublishProcess::GetInstance()->AddLiveViewSubscriber(callingUid);
133 }));
134 notificationSvrQueue_->wait(handler);
135 }
136 SendSubscribeHiSysEvent(IPCSkeleton::GetCallingPid(), IPCSkeleton::GetCallingUid(), info, errCode);
137 return errCode;
138 }
139
RemoveSystemLiveViewNotifications(const std::string & bundleName,const int32_t uid)140 ErrCode AdvancedNotificationService::RemoveSystemLiveViewNotifications(
141 const std::string& bundleName, const int32_t uid)
142 {
143 std::vector<std::shared_ptr<NotificationRecord>> recordList;
144 if (notificationSvrQueue_ == nullptr) {
145 ANS_LOGE("NotificationSvrQueue is nullptr");
146 return ERR_ANS_INVALID_PARAM;
147 }
148 ErrCode result = ERR_OK;
149 ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([&]() {
150 LivePublishProcess::GetInstance()->EraseLiveViewSubsciber(uid);
151 GetTargetRecordList(uid, NotificationConstant::SlotType::LIVE_VIEW,
152 NotificationContent::Type::LOCAL_LIVE_VIEW, recordList);
153 GetCommonTargetRecordList(uid, NotificationConstant::SlotType::LIVE_VIEW,
154 NotificationContent::Type::LIVE_VIEW, recordList);
155 if (recordList.size() == 0) {
156 ANS_LOGE("Empty list");
157 result = ERR_ANS_NOTIFICATION_NOT_EXISTS;
158 return;
159 }
160 result = RemoveNotificationFromRecordList(recordList);
161 }));
162 notificationSvrQueue_->wait(handler);
163 return result;
164 }
165
RemoveSystemLiveViewNotificationsOfSa(int32_t uid)166 ErrCode AdvancedNotificationService::RemoveSystemLiveViewNotificationsOfSa(int32_t uid)
167 {
168 {
169 std::lock_guard<ffrt::mutex> lock(delayNotificationMutext_);
170 for (auto iter = delayNotificationList_.begin(); iter != delayNotificationList_.end();) {
171 if ((*iter).first->notification->GetNotificationRequest().GetCreatorUid() == uid &&
172 (*iter).first->notification->GetNotificationRequest().IsInProgress()) {
173 CancelTimer((*iter).second);
174 iter = delayNotificationList_.erase(iter);
175 } else {
176 iter++;
177 }
178 }
179 }
180
181 ErrCode result = ERR_OK;
182 ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([&]() {
183 LivePublishProcess::GetInstance()->EraseLiveViewSubsciber(uid);
184 std::vector<std::shared_ptr<NotificationRecord>> recordList;
185 for (auto item : notificationList_) {
186 if (item->notification->GetNotificationRequest().GetCreatorUid() == uid &&
187 item->notification->GetNotificationRequest().IsInProgress()) {
188 recordList.emplace_back(item);
189 }
190 }
191 if (!recordList.empty()) {
192 result = RemoveNotificationFromRecordList(recordList);
193 }
194 }));
195 notificationSvrQueue_->wait(handler);
196 return result;
197 }
198 } // namespace Notification
199 } // namespace OHOS