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