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 "call_dialog.h"
17
18#include "extension_manager_client.h"
19#include "ipc_skeleton.h"
20#include "nlohmann/json.hpp"
21#include "telephony_log_wrapper.h"
22#include <securec.h>
23#include "display_manager.h"
24#include "fold_status_manager.h"
25#include "call_object_manager.h"
26#include "call_superprivacy_control_manager.h"
27
28namespace OHOS {
29namespace Telephony {
30constexpr int32_t DEFAULT_USER_ID = -1;
31const int32_t SOURCE_SCREENLOCKED = 2;
32
33bool CallDialog::DialogConnectExtension(const std::string &dialogReason)
34{
35    return DialogConnectExtension(dialogReason, -1);
36}
37
38bool CallDialog::DialogConnectExtension(const std::string &dialogReason, int32_t slotId)
39{
40    std::string commandStr = BuildStartCommand(dialogReason, slotId);
41    AAFwk::Want want;
42    std::string bundleName = "com.ohos.sceneboard";
43    std::string abilityName = "com.ohos.sceneboard.systemdialog";
44    want.SetElementName(bundleName, abilityName);
45    bool connectResult = false;
46    if (dialogReason.find("SATELLITE") != std::string::npos) {
47        connectResult = CallSettingDialogConnectExtensionAbility(want, commandStr);
48    } else {
49        connectResult = DialogConnectExtensionAbility(want, commandStr);
50    }
51    if (!connectResult) {
52        TELEPHONY_LOGE("DialogConnectExtensionAbility failed!");
53        return false;
54    }
55    return true;
56}
57
58bool CallDialog::DialogConnectExtensionAbility(const AAFwk::Want &want, const std::string commandStr)
59{
60    TELEPHONY_LOGI("DialogConnectExtensionAbility start");
61    sptr<CallAbilityConnection> connection =
62        sptr<CallAbilityConnection> (new (std::nothrow) CallAbilityConnection(commandStr));
63    if (connection == nullptr) {
64        TELEPHONY_LOGE("connection is nullptr");
65        return false;
66    }
67    std::string identity = IPCSkeleton::ResetCallingIdentity();
68    auto connectResult = AAFwk::ExtensionManagerClient::GetInstance().ConnectServiceExtensionAbility(want,
69        connection, nullptr, DEFAULT_USER_ID);
70    IPCSkeleton::SetCallingIdentity(identity);
71    if (connectResult != 0) {
72        TELEPHONY_LOGE("ConnectServiceExtensionAbility Failed!");
73        return false;
74    }
75    return true;
76}
77
78bool CallDialog::CallSettingDialogConnectExtensionAbility(const AAFwk::Want &want,
79    const std::string commandStr)
80{
81    TELEPHONY_LOGI("CallSettingDialogConnectExtensionAbility start");
82    sptr<CallSettingAbilityConnection> callSettingConnection = sptr<CallSettingAbilityConnection> (new (std::nothrow)
83        CallSettingAbilityConnection(commandStr));
84    if (callSettingConnection == nullptr) {
85        TELEPHONY_LOGE("connection is nullptr");
86        return false;
87    }
88    std::string identity = IPCSkeleton::ResetCallingIdentity();
89    auto connectResult = AAFwk::ExtensionManagerClient::GetInstance().ConnectServiceExtensionAbility(want,
90        callSettingConnection, nullptr, DEFAULT_USER_ID);
91    IPCSkeleton::SetCallingIdentity(identity);
92    if (connectResult != 0) {
93        TELEPHONY_LOGE("ConnectServiceExtensionAbility Failed!");
94        return false;
95    }
96    return true;
97}
98
99std::string CallDialog::BuildStartCommand(const std::string &dialogReason, int32_t slotId)
100{
101    nlohmann::json root;
102    std::string uiExtensionType = "sysDialog/common";
103    root["ability.want.params.uiExtensionType"] = uiExtensionType;
104    root["sysDialogZOrder"] = SOURCE_SCREENLOCKED;
105    root["dialogReason"] = dialogReason;
106    root["slotId"] = slotId;
107    std::string startCommand = root.dump();
108    TELEPHONY_LOGI("startCommand is: %{public}s", startCommand.c_str());
109    return startCommand;
110}
111
112bool CallDialog::DialogConnectPrivpacyModeExtension(const std::string &dialogReason, std::u16string &number,
113    int32_t &accountId, int32_t &videoState, int32_t &dialType, int32_t &dialScene, int32_t &callType, bool isVideo)
114{
115    std::string commandStr = BuildStartPrivpacyModeCommand(dialogReason, number,
116    accountId, videoState, dialType, dialScene, callType, isVideo);
117    AAFwk::Want want;
118    std::string bundleName = "com.ohos.sceneboard";
119    std::string abilityName = "com.ohos.sceneboard.systemdialog";
120    want.SetElementName(bundleName, abilityName);
121    bool connectResult = CallSettingDialogConnectExtensionAbility(want, commandStr);
122    if (!connectResult) {
123        TELEPHONY_LOGE("CallSettingDialogConnectExtensionAbility failed!");
124        return false;
125    }
126    return true;
127}
128
129bool CallDialog::DialogConnectAnswerPrivpacyModeExtension(const std::string &dialogReason,
130    int32_t &callId, int32_t &videoState, bool isVideo)
131{
132    std::string commandStr = BuildStartAnswerPrivpacyModeCommand(dialogReason, callId, videoState, isVideo);
133    AAFwk::Want want;
134    std::string bundleName = "com.ohos.sceneboard";
135    std::string abilityName = "com.ohos.sceneboard.systemdialog";
136    want.SetElementName(bundleName, abilityName);
137    bool connectResult = CallSettingDialogConnectExtensionAbility(want, commandStr);
138    if (!connectResult) {
139        TELEPHONY_LOGE("CallSettingDialogConnectExtensionAbility failed!");
140        return false;
141    }
142    return true;
143}
144
145void CallDialog::DialogCallingPrivacyModeExtension(Rosen::FoldStatus foldStatus)
146{
147    if (foldStatus != Rosen::FoldStatus::FOLDED
148        || !DelayedSingleton<CallSuperPrivacyControlManager>::GetInstance()->GetCurrentIsSuperPrivacyMode()) {
149        return;
150    }
151    sptr<CallBase> foregroundCall = CallObjectManager::GetForegroundCall(false);
152    if (foregroundCall == nullptr || foregroundCall->GetTelCallState() == TelCallState::CALL_STATUS_INCOMING) {
153        return;
154    }
155    int32_t videoState = static_cast<int32_t>(foregroundCall->GetVideoStateType());
156    std::string commandStr = BuildCallingPrivacyModeCommand(videoState);
157    AAFwk::Want want;
158    std::string bundleName = "com.ohos.sceneboard";
159    std::string abilityName = "com.ohos.sceneboard.systemdialog";
160    want.SetElementName(bundleName, abilityName);
161    bool connectResult = CallSettingDialogConnectExtensionAbility(want, commandStr);
162    if (!connectResult) {
163        TELEPHONY_LOGE("DialogCallingPrivacyModeExtension failed!");
164    }
165}
166
167std::string CallDialog::BuildStartPrivpacyModeCommand(const std::string &dialogReason, std::u16string &number,
168    int32_t &accountId, int32_t &videoState, int32_t &dialType, int32_t &dialScene, int32_t &callType, bool isVideo)
169{
170    nlohmann::json root;
171    std::string uiExtensionType = "sysDialog/common";
172    root["ability.want.params.uiExtensionType"] = uiExtensionType;
173    root["sysDialogZOrder"] = SOURCE_SCREENLOCKED;
174    root["dialogReason"] = dialogReason;
175    root["number"] = Str16ToStr8(number);
176    root["accountId"] = accountId;
177    root["videoState"] = videoState;
178    root["dialType"] = dialType;
179    root["dialScene"] = dialScene;
180    root["callType"] = callType;
181    root["isAnswer"] = false;
182    root["isVideo"] = isVideo;
183    root["isFold"] = FoldStatusManager::IsSmallFoldDevice()
184        && Rosen::DisplayManager::GetInstance().GetFoldStatus() == Rosen::FoldStatus::FOLDED;
185    std::string startCommand = root.dump();
186    TELEPHONY_LOGI("startCommand is: %{public}s", startCommand.c_str());
187    return startCommand;
188}
189
190std::string CallDialog::BuildStartAnswerPrivpacyModeCommand(const std::string &dialogReason,
191    int32_t &callId, int32_t &videoState, bool isVideo)
192{
193    nlohmann::json root;
194    std::string uiExtensionType = "sysDialog/common";
195    root["ability.want.params.uiExtensionType"] = uiExtensionType;
196    root["sysDialogZOrder"] = SOURCE_SCREENLOCKED;
197    root["dialogReason"] = dialogReason;
198    root["callId"] = callId;
199    root["videoState"] = videoState;
200    root["isAnswer"] = true;
201    root["isVideo"] = isVideo;
202    root["isFold"] = FoldStatusManager::IsSmallFoldDevice()
203        && Rosen::DisplayManager::GetInstance().GetFoldStatus() == Rosen::FoldStatus::FOLDED;
204    std::string startCommand = root.dump();
205    TELEPHONY_LOGI("startCommand is: %{public}s", startCommand.c_str());
206    return startCommand;
207}
208
209std::string CallDialog::BuildCallingPrivacyModeCommand(int32_t &videoState)
210{
211    nlohmann::json root;
212    std::string uiExtensionType = "sysDialog/common";
213    std::string dialogReason = "SUPER_PRIVACY_MODE";
214    root["ability.want.params.uiExtensionType"] = uiExtensionType;
215    root["sysDialogZOrder"] = SOURCE_SCREENLOCKED;
216    root["dialogReason"] = dialogReason;
217    root["videoState"] = videoState;
218    root["isInCall"] = true;
219    root["isAnswer"] = false;
220    root["isFold"] = true;
221    std::string startCommand = root.dump();
222    TELEPHONY_LOGI("startCommand is: %{public}s", startCommand.c_str());
223    return startCommand;
224}
225} // namespace Telephony
226} // namespace OHOS