• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }