Skip to content
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
1 change: 1 addition & 0 deletions dev/AppLifecycle/ActivationRegistrationManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +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_runKeyPath{ LR"(Software\Microsoft\Windows\CurrentVersion\Run\)" };

struct ActivationRegistrationManager
Expand Down
10 changes: 6 additions & 4 deletions dev/AppLifecycle/AppInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#include "FileActivatedEventArgs.h"
#include "Association.h"
#include "ExtensionContract.h"
#include "GetRawNotificationEventArgs.h"
#include "GetNotificationEventArgs.h"

using namespace winrt;
using namespace winrt::Windows::Foundation;
Expand Down Expand Up @@ -376,10 +376,12 @@ namespace winrt::Microsoft::Windows::AppLifecycle::implementation
// protocol, except the catch-all LaunchActivatedEventArgs case.
if (!contractArgument.empty())
{
if (contractArgument == c_pushProtocolArgumentString)
if (contractArgument == c_pushProtocolArgumentString || contractArgument == c_toastProtocolArgumentString)
{
// Generate a basic encoded launch Uri for all Push activations.
std::wstring tempContractData = GenerateEncodedLaunchUri(L"App", c_pushContractId);
// Generate a basic encoded launch Uri for Push/Toast activations
PCWSTR contractId = (contractArgument == c_pushProtocolArgumentString) ? c_pushContractId : c_toastContractId;
std::wstring tempContractData = GenerateEncodedLaunchUri(L"App", contractId);

contractArgument = c_msProtocolArgumentString;

// A non-empty contractData means we have a payload.
Expand Down
1 change: 1 addition & 0 deletions dev/AppLifecycle/AppLifecycle.idl
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ namespace Microsoft.Windows.AppLifecycle
// Windows.ApplicationModel.Activation.ActivationKind.

Push = 5000,
AppNotification,
};

runtimeclass AppActivationArguments
Expand Down
3 changes: 2 additions & 1 deletion dev/AppLifecycle/ExtensionContract.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#include "ProtocolActivatedEventArgs.h"
#include "FileActivatedEventArgs.h"
#include "StartupActivatedEventArgs.h"
#include "GetRawNotificationEventArgs.h"
#include "GetNotificationEventArgs.h"

namespace winrt::Microsoft::Windows::AppLifecycle::implementation
{
Expand All @@ -26,6 +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 },
};

inline bool IsEncodedLaunch(winrt::Windows::Foundation::Uri const& uri)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "externs.h"

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

namespace winrt::Microsoft::Windows::PushNotifications
{
Expand All @@ -25,11 +26,6 @@ namespace winrt::Microsoft::Windows::PushNotifications
return winrt::make<winrt::Microsoft::Windows::PushNotifications::implementation::PushNotificationReceivedEventArgs>(payloadAsWstring);
}
}

const DWORD receiveArgsTimeoutInMSec{ 2000 };
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);
return GetArgsFromComStore();
}
}
2 changes: 1 addition & 1 deletion dev/PushNotifications/PushNotifications.vcxitems
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
</ItemGroup>
<ItemGroup>
<ClInclude Include="$(MSBuildThisFileDirectory)externs.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)GetRawNotificationEventArgs.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)GetNotificationEventArgs.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)PushNotificationActivationInfo.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)PushNotificationBackgroundTask.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)PushNotificationChannel.h" />
Expand Down
10 changes: 10 additions & 0 deletions dev/PushNotifications/externs.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#pragma once
#include "pch.h"
#include <winrt/Windows.ApplicationModel.Core.h>

wil::unique_event& GetWaitHandleForArgs();

Expand All @@ -20,3 +21,12 @@ inline HRESULT GetCurrentProcessPath(wil::unique_cotaskmem_string& processName)
{
return wil::GetModuleFileNameExW(GetCurrentProcess(), nullptr, processName);
};

inline winrt::Windows::Foundation::IInspectable GetArgsFromComStore()
{
const DWORD receiveArgsTimeoutInMSec{ 2000 };
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);
}
2 changes: 1 addition & 1 deletion dev/ToastNotifications/ToastActivationCallback.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ struct ToastActivationCallbackFactory : winrt::implements<ToastActivationCallbac
{
STDMETHODIMP CreateInstance(_In_opt_ IUnknown* aggregateInterface, _In_ REFIID interfaceId, _Outptr_ VOID** object) noexcept final try
{
RETURN_HR_IF_NULL(CLASS_E_NOAGGREGATION, aggregateInterface);
RETURN_HR_IF(CLASS_E_NOAGGREGATION, aggregateInterface != nullptr);
Comment thread
pmpurifoy marked this conversation as resolved.
return winrt::make<ToastActivationCallback>().as(interfaceId, object);
}
CATCH_RETURN()
Expand Down
8 changes: 4 additions & 4 deletions dev/ToastNotifications/ToastNotificationManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,13 @@ namespace winrt::Microsoft::Windows::ToastNotifications::implementation
// TODO: Remove ToastGuid reference from LRP
}
}
winrt::event_token ToastNotificationManager::ToastActivated(winrt::Windows::Foundation::EventHandler<winrt::Microsoft::Windows::ToastNotifications::ToastActivatedEventArgs> const& /* handler */)
winrt::event_token ToastNotificationManager::ToastActivated(winrt::Windows::Foundation::EventHandler<winrt::Microsoft::Windows::ToastNotifications::ToastActivatedEventArgs> const& handler)
{
throw hresult_not_implemented();
return GetToastHandlers().add(handler);
}
void ToastNotificationManager::ToastActivated(winrt::event_token const&/* token */)
void ToastNotificationManager::ToastActivated(winrt::event_token const& token)
{
throw hresult_not_implemented();
GetToastHandlers().remove(token);
}
void ToastNotificationManager::ShowToast(winrt::Microsoft::Windows::ToastNotifications::ToastNotification const& /* toast */)
{
Expand Down
2 changes: 1 addition & 1 deletion dev/ToastNotifications/ToastNotificationUtility.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
const std::wstring c_appIdentifierPath{ LR"(Software\Classes\AppUserModelId\)" };
const std::wstring c_clsIdPath{ LR"(Software\Classes\CLSID\)" };
const std::wstring c_quote{ LR"(")" };
const std::wstring c_toastActivatedArgument{ L" ----ToastActivated:" };
const std::wstring c_toastActivatedArgument{ L" ----AppNotificationActivated:" };

winrt::event<winrt::Windows::Foundation::EventHandler<winrt::Microsoft::Windows::ToastNotifications::ToastActivatedEventArgs>>& GetToastHandlers();

Expand Down
37 changes: 32 additions & 5 deletions test/TestApps/ToastNotificationsTestApp/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,17 @@ namespace winrt
using namespace winrt::Microsoft::Windows::ToastNotifications;
}

bool BackgroundActivationTest() // Activating application for background test.
{
return true;
}

bool UnregisterBackgroundActivationTest()
{
winrt::ToastNotificationManager::Default().UnregisterActivator();
return true;
}

bool VerifyFailedRegisterActivatorUsingNullClsid()
{
try
Expand Down Expand Up @@ -78,12 +89,19 @@ bool VerifyFailedRegisterActivatorUsingNullAssets_Unpackaged()

bool VerifyRegisterActivatorandUnRegisterActivatorUsingClsid()
{
auto activationInfo = winrt::ToastActivationInfo::CreateFromActivationGuid(winrt::guid("1940DBA9-0F64-4F0D-8A4B-5D207B812E61"));

winrt::ToastNotificationManager::Default().RegisterActivator(activationInfo);

winrt::ToastNotificationManager::Default().UnregisterActivator();
try
{
auto activationInfo = winrt::ToastActivationInfo::CreateFromActivationGuid(c_toastComServerId);

winrt::ToastNotificationManager::Default().RegisterActivator(activationInfo);

winrt::ToastNotificationManager::Default().UnregisterActivator();
}
catch (...)
{
return false;
}
return true;
}

Expand All @@ -104,7 +122,7 @@ bool VerifyFailedMultipleRegisterActivatorUsingSameClsid()
{
try
{
auto activationInfo = winrt::ToastActivationInfo::CreateFromActivationGuid(winrt::guid("1940DBA9-0F64-4F0D-8A4B-5D207B812E61"));
auto activationInfo = winrt::ToastActivationInfo::CreateFromActivationGuid(c_toastComServerId);

winrt::ToastNotificationManager::Default().RegisterActivator(activationInfo);

Expand Down Expand Up @@ -201,9 +219,12 @@ std::string unitTestNameFromLaunchArguments(const winrt::ILaunchActivatedEventAr
std::map<std::string, bool(*)()> const& GetSwitchMapping()
{
static std::map<std::string, bool(*)()> switchMapping = {
{ "BackgroundActivationTest", &BackgroundActivationTest},
{ "UnregisterBackgroundActivationTest", &UnregisterBackgroundActivationTest},
{ "VerifyFailedRegisterActivatorUsingNullClsid", &VerifyFailedRegisterActivatorUsingNullClsid },
{ "VerifyFailedRegisterActivatorUsingNullClsid_Unpackaged", &VerifyFailedRegisterActivatorUsingNullClsid_Unpackaged},
{ "VerifyFailedRegisterActivatorUsingNullAssets", &VerifyFailedRegisterActivatorUsingNullAssets },
{ "VerifyFailedRegisterActivatorUsingNullAssets_Unpackaged", &VerifyFailedRegisterActivatorUsingNullAssets_Unpackaged},
{ "VerifyRegisterActivatorandUnRegisterActivatorUsingClsid", &VerifyRegisterActivatorandUnRegisterActivatorUsingClsid },
{ "VerifyRegisterActivatorandUnRegisterActivatorUsingAssets_Unpackaged", &VerifyRegisterActivatorandUnRegisterActivatorUsingAssets_Unpackaged },
{ "VerifyFailedMultipleRegisterActivatorUsingSameClsid", &VerifyFailedMultipleRegisterActivatorUsingSameClsid },
Expand Down Expand Up @@ -237,6 +258,12 @@ int main() try

::Test::Bootstrap::SetupBootstrap();

if (Test::AppModel::IsPackagedProcess())
{
auto activationInfo = winrt::ToastActivationInfo::CreateFromActivationGuid(c_toastComServerId);
winrt::ToastNotificationManager::Default().RegisterActivator(activationInfo);
}

auto args = winrt::AppInstance::GetCurrent().GetActivatedEventArgs();
auto kind = args.Kind();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
<com:Extension Category="windows.comServer">
<com:ComServer>
<com:ExeServer Executable="ToastNotificationsTestApp\ToastNotificationsTestApp.exe" DisplayName="SampleBackgroundApp" Arguments="----ToastActivated:">
<com:Class Id="1940DBA9-0F64-4F0D-8A4B-5D207B812E61" DisplayName="Windows App Runtime Toast" />
<com:Class Id="1940dba9-0f64-4f0d-8a4b-5d207b812e61" DisplayName="Windows App Runtime Toast" />
</com:ExeServer>
</com:ComServer>
</com:Extension>
Expand Down
11 changes: 11 additions & 0 deletions test/ToastNotificationTests/APITests.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "pch.h"
#include "NotificationActivationCallback.h"
#include <TestDef.h>

using namespace WEX::Common;
Expand Down Expand Up @@ -158,6 +159,16 @@ namespace Test::ToastNotifications
VERIFY_ARE_EQUAL(exitCode, 0);
}

TEST_METHOD(VerifyBackgroundActivation)
{
RunTest(L"BackgroundActivationTest", testWaitTime()); // Need to launch one time to enable background activation.

auto toastActivationCallback = winrt::create_instance<INotificationActivationCallback>(c_toastComServerId, CLSCTX_ALL);
VERIFY_SUCCEEDED(toastActivationCallback->Activate(L"AUMID", L"args", nullptr, 0));

RunTest(L"UnregisterBackgroundActivationTest", testWaitTime()); // Need to launch again to unregister activation
}

TEST_METHOD(VerifyFailedRegisterActivatorUsingNullClsid)
{
RunTest(L"VerifyFailedRegisterActivatorUsingNullClsid", testWaitTime());
Expand Down
1 change: 1 addition & 0 deletions test/inc/TestDef.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ static const std::wstring c_testInstanceRedirectedPhaseEventName = L"WindowsAppR
static const std::wstring c_testPushPhaseEventName = L"WindowsAppRuntimeTestPushPhaseEventName";
inline const winrt::hstring c_rawNotificationPayload = L"<toast></toast>";
inline IID c_comServerId = winrt::guid("ccd2ae3f-764f-4ae3-be45-9804761b28b2"); // Value from PushNotificationsTestAppPackage ComActivator in appxmanifest.
inline IID c_toastComServerId = winrt::guid("1940dba9-0f64-4f0d-8a4b-5d207b812e61"); // Value from ToastNotificationsTestAppPackage ComActivator in appxmanifest.
inline IID c_fakeComServerId = winrt::guid("00000000-0000-0000-0000-000000000001");

#ifndef WIDEN2
Expand Down