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 "antifraud_hsdr_helper.h"
17
18 #include <string>
19 #include <vector>
20 #include <cJSON.h>
21 #include "errors.h"
22 #include "extension_manager_client.h"
23 #include "ipc_types.h"
24 #include "iremote_object.h"
25 #include "message_option.h"
26 #include "telephony_log_wrapper.h"
27 #include "want.h"
28
29 namespace OHOS {
30 namespace Telephony {
31 using Client = AAFwk::ExtensionManagerClient;
32 constexpr int CALLMANAGER_HSDR_ERR_SUCCESS = 0;
33 constexpr int CALLMANAGER_HSDR_ERR_LOCAL_PTR_NULL = -1;
34 constexpr int CALLMANAGER_HSDR_ERR_WRITE_DATA_FAIL = -2;
35 constexpr int CALLMANAGER_HSDR_ERR_READ_DATA_FAIL = -3;
36 constexpr int CALLMANAGER_HSDR_ERR_PERMISSION_ERR = -4;
37 constexpr int UNEXPECT_DISCONNECT_CODE = -1;
38
ReadStr16(MessageParcel & parcel,std::string & str8)39 static bool ReadStr16(MessageParcel &parcel, std::string &str8)
40 {
41 std::u16string str16;
42 auto isOk = parcel.ReadString16(str16);
43 str8 = Str16ToStr8(str16);
44 return isOk;
45 }
46
OnAbilityConnectDone(const AppExecFwk::ElementName & element,const sptr<IRemoteObject> & remoteObject,int resultCode)47 void HsdrConnection::OnAbilityConnectDone(
48 const AppExecFwk::ElementName &element, const sptr<IRemoteObject> &remoteObject, int resultCode)
49 {
50 std::lock_guard<ffrt::mutex> lock(remoteProxyMutex_);
51 TELEPHONY_LOGI("HsdrConnection::OnAbilityConnectDone begin.");
52 if (resultCode != 0) {
53 TELEPHONY_LOGE("connect failed, resultCode: %{public}d", resultCode);
54 return;
55 }
56 if (remoteObject == nullptr || connectedCallback_ == nullptr) {
57 TELEPHONY_LOGE("remoteObject or connectedCallback_ is null.");
58 return;
59 }
60 remoteObject_ = remoteObject;
61 connectedCallback_(remoteObject_);
62 }
63
OnAbilityDisconnectDone(const AppExecFwk::ElementName & element,int resultCode)64 void HsdrConnection::OnAbilityDisconnectDone(const AppExecFwk::ElementName &element, int resultCode)
65 {
66 std::lock_guard<ffrt::mutex> lock(remoteProxyMutex_);
67 if (resultCode == UNEXPECT_DISCONNECT_CODE) {
68 TELEPHONY_LOGE("unexpected disconnect!");
69 }
70 TELEPHONY_LOGI("HsdrConnection::OnAbilityDisconnectDone");
71 remoteObject_ = nullptr;
72 }
73
IsAlive()74 bool HsdrConnection::IsAlive()
75 {
76 std::lock_guard<ffrt::mutex> lock(remoteProxyMutex_);
77 return remoteObject_ != nullptr && !remoteObject_->IsObjectDead();
78 }
79
GetAbilityProxy()80 sptr<IRemoteObject> HsdrConnection::GetAbilityProxy()
81 {
82 std::lock_guard<ffrt::mutex> lock(remoteProxyMutex_);
83 return remoteObject_;
84 }
85
HsdrHelper()86 HsdrHelper::HsdrHelper() {}
ConnectHsdr(ConnectedCallback connectedCallback)87 int HsdrHelper::ConnectHsdr(ConnectedCallback connectedCallback)
88 {
89 std::lock_guard<ffrt::mutex> lock(connectionMutex_);
90 TELEPHONY_LOGI("ConnectHsdr begin.");
91 if (connection_ != nullptr && connection_->IsAlive()) {
92 TELEPHONY_LOGI("Already connected, use old connection.");
93 connectedCallback(connection_->GetAbilityProxy());
94 return OHOS::ERR_OK;
95 }
96 AAFwk::Want want;
97 want.SetElementName(HSDR_BUNDLE_NAME, HSDR_ABILITY_NAME);
98 want.SetAction("NO_PUSH");
99 connection_ = new (std::nothrow) HsdrConnection(connectedCallback);
100 if (connection_ == nullptr) {
101 TELEPHONY_LOGE("connection_ is nullptr.");
102 return CALLMANAGER_HSDR_ERR_LOCAL_PTR_NULL;
103 }
104 auto errCode = Client::GetInstance().ConnectServiceExtensionAbility(want, connection_, HSDR_USERID);
105 if (errCode != OHOS::ERR_OK) {
106 connection_ = nullptr;
107 TELEPHONY_LOGE("ConnectServiceExtensionAbility failed, errCode: %{public}d", errCode);
108 return errCode;
109 }
110 TELEPHONY_LOGI("ConnectHsdr done.");
111 return CALLMANAGER_HSDR_ERR_SUCCESS;
112 }
113
DisconnectHsdr()114 void HsdrHelper::DisconnectHsdr()
115 {
116 std::lock_guard<ffrt::mutex> lock(connectionMutex_);
117 TELEPHONY_LOGI("HsdrHelper::DisconnectHsdr begin.");
118 if (connection_ == nullptr) {
119 return;
120 }
121 auto errCode = Client::GetInstance().DisconnectAbility(connection_);
122 connection_ = nullptr;
123 if (errCode != OHOS::ERR_OK) {
124 TELEPHONY_LOGE("DisconnectAbility failed, errCode: %{public}d", errCode);
125 }
126 }
127
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)128 int32_t HsdrCallbackStub::OnRemoteRequest(
129 uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
130 {
131 TELEPHONY_LOGI("HsdrCallbackStub::OnRemoteRequest begin, code = %{public}u", code);
132 auto descriptor = GetDescriptor();
133 auto remoteDescriptor = data.ReadInterfaceToken();
134 if (descriptor != remoteDescriptor) {
135 onError_(CALLMANAGER_HSDR_ERR_PERMISSION_ERR);
136 return CALLMANAGER_HSDR_ERR_PERMISSION_ERR;
137 }
138 HsdrResponse response;
139 if (!ReadStr16(data, response.requestId_)) {
140 onError_(CALLMANAGER_HSDR_ERR_READ_DATA_FAIL);
141 return CALLMANAGER_HSDR_ERR_READ_DATA_FAIL;
142 }
143 if (response.requestId_ != requestId_) {
144 TELEPHONY_LOGW("expect %{public}s, received %{public}s", requestId_.c_str(), response.requestId_.c_str());
145 }
146 int cloudErrCode = data.ReadInt32();
147 TELEPHONY_LOGI("cloud ErrCode: %{public}d", cloudErrCode);
148 std::vector<std::u16string> body;
149 if (!data.ReadString16Vector(&body)) {
150 onError_(CALLMANAGER_HSDR_ERR_READ_DATA_FAIL);
151 return CALLMANAGER_HSDR_ERR_READ_DATA_FAIL;
152 }
153 for (const auto &str : body) {
154 response.body_ += OHOS::Str16ToStr8(str);
155 }
156 onResponse_(response);
157 TELEPHONY_LOGI("HsdrCallbackStub::OnRemoteRequest done.");
158 return CALLMANAGER_HSDR_ERR_SUCCESS;
159 }
160
RequestHsdrServiceSync(const HsdrRequest & request,std::string & result)161 int HsdrProxy::RequestHsdrServiceSync(const HsdrRequest &request, std::string &result)
162 {
163 int errCode = CALLMANAGER_HSDR_ERR_SUCCESS;
164 MessageParcel data;
165 if (!WriteMessageParcel(data, request)) {
166 return CALLMANAGER_HSDR_ERR_WRITE_DATA_FAIL;
167 }
168
169 MessageParcel reply;
170 MessageOption option;
171 auto remote = Remote();
172 if (remote == nullptr) {
173 return CALLMANAGER_HSDR_ERR_LOCAL_PTR_NULL;
174 }
175 errCode = remote->SendRequest(static_cast<uint32_t>(request.command_), data, reply, option);
176 if (errCode != OHOS::ERR_OK) {
177 TELEPHONY_LOGE("SendRequest failed, errCode: %{public}d", errCode);
178 return errCode;
179 }
180 int replyCode = reply.ReadInt32();
181 TELEPHONY_LOGI("reply code: %{public}d", replyCode);
182 std::vector<std::u16string> responseBuffer;
183 if (!reply.ReadString16Vector(&responseBuffer)) {
184 return CALLMANAGER_HSDR_ERR_READ_DATA_FAIL;
185 }
186 for (const auto &part : responseBuffer) {
187 result += OHOS::Str16ToStr8(part);
188 }
189 return errCode;
190 }
191
RequestHsdrServiceAsync(sptr<IRemoteObject> callbackStub,const HsdrRequest & request)192 int HsdrProxy::RequestHsdrServiceAsync(sptr<IRemoteObject> callbackStub, const HsdrRequest &request)
193 {
194 int errCode = CALLMANAGER_HSDR_ERR_SUCCESS;
195 MessageParcel data;
196 if (!WriteMessageParcel(data, request)) {
197 return CALLMANAGER_HSDR_ERR_WRITE_DATA_FAIL;
198 }
199 if (!data.WriteRemoteObject(callbackStub)) {
200 return CALLMANAGER_HSDR_ERR_WRITE_DATA_FAIL;
201 }
202 MessageParcel reply;
203 MessageOption option;
204 auto remote = Remote();
205 if (remote == nullptr) {
206 return CALLMANAGER_HSDR_ERR_LOCAL_PTR_NULL;
207 }
208 errCode = remote->SendRequest(static_cast<uint32_t>(request.command_), data, reply, option);
209 if (errCode != OHOS::ERR_OK) {
210 TELEPHONY_LOGE("SendRequest failed, errCode: %{public}d", errCode);
211 return errCode;
212 }
213 auto replyCode = reply.ReadInt32();
214 TELEPHONY_LOGI("reply code: %{public}d", replyCode);
215 return errCode;
216 }
217
WriteMessageParcel(MessageParcel & data,const HsdrRequest & request)218 bool HsdrProxy::WriteMessageParcel(MessageParcel &data, const HsdrRequest &request)
219 {
220 if (!data.WriteInterfaceToken(GetDescriptor())) {
221 return false;
222 }
223
224 std::vector<std::u16string> payload = { OHOS::Str8ToStr16(request.body_) };
225 if (!data.WriteString16(OHOS::Str8ToStr16(request.serviceName_)) ||
226 !data.WriteString16(OHOS::Str8ToStr16(request.requestId_)) ||
227 !data.WriteString16Vector(payload)) {
228 return false;
229 }
230 return true;
231 }
232 } // namespace Telephony
233 } // namespace OHOS