Bug 1253438 - Expose Push observer notification topics. r=markh

MozReview-Commit-ID: HublNSAD3NY
This commit is contained in:
Kit Cambridge 2016-03-03 14:37:10 -08:00
parent 46820b1583
commit 6d0366cb92
21 changed files with 64 additions and 41 deletions

View File

@ -73,6 +73,10 @@ interface nsIPushClearResultCallback : nsISupports
[scriptable, uuid(678ef584-bf25-47aa-ac84-03efc0865b68)]
interface nsIPushService : nsISupports
{
/** Observer topic names, exported for convenience. */
readonly attribute DOMString pushTopic;
readonly attribute DOMString subscriptionChangeTopic;
/**
* Creates a push subscription for the given |scope| URL and |principal|.
* If a subscription already exists for this |(scope, principal)| pair,

View File

@ -16,6 +16,12 @@ Cu.import("resource://gre/modules/Services.jsm");
var isParent = Services.appinfo.processType === Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
// Observer notification topics for system subscriptions. These are duplicated
// and used in `PushNotifier.cpp`. They're exposed on `nsIPushService` instead
// of `nsIPushNotifier` so that JS callers only need to import this service.
const OBSERVER_TOPIC_PUSH = "push-message";
const OBSERVER_TOPIC_SUBSCRIPTION_CHANGE = "push-subscription-change";
/**
* `PushServiceBase`, `PushServiceParent`, and `PushServiceContent` collectively
* implement the `nsIPushService` interface. This interface provides calls
@ -43,6 +49,9 @@ PushServiceBase.prototype = {
Ci.nsIPushQuotaManager,
]),
pushTopic: OBSERVER_TOPIC_PUSH,
subscriptionChangeTopic: OBSERVER_TOPIC_SUBSCRIPTION_CHANGE,
_handleReady() {},
_addListeners() {

View File

@ -192,7 +192,7 @@ PushNotifier::NotifyPushObservers(const nsACString& aScope,
if (aData) {
message = new PushMessage(aData.ref());
}
return obsService->NotifyObservers(message, "push-message",
return obsService->NotifyObservers(message, OBSERVER_TOPIC_PUSH,
NS_ConvertUTF8toUTF16(aScope).get());
}
@ -204,7 +204,8 @@ PushNotifier::NotifySubscriptionChangeObservers(const nsACString& aScope)
if (!obsService) {
return NS_ERROR_FAILURE;
}
return obsService->NotifyObservers(nullptr, "push-subscription-change",
return obsService->NotifyObservers(nullptr,
OBSERVER_TOPIC_SUBSCRIPTION_CHANGE,
NS_ConvertUTF8toUTF16(aScope).get());
}

View File

@ -17,6 +17,10 @@
#define PUSHNOTIFIER_CONTRACTID \
"@mozilla.org/push/Notifier;1"
// These constants are duplicated in `PushComponents.js`.
#define OBSERVER_TOPIC_PUSH "push-message"
#define OBSERVER_TOPIC_SUBSCRIPTION_CHANGE "push-subscription-change"
namespace mozilla {
namespace dom {

View File

@ -13,8 +13,11 @@ Cu.import('resource://gre/modules/Promise.jsm');
Cu.import('resource://gre/modules/Preferences.jsm');
Cu.import('resource://gre/modules/PlacesUtils.jsm');
Cu.import('resource://gre/modules/ObjectUtils.jsm');
XPCOMUtils.defineLazyModuleGetter(this, "PlacesTestUtils",
"resource://testing-common/PlacesTestUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, 'PlacesTestUtils',
'resource://testing-common/PlacesTestUtils.jsm');
XPCOMUtils.defineLazyServiceGetter(this, 'PushServiceComponent',
'@mozilla.org/push/Service;1', 'nsIPushService');
const serviceExports = Cu.import('resource://gre/modules/PushService.jsm', {});
const servicePrefs = new Preferences('dom.push.');

View File

@ -99,7 +99,7 @@ add_task(function* setUp() {
});
let subChangePromise = promiseObserverNotification(
'push-subscription-change',
PushServiceComponent.subscriptionChangeTopic,
(subject, data) => data == 'https://example.com/expired-quota-restored'
);
@ -126,7 +126,7 @@ add_task(function* setUp() {
add_task(function* test_site_visited() {
let subChangePromise = promiseObserverNotification(
'push-subscription-change',
PushServiceComponent.subscriptionChangeTopic,
(subject, data) => data == 'https://example.xyz/expired-quota-exceeded'
);
@ -139,7 +139,7 @@ add_task(function* test_site_visited() {
add_task(function* test_perm_restored() {
let subChangePromise = promiseObserverNotification(
'push-subscription-change',
PushServiceComponent.subscriptionChangeTopic,
(subject, data) => data == 'https://example.info/expired-perm-revoked'
);

View File

@ -46,7 +46,7 @@ add_task(function* test_notification_ack() {
}
let notifyCount = 0;
let notifyPromise = promiseObserverNotification('push-message', () =>
let notifyPromise = promiseObserverNotification(PushServiceComponent.pushTopic, () =>
++notifyCount == 3);
let acks = 0;

View File

@ -218,7 +218,7 @@ add_task(function* test_notification_ack_data() {
];
let sendAndReceive = testData => {
let messageReceived = promiseObserverNotification('push-message', (subject, data) => {
let messageReceived = promiseObserverNotification(PushServiceComponent.pushTopic, (subject, data) => {
let notification = subject.QueryInterface(Ci.nsIPushMessage);
equal(notification.text(), testData.receive.data,
'Check data for notification ' + testData.version);

View File

@ -40,7 +40,7 @@ add_task(function* test_notification_duplicate() {
yield db.put(record);
}
let notifyPromise = promiseObserverNotification('push-message');
let notifyPromise = promiseObserverNotification(PushServiceComponent.pushTopic);
let acks = 0;
let ackDone;

View File

@ -50,7 +50,7 @@ add_task(function* test_notification_error() {
}
let scopes = [];
let notifyPromise = promiseObserverNotification('push-message', (subject, data) =>
let notifyPromise = promiseObserverNotification(PushServiceComponent.pushTopic, (subject, data) =>
scopes.push(data) == 2);
let ackDone;

View File

@ -128,21 +128,21 @@ add_task(function* test_pushNotifications() {
}
let notifyPromise = Promise.all([
promiseObserverNotification('push-message', function(subject, data) {
promiseObserverNotification(PushServiceComponent.pushTopic, function(subject, data) {
var message = subject.QueryInterface(Ci.nsIPushMessage);
if (message && (data == "https://example.com/page/1")){
equal(message.text(), "Some message", "decoded message is incorrect");
return true;
}
}),
promiseObserverNotification('push-message', function(subject, data) {
promiseObserverNotification(PushServiceComponent.pushTopic, function(subject, data) {
var message = subject.QueryInterface(Ci.nsIPushMessage);
if (message && (data == "https://example.com/page/2")){
equal(message.text(), "Some message", "decoded message is incorrect");
return true;
}
}),
promiseObserverNotification('push-message', function(subject, data) {
promiseObserverNotification(PushServiceComponent.pushTopic, function(subject, data) {
var message = subject.QueryInterface(Ci.nsIPushMessage);
if (message && (data == "https://example.com/page/3")){
equal(message.text(), "Some message", "decoded message is incorrect");

View File

@ -55,8 +55,8 @@ add_task(function* test_notification_incomplete() {
ok(false, 'Should not deliver malformed updates');
}
do_register_cleanup(() =>
Services.obs.removeObserver(observeMessage, 'push-message'));
Services.obs.addObserver(observeMessage, 'push-message', false);
Services.obs.removeObserver(observeMessage, PushServiceComponent.pushTopic));
Services.obs.addObserver(observeMessage, PushServiceComponent.pushTopic, false);
let notificationDone;
let notificationPromise = new Promise(resolve => notificationDone = after(2, resolve));

View File

@ -28,7 +28,7 @@ add_task(function* test_notification_version_string() {
systemRecord: true,
});
let notifyPromise = promiseObserverNotification('push-message');
let notifyPromise = promiseObserverNotification(PushServiceComponent.pushTopic);
let ackDone;
let ackPromise = new Promise(resolve => ackDone = resolve);

View File

@ -52,7 +52,7 @@ function makePushPermission(url, capability) {
function promiseSubscriptionChanges(count) {
let notifiedScopes = [];
let subChangePromise = promiseObserverNotification('push-subscription-change', (subject, data) => {
let subChangePromise = promiseObserverNotification(PushServiceComponent.subscriptionChangeTopic, (subject, data) => {
notifiedScopes.push(data);
return notifiedScopes.length == count;
});

View File

@ -79,7 +79,7 @@ add_task(function* test_expiration_origin_threshold() {
// different scopes, so each can send 5 notifications before we remove
// their subscription.
let updates = 0;
let notifyPromise = promiseObserverNotification('push-message', (subject, data) => {
let notifyPromise = promiseObserverNotification(PushServiceComponent.pushTopic, (subject, data) => {
updates++;
return updates == 6;
});

View File

@ -66,7 +66,7 @@ add_task(function* test_expiration_history_observer() {
let unregisterDone;
let unregisterPromise = new Promise(resolve => unregisterDone = resolve);
let subChangePromise = promiseObserverNotification('push-subscription-change', (subject, data) =>
let subChangePromise = promiseObserverNotification(PushServiceComponent.subscriptionChangeTopic, (subject, data) =>
data == 'https://example.com/stuff');
PushService.init({
@ -107,7 +107,7 @@ add_task(function* test_expiration_history_observer() {
strictEqual(expiredRecord.quota, 0, 'Expired record not updated');
let notifiedScopes = [];
subChangePromise = promiseObserverNotification('push-subscription-change', (subject, data) => {
subChangePromise = promiseObserverNotification(PushServiceComponent.subscriptionChangeTopic, (subject, data) => {
notifiedScopes.push(data);
return notifiedScopes.length == 2;
});

View File

@ -53,7 +53,7 @@ add_task(function* test_expiration_origin_threshold() {
let numMessages = 10;
let updates = 0;
let notifyPromise = promiseObserverNotification('push-message', (subject, data) => {
let notifyPromise = promiseObserverNotification(PushServiceComponent.pushTopic, (subject, data) => {
updates++;
return updates == numMessages;
});

View File

@ -32,7 +32,7 @@ add_task(function* test_register_flush() {
};
yield db.put(record);
let notifyPromise = promiseObserverNotification('push-message');
let notifyPromise = promiseObserverNotification(PushServiceComponent.pushTopic);
let ackDone;
let ackPromise = new Promise(resolve => ackDone = after(2, resolve));

View File

@ -5,11 +5,9 @@
const {PushDB, PushService, PushServiceWebSocket} = serviceExports;
var db, service;
var db;
function run_test() {
service = Cc['@mozilla.org/push/Service;1']
.getService(Ci.nsIPushService);
if (isParent) {
do_get_profile();
}
@ -26,7 +24,7 @@ if (isParent) {
add_test(function test_subscribe_success() {
do_test_pending();
service.subscribe(
PushServiceComponent.subscribe(
'https://example.com/sub/ok',
Services.scriptSecurityManager.getSystemPrincipal(),
(result, subscription) => {
@ -44,7 +42,7 @@ add_test(function test_subscribe_success() {
add_test(function test_subscribe_error() {
do_test_pending();
service.subscribe(
PushServiceComponent.subscribe(
'https://example.com/sub/fail',
Services.scriptSecurityManager.getSystemPrincipal(),
(result, subscription) => {
@ -59,7 +57,7 @@ add_test(function test_subscribe_error() {
add_test(function test_getSubscription_exists() {
do_test_pending();
service.getSubscription(
PushServiceComponent.getSubscription(
'https://example.com/get/ok',
Services.scriptSecurityManager.getSystemPrincipal(),
(result, subscription) => {
@ -78,7 +76,7 @@ add_test(function test_getSubscription_exists() {
add_test(function test_getSubscription_missing() {
do_test_pending();
service.getSubscription(
PushServiceComponent.getSubscription(
'https://example.com/get/missing',
Services.scriptSecurityManager.getSystemPrincipal(),
(result, subscription) => {
@ -93,7 +91,7 @@ add_test(function test_getSubscription_missing() {
add_test(function test_getSubscription_error() {
do_test_pending();
service.getSubscription(
PushServiceComponent.getSubscription(
'https://example.com/get/fail',
Services.scriptSecurityManager.getSystemPrincipal(),
(result, subscription) => {
@ -108,7 +106,7 @@ add_test(function test_getSubscription_error() {
add_test(function test_unsubscribe_success() {
do_test_pending();
service.unsubscribe(
PushServiceComponent.unsubscribe(
'https://example.com/unsub/ok',
Services.scriptSecurityManager.getSystemPrincipal(),
(result, success) => {
@ -123,7 +121,7 @@ add_test(function test_unsubscribe_success() {
add_test(function test_unsubscribe_nonexistent() {
do_test_pending();
service.unsubscribe(
PushServiceComponent.unsubscribe(
'https://example.com/unsub/ok',
Services.scriptSecurityManager.getSystemPrincipal(),
(result, success) => {
@ -138,7 +136,7 @@ add_test(function test_unsubscribe_nonexistent() {
add_test(function test_unsubscribe_error() {
do_test_pending();
service.unsubscribe(
PushServiceComponent.unsubscribe(
'https://example.com/unsub/fail',
Services.scriptSecurityManager.getSystemPrincipal(),
(result, success) => {
@ -159,7 +157,7 @@ add_test(function test_subscribe_app_principal() {
);
do_test_pending();
service.subscribe('https://example.net/scope/1', principal, (result, subscription) => {
PushServiceComponent.subscribe('https://example.net/scope/1', principal, (result, subscription) => {
ok(Components.isSuccessCode(result), 'Error creating subscription');
ok(subscription.endpoint.startsWith('https://example.org/push'),
'Wrong push endpoint in app subscription');
@ -176,7 +174,7 @@ add_test(function test_subscribe_origin_principal() {
Services.scriptSecurityManager.createCodebasePrincipalFromOrigin(scope);
do_test_pending();
service.subscribe(scope, principal, (result, subscription) => {
PushServiceComponent.subscribe(scope, principal, (result, subscription) => {
ok(Components.isSuccessCode(result),
'Expected error creating subscription with origin principal');
equal(subscription.quota, 16, 'Wrong quota for origin subscription');
@ -188,7 +186,7 @@ add_test(function test_subscribe_origin_principal() {
add_test(function test_subscribe_null_principal() {
do_test_pending();
service.subscribe(
PushServiceComponent.subscribe(
'chrome://push/null-principal',
Services.scriptSecurityManager.createNullPrincipal({}),
(result, subscription) => {
@ -205,7 +203,7 @@ add_test(function test_subscribe_null_principal() {
add_test(function test_subscribe_missing_principal() {
do_test_pending();
service.subscribe('chrome://push/missing-principal', null,
PushServiceComponent.subscribe('chrome://push/missing-principal', null,
(result, subscription) => {
ok(!Components.isSuccessCode(result),
'Expected error creating subscription without principal');

View File

@ -15,8 +15,12 @@ add_task(function* test_service_parent() {
do_register_cleanup(() => {return db.drop().then(_ => db.close());});
yield setUpServiceInParent(PushService, db);
// Start the service in the main process.
Cc['@mozilla.org/push/Service;1'].getService(Ci.nsIPushService);
// Accessing the lazy service getter will start the service in the main
// process.
equal(PushServiceComponent.pushTopic, "push-message",
"Wrong push message observer topic");
equal(PushServiceComponent.subscriptionChangeTopic,
"push-subscription-change", "Wrong subscription change observer topic");
yield run_test_in_child('./test_service_child.js');

View File

@ -59,7 +59,7 @@ add_task(function* test1() {
yield db.put(record);
let notifyPromise = promiseObserverNotification('push-subscription-change',
let notifyPromise = promiseObserverNotification(PushServiceComponent.subscriptionChangeTopic,
_ => true);
PushService.init({