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

RS5 Fixes #2060

Merged
merged 28 commits into from
Feb 14, 2022
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
82ce049
Wnp toast notifications (#1981)
loneursid Jan 13, 2022
984a883
User/erlangl/purifoypaul/arm64 build fix (#1983)
loneursid Jan 13, 2022
eb6591e
Add ToastNotificationManger::Setting API (#1984)
pmpurifoy Jan 18, 2022
52695d2
Add Foreground/Background handlers for ToastActivation (#1973)
pmpurifoy Jan 18, 2022
971e67f
Implemented ToastNotification + unit tests (#1996)
danielayala94 Jan 22, 2022
a423b51
Add ToastRegistration functions to PushNotificationsLongRunningTask (…
pmpurifoy Jan 25, 2022
e7e3f6c
First iteration of ToastNotificationDemoApp
pmpurifoy Jan 26, 2022
81b5921
Current iteration
pmpurifoy Jan 26, 2022
5a6dcbf
Adding DelayLoad Bootstrap.dll to make app hybrid
pmpurifoy Jan 26, 2022
6329259
Update PushNotificationManager.cpp
pmpurifoy Jan 30, 2022
a376427
User/purifoypaul/rs5 packaged com activation (#2044)
pmpurifoy Feb 2, 2022
032831d
Update PushActivationInfo
pmpurifoy Feb 2, 2022
45b72cf
Currently working on nits
pmpurifoy Feb 3, 2022
243c2bc
Addressing comments
pmpurifoy Feb 4, 2022
d1f22da
Cleaning up PushNotificationChannel.cpp + nits
pmpurifoy Feb 7, 2022
898c754
Issues with PushRawNotification
pmpurifoy Feb 7, 2022
e1c7203
Update PushNotificationManager.cpp
pmpurifoy Feb 7, 2022
49c92e2
Merge branch 'feature/WNP_ToastNotifications_L1' into user/purifoypau…
pmpurifoy Feb 7, 2022
8cddc98
Fixing some nits
pmpurifoy Feb 8, 2022
0960db0
Merge branch 'user/purifoypaul/RS5Fixes' of https://github.com/micros…
pmpurifoy Feb 8, 2022
6a47493
Move CoCreate packaged apps to helpers
pmpurifoy Feb 9, 2022
bc6102c
Remove background activation when args is handled
pmpurifoy Feb 10, 2022
a8e89be
Merge branch 'feature/WNP_ToastNotifications_L1' into user/purifoypau…
pmpurifoy Feb 11, 2022
dfaaad4
Update main.cpp
pmpurifoy Feb 11, 2022
e76cae0
Remove legacyImplementation from telemetry
pmpurifoy Feb 14, 2022
3a6edd9
Add Default to TestApp
pmpurifoy Feb 14, 2022
ddb3f4a
Update main.cpp
pmpurifoy Feb 14, 2022
abafda7
Update main.cpp
pmpurifoy Feb 14, 2022
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
4 changes: 0 additions & 4 deletions WindowsAppRuntime.sln
Original file line number Diff line number Diff line change
Expand Up @@ -1353,10 +1353,6 @@ Global
{A3FBA80D-5B35-471F-9A45-DB4B29E195B9} = {AC5FFC80-92FE-4933-BED2-EC5519AC4440}
{91D03B95-1B0C-4BEB-8441-30DA7D615538} = {448ED2E5-0B37-4D97-9E6B-8C10A507976A}
{103C0C23-7BA8-4D44-A63C-83488E2E3A81} = {91D03B95-1B0C-4BEB-8441-30DA7D615538}
{5B2D17FE-C371-417F-860C-3D32397C2404} = {AC5FFC80-92FE-4933-BED2-EC5519AC4440}
{424A6D96-37EE-4456-8347-08AB425C8DBE} = {AC5FFC80-92FE-4933-BED2-EC5519AC4440}
{56A1D696-FEDA-4333-BF37-772EBECECB10} = {AC5FFC80-92FE-4933-BED2-EC5519AC4440}
{D012E4BB-F16B-472D-A26D-D449CEFA988E} = {AC5FFC80-92FE-4933-BED2-EC5519AC4440}
{0A5FEE93-48B7-40EC-BB9A-B27D11060DA9} = {8630F7AA-2969-4DC9-8700-9B468C1DC21D}
{1307DD1B-BBE8-4CD0-B1A0-0DB6D61EEAA0} = {91D03B95-1B0C-4BEB-8441-30DA7D615538}
{A1B25DCF-6A54-414D-8E24-F4D24EE9299D} = {8630F7AA-2969-4DC9-8700-9B468C1DC21D}
Expand Down
2 changes: 1 addition & 1 deletion dev/AppLifecycle/ActivationRegistrationManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace winrt::Microsoft::Windows::AppLifecycle::implementation
static PCWSTR c_argumentSuffix{ L":" };
static PCWSTR c_msProtocolArgumentString{ L"ms-protocol" };
static PCWSTR c_pushProtocolArgumentString{ L"WindowsAppRuntimePushServer" };
static PCWSTR c_toastProtocolArgumentString{ L"AppNotificationActivated" };
static PCWSTR c_appNotificationProtocolArgumentString{ L"AppNotificationActivated" };
static PCWSTR c_runKeyPath{ LR"(Software\Microsoft\Windows\CurrentVersion\Run\)" };

struct ActivationRegistrationManager
Expand Down
7 changes: 4 additions & 3 deletions dev/AppLifecycle/AppInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ namespace winrt::Microsoft::Windows::AppLifecycle::implementation

wil::unique_hlocal_ptr<PWSTR[]> argv{ CommandLineToArgvW(commandLine.c_str(), &argc) };

PCWSTR activationKinds[] = { c_msProtocolArgumentString, c_pushProtocolArgumentString, c_toastProtocolArgumentString };
PCWSTR activationKinds[] = { c_msProtocolArgumentString, c_pushProtocolArgumentString, c_appNotificationProtocolArgumentString };

for (auto activationKind : activationKinds)
{
auto [ kind, data ] = GetActivationArguments(argv.get(), argc, activationKind);
Expand Down Expand Up @@ -488,10 +489,10 @@ namespace winrt::Microsoft::Windows::AppLifecycle::implementation
// protocol, except the catch-all LaunchActivatedEventArgs case.
if (!contractArgument.empty())
{
if (contractArgument == c_pushProtocolArgumentString || contractArgument == c_toastProtocolArgumentString)
if (contractArgument == c_pushProtocolArgumentString || contractArgument == c_appNotificationProtocolArgumentString)
{
// Generate a basic encoded launch Uri for Push/Toast activations
PCWSTR contractId = (contractArgument == c_pushProtocolArgumentString) ? c_pushContractId : c_toastContractId;
PCWSTR contractId = (contractArgument == c_pushProtocolArgumentString) ? c_pushContractId : c_appNotificationContractId;
std::wstring tempContractData = GenerateEncodedLaunchUri(L"App", contractId);

contractArgument = c_msProtocolArgumentString;
Expand Down
2 changes: 1 addition & 1 deletion dev/AppLifecycle/ExtensionContract.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ namespace winrt::Microsoft::Windows::AppLifecycle::implementation
{ ExtendedActivationKind::Protocol, c_protocolContractId, &ProtocolActivatedEventArgs::Deserialize },
{ ExtendedActivationKind::StartupTask, c_startupTaskContractId, &StartupActivatedEventArgs::Deserialize },
{ ExtendedActivationKind::Push, c_pushContractId, &winrt::Microsoft::Windows::PushNotifications::Deserialize },
{ ExtendedActivationKind::AppNotification, c_toastContractId, &winrt::Microsoft::Windows::PushNotifications::Deserialize },
{ ExtendedActivationKind::AppNotification, c_appNotificationContractId, &winrt::Microsoft::Windows::PushNotifications::Deserialize },
pmpurifoy marked this conversation as resolved.
Show resolved Hide resolved
};

inline bool IsEncodedLaunch(winrt::Windows::Foundation::Uri const& uri)
Expand Down
2 changes: 1 addition & 1 deletion dev/PushNotifications/GetNotificationEventArgs.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#include "externs.h"

constexpr PCWSTR c_pushContractId = L"Windows.Push";
constexpr PCWSTR c_toastContractId = L"Windows.Toast";
constexpr PCWSTR c_appNotificationContractId = L"Windows.Toast";

namespace winrt::Microsoft::Windows::PushNotifications
{
Expand Down
35 changes: 35 additions & 0 deletions dev/PushNotifications/PushBackgroundTaskInstance.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#include <winrt/Windows.ApplicationModel.background.h>

// Mocks IBackgroundTaskInstance to send raw payloads to packaged apps in
// PushNotificationBackgroundTask::Run by com activation from PushNotificationsLongRunningProcess
struct PushBackgroundTaskInstance : winrt::implements<PushBackgroundTaskInstance, winrt::Windows::ApplicationModel::Background::IBackgroundTaskInstance>
{
PushBackgroundTaskInstance() {};
PushBackgroundTaskInstance(std::wstring const& payload): m_payload(payload) {};

winrt::guid InstanceId() { return winrt::guid(); };
UINT32 SuspendedCount() { return 0; };
UINT32 Progress() { return 0; };
UINT32 Progress(UINT32 /* progress */) { return 0; };
winrt::Windows::ApplicationModel::Background::BackgroundTaskRegistration Task() { return nullptr; };
winrt::Windows::Foundation::IInspectable TriggerDetails() { return winrt::box_value(m_payload); };
winrt::event_token Canceled(winrt::Windows::ApplicationModel::Background::BackgroundTaskCanceledEventHandler const& /* handler */) { return winrt::event_token{}; };
void Canceled(winrt::event_token const& /* token */) noexcept { return; };
winrt::Windows::ApplicationModel::Background::BackgroundTaskDeferral GetDeferral() { return nullptr; };
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;
}
};
22 changes: 20 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,20 @@ 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);
// This function can be triggered by either OS background infrastructure
// or by the PushNotificationsLongRunningProcess.
if (PushNotificationHelpers::IsPackagedAppScenario())
pmpurifoy marked this conversation as resolved.
Show resolved Hide resolved
pmpurifoy marked this conversation as resolved.
Show resolved Hide resolved
{
winrt::PushNotificationReceivedEventArgs activatedEventArgs{ winrt::make<winrt::Microsoft::Windows::PushNotifications::implementation::PushNotificationReceivedEventArgs>(taskInstance) };
appProperties.Insert(ACTIVATED_EVENT_ARGS_KEY, activatedEventArgs);
}
else
{
// Need to mock a RawNotification object instead of winrt boxing: https://github.com/microsoft/WindowsAppSDK/issues/2075
winrt::hstring payload{ winrt::unbox_value<winrt::hstring>(taskInstance.TriggerDetails()) };
pmpurifoy marked this conversation as resolved.
Show resolved Hide resolved
winrt::PushNotificationReceivedEventArgs activatedEventArgs{ winrt::make<winrt::Microsoft::Windows::PushNotifications::implementation::PushNotificationReceivedEventArgs>(payload.c_str()) };
appProperties.Insert(LRP_ACTIVATED_EVENT_ARGS_KEY, activatedEventArgs);
}

SetEvent(GetWaitHandleForArgs().get());
}
157 changes: 50 additions & 107 deletions dev/PushNotifications/PushNotificationChannel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,16 @@
#include <winrt/Windows.Foundation.Metadata.h>
#include "PushNotificationChannel.h"
#include "Microsoft.Windows.PushNotifications.PushNotificationChannel.g.cpp"
#include <winrt\Windows.Networking.PushNotifications.h>
#include <winrt\Windows.Foundation.h>
#include "PushNotificationReceivedEventArgs.h"
#include <FrameworkUdk/PushNotifications.h>
#include "externs.h"
#include "PushNotificationTelemetry.h"
#include <TerminalVelocityFeatures-PushNotifications.h>
#include "PushNotificationUtility.h"

namespace winrt::Windows
{
using namespace winrt::Windows::Networking::PushNotifications;
using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::Metadata;
}
namespace winrt::Microsoft
{
using namespace winrt::Microsoft::Windows::PushNotifications;
}
using namespace winrt::Windows::Foundation;
using namespace winrt::Microsoft::Windows::PushNotifications;


namespace PushNotificationHelpers
{
Expand All @@ -32,143 +23,92 @@ namespace PushNotificationHelpers

namespace winrt::Microsoft::Windows::PushNotifications::implementation
{
PushNotificationChannel::PushNotificationChannel(winrt::Windows::PushNotificationChannel const& channel): m_channel(channel)
Uri PushNotificationChannel::Uri()
{
THROW_HR_IF(E_NOTIMPL, !::Microsoft::Windows::PushNotifications::Feature_PushNotifications::IsEnabled());
return winrt::Windows::Foundation::Uri{ m_channelInfo.channelUri };
}

winrt::Windows::Uri PushNotificationChannel::Uri()
DateTime PushNotificationChannel::ExpirationTime()
{
if (m_channel)
{
return winrt::Windows::Uri{ m_channel.Uri() };
}
else
{
return winrt::Windows::Uri{ m_channelInfo.channelUri };
}
}

winrt::Windows::DateTime PushNotificationChannel::ExpirationTime()
{
if (m_channel)
{
return m_channel.ExpirationTime();
}
else
{
return m_channelInfo.channelExpiryTime;
}
return m_channelInfo.channelExpiryTime;
}

void PushNotificationChannel::Close()
{
try
{
if (m_channel)
{
m_channel.Close();
}
else
{
THROW_IF_FAILED(PushNotifications_CloseChannel(m_channelInfo.appUserModelId.c_str(), m_channelInfo.channelId.c_str()));
}

THROW_IF_FAILED(PushNotifications_CloseChannel(m_channelInfo.appId.c_str(), m_channelInfo.channelId.c_str()));
PushNotificationTelemetry::ChannelClosedByApi(S_OK);
}

catch (...)
{
auto channelCloseException = hresult_error(to_hresult());
auto channelCloseException { hresult_error(to_hresult()) };

PushNotificationTelemetry::ChannelClosedByApi(channelCloseException.code());

if (channelCloseException.code() != HRESULT_FROM_WIN32(ERROR_NOT_FOUND))
{
throw hresult_error(to_hresult());
throw channelCloseException;
}
}
}

winrt::event_token PushNotificationChannel::PushReceived(winrt::Windows::TypedEventHandler<winrt::Microsoft::Windows::PushNotifications::PushNotificationChannel, winrt::Microsoft::Windows::PushNotifications::PushNotificationReceivedEventArgs> handler)
winrt::event_token PushNotificationChannel::PushReceived(TypedEventHandler<winrt::Microsoft::Windows::PushNotifications::PushNotificationChannel, winrt::Microsoft::Windows::PushNotifications::PushNotificationReceivedEventArgs> handler)
{
if (PushNotificationHelpers::IsPackagedAppScenario())
bool registeredEvent { false };
{
if (m_channel)
{
return m_channel.PushNotificationReceived([weak_self = get_weak(), handler](auto&&, auto&& args)
{
if (auto strong = weak_self.get())
{
auto pushArgs = winrt::make<winrt::Microsoft::Windows::PushNotifications::implementation::PushNotificationReceivedEventArgs>(args);
pushArgs.Handled(true);
handler(*strong, pushArgs);
};
});
}
else
{
// The channelUri is directly obtained when we request Channel from UDK using RemoteId
auto lock = m_lock.lock_exclusive();

if (!m_foregroundHandlerCount)
{
auto appUserModelId{ winrt::Microsoft::Helpers::GetAppUserModelId() };

THROW_IF_FAILED(PushNotifications_RegisterNotificationSinkForFullTrustApplication(appUserModelId.get(), this));
}
auto lock { m_lock.lock_shared() };
registeredEvent = bool(m_foregroundHandlers);
pmpurifoy marked this conversation as resolved.
Show resolved Hide resolved
}

++m_foregroundHandlerCount;
if(!registeredEvent)
{
if(PushNotificationHelpers::IsPackagedAppScenario())
{
auto appUserModelId{ PushNotificationHelpers::GetAppUserModelId() };

return m_foregroundHandlers.add(handler);
// Register foreground event through the UDK
pmpurifoy marked this conversation as resolved.
Show resolved Hide resolved
THROW_IF_FAILED(PushNotifications_RegisterNotificationSinkForFullTrustApplication(appUserModelId.get(), this));
}
}
else
{
auto lock = m_lock.lock_exclusive();
if (!m_foregroundHandlerCount++)
else
{
auto notificationsLongRunningPlatform{ winrt::Microsoft::Helpers::GetNotificationPlatform() };
auto notificationsLongRunningPlatform{ PushNotificationHelpers::GetNotificationPlatform() };

wil::unique_cotaskmem_string processName;
THROW_IF_FAILED(GetCurrentProcessPath(processName));

THROW_IF_FAILED(notificationsLongRunningPlatform->RegisterForegroundActivator(this, processName.get()));
// Register foreground event through the LRP
THROW_IF_FAILED(notificationsLongRunningPlatform->RegisterForegroundActivator(this, processName.get()));
pmpurifoy marked this conversation as resolved.
Show resolved Hide resolved
}
return m_foregroundHandlers.add(handler);
}

auto lock { m_lock.lock_exclusive() };
return m_foregroundHandlers.add(handler);
hulumane marked this conversation as resolved.
Show resolved Hide resolved
}

void PushNotificationChannel::PushReceived(winrt::event_token const& token) noexcept
{
if (PushNotificationHelpers::IsPackagedAppScenario())
bool registeredEvent { false };
{
if (m_channel)
{
m_channel.PushNotificationReceived(token);
}
else
{
auto lock = m_lock.lock_exclusive();

if (m_foregroundHandlerCount == 1)
{
auto appUserModelId{ winrt::Microsoft::Helpers::GetAppUserModelId() };
auto lock { m_lock.lock_exclusive() };
m_foregroundHandlers.remove(token);
registeredEvent = bool(m_foregroundHandlers);
hulumane marked this conversation as resolved.
Show resolved Hide resolved
}

THROW_IF_FAILED(PushNotifications_UnregisterNotificationSinkForFullTrustApplication(appUserModelId.get()));
}
if(!registeredEvent)
{
// Packaged apps with BI available will remove their handlers from the platform.
// Unpackaged apps / Packaged apps treated as unpackaged will unregister from Long Running process.
if (PushNotificationHelpers::IsPackagedAppScenario())
{
auto appUserModelId{ PushNotificationHelpers::GetAppUserModelId() };

m_foregroundHandlers.remove(token);
--m_foregroundHandlerCount;
THROW_IF_FAILED(PushNotifications_UnregisterNotificationSinkForFullTrustApplication(appUserModelId.get()));
hulumane marked this conversation as resolved.
Show resolved Hide resolved
}
}
else
{
auto lock = m_lock.lock_exclusive();
m_foregroundHandlers.remove(token);
if (!--m_foregroundHandlerCount)
else
pmpurifoy marked this conversation as resolved.
Show resolved Hide resolved
{
auto notificationsLongRunningPlatform{ winrt::Microsoft::Helpers::GetNotificationPlatform() };
auto notificationsLongRunningPlatform{ PushNotificationHelpers::GetNotificationPlatform() };

wil::unique_cotaskmem_string processName;
THROW_IF_FAILED(GetCurrentProcessPath(processName));
Expand All @@ -194,9 +134,12 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation

if (!foregroundHandled)
{
wil::unique_cotaskmem_string processName;
THROW_IF_FAILED(GetCurrentProcessPath(processName));
THROW_IF_FAILED(winrt::Microsoft::Helpers::ProtocolLaunchHelper(processName.get(), payloadLength, payload));
if (!AppModel::Identity::IsPackagedProcess())
{
wil::unique_cotaskmem_string processName;
THROW_IF_FAILED(GetCurrentProcessPath(processName));
THROW_IF_FAILED(PushNotificationHelpers::ProtocolLaunchHelper(processName.get(), payloadLength, payload));
}
}

return S_OK;
Expand Down
Loading