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