1 /*
2  * Copyright (C) 2021 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 #include "video_control_manager.h"
16 
17 #include <algorithm>
18 
19 #include "call_ability_report_proxy.h"
20 #include "cellular_call_connection.h"
21 #include "file_ex.h"
22 #include "telephony_errors.h"
23 #include "telephony_log_wrapper.h"
24 
25 #ifdef ABILITY_CAMERA_SUPPORT
26 #include "input/camera_manager.h"
27 #endif
28 
29 namespace OHOS {
30 namespace Telephony {
31 namespace {
32 const int16_t CAMERA_ROTATION_0 = 0;
33 const int16_t CAMERA_ROTATION_90 = 90;
34 const int16_t CAMERA_ROTATION_180 = 180;
35 const int16_t CAMERA_ROTATION_270 = 270;
36 const int16_t VIDEO_WINDOWS_Z_BOTTOM = 0;
37 const int16_t VIDEO_WINDOWS_Z_TOP = 1;
38 const float MIN_CAMERA_ZOOM = 0.1;
39 const float MAX_CAMERA_ZOOM = 10.0;
40 const std::string SUPPORT_PICTURE_EXT = "png";
41 } // namespace
42 
VideoControlManager()43 VideoControlManager::VideoControlManager() : isOpenCamera_(false) {}
44 
~VideoControlManager()45 VideoControlManager::~VideoControlManager() {}
46 
ControlCamera(int32_t callId,std::u16string & cameraId,int32_t callingUid,int32_t callingPid)47 int32_t VideoControlManager::ControlCamera(
48     int32_t callId, std::u16string &cameraId, int32_t callingUid, int32_t callingPid)
49 {
50     if (cameraId.empty()) {
51         return CloseCamera(callId, cameraId, callingUid, callingPid);
52     } else {
53         return OpenCamera(callId, cameraId, callingUid, callingPid);
54     }
55 }
56 
SetPreviewWindow(int32_t callId,std::string & surfaceId,sptr<Surface> surface)57 int32_t VideoControlManager::SetPreviewWindow(int32_t callId, std::string &surfaceId, sptr<Surface> surface)
58 {
59     int32_t ret = TELEPHONY_ERR_FAIL;
60     ret = CallPolicy::VideoCallPolicy(callId);
61     if (ret != TELEPHONY_SUCCESS) {
62         TELEPHONY_LOGE("check prerequisites failed !");
63         return ret;
64     }
65     sptr<CallBase> callPtr = CallObjectManager::GetOneCallObject(callId);
66     if (callPtr == nullptr) {
67         TELEPHONY_LOGE("the call object is nullptr, callId:%{public}d", callId);
68         return TELEPHONY_ERR_LOCAL_PTR_NULL;
69     }
70     if (callPtr->GetCallType() == CallType::TYPE_IMS) {
71         sptr<IMSCall> netCall = reinterpret_cast<IMSCall *>(callPtr.GetRefPtr());
72         ret = netCall->SetPreviewWindow(surfaceId, surface);
73         if (ret != TELEPHONY_SUCCESS) {
74             TELEPHONY_LOGE("SetPreviewWindow failed!");
75             return ret;
76         }
77     }
78     return TELEPHONY_SUCCESS;
79 }
80 
SetDisplayWindow(int32_t callId,std::string & surfaceId,sptr<Surface> surface)81 int32_t VideoControlManager::SetDisplayWindow(int32_t callId, std::string &surfaceId, sptr<Surface> surface)
82 {
83     int32_t ret = TELEPHONY_ERR_FAIL;
84     ret = CallPolicy::VideoCallPolicy(callId);
85     if (ret != TELEPHONY_SUCCESS) {
86         TELEPHONY_LOGE("check prerequisites failed !");
87         return ret;
88     }
89     sptr<CallBase> callPtr = CallObjectManager::GetOneCallObject(callId);
90     if (callPtr == nullptr) {
91         TELEPHONY_LOGE("the call object is nullptr, callId:%{public}d", callId);
92         return TELEPHONY_ERR_LOCAL_PTR_NULL;
93     }
94     if (callPtr->GetCallType() == CallType::TYPE_IMS) {
95         sptr<IMSCall> netCall = reinterpret_cast<IMSCall *>(callPtr.GetRefPtr());
96         ret = netCall->SetDisplayWindow(surfaceId, surface);
97         if (ret != TELEPHONY_SUCCESS) {
98             TELEPHONY_LOGE("SetDisplayWindow failed!");
99             return ret;
100         }
101     }
102     return TELEPHONY_SUCCESS;
103 }
104 
SetCameraZoom(float zoomRatio)105 int32_t VideoControlManager::SetCameraZoom(float zoomRatio)
106 {
107     // param check
108     if (zoomRatio < MIN_CAMERA_ZOOM || zoomRatio > MAX_CAMERA_ZOOM) {
109         TELEPHONY_LOGE("camera zoom error!!");
110         return CALL_ERR_VIDEO_INVALID_ZOOM;
111     }
112     return DelayedSingleton<CellularCallConnection>::GetInstance()->SetCameraZoom(zoomRatio);
113 }
114 
SetPausePicture(int32_t callId,std::u16string & path)115 int32_t VideoControlManager::SetPausePicture(int32_t callId, std::u16string &path)
116 {
117     int32_t ret = TELEPHONY_ERR_FAIL;
118     ret = CallPolicy::VideoCallPolicy(callId);
119     if (ret != TELEPHONY_SUCCESS) {
120         TELEPHONY_LOGE("check prerequisites failed !");
121         return ret;
122     }
123     std::string tempPath(Str16ToStr8(path));
124     sptr<CallBase> callPtr = CallObjectManager::GetOneCallObject(callId);
125     if (callPtr == nullptr) {
126         TELEPHONY_LOGE("the call object is nullptr, callId:%{public}d", callId);
127         return TELEPHONY_ERR_LOCAL_PTR_NULL;
128     }
129     if (callPtr->GetCallType() == CallType::TYPE_IMS) {
130         sptr<IMSCall> netCall = reinterpret_cast<IMSCall *>(callPtr.GetRefPtr());
131         ret = netCall->SetPausePicture(tempPath);
132         if (ret != TELEPHONY_SUCCESS) {
133             TELEPHONY_LOGE("SetPausePicture failed!");
134             return ret;
135         }
136     }
137     return TELEPHONY_SUCCESS;
138 }
139 
SetDeviceDirection(int32_t callId,int32_t rotation)140 int32_t VideoControlManager::SetDeviceDirection(int32_t callId, int32_t rotation)
141 {
142     int32_t ret = TELEPHONY_ERR_FAIL;
143     ret = CallPolicy::VideoCallPolicy(callId);
144     if (ret != TELEPHONY_SUCCESS) {
145         TELEPHONY_LOGE("check prerequisites failed !");
146         return ret;
147     }
148     // param check
149     if (rotation == CAMERA_ROTATION_0 || rotation == CAMERA_ROTATION_90 || rotation == CAMERA_ROTATION_180 ||
150         rotation == CAMERA_ROTATION_270) {
151         sptr<CallBase> callPtr = CallObjectManager::GetOneCallObject(callId);
152         if (callPtr == nullptr) {
153             TELEPHONY_LOGE("the call object is nullptr, callId:%{public}d", callId);
154             return TELEPHONY_ERR_LOCAL_PTR_NULL;
155         }
156         if (callPtr->GetCallType() == CallType::TYPE_IMS) {
157             sptr<IMSCall> netCall = reinterpret_cast<IMSCall *>(callPtr.GetRefPtr());
158             ret = netCall->SetDeviceDirection(rotation);
159             if (ret != TELEPHONY_SUCCESS) {
160                 TELEPHONY_LOGE("SetDeviceDirection failed!");
161                 return ret;
162             }
163         }
164         return TELEPHONY_SUCCESS;
165     }
166     TELEPHONY_LOGE("error rotation:%{public}d", rotation);
167     return CALL_ERR_VIDEO_INVALID_ROTATION;
168 }
169 
UpdateImsCallMode(int32_t callId,ImsCallMode callMode)170 int32_t VideoControlManager::UpdateImsCallMode(int32_t callId, ImsCallMode callMode)
171 {
172     int32_t ret = TELEPHONY_ERR_FAIL;
173     ret = CallPolicy::VideoCallPolicy(callId);
174     if (ret != TELEPHONY_SUCCESS) {
175         TELEPHONY_LOGE("check prerequisites failed !");
176         return ret;
177     }
178     sptr<CallBase> callPtr = CallObjectManager::GetOneCallObject(callId);
179     if (callPtr == nullptr) {
180         TELEPHONY_LOGE("the call object is nullptr, callId:%{public}d", callId);
181         return TELEPHONY_ERR_LOCAL_PTR_NULL;
182     }
183     if (callPtr->GetCallType() == CallType::TYPE_IMS) {
184         // only netcall type support update call media mode
185         sptr<IMSCall> netCall = reinterpret_cast<IMSCall *>(callPtr.GetRefPtr());
186         TELEPHONY_LOGI("ims call update media request");
187         ret = netCall->UpdateImsCallMode(callMode);
188         if (ret != TELEPHONY_SUCCESS) {
189             TELEPHONY_LOGE("UpdateImsCallMode failed!. %{public}d", ret);
190         }
191     }
192     return ret;
193 }
194 
ReportImsCallModeInfo(CallMediaModeInfo & imsCallModeInfo)195 int32_t VideoControlManager::ReportImsCallModeInfo(CallMediaModeInfo &imsCallModeInfo)
196 {
197     return DelayedSingleton<CallAbilityReportProxy>::GetInstance()->ReportImsCallModeChange(imsCallModeInfo);
198 }
199 
OpenCamera(int32_t callId,std::u16string & cameraId,int32_t callingUid,int32_t callingPid)200 int32_t VideoControlManager::OpenCamera(
201     int32_t callId, std::u16string &cameraId, int32_t callingUid, int32_t callingPid)
202 {
203     // cameraId check
204     std::string id(Str16ToStr8(cameraId));
205     int32_t ret = TELEPHONY_ERR_FAIL;
206     ret = CallPolicy::VideoCallPolicy(callId);
207     if (ret != TELEPHONY_SUCCESS) {
208         TELEPHONY_LOGE("check prerequisites failed !");
209         return ret;
210     }
211     sptr<CallBase> callPtr = CallObjectManager::GetOneCallObject(callId);
212     if (callPtr == nullptr || callPtr.GetRefPtr() == nullptr) {
213         TELEPHONY_LOGE("the call object is nullptr, callId:%{public}d", callId);
214         return TELEPHONY_ERR_LOCAL_PTR_NULL;
215     }
216     if (callPtr->GetCallType() == CallType::TYPE_IMS) {
217         sptr<IMSCall> netCall = reinterpret_cast<IMSCall *>(callPtr.GetRefPtr());
218         if (netCall == nullptr) {
219             TELEPHONY_LOGE("the netCall is nullptr, callId:%{public}d", callId);
220             return TELEPHONY_ERR_LOCAL_PTR_NULL;
221         }
222         ret = netCall->ControlCamera(id, callingUid, callingPid);
223         if (ret == TELEPHONY_SUCCESS) {
224             isOpenCamera_ = true;
225         }
226         ret = netCall->RequestCameraCapabilities();
227         if (ret != TELEPHONY_SUCCESS) {
228             TELEPHONY_LOGE("RequestCameraCapabilities failed!");
229             return ret;
230         }
231     }
232     return ret;
233 }
234 
CloseCamera(int32_t callId,std::u16string & cameraId,int32_t callingUid,int32_t callingPid)235 int32_t VideoControlManager::CloseCamera(
236     int32_t callId, std::u16string &cameraId, int32_t callingUid, int32_t callingPid)
237 {
238     std::string id(Str16ToStr8(cameraId));
239     int32_t ret = TELEPHONY_ERR_FAIL;
240     ret = CallPolicy::VideoCallPolicy(callId);
241     if (ret != TELEPHONY_SUCCESS) {
242         TELEPHONY_LOGE("check prerequisites failed !");
243         return ret;
244     }
245     if (isOpenCamera_) {
246         sptr<CallBase> callPtr = CallObjectManager::GetOneCallObject(callId);
247         if (callPtr == nullptr) {
248             TELEPHONY_LOGE("the call object is nullptr, callId:%{public}d", callId);
249             return TELEPHONY_ERR_LOCAL_PTR_NULL;
250         }
251         if (callPtr->GetCallType() == CallType::TYPE_IMS) {
252             sptr<IMSCall> netCall = reinterpret_cast<IMSCall *>(callPtr.GetRefPtr());
253             ret = netCall->ControlCamera(id, callingUid, callingPid);
254             if (ret == TELEPHONY_SUCCESS) {
255                 isOpenCamera_ = true;
256             }
257         }
258         return ret;
259     }
260     TELEPHONY_LOGE("Camera not turned on");
261     return CALL_ERR_CAMERA_NOT_TURNED_ON;
262 }
263 
ContainCameraID(std::string id)264 bool VideoControlManager::ContainCameraID(std::string id)
265 {
266     bool bRet = false;
267 #ifdef ABILITY_CAMERA_SUPPORT
268     using namespace OHOS::CameraStandard;
269     sptr<CameraManager> camManagerObj = CameraManager::GetInstance();
270     std::vector<sptr<CameraStandard::CameraDevice>> cameraObjList = camManagerObj->GetSupportedCameras();
271 
272     for (auto &it : cameraObjList) {
273         if (id.compare(it->GetID()) == 0) {
274             bRet = true;
275             TELEPHONY_LOGI("Contain Camera ID:  : %{public}s", id.c_str());
276             break;
277         }
278     }
279 #endif
280     return bRet;
281 }
282 
IsPngFile(std::string fileName)283 bool VideoControlManager::IsPngFile(std::string fileName)
284 {
285     size_t len = SUPPORT_PICTURE_EXT.length();
286     if (fileName.length() <= len + 1) {
287         TELEPHONY_LOGE("file not support: %{public}s", fileName.c_str());
288         return false;
289     }
290     std::string ext = fileName.substr(fileName.length() - len, len);
291     std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower);
292     if (!((ext == SUPPORT_PICTURE_EXT))) {
293         TELEPHONY_LOGE("file not support: %{public}s", fileName.c_str());
294         return false;
295     }
296     return true;
297 }
298 
CancelCallUpgrade(int32_t callId)299 int32_t VideoControlManager::CancelCallUpgrade(int32_t callId)
300 {
301     int32_t ret = TELEPHONY_ERR_FAIL;
302     ret = CallPolicy::VideoCallPolicy(callId);
303     if (ret != TELEPHONY_SUCCESS) {
304         TELEPHONY_LOGE("check prerequisites failed !");
305         return ret;
306     }
307     sptr<CallBase> callPtr = CallObjectManager::GetOneCallObject(callId);
308     if (callPtr == nullptr) {
309         TELEPHONY_LOGE("the call object is nullptr, callId:%{public}d", callId);
310         return TELEPHONY_ERR_LOCAL_PTR_NULL;
311     }
312     if (callPtr->GetCallType() == CallType::TYPE_IMS) {
313         sptr<IMSCall> netCall = reinterpret_cast<IMSCall *>(callPtr.GetRefPtr());
314         ret = netCall->CancelCallUpgrade();
315         if (ret != TELEPHONY_SUCCESS) {
316             TELEPHONY_LOGE("CancelCallUpgrade failed!");
317             return ret;
318         }
319     }
320     return TELEPHONY_SUCCESS;
321 }
322 
RequestCameraCapabilities(int32_t callId)323 int32_t VideoControlManager::RequestCameraCapabilities(int32_t callId)
324 {
325     int32_t ret = TELEPHONY_ERR_FAIL;
326     ret = CallPolicy::VideoCallPolicy(callId);
327     if (ret != TELEPHONY_SUCCESS) {
328         TELEPHONY_LOGE("check prerequisites failed !");
329         return ret;
330     }
331     sptr<CallBase> callPtr = CallObjectManager::GetOneCallObject(callId);
332     if (callPtr == nullptr) {
333         TELEPHONY_LOGE("the call object is nullptr, callId:%{public}d", callId);
334         return TELEPHONY_ERR_LOCAL_PTR_NULL;
335     }
336     if (callPtr->GetCallType() == CallType::TYPE_IMS) {
337         sptr<IMSCall> netCall = reinterpret_cast<IMSCall *>(callPtr.GetRefPtr());
338         ret = netCall->RequestCameraCapabilities();
339         if (ret != TELEPHONY_SUCCESS) {
340             TELEPHONY_LOGE("RequestCameraCapabilities failed!");
341             return ret;
342         }
343     }
344     return TELEPHONY_SUCCESS;
345 }
346 
CheckWindow(VideoWindow & window)347 bool VideoControlManager::CheckWindow(VideoWindow &window)
348 {
349     if (window.width <= 0 || window.height <= 0) {
350         TELEPHONY_LOGE("width or height value error");
351         return false;
352     }
353     if (window.z != VIDEO_WINDOWS_Z_BOTTOM && window.z != VIDEO_WINDOWS_Z_TOP) {
354         TELEPHONY_LOGE("z value error %{public}d", window.z);
355         return false;
356     }
357     return true;
358 }
359 } // namespace Telephony
360 } // namespace OHOS
361