1 /*
2 * Copyright (c) 2023 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 #include "task_state_manager.h"
17
18 #include "gallery_download_file_stat.h"
19 #include "iservice_registry.h"
20 #include "mem_mgr_client.h"
21 #include "parameters.h"
22 #include "system_ability_definition.h"
23 #include "utils_log.h"
24
25 namespace OHOS {
26 namespace FileManagement {
27 namespace CloudSync {
28 using namespace std;
29
30 const int32_t DELAY_TIME = 90000; // ms
31 const int32_t SYSTEM_LOAD_DELAY_TIME = 600000; // ms
32
GetInstance()33 TaskStateManager &TaskStateManager::GetInstance()
34 {
35 static TaskStateManager instance;
36 return instance;
37 }
38
TaskStateManager()39 TaskStateManager::TaskStateManager() : queue_("unloadTask")
40 {
41 }
42
StartTask(string bundleName,TaskType task)43 void TaskStateManager::StartTask(string bundleName, TaskType task)
44 {
45 CancelUnloadTask();
46 std::lock_guard<std::mutex> lock(taskMapsMutex_);
47 if (criticalStatus_ == false) {
48 int32_t ret = Memory::MemMgrClient::GetInstance().SetCritical(getpid(),
49 true, FILEMANAGEMENT_CLOUD_SYNC_SERVICE_SA_ID);
50 if (ret == ERR_OK) {
51 criticalStatus_ = true;
52 }
53 }
54 auto iterator = taskMaps_.find(bundleName);
55 if (iterator == taskMaps_.end()) {
56 taskMaps_[bundleName] = static_cast<uint64_t>(task);
57 return;
58 }
59 auto taskState = iterator->second | static_cast<uint64_t>(task);
60 taskMaps_[bundleName] = taskState;
61 }
62
CompleteTask(string bundleName,TaskType task)63 void TaskStateManager::CompleteTask(string bundleName, TaskType task)
64 {
65 std::lock_guard<std::mutex> lock(taskMapsMutex_);
66 auto iterator = taskMaps_.find(bundleName);
67 if (iterator == taskMaps_.end()) {
68 LOGE("task is not started");
69 } else {
70 taskMaps_[bundleName] = iterator->second & ~static_cast<uint64_t>(task);
71 if (taskMaps_[bundleName] == 0) {
72 taskMaps_.erase(bundleName);
73 }
74 }
75 if (taskMaps_.empty()) {
76 DelayUnloadTask(true);
77 }
78 }
79
StartTask()80 void TaskStateManager::StartTask()
81 {
82 std::lock_guard<std::mutex> lock(taskMapsMutex_);
83 if (taskMaps_.empty()) {
84 DelayUnloadTask(false);
85 }
86 }
87
HasTask(const string bundleName,TaskType task)88 bool TaskStateManager::HasTask(const string bundleName, TaskType task)
89 {
90 std::lock_guard<std::mutex> lock(taskMapsMutex_);
91 auto iterator = taskMaps_.find(bundleName);
92 if (iterator != taskMaps_.end()) {
93 if (taskMaps_[bundleName] & static_cast<uint64_t>(task)) {
94 return true;
95 }
96 }
97 return false;
98 }
99
100
CancelUnloadTask()101 void TaskStateManager::CancelUnloadTask()
102 {
103 std::lock_guard<ffrt::mutex> lock(unloadTaskMutex_);
104 if (unloadTaskHandle_ == nullptr) {
105 return;
106 }
107 LOGD("cancel unload task");
108 queue_.cancel(unloadTaskHandle_);
109 unloadTaskHandle_ = nullptr;
110 }
111
DelayUnloadTask(bool needSetCritical)112 void TaskStateManager::DelayUnloadTask(bool needSetCritical)
113 {
114 const std::string temperatureSysparamSync = "persist.kernel.cloudsync.temperature_abnormal_sync";
115 const std::string temperatureSysparamThumb = "persist.kernel.cloudsync.temperature_abnormal_thumb";
116 string systemLoadSync = system::GetParameter(temperatureSysparamSync, "");
117 string systemLoadThumb = system::GetParameter(temperatureSysparamThumb, "");
118 LOGI("delay unload task begin");
119 auto delayTime = DELAY_TIME;
120 if (systemLoadSync == "true" || systemLoadThumb == "true") {
121 LOGE("temperatureSysparam is true, unload task in 10 minutes");
122 needSetCritical = false;
123 delayTime = SYSTEM_LOAD_DELAY_TIME;
124 }
125 if (needSetCritical == true && criticalStatus_ == true) {
126 int32_t ret = Memory::MemMgrClient::GetInstance().SetCritical(getpid(),
127 false, FILEMANAGEMENT_CLOUD_SYNC_SERVICE_SA_ID);
128 if (ret == ERR_OK) {
129 criticalStatus_ = false;
130 }
131 }
132 auto task = [this]() {
133 LOGI("do unload task");
134 {
135 std::lock_guard<ffrt::mutex> lock(unloadTaskMutex_);
136 unloadTaskHandle_ = nullptr;
137 }
138
139 /* for big data statistics */
140 CloudFile::GalleryDownloadFileStat::GetInstance().OutputToFile();
141
142 auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
143 if (samgrProxy == nullptr) {
144 LOGE("get samgr failed");
145 return;
146 }
147 system::SetParameter(CLOUD_FILE_SERVICE_SA_STATUS_FLAG, CLOUD_FILE_SERVICE_SA_END);
148 int32_t ret = samgrProxy->UnloadSystemAbility(FILEMANAGEMENT_CLOUD_SYNC_SERVICE_SA_ID);
149 if (ret != ERR_OK) {
150 LOGE("remove system ability failed");
151 return;
152 }
153 };
154
155 CancelUnloadTask();
156 std::lock_guard<ffrt::mutex> lock(unloadTaskMutex_);
157 std::chrono::milliseconds ms(delayTime);
158 auto us = std::chrono::duration_cast<std::chrono::microseconds>(ms);
159 unloadTaskHandle_ = queue_.submit_h(task, ffrt::task_attr().delay(us.count()));
160 }
161 } // namespace CloudSync
162 } // namespace FileManagement
163 } // namespace OHOS