• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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_app_service_extension.h"
17 
18 #include "ability_business_error.h"
19 #include "ability_handler.h"
20 #include "ability_info.h"
21 #include "ability_manager_client.h"
22 #include "configuration_utils.h"
23 #include "display_util.h"
24 #include "freeze_util.h"
25 #include "hitrace_meter.h"
26 #include "hilog_tag_wrapper.h"
27 #include "js_extension_common.h"
28 #include "js_extension_context.h"
29 #include "js_runtime.h"
30 #include "js_runtime_utils.h"
31 #include "js_app_service_extension_context.h"
32 #include "napi/native_api.h"
33 #include "napi/native_node_api.h"
34 #include "napi_common_configuration.h"
35 #include "napi_common_want.h"
36 #include "napi_remote_object.h"
37 #ifdef SUPPORT_GRAPHICS
38 #include "iservice_registry.h"
39 #include "system_ability_definition.h"
40 #endif
41 
42 namespace OHOS {
43 namespace AbilityRuntime {
44 namespace {
45 constexpr size_t ARGC_ONE = 1;
46 constexpr size_t ARGC_TWO = 2;
47 }
48 
49 namespace {
GetNativeRemoteObject(napi_env env,napi_value obj)50 sptr<IRemoteObject> GetNativeRemoteObject(napi_env env, napi_value obj)
51 {
52     if (env == nullptr || obj == nullptr) {
53         TAG_LOGE(AAFwkTag::APP_SERVICE_EXT, "null obj");
54         return nullptr;
55     }
56     napi_valuetype type;
57     napi_typeof(env, obj, &type);
58     if (type == napi_undefined || type == napi_null) {
59         TAG_LOGE(AAFwkTag::APP_SERVICE_EXT, "obj type invalid");
60         return nullptr;
61     }
62     if (type != napi_object) {
63         TAG_LOGE(AAFwkTag::APP_SERVICE_EXT, "obj not object");
64         return nullptr;
65     }
66     return NAPI_ohos_rpc_getNativeRemoteObject(env, obj);
67 }
68 }
69 
70 using namespace OHOS::AppExecFwk;
71 
AttachAppServiceExtensionContext(napi_env env,void * value,void *)72 napi_value AttachAppServiceExtensionContext(napi_env env, void *value, void *)
73 {
74     if (value == nullptr) {
75         TAG_LOGW(AAFwkTag::APP_SERVICE_EXT, "null value");
76         return nullptr;
77     }
78     auto ptr = reinterpret_cast<std::weak_ptr<AppServiceExtensionContext> *>(value)->lock();
79     if (ptr == nullptr) {
80         TAG_LOGW(AAFwkTag::APP_SERVICE_EXT, "null ptr");
81         return nullptr;
82     }
83     napi_value object = CreateJsAppServiceExtensionContext(env, ptr);
84     auto sysModule = JsRuntime::LoadSystemModuleByEngine(env,
85         "application.AppServiceExtensionContext", &object, 1);
86     if (sysModule == nullptr) {
87         TAG_LOGW(AAFwkTag::APP_SERVICE_EXT, "null sysModule");
88         return nullptr;
89     }
90     auto contextObj = sysModule->GetNapiValue();
91     napi_coerce_to_native_binding_object(
92         env, contextObj, DetachCallbackFunc, AttachAppServiceExtensionContext, value, nullptr);
93     auto workContext = new (std::nothrow) std::weak_ptr<AppServiceExtensionContext>(ptr);
94     auto res = napi_wrap(env, contextObj, workContext,
95         [](napi_env, void *data, void *) {
96             TAG_LOGD(AAFwkTag::APP_SERVICE_EXT, "Finalizer for weak_ptr app service extension context is called");
97             delete static_cast<std::weak_ptr<AppServiceExtensionContext> *>(data);
98         },
99         nullptr, nullptr);
100     if (res != napi_ok && workContext != nullptr) {
101         TAG_LOGE(AAFwkTag::APP_SERVICE_EXT, "napi_wrap failed:%{public}d", res);
102         delete workContext;
103         return nullptr;
104     }
105     return contextObj;
106 }
107 
Create(const std::unique_ptr<Runtime> & runtime)108 JsAppServiceExtension* JsAppServiceExtension::Create(const std::unique_ptr<Runtime>& runtime)
109 {
110     return new JsAppServiceExtension(static_cast<JsRuntime&>(*runtime));
111 }
112 
JsAppServiceExtension(JsRuntime & jsRuntime)113 JsAppServiceExtension::JsAppServiceExtension(JsRuntime& jsRuntime) : jsRuntime_(jsRuntime) {}
~JsAppServiceExtension()114 JsAppServiceExtension::~JsAppServiceExtension()
115 {
116     TAG_LOGD(AAFwkTag::APP_SERVICE_EXT, "called");
117     auto context = GetContext();
118     if (context) {
119         context->Unbind();
120     }
121 
122     jsRuntime_.FreeNativeReference(std::move(jsObj_));
123     jsRuntime_.FreeNativeReference(std::move(shellContextRef_));
124 }
125 
Init(const std::shared_ptr<AbilityLocalRecord> & record,const std::shared_ptr<OHOSApplication> & application,std::shared_ptr<AbilityHandler> & handler,const sptr<IRemoteObject> & token)126 void JsAppServiceExtension::Init(const std::shared_ptr<AbilityLocalRecord> &record,
127     const std::shared_ptr<OHOSApplication> &application, std::shared_ptr<AbilityHandler> &handler,
128     const sptr<IRemoteObject> &token)
129 {
130     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
131     AppServiceExtension::Init(record, application, handler, token);
132     std::string srcPath = "";
133     GetSrcPath(srcPath);
134     if (srcPath.empty()) {
135         TAG_LOGE(AAFwkTag::APP_SERVICE_EXT, "get srcPath failed");
136         return;
137     }
138 
139     std::string moduleName(Extension::abilityInfo_->moduleName);
140     moduleName.append("::").append(abilityInfo_->name);
141     TAG_LOGD(AAFwkTag::APP_SERVICE_EXT, "called, moduleName:%{public}s,srcPath:%{public}s",
142         moduleName.c_str(), srcPath.c_str());
143     HandleScope handleScope(jsRuntime_);
144     auto env = jsRuntime_.GetNapiEnv();
145 
146     jsObj_ = jsRuntime_.LoadModule(
147         moduleName, srcPath, abilityInfo_->hapPath, abilityInfo_->compileMode == CompileMode::ES_MODULE,
148         false, abilityInfo_->srcEntrance);
149     if (jsObj_ == nullptr) {
150         TAG_LOGE(AAFwkTag::APP_SERVICE_EXT, "null jsObj_");
151         return;
152     }
153 
154     TAG_LOGD(AAFwkTag::APP_SERVICE_EXT, "ConvertNativeValueTo");
155     napi_value obj = jsObj_->GetNapiValue();
156     if (!CheckTypeForNapiValue(env, obj, napi_object)) {
157         TAG_LOGE(AAFwkTag::APP_SERVICE_EXT, "get JsAppServiceExtension obj failed");
158         return;
159     }
160 
161     BindContext(env, obj);
162 
163     SetExtensionCommon(JsExtensionCommon::Create(jsRuntime_, static_cast<NativeReference&>(*jsObj_), shellContextRef_));
164 
165     auto context = GetContext();
166     auto appContext = Context::GetApplicationContext();
167     if (context != nullptr && appContext != nullptr) {
168         auto appConfig = appContext->GetConfiguration();
169         if (appConfig != nullptr) {
170             TAG_LOGD(AAFwkTag::APP_SERVICE_EXT, "Original config dump: %{public}s", appConfig->GetName().c_str());
171             context->SetConfiguration(std::make_shared<Configuration>(*appConfig));
172         }
173     }
174     ListenWMS();
175 }
176 
ListenWMS()177 void JsAppServiceExtension::ListenWMS()
178 {
179 #ifdef SUPPORT_GRAPHICS
180     TAG_LOGD(AAFwkTag::APP_SERVICE_EXT, "RegisterDisplayListener");
181     auto abilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
182     if (abilityManager == nullptr) {
183         TAG_LOGE(AAFwkTag::APP_SERVICE_EXT, "null SaMgr");
184         return;
185     }
186 
187     auto jsAppServiceExtension = std::static_pointer_cast<JsAppServiceExtension>(shared_from_this());
188     displayListener_ = sptr<JsAppServiceExtensionDisplayListener>::MakeSptr(jsAppServiceExtension);
189     if (displayListener_ == nullptr) {
190         TAG_LOGE(AAFwkTag::APP_SERVICE_EXT, "null displayListener");
191         return;
192     }
193 
194     auto context = GetContext();
195     if (context == nullptr || context->GetToken() == nullptr) {
196         TAG_LOGE(AAFwkTag::APP_SERVICE_EXT, "null context");
197         return;
198     }
199 
200     saStatusChangeListener_ =
201         sptr<SystemAbilityStatusChangeListener>::MakeSptr(displayListener_, context->GetToken());
202     if (saStatusChangeListener_ == nullptr) {
203         TAG_LOGE(AAFwkTag::APP_SERVICE_EXT, "null saStatusChangeListener");
204         return;
205     }
206 
207     auto ret = abilityManager->SubscribeSystemAbility(WINDOW_MANAGER_SERVICE_ID, saStatusChangeListener_);
208     if (ret != 0) {
209         TAG_LOGE(AAFwkTag::APP_SERVICE_EXT, "subscribe system ability error:%{public}d.", ret);
210     }
211 #endif
212 }
213 
BindContext(napi_env env,napi_value obj)214 void JsAppServiceExtension::BindContext(napi_env env, napi_value obj)
215 {
216     auto context = GetContext();
217     if (context == nullptr) {
218         TAG_LOGE(AAFwkTag::APP_SERVICE_EXT, "null context");
219         return;
220     }
221     TAG_LOGD(AAFwkTag::APP_SERVICE_EXT, "call");
222     napi_value contextObj = CreateJsAppServiceExtensionContext(env, context);
223     shellContextRef_ = JsRuntime::LoadSystemModuleByEngine(env, "application.AppServiceExtensionContext",
224         &contextObj, ARGC_ONE);
225     if (shellContextRef_ == nullptr) {
226         TAG_LOGE(AAFwkTag::APP_SERVICE_EXT, "null shellContextRef");
227         return;
228     }
229     contextObj = shellContextRef_->GetNapiValue();
230     if (!CheckTypeForNapiValue(env, contextObj, napi_object)) {
231         TAG_LOGE(AAFwkTag::APP_SERVICE_EXT, "get context native obj failed");
232         return;
233     }
234     auto workContext = new (std::nothrow) std::weak_ptr<AppServiceExtensionContext>(context);
235     napi_coerce_to_native_binding_object(
236         env, contextObj, DetachCallbackFunc, AttachAppServiceExtensionContext, workContext, nullptr);
237     TAG_LOGD(AAFwkTag::APP_SERVICE_EXT, "Bind");
238     context->Bind(jsRuntime_, shellContextRef_.get());
239     napi_set_named_property(env, obj, "context", contextObj);
240 
241     auto res = napi_wrap(env, contextObj, workContext,
242         [](napi_env, void* data, void*) {
243             delete static_cast<std::weak_ptr<AppServiceExtensionContext>*>(data);
244         },
245         nullptr, nullptr);
246     if (res != napi_ok && workContext != nullptr) {
247         TAG_LOGE(AAFwkTag::APP_SERVICE_EXT, "napi_wrap failed:%{public}d", res);
248         delete workContext;
249         return;
250     }
251     TAG_LOGD(AAFwkTag::APP_SERVICE_EXT, "end");
252 }
253 
OnStart(const AAFwk::Want & want)254 void JsAppServiceExtension::OnStart(const AAFwk::Want &want)
255 {
256     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
257     Extension::OnStart(want);
258     TAG_LOGI(AAFwkTag::APP_SERVICE_EXT, "call");
259 
260     auto context = GetContext();
261     if (context != nullptr) {
262 #ifdef SUPPORT_GRAPHICS
263         int32_t displayId = AAFwk::DisplayUtil::GetDefaultDisplayId();
264         displayId = want.GetIntParam(Want::PARAM_RESV_DISPLAY_ID, displayId);
265         TAG_LOGD(AAFwkTag::APP_SERVICE_EXT, "displayId %{public}d", displayId);
266         auto configUtils = std::make_shared<ConfigurationUtils>();
267         configUtils->InitDisplayConfig(displayId, context->GetConfiguration(), context->GetResourceManager());
268 #endif //SUPPORT_GRAPHICS
269     }
270 
271     HandleScope handleScope(jsRuntime_);
272     napi_env env = jsRuntime_.GetNapiEnv();
273 
274     // display config has changed, need update context.config
275     if (context != nullptr) {
276         JsExtensionContext::ConfigurationUpdated(env, shellContextRef_, context->GetConfiguration());
277     }
278 
279     napi_value napiWant = OHOS::AppExecFwk::WrapWant(env, want);
280     napi_value argv[] = {napiWant};
281     CallObjectMethod("onCreate", argv, ARGC_ONE);
282     TAG_LOGD(AAFwkTag::APP_SERVICE_EXT, "ok");
283 }
284 
OnStop()285 void JsAppServiceExtension::OnStop()
286 {
287     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
288     AppServiceExtension::OnStop();
289     TAG_LOGD(AAFwkTag::APP_SERVICE_EXT, "call");
290     CallObjectMethod("onDestroy");
291     bool ret = ConnectionManager::GetInstance().DisconnectCaller(GetContext()->GetToken());
292     if (ret) {
293         ConnectionManager::GetInstance().ReportConnectionLeakEvent(getpid(), gettid());
294         TAG_LOGD(AAFwkTag::APP_SERVICE_EXT, "app service extension connection not disconnected");
295     }
296     TAG_LOGI(AAFwkTag::APP_SERVICE_EXT, "UnregisterDisplayInfoChangedListener");
297     auto context = GetContext();
298     if (context == nullptr || context->GetToken() == nullptr) {
299         TAG_LOGE(AAFwkTag::APP_SERVICE_EXT, "null context");
300         return;
301     }
302 #ifdef SUPPORT_GRAPHICS
303     Rosen::WindowManager::GetInstance()
304         .UnregisterDisplayInfoChangedListener(context->GetToken(), displayListener_);
305     if (saStatusChangeListener_) {
306         auto saMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
307         if (saMgr) {
308             saMgr->UnSubscribeSystemAbility(WINDOW_MANAGER_SERVICE_ID, saStatusChangeListener_);
309         } else {
310             TAG_LOGW(AAFwkTag::APP_SERVICE_EXT, "OnStop SaMgr null");
311         }
312     }
313 #endif //SUPPORT_GRAPHICS
314     TAG_LOGD(AAFwkTag::APP_SERVICE_EXT, "ok");
315 }
316 
AddLifecycleEventForJSCall(const std::string & eventStr)317 void JsAppServiceExtension::AddLifecycleEventForJSCall(const std::string &eventStr)
318 {
319     auto entry = std::string("JsAppServiceExtension:") + eventStr;
320     auto context = GetContext();
321     if (context) {
322         FreezeUtil::GetInstance().AddLifecycleEvent(context->GetToken(), entry);
323     }
324 }
325 
OnConnect(const AAFwk::Want & want)326 sptr<IRemoteObject> JsAppServiceExtension::OnConnect(const AAFwk::Want &want)
327 {
328     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
329     HandleScope handleScope(jsRuntime_);
330     AddLifecycleEventForJSCall("OnConnect begin");
331     napi_value result = CallOnConnect(want);
332     AddLifecycleEventForJSCall("OnConnect end");
333     napi_env env = jsRuntime_.GetNapiEnv();
334     auto remoteObj = GetNativeRemoteObject(env, result);
335     if (remoteObj == nullptr) {
336         TAG_LOGE(AAFwkTag::APP_SERVICE_EXT, "null remoteObj");
337     }
338     return remoteObj;
339 }
340 
OnDisconnect(const AAFwk::Want & want)341 void JsAppServiceExtension::OnDisconnect(const AAFwk::Want &want)
342 {
343     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
344     HandleScope handleScope(jsRuntime_);
345     Extension::OnDisconnect(want);
346     TAG_LOGD(AAFwkTag::APP_SERVICE_EXT, "called");
347     CallOnDisconnect(want, false);
348     TAG_LOGD(AAFwkTag::APP_SERVICE_EXT, "end");
349 }
350 
OnCommand(const AAFwk::Want & want,bool restart,int startId)351 void JsAppServiceExtension::OnCommand(const AAFwk::Want &want, bool restart, int startId)
352 {
353     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
354     Extension::OnCommand(want, restart, startId);
355     TAG_LOGD(AAFwkTag::APP_SERVICE_EXT, "restart=%{public}s,startId=%{public}d",
356         restart ? "true" : "false",
357         startId);
358     // wrap want
359     HandleScope handleScope(jsRuntime_);
360     napi_env env = jsRuntime_.GetNapiEnv();
361     napi_value napiWant = OHOS::AppExecFwk::WrapWant(env, want);
362     // wrap startId
363     napi_value napiStartId = nullptr;
364     napi_create_int32(env, startId, &napiStartId);
365     napi_value argv[] = {napiWant, napiStartId};
366     CallObjectMethod("onRequest", argv, ARGC_TWO);
367     TAG_LOGD(AAFwkTag::APP_SERVICE_EXT, "ok");
368 }
369 
CallObjectMethod(const char * name,napi_value const * argv,size_t argc)370 napi_value JsAppServiceExtension::CallObjectMethod(const char* name, napi_value const* argv, size_t argc)
371 {
372     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, std::string("CallObjectMethod:") + name);
373     TAG_LOGD(AAFwkTag::APP_SERVICE_EXT, "name:%{public}s", name);
374 
375     if (!jsObj_) {
376         TAG_LOGW(AAFwkTag::APP_SERVICE_EXT, "Not found AppServiceExtension.js");
377         return nullptr;
378     }
379 
380     HandleScope handleScope(jsRuntime_);
381     napi_env env = jsRuntime_.GetNapiEnv();
382 
383     napi_value obj = jsObj_->GetNapiValue();
384     if (!CheckTypeForNapiValue(env, obj, napi_object)) {
385         TAG_LOGE(AAFwkTag::APP_SERVICE_EXT, "get AppServiceExtension obj failed");
386         return nullptr;
387     }
388 
389     napi_value method = nullptr;
390     napi_get_named_property(env, obj, name, &method);
391     if (!CheckTypeForNapiValue(env, method, napi_function)) {
392         TAG_LOGE(AAFwkTag::APP_SERVICE_EXT, "get '%{public}s' from AppServiceExtension obj failed", name);
393         return nullptr;
394     }
395     TAG_LOGI(AAFwkTag::APP_SERVICE_EXT, "CallFunction(%{public}s) ok", name);
396     napi_value result = nullptr;
397     napi_status status = napi_call_function(env, obj, method, argc, argv, &result);
398     if (status != napi_ok) {
399         TAG_LOGE(AAFwkTag::APP_SERVICE_EXT, "call js func failed: %{public}d", status);
400     }
401     return result;
402 }
403 
GetSrcPath(std::string & srcPath)404 void JsAppServiceExtension::GetSrcPath(std::string &srcPath)
405 {
406     TAG_LOGD(AAFwkTag::APP_SERVICE_EXT, "called");
407     if (!Extension::abilityInfo_->srcEntrance.empty()) {
408         srcPath.append(Extension::abilityInfo_->moduleName + "/");
409         srcPath.append(Extension::abilityInfo_->srcEntrance);
410         srcPath.erase(srcPath.rfind('.'));
411         srcPath.append(".abc");
412     }
413 }
414 
CallOnConnect(const AAFwk::Want & want)415 napi_value JsAppServiceExtension::CallOnConnect(const AAFwk::Want &want)
416 {
417     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
418     Extension::OnConnect(want);
419     TAG_LOGD(AAFwkTag::APP_SERVICE_EXT, "call");
420     napi_env env = jsRuntime_.GetNapiEnv();
421     napi_value napiWant = OHOS::AppExecFwk::WrapWant(env, want);
422     napi_value argv[] = {napiWant};
423     if (!jsObj_) {
424         TAG_LOGW(AAFwkTag::APP_SERVICE_EXT, "Not found AppServiceExtension.js");
425         return nullptr;
426     }
427 
428     napi_value obj = jsObj_->GetNapiValue();
429     if (!CheckTypeForNapiValue(env, obj, napi_object)) {
430         TAG_LOGE(AAFwkTag::APP_SERVICE_EXT, "get AppServiceExtension obj failed");
431         return nullptr;
432     }
433 
434     napi_value method = nullptr;
435     napi_get_named_property(env, obj, "onConnect", &method);
436     if (method == nullptr) {
437         TAG_LOGE(AAFwkTag::APP_SERVICE_EXT, "null method");
438         return nullptr;
439     }
440     napi_value remoteNative = nullptr;
441     TAG_LOGI(AAFwkTag::APP_SERVICE_EXT, "Call onConnect");
442     napi_status status = napi_call_function(env, obj, method, ARGC_ONE, argv, &remoteNative);
443     if (status != napi_ok) {
444         TAG_LOGE(AAFwkTag::APP_SERVICE_EXT, "call js func failed %{public}d", status);
445     }
446     if (remoteNative == nullptr) {
447         TAG_LOGE(AAFwkTag::APP_SERVICE_EXT, "null remoteNative");
448     }
449     TAG_LOGD(AAFwkTag::APP_SERVICE_EXT, "ok");
450     return remoteNative;
451 }
452 
CallOnDisconnect(const AAFwk::Want & want,bool withResult)453 napi_value JsAppServiceExtension::CallOnDisconnect(const AAFwk::Want &want, bool withResult)
454 {
455     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
456     HandleEscape handleEscape(jsRuntime_);
457     napi_env env = jsRuntime_.GetNapiEnv();
458     napi_value napiWant = OHOS::AppExecFwk::WrapWant(env, want);
459     napi_value argv[] = { napiWant };
460     if (!jsObj_) {
461         TAG_LOGW(AAFwkTag::APP_SERVICE_EXT, "Not found AppServiceExtension.js");
462         return nullptr;
463     }
464 
465     napi_value obj = jsObj_->GetNapiValue();
466     if (!CheckTypeForNapiValue(env, obj, napi_object)) {
467         TAG_LOGE(AAFwkTag::APP_SERVICE_EXT, "get AppServiceExtension obj failed");
468         return nullptr;
469     }
470 
471     napi_value method = nullptr;
472     napi_get_named_property(env, obj, "onDisconnect", &method);
473     if (method == nullptr) {
474         TAG_LOGE(AAFwkTag::APP_SERVICE_EXT, "null method");
475         return nullptr;
476     }
477     TAG_LOGI(AAFwkTag::APP_SERVICE_EXT, "Call onDisconnect");
478     if (withResult) {
479         napi_value result = nullptr;
480         napi_status status = napi_call_function(env, obj, method, ARGC_ONE, argv, &result);
481         if (status != napi_ok) {
482             TAG_LOGE(AAFwkTag::APP_SERVICE_EXT, "call js func failed %{public}d", status);
483         }
484         return handleEscape.Escape(result);
485     } else {
486         napi_status status = napi_call_function(env, obj, method, ARGC_ONE, argv, nullptr);
487         if (status != napi_ok) {
488             TAG_LOGE(AAFwkTag::APP_SERVICE_EXT, "call js func failed %{public}d", status);
489         }
490         return nullptr;
491     }
492 }
493 
OnConfigurationUpdated(const AppExecFwk::Configuration & configuration)494 void JsAppServiceExtension::OnConfigurationUpdated(const AppExecFwk::Configuration& configuration)
495 {
496     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
497     AppServiceExtension::OnConfigurationUpdated(configuration);
498     TAG_LOGD(AAFwkTag::APP_SERVICE_EXT, "call");
499     auto context = GetContext();
500     if (context == nullptr) {
501         TAG_LOGE(AAFwkTag::APP_SERVICE_EXT, "null context");
502         return;
503     }
504 
505     auto contextConfig = context->GetConfiguration();
506     if (contextConfig != nullptr) {
507         TAG_LOGD(AAFwkTag::APP_SERVICE_EXT, "Config dump: %{public}s", contextConfig->GetName().c_str());
508         std::vector<std::string> changeKeyV;
509         contextConfig->CompareDifferent(changeKeyV, configuration);
510         if (!changeKeyV.empty()) {
511             contextConfig->Merge(changeKeyV, configuration);
512         }
513         TAG_LOGD(AAFwkTag::APP_SERVICE_EXT, "Config dump after merge: %{public}s", contextConfig->GetName().c_str());
514     }
515     ConfigurationUpdated();
516 }
517 
ConfigurationUpdated()518 void JsAppServiceExtension::ConfigurationUpdated()
519 {
520     TAG_LOGD(AAFwkTag::APP_SERVICE_EXT, "called");
521     HandleScope handleScope(jsRuntime_);
522     napi_env env = jsRuntime_.GetNapiEnv();
523 
524     // Notify extension context
525     auto fullConfig = GetContext()->GetConfiguration();
526     if (!fullConfig) {
527         TAG_LOGE(AAFwkTag::APP_SERVICE_EXT, "null configuration");
528         return;
529     }
530 
531     napi_value napiConfiguration = OHOS::AppExecFwk::WrapConfiguration(env, *fullConfig);
532     CallObjectMethod("onConfigurationUpdate", &napiConfiguration, ARGC_ONE);
533     JsExtensionContext::ConfigurationUpdated(env, shellContextRef_, fullConfig);
534 }
535 #ifdef SUPPORT_GRAPHICS
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)536 void JsAppServiceExtension::SystemAbilityStatusChangeListener::OnAddSystemAbility(int32_t systemAbilityId,
537     const std::string& deviceId)
538 {
539     TAG_LOGD(AAFwkTag::APP_SERVICE_EXT, "systemAbilityId: %{public}d add", systemAbilityId);
540     if (systemAbilityId == WINDOW_MANAGER_SERVICE_ID) {
541         TAG_LOGI(AAFwkTag::APP_SERVICE_EXT, "RegisterDisplayInfoChangedListener");
542         Rosen::WindowManager::GetInstance().RegisterDisplayInfoChangedListener(token_, tmpDisplayListener_);
543     }
544 }
545 
OnCreate(Rosen::DisplayId displayId)546 void JsAppServiceExtension::OnCreate(Rosen::DisplayId displayId)
547 {
548     TAG_LOGD(AAFwkTag::APP_SERVICE_EXT, "OnCreate");
549 }
550 
OnDestroy(Rosen::DisplayId displayId)551 void JsAppServiceExtension::OnDestroy(Rosen::DisplayId displayId)
552 {
553     TAG_LOGD(AAFwkTag::APP_SERVICE_EXT, "OnDestroy");
554 }
555 
OnDisplayInfoChange(const sptr<IRemoteObject> & token,Rosen::DisplayId displayId,float density,Rosen::DisplayOrientation orientation)556 void JsAppServiceExtension::OnDisplayInfoChange(const sptr<IRemoteObject>& token, Rosen::DisplayId displayId,
557     float density, Rosen::DisplayOrientation orientation)
558 {
559     TAG_LOGI(AAFwkTag::APP_SERVICE_EXT, "displayId: %{public}" PRIu64, displayId);
560     auto context = GetContext();
561     if (context == nullptr) {
562         TAG_LOGE(AAFwkTag::APP_SERVICE_EXT, "null context");
563         return;
564     }
565 
566     auto contextConfig = context->GetConfiguration();
567     if (contextConfig == nullptr) {
568         TAG_LOGE(AAFwkTag::APP_SERVICE_EXT, "null contextConfig");
569         return;
570     }
571 
572     TAG_LOGD(AAFwkTag::APP_SERVICE_EXT, "Config dump: %{public}s", contextConfig->GetName().c_str());
573     bool configChanged = false;
574     auto configUtils = std::make_shared<ConfigurationUtils>();
575     configUtils->UpdateDisplayConfig(displayId, contextConfig, context->GetResourceManager(), configChanged);
576     TAG_LOGD(AAFwkTag::APP_SERVICE_EXT, "Config dump after update: %{public}s", contextConfig->GetName().c_str());
577 
578     if (configChanged) {
579         auto jsAppServiceExtension = std::static_pointer_cast<JsAppServiceExtension>(shared_from_this());
580         auto task = [jsAppServiceExtension]() {
581             if (jsAppServiceExtension) {
582                 jsAppServiceExtension->ConfigurationUpdated();
583             }
584         };
585         if (handler_ != nullptr) {
586             handler_->PostTask(task, "JsAppServiceExtension:OnChange");
587         }
588     }
589 
590     TAG_LOGD(AAFwkTag::APP_SERVICE_EXT, "finished");
591 }
592 
OnChange(Rosen::DisplayId displayId)593 void JsAppServiceExtension::OnChange(Rosen::DisplayId displayId)
594 {
595     TAG_LOGD(AAFwkTag::APP_SERVICE_EXT, "displayId: %{public}" PRIu64"", displayId);
596     auto context = GetContext();
597     if (context == nullptr) {
598         TAG_LOGE(AAFwkTag::APP_SERVICE_EXT, "null context");
599         return;
600     }
601 
602     auto contextConfig = context->GetConfiguration();
603     if (contextConfig == nullptr) {
604         TAG_LOGE(AAFwkTag::APP_SERVICE_EXT, "null contextConfig");
605         return;
606     }
607 
608     TAG_LOGD(AAFwkTag::APP_SERVICE_EXT, "Config dump: %{public}s", contextConfig->GetName().c_str());
609     bool configChanged = false;
610     auto configUtils = std::make_shared<ConfigurationUtils>();
611     configUtils->UpdateDisplayConfig(displayId, contextConfig, context->GetResourceManager(), configChanged);
612     TAG_LOGD(AAFwkTag::APP_SERVICE_EXT, "Config dump after update: %{public}s", contextConfig->GetName().c_str());
613 
614     if (configChanged) {
615         auto jsAppServiceExtension = std::static_pointer_cast<JsAppServiceExtension>(shared_from_this());
616         auto task = [jsAppServiceExtension]() {
617             if (jsAppServiceExtension) {
618                 jsAppServiceExtension->ConfigurationUpdated();
619             }
620         };
621         if (handler_ != nullptr) {
622             handler_->PostTask(task, "JsAppServiceExtension:OnChange");
623         }
624     }
625 
626     TAG_LOGD(AAFwkTag::APP_SERVICE_EXT, "finished");
627 }
628 #endif
629 } // AbilityRuntime
630 } // OHOS
631