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 "file_access_service_proxy.h"
17 #include "user_access_tracer.h"
18 #include "file_access_framework_errno.h"
19 #include "file_access_service_ipc_interface_code.h"
20 #include "hilog_wrapper.h"
21 #include "hitrace_meter.h"
22 #include "iservice_registry.h"
23 #include "system_ability_definition.h"
24
25 namespace OHOS {
26 namespace FileAccessFwk {
27 constexpr int LOAD_SA_TIMEOUT_MS = 5000;
GetInstance()28 sptr<IFileAccessServiceBase> FileAccessServiceProxy::GetInstance()
29 {
30 HILOG_INFO("Getinstance");
31 std::unique_lock<std::mutex> lock(proxyMutex_);
32 if (serviceProxy_ != nullptr) {
33 return serviceProxy_;
34 }
35
36 auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
37 if (samgr == nullptr) {
38 HILOG_ERROR("Samgr is nullptr");
39 return nullptr;
40 }
41 sptr<ServiceProxyLoadCallback> loadCallback(new ServiceProxyLoadCallback());
42 if (loadCallback == nullptr) {
43 HILOG_ERROR("loadCallback is nullptr");
44 return nullptr;
45 }
46 int32_t ret = samgr->LoadSystemAbility(FILE_ACCESS_SERVICE_ID, loadCallback);
47 if (ret != ERR_OK) {
48 HILOG_ERROR("Failed to Load systemAbility, systemAbilityId:%{pulbic}d, ret code:%{pulbic}d",
49 FILE_ACCESS_SERVICE_ID, ret);
50 return nullptr;
51 }
52
53 auto waitStatus = loadCallback->proxyConVar_.wait_for(
54 lock, std::chrono::milliseconds(LOAD_SA_TIMEOUT_MS),
55 [loadCallback]() { return loadCallback->isLoadSuccess_.load(); });
56 if (!waitStatus) {
57 HILOG_ERROR("Load FileAccessService SA timeout");
58 return nullptr;
59 }
60 return serviceProxy_;
61 }
62
OnLoadSystemAbilitySuccess(int32_t systemAbilityId,const sptr<IRemoteObject> & remoteObject)63 void FileAccessServiceProxy::ServiceProxyLoadCallback::OnLoadSystemAbilitySuccess(
64 int32_t systemAbilityId,
65 const sptr<IRemoteObject> &remoteObject)
66 {
67 HILOG_INFO("Load FileAccessService SA success,systemAbilityId:%{public}d, remoteObj result:%{private}s",
68 systemAbilityId, (remoteObject == nullptr ? "false" : "true"));
69 std::unique_lock<std::mutex> lock(proxyMutex_);
70 serviceProxy_ = iface_cast<IFileAccessServiceBase>(remoteObject);
71 isLoadSuccess_.store(true);
72 proxyConVar_.notify_one();
73 }
74
OnLoadSystemAbilityFail(int32_t systemAbilityId)75 void FileAccessServiceProxy::ServiceProxyLoadCallback::OnLoadSystemAbilityFail(int32_t systemAbilityId)
76 {
77 HILOG_INFO("Load FileAccessService SA failed,systemAbilityId:%{public}d", systemAbilityId);
78 std::unique_lock<std::mutex> lock(proxyMutex_);
79 serviceProxy_ = nullptr;
80 isLoadSuccess_.store(false);
81 proxyConVar_.notify_one();
82 }
83
OnChange(Uri uri,NotifyType notifyType)84 int32_t FileAccessServiceProxy::OnChange(Uri uri, NotifyType notifyType)
85 {
86 UserAccessTracer trace;
87 trace.Start("OnChange");
88 MessageParcel data;
89 if (!data.WriteInterfaceToken(FileAccessServiceProxy::GetDescriptor())) {
90 HILOG_ERROR("WriteInterfaceToken failed");
91 return E_IPCS;
92 }
93
94 if (!data.WriteParcelable(&uri)) {
95 HILOG_ERROR("fail to WriteParcelable uri");
96 return E_IPCS;
97 }
98
99 if (!data.WriteInt32(static_cast<int32_t>(notifyType))) {
100 HILOG_ERROR("fail to WriteParcelable notifyType");
101 return E_IPCS;
102 }
103
104 MessageParcel reply;
105 MessageOption option;
106 int err = Remote()->SendRequest(static_cast<uint32_t>(FileAccessServiceInterfaceCode::CMD_ONCHANGE), data, reply,
107 option);
108 if (err != ERR_OK) {
109 HILOG_ERROR("fail to SendRequest. err: %{public}d", err);
110 return err;
111 }
112
113 int ret = E_IPCS;
114 if (!reply.ReadInt32(ret) || ret != ERR_OK) {
115 HILOG_ERROR("OnChange operation failed ret : %{public}d", ret);
116 return ret;
117 }
118
119 return ERR_OK;
120 }
121
RegisterNotify(Uri uri,bool notifyForDescendants,const sptr<IFileAccessObserver> & observer)122 int32_t FileAccessServiceProxy::RegisterNotify(Uri uri, bool notifyForDescendants,
123 const sptr<IFileAccessObserver> &observer)
124 {
125 UserAccessTracer trace;
126 trace.Start("RegisterNotify");
127 MessageParcel data;
128 if (!data.WriteInterfaceToken(FileAccessServiceProxy::GetDescriptor())) {
129 HILOG_ERROR("WriteInterfaceToken failed");
130 return E_IPCS;
131 }
132
133 if (!data.WriteParcelable(&uri)) {
134 HILOG_ERROR("fail to WriteParcelable uri");
135 return E_IPCS;
136 }
137
138 if (!data.WriteRemoteObject(observer->AsObject())) {
139 HILOG_ERROR("fail to WriteRemoteObject observer");
140 return E_IPCS;
141 }
142
143 if (!data.WriteBool(notifyForDescendants)) {
144 HILOG_ERROR("fail to WriteBool notifyForDescendants");
145 return E_IPCS;
146 }
147
148 MessageParcel reply;
149 MessageOption option;
150 int err = Remote()->SendRequest(static_cast<uint32_t>(FileAccessServiceInterfaceCode::CMD_REGISTER_NOTIFY), data,
151 reply, option);
152 if (err != ERR_OK) {
153 HILOG_ERROR("fail to SendRequest. err: %{public}d", err);
154 return err;
155 }
156
157 int ret = E_IPCS;
158 if (!reply.ReadInt32(ret) || ret != ERR_OK) {
159 HILOG_ERROR("RegisterNotify operation failed ret : %{public}d", ret);
160 return ret;
161 }
162
163 return ERR_OK;
164 }
165
UnregisterNotifyInternal(MessageParcel & data)166 int32_t FileAccessServiceProxy::UnregisterNotifyInternal(MessageParcel &data)
167 {
168 MessageParcel reply;
169 MessageOption option;
170 int err = Remote()->SendRequest(static_cast<uint32_t>(FileAccessServiceInterfaceCode::CMD_UNREGISTER_NOTIFY), data,
171 reply, option);
172 if (err != ERR_OK) {
173 HILOG_ERROR("fail to SendRequest. err: %{public}d", err);
174 return err;
175 }
176
177 int ret = E_IPCS;
178 if (!reply.ReadInt32(ret) || ret != ERR_OK) {
179 HILOG_ERROR("UnregisterNotify operation failed ret : %{public}d", ret);
180 return ret;
181 }
182
183 return ERR_OK;
184 }
185
UnregisterNotify(Uri uri,const sptr<IFileAccessObserver> & observer)186 int32_t FileAccessServiceProxy::UnregisterNotify(Uri uri, const sptr<IFileAccessObserver> &observer)
187 {
188 UserAccessTracer trace;
189 trace.Start("UnregisterNotify");
190 MessageParcel data;
191 if (!data.WriteInterfaceToken(FileAccessServiceProxy::GetDescriptor())) {
192 HILOG_ERROR("WriteInterfaceToken failed");
193 return E_IPCS;
194 }
195
196 if (!data.WriteParcelable(&uri)) {
197 HILOG_ERROR("fail to WriteParcelable uri");
198 return E_IPCS;
199 }
200 bool observerNotNull = true;
201 if (observer != nullptr) {
202 if (!data.WriteBool(observerNotNull)) {
203 HILOG_ERROR("fail to WriteBool observerNotNull");
204 return E_IPCS;
205 }
206 if (!data.WriteRemoteObject(observer->AsObject())) {
207 HILOG_ERROR("fail to WriteRemoteObject observer");
208 return E_IPCS;
209 }
210 } else {
211 observerNotNull = false;
212 if (!data.WriteBool(observerNotNull)) {
213 HILOG_ERROR("fail to WriteBool observerNotNull");
214 FinishTrace(HITRACE_TAG_FILEMANAGEMENT);
215 return E_IPCS;
216 }
217 }
218
219 // Split the code into two functions for better readability
220 int32_t result = UnregisterNotifyInternal(data);
221
222 return result;
223 }
224 } // namespace FileAccessFwk
225 } // namespace OHOS
226