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 <string>
17
18 #include "b_error/b_error.h"
19 #include "b_radar/b_radar.h"
20 #include "b_sa/b_sa_utils.h"
21 #include "b_jsonutil/b_jsonutil.h"
22 #include "filemgmt_libhilog.h"
23 #include "message_parcel.h"
24
25 #include "module_app_gallery/app_gallery_dispose_proxy.h"
26 #include "module_app_gallery/app_gallery_service_connection.h"
27 #include "want.h"
28
29 namespace OHOS::FileManagement::Backup {
30 using namespace std;
31
32 namespace {
33 const auto APP_FOUNDATION_SERVICE = u"appgalleryservice.openapi.privacymanager.AppFoundationService";
34 }
35 mutex AppGalleryDisposeProxy::instanceLock_;
36 mutex AppGalleryDisposeProxy::appGalleryConnectionLock_;
37
38 string AppGalleryDisposeProxy::abilityName = "AppFoundationService";
39 std::map<int32_t, sptr<AppGalleryConnection>> AppGalleryDisposeProxy::appGalleryConnectionMap_;
40 sptr<AppGalleryDisposeProxy> AppGalleryDisposeProxy::appGalleryDisposeProxyInstance_;
41
AppGalleryDisposeProxy()42 AppGalleryDisposeProxy::AppGalleryDisposeProxy()
43 {
44 HILOGI("AppGalleryDisposeProxy construct");
45 }
46
~AppGalleryDisposeProxy()47 AppGalleryDisposeProxy::~AppGalleryDisposeProxy()
48 {
49 appGalleryDisposeProxyInstance_ = nullptr;
50 }
51
GetInstance()52 sptr<AppGalleryDisposeProxy> AppGalleryDisposeProxy::GetInstance()
53 {
54 if (appGalleryDisposeProxyInstance_ == nullptr) {
55 lock_guard<mutex> autoLock(instanceLock_);
56 if (appGalleryDisposeProxyInstance_ == nullptr) {
57 appGalleryDisposeProxyInstance_ = new AppGalleryDisposeProxy;
58 }
59 }
60
61 return appGalleryDisposeProxyInstance_;
62 }
63
StartBackup(const std::string & bundleName,const int32_t userId)64 DisposeErr AppGalleryDisposeProxy::StartBackup(const std::string &bundleName, const int32_t userId)
65 {
66 HILOGI("StartBackup, app %{public}s, userId %{public}d", bundleName.c_str(), userId);
67 DisposeErr res = DoDispose(bundleName, DisposeOperation::START_BACKUP, userId);
68 if (res != DisposeErr::REQUEST_FAIL) {
69 AppRadar::Info info(bundleName, "", "");
70 AppRadar::GetInstance().RecordBackupFuncRes(info, "StartBackup", userId,
71 BizStageBackup::BIZ_STAGE_START_DISPOSE, static_cast<int32_t>(res));
72 }
73 return res;
74 }
75
EndBackup(const std::string & bundleName,const int32_t userId)76 DisposeErr AppGalleryDisposeProxy::EndBackup(const std::string &bundleName, const int32_t userId)
77 {
78 HILOGI("EndBackup, app %{public}s, userId %{public}d", bundleName.c_str(), userId);
79 DisposeErr res = DoDispose(bundleName, DisposeOperation::END_BACKUP, userId);
80 if (res != DisposeErr::REQUEST_FAIL) {
81 AppRadar::Info info(bundleName, "", "");
82 AppRadar::GetInstance().RecordBackupFuncRes(info, "EndBackup", userId,
83 BizStageBackup::BIZ_STAGE_END_DISPOSE, static_cast<int32_t>(res));
84 }
85 return res;
86 }
87
StartRestore(const std::string & bundleName,const int32_t userId)88 DisposeErr AppGalleryDisposeProxy::StartRestore(const std::string &bundleName, const int32_t userId)
89 {
90 if (SAUtils::IsSABundleName(bundleName)) {
91 HILOGI("SA does not need to StartRestore");
92 return DisposeErr::OK;
93 }
94 HILOGI("StartRestore, app %{public}s, userId %{public}d", bundleName.c_str(), userId);
95 DisposeErr res = DoDispose(bundleName, DisposeOperation::START_RESTORE, userId);
96 if (res != DisposeErr::REQUEST_FAIL) {
97 AppRadar::Info info(bundleName, "", "");
98 AppRadar::GetInstance().RecordRestoreFuncRes(info, "StartRestore", userId,
99 BizStageRestore::BIZ_STAGE_START_DISPOSE, static_cast<int32_t>(res));
100 }
101 return res;
102 }
103
EndRestore(const std::string & bundleName,const int32_t userId)104 DisposeErr AppGalleryDisposeProxy::EndRestore(const std::string &bundleName, const int32_t userId)
105 {
106 if (SAUtils::IsSABundleName(bundleName)) {
107 HILOGI("SA does not need to EndRestore");
108 return DisposeErr::OK;
109 }
110 HILOGI("EndRestore, app %{public}s, userId %{public}d", bundleName.c_str(), userId);
111 DisposeErr res = DoDispose(bundleName, DisposeOperation::END_RESTORE, userId);
112 if (res != DisposeErr::REQUEST_FAIL) {
113 AppRadar::Info info(bundleName, "", "");
114 AppRadar::GetInstance().RecordRestoreFuncRes(info, "EndRestore", userId,
115 BizStageRestore::BIZ_STAGE_END_DISPOSE, static_cast<int32_t>(res));
116 }
117 return res;
118 }
119
RecordDoDisposeRes(const std::string & bundleName,AppGalleryDisposeProxy::DisposeOperation disposeOperation,int32_t userId,int32_t err)120 void RecordDoDisposeRes(const std::string &bundleName,
121 AppGalleryDisposeProxy::DisposeOperation disposeOperation, int32_t userId, int32_t err)
122 {
123 AppRadar::Info info (bundleName, "", "REQUEST FAIL");
124 switch (disposeOperation) {
125 case AppGalleryDisposeProxy::DisposeOperation::START_BACKUP:
126 AppRadar::GetInstance().RecordBackupFuncRes(info, "StartBackup", userId,
127 BizStageBackup::BIZ_STAGE_START_DISPOSE, err);
128 break;
129 case AppGalleryDisposeProxy::DisposeOperation::END_BACKUP:
130 AppRadar::GetInstance().RecordBackupFuncRes(info, "EndBackup", userId,
131 BizStageBackup::BIZ_STAGE_END_DISPOSE, err);
132 break;
133 case AppGalleryDisposeProxy::DisposeOperation::START_RESTORE:
134 AppRadar::GetInstance().RecordRestoreFuncRes(info, "StartRestore", userId,
135 BizStageRestore::BIZ_STAGE_START_DISPOSE, err);
136 break;
137 case AppGalleryDisposeProxy::DisposeOperation::END_RESTORE:
138 AppRadar::GetInstance().RecordRestoreFuncRes(info, "EndRestore", userId,
139 BizStageRestore::BIZ_STAGE_END_DISPOSE, err);
140 break;
141 default:
142 break;
143 }
144 }
145
GetAppGalleryConnection(const int32_t userId)146 sptr<AppGalleryConnection> AppGalleryDisposeProxy::GetAppGalleryConnection(const int32_t userId)
147 {
148 auto it = appGalleryConnectionMap_.find(userId);
149 if (it == appGalleryConnectionMap_.end()) {
150 HILOGI("appGalleryConnectionMap not contain %{public}d, will register", userId);
151 return nullptr;
152 }
153 HILOGI("appGalleryConnectionMap contain %{public}d", userId);
154 return appGalleryConnectionMap_[userId];
155 }
156
ConnectAppGallery(const int32_t userId)157 sptr<AppGalleryConnection> AppGalleryDisposeProxy::ConnectAppGallery(const int32_t userId)
158 {
159 std::unique_lock<std::mutex> lock(appGalleryConnectionLock_);
160 sptr<AppGalleryConnection> connection = GetAppGalleryConnection(userId);
161 if (connection == nullptr) {
162 connection = sptr(new AppGalleryConnection(userId));
163 appGalleryConnectionMap_[userId] = connection;
164 }
165 if (connection->GetRemoteObj() == nullptr) {
166 HILOGI("AppGalleryConnection try to connect, userId = %{public}d", userId);
167 if (!connection->ConnectExtAbility(abilityName) || connection->GetRemoteObj() == nullptr) {
168 HILOGE("AppGalleryConnection failed to connect, userId = %{public}d", userId);
169 return nullptr;
170 }
171 }
172 return connection;
173 }
174
DoDispose(const std::string & bundleName,DisposeOperation disposeOperation,const int32_t userId)175 DisposeErr AppGalleryDisposeProxy::DoDispose(const std::string &bundleName, DisposeOperation disposeOperation,
176 const int32_t userId)
177 {
178 try {
179 HILOGI("DoDispose, app %{public}s, operation %{public}d, userId %{public}d", bundleName.c_str(),
180 disposeOperation, userId);
181 sptr<AppGalleryConnection> connection = ConnectAppGallery(userId);
182 if (connection == nullptr) {
183 HILOGE("Get AppGalleryConnection failed, userId = %{public}d", userId);
184 return DisposeErr::CONN_FAIL;
185 }
186
187 BJsonUtil::BundleDetailInfo bundleDetailInfo = BJsonUtil::ParseBundleNameIndexStr(bundleName);
188 MessageParcel data;
189 const auto interfaceToken = APP_FOUNDATION_SERVICE;
190 if (!data.WriteInterfaceToken(interfaceToken)) {
191 HILOGE("write WriteInterfaceToken failed");
192 return DisposeErr::IPC_FAIL;
193 }
194 if (!data.WriteString16(Str8ToStr16(bundleDetailInfo.bundleName))) {
195 HILOGE("write bundleName failed");
196 return DisposeErr::IPC_FAIL;
197 }
198 if (!data.WriteInt32(static_cast<int32_t>(bundleDetailInfo.bundleIndex))) {
199 HILOGE("write bundleIndex failed");
200 return DisposeErr::IPC_FAIL;
201 }
202
203 MessageParcel reply;
204 MessageOption option;
205 auto remoteObj = connection->GetRemoteObj();
206 if (remoteObj == nullptr) {
207 HILOGE("remoteObj is nullptr, bundleName=%{public}s, appindex=%{public}d, userId=%{public}d",
208 bundleDetailInfo.bundleName.c_str(), bundleDetailInfo.bundleIndex, userId);
209 return DisposeErr::CONN_FAIL;
210 }
211
212 int32_t ret = remoteObj->SendRequest(static_cast<int>(disposeOperation), data, reply, option);
213 if (ret != ERR_NONE) {
214 HILOGE("SendRequest error, code=%{public}d, bundleName=%{public}s , appindex=%{public}d, userId=%{public}d",
215 ret, bundleDetailInfo.bundleName.c_str(), bundleDetailInfo.bundleIndex, userId);
216 RecordDoDisposeRes(bundleName, disposeOperation, userId, ret);
217 return DisposeErr::REQUEST_FAIL;
218 }
219
220 HILOGI("SendRequest success, dispose=%{public}d, bundleName=%{public}s, appindex=%{public}d, userId=%{public}d",
221 disposeOperation, bundleDetailInfo.bundleName.c_str(), bundleDetailInfo.bundleIndex, userId);
222 return DisposeErr::OK;
223 } catch (const BError &e) {
224 HILOGE("Catch exception, errCode = %{public}d", e.GetCode());
225 return DisposeErr::IPC_FAIL;
226 } catch (...) {
227 HILOGE("Unexpected exception");
228 return DisposeErr::IPC_FAIL;
229 }
230 }
231
232 } // namespace OHOS::FileManagement::Backup