1 /* 2 * Copyright (c) 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 #include "work_scheduler_ffi.h" 17 #include "workscheduler_srv_client.h" 18 #include "work_sched_errors.h" 19 #include "work_scheduler_log.h" 20 21 namespace OHOS { 22 namespace WorkScheduler { 23 24 extern "C" { 25 const int32_t BATTERY_LEVEL_MIN = 0; 26 const int32_t BATTERY_LEVEL_MAX = 100; 27 CJ_StartWork(RetWorkInfo work)28 int32_t CJ_StartWork(RetWorkInfo work) 29 { 30 WorkInfo workInfo = WorkInfo(); 31 auto paraCode = GetWorkInfo(work, workInfo); 32 if (paraCode != SUCCESS_CODE) { 33 LOGE("WorkScheduler: CJ_StartWork parse parameter failed %{public}d", paraCode); 34 return paraCode; 35 } 36 ErrCode errCode = WorkSchedulerSrvClient::GetInstance().StartWork(workInfo); 37 return errCode; 38 } 39 CJ_StopWork(RetWorkInfo work,bool needCancel)40 int32_t CJ_StopWork(RetWorkInfo work, bool needCancel) 41 { 42 WorkInfo workInfo = WorkInfo(); 43 auto paraCode = GetWorkInfo(work, workInfo); 44 if (paraCode != SUCCESS_CODE) { 45 LOGE("WorkScheduler: CJ_StopWork parse parameter failed %{public}d", paraCode); 46 return paraCode; 47 } 48 ErrCode errCode = WorkSchedulerSrvClient::GetInstance().StopWork(workInfo); 49 return errCode; 50 } 51 CJ_GetWorkStatus(int32_t workId,RetWorkInfo & result)52 int32_t CJ_GetWorkStatus(int32_t workId, RetWorkInfo& result) 53 { 54 std::shared_ptr<WorkInfo> workInfo {nullptr}; 55 ErrCode errCode = WorkSchedulerSrvClient::GetInstance().GetWorkStatus(workId, workInfo); 56 if (errCode != ERR_OK) { 57 LOGE("WorkScheduler: CJ_GetWorkStatus failed %{public}d", errCode); 58 return errCode; 59 } 60 ParseWorkInfo(workInfo, result); 61 LOGI("WorkScheduler: CJ_GetWorkStatus success"); 62 return errCode; 63 } 64 CJ_ObtainAllWorks()65 RetArrRetWorkInfo CJ_ObtainAllWorks() 66 { 67 std::list<std::shared_ptr<WorkInfo>> workInfoList; 68 ErrCode errCode = WorkSchedulerSrvClient::GetInstance().ObtainAllWorks(workInfoList); 69 RetArrRetWorkInfo ret = { .code = errCode, .size = 0, .data = nullptr}; 70 if (errCode != ERR_OK) { 71 LOGE("WorkScheduler: CJ_ObtainAllWorks failed "); 72 return ret; 73 } 74 int64_t listSize = static_cast<int64_t>(workInfoList.size()); 75 if (listSize < 0 || listSize > UINT_MAX) { 76 LOGE("Illegal listSize parameter"); 77 return ret; 78 } 79 auto data = static_cast<RetWorkInfo*>(malloc(sizeof(RetWorkInfo) * listSize)); 80 if (data == nullptr) { 81 return ret; 82 } 83 ret.size = listSize; 84 int index = 0; 85 for (auto workInfo: workInfoList) { 86 ParseWorkInfo(workInfo, data[index]); 87 index++; 88 } 89 ret.data = data; 90 return ret; 91 } 92 CJ_IsLastWorkTimeOut(int32_t workId,bool & result)93 int32_t CJ_IsLastWorkTimeOut(int32_t workId, bool& result) 94 { 95 return WorkSchedulerSrvClient::GetInstance().IsLastWorkTimeout(workId, result); 96 } 97 98 // extra is not set GetWorkInfo(RetWorkInfo cwork,WorkInfo & workInfo)99 int32_t GetWorkInfo(RetWorkInfo cwork, WorkInfo& workInfo) 100 { 101 workInfo.SetWorkId(cwork.workId); 102 workInfo.SetElement(std::string(cwork.bundleName), std::string(cwork.abilityName)); 103 workInfo.RequestPersisted(cwork.isPersisted); 104 bool hasConditions = false; 105 int32_t ret = GetNetWorkInfo(cwork, workInfo, hasConditions); 106 if (ret != 0) { 107 return ret; 108 } 109 ret = GetChargeInfo(cwork, workInfo, hasConditions); 110 if (ret != 0) { 111 return ret; 112 } 113 ret = GetBatteryInfo(cwork, workInfo, hasConditions); 114 if (ret != 0) { 115 return ret; 116 } 117 ret = GetStorageInfo(cwork, workInfo, hasConditions); 118 if (ret != 0) { 119 return ret; 120 } 121 ret = GetRepeatInfo(cwork, workInfo, hasConditions); 122 if (ret != 0) { 123 return ret; 124 } 125 126 if (!hasConditions) { 127 LOGE("Set none conditions, so fail to init WorkInfo."); 128 return E_CONDITION_EMPTY; 129 } 130 return 0; 131 } 132 GetNetWorkInfo(RetWorkInfo cwork,WorkInfo & workInfo,bool & hasCondition)133 int32_t GetNetWorkInfo(RetWorkInfo cwork, WorkInfo& workInfo, bool& hasCondition) 134 { 135 int32_t code = 0; 136 if (cwork.netWorkType == UNSET_INT_PARAM) { 137 LOGI("Unset networkType."); 138 } else if (cwork.netWorkType >= WorkCondition::Network::NETWORK_TYPE_ANY && 139 cwork.netWorkType <= WorkCondition::Network::NETWORK_TYPE_ETHERNET) { 140 workInfo.RequestNetworkType(WorkCondition::Network(cwork.netWorkType)); 141 hasCondition = true; 142 } else { 143 LOGE("NetworkType set is invalid, just ignore set."); 144 code = E_NETWORK_TYPE_ERR; 145 } 146 return code; 147 } 148 GetChargeInfo(RetWorkInfo cwork,WorkInfo & workInfo,bool & hasCondition)149 int32_t GetChargeInfo(RetWorkInfo cwork, WorkInfo& workInfo, bool& hasCondition) 150 { 151 if (!cwork.isCharging) { 152 workInfo.RequestChargerType(false, WorkCondition::Charger::CHARGING_UNPLUGGED); 153 } else { 154 if (cwork.chargerType == UNSET_INT_PARAM) { 155 workInfo.RequestChargerType(true, WorkCondition::Charger::CHARGING_PLUGGED_ANY); 156 } else if (cwork.chargerType >= WorkCondition::Charger::CHARGING_PLUGGED_ANY && 157 cwork.chargerType <= WorkCondition::Charger::CHARGING_PLUGGED_WIRELESS) { 158 workInfo.RequestChargerType(true, WorkCondition::Charger(cwork.chargerType)); 159 hasCondition = true; 160 } else { 161 workInfo.RequestChargerType(true, WorkCondition::Charger::CHARGING_PLUGGED_ANY); 162 LOGE("ChargeType info is invalid, just ignore set."); 163 return E_CHARGER_TYPE_ERR; 164 } 165 } 166 return 0; 167 } 168 GetBatteryInfo(RetWorkInfo cwork,WorkInfo & workInfo,bool & hasCondition)169 int32_t GetBatteryInfo(RetWorkInfo cwork, WorkInfo& workInfo, bool& hasCondition) 170 { 171 if (cwork.batteryLevel == UNSET_INT_PARAM) { 172 LOGI("Unset batteryLevel."); 173 } else if (cwork.batteryLevel >= BATTERY_LEVEL_MIN && cwork.batteryLevel <= BATTERY_LEVEL_MAX) { 174 workInfo.RequestBatteryLevel(cwork.batteryLevel); 175 } else { 176 LOGE("BatteryLevel set is invalid, just ignore set."); 177 return E_BATTERY_LEVEL_ERR; 178 } 179 180 if (cwork.batteryStatus == UNSET_INT_PARAM) { 181 LOGI("Unset batteryStatus."); 182 } else if (cwork.batteryStatus >= WorkCondition::BatteryStatus::BATTERY_STATUS_LOW && 183 cwork.batteryStatus <= WorkCondition::BatteryStatus::BATTERY_STATUS_LOW_OR_OKAY) { 184 workInfo.RequestBatteryStatus(WorkCondition::BatteryStatus(cwork.batteryStatus)); 185 hasCondition = true; 186 } else { 187 LOGE("BatteryStatus set is invalid, just ignore set."); 188 return E_BATTERY_STATUS_ERR; 189 } 190 return 0; 191 } 192 GetStorageInfo(RetWorkInfo cwork,WorkInfo & workInfo,bool & hasCondition)193 int32_t GetStorageInfo(RetWorkInfo cwork, WorkInfo& workInfo, bool& hasCondition) 194 { 195 if (cwork.storageRequest == UNSET_INT_PARAM) { 196 LOGI("Unset StorageRequest."); 197 } else if (cwork.storageRequest >= WorkCondition::Storage::STORAGE_LEVEL_LOW && 198 cwork.storageRequest <= WorkCondition::Storage::STORAGE_LEVEL_LOW_OR_OKAY) { 199 workInfo.RequestStorageLevel(WorkCondition::Storage(cwork.storageRequest)); 200 hasCondition = true; 201 } else { 202 LOGE("StorageRequest set is invalid, just ignore set."); 203 return E_STORAGE_REQUEST_ERR; 204 } 205 return 0; 206 } 207 GetRepeatInfo(RetWorkInfo cwork,WorkInfo & workInfo,bool & hasCondition)208 int32_t GetRepeatInfo(RetWorkInfo cwork, WorkInfo& workInfo, bool& hasCondition) 209 { 210 if (cwork.repeatCycleTime == UNSET_INT_PARAM) { 211 LOGI("RepeatCycleTime not set, just ignore other repeat set."); 212 return 0; 213 } 214 215 if (!cwork.isRepeat && cwork.repeatCount == UNSET_INT_PARAM) { 216 LOGI("Not set isRepeat or repeatCount, ignore."); 217 return 0; 218 } 219 if (cwork.isRepeat) { 220 if (cwork.repeatCount > 0) { 221 LOGI("RepeatCount has been set , ignore isRepeat."); 222 workInfo.RequestRepeatCycle(cwork.repeatCycleTime, cwork.repeatCount); 223 } else { 224 workInfo.RequestRepeatCycle(cwork.repeatCycleTime); 225 } 226 hasCondition = true; 227 return 0; 228 } else { 229 if (cwork.repeatCount < 0) { 230 LOGE("RepeatCount is invalid, ignore."); 231 return E_REPEAT_COUNT_ERR; 232 } 233 workInfo.RequestRepeatCycle(cwork.repeatCycleTime, cwork.repeatCount); 234 hasCondition = true; 235 return 0; 236 } 237 } 238 ParseWorkInfo(std::shared_ptr<WorkInfo> workInfo,RetWorkInfo & cwork)239 void ParseWorkInfo(std::shared_ptr<WorkInfo> workInfo, RetWorkInfo& cwork) 240 { 241 cwork.workId = workInfo->GetWorkId(); 242 cwork.bundleName = MallocCString(workInfo->GetBundleName()); 243 cwork.abilityName = MallocCString(workInfo->GetAbilityName()); 244 cwork.isPersisted = workInfo->IsPersisted(); 245 cwork.netWorkType = workInfo->GetNetworkType(); 246 auto chargerType = workInfo->GetChargerType(); 247 if (chargerType >= WorkCondition::Charger::CHARGING_UNPLUGGED) { 248 cwork.isCharging = false; 249 cwork.chargerType = -1; 250 } else { 251 cwork.isCharging = true; 252 cwork.chargerType = chargerType; 253 } 254 cwork.batteryLevel = workInfo->GetBatteryLevel(); 255 cwork.batteryStatus = workInfo->GetBatteryStatus(); 256 cwork.storageRequest = workInfo->GetStorageLevel(); 257 cwork.isRepeat = workInfo->IsRepeat(); 258 cwork.repeatCycleTime = static_cast<int32_t>(workInfo->GetTimeInterval()); 259 cwork.repeatCount = workInfo->GetCycleCount(); 260 cwork.isDeepIdle = -1; 261 cwork.idleWaitTime = -1; 262 } 263 MallocCString(const std::string & origin)264 char* MallocCString(const std::string& origin) 265 { 266 if (origin.empty()) { 267 return nullptr; 268 } 269 auto len = origin.length() + 1; 270 char* res = static_cast<char*>(malloc(sizeof(char) * len)); 271 if (res == nullptr) { 272 return nullptr; 273 } 274 return std::char_traits<char>::copy(res, origin.c_str(), len); 275 } 276 } 277 } // WorkScheduler 278 } // OHOS