diff --git a/frameworks/ets/ani/service_extension_ability/include/sts_service_extension.h b/frameworks/ets/ani/service_extension_ability/include/sts_service_extension.h index f566358d0c3a6c5d6cfd2888d90e6d34c6ea7d71..c8c70b0f99d5026afff8bb569e8d2a3030c25de6 100644 --- a/frameworks/ets/ani/service_extension_ability/include/sts_service_extension.h +++ b/frameworks/ets/ani/service_extension_ability/include/sts_service_extension.h @@ -178,6 +178,8 @@ private: void ListenWMS(); + sptr OnConnectInner(ani_env* env, ani_object &aniRemoteobj, bool &isAsyncCallback); + STSRuntime& stsRuntime_; std::unique_ptr stsObj_; std::shared_ptr shellContextRef_ = nullptr; diff --git a/frameworks/ets/ani/service_extension_ability/src/sts_service_extension.cpp b/frameworks/ets/ani/service_extension_ability/src/sts_service_extension.cpp index 811d845ffd98b745c073a23553845b159b736f61..5696f344b38bbd0928a9865dd0584242d7e1e2ba 100644 --- a/frameworks/ets/ani/service_extension_ability/src/sts_service_extension.cpp +++ b/frameworks/ets/ani/service_extension_ability/src/sts_service_extension.cpp @@ -65,7 +65,7 @@ void DisconnectPromiseCallback(ani_env* env, ani_object aniObj) void ConnectPromiseCallback(ani_env* env, ani_object aniObj, ani_object obj) { - TAG_LOGD(AAFwkTag::SERVICE_EXT, "PromiseCallback"); + TAG_LOGD(AAFwkTag::SERVICE_EXT, "ConnectPromiseCallback"); if (env == nullptr) { TAG_LOGE(AAFwkTag::SERVICE_EXT, "null env"); return; @@ -139,14 +139,20 @@ void StsServiceExtension::Init(const std::shared_ptr &record TAG_LOGE(AAFwkTag::SERVICE_EXT, "null env"); return; } + ani_class cls = nullptr; + ani_status status = ANI_ERROR; + if ((status = env->FindClass("L@ohos/app/ability/ServiceExtensionAbility/ServiceExtensionAbility;", &cls)) != ANI_OK) { + TAG_LOGE(AAFwkTag::STSRUNTIME, "status: %{public}d", status); + return; + } std::array functions = { ani_native_function { "nativeOnDisconnectCallback", ":V", reinterpret_cast(DisconnectPromiseCallback) }, ani_native_function { "nativeOnConnectCallback", nullptr, reinterpret_cast(ConnectPromiseCallback) }, }; - - ani_status status = env->Class_BindNativeMethods(stsObj_->aniCls, functions.data(), functions.size()); + status = env->Class_BindNativeMethods(cls, functions.data(), functions.size()); if (ANI_OK != status) { TAG_LOGE(AAFwkTag::SERVICE_EXT, "Class_BindNativeMethods is fail %{public}d", status); + return; }; BindContext(env, record->GetWant(), application); return; @@ -272,9 +278,12 @@ sptr StsServiceExtension::OnConnect(const AAFwk::Want &want) sptr StsServiceExtension::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 = stsRuntime_.GetAniEnv(); - if (!env) { - TAG_LOGE(AAFwkTag::SERVICE_EXT, "env not found"); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "null env"); return nullptr; } ani_ref wantRef = OHOS::AppExecFwk::WrapWant(env, want); @@ -282,28 +291,54 @@ sptr StsServiceExtension::OnConnect(const AAFwk::Want &want, TAG_LOGE(AAFwkTag::SERVICE_EXT, "null wantRef"); return nullptr; } - if (callbackInfo == nullptr) { - isAsyncCallback = false; - return OnConnect(want); - } ani_long connectCallbackPoint = (ani_long)callbackInfo; ani_status status = ANI_ERROR; - ani_field field = nullptr; - if ((status = env->Class_FindField(stsObj_->aniCls, "connectCallbackPoint", &field)) != ANI_OK) { - TAG_LOGE(AAFwkTag::UIABILITY, "status : %{public}d", status); + ani_field callbackField = nullptr; + if ((status = env->Class_FindField(stsObj_->aniCls, "connectCallbackPoint", &callbackField)) != ANI_OK) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "status : %{public}d", status); + return nullptr; } - if ((status = env->Object_SetField_Long(stsObj_->aniObj, field, connectCallbackPoint)) != ANI_OK) { - TAG_LOGE(AAFwkTag::UIABILITY, "status : %{public}d", status); + if ((status = env->Object_SetField_Long(stsObj_->aniObj, callbackField, connectCallbackPoint)) != ANI_OK) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "status : %{public}d", status); + return nullptr; } - ani_ref result = - CallObjectMethod(true, "callOnConnect", "L@ohos/app/ability/Want/Want;:L@ohos/rpc/rpc/RemoteObject;", wantRef); - auto obj = reinterpret_cast(result); - auto remoteObj = AniGetNativeRemoteObject(env, obj); - if (remoteObj == nullptr) { - TAG_LOGE(AAFwkTag::SERVICE_EXT, "remoteObj null"); + ani_ref aniRemoteRef = CallObjectMethod(true, "onConnect", nullptr, wantRef); + auto aniRemoteobj = reinterpret_cast(aniRemoteRef); + return OnConnectInner(env, aniRemoteobj, isAsyncCallback); +} + +sptr StsServiceExtension::OnConnectInner(ani_env* env, ani_object &aniRemoteobj, bool &isAsyncCallback) +{ + ani_status status = ANI_ERROR; + ani_method method {}; + if ((status = env->Class_FindMethod(stsObj_->aniCls, "checkPromise", nullptr, &method)) != ANI_OK) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "status : %{public}d", status); return nullptr; } - return remoteObj; + ani_boolean isPromise = false; + if ((status = env->Object_CallMethod_Boolean(stsObj_->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; + } + if ((status = env->Class_FindMethod(stsObj_->aniCls, "callPromise", nullptr, &method)) != ANI_OK) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "status : %{public}d", status); + return nullptr; + } + ani_boolean callResult = false; + if ((status = env->Object_CallMethod_Boolean(stsObj_->aniObj, method, &callResult, aniRemoteobj)) != ANI_OK) { + TAG_LOGE(AAFwkTag::SERVICE_EXT, "status : %{public}d", status); + return nullptr; + } + isAsyncCallback = callResult; + return nullptr; } void StsServiceExtension::OnDisconnect(const AAFwk::Want &want) diff --git a/frameworks/ets/ets/@ohos.app.ability.ServiceExtensionAbility.ets b/frameworks/ets/ets/@ohos.app.ability.ServiceExtensionAbility.ets index 3f2442868bed5f0799ca90cbc7b313750a420ca2..ebb1bb64d21dc46d76fe6e6c3a10a090a39aa22b 100644 --- a/frameworks/ets/ets/@ohos.app.ability.ServiceExtensionAbility.ets +++ b/frameworks/ets/ets/@ohos.app.ability.ServiceExtensionAbility.ets @@ -34,66 +34,70 @@ class MyService extends rpc.RemoteObject { } export default class ServiceExtensionAbility { - private isOnConnectAsync: boolean = true; private connectCallbackPoint: long; - private native nativeOnConnectCallback(service: rpc.RemoteObject): void; - private callOnConnect(want: Want): rpc.RemoteObject { - let p = this.onConnectAsync(want); - if (this.isOnConnectAsync) { - p.then((a:rpc.RemoteObject) => { - this.nativeOnConnectCallback(a); - }); - return new MyService("onConnectAsync") - } else { - return this.onConnect(want); - } - } + + private native nativeOnConnectCallback(service: rpc.RemoteObject): boolean; + private native nativeOnDisconnectCallback(): void; private isOnDisconnectAsync: boolean = true; private disconnectCallbackPoint: long; - private native nativeOnDisconnectCallback(): void; + + 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 callOnDisconnect(want: Want): void { let p = this.onDisconnectAsync(want); if (this.isOnDisconnectAsync) { - p.then((a:undefined): void => { + 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{ + + onCreate(want: Want): void { console.log("onCreate"); } + onDestroy(): void { - console.log("ServiceExtensionAbility onRequest"); + console.log("onDestroy"); } + onRequest(want: Want, startld: double): void { console.log("onRequest"); } - onConnect(want: Want): rpc.RemoteObject { + + onConnect(want: Want): rpc.RemoteObject | Promise { console.log("onConnect"); let myService: rpc.RemoteObject = new MyService("onConnect"); return myService; } - onConnectAsync(want: Want): Promise { - console.log("onConnectAsync"); - this.isOnConnectAsync = false; - return new Promise((resolve, reject) => { - resolve(new MyService("onConnectAsync")); - }); - } + onDisconnect(want: Want): void { console.log("onDisconnect"); } + onDisconnectAsync(want: Want): Promise { console.log("onDisconnectAsync"); this.isOnDisconnectAsync = false; - return new Promise((resolve: (a: undefined)=>void, reject: (err: Error)=>void): void => {}); + return new Promise((resolve: (a: undefined) => void, reject: (err: Error) => void): void => { + }); } + onConfigurationUpdate(newConfig: Configuration): void { console.log("onConfigurationUpdate"); }