1 /*
2 * Copyright (c) 2022 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 #define LOG_TAG "AssetChangeTimer"
16 #include "asset_change_timer.h"
17
18 #include "client_adaptor.h"
19 #include "logger.h"
20 #include "objectstore_errors.h"
21
22 namespace OHOS::ObjectStore {
23 std::mutex AssetChangeTimer::instanceMutex;
24 AssetChangeTimer *AssetChangeTimer::instance = nullptr;
25
GetInstance(FlatObjectStore * flatObjectStore)26 AssetChangeTimer *AssetChangeTimer::GetInstance(FlatObjectStore *flatObjectStore)
27 {
28 if (instance == nullptr) {
29 std::lock_guard<decltype(instanceMutex)> lockGuard(instanceMutex);
30 if (instance == nullptr) {
31 instance = new (std::nothrow) AssetChangeTimer(flatObjectStore);
32 }
33 }
34 return instance;
35 }
36
AssetChangeTimer(FlatObjectStore * flatObjectStore)37 AssetChangeTimer::AssetChangeTimer(FlatObjectStore *flatObjectStore)
38 {
39 flatObjectStore_ = flatObjectStore;
40 executor_ = std::make_shared<ExecutorPool>(MAX_THREADS, MIN_THREADS);
41 }
42
OnAssetChanged(const std::string & sessionId,const std::string & assetKey,std::shared_ptr<ObjectWatcher> watcher)43 void AssetChangeTimer::OnAssetChanged(
44 const std::string &sessionId, const std::string &assetKey, std::shared_ptr<ObjectWatcher> watcher)
45 {
46 StartTimer(sessionId, assetKey, watcher);
47 }
48
StartTimer(const std::string & sessionId,const std::string & assetKey,std::shared_ptr<ObjectWatcher> watcher)49 void AssetChangeTimer::StartTimer(
50 const std::string &sessionId, const std::string &assetKey, std::shared_ptr<ObjectWatcher> watcher)
51 {
52 std::string key = sessionId + ASSET_SEPARATOR + assetKey;
53 std::lock_guard<decltype(mutex_)> lockGuard(mutex_);
54 if (assetChangeTasks_.find(key) == assetChangeTasks_.end()) {
55 assetChangeTasks_[key] =
56 executor_->Schedule(std::chrono::milliseconds(WAIT_INTERVAL), ProcessTask(sessionId, assetKey, watcher));
57 } else {
58 assetChangeTasks_[key] = executor_->Reset(assetChangeTasks_[key], std::chrono::milliseconds(WAIT_INTERVAL));
59 }
60 }
61
ProcessTask(const std::string & sessionId,const std::string & assetKey,std::shared_ptr<ObjectWatcher> watcher)62 std::function<void()> AssetChangeTimer::ProcessTask(
63 const std::string &sessionId, const std::string &assetKey, std::shared_ptr<ObjectWatcher> watcher)
64 {
65 return [=]() {
66 LOG_DEBUG("Start working on a task, sessionId: %{public}s, assetKey: %{public}s", sessionId.c_str(),
67 assetKey.c_str());
68 StopTimer(sessionId, assetKey);
69 uint32_t status = HandleAssetChanges(sessionId, assetKey);
70 if (status == SUCCESS) {
71 LOG_DEBUG("Asset change task end, start callback, sessionId: %{public}s, assetKey: %{public}s",
72 sessionId.c_str(), assetKey.c_str());
73 watcher->OnChanged(sessionId, { assetKey });
74 }
75 };
76 }
77
StopTimer(const std::string & sessionId,const std::string & assetKey)78 void AssetChangeTimer::StopTimer(const std::string &sessionId, const std::string &assetKey)
79 {
80 std::string key = sessionId + ASSET_SEPARATOR + assetKey;
81 std::lock_guard<decltype(mutex_)> lockGuard(mutex_);
82 executor_->Remove(assetChangeTasks_[key]);
83 assetChangeTasks_.erase(key);
84 }
85
HandleAssetChanges(const std::string & sessionId,const std::string & assetKey)86 uint32_t AssetChangeTimer::HandleAssetChanges(const std::string &sessionId, const std::string &assetKey)
87 {
88 Asset assetValue;
89 if (!GetAssetValue(sessionId, assetKey, assetValue)) {
90 LOG_ERROR("GetAssetValue assetValue is not complete, sessionId: %{public}s, assetKey: %{public}s",
91 sessionId.c_str(), assetKey.c_str());
92 return ERR_DB_GET_FAIL;
93 }
94
95 std::string deviceId;
96 uint32_t status = flatObjectStore_->GetString(sessionId, DEVICEID_KEY, deviceId);
97 if (status != SUCCESS) {
98 LOG_ERROR("get deviceId failed %{public}d", status);
99 return status;
100 }
101
102 sptr<OHOS::DistributedObject::IObjectService> proxy = ClientAdaptor::GetObjectService();
103 if (proxy == nullptr) {
104 LOG_ERROR("proxy is nullptr.");
105 return ERR_NULL_PTR;
106 }
107 int32_t res = proxy->OnAssetChanged(flatObjectStore_->GetBundleName(), sessionId, deviceId, assetValue);
108 if (res != SUCCESS) {
109 LOG_ERROR("OnAssetChanged failed status: %{public}d, sessionId: %{public}s, assetKey: %{public}s", status,
110 sessionId.c_str(), assetKey.c_str());
111 }
112 return res;
113 }
114
GetAssetValue(const std::string & sessionId,const std::string & assetKey,Asset & assetValue)115 bool AssetChangeTimer::GetAssetValue(const std::string &sessionId, const std::string &assetKey, Asset &assetValue)
116 {
117 double doubleStatus;
118 if (flatObjectStore_->GetDouble(sessionId, assetKey + STATUS_SUFFIX, doubleStatus) == SUCCESS) {
119 assetValue.status = static_cast<uint32_t>(doubleStatus);
120 }
121 bool isComplete = true;
122 isComplete = isComplete &&
123 (flatObjectStore_->GetString(sessionId, assetKey + NAME_SUFFIX, assetValue.name) == SUCCESS);
124 isComplete = isComplete &&
125 (flatObjectStore_->GetString(sessionId, assetKey + URI_SUFFIX, assetValue.uri) == SUCCESS);
126 isComplete = isComplete &&
127 (flatObjectStore_->GetString(sessionId, assetKey + PATH_SUFFIX, assetValue.path) == SUCCESS);
128 isComplete = isComplete &&
129 (flatObjectStore_->GetString(sessionId, assetKey + CREATE_TIME_SUFFIX, assetValue.createTime) == SUCCESS);
130 isComplete = isComplete &&
131 (flatObjectStore_->GetString(sessionId, assetKey + MODIFY_TIME_SUFFIX, assetValue.modifyTime) == SUCCESS);
132 isComplete = isComplete &&
133 (flatObjectStore_->GetString(sessionId, assetKey + SIZE_SUFFIX, assetValue.size) == SUCCESS);
134 if (isComplete) {
135 assetValue.name = assetValue.name.substr(STRING_PREFIX_LEN);
136 assetValue.uri = assetValue.uri.substr(STRING_PREFIX_LEN);
137 assetValue.path = assetValue.path.substr(STRING_PREFIX_LEN);
138 assetValue.createTime = assetValue.createTime.substr(STRING_PREFIX_LEN);
139 assetValue.modifyTime = assetValue.modifyTime.substr(STRING_PREFIX_LEN);
140 assetValue.size = assetValue.size.substr(STRING_PREFIX_LEN);
141 assetValue.hash = assetValue.modifyTime + "_" + assetValue.size;
142 }
143 return isComplete;
144 }
145 } // namespace OHOS::ObjectStore