1 /*
2 * Copyright (c) 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 "push_callback_stub.h"
17
18 #include "ans_log_wrapper.h"
19 #include "event_handler.h"
20 #include "ipc_types.h"
21 #include "message_parcel.h"
22 #include "push_callback_proxy.h"
23 #include "singleton.h"
24 #include "ans_inner_errors.h"
25
26 using namespace OHOS::AppExecFwk;
27 namespace OHOS {
28 namespace Notification {
PushCallBackStub()29 PushCallBackStub::PushCallBackStub() {}
30
~PushCallBackStub()31 PushCallBackStub::~PushCallBackStub() {}
32
33 enum PushCheckErrCode : int32_t {
34 SUCCESS = 0,
35 FIXED_PARAMETER_INVALID = 1,
36 NETWORK_UNREACHABLE = 2,
37 SPECIFIED_NOTIFICATIONS_FAILED = 3,
38 SYSTEM_ERROR = 4,
39 OPTIONAL_PARAMETER_INVALID = 5
40 };
41
ConvertPushCheckCodeToErrCode(int32_t pushCheckCode)42 ErrCode PushCallBackStub::ConvertPushCheckCodeToErrCode(int32_t pushCheckCode)
43 {
44 ErrCode errCode;
45 PushCheckErrCode checkCode = static_cast<PushCheckErrCode>(pushCheckCode);
46
47 switch (checkCode) {
48 case PushCheckErrCode::SUCCESS:
49 errCode = ERR_OK;
50 break;
51 case PushCheckErrCode::FIXED_PARAMETER_INVALID:
52 errCode = ERR_ANS_TASK_ERR;
53 break;
54 case PushCheckErrCode::NETWORK_UNREACHABLE:
55 errCode = ERR_ANS_PUSH_CHECK_NETWORK_UNREACHABLE;
56 break;
57 case PushCheckErrCode::SPECIFIED_NOTIFICATIONS_FAILED:
58 errCode = ERR_ANS_PUSH_CHECK_FAILED;
59 break;
60 case PushCheckErrCode::SYSTEM_ERROR:
61 errCode = ERR_ANS_TASK_ERR;
62 break;
63 case PushCheckErrCode::OPTIONAL_PARAMETER_INVALID:
64 errCode = ERR_ANS_PUSH_CHECK_EXTRAINFO_INVALID;
65 break;
66 default:
67 errCode = ERR_ANS_PUSH_CHECK_FAILED;
68 break;
69 }
70 return errCode;
71 }
72
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)73 int PushCallBackStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
74 {
75 ANS_LOGD("called.");
76 if (data.ReadInterfaceToken() != GetDescriptor()) {
77 ANS_LOGE("local descriptor is not equal to remote");
78 return ERR_INVALID_STATE;
79 }
80 switch (code) {
81 case static_cast<uint32_t>(NotificationInterfaceCode::ON_CHECK_NOTIFICATION): {
82 auto notificationData = data.ReadString();
83 int32_t checkResult = ERR_ANS_TASK_ERR;
84
85 std::shared_ptr<EventHandler> handler = std::make_shared<EventHandler>(EventRunner::GetMainEventRunner());
86 wptr<PushCallBackStub> weak = this;
87 std::shared_ptr<PushCallBackParam> pushCallBackParam = std::make_shared<PushCallBackParam>();
88 std::unique_lock<std::mutex> uniqueLock(pushCallBackParam->callBackMutex);
89 if (handler) {
90 handler->PostTask([weak, notificationData, pushCallBackParam]() {
91 auto pushCallBackStub = weak.promote();
92 if (pushCallBackStub == nullptr) {
93 ANS_LOGE("pushCallBackStub is nullptr!");
94 return;
95 }
96 pushCallBackStub->OnCheckNotification(notificationData, pushCallBackParam);
97 });
98 }
99
100 pushCallBackParam->callBackCondition.wait(uniqueLock, [=]() {return pushCallBackParam->ready; });
101 checkResult = ConvertPushCheckCodeToErrCode(pushCallBackParam->result);
102 ANS_LOGD("Push check result:%{public}d", checkResult);
103 if (!reply.WriteInt32(checkResult)) {
104 ANS_LOGE("Failed to write reply ");
105 return ERR_INVALID_REPLY;
106 }
107 return NO_ERROR;
108 }
109
110 default: {
111 return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
112 }
113 }
114 }
115
OnCheckNotification(const std::string & notificationData,const std::shared_ptr<PushCallBackParam> & pushCallBackParam)116 int32_t PushCallBackProxy::OnCheckNotification(
117 const std::string ¬ificationData, const std::shared_ptr<PushCallBackParam> &pushCallBackParam)
118 {
119 MessageParcel data;
120 MessageParcel reply;
121 MessageOption option;
122
123 if (!data.WriteInterfaceToken(PushCallBackProxy::GetDescriptor())) {
124 ANS_LOGE("Write interface token failed.");
125 return false;
126 }
127
128 if (!data.WriteString(notificationData)) {
129 ANS_LOGE("Connect done element error.");
130 return false;
131 }
132
133 auto remote = Remote();
134 if (remote == nullptr) {
135 ANS_LOGE("Get Remote fail.");
136 return false;
137 }
138
139 int error = remote->SendRequest(static_cast<uint32_t>(NotificationInterfaceCode::ON_CHECK_NOTIFICATION),
140 data, reply, option);
141 if (error != NO_ERROR) {
142 ANS_LOGE("Connect done fail, error: %{public}d", error);
143 return false;
144 }
145
146 return reply.ReadInt32();
147 }
148 } // namespace Notification
149 } // namespace OHOS
150