• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 "accesstoken_kit.h"
19 #include "access_token_helper.h"
20 #include "advanced_notification_flow_control_service.h"
21 #include "advanced_notification_inline.h"
22 #include "ans_const_define.h"
23 #include "ans_inner_errors.h"
24 #include "ans_log_wrapper.h"
25 #include "ans_status.h"
26 
27 #include "hitrace_meter_adapter.h"
28 #include "notification_analytics_util.h"
29 #include "os_account_manager.h"
30 #include "os_account_manager_helper.h"
31 #include "string_wrapper.h"
32 #include "hitrace_util.h"
33 
34 namespace OHOS {
35 namespace Notification {
36 
AtomicServicePublish(const sptr<NotificationRequest> & request)37 ErrCode AdvancedNotificationService::AtomicServicePublish(const sptr<NotificationRequest> &request)
38 {
39     ErrCode result = PermissionVerification();
40     if (result != ERR_OK) {
41         return result;
42     }
43 
44     AnsStatus ansStatus = ExecutePublishProcess(request, true);
45     if (!ansStatus.Ok()) {
46         ansStatus.AppendSceneBranch(EventSceneId::SCENE_1, EventBranchId::BRANCH_0, "Execute PublishProcess failed");
47         NotificationAnalyticsUtil::ReportPublishFailedEvent(request, ansStatus.BuildMessage(true));
48         return ansStatus.GetErrCode();
49     }
50 
51     sptr<NotificationBundleOption> bundleOption;
52     ansStatus = CheckAndPrepareNotificationInfoWithAtomicService(request, bundleOption);
53     if (!ansStatus.Ok()) {
54         ansStatus.AppendSceneBranch(EventSceneId::SCENE_1, EventBranchId::BRANCH_0,
55             "CheckAndPrepareNotificationInfoWithAtomicService failed");
56         NotificationAnalyticsUtil::ReportPublishFailedEvent(request, ansStatus.BuildMessage(true));
57         SendPublishHiSysEvent(request, result);
58         return ansStatus.GetErrCode();
59     }
60 
61     result = PublishPreparedNotification(request, bundleOption, false);
62     if (result != ERR_OK) {
63         SendPublishHiSysEvent(request, result);
64         return result;
65     }
66     return result;
67 }
68 
SetCreatorInfoWithAtomicService(const sptr<NotificationRequest> & request)69 ErrCode AdvancedNotificationService::SetCreatorInfoWithAtomicService(const sptr<NotificationRequest> &request)
70 {
71     // set agentBundle
72     std::string agentBundleName = "";
73     if (!AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID())) {
74         agentBundleName = GetClientBundleName();
75         if (agentBundleName.empty()) {
76             ANS_LOGE("Failed to GetClientBundleName");
77             return ERR_ANS_INVALID_BUNDLE;
78         }
79     }
80 
81     int32_t uid = IPCSkeleton::GetCallingUid();
82     std::shared_ptr<NotificationBundleOption> agentBundle =
83         std::make_shared<NotificationBundleOption>(agentBundleName, uid);
84     if (agentBundle == nullptr) {
85         ANS_LOGE("Failed to create agentBundle instance");
86         return ERR_ANS_INVALID_BUNDLE;
87     }
88     request->SetAgentBundle(agentBundle);
89     int32_t pid = IPCSkeleton::GetCallingPid();
90     request->SetCreatorUid(uid);
91     request->SetCreatorPid(pid);
92     int userId = -1;
93     OsAccountManagerHelper::GetInstance().GetOsAccountLocalIdFromUid(uid, userId);
94     request->SetCreatorUserId(userId);
95     request->SetCreatorBundleName(agentBundleName);
96     return ERR_OK;
97 }
98 
CheckAndPrepareNotificationInfoWithAtomicService(const sptr<NotificationRequest> & request,sptr<NotificationBundleOption> & bundleOption)99 AnsStatus AdvancedNotificationService::CheckAndPrepareNotificationInfoWithAtomicService(
100     const sptr<NotificationRequest> &request, sptr<NotificationBundleOption> &bundleOption)
101 {
102     bool isSubsystem = AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID());
103     request->SetIsSystemApp(AccessTokenHelper::IsSystemApp() ||
104         AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID()));
105     ErrCode result = CheckUserIdParams(request->GetReceiverUserId());
106     if (result != ERR_OK) {
107         return AnsStatus(result, "User is invalid");
108     }
109     if (request->GetOwnerUserId() <= SUBSCRIBE_USER_INIT || request->GetOwnerBundleName().empty()) {
110         return AnsStatus(ERR_ANS_INVALID_PARAM, "OwnerUserId or OwnerBundleName invalid");
111     }
112     CheckRemovalWantAgent(request);
113     request->SetCreateTime(GetCurrentTime());
114     if (request->GetDeliveryTime() <= 0) {
115         request->SetDeliveryTime(GetCurrentTime());
116     }
117     result = CheckPictureSize(request);
118 
119     SetCreatorInfoWithAtomicService(request);
120     request->SetOwnerUid(0);
121 
122     FillActionButtons(request);
123 
124     bundleOption = new (std::nothrow) NotificationBundleOption(request->GetOwnerBundleName(),
125         request->GetOwnerUid());
126     if (bundleOption == nullptr) {
127         return AnsStatus(ERR_ANS_INVALID_BUNDLE, "create bundleOption failed");
128     }
129     SetClassificationWithVoip(request);
130     request->SetNotDistributed(true);
131     SetRequestBySlotType(request, bundleOption);
132 
133     result = CheckSoundPermission(request, bundleOption);
134     if (result != ERR_OK) {
135         return AnsStatus(result, "CheckSoundPermission failed");
136     }
137     if (IsNeedPushCheck(request)) {
138         result = PushCheck(request);
139         if (result != ERR_OK) {
140             return AnsStatus(result, "PushCheck failed");
141         }
142     }
143     return AnsStatus();
144 }
145 
ExecutePublishProcess(const sptr<NotificationRequest> & request,bool isUpdateByOwnerAllowed)146 AnsStatus AdvancedNotificationService::ExecutePublishProcess(
147     const sptr<NotificationRequest> &request, bool isUpdateByOwnerAllowed)
148 {
149     if (!InitPublishProcess()) {
150         return AnsStatus(ERR_ANS_NO_MEMORY, "InitPublishProcess failed");
151     }
152 
153     AnsStatus ansStatus = publishProcess_[request->GetSlotType()]->PublishPreWork(request, isUpdateByOwnerAllowed);
154     if (!ansStatus.Ok()) {
155         return ansStatus;
156     }
157 
158     ErrCode result = publishProcess_[request->GetSlotType()]->PublishNotificationByApp(request);
159     if (result != ERR_OK) {
160         return AnsStatus(result, "PublishNotificationByApp failed");
161     }
162     return AnsStatus();
163 }
164 
165 }
166 }