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