From 819956dd68c98ac0e17cd88f37678329f64f90f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E6=89=94?= Date: Tue, 3 Jun 2025 09:51:31 +0800 Subject: [PATCH] add on/off MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 一扔 --- frameworks/ets/ani/BUILD.gn | 9 ++ frameworks/ets/ani/include/manager/ani_on.h | 27 ++++ .../ani/include/manager/ani_push_callback.h | 56 +++++++ .../ani/include/sts_notification_manager.h | 3 + frameworks/ets/ani/include/sts_request.h | 2 + frameworks/ets/ani/include/sts_throw_erro.h | 12 ++ .../ets/ani/src/manager/ani_manager.cpp | 8 + frameworks/ets/ani/src/manager/ani_on.cpp | 125 +++++++++++++++ .../ets/ani/src/manager/ani_push_callback.cpp | 148 +++++++++++++++++ frameworks/ets/ani/src/sts_action_button.cpp | 2 +- frameworks/ets/ani/src/sts_bundle_option.cpp | 2 +- frameworks/ets/ani/src/sts_common.cpp | 4 +- .../ets/ani/src/sts_notification_manager.cpp | 150 ++++++++++++++++++ frameworks/ets/ani/src/sts_request.cpp | 82 ++++++++++ frameworks/ets/ani/src/sts_subscribe.cpp | 4 +- .../ets/ets/@ohos.notificationManager.ets | 96 ++++++++++- 16 files changed, 723 insertions(+), 7 deletions(-) create mode 100755 frameworks/ets/ani/include/manager/ani_on.h create mode 100755 frameworks/ets/ani/include/manager/ani_push_callback.h create mode 100755 frameworks/ets/ani/src/manager/ani_on.cpp create mode 100755 frameworks/ets/ani/src/manager/ani_push_callback.cpp diff --git a/frameworks/ets/ani/BUILD.gn b/frameworks/ets/ani/BUILD.gn index fa0771b8a..34ea02605 100644 --- a/frameworks/ets/ani/BUILD.gn +++ b/frameworks/ets/ani/BUILD.gn @@ -56,6 +56,8 @@ ohos_shared_library("notification_manager_ani") { "./src/manager/ani_manager.cpp", "./src/manager/ani_request_enable.cpp", "./src/manager/ani_ans_dialog_callback.cpp", + "./src/manager/ani_on.cpp", + "./src/manager/ani_push_callback.cpp", ] cflags = [] @@ -68,6 +70,12 @@ ohos_shared_library("notification_manager_ani") { "${frameworks_path}/cj/ffi:cj_notification_manager_ffi", ] + defines = [] + + if (distributed_notification_service_feature_local_liveview) { + defines += [ "ANS_FEATURE_LIVEVIEW_LOCAL_LIVEVIEW" ] + } + external_deps = [ "c_utils:utils", "hilog:libhilog", @@ -87,6 +95,7 @@ ohos_shared_library("notification_manager_ani") { "ability_runtime:abilitykit_native", "ability_runtime:app_context", "ace_engine:ace_uicontent", + "access_token:libtokenid_sdk", ] innerapi_tags = [ "platformsdk" ] diff --git a/frameworks/ets/ani/include/manager/ani_on.h b/frameworks/ets/ani/include/manager/ani_on.h new file mode 100755 index 000000000..911d45fd8 --- /dev/null +++ b/frameworks/ets/ani/include/manager/ani_on.h @@ -0,0 +1,27 @@ +/* + * 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 BASE_NOTIFICATION_DISTRIBUTED_NOTIFICATION_SERVICE_FRAMEWORKS_ETS_ANI_INCLUDE_ANI_ON_H +#define BASE_NOTIFICATION_DISTRIBUTED_NOTIFICATION_SERVICE_FRAMEWORKS_ETS_ANI_INCLUDE_ANI_ON_H +#include "ani.h" + +namespace OHOS { +namespace NotificationManagerSts { +ani_int AniOn(ani_env *env, ani_string type, ani_fn_object fn, ani_object checkRequestObj); +ani_int AniOff(ani_env *env, ani_string type, ani_fn_object fn); +} // namespace NotificationManagerSts +} // namespace OHOS +#endif + diff --git a/frameworks/ets/ani/include/manager/ani_push_callback.h b/frameworks/ets/ani/include/manager/ani_push_callback.h new file mode 100755 index 000000000..fcaf53782 --- /dev/null +++ b/frameworks/ets/ani/include/manager/ani_push_callback.h @@ -0,0 +1,56 @@ +/* + * 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 BASE_NOTIFICATION_DISTRIBUTED_NOTIFICATION_SERVICE_FRAMEWORKS_ETS_ANI_INCLUDE_ANI_PUSH_CALLBACK_H +#define BASE_NOTIFICATION_DISTRIBUTED_NOTIFICATION_SERVICE_FRAMEWORKS_ETS_ANI_INCLUDE_ANI_PUSH_CALLBACK_H +#include +#include +#include "ani.h" +#include "push_callback_stub.h" +#include "notification_constant.h" + +namespace OHOS { +namespace NotificationManagerSts { +using namespace OHOS::Notification; +class StsPushCallBack : public PushCallBackStub { +public: + struct ResultParam { + int32_t code = -1; + std::string msg = ""; + }; + + StsPushCallBack(ani_env *env); + virtual ~StsPushCallBack(); + int32_t OnCheckNotification( + const std::string ¬ificationData, const std::shared_ptr &pushCallBackParam) override; + void SetJsPushCallBackObject(ani_env *env, NotificationConstant::SlotType slotType, ani_ref pushCallBackObject); + void HandleCheckCallback( + ani_env *env, ani_fn_object fn, ani_object value, const std::shared_ptr &pushCallBackParam); + +private: + int32_t CheckNotification( + ani_env *env, + const std::string ¬ificationData, + const std::shared_ptr &pushCallBackParam); + static bool WarpFunctionResult(ani_env *env, ani_object funcResult, ResultParam &result); + ani_vm *vm_ = nullptr; + std::map pushCallBackObjects_; + std::mutex mutexlock; +}; + +} // namespace NotificationManagerSts +} // namespace OHOS +#endif + diff --git a/frameworks/ets/ani/include/sts_notification_manager.h b/frameworks/ets/ani/include/sts_notification_manager.h index 8c9a089fb..f40c52115 100644 --- a/frameworks/ets/ani/include/sts_notification_manager.h +++ b/frameworks/ets/ani/include/sts_notification_manager.h @@ -22,6 +22,7 @@ #include "notification_button_option.h" #include "notification_local_live_view_subscriber.h" #include "sts_runtime.h" +#include "notification_check_info.h" namespace OHOS { namespace NotificationSts { @@ -138,6 +139,8 @@ ani_status UnWarpNotificationButtonOption(ani_env *env, const ani_object buttonO ani_object WarpNotificationButtonOption(ani_env *env, sptr buttonOption); bool WarpNotificationDoNotDisturbDate( ani_env *env, const std::shared_ptr &date, ani_object &outObj); +bool WarpNotificationCheckInfo( + ani_env *env, const std::shared_ptr &data, ani_object &outObj); } // namespace NotificationSts } // OHOS #endif \ No newline at end of file diff --git a/frameworks/ets/ani/include/sts_request.h b/frameworks/ets/ani/include/sts_request.h index 893d6ce46..02a69f21d 100644 --- a/frameworks/ets/ani/include/sts_request.h +++ b/frameworks/ets/ani/include/sts_request.h @@ -41,6 +41,8 @@ bool WarpNotificationRequest( ani_env *env, const NotificationRequest *notificationRequest, ani_class &cls, ani_object &outAniObj); ani_object GetAniNotificationRequestArray(ani_env *env, std::vector> requests); ani_object GetAniNotificationRequestArrayByNotifocations(ani_env *env, std::vector> requests); + +bool UnWarpNotificationCheckRequest(ani_env *env, ani_object obj, sptr &checkRequest); } // namespace NotificationSts } // OHOS #endif \ No newline at end of file diff --git a/frameworks/ets/ani/include/sts_throw_erro.h b/frameworks/ets/ani/include/sts_throw_erro.h index 6bd3d6d5a..44f75ae9b 100644 --- a/frameworks/ets/ani/include/sts_throw_erro.h +++ b/frameworks/ets/ani/include/sts_throw_erro.h @@ -71,6 +71,18 @@ inline void ThrowStsErroWithMsg(ani_env *env, std::string logMsg) OHOS::AbilityRuntime::ThrowStsError(env, OHOS::Notification::ERROR_INTERNAL_ERROR, FindAnsErrMsg(OHOS::Notification::ERROR_INTERNAL_ERROR)); } + +inline void ThrowStsErrorWithCode(ani_env *env, const int32_t errCode, std::string msg = "") +{ + if (env == nullptr) return; + OHOS::AbilityRuntime::ThrowStsError(env, errCode, msg.empty() ? FindAnsErrMsg(errCode) : msg); +} + +inline void ThrowStsErrorWithInvalidParam(ani_env *env) +{ + ThrowStsErrorWithCode(env, ERROR_PARAM_INVALID); +} + } // namespace NotificationSts } // OHOS #endif diff --git a/frameworks/ets/ani/src/manager/ani_manager.cpp b/frameworks/ets/ani/src/manager/ani_manager.cpp index 4cc8d56c2..ed6f74a8d 100644 --- a/frameworks/ets/ani/src/manager/ani_manager.cpp +++ b/frameworks/ets/ani/src/manager/ani_manager.cpp @@ -24,6 +24,7 @@ #include "ani_publish.h" #include "ani_local_live_view.h" #include "ani_request_enable.h" +#include "ani_on.h" namespace OHOS { namespace NotificationManagerSts { @@ -72,6 +73,13 @@ static std::array kitManagerFunctions = { ani_native_function {"nativeRequestEnableNotification", "Lapplication/UIAbilityContext/UIAbilityContext;:Lstd/core/Promise;", reinterpret_cast(AniRequestEnableNotification)}, + ani_native_function {"nativeOn", + "Lstd/core/String;" + "Lstd/core/Function1;" + "Lnotification/notificationRequest/NotificationCheckRequest;" + ":I", + reinterpret_cast(AniOn)}, + ani_native_function {"nativeOff", "Lstd/core/String;Lstd/core/Function1;:I", reinterpret_cast(AniOff)}, }; void AniNotificationManagerRegistryInit(ani_env *env) diff --git a/frameworks/ets/ani/src/manager/ani_on.cpp b/frameworks/ets/ani/src/manager/ani_on.cpp new file mode 100755 index 000000000..8d4da2c64 --- /dev/null +++ b/frameworks/ets/ani/src/manager/ani_on.cpp @@ -0,0 +1,125 @@ +/* + * 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 "ani_on.h" +#include "ans_log_wrapper.h" +#include "sts_common.h" +#include "sts_throw_erro.h" +#include "sts_request.h" +#include "ani_push_callback.h" +#include "ipc_skeleton.h" +#include "tokenid_kit.h" +#include "notification_helper.h" +#include "inner_errors.h" + +constexpr const char* TYPE_STRING = "checkNotification"; +namespace OHOS { +namespace NotificationManagerSts { +using namespace OHOS::Notification; + +bool CheckCallerIsSystemApp() +{ + auto selfToken = IPCSkeleton::GetSelfTokenID(); + if (!Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(selfToken)) { + ANS_LOGE("current app is not system app, not allow."); + return false; + } + return true; +} + +ani_int AniOn(ani_env *env, ani_string type, ani_fn_object fn, ani_object checkRequestObj) +{ + ANS_LOGD("enter"); +#ifdef ANS_FEATURE_LIVEVIEW_LOCAL_LIVEVIEW + std::string typeStr = ""; + ani_status status = OHOS::NotificationSts::GetStringByAniString(env, type, typeStr); + if (status != ANI_OK || typeStr.compare(TYPE_STRING)) { + ANS_LOGE("InvalidParam 'type'"); + int32_t errCode = OHOS::Notification::ERROR_PARAM_INVALID; + OHOS::NotificationSts::ThrowStsErrorWithInvalidParam(env); + return errCode; + } + if (OHOS::NotificationSts::IsUndefine(env, checkRequestObj)) { + ANS_LOGI("Old function param, don't need register."); + return ERR_OK; + } + sptr checkRequest = new NotificationCheckRequest(); + if (!OHOS::NotificationSts::UnWarpNotificationCheckRequest(env, checkRequestObj, checkRequest)) { + ANS_LOGE("InvalidParam 'checkRequest'"); + int32_t errCode = OHOS::Notification::ERROR_PARAM_INVALID; + OHOS::NotificationSts::ThrowStsErrorWithInvalidParam(env); + return errCode; + } + if (!CheckCallerIsSystemApp()) { + OHOS::NotificationSts::ThrowStsErrorWithCode(env, ERROR_NOT_SYSTEM_APP); + return ERROR_NOT_SYSTEM_APP; + } + + sptr stsPushCallBack_ = new (std::nothrow) StsPushCallBack(env); + if (stsPushCallBack_ == nullptr) { + ANS_LOGE("new stsPushCallBack_ failed"); + OHOS::NotificationSts::ThrowStsErrorWithCode(env, ERROR_INTERNAL_ERROR); + return ERROR_INTERNAL_ERROR; + } + NotificationConstant::SlotType outSlotType = checkRequest->GetSlotType(); + stsPushCallBack_->SetJsPushCallBackObject(env, outSlotType, fn); + auto result = NotificationHelper::RegisterPushCallback(stsPushCallBack_->AsObject(), checkRequest); + if (result != ERR_OK) { + int32_t externalCode = ERR_OK ? ERR_OK : CJSystemapi::Notification::ErrorToExternal(result); + ANS_LOGE("Register failed, result is %{public}d", externalCode); + OHOS::NotificationSts::ThrowStsErrorWithCode(env, externalCode); + return externalCode; + } + ANS_LOGD("done"); + return result; +#else + int32_t errCode = OHOS::Notification::ERROR_SYSTEM_CAP_ERROR; + OHOS::NotificationSts::ThrowStsErrorWithCode(env, errCode); + return errCode; +#endif +} + +ani_int AniOff(ani_env *env, ani_string type, ani_fn_object fn) +{ + ANS_LOGD("enter"); +#ifdef ANS_FEATURE_LIVEVIEW_LOCAL_LIVEVIEW + std::string typeStr = ""; + ani_status status = OHOS::NotificationSts::GetStringByAniString(env, type, typeStr); + if (status != ANI_OK || typeStr.compare(TYPE_STRING)) { + ANS_LOGE("InvalidParam 'type'"); + int32_t errCode = OHOS::Notification::ERROR_PARAM_INVALID; + OHOS::NotificationSts::ThrowStsErrorWithInvalidParam(env); + return errCode; + } + if (!CheckCallerIsSystemApp()) { + OHOS::NotificationSts::ThrowStsErrorWithCode(env, ERROR_NOT_SYSTEM_APP); + return ERROR_NOT_SYSTEM_APP; + } + if (!OHOS::NotificationSts::IsUndefine(env, fn)) { + int32_t errCode = OHOS::Notification::ERROR_PARAM_INVALID; + OHOS::NotificationSts::ThrowStsErrorWithInvalidParam(env); + return errCode; + } + int32_t ret = NotificationHelper::UnregisterPushCallback(); + ANS_LOGD("done. ret %{public}d", ret); + return ERR_OK; +#else + int32_t errCode = OHOS::Notification::ERROR_SYSTEM_CAP_ERROR; + OHOS::NotificationSts::ThrowStsErrorWithCode(env, errCode); + return errCode; +#endif +} +} +} \ No newline at end of file diff --git a/frameworks/ets/ani/src/manager/ani_push_callback.cpp b/frameworks/ets/ani/src/manager/ani_push_callback.cpp new file mode 100755 index 000000000..b20c33fbd --- /dev/null +++ b/frameworks/ets/ani/src/manager/ani_push_callback.cpp @@ -0,0 +1,148 @@ +/* + * 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 "ani_push_callback.h" +#include "ans_log_wrapper.h" +#include "sts_notification_manager.h" +#include "sts_common.h" + +namespace OHOS { +namespace NotificationManagerSts { +using namespace OHOS::Notification; +using namespace OHOS::NotificationSts; +StsPushCallBack::StsPushCallBack(ani_env *env) +{ + if (env == nullptr || env->GetVM(&vm_) != ANI_OK) { + ANS_LOGE("InvalidParam 'env'"); + } +} + +StsPushCallBack::~StsPushCallBack() +{ +} + +int32_t StsPushCallBack::OnCheckNotification( + const std::string ¬ificationData, const std::shared_ptr &pushCallBackParam) +{ + ANS_LOGD("enter"); + std::lock_guard l(mutexlock); + if (vm_ == nullptr || pushCallBackParam == nullptr) { + ANS_LOGE("InvalidParam"); + return ERR_INVALID_STATE; + } + ani_env* env; + ani_status aniResult = ANI_ERROR; + if (ANI_OK != (aniResult = vm_->GetEnv(ANI_VERSION_1, &env))) { + ANS_LOGD("GetEnv error. result: %{public}d.", aniResult); + return ERR_INVALID_STATE; + } + return CheckNotification(env, notificationData, pushCallBackParam); +} + +void StsPushCallBack::SetJsPushCallBackObject( + ani_env *env, NotificationConstant::SlotType slotType, ani_ref pushCallBackObject) +{ + ANS_LOGD("enter"); + if (env == nullptr || pushCallBackObject == nullptr) { + ANS_LOGE("InvalidParam"); + return; + } + ani_ref pushCheckObject; + ani_status status = ANI_OK; + if (ANI_OK != (status = env->GlobalReference_Create(pushCallBackObject, &pushCheckObject))) { + ANS_LOGE("GlobalReference_Create pushCallBackObject faild. status %{public}d", status); + return; + } + pushCallBackObjects_.insert_or_assign(slotType, pushCheckObject); +} + +void StsPushCallBack::HandleCheckCallback( + ani_env *env, ani_fn_object fn, ani_object value, const std::shared_ptr &pushCallBackParam) +{ + ANS_LOGD("enter"); + if (env == nullptr || fn == nullptr || value == nullptr || pushCallBackParam == nullptr) { + ANS_LOGE("pushCallBackObjects is nullptr"); + return; + } + std::vector vec; + vec.push_back(value); + ani_ref funcResult; + ani_status status = ANI_OK; + if (ANI_OK != (status = env->FunctionalObject_Call(fn, vec.size(), vec.data(), &funcResult))) { + ANS_LOGE("FunctionalObject_Call faild. status %{public}d", status); + return; + } + ResultParam result; + if (!WarpFunctionResult(env, static_cast(funcResult), result)) { + ANS_LOGE("WarpFunctionResult faild"); + return; + } + std::unique_lock uniqueLock(pushCallBackParam->callBackMutex); + pushCallBackParam->result = result.code; + pushCallBackParam->ready = true; + pushCallBackParam->callBackCondition.notify_all(); + ANS_LOGD("done"); +} + +int32_t StsPushCallBack::CheckNotification( + ani_env *env, + const std::string ¬ificationData, + const std::shared_ptr &pushCallBackParam) +{ + ANS_LOGD("enter"); + auto checkInfo = std::make_shared(); + checkInfo->ConvertJsonStringToValue(notificationData); + NotificationConstant::SlotType outSlotType = static_cast(checkInfo->GetSlotType()); + if (pushCallBackObjects_.find(outSlotType) == pushCallBackObjects_.end()) { + ANS_LOGE("pushCallBackObjects is nullptr"); + return ERR_INVALID_STATE; + } + ani_object checkInfoObj; + if (!WarpNotificationCheckInfo(env, checkInfo, checkInfoObj) || checkInfoObj == nullptr) { + ANS_LOGE("WarpNotificationCheckInfo faild"); + return ERR_INVALID_STATE; + } + HandleCheckCallback( + env, static_cast(pushCallBackObjects_[outSlotType]), checkInfoObj, pushCallBackParam); + return ERR_OK; +} + +bool StsPushCallBack::WarpFunctionResult(ani_env *env, ani_object obj, ResultParam &result) +{ + ANS_LOGD("enter"); + if (env == nullptr || obj == nullptr) return false; + ani_status status = ANI_OK; + ani_double code; + ani_ref msg; + std::string message = ""; + if (ANI_OK != (status = env->Object_GetPropertyByName_Double(obj, "code", &code))) { + ANS_LOGE("WarpFunctionResult. code faild. status %{public}d", status); + return false; + } + if (ANI_OK != (status = env->Object_GetPropertyByName_Ref(obj, "message", &msg))) { + ANS_LOGE("WarpFunctionResult. message faild. status %{public}d", status); + return false; + } + if (ANI_OK != (status = GetStringByAniString(env, static_cast(msg), message))) { + ANS_LOGE("GetStringByAniString faild. status %{public}d", status); + return false; + } + result.code = code; + result.msg = message; + ANS_LOGD("WarpFunctionResult: code %{public}d message %{public}s", result.code, result.msg.c_str()); + return true; +} +} +} \ No newline at end of file diff --git a/frameworks/ets/ani/src/sts_action_button.cpp b/frameworks/ets/ani/src/sts_action_button.cpp index 7b5288f74..26968f752 100644 --- a/frameworks/ets/ani/src/sts_action_button.cpp +++ b/frameworks/ets/ani/src/sts_action_button.cpp @@ -146,7 +146,7 @@ bool SetNotificationActionButtonByRequiredParameter( } ani_string stringValue; // title: string; - if (!GetAniStringByString(env, actionButton->GetTitle(), stringValue)) { + if (ANI_OK != GetAniStringByString(env, actionButton->GetTitle(), stringValue)) { ANS_LOGE("SetActionButtonByRequiredParameter: Get title failed"); return false; } diff --git a/frameworks/ets/ani/src/sts_bundle_option.cpp b/frameworks/ets/ani/src/sts_bundle_option.cpp index 4da10d202..c2e8937b8 100644 --- a/frameworks/ets/ani/src/sts_bundle_option.cpp +++ b/frameworks/ets/ani/src/sts_bundle_option.cpp @@ -95,7 +95,7 @@ bool WrapBundleOption(ani_env* env, } // bundle: string; ani_string stringValue = nullptr; - if (!GetAniStringByString(env, bundleOption->GetBundleName(), stringValue) + if (ANI_OK != GetAniStringByString(env, bundleOption->GetBundleName(), stringValue) || !CallSetter(env, bundleCls, bundleObject, "bundle", stringValue)) { ANS_LOGE("WrapBundleOption: set bundle failed"); return false; diff --git a/frameworks/ets/ani/src/sts_common.cpp b/frameworks/ets/ani/src/sts_common.cpp index 44ecf2cc0..f8f25b2f7 100644 --- a/frameworks/ets/ani/src/sts_common.cpp +++ b/frameworks/ets/ani/src/sts_common.cpp @@ -93,8 +93,8 @@ bool GetStringArrayByAniObj(ani_env *env, const ani_object ani_obj, std::vector< return false; } std::string std_string; - if (!GetStringByAniString(env, static_cast(stringEntryRef), std_string)) { - ANS_LOGE("GetStdString faild"); + if (ANI_OK != (status = GetStringByAniString(env, static_cast(stringEntryRef), std_string))) { + ANS_LOGE("GetStdString faild. status %{public}d", status); return false; } stdVString.emplace_back(std_string); diff --git a/frameworks/ets/ani/src/sts_notification_manager.cpp b/frameworks/ets/ani/src/sts_notification_manager.cpp index 45e711814..dfd92189c 100644 --- a/frameworks/ets/ani/src/sts_notification_manager.cpp +++ b/frameworks/ets/ani/src/sts_notification_manager.cpp @@ -15,6 +15,7 @@ #include "sts_notification_manager.h" #include "sts_common.h" #include "ani_common_util.h" +#include "ani_common_want.h" namespace OHOS { namespace NotificationSts { @@ -462,5 +463,154 @@ bool WarpNotificationDoNotDisturbDate( ANS_LOGD("WarpNotificationDoNotDisturbDate end"); return true; } + +bool SetCheckInfoContentType(ani_env *env, ani_object &obj, const std::string &name, ContentType type) +{ + if (env == nullptr || obj == nullptr || name.empty()) { + ANS_LOGE("InvalidParam"); + return false; + } + STSContentType stsType = NOTIFICATION_CONTENT_BASIC_TEXT; + ani_enum_item item; + if (!StsContentTypeUtils::CToSts(type, stsType)) { + ANS_LOGE("CToSts 'contentType' faild."); + return false; + } + if (!EnumConvertNativeToAni(env, "L@ohos/notificationManager/notificationManager/ContentType;", stsType, item)) { + ANS_LOGE("EnumConvertNativeToAni 'contentType' faild."); + return false; + } + if (!SetPropertyByRef(env, obj, name.c_str(), static_cast(item))) { + ANS_LOGE("SetPropertyByRef 'contentType' faild."); + return false; + } + return true; +} + +bool SetCheckInfoSlotType(ani_env *env, ani_object &obj, const std::string &name, SlotType type) +{ + if (env == nullptr || obj == nullptr || name.empty()) { + ANS_LOGE("InvalidParam"); + return false; + } + STSSlotType stsType = UNKNOWN_TYPE; + ani_enum_item item; + if (!StsSlotTypeUtils::CToSts(type, stsType)) { + ANS_LOGE("CToSts 'slotType' faild."); + return false; + } + if (!EnumConvertNativeToAni(env, "L@ohos/notificationManager/notificationManager/SlotType;", stsType, item)) { + ANS_LOGE("EnumConvertNativeToAni 'slotType' faild."); + return false; + } + if (!SetPropertyByRef(env, obj, name.c_str(), static_cast(item))) { + ANS_LOGE("SetPropertyByRef 'slotType' faild."); + return false; + } + return true; +} + +bool SetNotificationCheckInfoNumber( + ani_env *env, const std::shared_ptr &data, ani_object &outObj) +{ + ani_status status = ANI_OK; + // notificationId: number; + if (ANI_OK != (status = env->Object_SetPropertyByName_Double( + outObj, "notificationId", static_cast(data->GetNotifyId())))) { + ANS_LOGE("WarpNotificationCheckInfo. set 'notificationId' faild. status %{public}d", status); + return false; + } + // creatorUserId: number; + if (ANI_OK != (status = env->Object_SetPropertyByName_Double( + outObj, "creatorUserId", static_cast(data->GetCreatorUserId())))) { + ANS_LOGE("WarpNotificationCheckInfo. set 'creatorUserId' faild. status %{public}d", status); + return false; + } + return true; +} + +bool SetNotificationCheckInfoString( + ani_env *env, const std::shared_ptr &data, ani_object &outObj) +{ + // bundleName: string; + if (!SetPropertyOptionalByString(env, outObj, "bundleName", data->GetPkgName())) { + ANS_LOGE("WarpNotificationCheckInfo set 'bundleName' faild"); + return false; + } + // label?: string; + if (!data->GetLabel().empty() && !SetPropertyOptionalByString(env, outObj, "label", data->GetLabel())) { + ANS_LOGE("WarpNotificationCheckInfo set 'label' faild"); + return false; + } + return true; +} + +bool SetNotificationCheckInfoEnum( + ani_env *env, const std::shared_ptr &data, ani_object &outObj) +{ + // contentType: ContentType; + if (!SetCheckInfoContentType(env, outObj, "contentType", static_cast(data->GetContentType()))) { + ANS_LOGE("WarpNotificationCheckInfo set 'contentType' faild"); + return false; + } + // slotType: SlotType; + if (!SetCheckInfoSlotType(env, outObj, "slotType", static_cast(data->GetSlotType()))) { + ANS_LOGE("WarpNotificationCheckInfo set 'slotType' faild"); + return false; + } + return true; +} + +bool SetNotificationCheckInfo( + ani_env *env, const std::shared_ptr &data, ani_object &outObj) +{ + if (!SetNotificationCheckInfoNumber(env, data, outObj)) { + ANS_LOGE("SetNotificationCheckInfoNumber faild"); + return false; + } + if (!SetNotificationCheckInfoString(env, data, outObj)) { + ANS_LOGE("SetNotificationCheckInfoString faild"); + return false; + } + if (!SetNotificationCheckInfoEnum(env, data, outObj)) { + ANS_LOGE("SetNotificationCheckInfoEnum faild"); + return false; + } + // extraInfos?: Record; + if (data->GetExtraInfo() != nullptr) { + ani_ref extraInfos = OHOS::AppExecFwk::WrapWantParams(env, *(data->GetExtraInfo())); + if (extraInfos == nullptr) { + ANS_LOGE("WrapWantParams 'extraInfos' faild"); + return false; + } + if (!SetPropertyByRef(env, outObj, "extraInfos", extraInfos)) { + ANS_LOGE("WarpNotificationCheckInfo set 'extraInfos' faild"); + return false; + } + } + return true; +} + +bool WarpNotificationCheckInfo( + ani_env *env, const std::shared_ptr &data, ani_object &outObj) +{ + ani_object obj; + ani_class cls; + if (env == nullptr || data == nullptr) { + ANS_LOGE("InvalidParam"); + return false; + } + if (!CreateClassObjByClassName( + env, "L@ohos/notificationManager/notificationManager/NotificationCheckInfoInner;", cls, obj)) { + ANS_LOGE("WarpNotificationCheckInfo create faild"); + return false; + } + if (!SetNotificationCheckInfo(env, data, obj)) { + ANS_LOGE("SetNotificationCheckInfo faild"); + return false; + } + outObj = obj; + return true; +} } // namespace NotificationSts } // OHOS \ No newline at end of file diff --git a/frameworks/ets/ani/src/sts_request.cpp b/frameworks/ets/ani/src/sts_request.cpp index 7c9cc45d9..ed25b307b 100644 --- a/frameworks/ets/ani/src/sts_request.cpp +++ b/frameworks/ets/ani/src/sts_request.cpp @@ -1203,5 +1203,87 @@ ani_object GetAniNotificationRequestArrayByNotifocations(ani_env *env, std::vect } return arrayObj; } + +bool GetCheckRequestContent(ani_env *env, ani_object obj, NotificationContent::Type &outContentType) +{ + ani_status status = ANI_OK; + ani_ref contentAniType; + STSContentType contentType = NOTIFICATION_CONTENT_BASIC_TEXT; + if (ANI_OK != (status = env->Object_GetPropertyByName_Ref(obj, "contentType", &contentAniType))) { + ANS_LOGE("GetCheckRequestContent get contentType faild. status %{public}d", status); + return false; + } + if (contentAniType == nullptr || + !EnumConvertAniToNative(env, static_cast(contentAniType), contentType)) { + ANS_LOGE("EnumConvertAniToNative contentType faild"); + return false; + } + if (!StsContentTypeUtils::StsToC(contentType, outContentType)) { + ANS_LOGE("StsToC contentType faild"); + return false; + } + return true; +} + +bool GetCheckRequestSlotType(ani_env *env, ani_object obj, NotificationConstant::SlotType &outSlotType) +{ + ani_status status = ANI_OK; + ani_ref slotAniType; + STSSlotType slotType = UNKNOWN_TYPE; + if (ANI_OK != (status = env->Object_GetPropertyByName_Ref(obj, "slotType", &slotAniType))) { + ANS_LOGE("UnWarpNotificationCheckRequest get slotType faild. status %{public}d", status); + return false; + } + if (slotAniType == nullptr || !EnumConvertAniToNative(env, static_cast(slotAniType), slotType)) { + ANS_LOGE("EnumConvertAniToNative slotType faild"); + return false; + } + if (!StsSlotTypeUtils::StsToC(slotType, outSlotType)) { + ANS_LOGE("StsToC slotType faild"); + return false; + } + return true; +} + +bool UnWarpNotificationCheckRequest(ani_env *env, ani_object obj, sptr &checkRequest) +{ + if (env == nullptr || obj == nullptr || checkRequest == nullptr) { + ANS_LOGE("UnWarpNotificationCheckRequest invalid parameters"); + return false; + } + ani_status status = ANI_OK; + ani_ref extraInfoKeysObj; + NotificationContent::Type outContentType = NotificationContent::Type::NONE; + NotificationConstant::SlotType outSlotType = NotificationConstant::SlotType::OTHER; + std::vector extraInfoKeys; + // contentType: notificationManager.ContentType; + if (!GetCheckRequestContent(env, obj, outContentType)) { + ANS_LOGE("GetCheckRequestContent faild."); + return false; + } + checkRequest->SetContentType(outContentType); + // slotType: notificationManager.SlotType; + if (!GetCheckRequestSlotType(env, obj, outSlotType)) { + ANS_LOGE("GetCheckRequestSlotType faild."); + return false; + } + checkRequest->SetSlotType(outSlotType); + // extraInfoKeys: Array; + if (ANI_OK != (status = env->Object_GetPropertyByName_Ref(obj, "extraInfoKeys", &extraInfoKeysObj))) { + ANS_LOGE("UnWarpNotificationCheckRequest get extraInfoKeys faild. status %{public}d", status); + return false; + } + if (!GetStringArrayByAniObj(env, static_cast(extraInfoKeysObj), extraInfoKeys)) { + ANS_LOGE("UnWarpNotificationCheckRequest. extraInfoKeys GetStringArrayByAniObj faild."); + return false; + } + checkRequest->SetExtraKeys(extraInfoKeys); + ANS_LOGD("contentType %{public}d slotType %{public}d", + checkRequest->GetContentType(), checkRequest->GetSlotType()); + for (auto &it : checkRequest->GetExtraKeys()) { + ANS_LOGD("extrakey %{public}s", it.c_str()); + } + return true; +} } // namespace NotificationSts } // OHOS \ No newline at end of file diff --git a/frameworks/ets/ani/src/sts_subscribe.cpp b/frameworks/ets/ani/src/sts_subscribe.cpp index 11f2dd82c..441e053c1 100644 --- a/frameworks/ets/ani/src/sts_subscribe.cpp +++ b/frameworks/ets/ani/src/sts_subscribe.cpp @@ -481,9 +481,9 @@ bool StsSubscriberInstance::CallFunction(ani_env *env, const char *func, std::ve ANS_LOGD("enter"); if (env == nullptr) return false; ani_ref fn_ref; - ani_status aniResult = env->Object_GetFieldByName_Ref(static_cast(ref_), func, &fn_ref); + ani_status aniResult = env->Object_GetPropertyByName_Ref(static_cast(ref_), func, &fn_ref); if (ANI_OK != aniResult) { - ANS_LOGD("Object_GetFieldByName_Ref '%{public}s' error. result: %{public}d.", func, aniResult); + ANS_LOGD("Object_GetPropertyByName_Ref '%{public}s' error. result: %{public}d.", func, aniResult); return false; } ani_boolean IsUndefined = ANI_FALSE; diff --git a/frameworks/ets/ets/@ohos.notificationManager.ets b/frameworks/ets/ets/@ohos.notificationManager.ets index 999fa9b11..7dcb4589e 100644 --- a/frameworks/ets/ets/@ohos.notificationManager.ets +++ b/frameworks/ets/ets/@ohos.notificationManager.ets @@ -16,7 +16,7 @@ import { BundleOption } from 'notification.NotificationCommonDef'; import { BusinessError, AsyncCallback } from '@ohos.base'; import { NotificationSlot } from 'notification.notificationSlot'; -import { NotificationRequest } from 'notification.notificationRequest'; +import { NotificationRequest, NotificationCheckRequest } from 'notification.notificationRequest'; import UIAbilityContext from 'application.UIAbilityContext'; import { NotificationBasicContent } from 'notification.notificationContent'; import { NotificationLongTextContent } from 'notification.notificationContent'; @@ -31,6 +31,8 @@ import image from '@ohos.multimedia.image'; type ResolveCallback = (data: T) => void; type RejectCallback = (err: Object) => void; +type CallbackForCheckInfo = + (checkInfo: notificationManager.NotificationCheckInfo)=> notificationManager.NotificationCheckResult; const ERROR_OK = 0; const ERROR_PARAM_INVALID = 401; @@ -159,6 +161,11 @@ export default namespace notificationManager { export native function nativeSetNotificationEnable(bundle: BundleOption, enable: boolean): void; export native function nativeRequestEnableNotification(content: UIAbilityContext): Promise; + export native function nativeOn( + type: 'checkNotification', callback: CallbackForCheckInfo, checkRequest?: NotificationCheckRequest): int; + export native function nativeOff( + type: 'checkNotification', callback?: CallbackForCheckInfo): int; + function isInvalidParameter(bundle: BundleOption): BusinessError { let error: BusinessError = { @@ -1302,4 +1309,91 @@ export default namespace notificationManager { } ) } + + export interface NotificationCheckResult { + code: number; + message: string; + } + + class NotificationCheckResultInner implements NotificationCheckResult { + public code: number = -1; + public message: string = ''; + } + + export function on( + type: 'checkNotification', callback: (checkInfo: NotificationCheckInfo) => NotificationCheckResult): void + { + let errCode = nativeOn(type, callback); + if (errCode != 0) { + const error: BusinessError = {code: errCode, message: "unknown error"}; + throw error; + } + } + + export function on(type: 'checkNotification', checkRequest: NotificationCheckRequest, + callback: (checkInfo: NotificationCheckInfo) => Promise): void + { + let onFuncCallback: CallbackForCheckInfo = + (checkInfo: notificationManager.NotificationCheckInfo): notificationManager.NotificationCheckResult => { + let result: notificationManager.NotificationCheckResult = { + code: -1, + message: 'unknown error' + }; + let p = callback(checkInfo); + await p.then( + (e: NullishType): void => { + result = e as notificationManager.NotificationCheckResult; + }, (error: Object): void => { + let err: BusinessError = error as BusinessError; + result = { + code: err.code, + message: err.message + }; + } + ); + return result; + }; + let errCode = nativeOn(type, onFuncCallback, checkRequest); + if (errCode != 0) { + const error: BusinessError = {code: errCode, message: "unknown error"}; + throw error; + } + } + + export function off( + type: 'checkNotification', + callback?: (checkInfo: NotificationCheckInfo) => NotificationCheckResult + ): void + { + let errCode = -1; + if (callback === undefined) { + errCode = nativeOff(type); + } else { + errCode = nativeOff(type, callback); + } + if (errCode != 0) { + const error: BusinessError = {code: errCode, message: "unknown error"}; + throw error; + } + } + + export interface NotificationCheckInfo { + bundleName: string; + notificationId: number; + label?: string; + contentType: ContentType; + creatorUserId: number; + slotType: SlotType; + extraInfos?: Record; + } + + class NotificationCheckInfoInner implements NotificationCheckInfo { + public bundleName: string = ''; + public notificationId: number = -1; + public label?: string; + public contentType: ContentType = ContentType.NOTIFICATION_CONTENT_BASIC_TEXT; + public creatorUserId: number = -1; + public slotType: SlotType = SlotType.UNKNOWN_TYPE; + public extraInfos?: Record; + } } \ No newline at end of file -- Gitee