diff --git a/frameworks/ets/ani/ani_common/include/ani_common_util.h b/frameworks/ets/ani/ani_common/include/ani_common_util.h index 38d34f0a2026d68c4ebbb4210d4ea623fe8aebbc..a601a0493a039d66674e2f9165d5479bad088f73 100644 --- a/frameworks/ets/ani/ani_common/include/ani_common_util.h +++ b/frameworks/ets/ani/ani_common/include/ani_common_util.h @@ -51,6 +51,8 @@ bool GetStringOrUndefined(ani_env *env, ani_object param, const char *name, std: ani_object CreateDouble(ani_env *env, ani_double value); ani_object CreateBoolean(ani_env *env, ani_boolean value); + +bool AsyncCallback(ani_env *env, ani_object call, ani_object error, ani_object result); } // namespace AppExecFwk } // namespace OHOS #endif // OHOS_ABILITY_RUNTIME_ANI_COMMON_UTIL_H diff --git a/frameworks/ets/ani/ani_common/src/ani_common_util.cpp b/frameworks/ets/ani/ani_common/src/ani_common_util.cpp index 85a7a6dab7d32c02182a16d53aaa6a92e2968319..69c8f93b5e46e0cfd977e35c8f171bc882b35daf 100644 --- a/frameworks/ets/ani/ani_common/src/ani_common_util.cpp +++ b/frameworks/ets/ani/ani_common/src/ani_common_util.cpp @@ -24,6 +24,7 @@ namespace AppExecFwk { constexpr const char* CLASSNAME_DOUBLE = "Lstd/core/Double;"; constexpr const char* CLASSNAME_BOOL = "Lstd/core/Boolean;"; constexpr const char* CLASSNAME_ARRAY = "Lescompat/Array;"; +constexpr const char* CLASSNAME_ASYNC_CALLBACK_WRAPPER = "Lutils/AbilityUtils/AsyncCallbackWrapper;"; bool GetFieldDoubleByName(ani_env *env, ani_object object, const char *name, double &value) { @@ -502,5 +503,32 @@ bool GetStringOrUndefined(ani_env *env, ani_object param, const char *name, std: } return true; } + +bool AsyncCallback(ani_env *env, ani_object call, ani_object error, ani_object result) +{ + ani_status status = ANI_ERROR; + ani_class clsCall {}; + + if ((status = env->FindClass(CLASSNAME_ASYNC_CALLBACK_WRAPPER, &clsCall)) != ANI_OK) { + TAG_LOGE(AAFwkTag::JSNAPI, "status: %{public}d", status); + return false; + } + ani_method method {}; + if ((status = env->Class_FindMethod( + clsCall, "invoke", "L@ohos/base/BusinessError;Lstd/core/Object;:V", &method)) != ANI_OK) { + TAG_LOGE(AAFwkTag::JSNAPI, "status: %{public}d", status); + return false; + } + if (result == nullptr) { + ani_ref nullRef = nullptr; + env->GetNull(&nullRef); + result = reinterpret_cast(nullRef); + } + if ((status = env->Object_CallMethod_Void(call, method, error, result)) != ANI_OK) { + TAG_LOGE(AAFwkTag::JSNAPI, "status: %{public}d", status); + return false; + } + return true; +} } // namespace AppExecFwk } // namespace OHOS diff --git a/frameworks/ets/ani/native_constructor/context_native_constructor.cpp b/frameworks/ets/ani/native_constructor/context_native_constructor.cpp index 79964f5e4d9fee8b41d3f43dc6b145a62b75229c..cee2ac18682964abd6eefaf1a425e24bf0098318 100644 --- a/frameworks/ets/ani/native_constructor/context_native_constructor.cpp +++ b/frameworks/ets/ani/native_constructor/context_native_constructor.cpp @@ -22,6 +22,10 @@ void ContextConstructor() { } +void ExtensionContextConstructor() +{ +} + extern "C" { ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result) { @@ -48,6 +52,21 @@ ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result) TAG_LOGE(AAFwkTag::ETSRUNTIME, "Cannot bind native ctor to class %{public}s.", contextClassName); return ANI_ERROR; }; + + ani_class extensionContextClass; + static const char *extensionContextClassName = "Lapplication/ExtensionContext/ExtensionContext;"; + if (ANI_OK != env->FindClass(extensionContextClassName, &extensionContextClass)) { + TAG_LOGE(AAFwkTag::ETSRUNTIME, "Not found class %{public}s.", extensionContextClassName); + return ANI_NOT_FOUND; + } + std::array classMethods_extensionContext = { + ani_native_function {"", ":V", reinterpret_cast(ExtensionContextConstructor)}, + }; + if (ANI_OK != env->Class_BindNativeMethods(extensionContextClass, classMethods_extensionContext.data(), + classMethods_extensionContext.size())) { + TAG_LOGE(AAFwkTag::ETSRUNTIME, "Cannot bind native ctor to class %{public}s.", extensionContextClassName); + return ANI_ERROR; + }; *result = ANI_VERSION_1; return ANI_OK; } diff --git a/frameworks/ets/ani/service_extension_ability/include/ets_service_extension.h b/frameworks/ets/ani/service_extension_ability/include/ets_service_extension.h new file mode 100644 index 0000000000000000000000000000000000000000..ee550a541b47a29f5ec81257076335d0ec8fd65e --- /dev/null +++ b/frameworks/ets/ani/service_extension_ability/include/ets_service_extension.h @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OHOS_ABILITY_RUNTIME_ETS_SERVICE_EXTENSION_H +#define OHOS_ABILITY_RUNTIME_ETS_SERVICE_EXTENSION_H + +#include "configuration.h" +#include "ets_runtime.h" +#include "service_extension.h" + +namespace OHOS { +namespace AbilityRuntime { +/** + * @brief Basic service components. + */ +class EtsServiceExtension : public ServiceExtension { +public: + explicit EtsServiceExtension(ETSRuntime &etsRuntime); + virtual ~EtsServiceExtension() override; + + /** + * @brief Create EtsServiceExtension. + * + * @param runtime The runtime. + * @return The EtsServiceExtension instance. + */ + static EtsServiceExtension *Create(const std::unique_ptr &runtime); + + /** + * @brief Init the extension. + * + * @param record the extension record. + * @param application the application info. + * @param handler the extension handler. + * @param token the remote token. + */ + virtual void Init(const std::shared_ptr &record, + const std::shared_ptr &application, + std::shared_ptr &handler, const sptr &token) override; + + /** + * @brief Called when this extension is started. You must override this function if you want to perform some + * initialization operations during extension startup. + * + * This function can be called only once in the entire lifecycle of an extension. + * @param Want Indicates the {@link Want} structure containing startup information about the extension. + */ + virtual void OnStart(const AAFwk::Want &want) override; + + /** + * @brief Called when this Service extension is connected for the first time. + * + * You can override this function to implement your own processing logic. + * + * @param want Indicates the {@link Want} structure containing connection information about the Service extension. + * @return Returns a pointer to the sid of the connected Service extension. + */ + virtual sptr OnConnect(const AAFwk::Want &want) override; + + /** + * @brief Called when this Service extension is connected for the first time. + * + * You can override this function to implement your own processing logic. + * + * @param want Indicates the {@link Want} structure containing connection information about the Service extension. + * @param callbackInfo Indicates the lifecycle transaction callback information + * @param isAsyncCallback Indicates whether it is an asynchronous lifecycle callback + * @return Returns a pointer to the sid of the connected Service extension. + */ + virtual sptr OnConnect(const AAFwk::Want &want, + AppExecFwk::AbilityTransactionCallbackInfo> *callbackInfo, bool &isAsyncCallback) override; + + /** + * @brief Called when all abilities connected to this Service extension are disconnected. + * + * You can override this function to implement your own processing logic. + * + */ + virtual void OnDisconnect(const AAFwk::Want &want) override; + + /** + * @brief Called when all abilities connected to this Service extension are disconnected. + * + * You can override this function to implement your own processing logic. + * @param callbackInfo Indicates the lifecycle transaction callback information + * @param isAsyncCallback Indicates whether it is an asynchronous lifecycle callback + */ + void OnDisconnect(const AAFwk::Want &want, AppExecFwk::AbilityTransactionCallbackInfo<> *callbackInfo, + bool &isAsyncCallback) override; + + /** + * @brief Called back when Service is started. + * This method can be called only by Service. You can use the StartAbility(ohos.aafwk.content.Want) method to start + * Service. Then the system calls back the current method to use the transferred want parameter to execute its own + * logic. + * + * @param want Indicates the want of Service to start. + * @param restart Indicates the startup mode. The value true indicates that Service is restarted after being + * destroyed, and the value false indicates a normal startup. + * @param startId Indicates the number of times the Service extension has been started. The startId is incremented + * by 1 every time the extension is started. For example, if the extension has been started for six times, the + * value of startId is 6. + */ + virtual void OnCommand(const AAFwk::Want &want, bool restart, int startId) override; + + /** + * @brief Called when this extension enters the STATE_STOP state. + * + * The extension in the STATE_STOP is being destroyed. + * You can override this function to implement your own processing logic. + */ + virtual void OnStop() override; + + /** + * @brief Called when the system configuration is updated. + * + * @param configuration Indicates the updated configuration information. + */ + void OnConfigurationUpdated(const AppExecFwk::Configuration &configuration) override; + + /** + * @brief Called when extension need dump info. + * + * @param params The params from service. + * @param info The dump info to show. + */ + virtual void Dump(const std::vector ¶ms, std::vector &info) override; + +private: + void ConfigurationUpdated(); + ani_ref CallObjectMethod(bool withResult, const char *name, const char *signature, ...); + sptr OnConnectInner(ani_env *env, ani_object &aniRemoteobj, bool &isAsyncCallback); + + ETSRuntime &etsRuntime_; + std::unique_ptr etsObj_; +}; +} // namespace AbilityRuntime +} // namespace OHOS +#endif // OHOS_ABILITY_RUNTIME_ETS_SERVICE_EXTENSION_H \ No newline at end of file diff --git a/frameworks/ets/ani/service_extension_ability/src/ets_service_extension.cpp b/frameworks/ets/ani/service_extension_ability/src/ets_service_extension.cpp new file mode 100644 index 0000000000000000000000000000000000000000..099d12a309a6e7509b40bfae7926f04fb7b11620 --- /dev/null +++ b/frameworks/ets/ani/service_extension_ability/src/ets_service_extension.cpp @@ -0,0 +1,394 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ets_service_extension.h" + +#include "ability_info.h" +#include "ability_manager_client.h" +#include "ani_common_want.h" +#include "ani_remote_object.h" +#include "configuration_utils.h" +#include "hilog_tag_wrapper.h" +#include "hitrace_meter.h" +#include "js_service_extension_context.h" + +namespace OHOS { +namespace AbilityRuntime { +using namespace OHOS::AppExecFwk; +namespace { +constexpr const char *CLASSNAME_SERVICE_ABILITY = + "L@ohos/app/ability/ServiceExtensionAbility/ServiceExtensionAbility;"; +constexpr const char *NATIVE_ONCONNECT_CALLBACK_SIGNATURE = "L@ohos/rpc/rpc/RemoteObject;:Z"; +constexpr const char *ON_CREATE_SIGNATURE = "L@ohos/app/ability/Want/Want;:V"; +constexpr const char *VOID_SIGNATURE = ":V"; +constexpr const char *ON_CONNECT_SIGNATURE = "L@ohos/app/ability/Want/Want;:Lstd/core/Object;"; +constexpr const char *CHECK_PROMISE_SIGNATURE = "Lstd/core/Object;:Z"; +constexpr const char *CALL_PROMISE_SIGNATURE = "Lstd/core/Object;:Z"; +constexpr const char *ON_DISCONNECT_SIGNATURE = "L@ohos/app/ability/Want/Want;:V"; +constexpr const char *ON_REQUEST_SIGNATURE = "L@ohos/app/ability/Want/Want;D:V"; + +void DisconnectPromiseCallback(ani_env *env, ani_object aniObj) +{ + TAG_LOGD(AAFwkTag::SERVICE_EXT, "DisconnectPromiseCallback"); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null env"); + return; + } + ani_long disconnectCallbackPoint = 0; + ani_status status = ANI_ERROR; + if ((status = env->Object_GetFieldByName_Long(aniObj, "disconnectCallbackPoint", &disconnectCallbackPoint)) != + ANI_OK) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "status : %{public}d", status); + return; + } + auto *callbackInfo = reinterpret_cast *>(disconnectCallbackPoint); + if (callbackInfo == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null callbackInfo"); + return; + } + callbackInfo->Call(); + AppExecFwk::AbilityTransactionCallbackInfo<>::Destroy(callbackInfo); +} + +void ConnectPromiseCallback(ani_env *env, ani_object aniObj, ani_object obj) +{ + TAG_LOGD(AAFwkTag::SERVICE_EXT, "ConnectPromiseCallback"); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null env"); + return; + } + ani_long connectCallbackPoint = 0; + ani_status status = ANI_ERROR; + if ((status = env->Object_GetFieldByName_Long(aniObj, "connectCallbackPoint", &connectCallbackPoint)) != ANI_OK) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "status : %{public}d", status); + return; + } + auto remoteObject = AniGetNativeRemoteObject(env, obj); + if (remoteObject == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null remoteObject"); + } + auto *callbackInfo = + reinterpret_cast> *>(connectCallbackPoint); + if (callbackInfo == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null callbackInfo"); + return; + } + + callbackInfo->Call(remoteObject); + AppExecFwk::AbilityTransactionCallbackInfo>::Destroy(callbackInfo); +} +} // namespace + +EtsServiceExtension *EtsServiceExtension::Create(const std::unique_ptr &runtime) +{ + return new EtsServiceExtension(static_cast(*runtime)); +} + +EtsServiceExtension::EtsServiceExtension(ETSRuntime &etsRuntime) : etsRuntime_(etsRuntime) {} +EtsServiceExtension::~EtsServiceExtension() +{ + TAG_LOGD(AAFwkTag::SERVICE_EXT, "EtsServiceExtension destory"); + auto context = GetContext(); + if (context) { + context->Unbind(); + } +} + +void EtsServiceExtension::Init(const std::shared_ptr &record, + const std::shared_ptr &application, std::shared_ptr &handler, + const sptr &token) +{ + TAG_LOGD(AAFwkTag::SERVICE_EXT, "EtsServiceExtension init"); + if ((token == nullptr) || (application == nullptr) || (handler == nullptr) || (record == nullptr)) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "init failed, some obj null"); + return; + } + Extension::Init(record, application, handler, token); + if (Extension::abilityInfo_ == nullptr || Extension::abilityInfo_->srcEntrance.empty()) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "EtsServiceExtension Init abilityInfo error"); + return; + } + std::string srcPath(Extension::abilityInfo_->moduleName + "/"); + srcPath.append(Extension::abilityInfo_->srcEntrance); + auto pos = srcPath.rfind("."); + if (pos != std::string::npos) { + srcPath.erase(pos); + srcPath.append(".abc"); + } + std::string moduleName(Extension::abilityInfo_->moduleName); + moduleName.append("::").append(abilityInfo_->name); + etsObj_ = etsRuntime_.LoadModule(moduleName, srcPath, abilityInfo_->hapPath, + abilityInfo_->compileMode == AppExecFwk::CompileMode::ES_MODULE, false, abilityInfo_->srcEntrance); + if (etsObj_ == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null etsObj"); + return; + } + auto env = etsRuntime_.GetAniEnv(); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null env"); + return; + } + std::array functions = { + ani_native_function { + "nativeOnDisconnectCallback", VOID_SIGNATURE, reinterpret_cast(DisconnectPromiseCallback) }, + ani_native_function { "nativeOnConnectCallback", NATIVE_ONCONNECT_CALLBACK_SIGNATURE, + reinterpret_cast(ConnectPromiseCallback) }, + }; + ani_class cls = nullptr; + ani_status status = ANI_ERROR; + if ((status = env->FindClass(CLASSNAME_SERVICE_ABILITY, &cls)) != ANI_OK) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "status: %{public}d", status); + return; + } + if ((status = env->Class_BindNativeMethods(cls, functions.data(), functions.size())) != ANI_OK) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "Class_BindNativeMethods is fail %{public}d", status); + return; + } +} + +void EtsServiceExtension::OnStart(const AAFwk::Want &want) +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + TAG_LOGD(AAFwkTag::SERVICE_EXT, "OnStart"); + auto env = etsRuntime_.GetAniEnv(); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "env not found Ability.ets"); + return; + } + ani_ref wantRef = OHOS::AppExecFwk::WrapWant(env, want); + if (wantRef == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null wantRef"); + return; + } + + CallObjectMethod(false, "onCreate", ON_CREATE_SIGNATURE, wantRef); + TAG_LOGD(AAFwkTag::SERVICE_EXT, "end"); +} + +void EtsServiceExtension::OnStop() +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + TAG_LOGD(AAFwkTag::SERVICE_EXT, "OnStop"); + ServiceExtension::OnStop(); + CallObjectMethod(false, "onDestroy", VOID_SIGNATURE); + TAG_LOGD(AAFwkTag::SERVICE_EXT, "end"); +} + +sptr EtsServiceExtension::OnConnect(const AAFwk::Want &want) +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + TAG_LOGD(AAFwkTag::SERVICE_EXT, "OnConnect"); + Extension::OnConnect(want); + auto env = etsRuntime_.GetAniEnv(); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null env"); + return nullptr; + } + ani_ref wantRef = OHOS::AppExecFwk::WrapWant(env, want); + if (wantRef == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null wantRef"); + return nullptr; + } + ani_ref result = CallObjectMethod(true, "onConnect", ON_CONNECT_SIGNATURE, wantRef); + auto obj = reinterpret_cast(result); + auto remoteObj = AniGetNativeRemoteObject(env, obj); + if (remoteObj == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "remoteObj null"); + return nullptr; + } + TAG_LOGD(AAFwkTag::SERVICE_EXT, "end"); + return remoteObj; +} + +sptr EtsServiceExtension::OnConnect(const AAFwk::Want &want, + AppExecFwk::AbilityTransactionCallbackInfo> *callbackInfo, bool &isAsyncCallback) +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + TAG_LOGD(AAFwkTag::SERVICE_EXT, "OnConnect"); + Extension::OnConnect(want); + auto env = etsRuntime_.GetAniEnv(); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null env"); + return nullptr; + } + ani_ref wantRef = OHOS::AppExecFwk::WrapWant(env, want); + if (wantRef == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null wantRef"); + return nullptr; + } + ani_long connectCallbackPoint = (ani_long)callbackInfo; + ani_status status = ANI_ERROR; + ani_field callbackField = nullptr; + if ((status = env->Class_FindField(etsObj_->aniCls, "connectCallbackPoint", &callbackField)) != ANI_OK) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "status : %{public}d", status); + return nullptr; + } + if ((status = env->Object_SetField_Long(etsObj_->aniObj, callbackField, connectCallbackPoint)) != ANI_OK) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "status : %{public}d", status); + return nullptr; + } + ani_ref aniRemoteRef = CallObjectMethod(true, "onConnect", ON_CONNECT_SIGNATURE, wantRef); + auto aniRemoteobj = reinterpret_cast(aniRemoteRef); + ani_method method {}; + if ((status = env->Class_FindMethod(etsObj_->aniCls, "checkPromise", CHECK_PROMISE_SIGNATURE, &method)) != ANI_OK) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "status : %{public}d", status); + return nullptr; + } + ani_boolean isPromise = false; + if ((status = env->Object_CallMethod_Boolean(etsObj_->aniObj, method, &isPromise, aniRemoteobj)) != ANI_OK) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "status : %{public}d", status); + return nullptr; + } + if (!isPromise) { + isAsyncCallback = false; + auto remoteObj = AniGetNativeRemoteObject(env, aniRemoteobj); + if (remoteObj == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null remoteObj"); + } + return remoteObj; + } + return OnConnectInner(env, aniRemoteobj, isAsyncCallback); +} + +sptr EtsServiceExtension::OnConnectInner(ani_env *env, ani_object &aniRemoteobj, bool &isAsyncCallback) +{ + ani_status status = ANI_ERROR; + ani_method method {}; + if ((status = env->Class_FindMethod(etsObj_->aniCls, "callPromise", CALL_PROMISE_SIGNATURE, &method)) != ANI_OK) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "status : %{public}d", status); + return nullptr; + } + ani_boolean callResult = false; + if ((status = env->Object_CallMethod_Boolean(etsObj_->aniObj, method, &callResult, aniRemoteobj)) != ANI_OK) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "status : %{public}d", status); + return nullptr; + } + isAsyncCallback = callResult; + return nullptr; +} + +void EtsServiceExtension::OnDisconnect(const AAFwk::Want &want) +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + TAG_LOGD(AAFwkTag::SERVICE_EXT, "OnDisconnect"); + auto env = etsRuntime_.GetAniEnv(); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null env"); + return; + } + ani_ref wantRef = OHOS::AppExecFwk::WrapWant(env, want); + if (wantRef == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null wantRef"); + return; + } + CallObjectMethod(false, "onDisconnect", ON_DISCONNECT_SIGNATURE, wantRef); + TAG_LOGD(AAFwkTag::SERVICE_EXT, "end"); +} + +void EtsServiceExtension::OnDisconnect( + const AAFwk::Want &want, AppExecFwk::AbilityTransactionCallbackInfo<> *callbackInfo, bool &isAsyncCallback) +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + TAG_LOGD(AAFwkTag::SERVICE_EXT, "OnDisconnect"); + auto env = etsRuntime_.GetAniEnv(); + if (env) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null env"); + return; + } + ani_ref wantRef = OHOS::AppExecFwk::WrapWant(env, want); + if (wantRef == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null wantRef"); + return; + } + if (callbackInfo == nullptr) { + isAsyncCallback = false; + OnDisconnect(want); + return; + } + ani_long disconnectCallbackPoint = (ani_long)callbackInfo; + ani_status status = ANI_ERROR; + ani_field field = nullptr; + if ((status = env->Class_FindField(etsObj_->aniCls, "disconnectCallbackPoint", &field)) != ANI_OK) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "status : %{public}d", status); + return; + } + if ((status = env->Object_SetField_Long(etsObj_->aniObj, field, disconnectCallbackPoint)) != ANI_OK) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "status : %{public}d", status); + return; + } + CallObjectMethod(false, "callOnDisconnect", ON_DISCONNECT_SIGNATURE, wantRef); +} + +void EtsServiceExtension::OnCommand(const AAFwk::Want &want, bool restart, int startId) +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + TAG_LOGD(AAFwkTag::SERVICE_EXT, "OnCommand"); + auto env = etsRuntime_.GetAniEnv(); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null env"); + return; + } + ani_ref wantRef = OHOS::AppExecFwk::WrapWant(env, want); + if (wantRef == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null wantRef"); + return; + } + ani_int iStartId = static_cast(startId); + CallObjectMethod(false, "onRequest", ON_REQUEST_SIGNATURE, wantRef, iStartId); + TAG_LOGD(AAFwkTag::SERVICE_EXT, "end"); + return; +} + +ani_ref EtsServiceExtension::CallObjectMethod(bool withResult, const char *name, const char *signature, ...) +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, std::string("CallObjectMethod:") + name); + ani_status status = ANI_ERROR; + ani_method method = nullptr; + auto env = etsRuntime_.GetAniEnv(); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null env"); + return nullptr; + } + if ((status = env->Class_FindMethod(etsObj_->aniCls, name, signature, &method)) != ANI_OK) { + return nullptr; + } + if (method == nullptr) { + return nullptr; + } + ani_ref res = nullptr; + va_list args; + if (withResult) { + va_start(args, signature); + if ((status = env->Object_CallMethod_Ref_V(etsObj_->aniObj, method, &res, args)) != ANI_OK) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "status : %{public}d", status); + return nullptr; + } + va_end(args); + return res; + } + va_start(args, signature); + if ((status = env->Object_CallMethod_Void_V(etsObj_->aniObj, method, args)) != ANI_OK) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "status : %{public}d", status); + } + va_end(args); + return nullptr; +} +void EtsServiceExtension::OnConfigurationUpdated(const AppExecFwk::Configuration &configuration) {} + +void EtsServiceExtension::ConfigurationUpdated() {} + +void EtsServiceExtension::Dump(const std::vector ¶ms, std::vector &info) {} +} // namespace AbilityRuntime +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/ets/ani/ui_extension_ability/include/ets_ui_extension.h b/frameworks/ets/ani/ui_extension_ability/include/ets_ui_extension.h index 113de735159448400d5f92008cf7e4c225fb274e..09458863ad71f79362b2736513b67c2234bc0e49 100644 --- a/frameworks/ets/ani/ui_extension_ability/include/ets_ui_extension.h +++ b/frameworks/ets/ani/ui_extension_ability/include/ets_ui_extension.h @@ -177,10 +177,8 @@ public: void ConfigurationUpdated(); private: - virtual void BindContext(ani_env *env, std::shared_ptr want, - const std::shared_ptr &application); - ani_object CreateETSContext(ani_env *env, std::shared_ptr context, - int32_t screenMode, const std::shared_ptr &application); + virtual void BindContext(ani_env *env, std::shared_ptr want); + ani_object CreateETSContext(ani_env *env, std::shared_ptr context, int32_t screenMode); bool CallObjectMethod(bool withResult, const char* name, const char* signature, ...); diff --git a/frameworks/ets/ani/ui_extension_ability/include/ets_ui_extension_content_session.h b/frameworks/ets/ani/ui_extension_ability/include/ets_ui_extension_content_session.h index 877ccd402b59d5b19c4ad51eb401703201b6e789..a7828e853b5fe8815f3fd0d910852d7e0a43071e 100644 --- a/frameworks/ets/ani/ui_extension_ability/include/ets_ui_extension_content_session.h +++ b/frameworks/ets/ani/ui_extension_ability/include/ets_ui_extension_content_session.h @@ -19,7 +19,7 @@ #include "session_info.h" #include "start_options.h" #include "window.h" -#include "sts_runtime.h" +#include "ets_runtime.h" namespace OHOS { namespace AbilityRuntime { @@ -66,7 +66,7 @@ public: sptr uiWindow); virtual ~EtsUIExtensionContentSession() = default; static EtsUIExtensionContentSession* GetEtsContentSession(ani_env* env, ani_object obj); - static ani_object CreateStsUIExtensionContentSession(ani_env* env, + static ani_object CreateEtsUIExtensionContentSession(ani_env* env, sptr sessionInfo, sptr uiWindow, std::weak_ptr context, std::shared_ptr& abilityResultListeners, diff --git a/frameworks/ets/ani/ui_extension_ability/include/ets_ui_extension_context.h b/frameworks/ets/ani/ui_extension_ability/include/ets_ui_extension_context.h index ef7e5f679794bcce9c32a4cdab75df247903472a..802402b7b05b4777f377a255a2b09c4ad07c1410 100644 --- a/frameworks/ets/ani/ui_extension_ability/include/ets_ui_extension_context.h +++ b/frameworks/ets/ani/ui_extension_ability/include/ets_ui_extension_context.h @@ -15,7 +15,7 @@ #ifndef OHOS_ABILITY_RUNTIME_ETS_UI_EXTENSION_CONTEXT_H #define OHOS_ABILITY_RUNTIME_ETS_UI_EXTENSION_CONTEXT_H -#include "sts_runtime.h" +#include "ets_runtime.h" #include #include #include @@ -24,9 +24,7 @@ #include "hitrace_meter.h" #include "ohos_application.h" -ani_object CreateEtsUIExtensionContext(ani_env *env, - std::shared_ptr context, - const std::shared_ptr &application); +ani_object CreateEtsUIExtensionContext(ani_env *env, std::shared_ptr context); class EtsUIExtensionContext final { public: @@ -38,7 +36,7 @@ public: static void TerminateSelfWithResultSync(ani_env *env, ani_object obj, ani_object abilityResult, ani_object callback); static void EtsCreatExtensionContext(ani_env* aniEnv, ani_class contextClass, ani_object contextObj, - void* applicationCtxRef, std::shared_ptr context); + std::shared_ptr context); private: static void BindExtensionInfo(ani_env* aniEnv, ani_class contextClass, ani_object contextObj, std::shared_ptr context, std::shared_ptr abilityInfo); diff --git a/frameworks/ets/ani/ui_extension_ability/src/ets_ui_extension.cpp b/frameworks/ets/ani/ui_extension_ability/src/ets_ui_extension.cpp index 0361069d854ef0ca75d57f55d8094f9a7646767d..b992ef6bff4ebab65eb958fd34e04339e227bce5 100644 --- a/frameworks/ets/ani/ui_extension_ability/src/ets_ui_extension.cpp +++ b/frameworks/ets/ani/ui_extension_ability/src/ets_ui_extension.cpp @@ -24,8 +24,6 @@ #include "context.h" #include "hitrace_meter.h" #include "hilog_tag_wrapper.h" -#include "insight_intent_executor_info.h" -#include "insight_intent_executor_mgr.h" #include "int_wrapper.h" #include "ets_runtime.h" #include "ani_common_want.h" @@ -132,19 +130,18 @@ void EtsUIExtension::Init(const std::shared_ptr &record, if ((status = env->Class_BindNativeMethods(etsObj_->aniCls, functions.data(), functions.size())) != ANI_OK) { TAG_LOGE(AAFwkTag::UI_EXT, "status: %{public}d", status); } - BindContext(env, record->GetWant(), application); + BindContext(env, record->GetWant()); RegisterDisplayInfoChangedListener(); } -ani_object EtsUIExtension::CreateETSContext(ani_env* env, std::shared_ptr context, - int32_t screenMode, const std::shared_ptr &application) +ani_object EtsUIExtension::CreateETSContext(ani_env* env, + std::shared_ptr context, int32_t screenMode) { - ani_object obj = CreateEtsUIExtensionContext(env, context, application); + ani_object obj = CreateEtsUIExtensionContext(env, context); return obj; } -void EtsUIExtension::BindContext(ani_env*env, std::shared_ptr want, - const std::shared_ptr &application) +void EtsUIExtension::BindContext(ani_env*env, std::shared_ptr want) { if (env == nullptr || want == nullptr) { TAG_LOGE(AAFwkTag::UI_EXT, "Want info is null or env is null"); @@ -158,7 +155,7 @@ void EtsUIExtension::BindContext(ani_env*env, std::shared_ptr want, } int32_t screenMode = want->GetIntParam(AAFwk::SCREEN_MODE_KEY, AAFwk::IDLE_SCREEN_MODE); - ani_object contextObj = CreateETSContext(env, context, screenMode, application); + ani_object contextObj = CreateETSContext(env, context, screenMode); if (contextObj == nullptr) { TAG_LOGE(AAFwkTag::UI_EXT, "null contextObj"); return; diff --git a/frameworks/ets/ani/ui_extension_ability/src/ets_ui_extension_context.cpp b/frameworks/ets/ani/ui_extension_ability/src/ets_ui_extension_context.cpp index 44025a26d3e7eb631c955568147076dc950736ba..34dc8e4d11dcf6d803aa02b257d1f776ba8cd773 100644 --- a/frameworks/ets/ani/ui_extension_ability/src/ets_ui_extension_context.cpp +++ b/frameworks/ets/ani/ui_extension_ability/src/ets_ui_extension_context.cpp @@ -19,7 +19,6 @@ #include "ability_manager_client.h" #include "ets_context_utils.h" #include "ets_error_utils.h" -#include "ets_ui_extension_common.h" const char *INVOKE_METHOD_NAME = "invoke"; const char *UI_EXTENSION_CONTEXT_CLASS_NAME = "Lapplication/UIExtensionContext/UIExtensionContext;"; @@ -45,8 +44,8 @@ void EtsUIExtensionContext::TerminateSelfSync(ani_env *env, ani_object obj, ani_ return; } ret = ((OHOS::AbilityRuntime::UIExtensionContext*)nativeContextLong)->TerminateSelf(); - AppExecFwk::AsyncCallback(env, callback, - CreateEtsErrorByNativeErr(env, static_cast(ret)), nullptr); + OHOS::AppExecFwk::AsyncCallback(env, callback, + OHOS::AbilityRuntime::CreateEtsErrorByNativeErr(env, static_cast(ret)), nullptr); } void EtsUIExtensionContext::TerminateSelfWithResultSync(ani_env *env, ani_object obj, @@ -86,8 +85,8 @@ void EtsUIExtensionContext::TerminateSelfWithResultSync(ani_env *env, ani_objec TAG_LOGE(AAFwkTag::UI_EXT, "TerminateSelf failed, errorCode is %{public}d", ret); return; } - AppExecFwk::AsyncCallback(env, callback, - CreateEtsErrorByNativeErr(env, static_cast(ret)), nullptr); + OHOS::AppExecFwk::AsyncCallback(env, callback, + OHOS::AbilityRuntime::CreateEtsErrorByNativeErr(env, static_cast(ret)), nullptr); } void EtsUIExtensionContext::BindExtensionInfo(ani_env* aniEnv, ani_class contextClass, ani_object contextObj, @@ -124,15 +123,13 @@ void EtsUIExtensionContext::BindExtensionInfo(ani_env* aniEnv, ani_class context } void EtsUIExtensionContext::EtsCreatExtensionContext(ani_env* aniEnv, ani_class contextClass, ani_object contextObj, - void* applicationCtxRef, std::shared_ptr context) + std::shared_ptr context) { - OHOS::AbilityRuntime::ContextUtil::EtsCreatContext(aniEnv, contextClass, contextObj, applicationCtxRef, context); + OHOS::AbilityRuntime::ContextUtil::CreateEtsBaseContext(aniEnv, contextClass, contextObj, context); BindExtensionInfo(aniEnv, contextClass, contextObj, context, context->GetAbilityInfo()); } -ani_object CreateEtsUIExtensionContext(ani_env *env, - std::shared_ptr context, - const std::shared_ptr &application) +ani_object CreateEtsUIExtensionContext(ani_env *env, std::shared_ptr context) { TAG_LOGD(AAFwkTag::UI_EXT, "called"); ani_class cls = nullptr; @@ -171,13 +168,6 @@ ani_object CreateEtsUIExtensionContext(ani_env *env, TAG_LOGE(AAFwkTag::UI_EXT, "status: %{public}d", status); return nullptr; } - - // bind parent context - if (application == nullptr) { - TAG_LOGE(AAFwkTag::UI_EXT, "application null"); - return nullptr; - } - EtsUIExtensionContext::EtsCreatExtensionContext(env, cls, contextObj, - application->GetApplicationCtxObjRef(), context); + EtsUIExtensionContext::EtsCreatExtensionContext(env, cls, contextObj, context); return contextObj; } diff --git a/frameworks/ets/ets/@ohos.app.ability.ServiceExtensionAbility.ets b/frameworks/ets/ets/@ohos.app.ability.ServiceExtensionAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..c17298b63ebf2e620d569f7140218d4929ee888b --- /dev/null +++ b/frameworks/ets/ets/@ohos.app.ability.ServiceExtensionAbility.ets @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import rpc from '@ohos.rpc'; +import Want from '@ohos.app.ability.Want'; +import ServiceExtensionContext from 'application.ServiceExtensionContext'; +import { Configuration } from '@ohos.app.ability.Configuration' +import hilog from '@ohos.hilog'; + +class MyService extends rpc.RemoteObject { + constructor(descriptor: string) { + super(descriptor); + } + + public onRemoteMessageRequest( + code: number, + data: rpc.MessageSequence, + reply: rpc.MessageSequence, + options: rpc.MessageOption + ): boolean | Promise { + return false; + } +} + +export default class ServiceExtensionAbility { + private connectCallbackPoint: long; + + private native nativeOnConnectCallback(service: rpc.RemoteObject): boolean; + + private checkPromise(obj: NullishType): boolean { + if (obj instanceof Promise) { + return true; + } + return false; + } + + private callPromise(p: Promise): boolean { + let remoteObj: rpc.RemoteObject = await p; + return this.nativeOnConnectCallback(remoteObj); + } + + private isOnDisconnectAsync: boolean = true; + private disconnectCallbackPoint: long; + + private native nativeOnDisconnectCallback(): void; + + private callOnDisconnect(want: Want): void { + let p = this.onDisconnectAsync(want); + if (this.isOnDisconnectAsync) { + p.then((a: undefined): void => { + this.nativeOnDisconnectCallback(); + }); + } else { + this.onDisconnect(want); + } + } + + launchWant: Want = new Want(); + lastRequestWant: Want = new Want(); + context: ServiceExtensionContext = {}; + + onCreate(want: Want): void { + } + + onDestroy(): void { + } + + onRequest(want: Want, startld: double): void { + } + + onConnect(want: Want): rpc.RemoteObject | Promise { + let myService: rpc.RemoteObject = new MyService("onConnect"); + return myService; + } + + onDisconnect(want: Want): void { + } + + onDisconnectAsync(want: Want): Promise { + console.log("onDisconnectAsync"); + this.isOnDisconnectAsync = false; + return new Promise((resolve: (a: undefined) => void, reject: (err: Error) => void): void => { + }); + } +} \ No newline at end of file diff --git a/frameworks/ets/ets/BUILD.gn b/frameworks/ets/ets/BUILD.gn index d6d73e18eec3a85424c93cee108759a3f98d75d4..8a524a4c44e18567ebae5229eaa7d6fc0040ff65 100644 --- a/frameworks/ets/ets/BUILD.gn +++ b/frameworks/ets/ets/BUILD.gn @@ -161,6 +161,65 @@ ohos_prebuilt_etc("ability_runtime_extension_context_abc_etc") { deps = [ ":ability_runtime_extension_context_abc" ] } +generate_static_abc("service_extension_ability") { + base_url = "./" + files = [ + "./@ohos.app.ability.ServiceExtensionAbility.ets", + "./application/ServiceExtensionContext.ets", + ] + + is_boot_abc = "True" + device_dst_file = "/system/framework/service_extension_ability.abc" +} + +ohos_prebuilt_etc("service_extension_ability_abc_etc") { + source = "$target_out_dir/service_extension_ability.abc" + module_install_dir = "framework" + subsystem_name = "ability" + part_name = "ability_runtime" + deps = [ ":service_extension_ability" ] +} + +generate_static_abc("ui_extension_ability_ani_abc") { + base_url = "./" + + files = [ + "./application/UIExtensionContext.ets", + "./@ohos.app.ability.UIExtensionAbility.ets", + "./@ohos.app.ability.UIExtensionContentSession.ets", + ] + + dst_file = "$target_out_dir/ui_extension_ability_ani.abc" + out_puts = [ "$target_out_dir/ui_extension_ability_ani.abc" ] + + is_boot_abc = "True" + device_dst_file = "/system/framework/ui_extension_ability_ani.abc" +} + +ohos_prebuilt_etc("ui_extension_ability_ani_etc") { + source = "$target_out_dir/ui_extension_ability_ani.abc" + deps = [ ":ui_extension_ability_ani_abc" ] + module_install_dir = "framework" + subsystem_name = "ability" + part_name = "ability_runtime" +} + +generate_static_abc("ability_runtime_ability_stage_abc") { + base_url = "./" + files = [ "./@ohos.app.ability.AbilityStage.ets" ] + + is_boot_abc = "True" + device_dst_file = "/system/framework/ability_runtime_ability_stage_abc.abc" +} + +ohos_prebuilt_etc("ability_runtime_ability_stage_abc_etc") { + source = "$target_out_dir/ability_runtime_ability_stage_abc.abc" + module_install_dir = "framework" + subsystem_name = "ability" + part_name = "ability_runtime" + deps = [ ":ability_runtime_ability_stage_abc" ] +} + generate_static_abc("ability_runtime_configuration_abc") { base_url = "./" files = [ "./@ohos.app.ability.Configuration.ets" ] @@ -214,15 +273,18 @@ group("ets_packages") { deps = [ ":ability_runtime_ability_result_abc_etc", ":ability_runtime_ability_constant_abc_etc", + ":ability_runtime_ability_stage_abc_etc", ":ability_runtime_ability_utils_abc_etc", - ":ability_runtime_base_context_abc_etc", ":ability_runtime_application_context_abc_etc", + ":ability_runtime_base_context_abc_etc", ":ability_runtime_configuration_abc_etc", ":ability_runtime_configuration_constant_abc_etc", ":ability_runtime_context_abc_etc", + ":ability_runtime_extension_context_abc_etc", ":ability_runtime_start_options_abc_etc", ":ability_runtime_want_abc_etc", ":ability_runtime_want_constant_abc_etc", - ":ability_runtime_extension_context_abc_etc", + ":service_extension_ability_abc_etc", + ":ui_extension_ability_ani_etc", ] } diff --git a/frameworks/ets/ets/application/ExtensionContext.ets b/frameworks/ets/ets/application/ExtensionContext.ets index 2d46b66d2add1dcda7e2c90ec98db4ac75b47931..4b6cbf03130961de7de01973d59e6dc19dc2f451 100644 --- a/frameworks/ets/ets/application/ExtensionContext.ets +++ b/frameworks/ets/ets/application/ExtensionContext.ets @@ -17,6 +17,9 @@ import Context from 'application.Context' import {ExtensionAbilityInfo} from 'bundleManager.ExtensionAbilityInfo' export default class ExtensionContext extends Context { + static { + loadLibrary("context_ani"); + } extensionAbilityInfo: ExtensionAbilityInfo; native constructor(); constructor(extensionAbilityInfo: ExtensionAbilityInfo) { diff --git a/frameworks/ets/ets/application/ServiceExtensionContext.ets b/frameworks/ets/ets/application/ServiceExtensionContext.ets new file mode 100644 index 0000000000000000000000000000000000000000..8c9fe395ffa688932f94de366ebf8313b90d9514 --- /dev/null +++ b/frameworks/ets/ets/application/ServiceExtensionContext.ets @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import ExtensionContext from 'application.ExtensionContext' + +export default class ServiceExtensionContext extends ExtensionContext { + +} \ No newline at end of file diff --git a/frameworks/ets/ets/utils/AbilityUtils.ets b/frameworks/ets/ets/utils/AbilityUtils.ets index 573c5d3a20767a270ff0fff7f770c905f7817cd7..989136ed5b6084841371ee0d262242d63128337f 100644 --- a/frameworks/ets/ets/utils/AbilityUtils.ets +++ b/frameworks/ets/ets/utils/AbilityUtils.ets @@ -12,13 +12,25 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +import { BusinessError, AsyncCallback } from '@ohos.base'; import hilog from '@ohos.hilog' const DOMAIN_ID = 0xD001300; const TAG = 'AbilityUtils'; const LEVEL = 100; +export default class AsyncCallbackWrapper { + private myFun_:AsyncCallback = (err: BusinessError, data: T) => {} + + constructor(myFun:AsyncCallback){ + this.myFun_ = myFun; + } + + invoke(err: BusinessError, data: T) : void { + this.myFun_(err, data); + } +} + export class AbilityUtils { public static getClassType(obj: Object): ClassType | undefined { try { diff --git a/frameworks/native/ability/native/BUILD.gn b/frameworks/native/ability/native/BUILD.gn index f250b62c7ee429b750eaf3f11e657f9017f385f6..ab46d7ff5385a4ef309f273a9c5c0d44ed1840e9 100644 --- a/frameworks/native/ability/native/BUILD.gn +++ b/frameworks/native/ability/native/BUILD.gn @@ -93,9 +93,7 @@ config("app_service_extension_public_config") { "${ability_runtime_services_path}/common/include", ] if (ability_runtime_graphics) { - defines = [ - "SUPPORT_GRAPHICS", - ] + defines = [ "SUPPORT_GRAPHICS" ] } } @@ -699,8 +697,8 @@ ohos_shared_library("insight_intent_executor") { sources = [ "${ability_runtime_native_path}/ability/native/insight_intent_executor/insight_intent_executor.cpp", "${ability_runtime_native_path}/ability/native/insight_intent_executor/insight_intent_executor_mgr.cpp", - "${ability_runtime_native_path}/ability/native/insight_intent_executor/js_insight_intent_executor.cpp", "${ability_runtime_native_path}/ability/native/insight_intent_executor/js_insight_intent_entry.cpp", + "${ability_runtime_native_path}/ability/native/insight_intent_executor/js_insight_intent_executor.cpp", "${ability_runtime_native_path}/ability/native/insight_intent_executor/js_insight_intent_func.cpp", "${ability_runtime_native_path}/ability/native/insight_intent_executor/js_insight_intent_page.cpp", "${ability_runtime_native_path}/ability/native/insight_intent_executor/js_insight_intent_utils.cpp", @@ -958,10 +956,10 @@ ohos_shared_library("form_extension") { sources = [ "${ability_runtime_native_path}/ability/native/form_extension.cpp", + "${ability_runtime_native_path}/ability/native/form_runtime/cj_form_extension_instance.cpp", "${ability_runtime_native_path}/ability/native/form_runtime/form_extension_provider_client.cpp", "${ability_runtime_native_path}/ability/native/form_runtime/js_form_extension.cpp", "${ability_runtime_native_path}/ability/native/form_runtime/js_form_extension_context.cpp", - "${ability_runtime_native_path}/ability/native/form_runtime/cj_form_extension_instance.cpp", "${ability_runtime_native_path}/appkit/ability_runtime/form_extension_context.cpp", ] @@ -1032,8 +1030,8 @@ ohos_shared_library("cj_form_extension") { ":form_extension", "${ability_runtime_innerkits_path}/runtime:runtime", "${ability_runtime_native_path}/ability:ability_context_native", - "${ability_runtime_native_path}/appkit:app_context", "${ability_runtime_native_path}/ability:cj_ability_context_native", + "${ability_runtime_native_path}/appkit:app_context", "${ability_runtime_path}/frameworks/cj/ffi:cj_ability_ffi", ] @@ -1113,6 +1111,8 @@ ohos_shared_library("service_extension") { defines = [ "AMS_LOG_TAG = \"Ability\"" ] defines += [ "AMS_LOG_DOMAIN = 0xD001300" ] include_dirs = [ + "${ability_runtime_path}/frameworks/ets/ani/ani_common/include", + "${ability_runtime_path}/frameworks/ets/ani/service_extension_ability/include", "${ability_runtime_path}/interfaces/kits/native/ability/native", "${ability_runtime_path}/interfaces/kits/native/appkit/ability_runtime", "${ability_runtime_path}/utils/global/freeze/include", @@ -1123,6 +1123,7 @@ ohos_shared_library("service_extension") { "${ability_runtime_native_path}/ability/native/js_service_extension_context.cpp", "${ability_runtime_native_path}/ability/native/service_extension.cpp", "${ability_runtime_native_path}/appkit/ability_runtime/service_extension_context.cpp", + "${ability_runtime_path}/frameworks/ets/ani/service_extension_ability/src/ets_service_extension.cpp", ] deps = [ @@ -1139,12 +1140,14 @@ ohos_shared_library("service_extension") { "${ability_runtime_native_path}/appkit:app_context", "${ability_runtime_native_path}/insight_intent/insight_intent_context:insightintentcontext", "${ability_runtime_path}/utils/global/freeze:freeze_util", + "${ability_runtime_path}/frameworks/ets/ani/ani_common:ani_common", ] external_deps = [ "ability_base:configuration", "ability_base:want", "ability_base:zuri", + "bundle_framework:libappexecfwk_common", "c_utils:utils", "common_event_service:cesfwk_innerkits", "eventhandler:libeventhandler", @@ -1152,7 +1155,9 @@ ohos_shared_library("service_extension") { "hitrace:hitrace_meter", "ipc:ipc_core", "ipc:ipc_napi", + "ipc:rpc_ani", "napi:ace_napi", + "runtime_core:ani", "safwk:system_ability_fwk", "samgr:samgr_proxy", ] @@ -1667,7 +1672,13 @@ config("ui_extension_public_config") { } ohos_shared_library("ui_extension") { - include_dirs = [ "${ability_runtime_path}/interfaces/kits/native/ability/native/ui_service_extension_ability/connection" ] + include_dirs = [ + "${ability_runtime_path}/interfaces/kits/native/ability/native/ui_service_extension_ability/connection", + "${ability_runtime_path}/interfaces/kits/native/ability/native/ui_service_extension_ability/connection", + "${ability_runtime_path}/frameworks/ets/ani/ani_common/include", + "${ability_runtime_path}/frameworks/ets/ani/ui_extension_ability/include", + "${ability_runtime_path}/frameworks/ets/ani/enum_convert", + ] sources = [ "${ability_runtime_native_path}/ability/native/ui_extension_ability/js_embeddable_ui_ability_context.cpp", "${ability_runtime_native_path}/ability/native/ui_extension_ability/js_ui_extension.cpp", @@ -1678,6 +1689,8 @@ ohos_shared_library("ui_extension") { "${ability_runtime_native_path}/ability/native/ui_extension_base/js_uiservice_uiext_connection.cpp", "${ability_runtime_native_path}/ability/native/ui_extension_base/ui_extension_context.cpp", "${ability_runtime_native_path}/ability/native/ui_extension_base/ui_extension_servicehost_stub_impl.cpp", + "${ability_runtime_path}/frameworks/ets/ani/ui_extension_ability/src/ets_ui_extension_content_session.cpp", + "${ability_runtime_path}/frameworks/ets/ani/ui_extension_ability/src/ets_ui_extension_context.cpp", ] public_configs = [ ":ui_extension_public_config" ] @@ -1696,6 +1709,7 @@ ohos_shared_library("ui_extension") { "${ability_runtime_native_path}/ability/native:insight_intent_executor", "${ability_runtime_native_path}/appkit:app_context", "${ability_runtime_native_path}/appkit:app_context_utils", + "${ability_runtime_path}/frameworks/ets/ani/ani_common:ani_common", ] external_deps = [ @@ -1706,6 +1720,7 @@ ohos_shared_library("ui_extension") { "access_token:libaccesstoken_sdk", "access_token:libtokenid_sdk", "ace_engine:ace_uicontent", + "bundle_framework:bms_ani_common", "c_utils:utils", "eventhandler:libeventhandler", "hilog:libhilog", @@ -1714,6 +1729,7 @@ ohos_shared_library("ui_extension") { "ipc:ipc_napi", "napi:ace_napi", "window_manager:embeddablewindowstage_kit", + "window_manager:embeddablewindowstageani_kit", "window_manager:extensionwindow_napi", "window_manager:windowstage_kit", ] diff --git a/frameworks/native/ability/native/service_extension.cpp b/frameworks/native/ability/native/service_extension.cpp index 0838b03f9aa3437b08bcb5bc1047d4e7b1c0d9df..cbf2ad871c835fa25d94949c6befee59f818e352 100644 --- a/frameworks/native/ability/native/service_extension.cpp +++ b/frameworks/native/ability/native/service_extension.cpp @@ -21,6 +21,7 @@ #include "js_service_extension.h" #include "runtime.h" #include "service_extension_context.h" +#include "ets_service_extension.h" namespace OHOS { namespace AbilityRuntime { @@ -46,7 +47,8 @@ ServiceExtension* ServiceExtension::Create(const std::unique_ptr& runti switch (runtime->GetLanguage()) { case Runtime::Language::JS: return JsServiceExtension::Create(runtime); - + case Runtime::Language::ETS: + return EtsServiceExtension::Create(runtime); default: return new ServiceExtension(); }