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/sa_backup_connection.h"
17 #include "b_error/b_error.h"
18 #include "b_error/b_excep_utils.h"
19 #include "filemgmt_libhilog.h"
20 #include "system_ability_definition.h"
21
22 namespace OHOS::FileManagement::Backup {
23 using namespace std;
24
ConnectBackupSAExt(std::string bundleName,std::string extension,std::string extInfo)25 ErrCode SABackupConnection::ConnectBackupSAExt(std::string bundleName, std::string extension, std::string extInfo)
26 {
27 bundleName_ = bundleName;
28 extension_ = extension;
29 extInfo_ = extInfo;
30 saId_ = std::atoi(bundleName.c_str());
31 return LoadBackupSAExt();
32 }
33
DisconnectBackupSAExt()34 ErrCode SABackupConnection::DisconnectBackupSAExt()
35 {
36 HILOGI("called begin");
37 if (!isLoaded_.load() || !isConnected_.load() || !proxy_) {
38 HILOGD("No need to unload, connect first");
39 return BError(BError::Codes::OK);
40 }
41 isConnected_.store(false);
42 isLoaded_.store(false);
43 proxy_ = nullptr;
44 string().swap(bundleName_);
45 saId_ = BConstants::BACKUP_DEFAULT_SA_ID;
46 reloadNum_.store(0);
47 sptr<ISystemAbilityManager> samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
48 if (!samgrProxy) {
49 HILOGE("SamgrProxy is nullptr");
50 return BError(BError::Codes::SA_EXT_ERR_SAMGR);
51 }
52 int32_t result = samgrProxy->UnloadSystemAbility(saId_);
53 if (result != ERR_OK) {
54 HILOGE("UnloadSA, UnloadSystemAbility %{public}s result: %{public}d", bundleName_.c_str(), result);
55 }
56 return BError(BError::Codes::OK);
57 }
58
IsSAExtConnected()59 bool SABackupConnection::IsSAExtConnected()
60 {
61 HILOGI("called begin");
62 return isConnected_.load();
63 }
64
GetBackupSAExtProxy()65 sptr<ILocalAbilityManager> SABackupConnection::GetBackupSAExtProxy()
66 {
67 return proxy_;
68 }
69
LoadBackupSAExt()70 ErrCode SABackupConnection::LoadBackupSAExt()
71 {
72 if (proxy_ && isConnected_.load()) {
73 HILOGI("SA %{public}d is running.", saId_);
74 callConnected_(move(bundleName_));
75 return BError(BError::Codes::OK);
76 }
77 if (reloadNum_.load() >= BConstants::BACKUP_SA_RELOAD_MAX) {
78 HILOGI("SA %{public}d reload done and return", saId_);
79 callDied_(move(bundleName_));
80 return BError(BError::Codes::SA_EXT_RELOAD_FAIL);
81 }
82 vector<ISystemAbilityManager::SaExtensionInfo> saExtentionInfos;
83 sptr<ISystemAbilityManager> samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
84 if (!samgrProxy) {
85 HILOGE("SamgrProxy is nullptr");
86 return BError(BError::Codes::SA_EXT_ERR_SAMGR);
87 }
88 int32_t ret = samgrProxy->GetRunningSaExtensionInfoList(extension_, saExtentionInfos);
89 if (ret != ERR_OK) {
90 HILOGE("GetExtensionSaIds err, ret %{public}d.", ret);
91 return BError(BError::Codes::SA_EXT_ERR_SAMGR);
92 }
93 for (ISystemAbilityManager::SaExtensionInfo saExtentionInfo : saExtentionInfos) {
94 if (saExtentionInfo.saId == saId_) {
95 isConnected_.store(true);
96 isLoaded_.store(false);
97 HILOGI("Get running sa proxy success.");
98 proxy_ = iface_cast<ILocalAbilityManager>(saExtentionInfo.processObj);
99 callConnected_(move(bundleName_));
100 return BError(BError::Codes::OK);
101 }
102 }
103 return LoadBackupSAExtInner();
104 }
105
LoadBackupSAExtInner()106 ErrCode SABackupConnection::LoadBackupSAExtInner()
107 {
108 sptr<ISystemAbilityManager> samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
109 if (!samgrProxy) {
110 HILOGE("SamgrProxy is nullptr");
111 return BError(BError::Codes::SA_EXT_ERR_SAMGR);
112 }
113 sptr<SALoadCallback> loadCallback(new SALoadCallback());
114 if (loadCallback == nullptr) {
115 HILOGE("loadCallback is nullptr");
116 return BError(BError::Codes::SA_INVAL_ARG);
117 }
118 int32_t ret = samgrProxy->LoadSystemAbility(saId_, loadCallback);
119 if (ret != ERR_OK) {
120 HILOGE("Failed to Load systemAbility, systemAbility:%{private}d. ret code:%{public}d", saId_, ret);
121 return BError(BError::Codes::SA_EXT_ERR_SAMGR);
122 }
123 isLoaded_.store(true);
124 reloadNum_.store(reloadNum_.load() + 1);
125 unique_lock<mutex> lock(mutex_);
126 auto waitStatus =
127 loadCallback->proxyConVar_.wait_for(lock, std::chrono::milliseconds(BConstants::BACKUP_LOADSA_TIMEOUT_MS),
128 [loadCallback]() { return loadCallback->isLoadSuccess_.load(); });
129 if (!waitStatus) {
130 HILOGE("Load sa %{public}d timeout", saId_);
131 lock.unlock();
132 isConnected_.store(false);
133 return LoadBackupSAExt();
134 }
135 lock.unlock();
136 isConnected_.store(true);
137 return LoadBackupSAExt();
138 }
139
InputParaSet(MessageParcel & data)140 bool SABackupConnection::InputParaSet(MessageParcel &data)
141 {
142 if (extension_ == BConstants::EXTENSION_BACKUP) {
143 if (!data.WriteString(extInfo_)) {
144 HILOGE("InputParaSet WriteString failed sa: %{public}d, extInfo: %{public}s, extension: %{public}s",
145 saId_, extInfo_.c_str(), extension_.c_str());
146 return false;
147 }
148 return true;
149 } else if (extension_ == BConstants::EXTENSION_RESTORE) {
150 if (!data.WriteFileDescriptor(fd_) || !data.WriteString(extInfo_)) {
151 HILOGE("InputParaSet WriteString failed sa: %{public}d, extension: %{public}s",
152 saId_, extension_.c_str());
153 return false;
154 }
155 return true;
156 }
157
158 HILOGD("SABackupExtentionPara InFunc sa: %{public}d, extension: %{public}s", saId_, extension_.c_str());
159 return false;
160 }
161
OutputParaGet(MessageParcel & reply)162 bool SABackupConnection::OutputParaGet(MessageParcel &reply)
163 {
164 parcel_.ClearFileDescriptor();
165 if (!parcel_.Append(reply)) {
166 HILOGE("OutputParaGet append failed sa is %{public}d, extension: %{public}s", saId_, extension_.c_str());
167 return false;
168 }
169 HILOGD("SABackupExtentionPara OutFunc sa is %{public}d, extension: %{public}s", saId_, extension_.c_str());
170 return true;
171 }
172
CallBackupSA()173 ErrCode SABackupConnection::CallBackupSA()
174 {
175 auto task = [this]() {
176 HILOGI("called begin");
177 if (proxy_) {
178 HILOGI("SA backup called begin");
179 int32_t ret = proxy_->SystemAbilityExtProc(BConstants::EXTENSION_BACKUP, saId_, this);
180 HILOGI("SA backup done %{public}d", ret);
181 int fd = parcel_.ReadFileDescriptor();
182 std::string result = parcel_.ReadString();
183 callBackup_(move(bundleName_), move(fd), move(result), move(ret));
184 }
185 };
186
187 threadPool_.AddTask([task]() {
188 try {
189 task();
190 } catch (...) {
191 HILOGE("Failed to add task to thread pool");
192 }
193 });
194 return BError(BError::Codes::OK);
195 }
196
CallRestoreSA(UniqueFd fd)197 ErrCode SABackupConnection::CallRestoreSA(UniqueFd fd)
198 {
199 fd_ = move(fd);
200 auto task = [this]() {
201 HILOGI("called begin");
202 if (proxy_) {
203 HILOGI("SA restore called begin");
204 int32_t ret = proxy_->SystemAbilityExtProc(BConstants::EXTENSION_RESTORE, saId_, this);
205 HILOGI("SA restore done %{public}d", ret);
206 std::string result = parcel_.ReadString();
207 callRestore_(move(bundleName_), move(result), move(ret));
208 }
209 };
210
211 threadPool_.AddTask([task]() {
212 try {
213 task();
214 } catch (...) {
215 HILOGE("Failed to add task to thread pool");
216 }
217 });
218 return BError(BError::Codes::OK);
219 }
220
OnLoadSystemAbilitySuccess(int32_t systemAbilityId,const OHOS::sptr<IRemoteObject> & remoteObject)221 void SABackupConnection::SALoadCallback::OnLoadSystemAbilitySuccess(int32_t systemAbilityId,
222 const OHOS::sptr<IRemoteObject> &remoteObject)
223 {
224 HILOGI("Load backup sa success, systemAbilityId: %{private}d, remoteObject result:%{private}s", systemAbilityId,
225 (remoteObject != nullptr) ? "true" : "false");
226 if (remoteObject == nullptr) {
227 isLoadSuccess_.store(false);
228 proxyConVar_.notify_one();
229 return;
230 }
231 isLoadSuccess_.store(true);
232 proxyConVar_.notify_one();
233 }
234
OnLoadSystemAbilityFail(int32_t systemAbilityId)235 void SABackupConnection::SALoadCallback::OnLoadSystemAbilityFail(int32_t systemAbilityId)
236 {
237 HILOGE("Load backup sa failed, systemAbilityId:%{private}d", systemAbilityId);
238 isLoadSuccess_.store(false);
239 proxyConVar_.notify_one();
240 }
241 } // namespace OHOS::FileManagement::Backup
242