Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

User/purifoypaul/rs5 packaged com activation #2044

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
pmpurifoy marked this conversation as resolved.
Show resolved Hide resolved
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