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