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 "interoperable_communication_manager.h"
17 #include "interoperable_server_manager.h"
18 #include "interoperable_client_manager.h"
19 #include "parameters.h"
20 #include "telephony_log_wrapper.h"
21
22 namespace OHOS {
23 namespace Telephony {
InteroperableCommunicationManager()24 InteroperableCommunicationManager::InteroperableCommunicationManager()
25 {
26 devObserver_ = DelayedSingleton<InteroperableDeviceObserver>::GetInstance();
27 }
28
~InteroperableCommunicationManager()29 InteroperableCommunicationManager::~InteroperableCommunicationManager()
30 {
31 devObserver_ = nullptr;
32 }
33
OnDeviceOnline(const DistributedHardware::DmDeviceInfo & deviceInfo)34 void InteroperableCommunicationManager::OnDeviceOnline(const DistributedHardware::DmDeviceInfo &deviceInfo)
35 {
36 std::string networkId = deviceInfo.networkId;
37 std::string devName = deviceInfo.deviceName;
38 uint16_t devType = deviceInfo.deviceTypeId;
39 {
40 std::lock_guard<ffrt::mutex> lock(mutex_);
41 std::string ownType = system::GetParameter("const.product.devicetype", "");
42 if (devType == 0x0E && (ownType == "wearable" || ownType == "car")) { // 0x0E手机
43 role_ = InteroperableRole::OTHERS;
44 } else if (devType == 0x6D || devType == 0x83) { // 0x6D手表,0x83车机
45 role_ = InteroperableRole::PHONE;
46 } else {
47 TELEPHONY_LOGE("not interoperable device");
48 return;
49 }
50 auto iter = std::find(peerDevices_.begin(), peerDevices_.end(), networkId);
51 if (iter == peerDevices_.end()) {
52 peerDevices_.emplace_back(networkId);
53 }
54 if (dataController_ == nullptr) {
55 if (role_ == InteroperableRole::OTHERS) {
56 dataController_ = std::make_shared<InteroperableClientManager>();
57 } else {
58 dataController_ = std::make_shared<InteroperableServerManager>();
59 }
60 }
61 }
62 devObserver_->RegisterDevStatusCallback(dataController_);
63 devObserver_->OnDeviceOnline(networkId, devName, devType);
64 }
65
OnDeviceOffline(const DistributedHardware::DmDeviceInfo & deviceInfo)66 void InteroperableCommunicationManager::OnDeviceOffline(const DistributedHardware::DmDeviceInfo &deviceInfo)
67 {
68 if (devObserver_ == nullptr) {
69 return;
70 }
71 std::string networkId = deviceInfo.networkId;
72 std::string devName = deviceInfo.deviceName;
73 uint16_t devType = deviceInfo.deviceTypeId;
74 std::string ownType = system::GetParameter("const.product.devicetype", "");
75 if (devType == 0x0E && ownType != "wearable" && ownType != "car") { // 0x0E手机
76 TELEPHONY_LOGE("not interoperable device");
77 return;
78 }
79 devObserver_->OnDeviceOffline(networkId, devName, devType);
80 devObserver_->UnRegisterDevStatusCallback(dataController_);
81
82 std::lock_guard<ffrt::mutex> lock(mutex_);
83 auto iter = std::find(peerDevices_.begin(), peerDevices_.end(), networkId);
84 if (iter != peerDevices_.end()) {
85 peerDevices_.erase(iter);
86 }
87 if (!peerDevices_.empty()) {
88 TELEPHONY_LOGI("device list not empty");
89 return;
90 }
91
92 role_ = InteroperableRole::UNKNOWN;
93 if (dataController_ != nullptr) {
94 dataController_.reset();
95 dataController_ = nullptr;
96 }
97 }
98
SetMuted(bool isMute)99 void InteroperableCommunicationManager::SetMuted(bool isMute)
100 {
101 std::lock_guard<ffrt::mutex> lock(mutex_);
102 if (dataController_ == nullptr) {
103 return;
104 }
105 TELEPHONY_LOGI("InteroperableCommunicationManager set muted %{public}d", isMute);
106 dataController_->SetMuted(isMute);
107 }
108
MuteRinger()109 void InteroperableCommunicationManager::MuteRinger()
110 {
111 std::lock_guard<ffrt::mutex> lock(mutex_);
112 if (dataController_ == nullptr) {
113 return;
114 }
115 TELEPHONY_LOGI("InteroperableCommunicationManager mute ringer");
116 dataController_->MuteRinger();
117 }
118
CallStateUpdated(sptr<CallBase> & callObjectPtr,TelCallState priorState,TelCallState nextState)119 void InteroperableCommunicationManager::CallStateUpdated(
120 sptr<CallBase> &callObjectPtr, TelCallState priorState, TelCallState nextState)
121 {
122 std::lock_guard<ffrt::mutex> lock(mutex_);
123 if (callObjectPtr == nullptr || dataController_ == nullptr) {
124 TELEPHONY_LOGE("callObjectPtr is null or dataController_ is null");
125 return;
126 }
127 if (nextState == TelCallState::CALL_STATUS_INCOMING) {
128 TELEPHONY_LOGI("interoperable new call created");
129 if (role_ == InteroperableRole::PHONE) {
130 TELEPHONY_LOGI("phone recv call");
131 return;
132 }
133 if (peerDevices_.empty()) {
134 TELEPHONY_LOGE("call created but no peer device");
135 return;
136 }
137 dataController_->OnCallCreated(callObjectPtr, peerDevices_.front());
138 } else if (nextState == TelCallState::CALL_STATUS_DISCONNECTED ||
139 nextState == TelCallState::CALL_STATUS_DISCONNECTING) {
140 TELEPHONY_LOGI("interoperable call destroyed");
141 dataController_->OnCallDestroyed();
142 }
143 }
144
NewCallCreated(sptr<CallBase> & call)145 void InteroperableCommunicationManager::NewCallCreated(sptr<CallBase> &call)
146 {
147 TELEPHONY_LOGI("interoperable NewCallCreated");
148 if (dataController_ == nullptr) {
149 TELEPHONY_LOGE("dataController is nullptr");
150 return;
151 }
152 if (peerDevices_.empty() || call == nullptr) {
153 TELEPHONY_LOGE("no peer device or call is nullptr");
154 return;
155 }
156 dataController_->CallCreated(call, peerDevices_.front());
157 }
158
GetBtCallSlotId(const std::string & phoneNum)159 int32_t InteroperableCommunicationManager::GetBtCallSlotId(const std::string &phoneNum)
160 {
161 int32_t btCallSlot = BT_CALL_INVALID_SLOT;
162 if (dataController_ == nullptr) {
163 return btCallSlot;
164 }
165
166 btCallSlot = dataController_->GetBtSlotIdByPhoneNumber(phoneNum);
167 if (btCallSlot == BT_CALL_INVALID_SLOT) { // slotId has not been received yet, need wait.
168 dataController_->WaitForBtSlotId(phoneNum);
169 btCallSlot = dataController_->GetBtSlotIdByPhoneNumber(phoneNum);
170 }
171 dataController_->DeleteBtSlotIdByPhoneNumber(phoneNum); // delete after query
172 return btCallSlot;
173 }
174 }
175 }
176