michael@0: // -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*- michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this file, michael@0: * You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: "use strict"; michael@0: michael@0: this.EXPORTED_SYMBOLS = ["sendOrderedBroadcast"]; michael@0: michael@0: const { classes: Cc, interfaces: Ci, utils: Cu } = Components; michael@0: michael@0: // For adding observers. michael@0: Cu.import("resource://gre/modules/Services.jsm"); michael@0: Cu.import("resource://gre/modules/Messaging.jsm"); michael@0: michael@0: let _callbackId = 1; michael@0: michael@0: /** michael@0: * Send an ordered broadcast to Java. michael@0: * michael@0: * Internally calls Context.sendOrderedBroadcast. michael@0: * michael@0: * action {String} should be a string with a qualified name (like michael@0: * org.mozilla.gecko.action) that will be broadcast. michael@0: * michael@0: * token {Object} is a piece of arbitrary data that will be given as michael@0: * a parameter to the callback (possibly null). michael@0: * michael@0: * callback {function} should accept three arguments: the data michael@0: * returned from Java as an Object; the specified token; and the michael@0: * specified action. michael@0: * michael@0: * permission {String} is an optional string with an Android permission michael@0: * that packages must have to respond to the ordered broadcast. A null michael@0: * value allows any package to respond. If the parameter is omitted (or michael@0: * {undefined}), then the intent is restricted to the current package. michael@0: */ michael@0: function sendOrderedBroadcast(action, token, callback, permission) { michael@0: let callbackId = _callbackId++; michael@0: let responseEvent = "OrderedBroadcast:Response:" + callbackId; michael@0: michael@0: let observer = { michael@0: callbackId: callbackId, michael@0: callback: callback, michael@0: michael@0: observe: function observe(subject, topic, data) { michael@0: if (topic != responseEvent) { michael@0: return; michael@0: } michael@0: michael@0: // Unregister observer as soon as possible. michael@0: Services.obs.removeObserver(observer, responseEvent); michael@0: michael@0: let msg = JSON.parse(data); michael@0: if (!msg.action || !msg.token || !msg.token.callbackId) michael@0: return; michael@0: michael@0: let theToken = msg.token.data; michael@0: let theAction = msg.action; michael@0: let theData = msg.data ? JSON.parse(msg.data) : null; michael@0: michael@0: let theCallback = this.callback; michael@0: if (!theCallback) michael@0: return; michael@0: michael@0: // This is called from within a notified observer, so we don't michael@0: // need to take special pains to catch exceptions. michael@0: theCallback(theData, theToken, theAction); michael@0: }, michael@0: }; michael@0: michael@0: Services.obs.addObserver(observer, responseEvent, false); michael@0: michael@0: sendMessageToJava({ michael@0: type: "OrderedBroadcast:Send", michael@0: action: action, michael@0: responseEvent: responseEvent, michael@0: token: { callbackId: callbackId, data: token || null }, michael@0: permission: permission, michael@0: }); michael@0: };