Skip to content

Commit

Permalink
Addressed comments mostly on Background Activation and the IDL
Browse files Browse the repository at this point in the history
  • Loading branch information
Daniel Ayala committed Jun 10, 2021
1 parent ab1ac2b commit 6f55098
Show file tree
Hide file tree
Showing 13 changed files with 58 additions and 69 deletions.
17 changes: 2 additions & 15 deletions dev/PushNotifications/GetRawNotificationEventArgs.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,11 @@

constexpr PCWSTR c_pushContractId = L"Windows.Push";

using namespace winrt::Windows::ApplicationModel::Core;
namespace winrt::Microsoft::Windows::PushNotifications
{
static winrt::Windows::Foundation::IInspectable Deserialize(winrt::Windows::Foundation::Uri const&)
{
if (WaitForSingleObject(g_waitHandleForArgs.get(), 2000) == WAIT_OBJECT_0)
{
auto appProperties = CoreApplication::Properties();
if (auto foundActivatedEventArgs = appProperties.TryLookup(ACTIVATED_EVENT_ARGS_KEY))
{
return foundActivatedEventArgs.as<PushNotificationReceivedEventArgs>();
}
else
{
return nullptr;
}
}

winrt::throw_hresult(HRESULT_FROM_WIN32(ERROR_TIMEOUT));
THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_TIMEOUT), !g_waitHandleForArgs.wait(2000));
return winrt::Windows::ApplicationModel::Core::CoreApplication::Properties().TryLookup(ACTIVATED_EVENT_ARGS_KEY).as<PushNotificationReceivedEventArgs>();
}
}
6 changes: 3 additions & 3 deletions dev/PushNotifications/PushNotificationActivationInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,16 @@ namespace winrt

namespace winrt::Microsoft::Windows::PushNotifications::implementation
{
PushNotificationActivationInfo::PushNotificationActivationInfo(winrt::PushNotificationRegistrationOption const& option, winrt::guid const& taskClsid) : m_option(option), m_taskClsid(taskClsid) {}
PushNotificationActivationInfo::PushNotificationActivationInfo(winrt::PushNotificationRegistrationOptions const& options, winrt::guid const& taskClsid) : m_options(options), m_taskClsid(taskClsid) {}

winrt::guid PushNotificationActivationInfo::TaskClsid()
{
return m_taskClsid;
}

winrt::PushNotificationRegistrationOption PushNotificationActivationInfo::Option()
winrt::PushNotificationRegistrationOptions PushNotificationActivationInfo::Options()
{
return m_option;
return m_options;
}

winrt::com_array<winrt::IBackgroundCondition> PushNotificationActivationInfo::GetConditions()
Expand Down
6 changes: 3 additions & 3 deletions dev/PushNotifications/PushNotificationActivationInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation
{
struct PushNotificationActivationInfo : PushNotificationActivationInfoT<PushNotificationActivationInfo>
{
PushNotificationActivationInfo(Microsoft::Windows::PushNotifications::PushNotificationRegistrationOption const& option, winrt::guid const& taskClsid);
PushNotificationActivationInfo(Microsoft::Windows::PushNotifications::PushNotificationRegistrationOptions const& option, winrt::guid const& taskClsid);
winrt::guid TaskClsid();
Microsoft::Windows::PushNotifications::PushNotificationRegistrationOption Option();
Microsoft::Windows::PushNotifications::PushNotificationRegistrationOptions Options();
winrt::com_array<winrt::Windows::ApplicationModel::Background::IBackgroundCondition> GetConditions();
void SetConditions(array_view<winrt::Windows::ApplicationModel::Background::IBackgroundCondition const> conditions);

private:
const Microsoft::Windows::PushNotifications::PushNotificationRegistrationOption m_option;
const Microsoft::Windows::PushNotifications::PushNotificationRegistrationOptions m_options;
const winrt::guid m_taskClsid;
winrt::com_array<winrt::Windows::ApplicationModel::Background::IBackgroundCondition> m_backgroundConditions{};
wil::srwlock m_lock;
Expand Down
2 changes: 1 addition & 1 deletion dev/PushNotifications/PushNotificationBackgroundTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ namespace winrt
using namespace Windows::ApplicationModel::Core;
}

wil::unique_handle g_waitHandleForArgs = wil::unique_handle(CreateEvent(nullptr, FALSE, FALSE, nullptr));
wil::unique_event g_waitHandleForArgs;

void PushNotificationBackgroundTask::Run(winrt::IBackgroundTaskInstance const& taskInstance)
{
Expand Down
3 changes: 2 additions & 1 deletion dev/PushNotifications/PushNotificationBackgroundTask.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@ struct PushNotificationBackgroundTask : winrt::implements<PushNotificationBackgr

struct PushNotificationBackgroundTaskFactory : winrt::implements<PushNotificationBackgroundTaskFactory, IClassFactory>
{
HRESULT __stdcall CreateInstance(_In_opt_ IUnknown* aggregateInterface, _In_ REFIID interfaceId, _Outptr_ VOID** object) noexcept final
HRESULT __stdcall CreateInstance(_In_opt_ IUnknown* aggregateInterface, _In_ REFIID interfaceId, _Outptr_ VOID** object) noexcept final try
{
RETURN_HR_IF(CLASS_E_NOAGGREGATION, aggregateInterface != nullptr);
return winrt::make<PushNotificationBackgroundTask>().as(interfaceId, object);
}
CATCH_RETURN()

HRESULT __stdcall LockServer(BOOL fLock) noexcept final
{
Expand Down
31 changes: 14 additions & 17 deletions dev/PushNotifications/PushNotificationManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,14 +145,14 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation
GUID taskClsid = details.TaskClsid();
THROW_HR_IF(E_INVALIDARG, taskClsid == GUID_NULL);

auto registrationOption = details.Option();
THROW_HR_IF(E_INVALIDARG, WI_AreAllFlagsClear(registrationOption, PushNotificationRegistrationOption::PushTrigger | PushNotificationRegistrationOption::ComActivator));
auto registrationOptions = details.Options();
THROW_HR_IF(E_INVALIDARG, WI_AreAllFlagsClear(registrationOptions, PushNotificationRegistrationOptions::PushTrigger | PushNotificationRegistrationOptions::ComActivator));

DWORD cookie = 0;
IBackgroundTaskRegistration registeredTask = nullptr;
BackgroundTaskBuilder builder = nullptr;

if (WI_IsFlagSet(registrationOption, PushNotificationRegistrationOption::PushTrigger))
if (WI_IsFlagSet(registrationOptions, PushNotificationRegistrationOptions::PushTrigger))
{
winrt::hstring taskClsidStr = winrt::to_hstring(taskClsid);
winrt::hstring backgroundTaskFullName = backgroundTaskName + taskClsidStr;
Expand Down Expand Up @@ -201,28 +201,28 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation
}
}

bool registeredWithCom = false;
bool registeredWithBackgroundTask = false;
BackgroundTaskRegistration registeredTaskFromBuilder = nullptr;

auto scopeExitToCleanRegistrations = wil::scope_exit(
[&]()
{
if (registeredWithCom)
if (cookie > 0)
{
LOG_IF_FAILED(::CoRevokeClassObject(cookie));
}

// Clean the task registration only if it was created during this call
if (registeredWithBackgroundTask)
if (registeredTaskFromBuilder)
{
registeredTask.Unregister(true);
}

}
);

if (WI_IsFlagSet(registrationOption, PushNotificationRegistrationOption::ComActivator))
if (WI_IsFlagSet(registrationOptions, PushNotificationRegistrationOptions::ComActivator))
{
g_waitHandleForArgs.create();
THROW_HR_IF_NULL(E_UNEXPECTED, g_waitHandleForArgs);

THROW_IF_FAILED(::CoRegisterClassObject(
Expand All @@ -231,34 +231,31 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation
CLSCTX_LOCAL_SERVER,
REGCLS_MULTIPLEUSE,
&cookie));

registeredWithCom = true;
}

if (builder)
{
auto registeredTaskFromBuilder = builder.Register();
registeredTask = registeredTaskFromBuilder.as<IBackgroundTaskRegistration>();
registeredWithBackgroundTask = true;
registeredTaskFromBuilder = builder.Register();
}

PushNotificationRegistrationToken token = { cookie, registeredTask };
PushNotificationRegistrationToken token = { cookie, registeredTaskFromBuilder };
scopeExitToCleanRegistrations.release();

return token;
}

void PushNotificationManager::UnregisterActivator(PushNotificationRegistrationToken const& token, PushNotificationRegistrationOption const& option)
void PushNotificationManager::UnregisterActivator(PushNotificationRegistrationToken const& token, PushNotificationRegistrationOptions const& options)
{
THROW_HR_IF_NULL(E_INVALIDARG, token);
if (WI_IsFlagSet(option, PushNotificationRegistrationOption::PushTrigger))
if (WI_IsFlagSet(options, PushNotificationRegistrationOptions::PushTrigger))
{
auto taskRegistration = token.TaskRegistration();
THROW_HR_IF_NULL(HRESULT_FROM_WIN32(ERROR_NOT_FOUND), taskRegistration);
taskRegistration.Unregister(true);
}

if (WI_IsFlagSet(option, PushNotificationRegistrationOption::ComActivator) && token.Cookie())
// Check for COM flag, a valid cookie and if there are outstanding locks on the PushNotificationBackgroundTask class factory
if (WI_IsFlagSet(options, PushNotificationRegistrationOptions::ComActivator) && token.Cookie() && winrt::get_module_lock() == 0)
{
LOG_IF_FAILED(::CoRevokeClassObject(static_cast<DWORD>(token.Cookie())));
}
Expand Down
2 changes: 1 addition & 1 deletion dev/PushNotifications/PushNotificationManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation
PushNotificationManager() = delete;

static Microsoft::Windows::PushNotifications::PushNotificationRegistrationToken RegisterActivator(Microsoft::Windows::PushNotifications::PushNotificationActivationInfo const& details);
static void UnregisterActivator(Microsoft::Windows::PushNotifications::PushNotificationRegistrationToken const& token, Microsoft::Windows::PushNotifications::PushNotificationRegistrationOption const& option);
static void UnregisterActivator(Microsoft::Windows::PushNotifications::PushNotificationRegistrationToken const& token, Microsoft::Windows::PushNotifications::PushNotificationRegistrationOptions const& options);

static winrt::Windows::Foundation::IAsyncOperationWithProgress<winrt::Microsoft::Windows::PushNotifications::PushNotificationCreateChannelResult, winrt::Microsoft::Windows::PushNotifications::PushNotificationCreateChannelStatus> CreateChannelAsync(const winrt::guid &remoteId);

Expand Down
4 changes: 2 additions & 2 deletions dev/PushNotifications/PushNotificationRegistrationToken.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@

namespace winrt::Microsoft::Windows::PushNotifications::implementation
{
PushNotificationRegistrationToken::PushNotificationRegistrationToken(uint64_t const& cookie, winrt::Windows::ApplicationModel::Background::IBackgroundTaskRegistration const& taskRegistration): m_cookie(cookie), m_taskRegistration(taskRegistration) { }
PushNotificationRegistrationToken::PushNotificationRegistrationToken(uint32_t const& cookie, winrt::Windows::ApplicationModel::Background::IBackgroundTaskRegistration const& taskRegistration): m_cookie(cookie), m_taskRegistration(taskRegistration) { }

uint64_t PushNotificationRegistrationToken::Cookie()
uint32_t PushNotificationRegistrationToken::Cookie()
{
return m_cookie;
}
Expand Down
6 changes: 3 additions & 3 deletions dev/PushNotifications/PushNotificationRegistrationToken.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation
{
struct PushNotificationRegistrationToken : PushNotificationRegistrationTokenT<PushNotificationRegistrationToken>
{
PushNotificationRegistrationToken(uint64_t const& cookie, winrt::Windows::ApplicationModel::Background::IBackgroundTaskRegistration const& taskRegistration);
uint64_t Cookie();
PushNotificationRegistrationToken(uint32_t const& cookie, winrt::Windows::ApplicationModel::Background::IBackgroundTaskRegistration const& taskRegistration);
uint32_t Cookie();
winrt::Windows::ApplicationModel::Background::IBackgroundTaskRegistration TaskRegistration();

private:
const uint64_t m_cookie;
const uint32_t m_cookie;
const winrt::Windows::ApplicationModel::Background::IBackgroundTaskRegistration m_taskRegistration;
};
}
Expand Down
19 changes: 10 additions & 9 deletions dev/PushNotifications/PushNotifications.idl
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,19 @@ namespace Microsoft.Windows.PushNotifications
// The Push payload
byte[] Payload { get; };

// Gets a deferral to run under specific modes like low power mode
// Gets a deferral to allow push notification processing even if the system goes into low power mode.
Windows.ApplicationModel.Background.BackgroundTaskDeferral GetDeferral();

// Subscribe to Cancelled event handler to be signalled when resource policies are no longer true like 30s wallclock timer
event Windows.ApplicationModel.Background.BackgroundTaskCanceledEventHandler Canceled;

// Set to true to prevent proceeding launch due to Background Activation: false by default
// Indicates if the foreground push notification will be re-posted through background activation.
// Default value is false, which allows re-posting.
Boolean Handled;
};

[flags]
enum PushNotificationRegistrationOption
enum PushNotificationRegistrationOptions
{
PushTrigger = 0x1, // Registers a Push Trigger with Background Infrastructure
ComActivator = 0x2, // Registers the Project Reunion Background Task component as an InProc COM server
Expand All @@ -33,12 +34,12 @@ namespace Microsoft.Windows.PushNotifications
// Initialize using a RegistrationOption and optionally defined parameters like manifest defined activatorId
// 1) If option = PushTrigger is specified, only the Push Trigger will be Registered with Background Infrastructure
// 2) If option = ComActivator is specified, the Project Reunion Background Task component will be Registered as an InProc COM server
PushNotificationActivationInfo(PushNotificationRegistrationOption option, Guid taskClsid);
PushNotificationActivationInfo(PushNotificationRegistrationOptions options, Guid taskClsid);

// The CLSID associated with the Client COM server that Project Reunion will activate
Guid TaskClsid{ get; };

PushNotificationRegistrationOption Option{ get; };
PushNotificationRegistrationOptions Options{ get; };

// The conditions under which Push Triggers would execute
Windows.ApplicationModel.Background.IBackgroundCondition[] GetConditions();
Expand Down Expand Up @@ -106,13 +107,13 @@ namespace Microsoft.Windows.PushNotifications
runtimeclass PushNotificationRegistrationToken
{
PushNotificationRegistrationToken(
UInt64 cookie,
UInt32 cookie,
Windows.ApplicationModel.Background.IBackgroundTaskRegistration taskRegistration);

// The cookie from CoRegisterClassObject
UInt64 Cookie{ get; };
UInt32 Cookie{ get; };

// The Registration token for the Push Trigger
// The registration for the Push Trigger
Windows.ApplicationModel.Background.IBackgroundTaskRegistration TaskRegistration { get; };
};

Expand All @@ -125,7 +126,7 @@ namespace Microsoft.Windows.PushNotifications
// Unregister any activator if present using a token and registrationOption
// 1) If option = PushTrigger is specified, the trigger itself will be removed
// 2) If option = ComActivator is specified, the Project Reunion Background Task component will no longer act as an InProc COM Server
static void UnregisterActivator(PushNotificationRegistrationToken token, PushNotificationRegistrationOption option);
static void UnregisterActivator(PushNotificationRegistrationToken token, PushNotificationRegistrationOptions options);

// Request a Push Channel using an encoded AAD GUID identifier from WNS.
static Windows.Foundation.IAsyncOperationWithProgress<PushNotificationCreateChannelResult, PushNotificationCreateChannelStatus> CreateChannelAsync(Guid remoteId);
Expand Down
4 changes: 2 additions & 2 deletions dev/PushNotifications/externs.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@
#include "pch.h"
#include "PushNotificationReceivedEventArgs.h"

extern wil::unique_handle g_waitHandleForArgs;
extern wil::unique_event g_waitHandleForArgs;

const winrt::hstring ACTIVATED_EVENT_ARGS_KEY = L"GlobalActivatedEventArgs";
inline const winrt::hstring ACTIVATED_EVENT_ARGS_KEY = L"GlobalActivatedEventArgs";
6 changes: 4 additions & 2 deletions test/TestApps/PushNotificationsDemoApp/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ int main()
std::cout << "Project Reunion Push Notification Test App: " << buf << std::endl;

PushNotificationActivationInfo info(
PushNotificationRegistrationOption::PushTrigger | PushNotificationRegistrationOption::ComActivator,
PushNotificationRegistrationOptions::PushTrigger | PushNotificationRegistrationOptions::ComActivator,
winrt::guid("ccd2ae3f-764f-4ae3-be45-9804761b28b2")); // same clsid as app manifest

auto token = PushNotificationManager::RegisterActivator(info);
Expand Down Expand Up @@ -139,6 +139,8 @@ int main()
std::cin.ignore();
}

PushNotificationManager::UnregisterActivator(token, PushNotificationRegistrationOption::ComActivator); // Don't unregister PushTrigger because we still want to receive push notifications from background infrastructure.
// Don't unregister PushTrigger because we still want to receive push notifications from background infrastructure.
PushNotificationManager::UnregisterActivator(token, PushNotificationRegistrationOptions::ComActivator);

return 0;
}
Loading

0 comments on commit 6f55098

Please sign in to comment.