• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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> &notification)
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