1 /*
2 * Copyright (c) 2021-2023 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 <functional>
19 #include <iomanip>
20 #include <sstream>
21
22 #include "accesstoken_kit.h"
23 #include "ans_const_define.h"
24 #include "ans_inner_errors.h"
25 #include "ans_log_wrapper.h"
26 #include "errors.h"
27
28 #include "ipc_skeleton.h"
29 #include "notification_constant.h"
30 #include "os_account_manager_helper.h"
31 #include "hitrace_meter_adapter.h"
32 #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED
33 #include "distributed_notification_manager.h"
34 #include "distributed_preferences.h"
35 #include "distributed_screen_status_manager.h"
36 #endif
37
38 #include "advanced_notification_inline.cpp"
39 #include "notification_analytics_util.h"
40
41 namespace OHOS {
42 namespace Notification {
43
Subscribe( const sptr<AnsSubscriberInterface> &subscriber, const sptr<NotificationSubscribeInfo> &info)44 ErrCode AdvancedNotificationService::Subscribe(
45 const sptr<AnsSubscriberInterface> &subscriber, const sptr<NotificationSubscribeInfo> &info)
46 {
47 HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
48 ANS_LOGD("%{public}s", __FUNCTION__);
49 ErrCode errCode = ERR_OK;
50 do {
51 if (subscriber == nullptr) {
52 errCode = ERR_ANS_INVALID_PARAM;
53 break;
54 }
55
56 bool isSubsystem = AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID());
57 if (!isSubsystem && !AccessTokenHelper::IsSystemApp()) {
58 ANS_LOGE("Client is not a system app or subsystem");
59 errCode = ERR_ANS_NON_SYSTEM_APP;
60 break;
61 }
62
63 if (!AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_CONTROLLER)) {
64 errCode = ERR_ANS_PERMISSION_DENIED;
65 break;
66 }
67
68 if (info != nullptr && info->GetAppUserId() != SUBSCRIBE_USER_ALL) {
69 errCode = CheckUserIdParams(info->GetAppUserId());
70 if (errCode != ERR_OK) {
71 break;
72 }
73 }
74
75 errCode = NotificationSubscriberManager::GetInstance()->AddSubscriber(subscriber, info);
76 if (errCode != ERR_OK) {
77 break;
78 }
79 } while (0);
80 SendSubscribeHiSysEvent(IPCSkeleton::GetCallingPid(), IPCSkeleton::GetCallingUid(), info, errCode);
81 return errCode;
82 }
83
SubscribeSelf(const sptr<AnsSubscriberInterface> &subscriber)84 ErrCode AdvancedNotificationService::SubscribeSelf(const sptr<AnsSubscriberInterface> &subscriber)
85 {
86 HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
87 ANS_LOGD("%{public}s", __FUNCTION__);
88 sptr<NotificationSubscribeInfo> sptrInfo = new (std::nothrow) NotificationSubscribeInfo();
89 ErrCode errCode = ERR_OK;
90 HaMetaMessage message = HaMetaMessage(EventSceneId::SCENE_6, EventBranchId::BRANCH_2);
91 do {
92 if (subscriber == nullptr) {
93 errCode = ERR_ANS_INVALID_PARAM;
94 break;
95 }
96
97 bool isSubsystem = AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID());
98 if (!isSubsystem && !AccessTokenHelper::IsSystemApp()) {
99 ANS_LOGE("Client is not a system app or subsystem");
100 errCode = ERR_ANS_NON_SYSTEM_APP;
101 break;
102 }
103
104 int32_t uid = IPCSkeleton().GetCallingUid();
105 // subscribeSelf doesn't need OHOS_PERMISSION_NOTIFICATION_CONTROLLER permission
106 std::string bundle;
107 std::shared_ptr<BundleManagerHelper> bundleManager = BundleManagerHelper::GetInstance();
108 if (bundleManager != nullptr) {
109 bundle = bundleManager->GetBundleNameByUid(uid);
110 }
111
112 sptrInfo->AddAppName(bundle);
113 sptrInfo->SetSubscriberUid(uid);
114
115 errCode = NotificationSubscriberManager::GetInstance()->AddSubscriber(subscriber, sptrInfo);
116 if (errCode != ERR_OK) {
117 break;
118 }
119 } while (0);
120
121 message.Message("SubscribeSelf notification: " + std::to_string(errCode));
122 NotificationAnalyticsUtil::ReportModifyEvent(message);
123 if (errCode == ERR_OK) {
124 int32_t callingUid = IPCSkeleton::GetCallingUid();
125 ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([&]() {
126 LivePublishProcess::GetInstance()->AddLiveViewSubscriber(callingUid);
127 }));
128 notificationSvrQueue_->wait(handler);
129 }
130 SendSubscribeHiSysEvent(IPCSkeleton::GetCallingPid(), IPCSkeleton::GetCallingUid(), sptrInfo, errCode);
131 return errCode;
132 }
133
Unsubscribe( const sptr<AnsSubscriberInterface> &subscriber, const sptr<NotificationSubscribeInfo> &info)134 ErrCode AdvancedNotificationService::Unsubscribe(
135 const sptr<AnsSubscriberInterface> &subscriber, const sptr<NotificationSubscribeInfo> &info)
136 {
137 HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
138 ANS_LOGD("%{public}s", __FUNCTION__);
139
140 SendUnSubscribeHiSysEvent(IPCSkeleton::GetCallingPid(), IPCSkeleton::GetCallingUid(), info);
141 HaMetaMessage message = HaMetaMessage(EventSceneId::SCENE_6, EventBranchId::BRANCH_3);
142 bool isSubsystem = AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID());
143 if (!isSubsystem && !AccessTokenHelper::IsSystemApp()) {
144 ANS_LOGE("Client is not a system app or subsystem");
145 message.Message("Unsubscribe notification: " + std::to_string(ERR_ANS_NON_SYSTEM_APP));
146 NotificationAnalyticsUtil::ReportModifyEvent(message);
147 return ERR_ANS_NON_SYSTEM_APP;
148 }
149
150 if (!AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_CONTROLLER)) {
151 message.Message("Unsubscribe notification: " + std::to_string(ERR_ANS_PERMISSION_DENIED));
152 NotificationAnalyticsUtil::ReportModifyEvent(message);
153 return ERR_ANS_PERMISSION_DENIED;
154 }
155
156 if (subscriber == nullptr) {
157 message.Message("Unsubscribe notification: " + std::to_string(ERR_ANS_INVALID_PARAM));
158 NotificationAnalyticsUtil::ReportModifyEvent(message);
159 return ERR_ANS_INVALID_PARAM;
160 }
161
162 ErrCode errCode = NotificationSubscriberManager::GetInstance()->RemoveSubscriber(subscriber, info);
163 if (errCode != ERR_OK) {
164 return errCode;
165 }
166
167 return ERR_OK;
168 }
169 } // namespace Notification
170 } // namespace OHOS
171