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