• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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