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