1 /*
2 * Copyright (c) 2023 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 "connect.h"
17 #include <thread>
18 #include "hilog/log_cpp.h"
19 #include "iostream"
20
21 const int RESULT_OK = 0;
22
23 using namespace OHOS;
24
25 static const OHOS::HiviewDFX::HiLogLabel g_CONNECT_LABEL = { LOG_CORE, 0xD001610, "Connect"};
26
27 namespace {
28 constexpr const char *BUNDLE_NAME = "com.example.cloudsync";
29 constexpr const char *ABILITY_NAME = "ServiceExtAbility";
30 static OHOS::sptr<Connect> g_connect = nullptr;
31 static std::mutex mutex_;
32 }
33
OnAbilityConnectDone(const OHOS::AppExecFwk::ElementName & element,const OHOS::sptr<OHOS::IRemoteObject> & remoteObject,int resultCode)34 void Connect::OnAbilityConnectDone(const OHOS::AppExecFwk::ElementName &element,
35 const OHOS::sptr<OHOS::IRemoteObject> &remoteObject,
36 int resultCode)
37 {
38 if (resultCode != RESULT_OK) {
39 OHOS::HiviewDFX::HiLog::Error(g_CONNECT_LABEL, "ability connect failed, error code:%{public}d", resultCode);
40 }
41
42 OHOS::HiviewDFX::HiLog::Debug(g_CONNECT_LABEL,
43 "ability connect success, ability name:%{public}s",
44 element.GetAbilityName().c_str());
45 remoteObject_ = remoteObject;
46 std::unique_lock<std::mutex> lock(mtx_);
47 flag_ = true;
48 cv_.notify_one();
49 lock.unlock();
50 }
51
OnAbilityDisconnectDone(const OHOS::AppExecFwk::ElementName & element,int resultCode)52 void Connect::OnAbilityDisconnectDone(const OHOS::AppExecFwk::ElementName &element, int resultCode)
53 {
54 if (resultCode != RESULT_OK) {
55 OHOS::HiviewDFX::HiLog::Error(g_CONNECT_LABEL, "ability disconnect failed, error code:%{public}d", resultCode);
56 }
57 remoteObject_ = nullptr;
58 std::unique_lock<std::mutex> lock(mtx_);
59 flag_ = true;
60 cv_.notify_one();
61 lock.unlock();
62 }
63
IsConnect()64 bool Connect::IsConnect()
65 {
66 return remoteObject_ != nullptr;
67 }
68
WaitConnect()69 void Connect::WaitConnect()
70 {
71 std::unique_lock<std::mutex> lock(g_connect->mtx_);
72 cv_.wait_for(lock, std::chrono::seconds(CONNECT_TIMEOUT), [this] {
73 return flag_;
74 });
75 cv_.notify_one();
76 }
77
78 namespace ConnectInner {
DoConnect(int userId)79 void DoConnect(int userId)
80 {
81 OHOS::HiviewDFX::HiLog::Info(g_CONNECT_LABEL, "do connect");
82 AAFwk::Want want;
83 want.SetAction("");
84 want.SetElementName(BUNDLE_NAME, ABILITY_NAME);
85 auto ret = AAFwk::ExtensionManagerClient::GetInstance().ConnectServiceExtensionAbility(
86 want, g_connect->AsObject(), userId);
87 if (ret != ERR_OK) {
88 OHOS::HiviewDFX::HiLog::Error(g_CONNECT_LABEL, "connect ability fail, error code:%{public}d", ret);
89 return;
90 }
91 g_connect->WaitConnect();
92 }
93
ConnectServiceInner(int userId)94 OHOS::sptr<OHOS::IRemoteObject> ConnectServiceInner(int userId)
95 {
96 OHOS::HiviewDFX::HiLog::Info(g_CONNECT_LABEL, "Connect Service Inner access");
97 std::lock_guard<decltype(mutex_)> lockGuard(mutex_);
98 if (g_connect == nullptr) {
99 sptr<Connect> ipcConnect = new(std::nothrow) Connect();
100 if (ipcConnect == nullptr) {
101 OHOS::HiviewDFX::HiLog::Error(g_CONNECT_LABEL, "ipc connect is null");
102 return nullptr;
103 }
104 g_connect = ipcConnect;
105 }
106 if (!g_connect->IsConnect()) {
107 DoConnect(userId);
108 }
109 return g_connect->remoteObject_;
110 }
111 }