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