• 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 
16 #include "js_work_scheduler_extension.h"
17 
18 #include <string>
19 
20 #include "runtime.h"
21 #include "js_runtime.h"
22 #include "js_runtime_utils.h"
23 #include "work_scheduler_extension.h"
24 #include "js_work_scheduler_extension_context.h"
25 #include "work_scheduler_stub_imp.h"
26 #include "hitrace_meter.h"
27 #include "work_sched_constants.h"
28 
29 namespace OHOS {
30 namespace WorkScheduler {
Create(const std::unique_ptr<AbilityRuntime::Runtime> & runtime)31 JsWorkSchedulerExtension* JsWorkSchedulerExtension::Create(const std::unique_ptr<AbilityRuntime::Runtime>& runtime)
32 {
33     return new JsWorkSchedulerExtension(static_cast<AbilityRuntime::JsRuntime&>(*runtime));
34 }
35 
JsWorkSchedulerExtension(AbilityRuntime::JsRuntime & jsRuntime)36 JsWorkSchedulerExtension::JsWorkSchedulerExtension(AbilityRuntime::JsRuntime& jsRuntime) : jsRuntime_(jsRuntime) {}
~JsWorkSchedulerExtension()37 JsWorkSchedulerExtension::~JsWorkSchedulerExtension()
38 {
39     WS_HILOGD("Js WorkScheduler extension destructor.");
40     auto context = GetContext();
41     if (context) {
42         context->Unbind();
43     }
44 
45     jsRuntime_.FreeNativeReference(std::move(jsObj_));
46     jsRuntime_.FreeNativeReference(std::move(shellContextRef_));
47 }
48 
DetachCallbackFunc(napi_env env,void * value,void *)49 inline void *DetachCallbackFunc(napi_env env, void *value, void *)
50 {
51     return value;
52 }
53 
AttachWorkSchedulerExtensionContext(napi_env env,void * value,void *)54 napi_value AttachWorkSchedulerExtensionContext(napi_env env, void *value, void *)
55 {
56     WS_HILOGI("AttachWorkSchedulerExtensionContext");
57     if (value == nullptr) {
58         WS_HILOGE("invalid parameter.");
59         return nullptr;
60     }
61     auto ptr = reinterpret_cast<std::weak_ptr<WorkSchedulerExtensionContext> *>(value)->lock();
62     if (ptr == nullptr) {
63         WS_HILOGE("invalid context.");
64         return nullptr;
65     }
66     napi_value object = CreateJsWorkSchedulerExtensionContext(env, ptr);
67     auto loadObject = AbilityRuntime::JsRuntime::LoadSystemModuleByEngine(env,
68         "application.WorkSchedulerExtensionContext", &object, 1);
69     if (loadObject == nullptr) {
70         return nullptr;
71     }
72     napi_value contextObj = loadObject->GetNapiValue();
73     napi_coerce_to_native_binding_object(env, contextObj, DetachCallbackFunc,
74         AttachWorkSchedulerExtensionContext, value, nullptr);
75     auto workContext = new (std::nothrow) std::weak_ptr<WorkSchedulerExtensionContext>(ptr);
76     if (workContext == nullptr) {
77         WS_HILOGE("init WorkSchedulerExtensionContext failed.");
78         return nullptr;
79     }
80     napi_status status = napi_wrap(env, contextObj, workContext,
81         [](napi_env env, void *data, void *) {
82             WS_HILOGI("Finalizer for weak_ptr WorkSchedulerExtensionContext is called");
83             delete static_cast<std::weak_ptr<WorkSchedulerExtensionContext> *>(data);
84         }, nullptr, nullptr);
85     if (status != napi_ok) {
86         WS_HILOGE("WorkSchedulerExtension failed to wrap the context");
87         delete workContext;
88         workContext = nullptr;
89         return nullptr;
90     }
91 
92     return contextObj;
93 }
94 
Init(const std::shared_ptr<AppExecFwk::AbilityLocalRecord> & record,const std::shared_ptr<AppExecFwk::OHOSApplication> & application,std::shared_ptr<AppExecFwk::AbilityHandler> & handler,const sptr<IRemoteObject> & token)95 void JsWorkSchedulerExtension::Init(const std::shared_ptr<AppExecFwk::AbilityLocalRecord>& record,
96     const std::shared_ptr<AppExecFwk::OHOSApplication>& application,
97     std::shared_ptr<AppExecFwk::AbilityHandler>& handler,
98     const sptr<IRemoteObject>& token)
99 {
100     WS_HILOGD("enter");
101     WorkSchedulerExtension::Init(record, application, handler, token);
102     std::string srcPath = "";
103     GetSrcPath(srcPath);
104     if (srcPath.empty()) {
105         WS_HILOGE("JsWorkSchedulerExtension Failed to get srcPath");
106         return;
107     }
108 
109     std::string moduleName(Extension::abilityInfo_->moduleName);
110     moduleName.append("::").append(abilityInfo_->name);
111     WS_HILOGD("moduleName:%{public}s, srcPath:%{private}s.", moduleName.c_str(), srcPath.c_str());
112     AbilityRuntime::HandleScope handleScope(jsRuntime_);
113     napi_env env = jsRuntime_.GetNapiEnv();
114 
115     jsObj_ = jsRuntime_.LoadModule(moduleName, srcPath, abilityInfo_->hapPath,
116         abilityInfo_->compileMode == AbilityRuntime::CompileMode::ES_MODULE, false, abilityInfo_->srcEntrance);
117     if (jsObj_ == nullptr) {
118         WS_HILOGE("WorkSchedulerExtension Failed to get jsObj_");
119         return;
120     }
121     napi_value obj = jsObj_->GetNapiValue();
122     if (obj == nullptr) {
123         WS_HILOGE("WorkSchedulerExtension Failed to get JsWorkSchedulerExtension object");
124         return;
125     }
126     BindContext(env, obj);
127 
128     WS_HILOGD("end.");
129 }
130 
BindContext(napi_env env,napi_value obj)131 void JsWorkSchedulerExtension::BindContext(napi_env env, napi_value obj)
132 {
133     auto context = GetContext();
134     if (context == nullptr) {
135         WS_HILOGE("WorkSchedulerExtension Failed to get context");
136         return;
137     }
138     napi_value contextObj = CreateJsWorkSchedulerExtensionContext(env, context);
139     shellContextRef_ = jsRuntime_.LoadSystemModule("application.WorkSchedulerExtensionContext",
140         &contextObj, 1);
141     if (shellContextRef_ == nullptr) {
142         WS_HILOGE("WorkSchedulerExtension Failed to get shellContextRef_");
143         return;
144     }
145     contextObj = shellContextRef_->GetNapiValue();
146 
147     auto workContext = new (std::nothrow) std::weak_ptr<WorkSchedulerExtensionContext>(context);
148     if (workContext == nullptr) {
149         WS_HILOGE("init WorkSchedulerExtensionContext failed.");
150         return;
151     }
152     napi_coerce_to_native_binding_object(env, contextObj, DetachCallbackFunc,
153         AttachWorkSchedulerExtensionContext, workContext, nullptr);
154     WS_HILOGI("JsWorkSchedulerExtension init bind and set property.");
155     context->Bind(jsRuntime_, shellContextRef_.get());
156     napi_set_named_property(env, obj, "context", contextObj);
157     WS_HILOGI("Set JsWorkSchedulerExtension context pointer is nullptr or not:%{public}d",
158         context.get() == nullptr);
159 
160     napi_status status = napi_wrap(env, contextObj, workContext,
161         [](napi_env env, void* data, void*) {
162             WS_HILOGI("Finalizer for weak_ptr WorkSchedulerExtensionContext is called");
163             delete static_cast<std::weak_ptr<WorkSchedulerExtensionContext> *>(data);
164         }, nullptr, nullptr);
165     if (status != napi_ok) {
166         WS_HILOGE("WorkSchedulerExtension failed to wrap the context");
167         delete workContext;
168         workContext = nullptr;
169     }
170 }
171 
OnStart(const AAFwk::Want & want)172 void JsWorkSchedulerExtension::OnStart(const AAFwk::Want& want)
173 {
174     WS_HILOGD("begin");
175     AbilityRuntime::Extension::OnStart(want);
176 }
177 
OnStop()178 void JsWorkSchedulerExtension::OnStop()
179 {
180     AbilityRuntime::Extension::OnStop();
181     WS_HILOGD("end.");
182 }
183 
OnConnect(const AAFwk::Want & want)184 __attribute__((no_sanitize("cfi"))) sptr<IRemoteObject> JsWorkSchedulerExtension::OnConnect(const AAFwk::Want& want)
185 {
186     AbilityRuntime::Extension::OnConnect(want);
187     WS_HILOGD("begin.");
188     sptr<WorkSchedulerStubImp> remoteObject = new (std::nothrow) WorkSchedulerStubImp(
189         std::static_pointer_cast<JsWorkSchedulerExtension>(shared_from_this()));
190     if (remoteObject == nullptr) {
191         WS_HILOGE("OnConnect get null");
192         return remoteObject;
193     }
194     WS_HILOGD("end.");
195     return remoteObject->AsObject();
196 }
197 
OnDisconnect(const AAFwk::Want & want)198 void JsWorkSchedulerExtension::OnDisconnect(const AAFwk::Want& want)
199 {
200     WS_HILOGD("begin.");
201     AbilityRuntime::Extension::OnDisconnect(want);
202 }
203 
SetCommonInfo(napi_env env,napi_value workInfoData,int32_t workId,const std::string & bundleName,const std::string & abilityName)204 void SetCommonInfo(napi_env env, napi_value workInfoData, int32_t workId,
205     const std::string& bundleName, const std::string& abilityName)
206 {
207     napi_value workIdValue;
208     napi_create_int32(env, workId, &workIdValue);
209     napi_set_named_property(env, workInfoData, "workId", workIdValue);
210 
211     napi_value bundleNameValue;
212     napi_create_string_utf8(env, bundleName.c_str(), bundleName.size(), &bundleNameValue);
213     napi_set_named_property(env, workInfoData, "bundleName", bundleNameValue);
214 
215     napi_value abilityNameValue;
216     napi_create_string_utf8(env, abilityName.c_str(), abilityName.size(), &abilityNameValue);
217     napi_set_named_property(env, workInfoData, "abilityName", abilityNameValue);
218 }
219 
SetPersistedInfo(napi_env env,napi_value workInfoData,bool isPersisted)220 void SetPersistedInfo(napi_env env, napi_value workInfoData, bool isPersisted)
221 {
222     napi_value isPersistedValue;
223     napi_get_boolean(env, isPersisted, &isPersistedValue);
224     napi_set_named_property(env, workInfoData, "isPersisted", isPersistedValue);
225 }
226 
SetExtrasInfo(napi_env env,napi_value workInfoData,bool getExtrasRet,const std::string & extrasStr)227 void SetExtrasInfo(napi_env env, napi_value workInfoData, bool getExtrasRet, const std::string& extrasStr)
228 {
229     if (getExtrasRet) {
230         napi_value parametersValue;
231         napi_create_string_utf8(env, extrasStr.c_str(), extrasStr.size(), &parametersValue);
232         napi_set_named_property(env, workInfoData, "parameters", parametersValue);
233     }
234 }
235 
SetNetWorkInfo(napi_env env,napi_value workInfoData,WorkCondition::Network networkType)236 void SetNetWorkInfo(napi_env env, napi_value workInfoData, WorkCondition::Network networkType)
237 {
238     if (networkType != WorkCondition::Network::NETWORK_UNKNOWN) {
239         napi_value networkTypeValue;
240         napi_create_int32(env, networkType, &networkTypeValue);
241         napi_set_named_property(env, workInfoData, "networkType", networkTypeValue);
242     }
243 }
244 
SetChargerTypeInfo(napi_env env,napi_value workInfoData,WorkCondition::Charger charger)245 void SetChargerTypeInfo(napi_env env, napi_value workInfoData, WorkCondition::Charger charger)
246 {
247     if (charger != WorkCondition::Charger::CHARGING_UNKNOWN) {
248         if (charger == WorkCondition::Charger::CHARGING_UNPLUGGED) {
249             napi_value isChargingValue;
250             napi_get_boolean(env, false, &isChargingValue);
251             napi_set_named_property(env, workInfoData, "isCharging", isChargingValue);
252         } else {
253             napi_value isChargingValue;
254             napi_get_boolean(env, true, &isChargingValue);
255             napi_set_named_property(env, workInfoData, "isCharging", isChargingValue);
256 
257             napi_value chargerTypeValue;
258             napi_create_int32(env, charger, &chargerTypeValue);
259             napi_set_named_property(env, workInfoData, "chargerType", chargerTypeValue);
260         }
261     }
262 }
263 
SetBatteryInfo(napi_env env,napi_value workInfoData,int32_t batteryLevel,WorkCondition::BatteryStatus batteryStatus)264 void SetBatteryInfo(napi_env env, napi_value workInfoData, int32_t batteryLevel,
265     WorkCondition::BatteryStatus batteryStatus)
266 {
267     if (batteryLevel != INVALID_VALUE) {
268         napi_value batteryLevelValue;
269         napi_create_int32(env, batteryLevel, &batteryLevelValue);
270         napi_set_named_property(env, workInfoData, "batteryLevel", batteryLevelValue);
271     }
272     if (batteryStatus != WorkCondition::BatteryStatus::BATTERY_UNKNOWN) {
273         napi_value batteryStatusValue;
274         napi_create_int32(env, batteryStatus, &batteryStatusValue);
275         napi_set_named_property(env, workInfoData, "batteryStatus", batteryStatusValue);
276     }
277 }
278 
SetStorageInfo(napi_env env,napi_value workInfoData,WorkCondition::Storage storageLevel)279 void SetStorageInfo(napi_env env, napi_value workInfoData, WorkCondition::Storage storageLevel)
280 {
281     if (storageLevel != WorkCondition::Storage::STORAGE_UNKNOWN) {
282         napi_value storageLevelValue;
283         napi_create_int32(env, storageLevel, &storageLevelValue);
284         napi_set_named_property(env, workInfoData, "storageRequest", storageLevelValue);
285     }
286 }
287 
SetRepeatInfo(napi_env env,napi_value workInfoData,bool isRepeat,uint32_t timeInterval,int32_t cycleCount)288 void SetRepeatInfo(napi_env env, napi_value workInfoData, bool isRepeat,
289     uint32_t timeInterval, int32_t cycleCount)
290 {
291     if (isRepeat) {
292         napi_value isRepeatValue;
293         napi_get_boolean(env, true, &isRepeatValue);
294         napi_set_named_property(env, workInfoData, "isRepeat", isRepeatValue);
295 
296         napi_value repeatCycleTimeValue;
297         napi_create_uint32(env, timeInterval, &repeatCycleTimeValue);
298         napi_set_named_property(env, workInfoData, "repeatCycleTime", repeatCycleTimeValue);
299     } else {
300         napi_value repeatCycleTimeValue;
301         napi_create_uint32(env, timeInterval, &repeatCycleTimeValue);
302         napi_set_named_property(env, workInfoData, "repeatCycleTime", repeatCycleTimeValue);
303 
304         napi_value repeatCountValue;
305         napi_create_int32(env, cycleCount, &repeatCountValue);
306         napi_set_named_property(env, workInfoData, "repeatCount", repeatCountValue);
307     }
308 }
309 
SetDeepIdleInfo(napi_env env,napi_value workInfoData,WorkCondition::DeepIdle value)310 void SetDeepIdleInfo(napi_env env, napi_value workInfoData, WorkCondition::DeepIdle value)
311 {
312     if (value == WorkCondition::DeepIdle::DEEP_IDLE_UNKNOWN) {
313         return;
314     }
315     napi_value isDeepIdle;
316     napi_get_boolean(env, (value == WorkCondition::DeepIdle::DEEP_IDLE_IN), &isDeepIdle);
317     napi_set_named_property(env, workInfoData, "isDeepIdle", isDeepIdle);
318 }
319 
CallFuncation(napi_env env,napi_value workInfoData,std::unique_ptr<NativeReference> & jsObj_,const char * functionName)320 bool CallFuncation(napi_env env, napi_value workInfoData,
321     std::unique_ptr<NativeReference> &jsObj_, const char* functionName)
322 {
323     napi_value argv[] = {workInfoData};
324     if (!jsObj_) {
325         WS_HILOGE("WorkSchedulerExtension Not found js");
326         return false;
327     }
328 
329     napi_value value = jsObj_->GetNapiValue();
330     if (value == nullptr) {
331         WS_HILOGE("WorkSchedulerExtension Failed to get WorkSchedulerExtension object");
332         return false;
333     }
334 
335     napi_value method;
336     napi_get_named_property(env, value, functionName, &method);
337     if (method == nullptr) {
338         WS_HILOGE("WorkSchedulerExtension call function %{public}s error, method name is nullptr", functionName);
339         return false;
340     }
341 
342     napi_value callFunctionResult;
343     if (napi_call_function(env, value, method, 1, argv, &callFunctionResult) != napi_ok) {
344         WS_HILOGE("WorkSchedulerExtension call function %{public}s error", functionName);
345         return false;
346     }
347 
348     return true;
349 }
350 
OnWorkStart(WorkInfo & workInfo)351 void JsWorkSchedulerExtension::OnWorkStart(WorkInfo& workInfo)
352 {
353     if (handler_ == nullptr) {
354         return;
355     }
356     WS_HILOGD("begin.");
357     int32_t workId = workInfo.GetWorkId();
358     std::string bundleName = workInfo.GetBundleName();
359     std::string abilityName = workInfo.GetAbilityName();
360     bool isPersisted = workInfo.IsPersisted();
361     WorkCondition::Network networkType = workInfo.GetNetworkType();
362     WorkCondition::Charger charger = workInfo.GetChargerType();
363     int32_t batteryLevel = workInfo.GetBatteryLevel();
364     WorkCondition::BatteryStatus batteryStatus = workInfo.GetBatteryStatus();
365     WorkCondition::Storage storageLevel = workInfo.GetStorageLevel();
366     uint32_t timeInterval = workInfo.GetTimeInterval();
367     bool isRepeat = workInfo.IsRepeat();
368     int32_t cycleCount = workInfo.GetCycleCount();
369     WorkCondition::DeepIdle deepIdleValue = workInfo.GetDeepIdle();
370     std::string extrasStr;
371     bool getExtrasRet = GetExtrasJsonStr(workInfo, extrasStr);
372     WorkSchedulerExtension::OnWorkStart(workInfo);
373     auto task = [=]() {
374         AbilityRuntime::HandleScope handleScope(jsRuntime_);
375         napi_env env = jsRuntime_.GetNapiEnv();
376 
377         napi_value workInfoData;
378         if (napi_create_object(env, &workInfoData) != napi_ok) {
379             WS_HILOGE("WorkSchedulerExtension failed to create workInfoData OnWorkStart");
380             return;
381         }
382 
383         SetCommonInfo(env, workInfoData, workId, bundleName, abilityName);
384         SetExtrasInfo(env, workInfoData, getExtrasRet, extrasStr);
385         SetPersistedInfo(env, workInfoData, isPersisted);
386         SetNetWorkInfo(env, workInfoData, networkType);
387         SetChargerTypeInfo(env, workInfoData, charger);
388         SetBatteryInfo(env, workInfoData, batteryLevel, batteryStatus);
389         SetStorageInfo(env, workInfoData, storageLevel);
390         SetDeepIdleInfo(env, workInfoData, deepIdleValue);
391 
392         if (timeInterval > 0) {
393             SetRepeatInfo(env, workInfoData, isRepeat, timeInterval, cycleCount);
394         }
395 
396         HitraceScoped traceScoped(HITRACE_TAG_OHOS, "JsWorkSchedulerExtension::onWorkStart");
397         if (!CallFuncation(env, workInfoData, jsObj_, "onWorkStart")) {
398             return;
399         }
400     };
401     handler_->PostTask(task);
402 }
403 
OnWorkStop(WorkInfo & workInfo)404 void JsWorkSchedulerExtension::OnWorkStop(WorkInfo& workInfo)
405 {
406     if (handler_ == nullptr) {
407         return;
408     }
409     WS_HILOGD("begin.");
410     int32_t workId = workInfo.GetWorkId();
411     std::string bundleName = workInfo.GetBundleName();
412     std::string abilityName = workInfo.GetAbilityName();
413     bool isPersisted = workInfo.IsPersisted();
414     WorkCondition::Network networkType = workInfo.GetNetworkType();
415     WorkCondition::Charger charger = workInfo.GetChargerType();
416     int32_t batteryLevel = workInfo.GetBatteryLevel();
417     WorkCondition::BatteryStatus batteryStatus = workInfo.GetBatteryStatus();
418     WorkCondition::Storage storageLevel = workInfo.GetStorageLevel();
419     uint32_t timeInterval = workInfo.GetTimeInterval();
420     bool isRepeat = workInfo.IsRepeat();
421     int32_t cycleCount = workInfo.GetCycleCount();
422     WorkCondition::DeepIdle deepIdleValue = workInfo.GetDeepIdle();
423     std::string extrasStr;
424     bool getExtrasRet = GetExtrasJsonStr(workInfo, extrasStr);
425     WorkSchedulerExtension::OnWorkStop(workInfo);
426     auto task = [=]() {
427         AbilityRuntime::HandleScope handleScope(jsRuntime_);
428         napi_env env = jsRuntime_.GetNapiEnv();
429 
430         napi_value workInfoData;
431         if (napi_create_object(env, &workInfoData) != napi_ok) {
432             WS_HILOGE("WorkSchedulerExtension failed to create workInfoData OnWorkStop");
433             return;
434         }
435 
436         SetCommonInfo(env, workInfoData, workId, bundleName, abilityName);
437         SetExtrasInfo(env, workInfoData, getExtrasRet, extrasStr);
438         SetPersistedInfo(env, workInfoData, isPersisted);
439         SetNetWorkInfo(env, workInfoData, networkType);
440         SetChargerTypeInfo(env, workInfoData, charger);
441         SetBatteryInfo(env, workInfoData, batteryLevel, batteryStatus);
442         SetStorageInfo(env, workInfoData, storageLevel);
443         SetDeepIdleInfo(env, workInfoData, deepIdleValue);
444 
445         if (timeInterval > 0) {
446             SetRepeatInfo(env, workInfoData, isRepeat, timeInterval, cycleCount);
447         }
448 
449         HitraceScoped traceScoped(HITRACE_TAG_OHOS, "JsWorkSchedulerExtension::onWorkStop");
450         if (!CallFuncation(env, workInfoData, jsObj_, "onWorkStop")) {
451             return;
452         }
453     };
454     handler_->PostTask(task);
455 }
456 
GetSrcPath(std::string & srcPath)457 void JsWorkSchedulerExtension::GetSrcPath(std::string &srcPath)
458 {
459     if (!Extension::abilityInfo_->isStageBasedModel) {
460         /* temporary compatibility api8 + config.json */
461         srcPath.append(Extension::abilityInfo_->package);
462         srcPath.append("/assets/js/");
463         if (!Extension::abilityInfo_->srcPath.empty()) {
464             srcPath.append(Extension::abilityInfo_->srcPath);
465         }
466         srcPath.append("/").append(Extension::abilityInfo_->name).append(".abc");
467         return;
468     }
469 
470     if (!Extension::abilityInfo_->srcEntrance.empty()) {
471         srcPath.append(Extension::abilityInfo_->moduleName + "/");
472         srcPath.append(Extension::abilityInfo_->srcEntrance);
473         srcPath.erase(srcPath.rfind('.'));
474         srcPath.append(".abc");
475     }
476 }
477 
GetExtrasJsonStr(const WorkInfo & workInfo,std::string & extrasStr)478 bool JsWorkSchedulerExtension::GetExtrasJsonStr(const WorkInfo& workInfo, std::string& extrasStr)
479 {
480     std::shared_ptr<AAFwk::WantParams> extras = workInfo.GetExtras();
481     nlohmann::json extrasJson;
482     if (!extras) {
483         WS_HILOGD("parameter is null.");
484         return false;
485     }
486     auto extrasMap = extras->GetParams();
487     int typeId = INVALID_VALUE;
488     for (auto it : extrasMap) {
489         typeId = AAFwk::WantParams::GetDataType(it.second);
490         if (typeId != INVALID_VALUE) {
491             std::string value = AAFwk::WantParams::GetStringByType(it.second, typeId);
492             extrasJson[it.first] = value;
493         } else {
494             WS_HILOGE("parameters type not supported.");
495         }
496     }
497     extrasStr = extrasJson.dump(JSON_INDENT_WIDTH);
498     return true;
499 }
500 } // namespace WorkScheduler
501 } // namespace OHOS
502