diff --git a/interfaces/kits/ani/common_event/ets/commonEvent/commonEventSubscribeInfo.ets b/interfaces/kits/ani/common_event/ets/commonEvent/commonEventSubscribeInfo.ets index 1f6d0914c9e11f72d8e0abc05fd6cd37bc09e5f3..77b8886e32236da73a2edc915cc96faa7328d183 100644 --- a/interfaces/kits/ani/common_event/ets/commonEvent/commonEventSubscribeInfo.ets +++ b/interfaces/kits/ani/common_event/ets/commonEvent/commonEventSubscribeInfo.ets @@ -21,3 +21,12 @@ export interface CommonEventSubscribeInfo { priority?: number; publisherBundleName?: string; } + +class CommonEventSubscribeInfoImpl implements CommonEventSubscribeInfo { + public events: Array = {}; + public publisherPermission?: string | undefined; + public publisherDeviceId?: string | undefined; + public userId?: number | undefined; + public priority?: number | undefined; + public publisherBundleName?: string | undefined; +} \ No newline at end of file diff --git a/interfaces/kits/ani/common_event/ets/commonEvent/commonEventSubscriber.ets b/interfaces/kits/ani/common_event/ets/commonEvent/commonEventSubscriber.ets index 0e0ec4aa3798e43ee3599a0f3f39f07a13fe4190..abd4f8ea93885c55d095e085a78b732be140647a 100644 --- a/interfaces/kits/ani/common_event/ets/commonEvent/commonEventSubscriber.ets +++ b/interfaces/kits/ani/common_event/ets/commonEvent/commonEventSubscriber.ets @@ -13,6 +13,10 @@ * limitations under the License. */ +import hilog from '@ohos.hilog'; +import { AsyncCallback, BusinessError } from '@ohos.base'; +import { CommonEventSubscribeInfo } from 'commonEvent.commonEventSubscribeInfo'; + class Cleaner { private ptr: long = 0 @@ -28,16 +32,447 @@ function callback(cleaner: Cleaner): void { let destroyRegister = new FinalizationRegistry(callback) let unregisterToken = new object() +type ResolveCallback = (data: T) => void; +type RejectCallback = (err: Error) => void; +const TAG: string = 'commonEventSubscriber'; export interface CommonEventSubscriber { + getCode(callback: AsyncCallback): void; + getCode(): Promise; getCodeSync(): number; + setCode(code: number, callback: AsyncCallback): void; + setCode(code: number): Promise; + setCodeSync(code: number): void; + getData(callback: AsyncCallback): void; + getData(): Promise; + getDataSync(): string; + setData(data: string, callback: AsyncCallback): void; + setData(data: string): Promise; + setDataSync(data: string): void; + setCodeAndData(code: number, data: string, callback: AsyncCallback): void; + setCodeAndData(code: number, data: string): Promise; + setCodeAndDataSync(code: number, data: string): void; + isOrderedCommonEvent(callback: AsyncCallback): void; + isOrderedCommonEvent(): Promise; + isOrderedCommonEventSync(): boolean; + isStickyCommonEvent(callback: AsyncCallback): void; + isStickyCommonEvent(): Promise; + isStickyCommonEventSync(): boolean; + abortCommonEvent(callback: AsyncCallback): void; + abortCommonEvent(): Promise; + abortCommonEventSync(): void; + clearAbortCommonEvent(callback: AsyncCallback): void; + clearAbortCommonEvent(): Promise; + clearAbortCommonEventSync(): void; + getAbortCommonEvent(callback: AsyncCallback): void; + getAbortCommonEvent(): Promise; + getAbortCommonEventSync(): boolean; + getSubscribeInfo(callback: AsyncCallback): void; + getSubscribeInfo(): Promise; + getSubscribeInfoSync(): CommonEventSubscribeInfo; + finishCommonEvent(callback: AsyncCallback): void; + finishCommonEvent(): Promise; } class CommonEventSubscriberInner implements CommonEventSubscriber { static {loadLibrary("ani_commoneventmanager.z")} private subscriberInstanceWrapper: long = 0; - + + public native nativeGetCode(): number; + public native nativeSetCode(code: int): int; + public native nativeGetData(): string; + public native nativeSetData(data: string): int; + public native nativeSetCodeAndData(code: int, data: string): int; + public native nativeIsOrderedCommonEvent(): boolean; + public native nativeIsStickyCommonEvent(): boolean; + public native nativeAbortCommonEvent(): int; + public native nativeClearAbortCommonEvent(): int; + public native nativeGetAbortCommonEvent(): boolean; + public native nativeGetSubscribeInfo(): CommonEventSubscribeInfo; + public native nativeFinishCommonEvent(): int; + + public getCode(callback: AsyncCallback): void { + let p = taskpool.execute((): number => { return this.nativeGetCode(); }); + p.then((data: NullishType): void => { + let ret : number = data as number; + callback(null, ret); + }, (error: Error): void => { + let ret: number = -1; + let err: BusinessError = error as BusinessError; + callback(err, ret); + }); + } + + public getCode(): Promise { + let pPromise = new Promise((resolve: ResolveCallback, reject: RejectCallback): void => { + let p = taskpool.execute((): number => { return this.nativeGetCode(); }); + p.then((data: NullishType): void => { + let ret : number = data as number; + resolve(ret); + }, (error: Error): void => { + reject(error); + }); + }); + return pPromise; + } + public getCodeSync(): number { - return 2; + let ret : number = 0; + try { + ret = this.nativeGetCode() as number; + return ret; + } catch (err) { + return ret; + } + } + + public setCode(code: number, callback: AsyncCallback): void { + let pcode: Int = code.toInt(); + let p = taskpool.execute((): int => { return this.nativeSetCode(pcode); }); + p.then((data: NullishType): void => { + callback(null, undefined); + }, (error: Error): void => { + let err: BusinessError = error as BusinessError; + callback(err, undefined); + }); + } + + public setCode(code: number): Promise { + let pcode: Int = code.toInt(); + let pPromise = new Promise((resolve: ResolveCallback, reject: RejectCallback): void => { + let p = taskpool.execute((): int => { return this.nativeSetCode(pcode); }); + p.then((data: NullishType): void => { + resolve(undefined); + }, (error: Error): void => { + reject(error); + }); + }); + return pPromise; + } + + public setCodeSync(code: number): void { + try { + let pcode: Int = code.toInt(); + this.nativeSetCode(pcode); + return; + } catch (err) { + hilog.error(0xD001202, TAG, 'asyncResult is nullptr'); + } + } + + public getData(callback: AsyncCallback): void { + let p = taskpool.execute((): string => { return this.nativeGetData(); }); + p.then((data: NullishType): void => { + let ret : string = data as string; + callback(null, ret); + }, (error: Object): void => { + let err: BusinessError = error as BusinessError; + callback(err, undefined); + }) + } + + public getData(): Promise { + let pPromise = new Promise((resolve: ResolveCallback, reject: RejectCallback):void => { + let p = taskpool.execute((): string => { return this.nativeGetData(); }); + p.then((data :NullishType): void => { + let ret : string = data as string; + resolve(ret); + }, (err:Error): void => { + reject(err); + }); + }); + return pPromise; + } + + public getDataSync(): string { + let ret : string = ''; + try { + ret = this.nativeGetData() as string; + return ret; + } catch (err) { + return ret; + } + } + + public setData(data: string, callback: AsyncCallback): void { + let p = taskpool.execute((): int => { return this.nativeSetData(data); }); + p.then((e: NullishType): void => { + callback(null, undefined); + }, (error: Error): void => { + let err: BusinessError = error as BusinessError; + callback(err, undefined); + }) + } + + public setData(data: string): Promise { + let pPromise = new Promise((resolve: ResolveCallback, reject: RejectCallback): void => { + let p = taskpool.execute((): int => { return this.nativeSetData(data); }); + p.then((data: NullishType): void => { + resolve(undefined); + }, (error: Error): void => { + reject(error); + }); + }); + return pPromise; + } + + public setDataSync(data: string): void { + try { + this.nativeSetData(data); + return; + } catch (err) { + hilog.error(0xD001202, TAG, 'asyncResult is nullptr'); + } + } + + public setCodeAndData(code: number, data: string, callback: AsyncCallback): void { + let pcode: Int = code.toInt(); + let p = taskpool.execute((): int => { return this.nativeSetCodeAndData(pcode, data); }); + p.then((e: NullishType): void => { + callback(null, undefined); + }, (error: Error): void => { + let err: BusinessError = error as BusinessError; + callback(err, undefined); + }) + } + + public setCodeAndData(code: number, data: string): Promise { + let pcode: Int = code.toInt(); + let pPromise = new Promise((resolve: ResolveCallback, reject: RejectCallback): void => { + let p = taskpool.execute((): int => { return this.nativeSetCodeAndData(pcode, data); }); + p.then((data: NullishType): void => { + resolve(undefined); + }, (error: Error): void => { + reject(error); + }); + }); + return pPromise; + } + + public setCodeAndDataSync(code: number, data: string): void { + try { + let pcode: Int = code.toInt(); + this.nativeSetCodeAndData(pcode, data); + return; + } catch (err) { + hilog.error(0xD001202, TAG, 'asyncResult is nullptr'); + } + } + + public isOrderedCommonEvent(callback: AsyncCallback): void { + let p = taskpool.execute((): boolean => { return this.nativeIsOrderedCommonEvent(); }); + p.then((data: NullishType): void => { + let ret : boolean = data as boolean; + callback(null, ret); + }, (error: Error): void => { + let ret : boolean = false; + let err: BusinessError = error as BusinessError; + callback(err, ret); + }) + } + + public isOrderedCommonEvent(): Promise { + let pPromise = new Promise((resolve: ResolveCallback, reject: RejectCallback): void => { + let p = taskpool.execute((): boolean => { return this.nativeIsOrderedCommonEvent(); }); + p.then((data: NullishType): void => { + let ret : boolean = data as boolean; + resolve(ret); + }, (error: Error): void => { + reject(error); + }); + }); + return pPromise; + } + + public isOrderedCommonEventSync(): boolean { + try { + return this.nativeIsOrderedCommonEvent(); + } catch (err) { + hilog.error(0xD001202, TAG, 'asyncResult is nullptr'); + return false; + } + } + + public isStickyCommonEvent(callback: AsyncCallback): void { + let p = taskpool.execute((): boolean => { return this.nativeIsStickyCommonEvent(); }); + p.then((data: NullishType): void => { + let ret : boolean = data as boolean; + callback(null, ret); + }, (error: Error): void => { + let ret : boolean = false; + let err: BusinessError = error as BusinessError; + callback(err, ret); + }) + } + + public isStickyCommonEvent(): Promise { + let pPromise = new Promise((resolve: ResolveCallback, reject: RejectCallback): void => { + let p = taskpool.execute((): boolean => { return this.nativeIsStickyCommonEvent(); }); + p.then((data: NullishType): void => { + let ret : boolean = data as boolean; + resolve(ret); + }, (error: Error): void => { + reject(error); + }); + }); + return pPromise; + } + + public isStickyCommonEventSync(): boolean { + try { + return this.nativeIsStickyCommonEvent(); + } catch (err) { + hilog.error(0xD001202, TAG, 'asyncResult is nullptr'); + return false; + } + } + + public abortCommonEvent(callback: AsyncCallback): void { + let p = taskpool.execute((): int => { return this.nativeAbortCommonEvent(); }); + p.then((data: NullishType): void => { + callback(null, undefined); + }, (error: Error): void => { + let err: BusinessError = error as BusinessError; + callback(err, undefined); + }); + } + + public abortCommonEvent(): Promise { + let pPromise = new Promise((resolve: ResolveCallback, reject: RejectCallback): void => { + let p = taskpool.execute((): int => { return this.nativeAbortCommonEvent(); }); + p.then((data: NullishType): void => { + resolve(undefined); + }, (error: Error): void => { + reject(error); + }); + }); + return pPromise; + } + + public abortCommonEventSync(): void { + try { + this.nativeAbortCommonEvent(); + return; + } catch (err) { + hilog.error(0xD001202, TAG, 'asyncResult is nullptr'); + } + } + + public clearAbortCommonEvent(callback: AsyncCallback): void { + let p = taskpool.execute((): int => { return this.nativeClearAbortCommonEvent(); }); + p.then((data: NullishType): void => { + callback(null, undefined); + }, (error: Error): void => { + let err: BusinessError = error as BusinessError; + callback(err, undefined); + }); + } + + public clearAbortCommonEvent(): Promise { + let pPromise = new Promise((resolve: ResolveCallback, reject: RejectCallback): void => { + let p = taskpool.execute((): int => { return this.nativeClearAbortCommonEvent(); }); + p.then((data: NullishType): void => { + resolve(undefined); + }, (error: Error): void => { + reject(error); + }); + }); + return pPromise; + } + + public clearAbortCommonEventSync(): void { + try { + this.nativeClearAbortCommonEvent(); + return; + } catch (err) { + hilog.error(0xD001202, TAG, 'asyncResult is nullptr'); + } + } + + public getAbortCommonEvent(callback: AsyncCallback): void { + let p = taskpool.execute((): boolean => { return this.nativeGetAbortCommonEvent(); }); + p.then((data: NullishType): void => { + let ret : boolean = data as boolean; + callback(null, ret); + }, (error: Error): void => { + let ret : boolean = false; + let err: BusinessError = error as BusinessError; + callback(err, ret); + }) + } + + public getAbortCommonEvent(): Promise { + let pPromise = new Promise((resolve: ResolveCallback, reject: RejectCallback): void => { + let p = taskpool.execute((): boolean => { return this.nativeGetAbortCommonEvent(); }); + p.then((data: NullishType): void => { + let ret : boolean = data as boolean; + resolve(ret); + }, (error: Error): void => { + reject(error); + }); + }); + return pPromise; + } + + public getAbortCommonEventSync(): boolean { + let ret : boolean = false; + try { + ret = this.nativeGetAbortCommonEvent() as boolean; + return ret; + } catch (err) { + return ret; + } + } + + public getSubscribeInfo(callback: AsyncCallback): void { + let p = taskpool.execute((): CommonEventSubscribeInfo => { return this.nativeGetSubscribeInfo(); }); + p.then((data: NullishType): void => { + let ret : CommonEventSubscribeInfo = data as CommonEventSubscribeInfo; + callback(null, ret); + }, (error: Error): void => { + let ret : CommonEventSubscribeInfo ; + let err: BusinessError = error as BusinessError; + callback(err, ret); + }) + } + + public getSubscribeInfo(): Promise { + let pPromise = new Promise((resolve: ResolveCallback, + reject: RejectCallback): void => { + let p = taskpool.execute((): CommonEventSubscribeInfo => { return this.nativeGetSubscribeInfo(); }); + p.then((data: NullishType): void => { + let ret : CommonEventSubscribeInfo = data as CommonEventSubscribeInfo; + resolve(ret); + }, (error: Error): void => { + reject(error); + }); + }); + return pPromise; + } + + public getSubscribeInfoSync(): CommonEventSubscribeInfo { + return this.nativeGetSubscribeInfo(); + } + + public finishCommonEvent(callback: AsyncCallback): void { + let p = taskpool.execute((): int => { return this.nativeFinishCommonEvent(); }); + p.then((data: NullishType): void => { + callback(null, undefined); + }, (error: Error): void => { + let err: BusinessError = error as BusinessError; + callback(err, undefined); + }); + } + + public finishCommonEvent(): Promise { + let pPromise = new Promise((resolve: ResolveCallback, reject: RejectCallback): void => { + let p = taskpool.execute((): int => { return this.nativeFinishCommonEvent(); }); + p.then((data: NullishType): void => { + resolve(undefined); + }, (error: Error): void => { + reject(error); + }); + }); + return pPromise; } private cleaner: Cleaner | null = null; diff --git a/interfaces/kits/ani/common_event/include/ani_common_event.h b/interfaces/kits/ani/common_event/include/ani_common_event.h index 4c6b5b13efea4bf6f57d440b9d08c8f5c5ee5b30..cb266d94b7ba108675625f9ac28810f0bb047224 100644 --- a/interfaces/kits/ani/common_event/include/ani_common_event.h +++ b/interfaces/kits/ani/common_event/include/ani_common_event.h @@ -32,6 +32,7 @@ public: void SetEnv(ani_env* env); void SetVm(ani_vm* etsVm); void SetCallback(const ani_object& callback); + ani_object GetCallback(); void ClearEnv(); private: @@ -58,6 +59,8 @@ struct subscriberInstanceInfo { std::shared_ptr commonEventResult = nullptr; }; +std::shared_ptr GetSubscriber(ani_env* env, ani_ref subscribeRef); +std::shared_ptr GetAsyncCommonEventResult (ani_env* env, ani_ref subscribeRef); std::shared_ptr GetSubscriberByWrapper(SubscriberInstanceWrapper* wrapper); } // namespace EventManagerFwkAni diff --git a/interfaces/kits/ani/common_event/include/ani_common_event_utils.h b/interfaces/kits/ani/common_event/include/ani_common_event_utils.h index 1b63ac2c7a892d87b14af4ab7900981b2da28309..2fe9e84025be1b02cc36d7cb35d8031354c93aa8 100644 --- a/interfaces/kits/ani/common_event/include/ani_common_event_utils.h +++ b/interfaces/kits/ani/common_event/include/ani_common_event_utils.h @@ -21,6 +21,7 @@ #include #include +#include "ani_common_event.h" #include "common_event_manager.h" namespace OHOS { @@ -31,11 +32,14 @@ using CommonEventData = OHOS::EventFwk::CommonEventData; class AniCommonEventUtils { public: static void GetStdString(ani_env* env, ani_string str, std::string& result); + static ani_status GetAniString(ani_env* env, const std::string str, ani_string &aniStr); static void GetStdStringArrayClass(ani_env* env, ani_object arrayObj, std::vector& strings); static void ConvertCommonEventPublishData(ani_env* env, ani_object optionsObject, EventFwk::Want& want, EventFwk::CommonEventData& commonEventData, EventFwk::CommonEventPublishInfo& commonEventPublishInfo); static void ConvertCommonEventSubscribeInfo( ani_env* env, ani_object infoObject, CommonEventSubscribeInfo& subscribeInfo); + static void GetCommonEventSubscribeInfoToEts( + ani_env* env, std::shared_ptr subscriber, ani_object &infoObject); static void ConvertCommonEventDataToEts(ani_env* env, ani_object& ani_data, const CommonEventData& commonEventData); static bool GetStringOrUndefined(ani_env* env, ani_object param, const char* name, std::string& res); static bool GetIntOrUndefined(ani_env* env, ani_object param, const char* name, int32_t& res); @@ -49,6 +53,8 @@ public: static void CallSetter(ani_env* env, ani_class cls, ani_object object, const char* setterName, valueType value); static void CreateAniDoubleObject(ani_env* env, ani_object &object, ani_double value); static void CreateBusinessErrorObject(ani_env* env, ani_object &object, int32_t code, const std::string &message); + static ani_object GetAniStringArray(ani_env *env, std::vector strs); + static ani_object newArrayClass(ani_env *env, int length); }; } // namespace EventManagerFwkAni } // namespace OHOS diff --git a/interfaces/kits/ani/common_event/src/ani_common_event.cpp b/interfaces/kits/ani/common_event/src/ani_common_event.cpp index ca4385524780a70a6063dd843a2de47f7bff19ba..78642e40ff6a3770ee1151895d5ec9e8823cc12c 100644 --- a/interfaces/kits/ani/common_event/src/ani_common_event.cpp +++ b/interfaces/kits/ani/common_event/src/ani_common_event.cpp @@ -29,7 +29,6 @@ std::atomic_ullong SubscriberInstance::subscriberID_ = 0; static std::map, std::shared_ptr> subscriberInstances; static std::mutex subscriberInsMutex; - static uint32_t publishExecute(ani_env* env, ani_string eventId) { EVENT_LOGI("publishExecute call."); @@ -191,11 +190,36 @@ static uint32_t subscribeExecute(ani_env* env, ani_ref subscribeRef, ani_object } subscriberInstance->SetVm(etsVm); auto result = CommonEventManager::NewSubscribeCommonEvent(subscriberInstance); - + if (result == ANI_OK) { + EVENT_LOGD("result is ANI_OK"); + std::lock_guard lock(subscriberInsMutex); + subscriberInstances[subscriberInstance] = subscriberInstance->GoAsyncCommonEvent(); + } else { + subscriberInstance = nullptr; + } EVENT_LOGI("subscribeExecute result: %{public}d.", result); return result; } +static int32_t removeSubscriberInstance(ani_env* env, SubscriberInstanceWrapper* wrapper) +{ + int32_t result = ERR_OK; + std::lock_guard lock(subscriberInsMutex); + for (auto iter = subscriberInstances.begin(); iter != subscriberInstances.end();) { + if (iter->first.get() == wrapper->GetSubscriber().get()) { + result = CommonEventManager::NewUnSubscribeCommonEvent(iter->first); + ani_ref callbackRef = static_cast(iter->first->GetCallback()); + if (result == ANI_OK && callbackRef != nullptr) { + env->GlobalReference_Delete(callbackRef); + } + iter = subscriberInstances.erase(iter); + } else { + ++iter; + } + } + return result; +} + static uint32_t unsubscribeExecute(ani_env* env, ani_ref subscribeRef) { EVENT_LOGI("unsubscribeExecute call."); @@ -221,7 +245,7 @@ static uint32_t unsubscribeExecute(ani_env* env, ani_ref subscribeRef) EVENT_LOGE("subscriberInstance is null."); return ANI_INVALID_ARGS; } - auto result = CommonEventManager::NewUnSubscribeCommonEvent(subscriberInstance); + auto result = removeSubscriberInstance(env, wrapper); EVENT_LOGI("unsubscribeExecute result: %{public}d.", result); return result; } @@ -277,6 +301,28 @@ static uint32_t setStaticSubscriberStateWithEventsExecute(ani_env* env, ani_bool return returncode; } +std::shared_ptr GetSubscriber(ani_env* env, ani_ref subscribeRef) +{ + EVENT_LOGD("GetSubscriber excute"); + auto ret = ANI_OK; + + ani_long wrapper_long {}; + ret = env->Object_GetPropertyByName_Long( + static_cast(subscribeRef), "subscriberInstanceWrapper", &wrapper_long); + if (ret != ANI_OK) { + EVENT_LOGE("subscribeExecute Object_GetPropertyByName_Long error. result: %{public}d.", ret); + return nullptr; + } + + SubscriberInstanceWrapper* wrapper = nullptr; + wrapper = reinterpret_cast(wrapper_long); + if (wrapper == nullptr) { + EVENT_LOGE("unsubscribeExecute wrapper is null."); + return nullptr; + } + return GetSubscriberByWrapper(wrapper); +} + std::shared_ptr GetSubscriberByWrapper(SubscriberInstanceWrapper* wrapper) { if (wrapper->GetSubscriber() == nullptr) { @@ -375,6 +421,12 @@ void SubscriberInstance::SetCallback(const ani_object& callback) callback_ = callback; } +ani_object SubscriberInstance::GetCallback() +{ + std::lock_guard lockRef(callbackMutex_); + return callback_; +} + void SubscriberInstance::ClearEnv() { EVENT_LOGD("Env expired, clear SubscriberInstance env"); @@ -409,9 +461,265 @@ static void clean([[maybe_unused]] ani_env *env, [[maybe_unused]] ani_object obj if (ANI_OK != env->Object_GetFieldByName_Long(object, "ptr", &ptr)) { return; } - delete reinterpret_cast(ptr); + SubscriberInstanceWrapper* wrapper = nullptr; + wrapper = reinterpret_cast(ptr); + if (wrapper == nullptr) { + EVENT_LOGE("clean wrapper is null."); + return; + } + auto result = removeSubscriberInstance(env, wrapper); + EVENT_LOGD("clean result: %{public}d.", result); + return; +} + +std::shared_ptr GetAsyncCommonEventResult(ani_env* env, ani_object object) +{ + EVENT_LOGD("subscriberInstance GetAsyncCommonEventResult."); + auto subscriberInstance = GetSubscriber(env, object); + if (subscriberInstance == nullptr) { + EVENT_LOGE("subscriberInstance is null."); + return nullptr; + } + if (subscriberInstances.size() == 0) { + EVENT_LOGE("subscriberInstances is null."); + return nullptr; + } + std::lock_guard lock(subscriberInsMutex); + for (auto subscriberRes : subscriberInstances) { + if (subscriberRes.first.get() == subscriberInstance.get()) { + return subscriberInstances[subscriberRes.first]; + } + } + return nullptr; +} + +static ani_double getCode(ani_env *env, ani_object object) +{ + EVENT_LOGD("subscriberInstance getCode."); + auto subscriberRes = GetAsyncCommonEventResult(env, object); + int32_t code = 0; + if (subscriberRes != nullptr) { + code = subscriberRes->GetCode(); + } + ani_double returncode = static_cast(code); + return returncode; +} + +static uint32_t setCode(ani_env *env, ani_object object, ani_int code) +{ + EVENT_LOGD("subscriberInstance setCode."); + int32_t returncode = 0; + auto subscriberRes = GetAsyncCommonEventResult(env, object); + if (subscriberRes == nullptr) { + EVENT_LOGE("subscriberRes is null"); + returncode = Notification::ERR_NOTIFICATION_CESM_ERROR; + OHOS::AbilityRuntime::ThrowStsError(env, returncode, FindCesErrMsg(returncode)); + return returncode; + } + bool returnBoolean = subscriberRes->SetCode(code); + if (!returnBoolean) { + EVENT_LOGE("subscriberRes is null"); + returncode = Notification::ERR_NOTIFICATION_CESM_ERROR; + OHOS::AbilityRuntime::ThrowStsError(env, returncode, FindCesErrMsg(returncode)); + return returncode; + } + return returncode; } +static ani_string getData(ani_env *env, ani_object object) +{ + EVENT_LOGD("subscriberInstance getData."); + auto subscriberRes = GetAsyncCommonEventResult(env, object); + std::string str = ""; + if (subscriberRes != nullptr) { + str = subscriberRes->GetData(); + } + ani_string aniResult = nullptr; + AniCommonEventUtils::GetAniString(env, str, aniResult); + return aniResult; +} + +static uint32_t setData(ani_env *env, ani_object object, ani_string data) +{ + EVENT_LOGD("subscriberInstance setData."); + int32_t returncode = 0; + auto subscriberRes = GetAsyncCommonEventResult(env, object); + if (subscriberRes == nullptr) { + EVENT_LOGE("subscriberRes is null"); + returncode = Notification::ERR_NOTIFICATION_CESM_ERROR; + OHOS::AbilityRuntime::ThrowStsError(env, returncode, FindCesErrMsg(returncode)); + return returncode; + } + std::string stdData; + AniCommonEventUtils::GetStdString(env, data, stdData); + ani_boolean returnBoolean = static_cast(subscriberRes->SetData(stdData)); + if (!returnBoolean) { + EVENT_LOGE("subscriberRes is null"); + returncode = Notification::ERR_NOTIFICATION_CESM_ERROR; + OHOS::AbilityRuntime::ThrowStsError(env, returncode, FindCesErrMsg(returncode)); + return returncode; + } + return returncode; +} + +static uint32_t setCodeAndData(ani_env *env, ani_object object, ani_int code, ani_string data) +{ + EVENT_LOGD("subscriberInstance setCodeAndData."); + int32_t returncode = 0; + auto subscriberRes = GetAsyncCommonEventResult(env, object); + if (subscriberRes == nullptr) { + EVENT_LOGE("subscriberRes is null"); + returncode = Notification::ERR_NOTIFICATION_CESM_ERROR; + OHOS::AbilityRuntime::ThrowStsError(env, returncode, FindCesErrMsg(returncode)); + return returncode; + } + std::string stdData; + int32_t intCode = static_cast(code); + AniCommonEventUtils::GetStdString(env, data, stdData); + bool returnBoolean = subscriberRes->SetCodeAndData(intCode, stdData); + if (!returnBoolean) { + EVENT_LOGE("subscriberRes is null"); + returncode = Notification::ERR_NOTIFICATION_CESM_ERROR; + OHOS::AbilityRuntime::ThrowStsError(env, returncode, FindCesErrMsg(returncode)); + return returncode; + } + return returncode; +} + +static ani_boolean isOrderedCommonEvent(ani_env *env, ani_object object) +{ + EVENT_LOGD("subscriberInstance isOrderedCommonEvent."); + auto subscriberRes = GetAsyncCommonEventResult(env, object); + ani_boolean returnBoolean = ANI_FALSE; + if (subscriberRes != nullptr) { + returnBoolean = subscriberRes->IsOrderedCommonEvent() ? ANI_TRUE : ANI_FALSE; + } + return returnBoolean; +} + +static ani_boolean isStickyCommonEvent(ani_env *env, ani_object object) +{ + EVENT_LOGD("subscriberInstance isStickyCommonEvent."); + auto subscriberRes = GetAsyncCommonEventResult(env, object); + ani_boolean returnBoolean = ANI_FALSE; + if (subscriberRes != nullptr) { + returnBoolean = subscriberRes->IsStickyCommonEvent() ? ANI_TRUE : ANI_FALSE; + } + return returnBoolean; +} + +static uint32_t abortCommonEvent(ani_env *env, ani_object object) +{ + EVENT_LOGD("subscriberInstance abortCommonEvent."); + int32_t returncode = 0; + auto subscriberRes = GetAsyncCommonEventResult(env, object); + if (subscriberRes == nullptr) { + EVENT_LOGE("subscriberRes is null"); + returncode = Notification::ERR_NOTIFICATION_CESM_ERROR; + OHOS::AbilityRuntime::ThrowStsError(env, returncode, FindCesErrMsg(returncode)); + return returncode; + } + if (!(subscriberRes->AbortCommonEvent())) { + returncode = Notification::ERR_NOTIFICATION_CESM_ERROR; + OHOS::AbilityRuntime::ThrowStsError(env, returncode, FindCesErrMsg(returncode)); + return returncode; + } + return returncode; +} + +static uint32_t clearAbortCommonEvent(ani_env *env, ani_object object) +{ + EVENT_LOGD("subscriberInstance clearAbortCommonEvent."); + int32_t returncode = 0; + auto subscriberRes = GetAsyncCommonEventResult(env, object); + if (subscriberRes == nullptr) { + EVENT_LOGE("subscriberRes is null"); + returncode = Notification::ERR_NOTIFICATION_CESM_ERROR; + OHOS::AbilityRuntime::ThrowStsError(env, returncode, FindCesErrMsg(returncode)); + return returncode; + } + if (!(subscriberRes->ClearAbortCommonEvent())) { + returncode = Notification::ERR_NOTIFICATION_CESM_ERROR; + OHOS::AbilityRuntime::ThrowStsError(env, returncode, FindCesErrMsg(returncode)); + return returncode; + } + return returncode; +} + +static ani_boolean getAbortCommonEvent(ani_env *env, ani_object object) +{ + EVENT_LOGD("subscriberInstance getAbortCommonEvent."); + auto subscriberRes = GetAsyncCommonEventResult(env, object); + ani_boolean returnBoolean = ANI_FALSE; + if (subscriberRes != nullptr) { + returnBoolean = subscriberRes->GetAbortCommonEvent() ? ANI_TRUE : ANI_FALSE; + } + return returnBoolean; +} + +static ani_object getSubscribeInfo(ani_env *env, ani_object object) +{ + EVENT_LOGD("subscriberInstance getSubscribeInfo."); + auto subscriberInstance = GetSubscriber(env, object); + ani_object infoObject {}; + if (subscriberInstance == nullptr) { + EVENT_LOGE("subscriberInstance is null."); + ani_ref nullObject; + env->GetNull(&nullObject); + return static_cast(nullObject); + } + AniCommonEventUtils::GetCommonEventSubscribeInfoToEts(env, subscriberInstance, infoObject); + if (infoObject == nullptr) { + EVENT_LOGE("infoObject is null."); + ani_ref nullObject; + env->GetNull(&nullObject); + return static_cast(nullObject); + } + return infoObject; +} + +static uint32_t finishCommonEvent(ani_env *env, ani_object object) +{ + EVENT_LOGD("subscriberInstance finishCommonEvent."); + auto subscriberRes = GetAsyncCommonEventResult(env, object); + int32_t returncode = 0; + if (subscriberRes == nullptr) { + EVENT_LOGE("subscriberRes is null"); + returncode = Notification::ERR_NOTIFICATION_CESM_ERROR; + OHOS::AbilityRuntime::ThrowStsError(env, returncode, FindCesErrMsg(returncode)); + return returncode; + } + if (!(subscriberRes->FinishCommonEvent())) { + returncode = Notification::ERR_NOTIFICATION_CESM_ERROR; + OHOS::AbilityRuntime::ThrowStsError(env, returncode, FindCesErrMsg(returncode)); + return returncode; + } + return returncode; +} + +static std::array commonEventSubscriberFunctions = { + ani_native_function{"nativeGetCode", nullptr, reinterpret_cast(OHOS::EventManagerFwkAni::getCode)}, + ani_native_function{"nativeSetCode", nullptr, reinterpret_cast(OHOS::EventManagerFwkAni::setCode)}, + ani_native_function{"nativeGetData", nullptr, reinterpret_cast(OHOS::EventManagerFwkAni::getData)}, + ani_native_function{"nativeSetData", nullptr, reinterpret_cast(OHOS::EventManagerFwkAni::setData)}, + ani_native_function{"nativeSetCodeAndData", nullptr, + reinterpret_cast(OHOS::EventManagerFwkAni::setCodeAndData)}, + ani_native_function{"nativeIsOrderedCommonEvent", nullptr, + reinterpret_cast(OHOS::EventManagerFwkAni::isOrderedCommonEvent)}, + ani_native_function{"nativeIsStickyCommonEvent", nullptr, + reinterpret_cast(OHOS::EventManagerFwkAni::isStickyCommonEvent)}, + ani_native_function{"nativeAbortCommonEvent", nullptr, + reinterpret_cast(OHOS::EventManagerFwkAni::abortCommonEvent)}, + ani_native_function{"nativeClearAbortCommonEvent", nullptr, + reinterpret_cast(OHOS::EventManagerFwkAni::clearAbortCommonEvent)}, + ani_native_function{"nativeGetAbortCommonEvent", nullptr, + reinterpret_cast(OHOS::EventManagerFwkAni::getAbortCommonEvent)}, + ani_native_function{"nativeGetSubscribeInfo", nullptr, + reinterpret_cast(OHOS::EventManagerFwkAni::getSubscribeInfo)}, + ani_native_function{"nativeFinishCommonEvent", nullptr, + reinterpret_cast(OHOS::EventManagerFwkAni::finishCommonEvent)}, +}; + ani_status init(ani_env *env, ani_namespace kitNs) { ani_status status = ANI_ERROR; @@ -487,6 +795,19 @@ ANI_EXPORT ani_status ANI_Constructor(ani_vm* vm, uint32_t* result) return ANI_INVALID_TYPE; } + ani_class commonEventSubscriberCls; + status = env->FindClass("LcommonEvent/commonEventSubscriber/CommonEventSubscriberInner;", + &commonEventSubscriberCls); + if (status != ANI_OK) { + EVENT_LOGE("Not found LcommonEvent/commonEventSubscriber/CommonEventSubscriberInner"); + return ANI_INVALID_ARGS; + } + status = env->Class_BindNativeMethods(commonEventSubscriberCls, commonEventSubscriberFunctions.data(), + commonEventSubscriberFunctions.size()); + if (status != ANI_OK) { + EVENT_LOGE("Cannot bind native methods to LcommonEvent/commonEventSubscriber/CommonEventSubscriberInner"); + return ANI_INVALID_TYPE; + } *result = ANI_VERSION_1; return ANI_OK; } diff --git a/interfaces/kits/ani/common_event/src/ani_common_event_utils.cpp b/interfaces/kits/ani/common_event/src/ani_common_event_utils.cpp index 505e567241be351e5be5a23bc4bde72480a93182..2ee157529c89c7ee34fceee72ba45e7301a53841 100644 --- a/interfaces/kits/ani/common_event/src/ani_common_event_utils.cpp +++ b/interfaces/kits/ani/common_event/src/ani_common_event_utils.cpp @@ -42,6 +42,20 @@ void AniCommonEventUtils::GetStdString(ani_env* env, ani_string str, std::string result.resize(sz); } +ani_status AniCommonEventUtils::GetAniString(ani_env* env, const std::string str, ani_string& aniStr) +{ + if (env == nullptr) { + EVENT_LOGE("GetAniStringByString fail, env is nullptr"); + return ANI_INVALID_ARGS; + } + ani_status status = env->String_NewUTF8(str.c_str(), str.size(), &aniStr); + if (status != ANI_OK) { + EVENT_LOGE("String_NewUTF8 failed %{public}d", status); + return status; + } + return status; +} + void AniCommonEventUtils::GetStdStringArrayClass(ani_env* env, ani_object arrayObj, std::vector& strings) { ani_double length; @@ -343,6 +357,110 @@ void AniCommonEventUtils::ConvertCommonEventSubscribeInfo( subscribeInfo = commonEventSubscribeInfo; } +void AniCommonEventUtils::GetCommonEventSubscribeInfoToEts( + ani_env* env, std::shared_ptr subscriber, ani_object &infoObject) +{ + ani_class cls = nullptr; + ani_status status = ANI_ERROR; + CreateNewObjectByClass(env, "LcommonEvent/commonEventSubscribeInfo/CommonEventSubscribeInfoImpl;", cls, infoObject); + if ((infoObject == nullptr) || (cls == nullptr)) { + EVENT_LOGE("CommonEventSubscribeInfoToAni infoObject or cls is null."); + return; + } + if (subscriber == nullptr) { + EVENT_LOGE("subscriber is null."); + return; + } + + // set events [Array] + ani_object eventsParamRef = GetAniStringArray(env, subscriber->GetSubscribeInfo().GetMatchingSkills().GetEvents()); + CallSetter(env, cls, infoObject, SETTER_METHOD_NAME(events), eventsParamRef); + + ani_string string = nullptr; + // set publisherPermission [string] + status = env->String_NewUTF8( + subscriber->GetSubscribeInfo().GetPermission().c_str(), + subscriber->GetSubscribeInfo().GetPermission().size(), &string); + CallSetter(env, cls, infoObject, SETTER_METHOD_NAME(publisherPermission), string); + + // set publisherDeviceId [string] + status = env->String_NewUTF8( + subscriber->GetSubscribeInfo().GetDeviceId().c_str(), + subscriber->GetSubscribeInfo().GetDeviceId().size(), &string); + CallSetter(env, cls, infoObject, SETTER_METHOD_NAME(publisherDeviceId), string); + + // set publisherBundleName [string] + status = env->String_NewUTF8( + subscriber->GetSubscribeInfo().GetPublisherBundleName().c_str(), + subscriber->GetSubscribeInfo().GetPublisherBundleName().size(), &string); + CallSetter(env, cls, infoObject, SETTER_METHOD_NAME(publisherBundleName), string); + + // set userId [number] + ani_object userIdObject; + CreateAniDoubleObject(env, userIdObject, static_cast(subscriber->GetSubscribeInfo().GetUserId())); + CallSetter(env, cls, infoObject, SETTER_METHOD_NAME(userId), userIdObject); + + // set priority [number] + ani_object priorityObject; + CreateAniDoubleObject(env, priorityObject, static_cast(subscriber->GetSubscribeInfo().GetPriority())); + CallSetter(env, cls, infoObject, SETTER_METHOD_NAME(priority), priorityObject); +} + +ani_object AniCommonEventUtils::GetAniStringArray(ani_env *env, std::vector strs) +{ + if (env == nullptr) { + EVENT_LOGE("GetAniStringArray fail, env is nullptr or strs is empty"); + return nullptr; + } + int length = strs.size(); + ani_object arrayObj = newArrayClass(env, length); + if (arrayObj == nullptr) { + return nullptr; + } + ani_size i = 0; + for (auto &str : strs) { + EVENT_LOGI("GetAniStringArray: %{public}s", str.c_str()); + ani_string aniStr; + if ((env->String_NewUTF8(str.c_str(), str.size(), &aniStr) != ANI_OK) || aniStr == nullptr) { + EVENT_LOGE("String_NewUTF8 faild"); + return nullptr; + } + ani_status status = env->Object_CallMethodByName_Void(arrayObj, "$_set", "ILstd/core/Object;:V", i, aniStr); + if (status != ANI_OK) { + EVENT_LOGE("Object_CallMethodByName_Void failed %{public}d", status); + return nullptr; + } + i++; + } + return arrayObj; +} + +ani_object AniCommonEventUtils::newArrayClass(ani_env *env, int length) +{ + EVENT_LOGD("newArrayClass call"); + if (env == nullptr || length < 0) { + EVENT_LOGE("CreateDouble fail, env is nullptr or length is less than zero"); + return nullptr; + } + ani_class arrayCls = nullptr; + if (ANI_OK != env->FindClass("Lescompat/Array;", &arrayCls)) { + EVENT_LOGE("FindClass Lescompat/Array; Failed"); + return nullptr; + } + ani_method arrayCtor; + if (ANI_OK != env->Class_FindMethod(arrayCls, "", "I:V", &arrayCtor)) { + EVENT_LOGE("Class_FindMethod Failed"); + return nullptr; + } + ani_object arrayObj = nullptr; + if (ANI_OK != env->Object_New(arrayCls, arrayCtor, &arrayObj, length)) { + EVENT_LOGE("Object_New Array Faild"); + return nullptr; + } + EVENT_LOGD("newArrayClass end"); + return arrayObj; +} + void AniCommonEventUtils::CreateNewObjectByClass( ani_env* env, const char* className, ani_class& cls, ani_object& ani_data) {