Skip to content

Commit

Permalink
User/purifoypaul/rs5 packaged com activation (#2044)
Browse files Browse the repository at this point in the history
* Initial Commit

* Working packaged background RS5

* Remove IRawSerializer

* Update NotificationListener.cpp
  • Loading branch information
pmpurifoy authored Feb 2, 2022
1 parent 9f52385 commit 27ca1f6
Show file tree
Hide file tree
Showing 19 changed files with 202 additions and 40 deletions.
5 changes: 0 additions & 5 deletions dev/PushNotifications/PushNotificationActivationInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 0 additions & 1 deletion dev/PushNotifications/PushNotificationActivationInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation
struct PushNotificationActivationInfo : PushNotificationActivationInfoT<PushNotificationActivationInfo>
{
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();
Expand Down
19 changes: 17 additions & 2 deletions dev/PushNotifications/PushNotificationBackgroundTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@

#include "PushNotificationReceivedEventArgs.h"
#include "externs.h"
#include "PushNotificationUtility.h"

namespace PushNotificationHelpers
{
using namespace winrt::Microsoft::Windows::PushNotifications::Helpers;
}

namespace winrt
{
Expand All @@ -23,8 +29,17 @@ namespace winrt
void PushNotificationBackgroundTask::Run(winrt::IBackgroundTaskInstance const& taskInstance)
{
auto appProperties = winrt::CoreApplication::Properties();
winrt::PushNotificationReceivedEventArgs activatedEventArgs = winrt::make<winrt::Microsoft::Windows::PushNotifications::implementation::PushNotificationReceivedEventArgs>(taskInstance);
appProperties.Insert(ACTIVATED_EVENT_ARGS_KEY, activatedEventArgs);
if (PushNotificationHelpers::IsPackagedAppScenario())
{
winrt::PushNotificationReceivedEventArgs activatedEventArgs{ winrt::make<winrt::Microsoft::Windows::PushNotifications::implementation::PushNotificationReceivedEventArgs>(taskInstance) };
appProperties.Insert(ACTIVATED_EVENT_ARGS_KEY, activatedEventArgs);
}
else
{
winrt::hstring payload{ winrt::unbox_value<winrt::hstring>(taskInstance.TriggerDetails()) };
winrt::PushNotificationReceivedEventArgs activatedEventArgs{ winrt::make<winrt::Microsoft::Windows::PushNotifications::implementation::PushNotificationReceivedEventArgs>(payload.c_str()) };
appProperties.Insert(UNPACKAGED_EVENT_ARGS_KEY, activatedEventArgs);
}

SetEvent(GetWaitHandleForArgs().get());
}
11 changes: 10 additions & 1 deletion dev/PushNotifications/PushNotificationManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 };
Expand Down Expand Up @@ -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()));
Expand Down Expand Up @@ -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<PushNotificationBackgroundTaskFactory>().get(),
CLSCTX_LOCAL_SERVER,
REGCLS_MULTIPLEUSE,
&s_comActivatorRegistration));

{
auto lock = s_activatorInfoLock.lock_exclusive();
s_protocolRegistration = true;
Expand Down
4 changes: 1 addition & 3 deletions dev/PushNotifications/PushNotifications.idl
Original file line number Diff line number Diff line change
Expand Up @@ -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; };

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@

#include "pch.h"
#include "../PushNotificationUtility.h"
#include <winrt/Windows.ApplicationModel.background.h>
#include "PushBackgroundTaskInstance.h"

using namespace winrt::Windows::ApplicationModel::Background;
namespace ToastNotifications
{
using namespace ABI::Microsoft::Internal::ToastNotifications;
Expand All @@ -12,10 +15,12 @@ HRESULT NotificationListener::RuntimeClassInitialize(
std::shared_ptr<ForegroundSinkManager> foregroundSinkManager,
std::shared_ptr<ToastRegistrationManager> 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;
Expand All @@ -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<winrt::Windows::ApplicationModel::Background::IBackgroundTask>(m_comServerClsid, CLSCTX_ALL);
auto pushBackgroundTaskInstance{ winrt::make_self<PushBackgroundTaskInstance>() };
pushBackgroundTaskInstance->SetRawNotificationPayload(payloadString);
localBackgroundTask.Run(*pushBackgroundTaskInstance);
}
};

return S_OK;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ class NotificationListener : public Microsoft::WRL::RuntimeClass<::ABI::Microsof
std::shared_ptr<ForegroundSinkManager> foregroundSinkManager,
std::shared_ptr<ToastRegistrationManager> 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,
Expand All @@ -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;
};
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,24 @@ void NotificationListenerManager::Initialize(std::shared_ptr<ForegroundSinkManag
m_toastRegistrationManager = toastRegistrationManager;
}

void NotificationListenerManager::SetAppIdMapping(std::map<std::wstring, std::wstring>& appIdList)
void NotificationListenerManager::SetAppIdMapping(std::map<std::wstring, std::pair<std::wstring, winrt::guid>>& 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<INotificationListener> newListener;
{
auto lock{ m_lock.lock_shared() };
THROW_IF_FAILED(MakeAndInitialize<NotificationListener>(&newListener, m_foregroundSinkManager, m_toastRegistrationManager, appId, processName));
THROW_IF_FAILED(MakeAndInitialize<NotificationListener>(&newListener, m_foregroundSinkManager, m_toastRegistrationManager, appId, processName, comServerClsid));
}

THROW_IF_FAILED(PushNotifications_RegisterNotificationSinkForFullTrustApplication(appId.c_str(), newListener.Get()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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> foregroundSinkManager, std::shared_ptr<ToastRegistrationManager> toastRegistrationManager);

void SetAppIdMapping(std::map<std::wstring, std::wstring>& appIdList);
void SetAppIdMapping(std::map<std::wstring, std::pair<std::wstring, winrt::guid>>& 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();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#pragma once

#include "pch.h"

#include "PushBackgroundTaskInstance.h"
#include <winrt/base.h>

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);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#include <winrt/Windows.ApplicationModel.background.h>

struct PushBackgroundTaskInstance : winrt::implements<PushBackgroundTaskInstance, winrt::Windows::ApplicationModel::Background::IBackgroundTaskInstance>
{
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<PushBackgroundTaskInstanceFactory, IClassFactory>
{
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<PushBackgroundTaskInstance>().as(interfaceId, object);
}

HRESULT __stdcall LockServer(BOOL) noexcept final
{
return S_OK;
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@
<ClCompile Include="platformfactory.cpp" />
<ClCompile Include="PlatformLifetimeManager.cpp" />
<ClCompile Include="NotificationListenerManager.cpp" />
<ClCompile Include="PushBackgroundTaskInstance.cpp" />
<ClCompile Include="ToastRegistrationManager.cpp" />
<ClCompile Include="winmain.cpp" />
</ItemGroup>
Expand All @@ -243,6 +244,7 @@
<ClInclude Include="platformfactory.h" />
<ClInclude Include="PlatformLifetimeManager.h" />
<ClInclude Include="NotificationListenerManager.h" />
<ClInclude Include="PushBackgroundTaskInstance.h" />
<ClInclude Include="ToastRegistrationManager.h" />
</ItemGroup>
<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@
<ClInclude Include="ToastRegistrationManager.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="PushBackgroundTaskInstance.h">
<Filter>Source Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="pch.cpp">
Expand Down Expand Up @@ -68,6 +71,9 @@
<ClCompile Include="ToastRegistrationManager.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="PushBackgroundTaskInstance.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
Expand Down
4 changes: 3 additions & 1 deletion dev/PushNotifications/PushNotificationsLongRunningTask/pch.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@

#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Foundation.Collections.h>

#include <winrt/Windows.ApplicationModel.Activation.h>
#include <winrt/Windows.Storage.Streams.h>
#include <winrt/Windows.Networking.PushNotifications.h>
#include <winrt/Windows.Storage.h>

#include <wil/com.h>
Expand Down
Loading

0 comments on commit 27ca1f6

Please sign in to comment.