From 27ca1f63313def258e89328380419d01d9dd4902 Mon Sep 17 00:00:00 2001 From: Paul Purifoy <33183370+pmpurifoy@users.noreply.github.com> Date: Wed, 2 Feb 2022 14:46:56 -0800 Subject: [PATCH] User/purifoypaul/rs5 packaged com activation (#2044) * Initial Commit * Working packaged background RS5 * Remove IRawSerializer * Update NotificationListener.cpp --- .../PushNotificationActivationInfo.cpp | 5 -- .../PushNotificationActivationInfo.h | 1 - .../PushNotificationBackgroundTask.cpp | 19 ++++++- .../PushNotificationManager.cpp | 11 +++- dev/PushNotifications/PushNotifications.idl | 4 +- .../NotificationsLongRunningProcess.idl | 2 +- .../NotificationListener.cpp | 21 +++++++- .../NotificationListener.h | 5 +- .../NotificationListenerManager.cpp | 12 ++--- .../NotificationListenerManager.h | 4 +- .../PushBackgroundTaskInstance.cpp | 53 +++++++++++++++++++ .../PushBackgroundTaskInstance.h | 34 ++++++++++++ .../PushNotificationsLongRunningTask.vcxproj | 2 + ...tificationsLongRunningTask.vcxproj.filters | 6 +++ .../PushNotificationsLongRunningTask/pch.h | 4 +- .../platform.cpp | 28 +++++++--- .../platform.h | 8 +-- dev/PushNotifications/externs.h | 17 +++++- .../PushNotificationsDemoApp/main.cpp | 6 +-- 19 files changed, 202 insertions(+), 40 deletions(-) create mode 100644 dev/PushNotifications/PushNotificationsLongRunningTask/PushBackgroundTaskInstance.cpp create mode 100644 dev/PushNotifications/PushNotificationsLongRunningTask/PushBackgroundTaskInstance.h diff --git a/dev/PushNotifications/PushNotificationActivationInfo.cpp b/dev/PushNotifications/PushNotificationActivationInfo.cpp index 342168ae121..79a5d3bbfba 100644 --- a/dev/PushNotifications/PushNotificationActivationInfo.cpp +++ b/dev/PushNotifications/PushNotificationActivationInfo.cpp @@ -20,11 +20,6 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation THROW_HR_IF(E_NOTIMPL, !::Microsoft::Windows::PushNotifications::Feature_PushNotifications::IsEnabled()); } - PushNotificationActivationInfo::PushNotificationActivationInfo(winrt::PushNotificationRegistrationActivators const& activators) : m_activators(activators), m_taskClsid(GUID_NULL) - { - THROW_HR_IF(E_NOTIMPL, !::Microsoft::Windows::PushNotifications::Feature_PushNotifications::IsEnabled()); - } - winrt::guid PushNotificationActivationInfo::TaskClsid() { return m_taskClsid; diff --git a/dev/PushNotifications/PushNotificationActivationInfo.h b/dev/PushNotifications/PushNotificationActivationInfo.h index 92b80af6627..84f4201a6b1 100644 --- a/dev/PushNotifications/PushNotificationActivationInfo.h +++ b/dev/PushNotifications/PushNotificationActivationInfo.h @@ -9,7 +9,6 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation struct PushNotificationActivationInfo : PushNotificationActivationInfoT { PushNotificationActivationInfo(Microsoft::Windows::PushNotifications::PushNotificationRegistrationActivators const& activators, winrt::guid const& taskClsid); - PushNotificationActivationInfo(Microsoft::Windows::PushNotifications::PushNotificationRegistrationActivators const& activators); winrt::guid TaskClsid(); Microsoft::Windows::PushNotifications::PushNotificationRegistrationActivators Activators(); diff --git a/dev/PushNotifications/PushNotificationBackgroundTask.cpp b/dev/PushNotifications/PushNotificationBackgroundTask.cpp index 0064416edee..2ad3eb60d5a 100644 --- a/dev/PushNotifications/PushNotificationBackgroundTask.cpp +++ b/dev/PushNotifications/PushNotificationBackgroundTask.cpp @@ -12,6 +12,12 @@ #include "PushNotificationReceivedEventArgs.h" #include "externs.h" +#include "PushNotificationUtility.h" + +namespace PushNotificationHelpers +{ + using namespace winrt::Microsoft::Windows::PushNotifications::Helpers; +} namespace winrt { @@ -23,8 +29,17 @@ namespace winrt void PushNotificationBackgroundTask::Run(winrt::IBackgroundTaskInstance const& taskInstance) { auto appProperties = winrt::CoreApplication::Properties(); - winrt::PushNotificationReceivedEventArgs activatedEventArgs = winrt::make(taskInstance); - appProperties.Insert(ACTIVATED_EVENT_ARGS_KEY, activatedEventArgs); + if (PushNotificationHelpers::IsPackagedAppScenario()) + { + winrt::PushNotificationReceivedEventArgs activatedEventArgs{ winrt::make(taskInstance) }; + appProperties.Insert(ACTIVATED_EVENT_ARGS_KEY, activatedEventArgs); + } + else + { + winrt::hstring payload{ winrt::unbox_value(taskInstance.TriggerDetails()) }; + winrt::PushNotificationReceivedEventArgs activatedEventArgs{ winrt::make(payload.c_str()) }; + appProperties.Insert(UNPACKAGED_EVENT_ARGS_KEY, activatedEventArgs); + } SetEvent(GetWaitHandleForArgs().get()); } diff --git a/dev/PushNotifications/PushNotificationManager.cpp b/dev/PushNotifications/PushNotificationManager.cpp index 8dc13d97c56..99127ece5f2 100644 --- a/dev/PushNotifications/PushNotificationManager.cpp +++ b/dev/PushNotifications/PushNotificationManager.cpp @@ -49,6 +49,7 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation static winrt::Windows::ApplicationModel::Background::IBackgroundTaskRegistration s_pushTriggerRegistration{ nullptr }; static wil::unique_com_class_object_cookie s_comActivatorRegistration; static bool s_protocolRegistration{ false }; + static winrt::guid s_taskClsid{ GUID_NULL }; static wil::srwlock s_activatorInfoLock; inline constexpr auto c_maxBackoff{ 5min }; @@ -200,7 +201,7 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation wil::unique_cotaskmem_string processName; THROW_IF_FAILED(GetCurrentProcessPath(processName)); - THROW_IF_FAILED(notificationPlatform->RegisterLongRunningActivator(processName.get())); + THROW_IF_FAILED(notificationPlatform->RegisterLongRunningActivator(processName.get(), s_taskClsid)); std::wstring toastAppId{ RetrieveToastAppId() }; THROW_IF_FAILED(notificationPlatform->AddToastRegistrationMapping(processName.get(), toastAppId.c_str())); @@ -269,9 +270,17 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation THROW_HR_IF(E_INVALIDARG, s_protocolRegistration); } + s_taskClsid = details.TaskClsid(); wil::unique_cotaskmem_string unpackagedAppUserModelId; RegisterUnpackagedApplicationHelper(GUID_NULL, unpackagedAppUserModelId); // create default registration for app + THROW_IF_FAILED(::CoRegisterClassObject( + s_taskClsid, + winrt::make().get(), + CLSCTX_LOCAL_SERVER, + REGCLS_MULTIPLEUSE, + &s_comActivatorRegistration)); + { auto lock = s_activatorInfoLock.lock_exclusive(); s_protocolRegistration = true; diff --git a/dev/PushNotifications/PushNotifications.idl b/dev/PushNotifications/PushNotifications.idl index 7e41a286ab4..e3c978de98c 100644 --- a/dev/PushNotifications/PushNotifications.idl +++ b/dev/PushNotifications/PushNotifications.idl @@ -39,11 +39,9 @@ namespace Microsoft.Windows.PushNotifications // Initialize using a Registration option and optionally defined parameters like manifest defined activatorId // 1) If kind = PushTrigger is specified, only the Push Trigger will be Registered with Background Infra // 2) If kind = ComActivator is specified, the Background Task component will be Registered as an in-process COM server + // 3) If kind = ProtocolActivator is specified, the LRP will CoCreateInstance the application in background scenarios PushNotificationActivationInfo(PushNotificationRegistrationActivators activators, Guid taskClsid); - // Applications that need to use ProtocolActivator will use this constructor - PushNotificationActivationInfo(PushNotificationRegistrationActivators activators); - // The CLSID associated with the Client COM server that Windows App SDK will activate Guid TaskClsid{ get; }; diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/NotificationsLongRunningProcess.idl b/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/NotificationsLongRunningProcess.idl index 9011a91b7bd..d2018e0427f 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/NotificationsLongRunningProcess.idl +++ b/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/NotificationsLongRunningProcess.idl @@ -19,7 +19,7 @@ interface IWpnForegroundSink : IUnknown [pointer_default(unique)] interface INotificationsLongRunningPlatform : IUnknown { - HRESULT RegisterLongRunningActivator([in] LPCWSTR processName); + HRESULT RegisterLongRunningActivator([in] LPCWSTR processName, [in] GUID comServerClsid); HRESULT UnregisterLongRunningActivator([in] LPCWSTR processName); diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListener.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListener.cpp index 373d52db02b..e144394e3c2 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListener.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListener.cpp @@ -2,7 +2,10 @@ #include "pch.h" #include "../PushNotificationUtility.h" +#include +#include "PushBackgroundTaskInstance.h" +using namespace winrt::Windows::ApplicationModel::Background; namespace ToastNotifications { using namespace ABI::Microsoft::Internal::ToastNotifications; @@ -12,10 +15,12 @@ HRESULT NotificationListener::RuntimeClassInitialize( std::shared_ptr foregroundSinkManager, std::shared_ptr toastRegistrationManager, std::wstring const& appId, - std::wstring const& processName) noexcept try + std::wstring const& processName, + winrt::guid const& comServerClsid) noexcept try { m_foregroundSinkManager = foregroundSinkManager; m_toastRegistrationManager = toastRegistrationManager; + m_comServerClsid = comServerClsid; m_appId = appId; m_processName = processName; @@ -32,7 +37,19 @@ STDMETHODIMP_(HRESULT __stdcall) NotificationListener::OnRawNotificationReceived if (!m_foregroundSinkManager->InvokeForegroundHandlers(m_appId, payloadArray, payloadLength)) { - THROW_IF_FAILED(winrt::Microsoft::Windows::PushNotifications::Helpers::ProtocolLaunchHelper(m_processName, payloadLength, payload)); + if (m_comServerClsid == winrt::guid()) + { + THROW_IF_FAILED(winrt::Microsoft::Windows::PushNotifications::Helpers::ProtocolLaunchHelper(m_processName, payloadLength, payload)); + } + else + { + std::wstring payloadString(payloadArray.begin(), payloadArray.end()); + + auto localBackgroundTask = winrt::create_instance(m_comServerClsid, CLSCTX_ALL); + auto pushBackgroundTaskInstance{ winrt::make_self() }; + pushBackgroundTaskInstance->SetRawNotificationPayload(payloadString); + localBackgroundTask.Run(*pushBackgroundTaskInstance); + } }; return S_OK; diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListener.h b/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListener.h index 6bccf8193f7..a20f676b268 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListener.h +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListener.h @@ -12,7 +12,8 @@ class NotificationListener : public Microsoft::WRL::RuntimeClass<::ABI::Microsof std::shared_ptr foregroundSinkManager, std::shared_ptr toastRegistrationManager, std::wstring const& appId, - std::wstring const& processName) noexcept; + std::wstring const& processName, + winrt::guid const& comServerClsid) noexcept; STDMETHOD(OnRawNotificationReceived)(unsigned int payloadLength, _In_ byte* payload, _In_ HSTRING correlationVector) noexcept; STDMETHOD(OnToastNotificationReceived)(ABI::Microsoft::Internal::ToastNotifications::INotificationProperties* notificationProperties, @@ -23,6 +24,6 @@ class NotificationListener : public Microsoft::WRL::RuntimeClass<::ABI::Microsof std::wstring m_appId; std::wstring m_processName; - + winrt::guid m_comServerClsid; wil::srwlock m_lock; }; diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListenerManager.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListenerManager.cpp index b11fae07532..c0dee8ac451 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListenerManager.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListenerManager.cpp @@ -9,26 +9,24 @@ void NotificationListenerManager::Initialize(std::shared_ptr& appIdList) +void NotificationListenerManager::SetAppIdMapping(std::map>& appIdList) { for (auto appData : appIdList) { - AddListener(appData.first, appData.second); + AddListener(appData.first, appData.second.first, appData.second.second); } } -void NotificationListenerManager::AddListener(std::wstring const& appId, std::wstring const& processName) +void NotificationListenerManager::AddListener(std::wstring const& appId, std::wstring const& processName, winrt::guid const& comServerClsid) { THROW_HR_IF(E_INVALIDARG, appId.empty()); - THROW_HR_IF(E_INVALIDARG, processName.empty()); - - + THROW_HR_IF(E_INVALIDARG, processName.empty()); // Make sure we keep the long running sink up-to-date with wpncore. ComPtr newListener; { auto lock{ m_lock.lock_shared() }; - THROW_IF_FAILED(MakeAndInitialize(&newListener, m_foregroundSinkManager, m_toastRegistrationManager, appId, processName)); + THROW_IF_FAILED(MakeAndInitialize(&newListener, m_foregroundSinkManager, m_toastRegistrationManager, appId, processName, comServerClsid)); } THROW_IF_FAILED(PushNotifications_RegisterNotificationSinkForFullTrustApplication(appId.c_str(), newListener.Get())); diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListenerManager.h b/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListenerManager.h index 3a7e906842a..a0f43718a6b 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListenerManager.h +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListenerManager.h @@ -12,9 +12,9 @@ class NotificationListenerManager // This function has to be called after initializing the ForegroundSinkManager during Platform initialization void Initialize(std::shared_ptr foregroundSinkManager, std::shared_ptr toastRegistrationManager); - void SetAppIdMapping(std::map& appIdList); + void SetAppIdMapping(std::map>& appIdList); - void AddListener(std::wstring const& appId, std::wstring const& processName); + void AddListener(std::wstring const& appId, std::wstring const& processName, winrt::guid const& comServerClsid); void RemoveListener(std::wstring appId); bool IsEmpty(); diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/PushBackgroundTaskInstance.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/PushBackgroundTaskInstance.cpp new file mode 100644 index 00000000000..a5a4665b7f3 --- /dev/null +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/PushBackgroundTaskInstance.cpp @@ -0,0 +1,53 @@ +#pragma once + +#include "pch.h" + +#include "PushBackgroundTaskInstance.h" +#include + +using namespace winrt::Windows::Networking::PushNotifications; + +winrt::guid PushBackgroundTaskInstance::InstanceId() +{ + return winrt::guid(); +} + +UINT32 PushBackgroundTaskInstance::SuspendedCount() +{ + return 0; +} + +UINT32 PushBackgroundTaskInstance::Progress() +{ + return 0; +} + +UINT32 PushBackgroundTaskInstance::Progress(UINT32 progress) +{ + return 0; +} + +winrt::Windows::ApplicationModel::Background::BackgroundTaskRegistration PushBackgroundTaskInstance::Task() +{ + return nullptr; +} + +winrt::event_token PushBackgroundTaskInstance::Canceled(winrt::Windows::ApplicationModel::Background::BackgroundTaskCanceledEventHandler const& handler) +{ + return winrt::event_token{}; +} + +void PushBackgroundTaskInstance::Canceled(winrt::event_token const& token) noexcept +{ + return; +} + +winrt::Windows::ApplicationModel::Background::BackgroundTaskDeferral PushBackgroundTaskInstance::GetDeferral() +{ + return nullptr; +} + +winrt::Windows::Foundation::IInspectable PushBackgroundTaskInstance::TriggerDetails() +{ + return winrt::box_value(m_payload); +} diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/PushBackgroundTaskInstance.h b/dev/PushNotifications/PushNotificationsLongRunningTask/PushBackgroundTaskInstance.h new file mode 100644 index 00000000000..3dd5276a2e1 --- /dev/null +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/PushBackgroundTaskInstance.h @@ -0,0 +1,34 @@ +#include + +struct PushBackgroundTaskInstance : winrt::implements +{ + PushBackgroundTaskInstance() {}; + + winrt::guid InstanceId(); + UINT32 SuspendedCount(); + UINT32 Progress(); + UINT32 Progress(UINT32 progress); + winrt::Windows::ApplicationModel::Background::BackgroundTaskRegistration Task(); + winrt::Windows::Foundation::IInspectable TriggerDetails(); + winrt::event_token Canceled(winrt::Windows::ApplicationModel::Background::BackgroundTaskCanceledEventHandler const& handler); + void Canceled(winrt::event_token const& token) noexcept; + winrt::Windows::ApplicationModel::Background::BackgroundTaskDeferral GetDeferral(); + + void SetRawNotificationPayload(std::wstring const& payload) { m_payload = payload; }; +private: + std::wstring m_payload; +}; + +struct PushBackgroundTaskInstanceFactory : winrt::implements +{ + HRESULT __stdcall CreateInstance(_In_opt_ IUnknown* aggregateInterface, _In_ REFIID interfaceId, _Outptr_ VOID** object) noexcept final + { + RETURN_HR_IF(CLASS_E_NOAGGREGATION, aggregateInterface != nullptr); + return winrt::make().as(interfaceId, object); + } + + HRESULT __stdcall LockServer(BOOL) noexcept final + { + return S_OK; + } +}; diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj b/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj index dc0ca7c1504..6302cbcece3 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj @@ -232,6 +232,7 @@ + @@ -243,6 +244,7 @@ + diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj.filters b/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj.filters index 5a66aedcae0..e550c16df5a 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj.filters +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj.filters @@ -39,6 +39,9 @@ Header Files + + Source Files + @@ -68,6 +71,9 @@ Source Files + + Source Files + diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/pch.h b/dev/PushNotifications/PushNotificationsLongRunningTask/pch.h index 06a9eae8b1e..d81dbb7f945 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/pch.h +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/pch.h @@ -22,7 +22,9 @@ #include #include - +#include +#include +#include #include #include diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp index 7c595459adc..8a2418c923a 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp @@ -23,6 +23,9 @@ void NotificationsLongRunningPlatformImpl::Initialize() m_rawStorage = Storage::ApplicationData::Current().LocalSettings().CreateContainer( L"Raw", Storage::ApplicationDataCreateDisposition::Always); + m_comServerClsidStorage = Storage::ApplicationData::Current().LocalSettings().CreateContainer( + L"ComServerClsid", Storage::ApplicationDataCreateDisposition::Always); + m_foregroundSinkManager = std::make_shared(); m_toastRegistrationManager = std::make_shared(); @@ -73,7 +76,7 @@ STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::RegisterF } CATCH_RETURN() -STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::RegisterLongRunningActivator(_In_ PCWSTR processName) noexcept try +STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::RegisterLongRunningActivator(_In_ PCWSTR processName, GUID comServerClsid) noexcept try { auto lock = m_lock.lock_shared(); THROW_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); @@ -85,7 +88,8 @@ STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::RegisterL return S_OK; } - m_notificationListenerManager.AddListener(appId, processName); + AddComServerClsid(appId, comServerClsid); + m_notificationListenerManager.AddListener(appId, processName, comServerClsid); m_lifetimeManager.Cancel(); @@ -106,6 +110,7 @@ STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::Unregiste m_foregroundSinkManager->Remove(appId); RemoveAppIdentifier(appId); + RemoveComServerClsid(appId); RemoveToastHelper(processName); } @@ -182,9 +187,9 @@ CATCH_RETURN() // Returns a map of key-value pairs, where key is appId and value is processName. // It should only be called by Initialize(), which already acquired a lock. -std::map NotificationsLongRunningPlatformImpl::GetFullTrustApps() +std::map> NotificationsLongRunningPlatformImpl::GetFullTrustApps() { - std::map mapOfFullTrustApps; + std::map> mapOfFullTrustApps; // Get list of full trust apps with valid channels from wpncore wil::unique_cotaskmem_array_ptr appIds; @@ -192,13 +197,14 @@ std::map NotificationsLongRunningPlatformImpl::GetFu // Get list of apps from Storage auto values{ m_rawStorage.Values() }; - + auto comServerClsidValues{ m_comServerClsidStorage.Values() }; for (size_t i = 0; i < appIds.size(); ++i) { if (values.HasKey(appIds[i])) { winrt::hstring processName{ winrt::unbox_value(values.Lookup(appIds[i])) }; - mapOfFullTrustApps.emplace(reinterpret_cast(appIds[i]), processName.c_str()); + winrt::guid comServerClsid{ winrt::unbox_value(comServerClsidValues.Lookup(appIds[i])) }; + mapOfFullTrustApps.emplace(reinterpret_cast(appIds[i]), std::pair{ processName.c_str(), comServerClsid }); } } @@ -240,6 +246,16 @@ const std::wstring NotificationsLongRunningPlatformImpl::BuildAppIdentifier(std: return guidStr.get(); } +void NotificationsLongRunningPlatformImpl::AddComServerClsid(std::wstring const& appId, winrt::guid const& comServerClsid) +{ + m_comServerClsidStorage.Values().Insert(appId, winrt::box_value(comServerClsid)); +} + +void NotificationsLongRunningPlatformImpl::RemoveComServerClsid(std::wstring const& appId) +{ + m_comServerClsidStorage.Values().Remove(appId); +} + void NotificationsLongRunningPlatformImpl::RemoveAppIdentifier(std::wstring const& appId) { m_rawStorage.Values().Remove(appId); diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h index c7c3516254b..303463c6a90 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h @@ -15,7 +15,7 @@ struct __declspec(uuid(PUSHNOTIFICATIONS_IMPL_CLSID_STRING)) NotificationsLongRu STDMETHOD(RegisterFullTrustApplication)(_In_ PCWSTR processName, GUID remoteId, _Out_ PWSTR* appId) noexcept; - STDMETHOD(RegisterLongRunningActivator)(_In_ PCWSTR processName) noexcept; + STDMETHOD(RegisterLongRunningActivator)(_In_ PCWSTR processName, GUID comServerClsid) noexcept; STDMETHOD(UnregisterLongRunningActivator)(_In_ PCWSTR processName) noexcept; @@ -28,14 +28,16 @@ struct __declspec(uuid(PUSHNOTIFICATIONS_IMPL_CLSID_STRING)) NotificationsLongRu STDMETHOD(RemoveToastRegistrationMapping)(_In_ PCWSTR processName) noexcept; private: - std::map GetFullTrustApps(); + std::map> GetFullTrustApps(); const std::wstring GetAppIdentifier(std::wstring const& processName); const std::wstring BuildAppIdentifier(std::wstring const& processName); + void AddComServerClsid(std::wstring const& appId, winrt::guid const& comServerClsid); + void RemoveComServerClsid(std::wstring const& appId); void RemoveAppIdentifier(std::wstring const& processName); void RemoveToastHelper(std::wstring const& processName); winrt::Windows::Storage::ApplicationDataContainer m_rawStorage{ nullptr }; - + winrt::Windows::Storage::ApplicationDataContainer m_comServerClsidStorage{ nullptr }; wil::srwlock m_lock; bool m_initialized = false; diff --git a/dev/PushNotifications/externs.h b/dev/PushNotifications/externs.h index d0eb2d1b588..9ecb3a04b37 100644 --- a/dev/PushNotifications/externs.h +++ b/dev/PushNotifications/externs.h @@ -4,10 +4,17 @@ #pragma once #include "pch.h" #include +#include "PushNotificationUtility.h" wil::unique_event& GetWaitHandleForArgs(); inline const winrt::hstring ACTIVATED_EVENT_ARGS_KEY = L"GlobalActivatedEventArgs"; +inline const winrt::hstring UNPACKAGED_EVENT_ARGS_KEY = L"UnpackagedActivatedEventArgs"; + +namespace PushNotificationHelpers +{ + using namespace winrt::Microsoft::Windows::PushNotifications::Helpers; +} struct ChannelDetails { @@ -28,5 +35,13 @@ inline winrt::Windows::Foundation::IInspectable GetArgsFromComStore() THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_TIMEOUT), !GetWaitHandleForArgs().wait(receiveArgsTimeoutInMSec)); // If COM static store was uninit, let it throw - return winrt::Windows::ApplicationModel::Core::CoreApplication::Properties().Lookup(ACTIVATED_EVENT_ARGS_KEY); + if (PushNotificationHelpers::IsPackagedAppScenario()) + { + return winrt::Windows::ApplicationModel::Core::CoreApplication::Properties().Lookup(ACTIVATED_EVENT_ARGS_KEY); + } + else + { + return winrt::Windows::ApplicationModel::Core::CoreApplication::Properties().Lookup(UNPACKAGED_EVENT_ARGS_KEY); + } + } diff --git a/test/TestApps/PushNotificationsDemoApp/main.cpp b/test/TestApps/PushNotificationsDemoApp/main.cpp index a5661a28c6d..33d6c52832b 100644 --- a/test/TestApps/PushNotificationsDemoApp/main.cpp +++ b/test/TestApps/PushNotificationsDemoApp/main.cpp @@ -56,8 +56,8 @@ winrt::Windows::Foundation::IAsyncOperation RequestChan auto payload = args.Payload(); // Do stuff to process the raw payload - std::string payloadString(payload.begin(), payload.end()); - std::cout << "Push notification content received from FOREGROUND: " << payloadString << std::endl << std::endl; + std::wstring payloadString(payload.begin(), payload.end()); + std::wcout << L"Push notification content received from FOREGROUND: " << payloadString << std::endl << std::endl; args.Handled(true); }); // Caller's responsibility to keep the channel alive @@ -104,7 +104,7 @@ int main() } else { - PushNotificationActivationInfo info(PushNotificationRegistrationActivators::ProtocolActivator); + PushNotificationActivationInfo info(PushNotificationRegistrationActivators::ProtocolActivator, winrt::guid("ccd2ae3f-764f-4ae3-be45-9804761b28b2")); PushNotificationManager::RegisterActivator(info); }