From 8caa46c09f6d85e30621588615e2ca242224b226 Mon Sep 17 00:00:00 2001 From: XKK Date: Fri, 7 Jul 2023 10:52:03 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BC=B9=E7=AA=97=E7=BB=91=E5=AE=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: XKK --- frameworks/ans/src/notification_helper.cpp | 5 ++ .../core/include/ans_manager_interface.h | 4 ++ frameworks/core/include/ans_manager_proxy.h | 2 + frameworks/core/include/ans_manager_stub.h | 4 ++ frameworks/core/include/ans_notification.h | 2 + ..._notification_service_ipc_interface_code.h | 1 + frameworks/core/src/ans_manager_proxy.cpp | 34 ++++++++++++ frameworks/core/src/ans_manager_stub.cpp | 28 ++++++++++ frameworks/core/src/ans_notification.cpp | 10 ++++ frameworks/js/napi/BUILD.gn | 1 + .../js/napi/include/enable_notification.h | 2 + .../js/napi/src/enable_notification.cpp | 16 +++++- frameworks/js/napi/src/manager/BUILD.gn | 1 + .../src/manager/napi_enable_notification.cpp | 9 +++- interfaces/inner_api/notification_helper.h | 2 + .../include/advanced_notification_service.h | 2 + services/ans/include/notification_dialog.h | 2 + .../ans/src/advanced_notification_service.cpp | 42 +++++++++++++++ services/ans/src/notification_dialog.cpp | 19 +++++++ .../NotificationServiceExtAbility.ts | 53 +++++++++++++++---- 20 files changed, 226 insertions(+), 13 deletions(-) diff --git a/frameworks/ans/src/notification_helper.cpp b/frameworks/ans/src/notification_helper.cpp index 0fc8750b9..ae6ff17e6 100644 --- a/frameworks/ans/src/notification_helper.cpp +++ b/frameworks/ans/src/notification_helper.cpp @@ -149,6 +149,11 @@ ErrCode NotificationHelper::RequestEnableNotification(std::string &deviceId) return DelayedSingleton::GetInstance()->RequestEnableNotification(deviceId); } +ErrCode NotificationHelper::RequestEnableNotification(std::string &deviceId, sptr &callerToken) +{ + return DelayedSingleton::GetInstance()->RequestEnableNotification(deviceId, callerToken); +} + ErrCode NotificationHelper::HasNotificationPolicyAccessPermission(bool &hasPermission) { return DelayedSingleton::GetInstance()->HasNotificationPolicyAccessPermission(hasPermission); diff --git a/frameworks/core/include/ans_manager_interface.h b/frameworks/core/include/ans_manager_interface.h index ccccdcd2f..a8568e6d7 100644 --- a/frameworks/core/include/ans_manager_interface.h +++ b/frameworks/core/include/ans_manager_interface.h @@ -320,6 +320,10 @@ public: */ virtual ErrCode RequestEnableNotification(const std::string &deviceId) = 0; + + virtual ErrCode RequestEnableNotification(const std::string &deviceId, const sptr &callerToken) = 0; + + /** * @brief Set whether to allow the specified deviceId to send notifications for current bundle. * diff --git a/frameworks/core/include/ans_manager_proxy.h b/frameworks/core/include/ans_manager_proxy.h index a73751a9e..fbaea14bd 100644 --- a/frameworks/core/include/ans_manager_proxy.h +++ b/frameworks/core/include/ans_manager_proxy.h @@ -309,6 +309,8 @@ public: */ ErrCode RequestEnableNotification(const std::string &deviceId) override; + ErrCode RequestEnableNotification(const std::string &deviceId, const sptr &callerToken) override; + /** * @brief Set whether to allow the specified deviceId to send notifications for current bundle. * diff --git a/frameworks/core/include/ans_manager_stub.h b/frameworks/core/include/ans_manager_stub.h index b91aeef02..8a2e665f4 100644 --- a/frameworks/core/include/ans_manager_stub.h +++ b/frameworks/core/include/ans_manager_stub.h @@ -325,6 +325,9 @@ public: ErrCode RequestEnableNotification( const std::string &deviceId) override; + virtual ErrCode RequestEnableNotification( + const std::string &deviceId, const sptr &callerToken) override; + /** * @brief Set whether to allow the specified deviceId to send notifications for current bundle. * @@ -760,6 +763,7 @@ private: ErrCode HandleSetBadgeNumber(MessageParcel &data, MessageParcel &reply); ErrCode HandleRegisterPushCallback(MessageParcel &data, MessageParcel &reply); ErrCode HandleUnregisterPushCallback(MessageParcel &data, MessageParcel &reply); + ErrCode HandleEnableRequestByToken(MessageParcel &data, MessageParcel &reply); template bool WriteParcelableVector(const std::vector> &parcelableVector, MessageParcel &reply, ErrCode &result); diff --git a/frameworks/core/include/ans_notification.h b/frameworks/core/include/ans_notification.h index 0794a5c4c..aeb3a9ffa 100644 --- a/frameworks/core/include/ans_notification.h +++ b/frameworks/core/include/ans_notification.h @@ -264,6 +264,8 @@ public: */ ErrCode RequestEnableNotification(std::string &deviceId); + ErrCode RequestEnableNotification(std::string &deviceId, sptr &callerToken); + /** * @brief Checks whether this application has permission to modify the Do Not Disturb (DND) notification policy. * diff --git a/frameworks/core/include/distributed_notification_service_ipc_interface_code.h b/frameworks/core/include/distributed_notification_service_ipc_interface_code.h index 959baaa8d..c606860fb 100644 --- a/frameworks/core/include/distributed_notification_service_ipc_interface_code.h +++ b/frameworks/core/include/distributed_notification_service_ipc_interface_code.h @@ -117,6 +117,7 @@ namespace Notification { ON_BADGE_CHANGED, // push_callback_interface ON_CHECK_NOTIFICATION, + REQUEST_ENABLE_NOTIFICATION_BY_TOKEN, }; } } diff --git a/frameworks/core/src/ans_manager_proxy.cpp b/frameworks/core/src/ans_manager_proxy.cpp index 7afd2eb3d..d4b7afe95 100644 --- a/frameworks/core/src/ans_manager_proxy.cpp +++ b/frameworks/core/src/ans_manager_proxy.cpp @@ -1079,6 +1079,40 @@ ErrCode AnsManagerProxy::RequestEnableNotification(const std::string &deviceId) return result; } +ErrCode AnsManagerProxy::RequestEnableNotification(const std::string &deviceId, const sptr &callerToken) +{ + ANS_LOGI("enter"); + MessageParcel data; + if (!data.WriteInterfaceToken(AnsManagerProxy::GetDescriptor())) { + ANS_LOGE("[RequestEnableNotification] fail: write interface token failed."); + return ERR_ANS_PARCELABLE_FAILED; + } + + if (!data.WriteString(deviceId)) { + ANS_LOGE("[RequestEnableNotification] fail: write deviceId failed"); + return ERR_ANS_PARCELABLE_FAILED; + } + + if (!data.WriteRemoteObject(callerToken)) { + ANS_LOGE("fail: write callerToken failed"); + return ERR_ANS_PARCELABLE_FAILED; + } + + MessageParcel reply; + MessageOption option = {MessageOption::TF_SYNC}; + ErrCode result = InnerTransact(NotificationInterfaceCode::REQUEST_ENABLE_NOTIFICATION_BY_TOKEN, option, data, reply); + if (result != ERR_OK) { + ANS_LOGE("[RequestEnableNotification] fail: transact ErrCode=%{public}d", result); + return ERR_ANS_TRANSACT_FAILED; + } + + if (!reply.ReadInt32(result)) { + ANS_LOGE("[RequestEnableNotification] fail: read result failed."); + return ERR_ANS_PARCELABLE_FAILED; + } + return result; +} + ErrCode AnsManagerProxy::SetNotificationsEnabledForBundle(const std::string &deviceId, bool enabled) { MessageParcel data; diff --git a/frameworks/core/src/ans_manager_stub.cpp b/frameworks/core/src/ans_manager_stub.cpp index 1ac0f75a4..dc74853f5 100644 --- a/frameworks/core/src/ans_manager_stub.cpp +++ b/frameworks/core/src/ans_manager_stub.cpp @@ -251,6 +251,10 @@ const std::map callerToken = data.ReadRemoteObject(); + + ErrCode result = RequestEnableNotification(deviceId, callerToken); + if (!reply.WriteInt32(result)) { + ANS_LOGE("[HandleRequestEnableNotification] fail: write result failed, ErrCode=%{public}d", result); + return ERR_ANS_PARCELABLE_FAILED; + } + return ERR_OK; +} + ErrCode AnsManagerStub::HandleSetNotificationsEnabledForBundle(MessageParcel &data, MessageParcel &reply) { std::string deviceId; @@ -1976,6 +1998,12 @@ ErrCode AnsManagerStub::RequestEnableNotification(const std::string &deviceId) return ERR_INVALID_OPERATION; } +ErrCode AnsManagerStub::RequestEnableNotification(const std::string &deviceId, const sptr &callerToken) +{ + ANS_LOGE("AnsManagerStub::RequestEnableNotification called!"); + return ERR_INVALID_OPERATION; +} + ErrCode AnsManagerStub::SetNotificationsEnabledForBundle(const std::string &bundle, bool enabled) { ANS_LOGE("AnsManagerStub::SetNotificationsEnabledForBundle called!"); diff --git a/frameworks/core/src/ans_notification.cpp b/frameworks/core/src/ans_notification.cpp index feea0bbbc..3ce36cac6 100644 --- a/frameworks/core/src/ans_notification.cpp +++ b/frameworks/core/src/ans_notification.cpp @@ -336,6 +336,16 @@ ErrCode AnsNotification::RequestEnableNotification(std::string &deviceId) return ansManagerProxy_->RequestEnableNotification(deviceId); } +ErrCode AnsNotification::RequestEnableNotification(std::string &deviceId, sptr &callerToken) +{ + ANS_LOGD("enter"); + if (!GetAnsManagerProxy()) { + ANS_LOGE("GetAnsManagerProxy fail."); + return ERR_ANS_SERVICE_NOT_CONNECTED; + } + return ansManagerProxy_->RequestEnableNotification(deviceId, callerToken); +} + ErrCode AnsNotification::HasNotificationPolicyAccessPermission(bool &hasPermission) { if (!GetAnsManagerProxy()) { diff --git a/frameworks/js/napi/BUILD.gn b/frameworks/js/napi/BUILD.gn index 635ff71a2..8637c67fb 100644 --- a/frameworks/js/napi/BUILD.gn +++ b/frameworks/js/napi/BUILD.gn @@ -76,6 +76,7 @@ ohos_shared_library("notification") { external_deps = [ "ability_base:want", "ability_base:zuri", + "ability_runtime:napi_base_context", "ability_runtime:ability_manager", "ability_runtime:abilitykit_native", "ability_runtime:app_context", diff --git a/frameworks/js/napi/include/enable_notification.h b/frameworks/js/napi/include/enable_notification.h index 9c76362c5..182f495e0 100644 --- a/frameworks/js/napi/include/enable_notification.h +++ b/frameworks/js/napi/include/enable_notification.h @@ -31,6 +31,8 @@ struct IsEnableParams { int32_t userId = SUBSCRIBE_USER_INIT; bool hasUserId = false; bool allowToPop = false; + sptr callerToken = nullptr; + bool hasCallerToken = false; }; struct AsyncCallbackInfoIsEnable { diff --git a/frameworks/js/napi/src/enable_notification.cpp b/frameworks/js/napi/src/enable_notification.cpp index a7a7e7e46..5f4d2e827 100644 --- a/frameworks/js/napi/src/enable_notification.cpp +++ b/frameworks/js/napi/src/enable_notification.cpp @@ -16,6 +16,7 @@ #include #include "enable_notification.h" #include "ability_manager_client.h" +#include "napi_base_context.h" namespace OHOS { namespace NotificationNapi { @@ -94,9 +95,20 @@ napi_value ParseParameters(const napi_env &env, const napi_callback_info &info, auto retValue = Common::GetBundleOption(env, argv[PARAM0], params.option); if (retValue == nullptr) { ANS_LOGE("GetBundleOption failed."); - return nullptr; + bool stageMode = false; + napi_status status = OHOS::AbilityRuntime::IsStageContext(env, argv[PARAM0], stageMode); + if (status == napi_ok && stageMode) { + auto context = OHOS::AbilityRuntime::GetStageModeContext(env, argv[PARAM0]); + sptr callerToken = context->GetToken(); + params.callerToken = callerToken; + params.hasCallerToken = true; + } else { + return nullptr; + } + } + if (retValue != nullptr) { + params.hasBundleOption = true; } - params.hasBundleOption = true; } else if (valuetype == napi_number) { NAPI_CALL(env, napi_get_value_int32(env, argv[PARAM0], ¶ms.userId)); params.hasUserId = true; diff --git a/frameworks/js/napi/src/manager/BUILD.gn b/frameworks/js/napi/src/manager/BUILD.gn index cf5a0f870..b9acf60fb 100644 --- a/frameworks/js/napi/src/manager/BUILD.gn +++ b/frameworks/js/napi/src/manager/BUILD.gn @@ -74,6 +74,7 @@ ohos_shared_library("notificationmanager") { "ability_base:zuri", "ability_runtime:ability_manager", "ability_runtime:abilitykit_native", + "ability_runtime:napi_base_context", "ability_runtime:app_context", "ability_runtime:napi_common", "ability_runtime:runtime", diff --git a/frameworks/js/napi/src/manager/napi_enable_notification.cpp b/frameworks/js/napi/src/manager/napi_enable_notification.cpp index d5358fd0d..2e5339373 100644 --- a/frameworks/js/napi/src/manager/napi_enable_notification.cpp +++ b/frameworks/js/napi/src/manager/napi_enable_notification.cpp @@ -276,8 +276,13 @@ napi_value NapiRequestEnableNotification(napi_env env, napi_callback_info info) AsyncCallbackInfoIsEnable *asynccallbackinfo = static_cast(data); if (asynccallbackinfo) { std::string deviceId {""}; - asynccallbackinfo->info.errorCode = - NotificationHelper::RequestEnableNotification(deviceId); + if (asynccallbackinfo->params.hasCallerToken) { + asynccallbackinfo->info.errorCode = + NotificationHelper::RequestEnableNotification(deviceId, asynccallbackinfo->params.callerToken); + } else { + asynccallbackinfo->info.errorCode = + NotificationHelper::RequestEnableNotification(deviceId); + } } }, [](napi_env env, napi_status status, void *data) { diff --git a/interfaces/inner_api/notification_helper.h b/interfaces/inner_api/notification_helper.h index 6956d1b8d..08d622b74 100644 --- a/interfaces/inner_api/notification_helper.h +++ b/interfaces/inner_api/notification_helper.h @@ -266,6 +266,8 @@ public: */ static ErrCode RequestEnableNotification(std::string &deviceId); + static ErrCode RequestEnableNotification(std::string &deviceId, sptr &callerToken); + /** * @brief Checks whether this application has permission to modify the Do Not Disturb (DND) notification policy. * diff --git a/services/ans/include/advanced_notification_service.h b/services/ans/include/advanced_notification_service.h index c5e3f0aaf..ce0b5537c 100644 --- a/services/ans/include/advanced_notification_service.h +++ b/services/ans/include/advanced_notification_service.h @@ -335,6 +335,8 @@ public: */ ErrCode RequestEnableNotification(const std::string &deviceId) override; + ErrCode RequestEnableNotification(const std::string &deviceId, const sptr &callerToken) override; + /** * @brief Set whether to allow the specified deviceId to send notifications for current bundle. * diff --git a/services/ans/include/notification_dialog.h b/services/ans/include/notification_dialog.h index a47a54b8b..f400816f8 100644 --- a/services/ans/include/notification_dialog.h +++ b/services/ans/include/notification_dialog.h @@ -32,6 +32,8 @@ public: */ ErrCode StartEnableNotificationDialogAbility(int32_t uid); + ErrCode StartEnableNotificationDialogAbility(int32_t uid, const sptr &callerToken); + private: int32_t GetActiveUserId(); int32_t GetUidByBundleName(const std::string &bundleName); diff --git a/services/ans/src/advanced_notification_service.cpp b/services/ans/src/advanced_notification_service.cpp index 1630fa255..cfc015ad1 100644 --- a/services/ans/src/advanced_notification_service.cpp +++ b/services/ans/src/advanced_notification_service.cpp @@ -1528,6 +1528,48 @@ ErrCode AdvancedNotificationService::RequestEnableNotification( return result; } +ErrCode AdvancedNotificationService::RequestEnableNotification( + const std::string &deviceId, const sptr &callerToken) +{ + ANS_LOGD("%{public}s", __FUNCTION__); + + ErrCode result = ERR_OK; + sptr bundleOption = GenerateBundleOption(); + if (bundleOption == nullptr) { + ANS_LOGD("bundleOption == nullptr"); + return ERR_ANS_INVALID_BUNDLE; + } + + // To get the permission + bool allowedNotify = false; + result = IsAllowedNotifySelf(bundleOption, allowedNotify); + ANS_LOGI("result = %{public}d, allowedNotify = %{public}d", result, allowedNotify); + if (result != ERR_OK || allowedNotify) { + ANS_LOGD("Already granted permission"); + return result; + } + + // Check to see if it has been popover before + bool hasPopped = false; + result = GetHasPoppedDialog(bundleOption, hasPopped); + if (result != ERR_OK || hasPopped) { + ANS_LOGD("Already shown dialog"); + return result; + } + + ANS_LOGI("hasPopped = %{public}d, allowedNotify = %{public}d", hasPopped, allowedNotify); + if (!hasPopped && !allowedNotify) { + auto notificationDialog = std::make_shared(); + result = notificationDialog->StartEnableNotificationDialogAbility(bundleOption->GetUid(), callerToken); + if (result != ERR_OK) { + ANS_LOGD("StartEnableNotificationDialogAbility failed, result = %{public}d", result); + return result; + } + } + SetHasPoppedDialog(bundleOption, true); + return result; +} + ErrCode AdvancedNotificationService::SetNotificationsEnabledForBundle(const std::string &deviceId, bool enabled) { return ERR_INVALID_OPERATION; diff --git a/services/ans/src/notification_dialog.cpp b/services/ans/src/notification_dialog.cpp index 1fb3b2884..2f8281941 100644 --- a/services/ans/src/notification_dialog.cpp +++ b/services/ans/src/notification_dialog.cpp @@ -64,5 +64,24 @@ ErrCode NotificationDialog::StartEnableNotificationDialogAbility(int32_t uid) ANS_LOGD("End, result = %{public}d", result); return result; } + +ErrCode NotificationDialog::StartEnableNotificationDialogAbility(int32_t uid, const sptr &callerToken) +{ + ANS_LOGD("%{public}s, Enter.", __func__); + auto bundleName = IN_PROCESS_CALL(AAFwk::AbilityManagerClient::GetInstance()->GetTopAbility().GetBundleName()); + auto topUid = GetUidByBundleName(bundleName); + if (topUid != uid) { + ANS_LOGE("Current application isn't in foreground, top is %{private}s.", bundleName.c_str()); + return ERR_ANS_INVALID_BUNDLE; + } + + AAFwk::Want want; + want.SetElementName("com.ohos.notificationdialog", "EnableNotificationDialog"); + want.SetParam("from", bundleName); + want.SetParam("callerToken", callerToken); + auto result = IN_PROCESS_CALL(AAFwk::AbilityManagerClient::GetInstance()->StartAbility(want)); + ANS_LOGD("End, result = %{public}d", result); + return result; +} } // namespace Notification } // namespace OHOS \ No newline at end of file diff --git a/services/dialog_ui/enable_notification_dialog/entry/src/main/ets/ServiceExtAbility/NotificationServiceExtAbility.ts b/services/dialog_ui/enable_notification_dialog/entry/src/main/ets/ServiceExtAbility/NotificationServiceExtAbility.ts index 711ce1f95..19d910028 100644 --- a/services/dialog_ui/enable_notification_dialog/entry/src/main/ets/ServiceExtAbility/NotificationServiceExtAbility.ts +++ b/services/dialog_ui/enable_notification_dialog/entry/src/main/ets/ServiceExtAbility/NotificationServiceExtAbility.ts @@ -19,21 +19,39 @@ import display from '@ohos.display'; import deviceInfo from '@ohos.deviceInfo'; const TAG = 'NotificationDialog_Service'; +var winNum = 1; +var win; export default class NotificationDialogServiceExtensionAbility extends extension { onCreate(want): void { - console.debug(TAG, "onCreate, want: " + JSON.stringify(want)); - globalThis.notificationExtensionContext = this.context; - globalThis.closeDialog = (): void => { - console.info(TAG, 'click waiting for a response'); - globalThis.notificationExtensionContext.terminateSelf(); - } + console.debug(TAG, "onCreate, want: " + JSON.stringify(want)); + globalThis.notificationExtensionContext = this.context; + globalThis.closeDialog = (): void => { + console.info(TAG, 'click waiting for a response'); + globalThis.notificationExtensionContext.terminateSelf(); + } }; onRequest(want, startId): void { globalThis.abilityWant = want; - console.log(TAG, 'globalThis.resolution' + JSON.stringify(globalThis.resolution)); + + if(want["parameters"]["callerToken"]){ + console.info('callerToken want is exist'); + console.info('111111'); + } + globalThis.callerToken = want["parameters"]["callerToken"]; + console.info('222222'); display.getDefaultDisplay().then(() => { - this.createWindow('EnableNotificationDialog' + startId, window.WindowType.TYPE_SYSTEM_ALERT); + + console.info('getDefaultDisplay is display'); + + if (winNum > 1) { + win.destroy(); + winNum--; + } + console.info('333333333'); + this.createWindow('EnableNotificationDialog' + startId, window.WindowType.TYPE_DIALOG); + + winNum++; }); } @@ -44,7 +62,24 @@ export default class NotificationDialogServiceExtensionAbility extends extension private async createWindow(name: string, windowType: number) { console.info(TAG, 'create window'); try { - const win = await window.create(globalThis.notificationExtensionContext, name, windowType); + win = await window.create(globalThis.notificationExtensionContext, name, windowType); + + console.info("callerToken!!!!") + + if (globalThis.callerToken) { + console.info('callerToken exist') + if (globalThis.callerToken.value) { + console.info('globalThis.callerToken.value ') + } + await win.bindDialogTarget(globalThis.callerToken.value, () => { + win.destroyWindow(); + winNum--; + if (winNum === 0) { + globalThis.selectExtensionContext.terminateSelf(); + } + }); + } + await win.show(); if (deviceInfo.deviceType === 'default' || deviceInfo.deviceType === 'phone') { await win.setWindowLayoutFullScreen(true); -- Gitee