1/*
2 * Copyright (C) 2022 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_connect_ability.h"
17
18#include "ability_manager_client.h"
19#include "call_ability_connect_callback.h"
20#include "call_number_utils.h"
21#include "int_wrapper.h"
22#include "string_wrapper.h"
23#include "telephony_log_wrapper.h"
24#include "want.h"
25
26namespace OHOS {
27namespace Telephony {
28std::condition_variable CallConnectAbility::cv_;
29
30CallConnectAbility::~CallConnectAbility() {}
31
32CallConnectAbility::CallConnectAbility() {}
33
34void CallConnectAbility::ConnectAbility()
35{
36    SetConnectingFlag(true);
37    if (isDisconnecting_) {
38        TELEPHONY_LOGE("callui is disconnecting");
39        return;
40    }
41    if (isConnected_) {
42        TELEPHONY_LOGE("callui has already connected");
43        SetConnectingFlag(false);
44        return;
45    }
46    TELEPHONY_LOGW("Connect callui ability");
47    AAFwk::Want want;
48    AppExecFwk::ElementName element("", "com.ohos.callui", "com.ohos.callui.ServiceAbility");
49    want.SetElement(element);
50    if (connectCallback_ == nullptr) {
51        connectCallback_ = new CallAbilityConnectCallback();
52    }
53    int32_t userId = -1;
54    std::string identity = IPCSkeleton::ResetCallingIdentity();
55    AAFwk::AbilityManagerClient::GetInstance()->ConnectAbility(want, connectCallback_, userId);
56    IPCSkeleton::SetCallingIdentity(identity);
57}
58
59void CallConnectAbility::DisconnectAbility()
60{
61    SetDisconnectingFlag(true);
62    if (isConnecting_) {
63        TELEPHONY_LOGE("callui is connecting");
64        return;
65    }
66    if (!WaitForConnectResult()) {
67        SetDisconnectingFlag(false);
68        return;
69    }
70    if (connectCallback_ != nullptr) {
71        TELEPHONY_LOGW("Disconnect callui ability");
72        std::string identity = IPCSkeleton::ResetCallingIdentity();
73        AAFwk::AbilityManagerClient::GetInstance()->DisconnectAbility(connectCallback_);
74        IPCSkeleton::SetCallingIdentity(identity);
75        connectCallback_ = nullptr;
76    }
77}
78
79void CallConnectAbility::SetConnectFlag(bool isConnected)
80{
81    isConnected_ = isConnected;
82}
83
84bool CallConnectAbility::GetConnectFlag()
85{
86    return isConnected_;
87}
88
89void CallConnectAbility::SetDisconnectingFlag(bool isDisconnecting)
90{
91    isDisconnecting_ = isDisconnecting;
92    if (!isDisconnecting_ && isConnecting_) {
93        ConnectAbility();
94        TELEPHONY_LOGE("reconnect ability");
95    }
96}
97
98void CallConnectAbility::SetConnectingFlag(bool isConnecting)
99{
100    isConnecting_ = isConnecting;
101    if (!isConnecting_ && isDisconnecting_) {
102        DisconnectAbility();
103        TELEPHONY_LOGE("redisconnect ability");
104    }
105}
106
107void CallConnectAbility::NotifyAll()
108{
109    cv_.notify_all();
110}
111
112bool CallConnectAbility::WaitForConnectResult()
113{
114    if (!isConnected_) {
115        std::unique_lock<std::mutex> lock(mutex_);
116        while (!isConnected_) {
117            if (cv_.wait_for(lock, std::chrono::seconds(WAIT_TIME_ONE_SECOND)) == std::cv_status::timeout) {
118                TELEPHONY_LOGE("callui is not connected, no need to disconnect ability");
119                return false;
120            }
121        }
122    }
123    return true;
124}
125} // namespace Telephony
126} // namespace OHOS
127