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 "app_file_access_ext_connection.h"
17 
18 #include <errors.h>
19 #include <memory>
20 
21 #include "ability_connect_callback_interface.h"
22 #include "ability_manager_client.h"
23 #include "file_access_service_proxy.h"
24 #include "hilog_wrapper.h"
25 #include "iremote_broker.h"
26 
27 namespace OHOS {
28 
29 namespace FileAccessFwk {
30 std::mutex AppFileAccessExtConnection::mutex_;
31 
OnAbilityConnectDone(const AppExecFwk::ElementName & element,const sptr<IRemoteObject> & remoteObject,int resultCode)32 void AppFileAccessExtConnection::OnAbilityConnectDone(
33     const AppExecFwk::ElementName &element, const sptr<IRemoteObject> &remoteObject, int resultCode)
34 {
35     std::lock_guard<std::mutex> lock(proxyMutex_);
36     if (remoteObject == nullptr) {
37         HILOG_ERROR("remote is nullptr");
38         return;
39     }
40     fileExtProxy_ = iface_cast<IFileAccessExtBase>(remoteObject);
41     if (fileExtProxy_ == nullptr) {
42         HILOG_ERROR("fileExtProxy_ is nullptr");
43         return;
44     }
45     AddFileAccessDeathRecipient(fileExtProxy_->AsObject());
46     HILOG_INFO("OnAbilityConnectDone set connected info");
47     isConnected_.store(true);
48     connectLockInfo_.isReady = true;
49     connectLockInfo_.condition.notify_all();
50 }
51 
OnAbilityDisconnectDone(const AppExecFwk::ElementName & element,int resultCode)52 void AppFileAccessExtConnection::OnAbilityDisconnectDone(const AppExecFwk::ElementName &element, int resultCode)
53 {
54     std::lock_guard<std::mutex> lock(proxyMutex_);
55     if (fileExtProxy_) {
56         fileExtProxy_ = nullptr;
57     }
58     isConnected_.store(false);
59     HILOG_INFO("OnAbilityDisconnectDone resultCode=%{public}d", resultCode);
60 }
61 
ConnectFileExtAbility(const AAFwk::Want & want)62 void AppFileAccessExtConnection::ConnectFileExtAbility(const AAFwk::Want &want)
63 {
64     std::unique_lock<std::mutex> lock(proxyMutex_);
65     if (fileExtProxy_) {
66         fileExtProxy_ = nullptr;
67     }
68     isConnected_.store(false);
69     auto proxy = FileAccessServiceProxy::GetInstance();
70     if (proxy == nullptr) {
71         HILOG_ERROR("ConnectFileExtAbility FileAccessServiceProxy GetInstance fail");
72         return;
73     }
74 
75     ErrCode ret = proxy->ConnectFileExtAbility(want, this);
76     if (ret != ERR_OK) {
77         HILOG_ERROR("ConnectAbility failed, ret=%{public}d", ret);
78         return;
79     }
80     const int WAIT_TIME = 3;  // second
81     if (!connectLockInfo_.condition.wait_for(lock, std::chrono::seconds(WAIT_TIME),
82         [this] { return fileExtProxy_ != nullptr && connectLockInfo_.isReady; })) {
83         HILOG_ERROR("Wait connect timeout.");
84         return;
85     }
86     HILOG_INFO("ConnectFileExtAbility success");
87 }
88 
DisconnectFileExtAbility()89 void AppFileAccessExtConnection::DisconnectFileExtAbility()
90 {
91     std::lock_guard<std::mutex> lock(proxyMutex_);
92     if (fileExtProxy_ != nullptr) {
93         RemoveFileAccessDeathRecipient(fileExtProxy_->AsObject());
94     }
95     auto proxy = FileAccessServiceProxy::GetInstance();
96     if (proxy == nullptr) {
97         HILOG_ERROR("DisconnectFileExtAbility FileAccessServiceProxy GetInstance fail");
98         return;
99     }
100     ErrCode ret = proxy->DisConnectFileExtAbility(this);
101     if (ret != ERR_OK) {
102         HILOG_ERROR("DisconnectAbility failed, ret=%{public}d", ret);
103         return;
104     }
105     if (fileExtProxy_) {
106         fileExtProxy_ = nullptr;
107     }
108     isConnected_.store(false);
109     HILOG_INFO("DisconnectFileExtAbility done");
110 }
111 
IsExtAbilityConnected()112 bool AppFileAccessExtConnection::IsExtAbilityConnected()
113 {
114     return isConnected_.load();
115 }
116 
GetFileExtProxy()117 sptr<IFileAccessExtBase> AppFileAccessExtConnection::GetFileExtProxy()
118 {
119     return fileExtProxy_;
120 }
121 
AddFileAccessDeathRecipient(const sptr<IRemoteObject> & token)122 void AppFileAccessExtConnection::AddFileAccessDeathRecipient(const sptr<IRemoteObject> &token)
123 {
124     std::lock_guard<std::mutex> lock(deathRecipientMutex_);
125     if (token != nullptr && callerDeathRecipient_ != nullptr) {
126         token->RemoveDeathRecipient(callerDeathRecipient_);
127     }
128     if (callerDeathRecipient_ == nullptr) {
129         callerDeathRecipient_ =
130             new FileAccessDeathRecipient(
131                 std::bind(&AppFileAccessExtConnection::OnSchedulerDied, this, std::placeholders::_1));
132     }
133     if (token != nullptr) {
134         token->AddDeathRecipient(callerDeathRecipient_);
135     }
136 }
137 
RemoveFileAccessDeathRecipient(const sptr<IRemoteObject> & token)138 void AppFileAccessExtConnection::RemoveFileAccessDeathRecipient(const sptr<IRemoteObject> &token)
139 {
140     std::lock_guard<std::mutex> lock(deathRecipientMutex_);
141     if (token != nullptr && callerDeathRecipient_ != nullptr) {
142         token->RemoveDeathRecipient(callerDeathRecipient_);
143     }
144 }
145 
OnSchedulerDied(const wptr<IRemoteObject> & remote)146 void AppFileAccessExtConnection::OnSchedulerDied(const wptr<IRemoteObject> &remote)
147 {
148     std::lock_guard<std::mutex> lock(proxyMutex_);
149     HILOG_ERROR("OnSchedulerDied");
150     auto object = remote.promote();
151     if (object) {
152         object = nullptr;
153     }
154     isConnected_.store(false);
155     if (fileExtProxy_) {
156         fileExtProxy_ = nullptr;
157     }
158 }
159 
~AppFileAccessExtConnection()160 AppFileAccessExtConnection::~AppFileAccessExtConnection()
161 {
162     HILOG_INFO("~AppFileAccessExtConnection");
163     if (isConnected_.load()) {
164         DisconnectFileExtAbility();
165     }
166 }
167 
OnRemoteDied(const wptr<IRemoteObject> & remote)168 void FileAccessDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
169 {
170     HILOG_ERROR("OnRemoteDied");
171     if (handler_) {
172         handler_(remote);
173     }
174 }
175 
FileAccessDeathRecipient(RemoteDiedHandler handler)176 FileAccessDeathRecipient::FileAccessDeathRecipient(RemoteDiedHandler handler) : handler_(handler)
177 {
178 }
179 
~FileAccessDeathRecipient()180 FileAccessDeathRecipient::~FileAccessDeathRecipient()
181 {
182 }
183 } // namespace FileAccessFwk
184 } // namespace OHOS
185