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