• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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 "distributed_data_sink_controller.h"
17 #include "call_ability_report_proxy.h"
18 #include "common_type.h"
19 #include "telephony_log_wrapper.h"
20 #include "call_object_manager.h"
21 #include "transmission_manager.h"
22 
23 namespace OHOS {
24 namespace Telephony {
OnCallCreated(const sptr<CallBase> & call,const std::string & devId)25 void DistributedDataSinkController::OnCallCreated(const sptr<CallBase> &call, const std::string &devId)
26 {
27     ConnectRemote(devId);
28     CheckLocalData(call, DistributedDataType::NAME);
29     CheckLocalData(call, DistributedDataType::LOCATION);
30     SendDataQueryReq();
31 }
32 
OnCallDestroyed()33 void DistributedDataSinkController::OnCallDestroyed()
34 {
35     if (CallObjectManager::HasCallExist()) {
36         return;
37     }
38     if (session_ != nullptr) {
39         session_->Disconnect();
40         session_.reset();
41         session_ = nullptr;
42     }
43 
44     std::lock_guard<ffrt::mutex> lock(mutex_);
45     queryInfo_.clear();
46 }
47 
ProcessCallInfo(const sptr<CallBase> & call,DistributedDataType type)48 void DistributedDataSinkController::ProcessCallInfo(const sptr<CallBase> &call, DistributedDataType type)
49 {
50     CheckLocalData(call, type);
51     SendDataQueryReq();
52 }
53 
OnConnected()54 void DistributedDataSinkController::OnConnected()
55 {
56     SendDataQueryReq();
57     SendCurrentDataQueryReq();
58 }
59 
HandleRecvMsg(int32_t msgType,const cJSON * msg)60 void DistributedDataSinkController::HandleRecvMsg(int32_t msgType, const cJSON *msg)
61 {
62     if (msg == nullptr) {
63         return;
64     }
65     switch (msgType) {
66         case static_cast<int32_t>(DistributedMsgType::DATA_RSP):
67             HandleDataQueryRsp(msg);
68             break;
69         case static_cast<int32_t>(DistributedMsgType::CURRENT_DATA_RSP):
70             HandleCurrentDataQueryRsp(msg);
71             break;
72         default:
73             break;
74     }
75 }
76 
ConnectRemote(const std::string & devId)77 void DistributedDataSinkController::ConnectRemote(const std::string &devId)
78 {
79     if (session_ != nullptr) {
80         return;
81     }
82     auto transMgr = DelayedSingleton<TransmissionManager>::GetInstance();
83     if (transMgr == nullptr) {
84         TELEPHONY_LOGE("get transmission manager fail");
85         return;
86     }
87     session_ = transMgr->CreateClientSession(shared_from_this());
88     if (session_ != nullptr) {
89         session_->Connect(devId, SESSION_NAME, SESSION_NAME);
90     }
91 }
92 
CheckLocalData(const sptr<CallBase> & call,DistributedDataType type)93 void DistributedDataSinkController::CheckLocalData(const sptr<CallBase> &call, DistributedDataType type)
94 {
95     if (call == nullptr) {
96         return;
97     }
98     std::string num = call->GetAccountNumber();
99     std::string location = call->GetNumberLocation();
100     std::string name(call->GetCallerInfo().name);
101     if (num.empty()) {
102         TELEPHONY_LOGE("invalid phone num");
103         return;
104     }
105     uint32_t queryInfo = 0;
106     if (type == DistributedDataType::NAME && name.empty()) {
107         queryInfo |= DISTRIBUTED_DATA_TYPE_OFFSET_BASE << static_cast<uint32_t>(DistributedDataType::NAME);
108     }
109     if (type == DistributedDataType::LOCATION && (location.empty() || location == "default")) {
110         queryInfo |= DISTRIBUTED_DATA_TYPE_OFFSET_BASE << static_cast<uint32_t>(DistributedDataType::LOCATION);
111     }
112     TELEPHONY_LOGI("query distributed data info %{public}d", queryInfo);
113 
114     std::lock_guard<ffrt::mutex> lock(mutex_);
115     if (queryInfo_.find(num) == queryInfo_.end()) {
116         queryInfo_[num] = queryInfo;
117     } else {
118         queryInfo_[num] |= queryInfo;
119     }
120 }
121 
CreateDataReqMsg(DistributedMsgType msgType,uint32_t itemType,const std::string & num)122 std::string DistributedDataSinkController::CreateDataReqMsg(DistributedMsgType msgType, uint32_t itemType,
123     const std::string &num)
124 {
125     std::string data = "";
126     cJSON *reqMsg = cJSON_CreateObject();
127     if (reqMsg == nullptr) {
128         TELEPHONY_LOGE("create json msg fail");
129         return data;
130     }
131     do {
132         if (cJSON_AddNumberToObject(reqMsg, DISTRIBUTED_MSG_TYPE, static_cast<int32_t>(msgType)) == nullptr) {
133             TELEPHONY_LOGE("add msg type fail");
134             break;
135         }
136         if (cJSON_AddNumberToObject(reqMsg, DISTRIBUTED_ITEM_TYPE, static_cast<int32_t>(itemType)) == nullptr) {
137             TELEPHONY_LOGE("add item type fail");
138             break;
139         }
140         if (cJSON_AddStringToObject(reqMsg, DISTRIBUTED_ITEM_NUM, num.c_str()) == nullptr) {
141             TELEPHONY_LOGE("add num fail");
142             break;
143         }
144         char *jsonData = cJSON_PrintUnformatted(reqMsg);
145         if (jsonData != nullptr) {
146             data = jsonData;
147             free(jsonData);
148             jsonData = nullptr;
149         }
150     } while (false);
151     cJSON_Delete(reqMsg);
152     return data;
153 }
154 
SendDataQueryReq()155 void DistributedDataSinkController::SendDataQueryReq()
156 {
157     if (session_ == nullptr || !session_->IsReady()) {
158         TELEPHONY_LOGI("session not ready");
159         return;
160     }
161     std::lock_guard<ffrt::mutex> lock(mutex_);
162     for (auto iter = queryInfo_.begin(); iter != queryInfo_.end(); iter++) {
163         uint32_t queryInfo = iter->second;
164         for (auto type = static_cast<uint32_t>(DistributedDataType::NAME);
165              type < static_cast<uint32_t>(DistributedDataType::MAX); type++) {
166             if (((queryInfo >> type) & DISTRIBUTED_DATA_TYPE_OFFSET_BASE) != DISTRIBUTED_DATA_TYPE_OFFSET_BASE) {
167                 continue;
168             }
169             TELEPHONY_LOGI("send request data, type %{public}d", type);
170             auto data = CreateDataReqMsg(DistributedMsgType::DATA_REQ, type, iter->first);
171             if (data.empty()) {
172                 continue;
173             }
174             session_->SendMsg(data.c_str(), static_cast<uint32_t>(data.length()));
175             iter->second &= ~(DISTRIBUTED_DATA_TYPE_OFFSET_BASE << type);
176         }
177     }
178 }
179 
HandleDataQueryRsp(const cJSON * msg)180 void DistributedDataSinkController::HandleDataQueryRsp(const cJSON *msg)
181 {
182     int32_t type = static_cast<int32_t>(DistributedDataType::MAX);
183     if (!GetInt32Value(msg, DISTRIBUTED_ITEM_TYPE, type)) {
184         return;
185     }
186     std::string num = "";
187     if (!GetStringValue(msg, DISTRIBUTED_ITEM_NUM, num)) {
188         return;
189     }
190     auto call = CallObjectManager::GetOneCallObject(num);
191     if (call == nullptr) {
192         TELEPHONY_LOGE("not find distributed call");
193         return;
194     }
195     if (type == static_cast<int32_t>(DistributedDataType::NAME)) {
196         UpdateCallName(call, msg);
197     } else if (type == static_cast<int32_t>(DistributedDataType::LOCATION)) {
198         UpdateCallLocation(call, msg);
199     }
200 }
201 
UpdateCallName(sptr<CallBase> & call,const cJSON * msg)202 void DistributedDataSinkController::UpdateCallName(sptr<CallBase> &call, const cJSON *msg)
203 {
204     std::string name = "";
205     if (!GetStringValue(msg, DISTRIBUTED_ITEM_NAME, name)) {
206         return;
207     }
208     if (name.empty()) {
209         return;
210     }
211     auto callerInfo = call->GetCallerInfo();
212     callerInfo.name = name;
213     call->SetCallerInfo(callerInfo);
214     ReportCallInfo(call);
215 }
216 
UpdateCallLocation(sptr<CallBase> & call,const cJSON * msg)217 void DistributedDataSinkController::UpdateCallLocation(sptr<CallBase> &call, const cJSON *msg)
218 {
219     std::string location = "";
220     if (!GetStringValue(msg, DISTRIBUTED_ITEM_LOCATION, location)) {
221         return;
222     }
223     if (!location.empty()) {
224         call->SetNumberLocation(location);
225         ReportCallInfo(call);
226     }
227 }
228 
ReportCallInfo(const sptr<CallBase> & call)229 void DistributedDataSinkController::ReportCallInfo(const sptr<CallBase> &call)
230 {
231     CallAttributeInfo info;
232     call->GetCallAttributeBaseInfo(info);
233     auto abilityProxy = DelayedSingleton<CallAbilityReportProxy>::GetInstance();
234     if (abilityProxy != nullptr) {
235         abilityProxy->ReportCallStateInfo(info);
236     }
237 }
238 
CreateCurrentDataReqMsg(const std::string & num)239 std::string DistributedDataSinkController::CreateCurrentDataReqMsg(const std::string &num)
240 {
241     std::string data = "";
242     cJSON *currentReqMsg = cJSON_CreateObject();
243     if (currentReqMsg == nullptr) {
244         TELEPHONY_LOGE("create json msg fail");
245         return data;
246     }
247     do {
248         if (cJSON_AddNumberToObject(currentReqMsg, DISTRIBUTED_MSG_TYPE,
249             static_cast<int32_t>(DistributedMsgType::CURRENT_DATA_REQ)) == nullptr) {
250             TELEPHONY_LOGE("add msg type fail");
251             break;
252         }
253         if (cJSON_AddStringToObject(currentReqMsg, DISTRIBUTED_ITEM_NUM, num.c_str()) == nullptr) {
254             TELEPHONY_LOGE("add num fail");
255             break;
256         }
257         char *jsonData = cJSON_PrintUnformatted(currentReqMsg);
258         if (jsonData != nullptr) {
259             data = jsonData;
260             free(jsonData);
261             jsonData = nullptr;
262         }
263     } while (false);
264     cJSON_Delete(currentReqMsg);
265     return data;
266 }
267 
SendCurrentDataQueryReq()268 void DistributedDataSinkController::SendCurrentDataQueryReq()
269 {
270     if (session_ == nullptr) {
271         return;
272     }
273     auto calls = CallObjectManager::GetAllCallList();
274     for (auto &call : calls) {
275         if (call == nullptr) {
276             continue;
277         }
278         auto callType = call->GetCallType();
279         if (callType != CallType::TYPE_IMS && callType != CallType::TYPE_CS) {
280             continue;
281         }
282         TELEPHONY_LOGI("send current data request");
283         auto data = CreateCurrentDataReqMsg(call->GetAccountNumber());
284         if (data.empty()) {
285             continue;
286         }
287         session_->SendMsg(data.c_str(), static_cast<uint32_t>(data.length()));
288     }
289 }
290 
HandleCurrentDataQueryRsp(const cJSON * msg)291 void DistributedDataSinkController::HandleCurrentDataQueryRsp(const cJSON *msg)
292 {
293     HandleMuted(msg);
294     std::string num = "";
295     if (!GetStringValue(msg, DISTRIBUTED_ITEM_NUM, num)) {
296         return;
297     }
298     int32_t direction = static_cast<int32_t>(CallDirection::CALL_DIRECTION_UNKNOW);
299     if (!GetInt32Value(msg, DISTRIBUTED_ITEM_DIRECTION, direction)) {
300         return;
301     }
302     TELEPHONY_LOGI("get distributed call direction %{public}d", direction);
303     if (direction < static_cast<int32_t>(CallDirection::CALL_DIRECTION_IN) ||
304         direction > static_cast<int32_t>(CallDirection::CALL_DIRECTION_OUT)) {
305         return;
306     }
307     auto call = CallObjectManager::GetOneCallObject(num);
308     if (call != nullptr) {
309         call->SetCallDirection(static_cast<CallDirection>(direction));
310     }
311 }
312 
313 } // namespace Telephony
314 } // namespace OHOS
315