1 /*
2  * Copyright (C) 2023-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 #ifndef FILE_ACCESS_SERVICE_H
17 #define FILE_ACCESS_SERVICE_H
18 
19 #include <atomic>
20 #include <memory>
21 #include <mutex>
22 #include <string>
23 #include <system_ability.h>
24 #include <unordered_map>
25 #include <vector>
26 
27 #include "bundle_mgr_interface.h"
28 #include "file_access_ext_connection.h"
29 #include "file_access_service_stub.h"
30 #include "ifile_access_ext_base.h"
31 #include "holder_manager.h"
32 #include "ifile_access_ext_base.h"
33 #include "iremote_object.h"
34 #include "timer.h"
35 #include "uri.h"
36 #include "want.h"
37 
38 namespace OHOS {
39 namespace FileAccessFwk {
40 class AgentFileAccessExtConnection;
41 class ObserverContext {
42     public:
ObserverContext(sptr<IFileAccessObserver> obs)43         ObserverContext(sptr<IFileAccessObserver> obs): obs_(obs) {}
44         virtual ~ObserverContext() = default;
45         sptr<IFileAccessObserver> obs_ = nullptr;
Ref()46         void Ref()
47         {
48             if (ref_ == std::numeric_limits<int32_t>::max()) {
49                 HILOG_ERROR("Ref is over max");
50                 return;
51             }
52             ref_++;
53         }
54 
UnRef()55         void UnRef()
56         {
57             if (ref_ == 0) {
58                 HILOG_ERROR("Ref is already zero");
59                 return;
60             }
61             ref_--;
62         }
63 
IsValid()64         bool IsValid()
65         {
66             return ref_ > 0;
67         }
68 
EqualTo(std::shared_ptr<ObserverContext> observerContext)69         bool EqualTo(std::shared_ptr<ObserverContext> observerContext)
70         {
71             if (!(observerContext != nullptr && observerContext->obs_ != nullptr) || obs_ == nullptr) {
72                 HILOG_ERROR("context pointer is nullptr");
73                 return false;
74             }
75             return obs_->AsObject() == observerContext->obs_->AsObject();
76         }
77 
78     std::unordered_map<NotifyType, std::vector<std::string>> notifyMap_;
79     std::mutex mapMutex_;
80     private:
81         std::atomic<int32_t> ref_;
82 };
83 
84 class ObserverNode {
85     public:
ObserverNode(const bool needChildNote)86         ObserverNode(const bool needChildNote): needChildNote_(needChildNote) {}
87         virtual ~ObserverNode() = default;
88         std::shared_ptr<ObserverNode> parent_;
89         std::vector<std::shared_ptr<ObserverNode>> children_;
90         std::mutex obsCodeMutex_;
91         std::vector<uint32_t> obsCodeList_;
92         bool needChildNote_;
93     public:
FindAndRmObsCodeByCode(uint32_t code)94        int32_t FindAndRmObsCodeByCode(uint32_t code)
95        {
96             std::lock_guard<std::mutex> lock(obsCodeMutex_);
97             auto haveCodeIter = find_if(obsCodeList_.begin(), obsCodeList_.end(),
98             [code](const uint32_t &listCode) { return code == listCode; });
99             if (haveCodeIter == obsCodeList_.end()) {
100                 HILOG_ERROR("Uri node observer list don not has this observer");
101                 return E_CALLBACK_AND_URI_HAS_NOT_RELATIONS;
102             }
103             obsCodeList_.erase(haveCodeIter);
104             return ERR_OK;
105         }
106 
CheckObsCodeListNotEmpty()107         bool CheckObsCodeListNotEmpty()
108         {
109             std::lock_guard<std::mutex> lock(obsCodeMutex_);
110             if (obsCodeList_.size() != 0) {
111                 HILOG_DEBUG("Has code do not stopWatcher");
112                 return true;
113             }
114             return false;
115         }
116 };
117 
118 class OnDemandTimer {
119 public:
120     using TimerCallback = std::function<bool()>;
OnDemandTimer(const TimerCallback & callback,int32_t intervalTime,int32_t maxCount)121     OnDemandTimer(const TimerCallback &callback, int32_t intervalTime, int32_t maxCount) : timerCallback_(callback),
122         intervalTime_(intervalTime), maxCount_(maxCount) {
123             if (timerCallback_ == nullptr) {
124                 HILOG_ERROR("timerCallback_ is required not to be nullptr");
125             }
126             timer_.Setup();
127         }
~OnDemandTimer()128     virtual ~OnDemandTimer()
129     {
130         timer_.Shutdown();
131     }
start()132     void start()
133     {
134         if (isTimerStart_) {
135             return;
136         }
137         std::lock_guard<std::mutex> lock(timerMutex_);
138         if (isTimerStart_) {
139             return;
140         }
141         timerId_ = timer_.Register([this] {
142             if (timerCallback_ == nullptr) {
143                 HILOG_ERROR("timerCallback_ is nullptr");
144                 return;
145             }
146             if (!timerCallback_()) {
147                 if (++count_ >= maxCount_) {
148                     stop();
149                     count_ = 0;
150                 }
151             } else {
152                 count_ = 0;
153             }
154         }, intervalTime_);
155         isTimerStart_ = true;
156     }
157 
stop()158     void stop()
159     {
160         timer_.Unregister(timerId_);
161         isTimerStart_ = false;
162     }
163 private:
164     Utils::Timer timer_{"OnDemandTimer"};
165     TimerCallback timerCallback_ = nullptr;
166     bool isTimerStart_ = false;
167     uint32_t intervalTime_ = 0;
168     uint32_t timerId_ = 0;
169     uint32_t maxCount_ = 0;
170     uint32_t count_ = 0;
171     std::mutex timerMutex_;
172 };
173 
174 class UnloadTimer {
175 public:
176     using UnloadTimerCallback = std::function<void()>;
UnloadTimer(const UnloadTimerCallback unloadTimerCallback,int32_t intervalTime,int32_t maxCount)177     UnloadTimer(const UnloadTimerCallback unloadTimerCallback, int32_t intervalTime, int32_t maxCount)
178         : unloadTimerCallback_(unloadTimerCallback), intervalTime_(intervalTime), maxCount_(maxCount)
179     {
180         timer_.Setup();
181     }
182 
~UnloadTimer()183     virtual ~UnloadTimer()
184     {
185         timer_.Unregister(timerId_);
186         timer_.Shutdown();
187     }
188 
start()189     void start()
190     {
191         timerId_ = timer_.Register([this] {
192             count_++;
193             if (count_ >= maxCount_) {
194                 if (unloadTimerCallback_ == nullptr) {
195                     HILOG_ERROR("unloadTimerCallback_ is nullptr");
196                     return;
197                 }
198                 unloadTimerCallback_();
199                 reset();
200             }
201         }, intervalTime_);
202     }
203 
reset()204     void reset()
205     {
206         count_ = 0;
207     }
208 
209 private:
210     Utils::Timer timer_{"UnloadTimer"};
211     UnloadTimerCallback unloadTimerCallback_ = nullptr;
212     uint32_t intervalTime_ = 0;
213     uint32_t timerId_ = 0;
214     uint32_t maxCount_ = 0;
215     uint32_t count_ = 0;
216 };
217 
218 class FileAccessService final : public SystemAbility, public FileAccessServiceStub {
219     DECLARE_SYSTEM_ABILITY(FileAccessService)
220 
221 public:
222     static sptr<FileAccessService> GetInstance();
223     void Init();
224     virtual ~FileAccessService() = default;
225 
226     virtual void OnStart() override;
227     virtual void OnStop() override;
228     int32_t Dump(int32_t fd, const std::vector<std::u16string> &args) override;
229 
230     void DisconnectAppProxy(const sptr<AAFwk::IAbilityConnection>& connection);
231     void RemoveAppProxy(const sptr<AAFwk::IAbilityConnection>& connection);
232 
233 protected:
234     int32_t RegisterNotify(Uri uri, bool notifyForDescendants, const sptr<IFileAccessObserver> &observer,
235         const std::shared_ptr<ConnectExtensionInfo> &info) override;
236     int32_t UnregisterNotify(Uri uri, const sptr<IFileAccessObserver> &observer,
237         const std::shared_ptr<ConnectExtensionInfo> &info = nullptr) override;
238     int32_t CleanAllNotify(Uri uri, const std::shared_ptr<ConnectExtensionInfo> &info) override;
239     int32_t OnChange(Uri uri, NotifyType notifyType) override;
240     int32_t GetExtensionProxy(const std::shared_ptr<ConnectExtensionInfo> &info,
241                              sptr<IFileAccessExtBase> &extensionProxy) override;
242     int32_t ConnectFileExtAbility(const AAFwk::Want &want,
243         const sptr<AAFwk::IAbilityConnection>& connection) override;
244     int32_t DisConnectFileExtAbility(const sptr<AAFwk::IAbilityConnection>& connection) override;
245 
246 private:
247     class ExtensionDeathRecipient : public IRemoteObject::DeathRecipient {
248     public:
249         ExtensionDeathRecipient() = default;
250         virtual void OnRemoteDied(const wptr<IRemoteObject>& remote);
251         virtual ~ExtensionDeathRecipient() = default;
252     };
253 
254     class ObserverDeathRecipient : public IRemoteObject::DeathRecipient {
255     public:
256         ObserverDeathRecipient() = default;
257         virtual void OnRemoteDied(const wptr<IRemoteObject>& remote);
258         virtual ~ObserverDeathRecipient() = default;
259     };
260 
261     int32_t RegisterNotifyImpl(Uri uri, bool notifyForDescendants, const sptr<IFileAccessObserver> &observer,
262         const std::shared_ptr<ConnectExtensionInfo> &info);
263     int32_t UnregisterNotifyImpl(Uri uri, const sptr<IFileAccessObserver> &observer,
264         const std::shared_ptr<ConnectExtensionInfo> &info = nullptr);
265     int32_t CleanAllNotifyImpl(Uri uri, const std::shared_ptr<ConnectExtensionInfo> &info);
266     int32_t OperateObsNode(Uri &uri, bool notifyForDescendants, uint32_t code,
267         const std::shared_ptr<ConnectExtensionInfo> &info);
268     void CleanRelativeObserver(const sptr<IFileAccessObserver> &observer);
269     std::vector<Uri> GetUriList(uint32_t code);
270     void SendListNotify(std::string uri, NotifyType notifyType, const std::vector<uint32_t> &list);
271     void RemoveRelations(std::string &uriStr, std::shared_ptr<ObserverNode> obsNode);
272     int FindUri(const std::string &uriStr, std::shared_ptr<ObserverNode> &outObsNode);
273     sptr<IFileAccessExtBase> ConnectExtension(Uri &uri, const std::shared_ptr<ConnectExtensionInfo> &info);
274     void ResetProxy(const wptr<IRemoteObject> &remote);
275     FileAccessService();
276     bool IsServiceReady() const;
277     void InitTimer();
278     bool IsUnused();
279     int32_t RmUriObsNodeRelations(std::string &uriStr, std::shared_ptr<ObserverNode> &obsNode,
280         const std::shared_ptr<ConnectExtensionInfo> &info);
281     sptr<IFileAccessExtBase> FindExtProxyByBundleName(std::string bundleName);
282     void AddExtProxyInfo(std::string bundleName, sptr<IFileAccessExtBase> extProxy);
283     // 管理对象 方法
284     void AddAppProxy(const sptr<AAFwk::IAbilityConnection>& key, sptr<AgentFileAccessExtConnection>& value);
285     std::shared_ptr<UnloadTimer> unLoadTimer_ = nullptr;
286     std::shared_ptr<OnDemandTimer> onDemandTimer_ = nullptr;
287     static sptr<FileAccessService> instance_;
288     sptr<IRemoteObject::DeathRecipient> extensionDeathRecipient_;
289     sptr<IRemoteObject::DeathRecipient> observerDeathRecipient_;
290     std::vector<AAFwk::Want> wants_;
291     bool ready_ = false;
292     static std::mutex mutex_;
293     std::mutex nodeMutex_;
294     std::unordered_map<std::string, std::shared_ptr<ObserverNode>> relationshipMap_;
295     HolderManager<std::shared_ptr<ObserverContext>> obsManager_;
296     std::mutex mapMutex_;
297     std::unordered_map<std::string, sptr<IFileAccessExtBase>> cMap_;
298 
299     class AppDeathRecipient : public IRemoteObject::DeathRecipient {
300     public:
AppDeathRecipient()301         AppDeathRecipient() {}
302         virtual void OnRemoteDied(const wptr<IRemoteObject>& remote);
303         virtual ~AppDeathRecipient() = default;
304     };
305 
306     std::mutex appProxyMutex_;
307     std::unordered_map<size_t, sptr<AgentFileAccessExtConnection>> appProxyMap_;
308     std::unordered_map<size_t, sptr<AAFwk::IAbilityConnection>> appConnection_;
309     sptr<IRemoteObject::DeathRecipient> appDeathRecipient_;
310 };
311 } // namespace FileAccessFwk
312 } // namespace OHOS
313 #endif // FILE_ACCESS_SERVICE_H
314