diff --git a/frameworks/ans/src/notification_helper.cpp b/frameworks/ans/src/notification_helper.cpp index 0fc8750b92458c85c5304903416072212451d28c..ae6ff17e617cfc8e131343da2273447f1689be4a 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 ccccdcd2fc88d613189b2ad55c99925cf285ad6c..a8568e6d781db14ea8643364c655d4f6e0cc2ca2 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 a73751a9e52168c87f7beb403baf02ef1a2eda66..fbaea14bde2e4f5492f51fee0916145c1ff702c2 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 b91aeef02f98603a2879f7503670f44b4fdf4982..8a2e665f4ea0f2423887440d426d6869db241239 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 0794a5c4cd974e24faf77d792cc805da9750202a..aeb3a9ffa9ea8ea6e171ccbe5a21078075ffd34e 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 959baaa8dee18a1778e8c36b3d114a71c78e6648..c606860fb3ade9577d4c80e411e8fbba0aae3f46 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 7afd2eb3d21fab9107239bd7cb5d154a47d72dde..d4b7afe952e79351bab1e8b74839247b4857c8b0 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 1ac0f75a4468f89b8b31f8bd88cacb1b2ad3d430..dc74853f5d95c528336f1826e363a8aeb4d1e660 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 feea0bbbc85b875c735827cbc7143ba7a517d0f5..3ce36cac601f230d81cc3c559d2c774b96c1203d 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 635ff71a2111a514c7306d5d8093c88dbeadb52f..8637c67fb40a39fb61cf32cd152f7f5bd883336b 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 9c76362c55414a2406758b5718bacdfd6a5b9016..182f495e0fe9e9e66876fa9cd59a8db0c00c725f 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 a7a7e7e46ee98c30df0295e2ed475f83ebacceec..5f4d2e827737231adc05c983afa9c3bc3046868c 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 cf5a0f870e9f9182a2bb3a3085e5760bf23dfaff..b9acf60fb7069e5b4c2e54023d7c955a030bf692 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 d5358fd0d466a5ac7d9c86208d9169e505e6e78d..2e53393731bcdc2560e37447768d9c6db573efb8 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 6956d1b8d9a052f6e1de2a546f5f93f842dd7d11..08d622b741ce8f6f30b5b4cb07cdd387358bf55a 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 c5e3f0aafde0ffafe71938742fdaec8e45172e7e..ce0b5537c89a9475e980a5c43eb0ac6ca9ffc162 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 a47a54b8bfb714ccfd9cfd9299b7aef72b4ac923..f400816f88de05a0405394f2ad3a85b78007445d 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 1630fa255b3071ba5680b4b041801380a7b597c4..cfc015ad19944835b82f45755dec1e9e3a80360a 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 1fb3b28849baa7c4a72607cc548c0334c6cc268a..2f8281941645ad1eb2198c76ce7caa8bfc87870c 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 711ce1f9533057e5ed78073f8d4e1834b02e52d6..19d9100285810596f3208a457d1b06fdff06a297 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);