1 /*
2 * Copyright (c) 2025 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 "svc_distributed_connection.h"
17
18 #include <chrono>
19 #include <iomanip>
20 #include <thread>
21
22 #include "ability_manager_client.h"
23 #include "dtbschedmgr_log.h"
24 #include "hisysevent.h"
25 #include "distributed_extension_proxy.h"
26
27 namespace OHOS {
28 namespace DistributedSchedule {
29 const std::string TAG = "SvcDistributedConnection";
30 constexpr int WAIT_TIME = 3;
31 constexpr int32_t INDEX = 3;
32 constexpr int32_t MS_1000 = 1000;
33 constexpr int32_t TIME_OUT_CLOSE = 10 * 1000 * 1000; // 10s;
34 const std::string FILE_BACKUP_EVENTS = "FILE_BACKUP_EVENTS";
35 using namespace std;
36
OnAbilityConnectDone(const AppExecFwk::ElementName & element,const sptr<IRemoteObject> & remoteObject,int resultCode)37 void SvcDistributedConnection::OnAbilityConnectDone(const AppExecFwk::ElementName &element,
38 const sptr<IRemoteObject> &remoteObject, int resultCode)
39 {
40 HILOGI("called begin");
41 if (remoteObject == nullptr) {
42 HILOGE("Failed to ability connect done, remote is nullptr");
43 return;
44 }
45 auto func = [this]() {
46 HILOGI("close begin");
47 usleep(TIME_OUT_CLOSE);
48 this->DisconnectDistributedExtAbility();
49 HILOGI("close end");
50 };
51 std::thread task(func);
52 task.detach();
53 distributedProxy_ = iface_cast<DExtensionProxy>(remoteObject);
54 if (distributedProxy_ == nullptr) {
55 HILOGE("Failed to ability connect done, distributedProxy_ is nullptr");
56 return;
57 }
58 isConnected_.store(true);
59 string bundleName = element.GetBundleName();
60 HILOGI("bundleName:%{public}s, OnAbilityConnectDone, bundleNameIndexInfo:%{public}s", bundleName.c_str(),
61 bundleNameIndexInfo_.c_str());
62
63 auto now = std::chrono::system_clock::now();
64 auto time = std::chrono::system_clock::to_time_t(now);
65 auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch());
66 std::stringstream strTime;
67 strTime << (std::put_time(std::localtime(&time), "%Y-%m-%d %H:%M:%S:")) << (std::setfill('0'))
68 << (std::setw(INDEX)) << (ms.count() % MS_1000);
69 HiSysEventWrite(
70 OHOS::HiviewDFX::HiSysEvent::Domain::FILEMANAGEMENT,
71 FILE_BACKUP_EVENTS,
72 OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
73 "PROC_NAME", "ohos.appfileservice",
74 "BUNDLENAME", bundleName,
75 "PID", getpid(),
76 "TIME", strTime.str()
77 );
78
79 if (bundleNameIndexInfo_.find(bundleName) == string::npos) {
80 HILOGE("Current bundle name is wrong, bundleNameIndexInfo:%{public}s, bundleName:%{public}s",
81 bundleNameIndexInfo_.c_str(), bundleName.c_str());
82 return;
83 }
84 bundleName = bundleNameIndexInfo_;
85 callConnected_(move(bundleName));
86 HILOGI("called end");
87 }
88
OnAbilityDisconnectDone(const AppExecFwk::ElementName & element,int resultCode)89 void SvcDistributedConnection::OnAbilityDisconnectDone(const AppExecFwk::ElementName &element, int resultCode)
90 {
91 HILOGI("called begin");
92 isConnected_.store(false);
93 string bundleName = element.GetBundleName();
94 HILOGI("bundleName:%{public}s, OnAbilityDisconnectDone, bundleNameIndexInfo:%{public}s", bundleName.c_str(),
95 bundleNameIndexInfo_.c_str());
96 if (bundleNameIndexInfo_.find(bundleName) == string::npos) {
97 HILOGE("Current bundle name is wrong, bundleNameIndexInfo:%{public}s, bundleName:%{public}s",
98 bundleNameIndexInfo_.c_str(), bundleName.c_str());
99 return;
100 }
101 bundleName = bundleNameIndexInfo_;
102 HILOGI("called end, name: %{public}s", bundleNameIndexInfo_.c_str());
103 }
104
ConnectDExtAbility(AAFwk::Want & want,int32_t userId,bool isCleanCalled)105 ErrCode SvcDistributedConnection::ConnectDExtAbility(AAFwk::Want &want, int32_t userId, bool isCleanCalled)
106 {
107 HILOGI("SvcDistributedConnection::ConnectDExtAbility Called begin");
108 isCleanCalled_.store(isCleanCalled);
109 isConnectCalled_.store(true);
110 std::unique_lock<std::mutex> lock(mutex_);
111 ErrCode ret = AAFwk::AbilityManagerClient::GetInstance()->ConnectAbility(want, this, userId);
112 HILOGI("Called end, ret=%{public}d, userId=%{public}d.", ret, userId);
113 return ret;
114 }
115
DisconnectDistributedExtAbility()116 ErrCode SvcDistributedConnection::DisconnectDistributedExtAbility()
117 {
118 HILOGI("called begin");
119 isConnectCalled_.store(false);
120 std::unique_lock<std::mutex> lock(mutex_);
121 int32_t res = distributedProxy_->TriggerOnDestroy();
122 if (res != ERR_OK) {
123 HILOGE("destroy connect failed");
124 }
125 ErrCode ret = AppExecFwk::AbilityManagerClient::GetInstance()->DisconnectAbility(this);
126 auto callback = [extConn {wptr(this)}] {
127 auto extPtr = extConn.promote();
128 if (!extPtr) {
129 HILOGE("Dis connect failed");
130 return false;
131 }
132 return extPtr->isConnected_.load() == false;
133 };
134 if (condition_.wait_for(lock, std::chrono::seconds(WAIT_TIME), callback)) {
135 HILOGI("Wait until the connection ends");
136 }
137 HILOGI("called end, ret=%{public}d", ret);
138 return ret;
139 }
140
IsExtAbilityConnected()141 bool SvcDistributedConnection::IsExtAbilityConnected()
142 {
143 return isConnected_.load();
144 }
145
GetDistributedExtProxy()146 sptr<IDExtension> SvcDistributedConnection::GetDistributedExtProxy()
147 {
148 return distributedProxy_;
149 }
150
SetCallback(function<void (const std::string &&)> callConnected)151 void SvcDistributedConnection::SetCallback(function<void(const std::string &&)> callConnected)
152 {
153 callConnected_ = callConnected;
154 }
155 }
156 }
157