Skip to content

Commit 6f55098

Browse files
author
Daniel Ayala
committed
Addressed comments mostly on Background Activation and the IDL
1 parent ab1ac2b commit 6f55098

13 files changed

+58
-69
lines changed

dev/PushNotifications/GetRawNotificationEventArgs.h

+2-15
Original file line numberDiff line numberDiff line change
@@ -8,24 +8,11 @@
88

99
constexpr PCWSTR c_pushContractId = L"Windows.Push";
1010

11-
using namespace winrt::Windows::ApplicationModel::Core;
1211
namespace winrt::Microsoft::Windows::PushNotifications
1312
{
1413
static winrt::Windows::Foundation::IInspectable Deserialize(winrt::Windows::Foundation::Uri const&)
1514
{
16-
if (WaitForSingleObject(g_waitHandleForArgs.get(), 2000) == WAIT_OBJECT_0)
17-
{
18-
auto appProperties = CoreApplication::Properties();
19-
if (auto foundActivatedEventArgs = appProperties.TryLookup(ACTIVATED_EVENT_ARGS_KEY))
20-
{
21-
return foundActivatedEventArgs.as<PushNotificationReceivedEventArgs>();
22-
}
23-
else
24-
{
25-
return nullptr;
26-
}
27-
}
28-
29-
winrt::throw_hresult(HRESULT_FROM_WIN32(ERROR_TIMEOUT));
15+
THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_TIMEOUT), !g_waitHandleForArgs.wait(2000));
16+
return winrt::Windows::ApplicationModel::Core::CoreApplication::Properties().TryLookup(ACTIVATED_EVENT_ARGS_KEY).as<PushNotificationReceivedEventArgs>();
3017
}
3118
}

dev/PushNotifications/PushNotificationActivationInfo.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,16 @@ namespace winrt
1515

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

2020
winrt::guid PushNotificationActivationInfo::TaskClsid()
2121
{
2222
return m_taskClsid;
2323
}
2424

25-
winrt::PushNotificationRegistrationOption PushNotificationActivationInfo::Option()
25+
winrt::PushNotificationRegistrationOptions PushNotificationActivationInfo::Options()
2626
{
27-
return m_option;
27+
return m_options;
2828
}
2929

3030
winrt::com_array<winrt::IBackgroundCondition> PushNotificationActivationInfo::GetConditions()

dev/PushNotifications/PushNotificationActivationInfo.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation
88
{
99
struct PushNotificationActivationInfo : PushNotificationActivationInfoT<PushNotificationActivationInfo>
1010
{
11-
PushNotificationActivationInfo(Microsoft::Windows::PushNotifications::PushNotificationRegistrationOption const& option, winrt::guid const& taskClsid);
11+
PushNotificationActivationInfo(Microsoft::Windows::PushNotifications::PushNotificationRegistrationOptions const& option, winrt::guid const& taskClsid);
1212
winrt::guid TaskClsid();
13-
Microsoft::Windows::PushNotifications::PushNotificationRegistrationOption Option();
13+
Microsoft::Windows::PushNotifications::PushNotificationRegistrationOptions Options();
1414
winrt::com_array<winrt::Windows::ApplicationModel::Background::IBackgroundCondition> GetConditions();
1515
void SetConditions(array_view<winrt::Windows::ApplicationModel::Background::IBackgroundCondition const> conditions);
1616

1717
private:
18-
const Microsoft::Windows::PushNotifications::PushNotificationRegistrationOption m_option;
18+
const Microsoft::Windows::PushNotifications::PushNotificationRegistrationOptions m_options;
1919
const winrt::guid m_taskClsid;
2020
winrt::com_array<winrt::Windows::ApplicationModel::Background::IBackgroundCondition> m_backgroundConditions{};
2121
wil::srwlock m_lock;

dev/PushNotifications/PushNotificationBackgroundTask.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ namespace winrt
2020
using namespace Windows::ApplicationModel::Core;
2121
}
2222

23-
wil::unique_handle g_waitHandleForArgs = wil::unique_handle(CreateEvent(nullptr, FALSE, FALSE, nullptr));
23+
wil::unique_event g_waitHandleForArgs;
2424

2525
void PushNotificationBackgroundTask::Run(winrt::IBackgroundTaskInstance const& taskInstance)
2626
{

dev/PushNotifications/PushNotificationBackgroundTask.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,12 @@ struct PushNotificationBackgroundTask : winrt::implements<PushNotificationBackgr
1818

1919
struct PushNotificationBackgroundTaskFactory : winrt::implements<PushNotificationBackgroundTaskFactory, IClassFactory>
2020
{
21-
HRESULT __stdcall CreateInstance(_In_opt_ IUnknown* aggregateInterface, _In_ REFIID interfaceId, _Outptr_ VOID** object) noexcept final
21+
HRESULT __stdcall CreateInstance(_In_opt_ IUnknown* aggregateInterface, _In_ REFIID interfaceId, _Outptr_ VOID** object) noexcept final try
2222
{
2323
RETURN_HR_IF(CLASS_E_NOAGGREGATION, aggregateInterface != nullptr);
2424
return winrt::make<PushNotificationBackgroundTask>().as(interfaceId, object);
2525
}
26+
CATCH_RETURN()
2627

2728
HRESULT __stdcall LockServer(BOOL fLock) noexcept final
2829
{

dev/PushNotifications/PushNotificationManager.cpp

+14-17
Original file line numberDiff line numberDiff line change
@@ -145,14 +145,14 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation
145145
GUID taskClsid = details.TaskClsid();
146146
THROW_HR_IF(E_INVALIDARG, taskClsid == GUID_NULL);
147147

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

151151
DWORD cookie = 0;
152152
IBackgroundTaskRegistration registeredTask = nullptr;
153153
BackgroundTaskBuilder builder = nullptr;
154154

155-
if (WI_IsFlagSet(registrationOption, PushNotificationRegistrationOption::PushTrigger))
155+
if (WI_IsFlagSet(registrationOptions, PushNotificationRegistrationOptions::PushTrigger))
156156
{
157157
winrt::hstring taskClsidStr = winrt::to_hstring(taskClsid);
158158
winrt::hstring backgroundTaskFullName = backgroundTaskName + taskClsidStr;
@@ -201,28 +201,28 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation
201201
}
202202
}
203203

204-
bool registeredWithCom = false;
205-
bool registeredWithBackgroundTask = false;
204+
BackgroundTaskRegistration registeredTaskFromBuilder = nullptr;
206205

207206
auto scopeExitToCleanRegistrations = wil::scope_exit(
208207
[&]()
209208
{
210-
if (registeredWithCom)
209+
if (cookie > 0)
211210
{
212211
LOG_IF_FAILED(::CoRevokeClassObject(cookie));
213212
}
214213

215214
// Clean the task registration only if it was created during this call
216-
if (registeredWithBackgroundTask)
215+
if (registeredTaskFromBuilder)
217216
{
218217
registeredTask.Unregister(true);
219218
}
220219

221220
}
222221
);
223222

224-
if (WI_IsFlagSet(registrationOption, PushNotificationRegistrationOption::ComActivator))
223+
if (WI_IsFlagSet(registrationOptions, PushNotificationRegistrationOptions::ComActivator))
225224
{
225+
g_waitHandleForArgs.create();
226226
THROW_HR_IF_NULL(E_UNEXPECTED, g_waitHandleForArgs);
227227

228228
THROW_IF_FAILED(::CoRegisterClassObject(
@@ -231,34 +231,31 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation
231231
CLSCTX_LOCAL_SERVER,
232232
REGCLS_MULTIPLEUSE,
233233
&cookie));
234-
235-
registeredWithCom = true;
236234
}
237235

238236
if (builder)
239237
{
240-
auto registeredTaskFromBuilder = builder.Register();
241-
registeredTask = registeredTaskFromBuilder.as<IBackgroundTaskRegistration>();
242-
registeredWithBackgroundTask = true;
238+
registeredTaskFromBuilder = builder.Register();
243239
}
244240

245-
PushNotificationRegistrationToken token = { cookie, registeredTask };
241+
PushNotificationRegistrationToken token = { cookie, registeredTaskFromBuilder };
246242
scopeExitToCleanRegistrations.release();
247243

248244
return token;
249245
}
250246

251-
void PushNotificationManager::UnregisterActivator(PushNotificationRegistrationToken const& token, PushNotificationRegistrationOption const& option)
247+
void PushNotificationManager::UnregisterActivator(PushNotificationRegistrationToken const& token, PushNotificationRegistrationOptions const& options)
252248
{
253249
THROW_HR_IF_NULL(E_INVALIDARG, token);
254-
if (WI_IsFlagSet(option, PushNotificationRegistrationOption::PushTrigger))
250+
if (WI_IsFlagSet(options, PushNotificationRegistrationOptions::PushTrigger))
255251
{
256252
auto taskRegistration = token.TaskRegistration();
257253
THROW_HR_IF_NULL(HRESULT_FROM_WIN32(ERROR_NOT_FOUND), taskRegistration);
258254
taskRegistration.Unregister(true);
259255
}
260256

261-
if (WI_IsFlagSet(option, PushNotificationRegistrationOption::ComActivator) && token.Cookie())
257+
// Check for COM flag, a valid cookie and if there are outstanding locks on the PushNotificationBackgroundTask class factory
258+
if (WI_IsFlagSet(options, PushNotificationRegistrationOptions::ComActivator) && token.Cookie() && winrt::get_module_lock() == 0)
262259
{
263260
LOG_IF_FAILED(::CoRevokeClassObject(static_cast<DWORD>(token.Cookie())));
264261
}

dev/PushNotifications/PushNotificationManager.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation
1111
PushNotificationManager() = delete;
1212

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

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

dev/PushNotifications/PushNotificationRegistrationToken.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99

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

14-
uint64_t PushNotificationRegistrationToken::Cookie()
14+
uint32_t PushNotificationRegistrationToken::Cookie()
1515
{
1616
return m_cookie;
1717
}

dev/PushNotifications/PushNotificationRegistrationToken.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation
88
{
99
struct PushNotificationRegistrationToken : PushNotificationRegistrationTokenT<PushNotificationRegistrationToken>
1010
{
11-
PushNotificationRegistrationToken(uint64_t const& cookie, winrt::Windows::ApplicationModel::Background::IBackgroundTaskRegistration const& taskRegistration);
12-
uint64_t Cookie();
11+
PushNotificationRegistrationToken(uint32_t const& cookie, winrt::Windows::ApplicationModel::Background::IBackgroundTaskRegistration const& taskRegistration);
12+
uint32_t Cookie();
1313
winrt::Windows::ApplicationModel::Background::IBackgroundTaskRegistration TaskRegistration();
1414

1515
private:
16-
const uint64_t m_cookie;
16+
const uint32_t m_cookie;
1717
const winrt::Windows::ApplicationModel::Background::IBackgroundTaskRegistration m_taskRegistration;
1818
};
1919
}

dev/PushNotifications/PushNotifications.idl

+10-9
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,19 @@ namespace Microsoft.Windows.PushNotifications
1010
// The Push payload
1111
byte[] Payload { get; };
1212

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

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

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

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

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

41-
PushNotificationRegistrationOption Option{ get; };
42+
PushNotificationRegistrationOptions Options{ get; };
4243

4344
// The conditions under which Push Triggers would execute
4445
Windows.ApplicationModel.Background.IBackgroundCondition[] GetConditions();
@@ -106,13 +107,13 @@ namespace Microsoft.Windows.PushNotifications
106107
runtimeclass PushNotificationRegistrationToken
107108
{
108109
PushNotificationRegistrationToken(
109-
UInt64 cookie,
110+
UInt32 cookie,
110111
Windows.ApplicationModel.Background.IBackgroundTaskRegistration taskRegistration);
111112

112113
// The cookie from CoRegisterClassObject
113-
UInt64 Cookie{ get; };
114+
UInt32 Cookie{ get; };
114115

115-
// The Registration token for the Push Trigger
116+
// The registration for the Push Trigger
116117
Windows.ApplicationModel.Background.IBackgroundTaskRegistration TaskRegistration { get; };
117118
};
118119

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

130131
// Request a Push Channel using an encoded AAD GUID identifier from WNS.
131132
static Windows.Foundation.IAsyncOperationWithProgress<PushNotificationCreateChannelResult, PushNotificationCreateChannelStatus> CreateChannelAsync(Guid remoteId);

dev/PushNotifications/externs.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@
55
#include "pch.h"
66
#include "PushNotificationReceivedEventArgs.h"
77

8-
extern wil::unique_handle g_waitHandleForArgs;
8+
extern wil::unique_event g_waitHandleForArgs;
99

10-
const winrt::hstring ACTIVATED_EVENT_ARGS_KEY = L"GlobalActivatedEventArgs";
10+
inline const winrt::hstring ACTIVATED_EVENT_ARGS_KEY = L"GlobalActivatedEventArgs";

test/TestApps/PushNotificationsDemoApp/main.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ int main()
100100
std::cout << "Project Reunion Push Notification Test App: " << buf << std::endl;
101101

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

106106
auto token = PushNotificationManager::RegisterActivator(info);
@@ -139,6 +139,8 @@ int main()
139139
std::cin.ignore();
140140
}
141141

142-
PushNotificationManager::UnregisterActivator(token, PushNotificationRegistrationOption::ComActivator); // Don't unregister PushTrigger because we still want to receive push notifications from background infrastructure.
142+
// Don't unregister PushTrigger because we still want to receive push notifications from background infrastructure.
143+
PushNotificationManager::UnregisterActivator(token, PushNotificationRegistrationOptions::ComActivator);
144+
143145
return 0;
144146
}

0 commit comments

Comments
 (0)