зеркало из https://github.com/mozilla/gecko-dev.git
Backout bug 907585, break B2G Mnw test cases
This commit is contained in:
Родитель
c293ef20cd
Коммит
a74bb49601
|
@ -79,6 +79,7 @@ const RIL_IPC_MOBILECONNECTION_MSG_NAMES = [
|
||||||
"RIL:SelectNetworkAuto",
|
"RIL:SelectNetworkAuto",
|
||||||
"RIL:SendMMI",
|
"RIL:SendMMI",
|
||||||
"RIL:CancelMMI",
|
"RIL:CancelMMI",
|
||||||
|
"RIL:RegisterMobileConnectionMsg",
|
||||||
"RIL:SetCallForwardingOption",
|
"RIL:SetCallForwardingOption",
|
||||||
"RIL:GetCallForwardingOption",
|
"RIL:GetCallForwardingOption",
|
||||||
"RIL:SetCallBarringOption",
|
"RIL:SetCallBarringOption",
|
||||||
|
@ -108,13 +109,19 @@ const RIL_IPC_ICCMANAGER_MSG_NAMES = [
|
||||||
"RIL:IccExchangeAPDU",
|
"RIL:IccExchangeAPDU",
|
||||||
"RIL:IccCloseChannel",
|
"RIL:IccCloseChannel",
|
||||||
"RIL:ReadIccContacts",
|
"RIL:ReadIccContacts",
|
||||||
"RIL:UpdateIccContact"
|
"RIL:UpdateIccContact",
|
||||||
|
"RIL:RegisterIccMsg"
|
||||||
];
|
];
|
||||||
|
|
||||||
const RIL_IPC_VOICEMAIL_MSG_NAMES = [
|
const RIL_IPC_VOICEMAIL_MSG_NAMES = [
|
||||||
|
"RIL:RegisterVoicemailMsg",
|
||||||
"RIL:GetVoicemailInfo"
|
"RIL:GetVoicemailInfo"
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const RIL_IPC_CELLBROADCAST_MSG_NAMES = [
|
||||||
|
"RIL:RegisterCellBroadcastMsg"
|
||||||
|
];
|
||||||
|
|
||||||
XPCOMUtils.defineLazyServiceGetter(this, "gPowerManagerService",
|
XPCOMUtils.defineLazyServiceGetter(this, "gPowerManagerService",
|
||||||
"@mozilla.org/power/powermanagerservice;1",
|
"@mozilla.org/power/powermanagerservice;1",
|
||||||
"nsIPowerManagerService");
|
"nsIPowerManagerService");
|
||||||
|
@ -131,6 +138,10 @@ XPCOMUtils.defineLazyServiceGetter(this, "gMobileMessageDatabaseService",
|
||||||
"@mozilla.org/mobilemessage/rilmobilemessagedatabaseservice;1",
|
"@mozilla.org/mobilemessage/rilmobilemessagedatabaseservice;1",
|
||||||
"nsIRilMobileMessageDatabaseService");
|
"nsIRilMobileMessageDatabaseService");
|
||||||
|
|
||||||
|
XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
|
||||||
|
"@mozilla.org/parentprocessmessagemanager;1",
|
||||||
|
"nsIMessageBroadcaster");
|
||||||
|
|
||||||
XPCOMUtils.defineLazyServiceGetter(this, "gSettingsService",
|
XPCOMUtils.defineLazyServiceGetter(this, "gSettingsService",
|
||||||
"@mozilla.org/settingsService;1",
|
"@mozilla.org/settingsService;1",
|
||||||
"nsISettingsService");
|
"nsISettingsService");
|
||||||
|
@ -168,22 +179,281 @@ XPCOMUtils.defineLazyGetter(this, "PhoneNumberUtils", function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
XPCOMUtils.defineLazyGetter(this, "gMessageManager", function () {
|
XPCOMUtils.defineLazyGetter(this, "gMessageManager", function () {
|
||||||
let ns = {};
|
return {
|
||||||
Cu.import("resource://gre/modules/RilMessageManager.jsm", ns);
|
QueryInterface: XPCOMUtils.generateQI([Ci.nsIMessageListener,
|
||||||
return ns.RilMessageManager;
|
Ci.nsIObserver]),
|
||||||
|
|
||||||
|
ril: null,
|
||||||
|
|
||||||
|
// Manage message targets in terms of topic. Only the authorized and
|
||||||
|
// registered contents can receive related messages.
|
||||||
|
targetsByTopic: {},
|
||||||
|
topics: [],
|
||||||
|
|
||||||
|
targetMessageQueue: [],
|
||||||
|
ready: false,
|
||||||
|
|
||||||
|
init: function init(ril) {
|
||||||
|
this.ril = ril;
|
||||||
|
|
||||||
|
Services.obs.addObserver(this, "xpcom-shutdown", false);
|
||||||
|
Services.obs.addObserver(this, kSysMsgListenerReadyObserverTopic, false);
|
||||||
|
this._registerMessageListeners();
|
||||||
|
},
|
||||||
|
|
||||||
|
_shutdown: function _shutdown() {
|
||||||
|
this.ril = null;
|
||||||
|
|
||||||
|
Services.obs.removeObserver(this, "xpcom-shutdown");
|
||||||
|
this._unregisterMessageListeners();
|
||||||
|
},
|
||||||
|
|
||||||
|
_registerMessageListeners: function _registerMessageListeners() {
|
||||||
|
ppmm.addMessageListener("child-process-shutdown", this);
|
||||||
|
for (let msgname of RIL_IPC_MOBILECONNECTION_MSG_NAMES) {
|
||||||
|
ppmm.addMessageListener(msgname, this);
|
||||||
|
}
|
||||||
|
for (let msgName of RIL_IPC_ICCMANAGER_MSG_NAMES) {
|
||||||
|
ppmm.addMessageListener(msgName, this);
|
||||||
|
}
|
||||||
|
for (let msgname of RIL_IPC_VOICEMAIL_MSG_NAMES) {
|
||||||
|
ppmm.addMessageListener(msgname, this);
|
||||||
|
}
|
||||||
|
for (let msgname of RIL_IPC_CELLBROADCAST_MSG_NAMES) {
|
||||||
|
ppmm.addMessageListener(msgname, this);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_unregisterMessageListeners: function _unregisterMessageListeners() {
|
||||||
|
ppmm.removeMessageListener("child-process-shutdown", this);
|
||||||
|
for (let msgname of RIL_IPC_MOBILECONNECTION_MSG_NAMES) {
|
||||||
|
ppmm.removeMessageListener(msgname, this);
|
||||||
|
}
|
||||||
|
for (let msgName of RIL_IPC_ICCMANAGER_MSG_NAMES) {
|
||||||
|
ppmm.removeMessageListener(msgName, this);
|
||||||
|
}
|
||||||
|
for (let msgname of RIL_IPC_VOICEMAIL_MSG_NAMES) {
|
||||||
|
ppmm.removeMessageListener(msgname, this);
|
||||||
|
}
|
||||||
|
for (let msgname of RIL_IPC_CELLBROADCAST_MSG_NAMES) {
|
||||||
|
ppmm.removeMessageListener(msgname, this);
|
||||||
|
}
|
||||||
|
ppmm = null;
|
||||||
|
},
|
||||||
|
|
||||||
|
_registerMessageTarget: function _registerMessageTarget(topic, target) {
|
||||||
|
let targets = this.targetsByTopic[topic];
|
||||||
|
if (!targets) {
|
||||||
|
targets = this.targetsByTopic[topic] = [];
|
||||||
|
let list = this.topics;
|
||||||
|
if (list.indexOf(topic) == -1) {
|
||||||
|
list.push(topic);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (targets.indexOf(target) != -1) {
|
||||||
|
if (DEBUG) debug("Already registered this target!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
targets.push(target);
|
||||||
|
if (DEBUG) debug("Registered " + topic + " target: " + target);
|
||||||
|
},
|
||||||
|
|
||||||
|
_unregisterMessageTarget: function _unregisterMessageTarget(topic, target) {
|
||||||
|
if (topic == null) {
|
||||||
|
// Unregister the target for every topic when no topic is specified.
|
||||||
|
for (let type of this.topics) {
|
||||||
|
this._unregisterMessageTarget(type, target);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unregister the target for a specified topic.
|
||||||
|
let targets = this.targetsByTopic[topic];
|
||||||
|
if (!targets) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let index = targets.indexOf(target);
|
||||||
|
if (index != -1) {
|
||||||
|
targets.splice(index, 1);
|
||||||
|
if (DEBUG) debug("Unregistered " + topic + " target: " + target);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_enqueueTargetMessage: function _enqueueTargetMessage(topic, message, options) {
|
||||||
|
let msg = { topic : topic,
|
||||||
|
message : message,
|
||||||
|
options : options };
|
||||||
|
// Remove previous queued message of same message type, only one message
|
||||||
|
// per message type is allowed in queue.
|
||||||
|
let messageQueue = this.targetMessageQueue;
|
||||||
|
for(let i = 0; i < messageQueue.length; i++) {
|
||||||
|
if (messageQueue[i].message === message) {
|
||||||
|
messageQueue.splice(i, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
messageQueue.push(msg);
|
||||||
|
},
|
||||||
|
|
||||||
|
_sendTargetMessage: function _sendTargetMessage(topic, message, options) {
|
||||||
|
if (!this.ready) {
|
||||||
|
this._enqueueTargetMessage(topic, message, options);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let targets = this.targetsByTopic[topic];
|
||||||
|
if (!targets) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let target of targets) {
|
||||||
|
target.sendAsyncMessage(message, options);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_resendQueuedTargetMessage: function _resendQueuedTargetMessage() {
|
||||||
|
this.ready = true;
|
||||||
|
|
||||||
|
// Here uses this._sendTargetMessage() to resend message, which will
|
||||||
|
// enqueue message if listener is not ready.
|
||||||
|
// So only resend after listener is ready, or it will cause infinate loop and
|
||||||
|
// hang the system.
|
||||||
|
|
||||||
|
// Dequeue and resend messages.
|
||||||
|
for each (let msg in this.targetMessageQueue) {
|
||||||
|
this._sendTargetMessage(msg.topic, msg.message, msg.options);
|
||||||
|
}
|
||||||
|
this.targetMessageQueue = null;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nsIMessageListener interface methods.
|
||||||
|
*/
|
||||||
|
|
||||||
|
receiveMessage: function receiveMessage(msg) {
|
||||||
|
if (DEBUG) debug("Received '" + msg.name + "' message from content process");
|
||||||
|
if (msg.name == "child-process-shutdown") {
|
||||||
|
// By the time we receive child-process-shutdown, the child process has
|
||||||
|
// already forgotten its permissions so we need to unregister the target
|
||||||
|
// for every permission.
|
||||||
|
this._unregisterMessageTarget(null, msg.target);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RIL_IPC_MOBILECONNECTION_MSG_NAMES.indexOf(msg.name) != -1) {
|
||||||
|
if (!msg.target.assertPermission("mobileconnection")) {
|
||||||
|
if (DEBUG) {
|
||||||
|
debug("MobileConnection message " + msg.name +
|
||||||
|
" from a content process with no 'mobileconnection' privileges.");
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} else if (RIL_IPC_ICCMANAGER_MSG_NAMES.indexOf(msg.name) != -1) {
|
||||||
|
if (!msg.target.assertPermission("mobileconnection")) {
|
||||||
|
if (DEBUG) {
|
||||||
|
debug("IccManager message " + msg.name +
|
||||||
|
" from a content process with no 'mobileconnection' privileges.");
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} else if (RIL_IPC_VOICEMAIL_MSG_NAMES.indexOf(msg.name) != -1) {
|
||||||
|
if (!msg.target.assertPermission("voicemail")) {
|
||||||
|
if (DEBUG) {
|
||||||
|
debug("Voicemail message " + msg.name +
|
||||||
|
" from a content process with no 'voicemail' privileges.");
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} else if (RIL_IPC_CELLBROADCAST_MSG_NAMES.indexOf(msg.name) != -1) {
|
||||||
|
if (!msg.target.assertPermission("cellbroadcast")) {
|
||||||
|
if (DEBUG) {
|
||||||
|
debug("Cell Broadcast message " + msg.name +
|
||||||
|
" from a content process with no 'cellbroadcast' privileges.");
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (DEBUG) debug("Ignoring unknown message type: " + msg.name);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (msg.name) {
|
||||||
|
case "RIL:RegisterMobileConnectionMsg":
|
||||||
|
this._registerMessageTarget("mobileconnection", msg.target);
|
||||||
|
return;
|
||||||
|
case "RIL:RegisterIccMsg":
|
||||||
|
this._registerMessageTarget("icc", msg.target);
|
||||||
|
return;
|
||||||
|
case "RIL:RegisterVoicemailMsg":
|
||||||
|
this._registerMessageTarget("voicemail", msg.target);
|
||||||
|
return;
|
||||||
|
case "RIL:RegisterCellBroadcastMsg":
|
||||||
|
this._registerMessageTarget("cellbroadcast", msg.target);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let clientId = msg.json.clientId || 0;
|
||||||
|
let radioInterface = this.ril.getRadioInterface(clientId);
|
||||||
|
if (!radioInterface) {
|
||||||
|
if (DEBUG) debug("No such radio interface: " + clientId);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return radioInterface.receiveMessage(msg);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nsIObserver interface methods.
|
||||||
|
*/
|
||||||
|
|
||||||
|
observe: function observe(subject, topic, data) {
|
||||||
|
switch (topic) {
|
||||||
|
case kSysMsgListenerReadyObserverTopic:
|
||||||
|
Services.obs.removeObserver(this, kSysMsgListenerReadyObserverTopic);
|
||||||
|
this._resendQueuedTargetMessage();
|
||||||
|
break;
|
||||||
|
case "xpcom-shutdown":
|
||||||
|
this._shutdown();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
sendMobileConnectionMessage: function sendMobileConnectionMessage(message, clientId, data) {
|
||||||
|
this._sendTargetMessage("mobileconnection", message, {
|
||||||
|
clientId: clientId,
|
||||||
|
data: data
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
sendVoicemailMessage: function sendVoicemailMessage(message, clientId, data) {
|
||||||
|
this._sendTargetMessage("voicemail", message, {
|
||||||
|
clientId: clientId,
|
||||||
|
data: data
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
sendCellBroadcastMessage: function sendCellBroadcastMessage(message, clientId, data) {
|
||||||
|
this._sendTargetMessage("cellbroadcast", message, {
|
||||||
|
clientId: clientId,
|
||||||
|
data: data
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
sendIccMessage: function sendIccMessage(message, clientId, data) {
|
||||||
|
this._sendTargetMessage("icc", message, {
|
||||||
|
clientId: clientId,
|
||||||
|
data: data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
function RadioInterfaceLayer() {
|
function RadioInterfaceLayer() {
|
||||||
let callback = this._receiveMessage.bind(this);
|
gMessageManager.init(this);
|
||||||
gMessageManager.registerMessageListeners("mobileconnection",
|
|
||||||
RIL_IPC_ICCMANAGER_MSG_NAMES,
|
|
||||||
callback);
|
|
||||||
gMessageManager.registerMessageListeners("mobileconnection",
|
|
||||||
RIL_IPC_MOBILECONNECTION_MSG_NAMES,
|
|
||||||
callback);
|
|
||||||
gMessageManager.registerMessageListeners("voicemail",
|
|
||||||
RIL_IPC_VOICEMAIL_MSG_NAMES,
|
|
||||||
callback);
|
|
||||||
|
|
||||||
let options = {
|
let options = {
|
||||||
debug: debugPref,
|
debug: debugPref,
|
||||||
|
@ -218,17 +488,6 @@ RadioInterfaceLayer.prototype = {
|
||||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIRadioInterfaceLayer,
|
QueryInterface: XPCOMUtils.generateQI([Ci.nsIRadioInterfaceLayer,
|
||||||
Ci.nsIObserver]),
|
Ci.nsIObserver]),
|
||||||
|
|
||||||
_receiveMessage: function _receiveMessage(topic, msg) {
|
|
||||||
let clientId = msg.json.clientId || 0;
|
|
||||||
let radioInterface = this.getRadioInterface(clientId);
|
|
||||||
if (!radioInterface) {
|
|
||||||
if (DEBUG) debug("No such radio interface: " + clientId);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return radioInterface.receiveMessage(msg);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* nsIObserver interface methods.
|
* nsIObserver interface methods.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,329 +0,0 @@
|
||||||
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
||||||
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
|
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
||||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
|
||||||
|
|
||||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
|
||||||
Cu.import("resource://gre/modules/Services.jsm");
|
|
||||||
|
|
||||||
XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
|
|
||||||
"@mozilla.org/parentprocessmessagemanager;1",
|
|
||||||
"nsIMessageBroadcaster");
|
|
||||||
|
|
||||||
// Observer topics.
|
|
||||||
const kPrefenceChangedObserverTopic = "nsPref:changed";
|
|
||||||
const kSysMsgListenerReadyObserverTopic = "system-message-listener-ready";
|
|
||||||
const kXpcomShutdownObserverTopic = "xpcom-shutdown";
|
|
||||||
|
|
||||||
// Preference keys.
|
|
||||||
const kPrefKeyRilDebuggingEnabled = "ril.debugging.enabled";
|
|
||||||
|
|
||||||
// Frame message names.
|
|
||||||
const kMsgNameChildProcessShutdown = "child-process-shutdown";
|
|
||||||
|
|
||||||
let DEBUG;
|
|
||||||
function debug(s) {
|
|
||||||
dump("RilMessageManager: " + s + "\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
this.RilMessageManager = {
|
|
||||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIMessageListener,
|
|
||||||
Ci.nsIObserver]),
|
|
||||||
|
|
||||||
topicRegistrationNames: {
|
|
||||||
cellbroadcast: ["RIL:RegisterCellBroadcastMsg"],
|
|
||||||
mobileconnection: ["RIL:RegisterMobileConnectionMsg", "RIL:RegisterIccMsg"],
|
|
||||||
voicemail: ["RIL:RegisterVoicemailMsg"],
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* this.callbacksByName[< A string message name>] = {
|
|
||||||
* topic: <A string topic>,
|
|
||||||
* callback: <A callback that accepts two parameters -- topic and msg>,
|
|
||||||
* }
|
|
||||||
*/
|
|
||||||
callbacksByName: {},
|
|
||||||
|
|
||||||
// Manage message targets in terms of topic. Only the authorized and
|
|
||||||
// registered contents can receive related messages.
|
|
||||||
targetsByTopic: {},
|
|
||||||
topics: [],
|
|
||||||
|
|
||||||
targetMessageQueue: [],
|
|
||||||
ready: false,
|
|
||||||
|
|
||||||
_init: function _init() {
|
|
||||||
this._updateDebugFlag();
|
|
||||||
|
|
||||||
Services.obs.addObserver(this, kPrefenceChangedObserverTopic, false);
|
|
||||||
Services.obs.addObserver(this, kSysMsgListenerReadyObserverTopic, false);
|
|
||||||
Services.obs.addObserver(this, kXpcomShutdownObserverTopic, false);
|
|
||||||
|
|
||||||
ppmm.addMessageListener(kMsgNameChildProcessShutdown, this);
|
|
||||||
|
|
||||||
let callback = this._registerMessageTarget.bind(this);
|
|
||||||
for (let topic in this.topicRegistrationNames) {
|
|
||||||
let names = this.topicRegistrationNames[topic];
|
|
||||||
this.registerMessageListeners(topic, names, callback);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_shutdown: function _shutdown() {
|
|
||||||
if (!this.ready) {
|
|
||||||
Services.obs.removeObserver(this, kSysMsgListenerReadyObserverTopic);
|
|
||||||
}
|
|
||||||
Services.obs.removeObserver(this, kPrefenceChangedObserverTopic);
|
|
||||||
Services.obs.removeObserver(this, kXpcomShutdownObserverTopic);
|
|
||||||
|
|
||||||
for (let name in this.callbacksByName) {
|
|
||||||
ppmm.removeMessageListener(name, this);
|
|
||||||
}
|
|
||||||
this.callbacksByName = null;
|
|
||||||
|
|
||||||
ppmm.removeMessageListener(kMsgNameChildProcessShutdown, this);
|
|
||||||
ppmm = null;
|
|
||||||
|
|
||||||
this.targetsByTopic = null;
|
|
||||||
this.targetMessageQueue = null;
|
|
||||||
},
|
|
||||||
|
|
||||||
_registerMessageTarget: function _registerMessageTarget(topic, msg) {
|
|
||||||
let targets = this.targetsByTopic[topic];
|
|
||||||
if (!targets) {
|
|
||||||
targets = this.targetsByTopic[topic] = [];
|
|
||||||
let list = this.topics;
|
|
||||||
if (list.indexOf(topic) == -1) {
|
|
||||||
list.push(topic);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let target = msg.target;
|
|
||||||
if (targets.indexOf(target) != -1) {
|
|
||||||
if (DEBUG) debug("Already registered this target!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
targets.push(target);
|
|
||||||
if (DEBUG) debug("Registered " + topic + " target: " + target);
|
|
||||||
},
|
|
||||||
|
|
||||||
_unregisterMessageTarget: function _unregisterMessageTarget(topic, target) {
|
|
||||||
if (topic == null) {
|
|
||||||
// Unregister the target for every topic when no topic is specified.
|
|
||||||
for (let type of this.topics) {
|
|
||||||
this._unregisterMessageTarget(type, target);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unregister the target for a specified topic.
|
|
||||||
let targets = this.targetsByTopic[topic];
|
|
||||||
if (!targets) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let index = targets.indexOf(target);
|
|
||||||
if (index != -1) {
|
|
||||||
targets.splice(index, 1);
|
|
||||||
if (DEBUG) debug("Unregistered " + topic + " target: " + target);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_enqueueTargetMessage: function _enqueueTargetMessage(topic, name, options) {
|
|
||||||
let msg = { topic : topic,
|
|
||||||
name : name,
|
|
||||||
options : options };
|
|
||||||
// Remove previous queued message of same message name, only one message
|
|
||||||
// per message name is allowed in queue.
|
|
||||||
let messageQueue = this.targetMessageQueue;
|
|
||||||
for (let i = 0; i < messageQueue.length; i++) {
|
|
||||||
if (messageQueue[i].name === name) {
|
|
||||||
messageQueue.splice(i, 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
messageQueue.push(msg);
|
|
||||||
},
|
|
||||||
|
|
||||||
_sendTargetMessage: function _sendTargetMessage(topic, name, options) {
|
|
||||||
if (!this.ready) {
|
|
||||||
this._enqueueTargetMessage(topic, name, options);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let targets = this.targetsByTopic[topic];
|
|
||||||
if (!targets) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let target of targets) {
|
|
||||||
target.sendAsyncMessage(name, options);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_resendQueuedTargetMessage: function _resendQueuedTargetMessage() {
|
|
||||||
// Here uses this._sendTargetMessage() to resend message, which will
|
|
||||||
// enqueue message if listener is not ready. So only resend after listener
|
|
||||||
// is ready, or it will cause infinate loop and hang the system.
|
|
||||||
|
|
||||||
// Dequeue and resend messages.
|
|
||||||
for (let msg of this.targetMessageQueue) {
|
|
||||||
this._sendTargetMessage(msg.topic, msg.name, msg.options);
|
|
||||||
}
|
|
||||||
this.targetMessageQueue = null;
|
|
||||||
},
|
|
||||||
|
|
||||||
_updateDebugFlag: function _updateDebugFlag() {
|
|
||||||
try {
|
|
||||||
DEBUG = RIL.DEBUG_RIL ||
|
|
||||||
Services.prefs.getBoolPref(kPrefKeyRilDebuggingEnabled);
|
|
||||||
} catch(e) {}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* nsIMessageListener interface methods.
|
|
||||||
*/
|
|
||||||
|
|
||||||
receiveMessage: function receiveMessage(msg) {
|
|
||||||
if (DEBUG) {
|
|
||||||
debug("Received '" + msg.name + "' message from content process");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (msg.name == kMsgNameChildProcessShutdown) {
|
|
||||||
// By the time we receive child-process-shutdown, the child process has
|
|
||||||
// already forgotten its permissions so we need to unregister the target
|
|
||||||
// for every permission.
|
|
||||||
this._unregisterMessageTarget(null, msg.target);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let entry = this.callbacksByName[msg.name];
|
|
||||||
if (!entry) {
|
|
||||||
if (DEBUG) debug("Ignoring unknown message type: " + msg.name);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entry.topic && !msg.target.assertPermission(entry.topic)) {
|
|
||||||
if (DEBUG) {
|
|
||||||
debug("Message " + msg.name + " from a content process with no '" +
|
|
||||||
entry.topic + "' privileges.");
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return entry.callback(entry.topic, msg);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* nsIObserver interface methods.
|
|
||||||
*/
|
|
||||||
|
|
||||||
observe: function observe(subject, topic, data) {
|
|
||||||
switch (topic) {
|
|
||||||
case kSysMsgListenerReadyObserverTopic:
|
|
||||||
this.ready = true;
|
|
||||||
Services.obs.removeObserver(this, kSysMsgListenerReadyObserverTopic);
|
|
||||||
|
|
||||||
this._resendQueuedTargetMessage();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kPrefenceChangedObserverTopic:
|
|
||||||
if (data === kPrefKeyRilDebuggingEnabled) {
|
|
||||||
this._updateDebugFlag();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kXpcomShutdownObserverTopic:
|
|
||||||
this._shutdown();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Public methods.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param topic
|
|
||||||
* A string for the topic of the registrating names. Also the
|
|
||||||
* permission to listen messages of these names.
|
|
||||||
* @param names
|
|
||||||
* An array of string message names to listen.
|
|
||||||
* @param callback
|
|
||||||
* A callback that accepts two parameters -- topic and msg.
|
|
||||||
*/
|
|
||||||
registerMessageListeners: function registerMessageListeners(topic, names,
|
|
||||||
callback) {
|
|
||||||
for (let name of names) {
|
|
||||||
if (this.callbacksByName[name]) {
|
|
||||||
if (DEBUG) {
|
|
||||||
debug("Message name '" + name + "' was already registered. Ignored.");
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.callbacksByName[name] = { topic: topic, callback: callback };
|
|
||||||
ppmm.addMessageListener(name, this);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove all listening names with specified callback.
|
|
||||||
*
|
|
||||||
* @param callback
|
|
||||||
* The callback previously registered for messages.
|
|
||||||
*/
|
|
||||||
unregisterMessageListeners: function unregisterMessageListeners(callback) {
|
|
||||||
let remains = {};
|
|
||||||
for (let name in this.callbacksByName) {
|
|
||||||
let entry = this.callbacksByName[name];
|
|
||||||
if (entry.callback != callback) {
|
|
||||||
remains[name] = entry;
|
|
||||||
} else {
|
|
||||||
ppmm.removeMessageListener(name, this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.callbacksByName = remains;
|
|
||||||
},
|
|
||||||
|
|
||||||
sendMobileConnectionMessage: function sendMobileConnectionMessage(name,
|
|
||||||
clientId,
|
|
||||||
data) {
|
|
||||||
this._sendTargetMessage("mobileconnection", name, {
|
|
||||||
clientId: clientId,
|
|
||||||
data: data
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
sendVoicemailMessage: function sendVoicemailMessage(name, clientId, data) {
|
|
||||||
this._sendTargetMessage("voicemail", name, {
|
|
||||||
clientId: clientId,
|
|
||||||
data: data
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
sendCellBroadcastMessage: function sendCellBroadcastMessage(name, clientId,
|
|
||||||
data) {
|
|
||||||
this._sendTargetMessage("cellbroadcast", name, {
|
|
||||||
clientId: clientId,
|
|
||||||
data: data
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
sendIccMessage: function sendIccMessage(name, clientId, data) {
|
|
||||||
this._sendTargetMessage("icc", name, {
|
|
||||||
clientId: clientId,
|
|
||||||
data: data
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
RilMessageManager._init();
|
|
||||||
|
|
||||||
this.EXPORTED_SYMBOLS = ["RilMessageManager"];
|
|
|
@ -74,7 +74,6 @@ EXTRA_COMPONENTS += [
|
||||||
]
|
]
|
||||||
|
|
||||||
EXTRA_JS_MODULES += [
|
EXTRA_JS_MODULES += [
|
||||||
'RilMessageManager.jsm',
|
|
||||||
'net_worker.js',
|
'net_worker.js',
|
||||||
'ril_consts.js',
|
'ril_consts.js',
|
||||||
'ril_worker.js',
|
'ril_worker.js',
|
||||||
|
|
Загрузка…
Ссылка в новой задаче