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 (isSecondOnDisCon_ == false) {
91         isSecondOnDisCon_.store(true);
92     } else {
93         HILOGE("It's error that the backup extension second died before the backup sa. name : %{public}s",
94             bundleName.data());
95         callDied_(move(bundleName), true);
96     }
97     if (isConnectedDone_ == false) {
98         isConnectedDone_.store(true);
99         HILOGE("It's error that the backup extension dies before the backup sa. name : %{public}s", bundleName.data());
100         callDied_(move(bundleName), false);
101     }
102     condition_.notify_all();
103     waitCondition_.notify_all();
104     HILOGI("called end, name: %{public}s", bundleNameIndexInfo_.c_str());
105 }
106 
ConnectBackupExtAbility(AAFwk::Want & want,int32_t userId)107 ErrCode SvcBackupConnection::ConnectBackupExtAbility(AAFwk::Want &want, int32_t userId)
108 {
109     HILOGI("Called begin");
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 
DisconnectBackupExtAbility()116 ErrCode SvcBackupConnection::DisconnectBackupExtAbility()
117 {
118     HILOGI("called begin");
119     isConnectedDone_.store(true);
120     std::unique_lock<std::mutex> lock(mutex_);
121     ErrCode ret = AppExecFwk::AbilityManagerClient::GetInstance()->DisconnectAbility(this);
122     auto callback = [extConn {wptr(this)}] {
123         auto extPtr = extConn.promote();
124         if (!extPtr) {
125             HILOGE("Dis connect failed");
126             return false;
127         }
128         return extPtr->isConnected_.load() == false;
129     };
130     if (condition_.wait_for(lock, std::chrono::seconds(WAIT_TIME), callback)) {
131         HILOGI("Wait until the connection ends");
132     }
133     HILOGI("called end, ret=%{public}d", ret);
134     return ret;
135 }
136 
WaitDisconnectDone()137 bool SvcBackupConnection::WaitDisconnectDone()
138 {
139     std::unique_lock<std::mutex> lock(waitMutex_);
140     if (waitCondition_.wait_for(lock, std::chrono::seconds(WAIT_TIME),
141         [this]() { return isConnected_.load() == false; })) {
142         HILOGI("Wait disconnected done success");
143         return true;
144     }
145     return false;
146 }
147 
IsExtAbilityConnected()148 bool SvcBackupConnection::IsExtAbilityConnected()
149 {
150     return isConnected_.load();
151 }
152 
GetBackupExtProxy()153 sptr<IExtension> SvcBackupConnection::GetBackupExtProxy()
154 {
155     return backupProxy_;
156 }
157 
SetCallback(function<void (const std::string &&)> callConnected)158 void SvcBackupConnection::SetCallback(function<void(const std::string &&)> callConnected)
159 {
160     callConnected_ = callConnected;
161 }
162 
SetCallDied(function<void (const std::string &&,bool)> callDied)163 void SvcBackupConnection::SetCallDied(function<void(const std::string &&, bool)> callDied)
164 {
165     callDied_ = callDied;
166 }
167 } // namespace OHOS::FileManagement::Backup