2012-07-20 02:10:44 -07:00
|
|
|
/* Copyright 2012 Mozilla Foundation and Mozilla contributors
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
2011-12-04 23:58:27 -08:00
|
|
|
|
2012-01-09 14:28:47 -08:00
|
|
|
"use strict";
|
|
|
|
|
2011-12-04 23:58:27 -08:00
|
|
|
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
|
|
|
|
|
|
|
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
2011-12-23 21:02:52 -08:00
|
|
|
Cu.import("resource://gre/modules/Services.jsm");
|
2011-12-04 23:58:27 -08:00
|
|
|
|
2012-01-09 14:28:47 -08:00
|
|
|
var RIL = {};
|
|
|
|
Cu.import("resource://gre/modules/ril_consts.js", RIL);
|
|
|
|
|
2012-06-19 15:52:06 -07:00
|
|
|
// set to true in ril_consts.js to see debug messages
|
2012-11-14 02:25:35 -08:00
|
|
|
var DEBUG = RIL.DEBUG_RIL;
|
|
|
|
|
|
|
|
// Read debug setting from pref
|
|
|
|
let debugPref = false;
|
|
|
|
try {
|
|
|
|
debugPref = Services.prefs.getBoolPref("ril.debugging.enabled");
|
|
|
|
} catch(e) {
|
|
|
|
debugPref = false;
|
|
|
|
}
|
|
|
|
DEBUG = RIL.DEBUG_RIL || debugPref;
|
2011-12-04 23:58:27 -08:00
|
|
|
|
2013-07-02 02:36:58 -07:00
|
|
|
function debug(s) {
|
|
|
|
dump("-*- RadioInterfaceLayer: " + s + "\n");
|
2013-07-30 05:52:19 -07:00
|
|
|
};
|
2013-06-09 19:41:14 -07:00
|
|
|
|
2012-01-19 12:53:32 -08:00
|
|
|
const RADIOINTERFACELAYER_CID =
|
2012-01-09 15:18:23 -08:00
|
|
|
Components.ID("{2d831c8d-6017-435b-a80c-e5d422810cea}");
|
2013-07-02 02:36:37 -07:00
|
|
|
const RADIOINTERFACE_CID =
|
|
|
|
Components.ID("{6a7c91f0-a2b3-4193-8562-8969296c0b54}");
|
2012-09-26 05:52:21 -07:00
|
|
|
const RILNETWORKINTERFACE_CID =
|
|
|
|
Components.ID("{3bdd52a9-3965-4130-b569-0ac5afed045e}");
|
2011-12-04 23:58:27 -08:00
|
|
|
|
2012-01-09 14:28:47 -08:00
|
|
|
const nsIAudioManager = Ci.nsIAudioManager;
|
2013-03-06 01:53:23 -08:00
|
|
|
const nsITelephonyProvider = Ci.nsITelephonyProvider;
|
2011-12-12 10:22:26 -08:00
|
|
|
|
2012-04-19 14:33:25 -07:00
|
|
|
const kNetworkInterfaceStateChangedTopic = "network-interface-state-changed";
|
2011-12-23 21:02:52 -08:00
|
|
|
const kSmsReceivedObserverTopic = "sms-received";
|
2013-07-29 15:50:22 -07:00
|
|
|
const kSilentSmsReceivedObserverTopic = "silent-sms-received";
|
2012-12-11 01:09:46 -08:00
|
|
|
const kSmsSendingObserverTopic = "sms-sending";
|
2012-09-09 22:55:59 -07:00
|
|
|
const kSmsSentObserverTopic = "sms-sent";
|
2012-12-11 01:09:46 -08:00
|
|
|
const kSmsFailedObserverTopic = "sms-failed";
|
2012-10-30 03:53:27 -07:00
|
|
|
const kSmsDeliverySuccessObserverTopic = "sms-delivery-success";
|
|
|
|
const kSmsDeliveryErrorObserverTopic = "sms-delivery-error";
|
2012-04-24 13:46:42 -07:00
|
|
|
const kMozSettingsChangedObserverTopic = "mozsettings-changed";
|
2012-09-05 13:00:06 -07:00
|
|
|
const kSysMsgListenerReadyObserverTopic = "system-message-listener-ready";
|
2012-10-23 00:15:53 -07:00
|
|
|
const kSysClockChangeObserverTopic = "system-clock-change";
|
2013-06-06 00:28:59 -07:00
|
|
|
const kScreenStateChangedTopic = "screen-state-changed";
|
2012-09-27 23:02:57 -07:00
|
|
|
const kTimeNitzAutomaticUpdateEnabled = "time.nitz.automatic-update.enabled";
|
2013-01-25 02:06:24 -08:00
|
|
|
const kTimeNitzAvailable = "time.nitz.available";
|
2012-12-03 18:41:39 -08:00
|
|
|
const kCellBroadcastSearchList = "ril.cellbroadcast.searchlist";
|
2013-06-07 00:32:24 -07:00
|
|
|
const kCellBroadcastDisabled = "ril.cellbroadcast.disabled";
|
|
|
|
const kPrefenceChangedObserverTopic = "nsPref:changed";
|
2013-07-31 00:56:43 -07:00
|
|
|
const kClirModePreference = "ril.clirMode";
|
2012-10-30 03:53:27 -07:00
|
|
|
|
2013-03-01 00:38:47 -08:00
|
|
|
const DOM_MOBILE_MESSAGE_DELIVERY_RECEIVED = "received";
|
|
|
|
const DOM_MOBILE_MESSAGE_DELIVERY_SENDING = "sending";
|
|
|
|
const DOM_MOBILE_MESSAGE_DELIVERY_SENT = "sent";
|
|
|
|
const DOM_MOBILE_MESSAGE_DELIVERY_ERROR = "error";
|
2011-12-23 21:02:52 -08:00
|
|
|
|
2013-01-24 00:35:50 -08:00
|
|
|
const CALL_WAKELOCK_TIMEOUT = 5000;
|
|
|
|
|
2012-09-27 22:43:35 -07:00
|
|
|
const RIL_IPC_TELEPHONY_MSG_NAMES = [
|
2012-04-24 08:44:42 -07:00
|
|
|
"RIL:EnumerateCalls",
|
|
|
|
"RIL:GetMicrophoneMuted",
|
|
|
|
"RIL:SetMicrophoneMuted",
|
|
|
|
"RIL:GetSpeakerEnabled",
|
|
|
|
"RIL:SetSpeakerEnabled",
|
|
|
|
"RIL:StartTone",
|
|
|
|
"RIL:StopTone",
|
|
|
|
"RIL:Dial",
|
2012-07-20 05:08:24 -07:00
|
|
|
"RIL:DialEmergency",
|
2012-04-24 08:44:42 -07:00
|
|
|
"RIL:HangUp",
|
|
|
|
"RIL:AnswerCall",
|
|
|
|
"RIL:RejectCall",
|
|
|
|
"RIL:HoldCall",
|
|
|
|
"RIL:ResumeCall",
|
2012-10-09 03:07:11 -07:00
|
|
|
"RIL:RegisterTelephonyMsg"
|
2012-09-27 22:43:35 -07:00
|
|
|
];
|
|
|
|
|
|
|
|
const RIL_IPC_MOBILECONNECTION_MSG_NAMES = [
|
|
|
|
"RIL:GetRilContext",
|
2012-06-01 14:10:39 -07:00
|
|
|
"RIL:GetAvailableNetworks",
|
2012-06-19 15:52:06 -07:00
|
|
|
"RIL:SelectNetwork",
|
|
|
|
"RIL:SelectNetworkAuto",
|
2012-10-05 07:08:55 -07:00
|
|
|
"RIL:SendMMI",
|
|
|
|
"RIL:CancelMMI",
|
2013-04-08 23:18:43 -07:00
|
|
|
"RIL:RegisterMobileConnectionMsg",
|
|
|
|
"RIL:SetCallForwardingOption",
|
|
|
|
"RIL:GetCallForwardingOption",
|
2013-05-20 22:13:37 -07:00
|
|
|
"RIL:SetCallBarringOption",
|
|
|
|
"RIL:GetCallBarringOption",
|
2013-04-08 23:18:43 -07:00
|
|
|
"RIL:SetCallWaitingOption",
|
2013-07-17 14:18:29 -07:00
|
|
|
"RIL:GetCallWaitingOption",
|
|
|
|
"RIL:SetCallingLineIdRestriction",
|
2013-06-10 00:47:03 -07:00
|
|
|
"RIL:GetCallingLineIdRestriction",
|
|
|
|
"RIL:SetRoamingPreference",
|
|
|
|
"RIL:GetRoamingPreference"
|
2013-04-08 23:18:43 -07:00
|
|
|
];
|
|
|
|
|
|
|
|
const RIL_IPC_ICCMANAGER_MSG_NAMES = [
|
2012-04-10 05:04:27 -07:00
|
|
|
"RIL:SendStkResponse",
|
2012-09-27 22:43:35 -07:00
|
|
|
"RIL:SendStkMenuSelection",
|
2012-11-28 00:16:20 -08:00
|
|
|
"RIL:SendStkTimerExpiration",
|
2012-09-10 19:34:36 -07:00
|
|
|
"RIL:SendStkEventDownload",
|
2013-04-11 00:12:09 -07:00
|
|
|
"RIL:GetCardLockState",
|
|
|
|
"RIL:UnlockCardLock",
|
|
|
|
"RIL:SetCardLock",
|
Bug 875710: Added getCardLockRetryCount to nsIIccProvider, r=vyang, sr=mounir
This patch adds getCardLockRetryCount to nsIIccProvider and its
implementations. This method allows callers to query the number
of remaining tries for unlocking a SIM-card lock. Supported locks
are 'pin', 'puk', 'pin2', 'puk2', 'nck', 'cck', and 'spck'. The
call returns a DOM request that returns the retry count in its
success handler, or signals an appropriate error.
Reading the retry count is an optional feature and may not be
supported for all lock types. In this case the DOM request receives
and error with the name GECKO_ERROR_NOT_SUPPORTED. For an invalid
lock type, the error name is GECKO_ERROR_GENERIC_FAILURE.
getCardLockRetryCount replaces retryCount in nsIDOMMobileConnection,
which is now deprecated.
--HG--
extra : rebase_source : d1d11612f836652dca85f7c701f09e7af962e3b7
2013-07-09 07:06:05 -07:00
|
|
|
"RIL:GetCardLockRetryCount",
|
2013-02-25 01:27:26 -08:00
|
|
|
"RIL:IccOpenChannel",
|
|
|
|
"RIL:IccExchangeAPDU",
|
|
|
|
"RIL:IccCloseChannel",
|
2013-03-05 18:51:40 -08:00
|
|
|
"RIL:ReadIccContacts",
|
2013-03-24 20:09:01 -07:00
|
|
|
"RIL:UpdateIccContact",
|
2013-04-08 23:18:43 -07:00
|
|
|
"RIL:RegisterIccMsg"
|
2012-10-09 03:07:11 -07:00
|
|
|
];
|
|
|
|
|
|
|
|
const RIL_IPC_VOICEMAIL_MSG_NAMES = [
|
2012-12-26 02:49:08 -08:00
|
|
|
"RIL:RegisterVoicemailMsg",
|
|
|
|
"RIL:GetVoicemailInfo"
|
2012-04-24 08:44:42 -07:00
|
|
|
];
|
|
|
|
|
2012-12-03 18:40:47 -08:00
|
|
|
const RIL_IPC_CELLBROADCAST_MSG_NAMES = [
|
|
|
|
"RIL:RegisterCellBroadcastMsg"
|
|
|
|
];
|
|
|
|
|
2013-01-24 00:35:50 -08:00
|
|
|
XPCOMUtils.defineLazyServiceGetter(this, "gPowerManagerService",
|
|
|
|
"@mozilla.org/power/powermanagerservice;1",
|
|
|
|
"nsIPowerManagerService");
|
|
|
|
|
2013-03-08 23:22:25 -08:00
|
|
|
XPCOMUtils.defineLazyServiceGetter(this, "gMobileMessageService",
|
|
|
|
"@mozilla.org/mobilemessage/mobilemessageservice;1",
|
|
|
|
"nsIMobileMessageService");
|
2011-12-12 10:22:26 -08:00
|
|
|
|
2013-07-29 15:50:22 -07:00
|
|
|
XPCOMUtils.defineLazyServiceGetter(this, "gSmsService",
|
|
|
|
"@mozilla.org/sms/smsservice;1",
|
|
|
|
"nsISmsService");
|
|
|
|
|
2013-02-05 03:10:39 -08:00
|
|
|
XPCOMUtils.defineLazyServiceGetter(this, "gMobileMessageDatabaseService",
|
|
|
|
"@mozilla.org/mobilemessage/rilmobilemessagedatabaseservice;1",
|
|
|
|
"nsIRilMobileMessageDatabaseService");
|
2012-02-20 09:12:37 -08:00
|
|
|
|
2012-04-19 14:33:25 -07:00
|
|
|
XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
|
|
|
|
"@mozilla.org/parentprocessmessagemanager;1",
|
2012-08-27 07:13:02 -07:00
|
|
|
"nsIMessageBroadcaster");
|
2012-04-19 14:33:25 -07:00
|
|
|
|
2012-05-23 22:12:07 -07:00
|
|
|
XPCOMUtils.defineLazyServiceGetter(this, "gSettingsService",
|
|
|
|
"@mozilla.org/settingsService;1",
|
|
|
|
"nsISettingsService");
|
|
|
|
|
2012-08-31 07:45:32 -07:00
|
|
|
XPCOMUtils.defineLazyServiceGetter(this, "gSystemMessenger",
|
|
|
|
"@mozilla.org/system-message-internal;1",
|
|
|
|
"nsISystemMessagesInternal");
|
|
|
|
|
2012-09-26 05:52:21 -07:00
|
|
|
XPCOMUtils.defineLazyServiceGetter(this, "gNetworkManager",
|
|
|
|
"@mozilla.org/network/manager;1",
|
|
|
|
"nsINetworkManager");
|
|
|
|
|
2012-09-27 23:02:57 -07:00
|
|
|
XPCOMUtils.defineLazyServiceGetter(this, "gTimeService",
|
|
|
|
"@mozilla.org/time/timeservice;1",
|
|
|
|
"nsITimeService");
|
|
|
|
|
2013-01-23 22:42:07 -08:00
|
|
|
XPCOMUtils.defineLazyServiceGetter(this, "gSystemWorkerManager",
|
|
|
|
"@mozilla.org/telephony/system-worker-manager;1",
|
|
|
|
"nsISystemWorkerManager");
|
|
|
|
|
2012-06-03 22:04:28 -07:00
|
|
|
XPCOMUtils.defineLazyGetter(this, "WAP", function () {
|
2013-06-09 19:41:14 -07:00
|
|
|
let wap = {};
|
|
|
|
Cu.import("resource://gre/modules/WapPushManager.js", wap);
|
|
|
|
return wap;
|
2012-06-03 22:04:28 -07:00
|
|
|
});
|
|
|
|
|
2013-02-20 01:02:50 -08:00
|
|
|
XPCOMUtils.defineLazyGetter(this, "PhoneNumberUtils", function () {
|
|
|
|
let ns = {};
|
|
|
|
Cu.import("resource://gre/modules/PhoneNumberUtils.jsm", ns);
|
|
|
|
return ns.PhoneNumberUtils;
|
|
|
|
});
|
|
|
|
|
2012-01-09 14:28:47 -08:00
|
|
|
function convertRILCallState(state) {
|
|
|
|
switch (state) {
|
|
|
|
case RIL.CALL_STATE_ACTIVE:
|
2013-03-06 01:53:23 -08:00
|
|
|
return nsITelephonyProvider.CALL_STATE_CONNECTED;
|
2012-01-09 14:28:47 -08:00
|
|
|
case RIL.CALL_STATE_HOLDING:
|
2013-03-06 01:53:23 -08:00
|
|
|
return nsITelephonyProvider.CALL_STATE_HELD;
|
2012-01-09 14:28:47 -08:00
|
|
|
case RIL.CALL_STATE_DIALING:
|
2013-03-06 01:53:23 -08:00
|
|
|
return nsITelephonyProvider.CALL_STATE_DIALING;
|
2012-01-09 14:28:47 -08:00
|
|
|
case RIL.CALL_STATE_ALERTING:
|
2013-03-06 01:53:23 -08:00
|
|
|
return nsITelephonyProvider.CALL_STATE_ALERTING;
|
2012-01-09 14:28:47 -08:00
|
|
|
case RIL.CALL_STATE_INCOMING:
|
|
|
|
case RIL.CALL_STATE_WAITING:
|
2013-03-06 01:53:23 -08:00
|
|
|
return nsITelephonyProvider.CALL_STATE_INCOMING;
|
2012-01-09 14:28:47 -08:00
|
|
|
default:
|
|
|
|
throw new Error("Unknown rilCallState: " + state);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-12-12 10:22:26 -08:00
|
|
|
/**
|
|
|
|
* Fake nsIAudioManager implementation so that we can run the telephony
|
|
|
|
* code in a non-Gonk build.
|
|
|
|
*/
|
|
|
|
let FakeAudioManager = {
|
|
|
|
microphoneMuted: false,
|
|
|
|
masterVolume: 1.0,
|
|
|
|
masterMuted: false,
|
2012-01-09 14:28:47 -08:00
|
|
|
phoneState: nsIAudioManager.PHONE_STATE_CURRENT,
|
2011-12-12 10:22:26 -08:00
|
|
|
_forceForUse: {},
|
|
|
|
setForceForUse: function setForceForUse(usage, force) {
|
|
|
|
this._forceForUse[usage] = force;
|
|
|
|
},
|
|
|
|
getForceForUse: function setForceForUse(usage) {
|
2012-01-09 14:28:47 -08:00
|
|
|
return this._forceForUse[usage] || nsIAudioManager.FORCE_NONE;
|
2011-12-12 10:22:26 -08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
XPCOMUtils.defineLazyGetter(this, "gAudioManager", function getAudioManager() {
|
|
|
|
try {
|
|
|
|
return Cc["@mozilla.org/telephony/audiomanager;1"]
|
2012-01-09 14:28:47 -08:00
|
|
|
.getService(nsIAudioManager);
|
2011-12-12 10:22:26 -08:00
|
|
|
} catch (ex) {
|
|
|
|
//TODO on the phone this should not fall back as silently.
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) debug("Using fake audio manager.");
|
2011-12-12 10:22:26 -08:00
|
|
|
return FakeAudioManager;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2013-07-02 02:36:40 -07:00
|
|
|
XPCOMUtils.defineLazyGetter(this, "gMessageManager", function () {
|
|
|
|
return {
|
|
|
|
QueryInterface: XPCOMUtils.generateQI([Ci.nsIMessageListener,
|
|
|
|
Ci.nsIObserver]),
|
|
|
|
|
|
|
|
ril: null,
|
|
|
|
|
|
|
|
targetsByRequestId: {},
|
|
|
|
// 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_TELEPHONY_MSG_NAMES) {
|
|
|
|
ppmm.addMessageListener(msgname, 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_TELEPHONY_MSG_NAMES) {
|
|
|
|
ppmm.removeMessageListener(msgname, 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) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) debug("Already registered this target!");
|
2013-07-02 02:36:40 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
targets.push(target);
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) debug("Registered " + topic + " target: " + target);
|
2013-07-02 02:36:40 -07:00
|
|
|
},
|
|
|
|
|
|
|
|
_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);
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) debug("Unregistered " + topic + " target: " + target);
|
2013-07-02 02:36:40 -07:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
_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) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) debug("Received '" + msg.name + "' message from content process");
|
2013-07-02 02:36:40 -07:00
|
|
|
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_TELEPHONY_MSG_NAMES.indexOf(msg.name) != -1) {
|
|
|
|
if (!msg.target.assertPermission("telephony")) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) {
|
|
|
|
debug("Telephony message " + msg.name +
|
|
|
|
" from a content process with no 'telephony' privileges.");
|
|
|
|
}
|
2013-07-02 02:36:40 -07:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
} else if (RIL_IPC_MOBILECONNECTION_MSG_NAMES.indexOf(msg.name) != -1) {
|
|
|
|
if (!msg.target.assertPermission("mobileconnection")) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) {
|
|
|
|
debug("MobileConnection message " + msg.name +
|
|
|
|
" from a content process with no 'mobileconnection' privileges.");
|
|
|
|
}
|
2013-07-02 02:36:40 -07:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
} else if (RIL_IPC_ICCMANAGER_MSG_NAMES.indexOf(msg.name) != -1) {
|
|
|
|
if (!msg.target.assertPermission("mobileconnection")) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) {
|
|
|
|
debug("IccManager message " + msg.name +
|
|
|
|
" from a content process with no 'mobileconnection' privileges.");
|
|
|
|
}
|
2013-07-02 02:36:40 -07:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
} else if (RIL_IPC_VOICEMAIL_MSG_NAMES.indexOf(msg.name) != -1) {
|
|
|
|
if (!msg.target.assertPermission("voicemail")) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) {
|
|
|
|
debug("Voicemail message " + msg.name +
|
|
|
|
" from a content process with no 'voicemail' privileges.");
|
|
|
|
}
|
2013-07-02 02:36:40 -07:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
} else if (RIL_IPC_CELLBROADCAST_MSG_NAMES.indexOf(msg.name) != -1) {
|
|
|
|
if (!msg.target.assertPermission("cellbroadcast")) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) {
|
|
|
|
debug("Cell Broadcast message " + msg.name +
|
|
|
|
" from a content process with no 'cellbroadcast' privileges.");
|
|
|
|
}
|
2013-07-02 02:36:40 -07:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
} else {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) debug("Ignoring unknown message type: " + msg.name);
|
2013-07-02 02:36:40 -07:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (msg.name) {
|
|
|
|
case "RIL:RegisterTelephonyMsg":
|
|
|
|
this._registerMessageTarget("telephony", msg.target);
|
|
|
|
return;
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
sendTelephonyMessage: function sendTelephonyMessage(message, clientId, data) {
|
|
|
|
this._sendTargetMessage("telephony", message, {
|
|
|
|
clientId: clientId,
|
|
|
|
data: data
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
|
|
|
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
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
|
|
|
saveRequestTarget: function saveRequestTarget(msg) {
|
|
|
|
let requestId = msg.json.data.requestId;
|
|
|
|
if (!requestId) {
|
|
|
|
// The content is not interested in a response;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.targetsByRequestId[requestId] = msg.target;
|
|
|
|
},
|
|
|
|
|
|
|
|
sendRequestResults: function sendRequestResults(requestType, options) {
|
|
|
|
let target = this.targetsByRequestId[options.requestId];
|
|
|
|
delete this.targetsByRequestId[options.requestId];
|
|
|
|
|
|
|
|
if (!target) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
target.sendAsyncMessage(requestType, options);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
});
|
2011-12-04 23:58:27 -08:00
|
|
|
|
2012-01-19 12:53:32 -08:00
|
|
|
function RadioInterfaceLayer() {
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.init(this);
|
|
|
|
|
2013-07-02 02:36:37 -07:00
|
|
|
let options = {
|
|
|
|
debug: debugPref,
|
2013-07-31 00:56:43 -07:00
|
|
|
cellBroadcastDisabled: false,
|
|
|
|
clirMode: RIL.CLIR_DEFAULT
|
2013-07-02 02:36:37 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
try {
|
|
|
|
options.cellBroadcastDisabled =
|
|
|
|
Services.prefs.getBoolPref(kCellBroadcastDisabled);
|
|
|
|
} catch(e) {}
|
|
|
|
|
2013-07-31 00:56:43 -07:00
|
|
|
try {
|
|
|
|
options.clirMode = Services.prefs.getIntPref(kClirModePreference);
|
|
|
|
} catch(e) {}
|
|
|
|
|
2013-07-02 02:36:37 -07:00
|
|
|
let numIfaces = this.numRadioInterfaces;
|
|
|
|
debug(numIfaces + " interfaces");
|
|
|
|
this.radioInterfaces = [];
|
|
|
|
for (let clientId = 0; clientId < numIfaces; clientId++) {
|
|
|
|
options.clientId = clientId;
|
|
|
|
this.radioInterfaces.push(new RadioInterface(options));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
RadioInterfaceLayer.prototype = {
|
|
|
|
|
|
|
|
classID: RADIOINTERFACELAYER_CID,
|
|
|
|
classInfo: XPCOMUtils.generateCI({classID: RADIOINTERFACELAYER_CID,
|
|
|
|
classDescription: "RadioInterfaceLayer",
|
|
|
|
interfaces: [Ci.nsIRadioInterfaceLayer]}),
|
|
|
|
|
|
|
|
QueryInterface: XPCOMUtils.generateQI([Ci.nsIRadioInterfaceLayer,
|
|
|
|
Ci.nsIObserver]),
|
|
|
|
|
|
|
|
/**
|
|
|
|
* nsIObserver interface methods.
|
|
|
|
*/
|
|
|
|
|
|
|
|
observe: function observe(subject, topic, data) {
|
|
|
|
// Nothing to do now. Just for profile-after-change.
|
|
|
|
},
|
2013-06-07 00:32:20 -07:00
|
|
|
|
2013-07-02 02:36:37 -07:00
|
|
|
/**
|
|
|
|
* nsIRadioInterfaceLayer interface methods.
|
|
|
|
*/
|
|
|
|
|
|
|
|
getRadioInterface: function getRadioInterface(clientId) {
|
|
|
|
return this.radioInterfaces[clientId];
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
XPCOMUtils.defineLazyGetter(RadioInterfaceLayer.prototype,
|
|
|
|
"numRadioInterfaces", function () {
|
|
|
|
try {
|
|
|
|
return Services.prefs.getIntPref("ril.numRadioInterfaces");
|
|
|
|
} catch (e) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
function RadioInterface(options) {
|
|
|
|
this.clientId = options.clientId;
|
|
|
|
|
2013-07-11 21:44:22 -07:00
|
|
|
this.dataCallSettings = {
|
|
|
|
oldEnabled: false,
|
|
|
|
enabled: false,
|
|
|
|
roamingEnabled: false
|
|
|
|
};
|
|
|
|
|
|
|
|
// apnSettings is used to keep all APN settings.
|
|
|
|
// byApn[] makes it easier to get the APN settings via APN, user
|
|
|
|
// name, and password.
|
|
|
|
// byType[] makes it easier to get the APN settings via APN types.
|
|
|
|
this.apnSettings = {
|
|
|
|
byType: {},
|
|
|
|
byAPN: {}
|
|
|
|
};
|
2012-09-26 05:52:21 -07:00
|
|
|
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("Starting RIL Worker[" + this.clientId + "]");
|
2011-12-04 23:58:27 -08:00
|
|
|
this.worker = new ChromeWorker("resource://gre/modules/ril_worker.js");
|
|
|
|
this.worker.onerror = this.onerror.bind(this);
|
|
|
|
this.worker.onmessage = this.onmessage.bind(this);
|
2012-04-19 14:33:25 -07:00
|
|
|
|
2013-06-07 00:32:20 -07:00
|
|
|
// Pass initial options to ril_worker.
|
2013-07-02 02:36:37 -07:00
|
|
|
options.rilMessageType = "setInitialOptions";
|
|
|
|
this.worker.postMessage(options);
|
2013-06-07 00:32:20 -07:00
|
|
|
|
2012-06-12 19:46:41 -07:00
|
|
|
this.rilContext = {
|
2012-03-20 16:18:41 -07:00
|
|
|
radioState: RIL.GECKO_RADIOSTATE_UNAVAILABLE,
|
2013-02-01 05:17:48 -08:00
|
|
|
cardState: RIL.GECKO_CARDSTATE_UNKNOWN,
|
2013-03-28 19:56:07 -07:00
|
|
|
networkSelectionMode: RIL.GECKO_NETWORK_SELECTION_UNKNOWN,
|
2013-01-10 08:18:54 -08:00
|
|
|
iccInfo: null,
|
2013-01-11 01:20:12 -08:00
|
|
|
imsi: null,
|
2012-04-19 14:33:25 -07:00
|
|
|
|
|
|
|
// These objects implement the nsIDOMMozMobileConnectionInfo interface,
|
2012-08-15 18:36:56 -07:00
|
|
|
// although the actual implementation lives in the content process. So are
|
|
|
|
// the child attributes `network` and `cell`, which implement
|
|
|
|
// nsIDOMMozMobileNetworkInfo and nsIDOMMozMobileCellInfo respectively.
|
2012-04-19 14:33:25 -07:00
|
|
|
voice: {connected: false,
|
|
|
|
emergencyCallsOnly: false,
|
|
|
|
roaming: false,
|
2012-06-12 14:05:50 -07:00
|
|
|
network: null,
|
2012-08-15 18:36:56 -07:00
|
|
|
cell: null,
|
2012-04-19 14:33:25 -07:00
|
|
|
type: null,
|
|
|
|
signalStrength: null,
|
|
|
|
relSignalStrength: null},
|
2012-06-12 19:46:41 -07:00
|
|
|
data: {connected: false,
|
2012-04-19 14:33:25 -07:00
|
|
|
emergencyCallsOnly: false,
|
|
|
|
roaming: false,
|
2012-06-12 14:05:50 -07:00
|
|
|
network: null,
|
2012-08-15 18:36:56 -07:00
|
|
|
cell: null,
|
2012-04-19 14:33:25 -07:00
|
|
|
type: null,
|
|
|
|
signalStrength: null,
|
|
|
|
relSignalStrength: null},
|
2011-12-06 22:57:19 -08:00
|
|
|
};
|
2012-05-23 22:12:07 -07:00
|
|
|
|
2012-12-26 02:49:08 -08:00
|
|
|
this.voicemailInfo = {
|
|
|
|
number: null,
|
|
|
|
displayName: null
|
|
|
|
};
|
|
|
|
|
2012-05-25 10:37:37 -07:00
|
|
|
// Read the 'ril.radio.disabled' setting in order to start with a known
|
|
|
|
// value at boot time.
|
2012-09-07 11:05:08 -07:00
|
|
|
let lock = gSettingsService.createLock();
|
|
|
|
lock.get("ril.radio.disabled", this);
|
2012-05-23 22:12:07 -07:00
|
|
|
|
2012-09-27 20:45:06 -07:00
|
|
|
// Read preferred network type from the setting DB.
|
|
|
|
lock.get("ril.radio.preferredNetworkType", this);
|
|
|
|
|
2012-09-26 05:57:37 -07:00
|
|
|
// Read the APN data from the settings DB.
|
2012-09-07 11:05:08 -07:00
|
|
|
lock.get("ril.data.roaming_enabled", this);
|
|
|
|
lock.get("ril.data.enabled", this);
|
2013-07-11 21:44:22 -07:00
|
|
|
lock.get("ril.data.apnSettings", this);
|
2012-09-26 05:57:37 -07:00
|
|
|
|
2012-09-27 23:02:57 -07:00
|
|
|
// Read the 'time.nitz.automatic-update.enabled' setting to see if
|
|
|
|
// we need to adjust the system clock time and time zone by NITZ.
|
|
|
|
lock.get(kTimeNitzAutomaticUpdateEnabled, this);
|
|
|
|
|
2013-01-25 02:06:24 -08:00
|
|
|
// Set "time.nitz.available" to false when starting up.
|
|
|
|
this.setNitzAvailable(false);
|
|
|
|
|
2012-12-03 18:41:39 -08:00
|
|
|
// Read the Cell Broadcast Search List setting, string of integers or integer
|
|
|
|
// ranges separated by comma, to set listening channels.
|
|
|
|
lock.get(kCellBroadcastSearchList, this);
|
|
|
|
|
2012-04-19 14:33:25 -07:00
|
|
|
Services.obs.addObserver(this, "xpcom-shutdown", false);
|
2012-04-24 13:46:42 -07:00
|
|
|
Services.obs.addObserver(this, kMozSettingsChangedObserverTopic, false);
|
2012-09-05 13:00:06 -07:00
|
|
|
Services.obs.addObserver(this, kSysMsgListenerReadyObserverTopic, false);
|
2012-10-23 00:15:53 -07:00
|
|
|
Services.obs.addObserver(this, kSysClockChangeObserverTopic, false);
|
2013-06-06 00:28:59 -07:00
|
|
|
Services.obs.addObserver(this, kScreenStateChangedTopic, false);
|
2012-04-19 14:33:25 -07:00
|
|
|
|
2013-06-07 00:32:24 -07:00
|
|
|
Services.prefs.addObserver(kCellBroadcastDisabled, this, false);
|
|
|
|
|
2012-04-05 14:16:56 -07:00
|
|
|
this._sentSmsEnvelopes = {};
|
2012-06-03 22:04:28 -07:00
|
|
|
|
2012-04-23 16:43:32 -07:00
|
|
|
this.portAddressedSmsApps = {};
|
2012-06-03 22:04:28 -07:00
|
|
|
this.portAddressedSmsApps[WAP.WDP_PORT_PUSH] = this.handleSmsWdpPortPush.bind(this);
|
2012-11-12 03:19:48 -08:00
|
|
|
|
2013-06-07 00:32:20 -07:00
|
|
|
gSystemWorkerManager.registerRilWorker(this.clientId, this.worker);
|
2011-12-04 23:58:27 -08:00
|
|
|
}
|
2013-07-02 02:36:37 -07:00
|
|
|
RadioInterface.prototype = {
|
2011-12-04 23:58:27 -08:00
|
|
|
|
2013-07-02 02:36:37 -07:00
|
|
|
classID: RADIOINTERFACE_CID,
|
|
|
|
classInfo: XPCOMUtils.generateCI({classID: RADIOINTERFACE_CID,
|
|
|
|
classDescription: "RadioInterface",
|
|
|
|
interfaces: [Ci.nsIRadioInterface]}),
|
2011-12-04 23:58:27 -08:00
|
|
|
|
2013-07-02 02:36:37 -07:00
|
|
|
QueryInterface: XPCOMUtils.generateQI([Ci.nsIRadioInterface,
|
2012-05-23 22:12:07 -07:00
|
|
|
Ci.nsIObserver,
|
|
|
|
Ci.nsISettingsServiceCallback]),
|
2011-12-04 23:58:27 -08:00
|
|
|
|
2013-07-02 02:36:58 -07:00
|
|
|
debug: function debug(s) {
|
|
|
|
dump("-*- RadioInterface[" + this.clientId + "]: " + s + "\n");
|
|
|
|
},
|
|
|
|
|
2012-04-19 14:33:25 -07:00
|
|
|
/**
|
|
|
|
* Process a message from the content process.
|
|
|
|
*/
|
|
|
|
receiveMessage: function receiveMessage(msg) {
|
|
|
|
switch (msg.name) {
|
2012-06-12 19:46:41 -07:00
|
|
|
case "RIL:GetRilContext":
|
2012-04-19 14:33:25 -07:00
|
|
|
// This message is sync.
|
2012-06-12 19:46:41 -07:00
|
|
|
return this.rilContext;
|
2012-04-24 08:44:42 -07:00
|
|
|
case "RIL:EnumerateCalls":
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.saveRequestTarget(msg);
|
|
|
|
this.enumerateCalls(msg.json.data);
|
2012-04-24 08:44:42 -07:00
|
|
|
break;
|
|
|
|
case "RIL:GetMicrophoneMuted":
|
|
|
|
// This message is sync.
|
|
|
|
return this.microphoneMuted;
|
|
|
|
case "RIL:SetMicrophoneMuted":
|
2013-07-02 02:36:40 -07:00
|
|
|
this.microphoneMuted = msg.json.data;
|
2012-04-24 08:44:42 -07:00
|
|
|
break;
|
|
|
|
case "RIL:GetSpeakerEnabled":
|
|
|
|
// This message is sync.
|
|
|
|
return this.speakerEnabled;
|
|
|
|
case "RIL:SetSpeakerEnabled":
|
2013-07-02 02:36:40 -07:00
|
|
|
this.speakerEnabled = msg.json.data;
|
2012-04-24 08:44:42 -07:00
|
|
|
break;
|
|
|
|
case "RIL:StartTone":
|
2013-07-02 02:36:40 -07:00
|
|
|
this.startTone(msg.json.data);
|
2012-04-24 08:44:42 -07:00
|
|
|
break;
|
|
|
|
case "RIL:StopTone":
|
|
|
|
this.stopTone();
|
|
|
|
break;
|
|
|
|
case "RIL:Dial":
|
2013-07-02 02:36:40 -07:00
|
|
|
this.dial(msg.json.data);
|
2012-04-24 08:44:42 -07:00
|
|
|
break;
|
2012-07-20 05:08:24 -07:00
|
|
|
case "RIL:DialEmergency":
|
2013-07-02 02:36:40 -07:00
|
|
|
this.dialEmergency(msg.json.data);
|
2012-07-20 05:08:24 -07:00
|
|
|
break;
|
2012-04-24 08:44:42 -07:00
|
|
|
case "RIL:HangUp":
|
2013-07-02 02:36:40 -07:00
|
|
|
this.hangUp(msg.json.data);
|
2012-04-24 08:44:42 -07:00
|
|
|
break;
|
|
|
|
case "RIL:AnswerCall":
|
2013-07-02 02:36:40 -07:00
|
|
|
this.answerCall(msg.json.data);
|
2012-04-24 08:44:42 -07:00
|
|
|
break;
|
|
|
|
case "RIL:RejectCall":
|
2013-07-02 02:36:40 -07:00
|
|
|
this.rejectCall(msg.json.data);
|
2012-04-24 08:44:42 -07:00
|
|
|
break;
|
|
|
|
case "RIL:HoldCall":
|
2013-07-02 02:36:40 -07:00
|
|
|
this.holdCall(msg.json.data);
|
2012-04-24 08:44:42 -07:00
|
|
|
break;
|
|
|
|
case "RIL:ResumeCall":
|
2013-07-02 02:36:40 -07:00
|
|
|
this.resumeCall(msg.json.data);
|
2012-10-09 03:07:11 -07:00
|
|
|
break;
|
2012-06-01 14:10:39 -07:00
|
|
|
case "RIL:GetAvailableNetworks":
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.saveRequestTarget(msg);
|
|
|
|
this.getAvailableNetworks(msg.json.data.requestId);
|
2012-06-01 14:10:39 -07:00
|
|
|
break;
|
2012-06-19 15:52:06 -07:00
|
|
|
case "RIL:SelectNetwork":
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.saveRequestTarget(msg);
|
|
|
|
this.selectNetwork(msg.json.data);
|
2012-06-19 15:52:06 -07:00
|
|
|
break;
|
|
|
|
case "RIL:SelectNetworkAuto":
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.saveRequestTarget(msg);
|
|
|
|
this.selectNetworkAuto(msg.json.data.requestId);
|
2012-10-09 03:07:11 -07:00
|
|
|
break;
|
2013-04-11 00:12:09 -07:00
|
|
|
case "RIL:GetCardLockState":
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.saveRequestTarget(msg);
|
|
|
|
this.getCardLockState(msg.json.data);
|
2012-04-11 21:01:49 -07:00
|
|
|
break;
|
|
|
|
case "RIL:UnlockCardLock":
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.saveRequestTarget(msg);
|
|
|
|
this.unlockCardLock(msg.json.data);
|
2012-04-11 21:01:49 -07:00
|
|
|
break;
|
|
|
|
case "RIL:SetCardLock":
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.saveRequestTarget(msg);
|
|
|
|
this.setCardLock(msg.json.data);
|
2012-04-11 21:01:49 -07:00
|
|
|
break;
|
Bug 875710: Added getCardLockRetryCount to nsIIccProvider, r=vyang, sr=mounir
This patch adds getCardLockRetryCount to nsIIccProvider and its
implementations. This method allows callers to query the number
of remaining tries for unlocking a SIM-card lock. Supported locks
are 'pin', 'puk', 'pin2', 'puk2', 'nck', 'cck', and 'spck'. The
call returns a DOM request that returns the retry count in its
success handler, or signals an appropriate error.
Reading the retry count is an optional feature and may not be
supported for all lock types. In this case the DOM request receives
and error with the name GECKO_ERROR_NOT_SUPPORTED. For an invalid
lock type, the error name is GECKO_ERROR_GENERIC_FAILURE.
getCardLockRetryCount replaces retryCount in nsIDOMMobileConnection,
which is now deprecated.
--HG--
extra : rebase_source : d1d11612f836652dca85f7c701f09e7af962e3b7
2013-07-09 07:06:05 -07:00
|
|
|
case "RIL:GetCardLockRetryCount":
|
|
|
|
gMessageManager.saveRequestTarget(msg);
|
|
|
|
this.getCardLockRetryCount(msg.json.data);
|
|
|
|
break;
|
2012-10-05 07:08:55 -07:00
|
|
|
case "RIL:SendMMI":
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.saveRequestTarget(msg);
|
|
|
|
this.sendMMI(msg.json.data);
|
2012-06-09 14:07:18 -07:00
|
|
|
break;
|
2012-10-05 07:08:55 -07:00
|
|
|
case "RIL:CancelMMI":
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.saveRequestTarget(msg);
|
|
|
|
this.cancelMMI(msg.json.data);
|
2012-06-09 14:07:18 -07:00
|
|
|
break;
|
2012-04-10 05:04:27 -07:00
|
|
|
case "RIL:SendStkResponse":
|
2013-07-02 02:36:40 -07:00
|
|
|
this.sendStkResponse(msg.json.data);
|
2012-04-10 05:04:27 -07:00
|
|
|
break;
|
|
|
|
case "RIL:SendStkMenuSelection":
|
2013-07-02 02:36:40 -07:00
|
|
|
this.sendStkMenuSelection(msg.json.data);
|
2012-04-10 05:04:27 -07:00
|
|
|
break;
|
2012-11-28 00:16:20 -08:00
|
|
|
case "RIL:SendStkTimerExpiration":
|
2013-07-02 02:36:40 -07:00
|
|
|
this.sendStkTimerExpiration(msg.json.data);
|
2012-11-28 00:16:20 -08:00
|
|
|
break;
|
2012-09-10 19:34:36 -07:00
|
|
|
case "RIL:SendStkEventDownload":
|
2013-07-02 02:36:40 -07:00
|
|
|
this.sendStkEventDownload(msg.json.data);
|
2012-09-10 19:34:36 -07:00
|
|
|
break;
|
2013-02-25 01:27:26 -08:00
|
|
|
case "RIL:IccOpenChannel":
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.saveRequestTarget(msg);
|
|
|
|
this.iccOpenChannel(msg.json.data);
|
2013-02-25 01:27:26 -08:00
|
|
|
break;
|
|
|
|
case "RIL:IccCloseChannel":
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.saveRequestTarget(msg);
|
|
|
|
this.iccCloseChannel(msg.json.data);
|
2013-02-25 01:27:26 -08:00
|
|
|
break;
|
|
|
|
case "RIL:IccExchangeAPDU":
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.saveRequestTarget(msg);
|
|
|
|
this.iccExchangeAPDU(msg.json.data);
|
2013-02-25 01:27:26 -08:00
|
|
|
break;
|
2013-03-05 18:51:40 -08:00
|
|
|
case "RIL:ReadIccContacts":
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.saveRequestTarget(msg);
|
|
|
|
this.readIccContacts(msg.json.data);
|
2013-03-05 18:51:40 -08:00
|
|
|
break;
|
2013-03-24 20:09:01 -07:00
|
|
|
case "RIL:UpdateIccContact":
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.saveRequestTarget(msg);
|
|
|
|
this.updateIccContact(msg.json.data);
|
2012-10-09 03:07:11 -07:00
|
|
|
break;
|
2012-10-31 06:58:39 -07:00
|
|
|
case "RIL:SetCallForwardingOption":
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.saveRequestTarget(msg);
|
|
|
|
this.setCallForwardingOption(msg.json.data);
|
2012-10-31 06:58:39 -07:00
|
|
|
break;
|
|
|
|
case "RIL:GetCallForwardingOption":
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.saveRequestTarget(msg);
|
|
|
|
this.getCallForwardingOption(msg.json.data);
|
2012-10-31 06:58:39 -07:00
|
|
|
break;
|
2013-05-20 22:13:37 -07:00
|
|
|
case "RIL:SetCallBarringOption":
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.saveRequestTarget(msg);
|
|
|
|
this.setCallBarringOption(msg.json.data);
|
2013-05-20 22:13:37 -07:00
|
|
|
break;
|
|
|
|
case "RIL:GetCallBarringOption":
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.saveRequestTarget(msg);
|
|
|
|
this.getCallBarringOption(msg.json.data);
|
2013-05-20 22:13:37 -07:00
|
|
|
break;
|
2013-04-18 05:18:50 -07:00
|
|
|
case "RIL:SetCallWaitingOption":
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.saveRequestTarget(msg);
|
|
|
|
this.setCallWaitingOption(msg.json.data);
|
2013-04-18 05:18:50 -07:00
|
|
|
break;
|
|
|
|
case "RIL:GetCallWaitingOption":
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.saveRequestTarget(msg);
|
|
|
|
this.getCallWaitingOption(msg.json.data);
|
2012-12-03 18:40:47 -08:00
|
|
|
break;
|
2013-07-17 14:18:29 -07:00
|
|
|
case "RIL:SetCallingLineIdRestriction":
|
|
|
|
gMessageManager.saveRequestTarget(msg);
|
|
|
|
this.setCallingLineIdRestriction(msg.json.data);
|
|
|
|
break;
|
|
|
|
case "RIL:GetCallingLineIdRestriction":
|
|
|
|
gMessageManager.saveRequestTarget(msg);
|
|
|
|
this.getCallingLineIdRestriction(msg.json.data);
|
|
|
|
break;
|
2012-12-26 02:49:08 -08:00
|
|
|
case "RIL:GetVoicemailInfo":
|
|
|
|
// This message is sync.
|
|
|
|
return this.voicemailInfo;
|
2013-06-10 00:47:03 -07:00
|
|
|
case "RIL:SetRoamingPreference":
|
|
|
|
gMessageManager.saveRequestTarget(msg);
|
|
|
|
this.setRoamingPreference(msg.json.data);
|
|
|
|
break;
|
|
|
|
case "RIL:GetRoamingPreference":
|
|
|
|
gMessageManager.saveRequestTarget(msg);
|
|
|
|
this.getRoamingPreference(msg.json.data);
|
|
|
|
break;
|
2012-04-19 14:33:25 -07:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2011-12-04 23:58:27 -08:00
|
|
|
onerror: function onerror(event) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) {
|
|
|
|
this.debug("Got an error: " + event.filename + ":" +
|
|
|
|
event.lineno + ": " + event.message + "\n");
|
|
|
|
}
|
2012-01-09 14:28:47 -08:00
|
|
|
event.preventDefault();
|
2011-12-04 23:58:27 -08:00
|
|
|
},
|
|
|
|
|
2011-12-12 10:22:26 -08:00
|
|
|
/**
|
2012-04-19 14:33:25 -07:00
|
|
|
* Process the incoming message from the RIL worker. This roughly
|
|
|
|
* works as follows:
|
|
|
|
* (1) Update local state.
|
2011-12-12 10:22:26 -08:00
|
|
|
* (2) Update state in related systems such as the audio.
|
2012-04-19 14:33:25 -07:00
|
|
|
* (3) Multiplex the message to callbacks / listeners (typically the DOM).
|
2011-12-12 10:22:26 -08:00
|
|
|
*/
|
2011-12-04 23:58:27 -08:00
|
|
|
onmessage: function onmessage(event) {
|
|
|
|
let message = event.data;
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) {
|
|
|
|
this.debug("Received message from worker: " + JSON.stringify(message));
|
|
|
|
}
|
2012-08-06 14:28:03 -07:00
|
|
|
switch (message.rilMessageType) {
|
2012-11-27 17:28:43 -08:00
|
|
|
case "callRing":
|
|
|
|
this.handleCallRing();
|
|
|
|
break;
|
2012-01-09 14:28:47 -08:00
|
|
|
case "callStateChange":
|
|
|
|
// This one will handle its own notifications.
|
|
|
|
this.handleCallStateChange(message.call);
|
|
|
|
break;
|
|
|
|
case "callDisconnected":
|
|
|
|
// This one will handle its own notifications.
|
|
|
|
this.handleCallDisconnected(message.call);
|
|
|
|
break;
|
|
|
|
case "enumerateCalls":
|
|
|
|
// This one will handle its own notifications.
|
2012-08-16 20:46:34 -07:00
|
|
|
this.handleEnumerateCalls(message);
|
2012-01-09 14:28:47 -08:00
|
|
|
break;
|
2012-05-14 21:13:06 -07:00
|
|
|
case "callError":
|
|
|
|
this.handleCallError(message);
|
|
|
|
break;
|
2013-02-25 01:27:26 -08:00
|
|
|
case "iccOpenChannel":
|
|
|
|
this.handleIccOpenChannel(message);
|
|
|
|
break;
|
|
|
|
case "iccCloseChannel":
|
|
|
|
this.handleIccCloseChannel(message);
|
|
|
|
break;
|
|
|
|
case "iccExchangeAPDU":
|
|
|
|
this.handleIccExchangeAPDU(message);
|
|
|
|
break;
|
2012-06-01 14:10:39 -07:00
|
|
|
case "getAvailableNetworks":
|
|
|
|
this.handleGetAvailableNetworks(message);
|
|
|
|
break;
|
2012-06-19 15:52:06 -07:00
|
|
|
case "selectNetwork":
|
|
|
|
this.handleSelectNetwork(message);
|
|
|
|
break;
|
|
|
|
case "selectNetworkAuto":
|
|
|
|
this.handleSelectNetworkAuto(message);
|
|
|
|
break;
|
|
|
|
case "networkinfochanged":
|
|
|
|
this.updateNetworkInfo(message);
|
|
|
|
break;
|
|
|
|
case "networkselectionmodechange":
|
|
|
|
this.updateNetworkSelectionMode(message);
|
|
|
|
break;
|
2012-03-19 15:49:27 -07:00
|
|
|
case "voiceregistrationstatechange":
|
2012-04-19 14:33:25 -07:00
|
|
|
this.updateVoiceConnection(message);
|
2012-02-10 11:27:23 -08:00
|
|
|
break;
|
2012-03-19 15:49:27 -07:00
|
|
|
case "dataregistrationstatechange":
|
2012-04-19 14:33:25 -07:00
|
|
|
this.updateDataConnection(message);
|
2012-02-10 11:27:23 -08:00
|
|
|
break;
|
2012-06-01 14:09:59 -07:00
|
|
|
case "datacallerror":
|
2012-09-25 12:22:38 -07:00
|
|
|
this.handleDataCallError(message);
|
2012-06-01 14:09:59 -07:00
|
|
|
break;
|
2011-12-04 23:58:27 -08:00
|
|
|
case "signalstrengthchange":
|
2012-04-19 14:33:25 -07:00
|
|
|
this.handleSignalStrengthChange(message);
|
2011-12-04 23:58:27 -08:00
|
|
|
break;
|
|
|
|
case "operatorchange":
|
2012-04-19 14:33:25 -07:00
|
|
|
this.handleOperatorChange(message);
|
2011-12-04 23:58:27 -08:00
|
|
|
break;
|
2011-12-06 22:57:19 -08:00
|
|
|
case "radiostatechange":
|
2012-05-23 22:12:07 -07:00
|
|
|
this.handleRadioStateChange(message);
|
2011-12-04 23:58:27 -08:00
|
|
|
break;
|
|
|
|
case "cardstatechange":
|
2012-06-12 19:46:41 -07:00
|
|
|
this.rilContext.cardState = message.cardState;
|
2013-05-22 02:32:18 -07:00
|
|
|
gMessageManager.sendIccMessage("RIL:CardStateChanged",
|
|
|
|
this.clientId, message);
|
2011-12-04 23:58:27 -08:00
|
|
|
break;
|
2011-12-23 21:02:52 -08:00
|
|
|
case "sms-received":
|
2013-02-17 23:11:13 -08:00
|
|
|
let ackOk = this.handleSmsReceived(message);
|
|
|
|
if (ackOk) {
|
|
|
|
this.worker.postMessage({
|
|
|
|
rilMessageType: "ackSMS",
|
|
|
|
result: RIL.PDU_FCS_OK
|
|
|
|
});
|
|
|
|
}
|
2011-12-06 22:57:19 -08:00
|
|
|
return;
|
2012-02-19 15:44:29 -08:00
|
|
|
case "sms-sent":
|
|
|
|
this.handleSmsSent(message);
|
|
|
|
return;
|
2012-10-30 03:53:27 -07:00
|
|
|
case "sms-delivery":
|
|
|
|
this.handleSmsDelivery(message);
|
2012-04-05 14:16:56 -07:00
|
|
|
return;
|
2012-04-05 14:16:56 -07:00
|
|
|
case "sms-send-failed":
|
|
|
|
this.handleSmsSendFailed(message);
|
|
|
|
return;
|
2012-12-03 18:40:47 -08:00
|
|
|
case "cellbroadcast-received":
|
|
|
|
message.timestamp = Date.now();
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.sendCellBroadcastMessage("RIL:CellBroadcastReceived",
|
|
|
|
this.clientId, message);
|
2012-12-03 18:40:47 -08:00
|
|
|
break;
|
2012-01-17 17:34:09 -08:00
|
|
|
case "datacallstatechange":
|
2012-07-19 16:56:57 -07:00
|
|
|
this.handleDataCallState(message);
|
2012-01-17 17:34:09 -08:00
|
|
|
break;
|
|
|
|
case "datacalllist":
|
|
|
|
this.handleDataCallList(message);
|
|
|
|
break;
|
2012-03-08 20:16:06 -08:00
|
|
|
case "nitzTime":
|
2012-09-27 23:02:57 -07:00
|
|
|
this.handleNitzTime(message);
|
2012-03-08 20:16:06 -08:00
|
|
|
break;
|
2012-04-18 03:07:29 -07:00
|
|
|
case "iccinfochange":
|
2013-03-24 20:09:01 -07:00
|
|
|
this.handleIccInfoChange(message);
|
2012-03-17 07:23:17 -07:00
|
|
|
break;
|
2013-01-11 01:20:12 -08:00
|
|
|
case "iccimsi":
|
|
|
|
this.rilContext.imsi = message.imsi;
|
|
|
|
break;
|
2013-04-11 00:12:09 -07:00
|
|
|
case "iccGetCardLockState":
|
2012-08-15 09:49:12 -07:00
|
|
|
case "iccSetCardLock":
|
|
|
|
case "iccUnlockCardLock":
|
2013-03-24 20:09:01 -07:00
|
|
|
this.handleIccCardLockResult(message);
|
2012-04-11 21:01:49 -07:00
|
|
|
break;
|
Bug 875710: Added getCardLockRetryCount to nsIIccProvider, r=vyang, sr=mounir
This patch adds getCardLockRetryCount to nsIIccProvider and its
implementations. This method allows callers to query the number
of remaining tries for unlocking a SIM-card lock. Supported locks
are 'pin', 'puk', 'pin2', 'puk2', 'nck', 'cck', and 'spck'. The
call returns a DOM request that returns the retry count in its
success handler, or signals an appropriate error.
Reading the retry count is an optional feature and may not be
supported for all lock types. In this case the DOM request receives
and error with the name GECKO_ERROR_NOT_SUPPORTED. For an invalid
lock type, the error name is GECKO_ERROR_GENERIC_FAILURE.
getCardLockRetryCount replaces retryCount in nsIDOMMobileConnection,
which is now deprecated.
--HG--
extra : rebase_source : d1d11612f836652dca85f7c701f09e7af962e3b7
2013-07-09 07:06:05 -07:00
|
|
|
case "iccGetCardLockRetryCount":
|
|
|
|
this.handleIccCardLockRetryCount(message);
|
|
|
|
break;
|
2012-05-07 11:53:42 -07:00
|
|
|
case "icccontacts":
|
2013-03-05 18:51:40 -08:00
|
|
|
this.handleReadIccContacts(message);
|
2012-05-07 11:53:42 -07:00
|
|
|
break;
|
2012-12-27 19:11:36 -08:00
|
|
|
case "icccontactupdate":
|
2013-03-24 20:09:01 -07:00
|
|
|
this.handleUpdateIccContact(message);
|
2012-12-27 19:11:36 -08:00
|
|
|
break;
|
2012-07-20 17:19:38 -07:00
|
|
|
case "iccmbdn":
|
2013-03-24 20:09:01 -07:00
|
|
|
this.handleIccMbdn(message);
|
2012-07-20 17:19:38 -07:00
|
|
|
break;
|
2012-10-05 07:08:55 -07:00
|
|
|
case "USSDReceived":
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("USSDReceived " + JSON.stringify(message));
|
2012-06-09 14:07:18 -07:00
|
|
|
this.handleUSSDReceived(message);
|
|
|
|
break;
|
2012-10-05 07:08:55 -07:00
|
|
|
case "sendMMI":
|
2012-10-05 07:09:00 -07:00
|
|
|
case "sendUSSD":
|
2012-10-05 07:08:55 -07:00
|
|
|
this.handleSendMMI(message);
|
2012-06-09 14:07:18 -07:00
|
|
|
break;
|
2012-10-05 07:08:55 -07:00
|
|
|
case "cancelMMI":
|
2012-10-05 07:09:00 -07:00
|
|
|
case "cancelUSSD":
|
2012-10-05 07:08:55 -07:00
|
|
|
this.handleCancelMMI(message);
|
2012-06-09 14:07:18 -07:00
|
|
|
break;
|
2012-04-10 05:04:27 -07:00
|
|
|
case "stkcommand":
|
|
|
|
this.handleStkProactiveCommand(message);
|
|
|
|
break;
|
|
|
|
case "stksessionend":
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.sendIccMessage("RIL:StkSessionEnd", this.clientId, null);
|
2012-04-10 05:04:27 -07:00
|
|
|
break;
|
2012-09-27 20:45:06 -07:00
|
|
|
case "setPreferredNetworkType":
|
|
|
|
this.handleSetPreferredNetworkType(message);
|
|
|
|
break;
|
2012-10-31 06:58:39 -07:00
|
|
|
case "queryCallForwardStatus":
|
|
|
|
this.handleQueryCallForwardStatus(message);
|
|
|
|
break;
|
|
|
|
case "setCallForward":
|
|
|
|
this.handleSetCallForward(message);
|
|
|
|
break;
|
2013-05-20 22:13:37 -07:00
|
|
|
case "queryCallBarringStatus":
|
|
|
|
this.handleQueryCallBarringStatus(message);
|
|
|
|
break;
|
|
|
|
case "setCallBarring":
|
|
|
|
this.handleSetCallBarring(message);
|
|
|
|
break;
|
2013-04-18 05:18:50 -07:00
|
|
|
case "queryCallWaiting":
|
|
|
|
this.handleQueryCallWaiting(message);
|
|
|
|
break;
|
|
|
|
case "setCallWaiting":
|
|
|
|
this.handleSetCallWaiting(message);
|
|
|
|
break;
|
2013-07-17 14:18:29 -07:00
|
|
|
case "getCLIR":
|
|
|
|
this.handleGetCLIR(message);
|
|
|
|
break;
|
|
|
|
case "setCLIR":
|
|
|
|
this.handleSetCLIR(message);
|
|
|
|
break;
|
2012-12-03 18:41:39 -08:00
|
|
|
case "setCellBroadcastSearchList":
|
|
|
|
this.handleSetCellBroadcastSearchList(message);
|
|
|
|
break;
|
2013-03-18 02:03:49 -07:00
|
|
|
case "setRadioEnabled":
|
|
|
|
let lock = gSettingsService.createLock();
|
|
|
|
lock.set("ril.radio.disabled", !message.on, null, null);
|
|
|
|
break;
|
2013-06-10 00:47:03 -07:00
|
|
|
case "setRoamingPreference":
|
|
|
|
this.handleSetRoamingPreference(message);
|
|
|
|
break;
|
|
|
|
case "queryRoamingPreference":
|
|
|
|
this.handleQueryRoamingPreference(message);
|
|
|
|
break;
|
2012-01-09 14:28:47 -08:00
|
|
|
default:
|
2012-08-06 14:28:03 -07:00
|
|
|
throw new Error("Don't know about this message type: " +
|
|
|
|
message.rilMessageType);
|
2011-12-04 23:58:27 -08:00
|
|
|
}
|
2012-01-09 14:28:47 -08:00
|
|
|
},
|
|
|
|
|
2013-07-02 02:36:47 -07:00
|
|
|
getMsisdn: function getMsisdn() {
|
|
|
|
let iccInfo = this.rilContext.iccInfo;
|
|
|
|
let number = iccInfo ? iccInfo.msisdn : null;
|
|
|
|
|
|
|
|
// Workaround an xpconnect issue with undefined string objects.
|
|
|
|
// See bug 808220
|
|
|
|
if (number === undefined || number === "undefined") {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
return number;
|
|
|
|
},
|
|
|
|
|
2012-06-19 15:52:06 -07:00
|
|
|
updateNetworkInfo: function updateNetworkInfo(message) {
|
|
|
|
let voiceMessage = message[RIL.NETWORK_INFO_VOICE_REGISTRATION_STATE];
|
|
|
|
let dataMessage = message[RIL.NETWORK_INFO_DATA_REGISTRATION_STATE];
|
|
|
|
let operatorMessage = message[RIL.NETWORK_INFO_OPERATOR];
|
|
|
|
let selectionMessage = message[RIL.NETWORK_INFO_NETWORK_SELECTION_MODE];
|
|
|
|
|
|
|
|
// Batch the *InfoChanged messages together
|
|
|
|
if (voiceMessage) {
|
|
|
|
voiceMessage.batch = true;
|
2012-08-07 12:11:48 -07:00
|
|
|
this.updateVoiceConnection(voiceMessage);
|
2012-06-19 15:52:06 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if (dataMessage) {
|
|
|
|
dataMessage.batch = true;
|
2012-08-07 12:11:48 -07:00
|
|
|
this.updateDataConnection(dataMessage);
|
2012-06-19 15:52:06 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if (operatorMessage) {
|
2013-01-27 19:41:34 -08:00
|
|
|
operatorMessage.batch = true;
|
|
|
|
this.handleOperatorChange(operatorMessage);
|
2012-06-19 15:52:06 -07:00
|
|
|
}
|
|
|
|
|
2013-01-27 19:41:34 -08:00
|
|
|
let voice = this.rilContext.voice;
|
|
|
|
let data = this.rilContext.data;
|
|
|
|
|
2012-09-03 14:50:55 -07:00
|
|
|
this.checkRoamingBetweenOperators(voice);
|
|
|
|
this.checkRoamingBetweenOperators(data);
|
|
|
|
|
2012-08-07 12:11:48 -07:00
|
|
|
if (voiceMessage || operatorMessage) {
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.sendMobileConnectionMessage("RIL:VoiceInfoChanged",
|
|
|
|
this.clientId, voice);
|
2012-06-19 15:52:06 -07:00
|
|
|
}
|
2012-08-07 12:11:48 -07:00
|
|
|
if (dataMessage || operatorMessage) {
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.sendMobileConnectionMessage("RIL:DataInfoChanged",
|
|
|
|
this.clientId, data);
|
2012-06-19 15:52:06 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if (selectionMessage) {
|
|
|
|
this.updateNetworkSelectionMode(selectionMessage);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2012-09-03 14:50:55 -07:00
|
|
|
/**
|
|
|
|
* Fix the roaming. RIL can report roaming in some case it is not
|
|
|
|
* really the case. See bug 787967
|
|
|
|
*
|
|
|
|
* @param registration The voiceMessage or dataMessage from which the
|
|
|
|
* roaming state will be changed (maybe, if needed).
|
|
|
|
*/
|
|
|
|
checkRoamingBetweenOperators: function checkRoamingBetweenOperators(registration) {
|
2013-01-10 08:18:54 -08:00
|
|
|
let iccInfo = this.rilContext.iccInfo;
|
|
|
|
if (!iccInfo || !registration.connected) {
|
2012-09-03 14:50:55 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-01-10 08:18:54 -08:00
|
|
|
let spn = iccInfo.spn && iccInfo.spn.toLowerCase();
|
2012-09-03 14:50:55 -07:00
|
|
|
let operator = registration.network;
|
2012-10-04 15:30:06 -07:00
|
|
|
let longName = operator.longName && operator.longName.toLowerCase();
|
|
|
|
let shortName = operator.shortName && operator.shortName.toLowerCase();
|
2012-09-03 14:50:55 -07:00
|
|
|
|
|
|
|
let equalsLongName = longName && (spn == longName);
|
|
|
|
let equalsShortName = shortName && (spn == shortName);
|
2013-01-10 08:18:54 -08:00
|
|
|
let equalsMcc = iccInfo.mcc == operator.mcc;
|
2012-09-03 14:50:55 -07:00
|
|
|
|
|
|
|
registration.roaming = registration.roaming &&
|
|
|
|
!(equalsMcc && (equalsLongName || equalsShortName));
|
|
|
|
},
|
|
|
|
|
2012-06-19 15:52:06 -07:00
|
|
|
/**
|
|
|
|
* Sends the RIL:VoiceInfoChanged message when the voice
|
|
|
|
* connection's state has changed.
|
|
|
|
*
|
2012-08-07 12:11:48 -07:00
|
|
|
* @param newInfo The new voice connection information. When newInfo.batch is true,
|
|
|
|
* the RIL:VoiceInfoChanged message will not be sent.
|
2012-06-19 15:52:06 -07:00
|
|
|
*/
|
2012-08-07 12:11:48 -07:00
|
|
|
updateVoiceConnection: function updateVoiceConnection(newInfo) {
|
2012-06-12 19:46:41 -07:00
|
|
|
let voiceInfo = this.rilContext.voice;
|
2012-08-07 12:11:48 -07:00
|
|
|
voiceInfo.state = newInfo.state;
|
|
|
|
voiceInfo.connected = newInfo.connected;
|
|
|
|
voiceInfo.roaming = newInfo.roaming;
|
|
|
|
voiceInfo.emergencyCallsOnly = newInfo.emergencyCallsOnly;
|
2013-06-07 01:50:10 -07:00
|
|
|
voiceInfo.type = newInfo.type;
|
2012-08-07 12:11:48 -07:00
|
|
|
|
|
|
|
// Make sure we also reset the operator and signal strength information
|
|
|
|
// if we drop off the network.
|
2013-07-03 20:48:48 -07:00
|
|
|
if (newInfo.regState !== RIL.NETWORK_CREG_STATE_REGISTERED_HOME &&
|
|
|
|
newInfo.regState !== RIL.NETWORK_CREG_STATE_REGISTERED_ROAMING) {
|
|
|
|
voiceInfo.cell = null;
|
2012-06-12 14:05:50 -07:00
|
|
|
voiceInfo.network = null;
|
2012-04-19 14:33:25 -07:00
|
|
|
voiceInfo.signalStrength = null;
|
|
|
|
voiceInfo.relSignalStrength = null;
|
2012-08-15 18:36:56 -07:00
|
|
|
} else {
|
2013-07-03 20:48:48 -07:00
|
|
|
voiceInfo.cell = newInfo.cell;
|
2012-08-15 18:36:56 -07:00
|
|
|
}
|
|
|
|
|
2012-08-07 12:11:48 -07:00
|
|
|
if (!newInfo.batch) {
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.sendMobileConnectionMessage("RIL:VoiceInfoChanged",
|
|
|
|
this.clientId, voiceInfo);
|
2012-06-19 15:52:06 -07:00
|
|
|
}
|
2012-04-19 14:33:25 -07:00
|
|
|
},
|
|
|
|
|
2012-08-07 12:11:48 -07:00
|
|
|
updateDataConnection: function updateDataConnection(newInfo) {
|
|
|
|
let dataInfo = this.rilContext.data;
|
|
|
|
dataInfo.state = newInfo.state;
|
|
|
|
dataInfo.roaming = newInfo.roaming;
|
|
|
|
dataInfo.emergencyCallsOnly = newInfo.emergencyCallsOnly;
|
|
|
|
dataInfo.type = newInfo.type;
|
|
|
|
// For the data connection, the `connected` flag indicates whether
|
|
|
|
// there's an active data call.
|
2013-07-11 21:44:22 -07:00
|
|
|
let apnSetting = this.apnSettings.byType.default;
|
|
|
|
dataInfo.connected = false;
|
|
|
|
if (apnSetting) {
|
|
|
|
dataInfo.connected = (this.getDataCallStateByType("default") ==
|
|
|
|
RIL.GECKO_NETWORK_STATE_CONNECTED);
|
|
|
|
}
|
2012-08-07 12:11:48 -07:00
|
|
|
|
|
|
|
// Make sure we also reset the operator and signal strength information
|
|
|
|
// if we drop off the network.
|
2013-07-03 20:48:48 -07:00
|
|
|
if (newInfo.regState !== RIL.NETWORK_CREG_STATE_REGISTERED_HOME &&
|
|
|
|
newInfo.regState !== RIL.NETWORK_CREG_STATE_REGISTERED_ROAMING) {
|
|
|
|
dataInfo.cell = null;
|
2012-08-07 12:11:48 -07:00
|
|
|
dataInfo.network = null;
|
|
|
|
dataInfo.signalStrength = null;
|
|
|
|
dataInfo.relSignalStrength = null;
|
2012-08-15 18:36:56 -07:00
|
|
|
} else {
|
2013-07-03 20:48:48 -07:00
|
|
|
dataInfo.cell = newInfo.cell;
|
2012-08-15 18:36:56 -07:00
|
|
|
}
|
|
|
|
|
2012-08-07 12:11:48 -07:00
|
|
|
if (!newInfo.batch) {
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.sendMobileConnectionMessage("RIL:DataInfoChanged",
|
|
|
|
this.clientId, dataInfo);
|
2012-06-21 17:22:47 -07:00
|
|
|
}
|
2012-08-30 12:41:46 -07:00
|
|
|
this.updateRILNetworkInterface();
|
2012-04-19 14:33:25 -07:00
|
|
|
},
|
|
|
|
|
2012-09-25 12:22:38 -07:00
|
|
|
/**
|
|
|
|
* Handle data errors
|
|
|
|
*/
|
|
|
|
handleDataCallError: function handleDataCallError(message) {
|
2012-09-26 05:52:21 -07:00
|
|
|
// Notify data call error only for data APN
|
2013-07-11 21:44:22 -07:00
|
|
|
if (this.apnSettings.byType.default) {
|
|
|
|
let apnSetting = this.apnSettings.byType.default;
|
|
|
|
if (message.apn == apnSetting.apn &&
|
|
|
|
apnSetting.iface.inConnectedTypes("default")) {
|
|
|
|
gMessageManager.sendMobileConnectionMessage("RIL:DataError",
|
|
|
|
this.clientId, message);
|
|
|
|
}
|
2012-09-25 12:22:38 -07:00
|
|
|
}
|
|
|
|
|
2012-09-26 05:52:21 -07:00
|
|
|
this._deliverDataCallCallback("dataCallError", [message]);
|
2012-09-25 12:22:38 -07:00
|
|
|
},
|
|
|
|
|
2012-09-27 20:45:06 -07:00
|
|
|
_preferredNetworkType: null,
|
|
|
|
setPreferredNetworkType: function setPreferredNetworkType(value) {
|
|
|
|
let networkType = RIL.RIL_PREFERRED_NETWORK_TYPE_TO_GECKO.indexOf(value);
|
|
|
|
if (networkType < 0) {
|
|
|
|
networkType = (this._preferredNetworkType != null)
|
|
|
|
? RIL.RIL_PREFERRED_NETWORK_TYPE_TO_GECKO[this._preferredNetworkType]
|
|
|
|
: RIL.GECKO_PREFERRED_NETWORK_TYPE_DEFAULT;
|
|
|
|
gSettingsService.createLock().set("ril.radio.preferredNetworkType",
|
|
|
|
networkType, null);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (networkType == this._preferredNetworkType) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.worker.postMessage({rilMessageType: "setPreferredNetworkType",
|
|
|
|
networkType: networkType});
|
|
|
|
},
|
|
|
|
|
|
|
|
handleSetPreferredNetworkType: function handleSetPreferredNetworkType(message) {
|
|
|
|
if ((this._preferredNetworkType != null) && !message.success) {
|
|
|
|
gSettingsService.createLock().set("ril.radio.preferredNetworkType",
|
|
|
|
this._preferredNetworkType,
|
|
|
|
null);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
this._preferredNetworkType = message.networkType;
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) {
|
|
|
|
this.debug("_preferredNetworkType is now " +
|
|
|
|
RIL.RIL_PREFERRED_NETWORK_TYPE_TO_GECKO[this._preferredNetworkType]);
|
|
|
|
}
|
2012-09-27 20:45:06 -07:00
|
|
|
},
|
|
|
|
|
2012-12-03 18:41:39 -08:00
|
|
|
setCellBroadcastSearchList: function setCellBroadcastSearchList(newSearchListStr) {
|
|
|
|
if (newSearchListStr == this._cellBroadcastSearchListStr) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.worker.postMessage({
|
|
|
|
rilMessageType: "setCellBroadcastSearchList",
|
|
|
|
searchListStr: newSearchListStr
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
|
|
|
handleSetCellBroadcastSearchList: function handleSetCellBroadcastSearchList(message) {
|
|
|
|
if (message.rilRequestError != RIL.ERROR_SUCCESS) {
|
|
|
|
let lock = gSettingsService.createLock();
|
|
|
|
lock.set(kCellBroadcastSearchList, this._cellBroadcastSearchListStr, null);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
this._cellBroadcastSearchListStr = message.searchListStr;
|
|
|
|
},
|
|
|
|
|
2012-04-19 14:33:25 -07:00
|
|
|
handleSignalStrengthChange: function handleSignalStrengthChange(message) {
|
2012-08-07 12:11:48 -07:00
|
|
|
let voiceInfo = this.rilContext.voice;
|
2012-04-19 14:33:25 -07:00
|
|
|
// TODO CDMA, EVDO, LTE, etc. (see bug 726098)
|
2012-08-07 12:11:48 -07:00
|
|
|
if (voiceInfo.signalStrength != message.gsmDBM ||
|
|
|
|
voiceInfo.relSignalStrength != message.gsmRelative) {
|
|
|
|
voiceInfo.signalStrength = message.gsmDBM;
|
|
|
|
voiceInfo.relSignalStrength = message.gsmRelative;
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.sendMobileConnectionMessage("RIL:VoiceInfoChanged",
|
|
|
|
this.clientId, voiceInfo);
|
2012-08-07 12:11:48 -07:00
|
|
|
}
|
2012-04-19 14:33:25 -07:00
|
|
|
|
2012-08-07 12:11:48 -07:00
|
|
|
let dataInfo = this.rilContext.data;
|
|
|
|
if (dataInfo.signalStrength != message.gsmDBM ||
|
|
|
|
dataInfo.relSignalStrength != message.gsmRelative) {
|
|
|
|
dataInfo.signalStrength = message.gsmDBM;
|
|
|
|
dataInfo.relSignalStrength = message.gsmRelative;
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.sendMobileConnectionMessage("RIL:DataInfoChanged",
|
|
|
|
this.clientId, dataInfo);
|
2012-08-07 12:11:48 -07:00
|
|
|
}
|
2012-04-19 14:33:25 -07:00
|
|
|
},
|
|
|
|
|
2012-06-12 14:05:50 -07:00
|
|
|
networkChanged: function networkChanged(srcNetwork, destNetwork) {
|
|
|
|
return !destNetwork ||
|
|
|
|
destNetwork.longName != srcNetwork.longName ||
|
|
|
|
destNetwork.shortName != srcNetwork.shortName ||
|
|
|
|
destNetwork.mnc != srcNetwork.mnc ||
|
|
|
|
destNetwork.mcc != srcNetwork.mcc;
|
|
|
|
},
|
|
|
|
|
2012-04-19 14:33:25 -07:00
|
|
|
handleOperatorChange: function handleOperatorChange(message) {
|
2012-06-12 19:46:41 -07:00
|
|
|
let voice = this.rilContext.voice;
|
|
|
|
let data = this.rilContext.data;
|
2012-06-12 14:05:50 -07:00
|
|
|
|
|
|
|
if (this.networkChanged(message, voice.network)) {
|
2013-05-02 18:37:51 -07:00
|
|
|
// Update lastKnownNetwork
|
|
|
|
if (message.mcc && message.mnc) {
|
|
|
|
try {
|
|
|
|
Services.prefs.setCharPref("ril.lastKnownNetwork",
|
|
|
|
message.mcc + "-" + message.mnc);
|
|
|
|
} catch (e) {}
|
|
|
|
}
|
|
|
|
|
2012-06-12 14:05:50 -07:00
|
|
|
voice.network = message;
|
2013-01-27 19:41:34 -08:00
|
|
|
if (!message.batch) {
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.sendMobileConnectionMessage("RIL:VoiceInfoChanged",
|
|
|
|
this.clientId, voice);
|
2013-01-27 19:41:34 -08:00
|
|
|
}
|
2012-04-19 14:33:25 -07:00
|
|
|
}
|
2012-06-12 14:05:50 -07:00
|
|
|
|
|
|
|
if (this.networkChanged(message, data.network)) {
|
|
|
|
data.network = message;
|
2013-01-27 19:41:34 -08:00
|
|
|
if (!message.batch) {
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.sendMobileConnectionMessage("RIL:DataInfoChanged",
|
|
|
|
this.clientId, data);
|
2013-01-27 19:41:34 -08:00
|
|
|
}
|
2012-04-19 14:33:25 -07:00
|
|
|
}
|
2012-03-12 16:46:08 -07:00
|
|
|
},
|
|
|
|
|
2012-05-23 22:12:07 -07:00
|
|
|
handleRadioStateChange: function handleRadioStateChange(message) {
|
2012-09-27 19:53:29 -07:00
|
|
|
this._changingRadioPower = false;
|
|
|
|
|
2012-05-23 22:12:07 -07:00
|
|
|
let newState = message.radioState;
|
2012-06-12 19:46:41 -07:00
|
|
|
if (this.rilContext.radioState == newState) {
|
2012-05-23 22:12:07 -07:00
|
|
|
return;
|
|
|
|
}
|
2012-06-12 19:46:41 -07:00
|
|
|
this.rilContext.radioState = newState;
|
2012-05-23 22:12:07 -07:00
|
|
|
//TODO Should we notify this change as a card state change?
|
|
|
|
|
2012-05-25 10:37:37 -07:00
|
|
|
this._ensureRadioState();
|
|
|
|
},
|
|
|
|
|
|
|
|
_ensureRadioState: function _ensureRadioState() {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) {
|
|
|
|
this.debug("Reported radio state is " + this.rilContext.radioState +
|
|
|
|
", desired radio enabled state is " + this._radioEnabled);
|
|
|
|
}
|
2012-05-25 10:37:37 -07:00
|
|
|
if (this._radioEnabled == null) {
|
|
|
|
// We haven't read the initial value from the settings DB yet.
|
|
|
|
// Wait for that.
|
|
|
|
return;
|
|
|
|
}
|
2012-09-05 13:00:06 -07:00
|
|
|
if (!this._sysMsgListenerReady) {
|
|
|
|
// The UI's system app isn't ready yet for us to receive any
|
|
|
|
// events (e.g. incoming SMS, etc.). Wait for that.
|
|
|
|
return;
|
|
|
|
}
|
2012-06-12 19:46:41 -07:00
|
|
|
if (this.rilContext.radioState == RIL.GECKO_RADIOSTATE_UNKNOWN) {
|
2012-05-25 10:37:37 -07:00
|
|
|
// We haven't received a radio state notification from the RIL
|
|
|
|
// yet. Wait for that.
|
|
|
|
return;
|
|
|
|
}
|
2012-09-27 19:53:29 -07:00
|
|
|
if (this._changingRadioPower) {
|
|
|
|
// We're changing the radio power currently, ignore any changes.
|
|
|
|
return;
|
|
|
|
}
|
2012-05-25 10:37:37 -07:00
|
|
|
|
2012-06-12 19:46:41 -07:00
|
|
|
if (this.rilContext.radioState == RIL.GECKO_RADIOSTATE_OFF &&
|
2012-05-23 22:12:07 -07:00
|
|
|
this._radioEnabled) {
|
|
|
|
this.setRadioEnabled(true);
|
|
|
|
}
|
2012-06-12 19:46:41 -07:00
|
|
|
if (this.rilContext.radioState == RIL.GECKO_RADIOSTATE_READY &&
|
2012-05-23 22:12:07 -07:00
|
|
|
!this._radioEnabled) {
|
|
|
|
this.setRadioEnabled(false);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2013-07-11 21:44:22 -07:00
|
|
|
/**
|
|
|
|
* This function will do the following steps:
|
|
|
|
* 1. Clear the old APN settings.
|
|
|
|
* 2. Combine APN, user name, and password as the key of byAPN{} and store
|
|
|
|
* corresponding APN setting into byApn{}, which makes it easiler to get
|
|
|
|
* the APN setting.
|
|
|
|
* 3. Use APN type as the index of byType{} and store the link of
|
|
|
|
* corresponding APN setting into byType{}, which makes it easier to get
|
|
|
|
* the APN setting via APN types.
|
|
|
|
*/
|
|
|
|
updateApnSettings: function updateApnSettings(allApnSettings) {
|
|
|
|
// TODO: Support multi-SIM, bug 799023.
|
|
|
|
let simNumber = 1;
|
|
|
|
for (let simId = 0; simId < simNumber; simId++) {
|
|
|
|
let thisSimApnSettings = allApnSettings[simId];
|
|
|
|
if (!thisSimApnSettings) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Clear old APN settings.
|
|
|
|
for each (let apnSetting in this.apnSettings.byAPN) {
|
|
|
|
// Clear all connections of this APN settings.
|
|
|
|
for each (let type in apnSetting.types) {
|
|
|
|
if (this.getDataCallStateByType(type) ==
|
|
|
|
RIL.GECKO_NETWORK_STATE_CONNECTED) {
|
|
|
|
this.deactivateDataCallByType(type);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (apnSetting.iface.name in gNetworkManager.networkInterfaces) {
|
|
|
|
gNetworkManager.unregisterNetworkInterface(apnSetting.iface);
|
|
|
|
}
|
|
|
|
this.unregisterDataCallCallback(apnSetting.iface);
|
|
|
|
delete apnSetting.iface;
|
|
|
|
}
|
|
|
|
this.apnSettings.byAPN = {};
|
|
|
|
this.apnSettings.byType = {};
|
|
|
|
|
|
|
|
// Create new APN settings.
|
|
|
|
for (let apnIndex = 0; thisSimApnSettings[apnIndex]; apnIndex++) {
|
|
|
|
let inputApnSetting = thisSimApnSettings[apnIndex];
|
|
|
|
if (!this.validateApnSetting(inputApnSetting)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Combine APN, user name, and password as the key of byAPN{} to get
|
|
|
|
// the corresponding APN setting.
|
|
|
|
let apnKey = inputApnSetting.apn + (inputApnSetting.user || '') +
|
|
|
|
(inputApnSetting.password || '');
|
|
|
|
if (!this.apnSettings.byAPN[apnKey]) {
|
|
|
|
this.apnSettings.byAPN[apnKey] = {};
|
|
|
|
this.apnSettings.byAPN[apnKey] = inputApnSetting;
|
|
|
|
this.apnSettings.byAPN[apnKey].iface =
|
|
|
|
new RILNetworkInterface(this, this.apnSettings.byAPN[apnKey]);
|
|
|
|
} else {
|
|
|
|
this.apnSettings.byAPN[apnKey].types.push(inputApnSetting.types);
|
|
|
|
}
|
|
|
|
for each (let type in inputApnSetting.types) {
|
|
|
|
this.apnSettings.byType[type] = {};
|
|
|
|
this.apnSettings.byType[type] = this.apnSettings.byAPN[apnKey];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check if we get all necessary APN data.
|
|
|
|
*/
|
|
|
|
validateApnSetting: function validateApnSetting(apnSetting) {
|
|
|
|
return (apnSetting &&
|
|
|
|
apnSetting.apn &&
|
|
|
|
apnSetting.types &&
|
|
|
|
apnSetting.types.length);
|
|
|
|
},
|
|
|
|
|
2012-08-01 07:54:04 -07:00
|
|
|
updateRILNetworkInterface: function updateRILNetworkInterface() {
|
2013-07-11 21:44:22 -07:00
|
|
|
let apnSetting = this.apnSettings.byType.default;
|
|
|
|
if (!this.validateApnSetting(apnSetting)) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) {
|
2013-07-11 21:44:22 -07:00
|
|
|
this.debug("We haven't gotten completely the APN data.");
|
2013-07-02 02:36:58 -07:00
|
|
|
}
|
2012-08-01 07:54:04 -07:00
|
|
|
return;
|
2013-01-23 01:40:45 -08:00
|
|
|
}
|
2012-08-01 07:54:04 -07:00
|
|
|
|
2013-01-23 01:40:45 -08:00
|
|
|
// This check avoids data call connection if the radio is not ready
|
|
|
|
// yet after toggling off airplane mode.
|
2012-08-01 07:54:04 -07:00
|
|
|
if (this.rilContext.radioState != RIL.GECKO_RADIOSTATE_READY) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) {
|
|
|
|
this.debug("RIL is not ready for data connection: radio's not ready");
|
|
|
|
}
|
2013-01-23 01:40:45 -08:00
|
|
|
return;
|
2012-08-01 07:54:04 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// We only watch at "ril.data.enabled" flag changes for connecting or
|
|
|
|
// disconnecting the data call. If the value of "ril.data.enabled" is
|
|
|
|
// true and any of the remaining flags change the setting application
|
|
|
|
// should turn this flag to false and then to true in order to reload
|
|
|
|
// the new values and reconnect the data call.
|
2013-07-11 21:44:22 -07:00
|
|
|
if (this.dataCallSettings.oldEnabled == this.dataCallSettings.enabled) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) {
|
|
|
|
this.debug("No changes for ril.data.enabled flag. Nothing to do.");
|
|
|
|
}
|
2012-08-01 07:54:04 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-06-27 18:46:00 -07:00
|
|
|
let defaultDataCallState = this.getDataCallStateByType("default");
|
|
|
|
if (defaultDataCallState == RIL.GECKO_NETWORK_STATE_CONNECTING ||
|
|
|
|
defaultDataCallState == RIL.GECKO_NETWORK_STATE_DISCONNECTING) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) {
|
|
|
|
this.debug("Nothing to do during connecting/disconnecting in progress.");
|
|
|
|
}
|
2012-09-26 06:05:28 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-08-30 12:41:46 -07:00
|
|
|
let dataInfo = this.rilContext.data;
|
|
|
|
let isRegistered =
|
|
|
|
dataInfo.state == RIL.GECKO_MOBILE_CONNECTION_STATE_REGISTERED;
|
|
|
|
let haveDataConnection =
|
|
|
|
dataInfo.type != RIL.GECKO_MOBILE_CONNECTION_STATE_UNKNOWN;
|
|
|
|
if (!isRegistered || !haveDataConnection) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) {
|
|
|
|
this.debug("RIL is not ready for data connection: Phone's not " +
|
|
|
|
"registered or doesn't have data connection.");
|
|
|
|
}
|
2012-08-30 12:41:46 -07:00
|
|
|
return;
|
|
|
|
}
|
2013-01-22 20:05:34 -08:00
|
|
|
let wifi_active = false;
|
|
|
|
if (gNetworkManager.active &&
|
|
|
|
gNetworkManager.active.type == Ci.nsINetworkInterface.NETWORK_TYPE_WIFI) {
|
|
|
|
wifi_active = true;
|
|
|
|
}
|
2013-01-08 08:21:14 -08:00
|
|
|
|
2013-06-27 18:46:00 -07:00
|
|
|
let defaultDataCallConnected = defaultDataCallState ==
|
|
|
|
RIL.GECKO_NETWORK_STATE_CONNECTED;
|
|
|
|
if (defaultDataCallConnected &&
|
2013-07-11 21:44:22 -07:00
|
|
|
(!this.dataCallSettings.enabled ||
|
|
|
|
(dataInfo.roaming && !this.dataCallSettings.roamingEnabled))) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("Data call settings: disconnect data call.");
|
2013-06-27 18:46:00 -07:00
|
|
|
this.deactivateDataCallByType("default");
|
2013-01-08 08:21:14 -08:00
|
|
|
return;
|
|
|
|
}
|
2013-07-11 21:44:22 -07:00
|
|
|
|
|
|
|
if (defaultDataCallConnected && wifi_active) {
|
|
|
|
if (DEBUG) this.debug("Disconnect data call when Wifi is connected.");
|
|
|
|
this.deactivateDataCallByType("default");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-06-27 18:46:00 -07:00
|
|
|
if (!this.dataCallSettings.enabled || defaultDataCallConnected) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("Data call settings: nothing to do.");
|
2013-01-08 08:21:14 -08:00
|
|
|
return;
|
|
|
|
}
|
2013-07-11 21:44:22 -07:00
|
|
|
if (dataInfo.roaming && !this.dataCallSettings.roamingEnabled) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("We're roaming, but data roaming is disabled.");
|
2012-08-30 12:41:46 -07:00
|
|
|
return;
|
|
|
|
}
|
2013-06-27 18:46:00 -07:00
|
|
|
if (wifi_active) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("Don't connect data call when Wifi is connected.");
|
2013-01-22 20:05:34 -08:00
|
|
|
return;
|
|
|
|
}
|
2012-10-04 18:19:21 -07:00
|
|
|
if (this._changingRadioPower) {
|
|
|
|
// We're changing the radio power currently, ignore any changes.
|
|
|
|
return;
|
|
|
|
}
|
2012-08-30 12:41:46 -07:00
|
|
|
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("Data call settings: connect data call.");
|
2013-06-27 18:46:00 -07:00
|
|
|
this.setupDataCallByType("default");
|
2012-08-01 07:54:04 -07:00
|
|
|
},
|
|
|
|
|
2012-01-09 14:28:47 -08:00
|
|
|
/**
|
|
|
|
* Track the active call and update the audio system as its state changes.
|
|
|
|
*/
|
|
|
|
_activeCall: null,
|
2012-12-02 19:25:28 -08:00
|
|
|
updateCallAudioState: function updateCallAudioState(call) {
|
|
|
|
switch (call.state) {
|
2013-03-06 01:53:23 -08:00
|
|
|
case nsITelephonyProvider.CALL_STATE_DIALING: // Fall through...
|
|
|
|
case nsITelephonyProvider.CALL_STATE_ALERTING:
|
|
|
|
case nsITelephonyProvider.CALL_STATE_CONNECTED:
|
2012-12-02 19:25:28 -08:00
|
|
|
call.isActive = true;
|
|
|
|
this._activeCall = call;
|
2012-01-11 16:20:16 -08:00
|
|
|
gAudioManager.phoneState = nsIAudioManager.PHONE_STATE_IN_CALL;
|
2012-09-27 23:03:43 -07:00
|
|
|
if (this.speakerEnabled) {
|
|
|
|
gAudioManager.setForceForUse(nsIAudioManager.USE_COMMUNICATION,
|
|
|
|
nsIAudioManager.FORCE_SPEAKER);
|
|
|
|
}
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) {
|
|
|
|
this.debug("Active call, put audio system into PHONE_STATE_IN_CALL: "
|
|
|
|
+ gAudioManager.phoneState);
|
|
|
|
}
|
2012-01-11 16:20:16 -08:00
|
|
|
break;
|
2013-03-06 01:53:23 -08:00
|
|
|
case nsITelephonyProvider.CALL_STATE_INCOMING:
|
2012-12-02 19:25:28 -08:00
|
|
|
call.isActive = false;
|
|
|
|
if (!this._activeCall) {
|
|
|
|
// We can change the phone state into RINGTONE only when there's
|
|
|
|
// no active call.
|
|
|
|
gAudioManager.phoneState = nsIAudioManager.PHONE_STATE_RINGTONE;
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) {
|
|
|
|
this.debug("Incoming call, put audio system into " +
|
|
|
|
"PHONE_STATE_RINGTONE: " + gAudioManager.phoneState);
|
|
|
|
}
|
2012-12-02 19:25:28 -08:00
|
|
|
}
|
|
|
|
break;
|
2013-03-06 01:53:23 -08:00
|
|
|
case nsITelephonyProvider.CALL_STATE_HELD: // Fall through...
|
|
|
|
case nsITelephonyProvider.CALL_STATE_DISCONNECTED:
|
2012-12-02 19:25:28 -08:00
|
|
|
call.isActive = false;
|
|
|
|
if (this._activeCall &&
|
|
|
|
this._activeCall.callIndex == call.callIndex) {
|
2013-01-29 19:16:31 -08:00
|
|
|
// Previously active call is not active now.
|
2012-12-02 19:25:28 -08:00
|
|
|
this._activeCall = null;
|
2013-01-29 19:16:31 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!this._activeCall) {
|
|
|
|
// No active call. Disable the audio.
|
2012-12-02 19:25:28 -08:00
|
|
|
gAudioManager.phoneState = nsIAudioManager.PHONE_STATE_NORMAL;
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) {
|
|
|
|
this.debug("No active call, put audio system into " +
|
|
|
|
"PHONE_STATE_NORMAL: " + gAudioManager.phoneState);
|
|
|
|
}
|
2012-12-02 19:25:28 -08:00
|
|
|
}
|
|
|
|
break;
|
2012-01-09 14:28:47 -08:00
|
|
|
}
|
2011-12-04 23:58:27 -08:00
|
|
|
},
|
|
|
|
|
2013-01-24 00:35:50 -08:00
|
|
|
_callRingWakeLock: null,
|
|
|
|
_callRingWakeLockTimer: null,
|
|
|
|
_cancelCallRingWakeLockTimer: function _cancelCallRingWakeLockTimer() {
|
|
|
|
if (this._callRingWakeLockTimer) {
|
|
|
|
this._callRingWakeLockTimer.cancel();
|
|
|
|
}
|
|
|
|
if (this._callRingWakeLock) {
|
|
|
|
this._callRingWakeLock.unlock();
|
|
|
|
this._callRingWakeLock = null;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2012-11-27 17:28:43 -08:00
|
|
|
/**
|
|
|
|
* Handle an incoming call.
|
|
|
|
*
|
|
|
|
* Not much is known about this call at this point, but it's enough
|
|
|
|
* to start bringing up the Phone app already.
|
|
|
|
*/
|
|
|
|
handleCallRing: function handleCallRing() {
|
2013-01-24 00:35:50 -08:00
|
|
|
if (!this._callRingWakeLock) {
|
|
|
|
this._callRingWakeLock = gPowerManagerService.newWakeLock("cpu");
|
|
|
|
}
|
|
|
|
if (!this._callRingWakeLockTimer) {
|
|
|
|
this._callRingWakeLockTimer =
|
|
|
|
Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
|
|
|
}
|
|
|
|
this._callRingWakeLockTimer
|
|
|
|
.initWithCallback(this._cancelCallRingWakeLockTimer.bind(this),
|
|
|
|
CALL_WAKELOCK_TIMEOUT, Ci.nsITimer.TYPE_ONE_SHOT);
|
|
|
|
|
2012-11-28 11:23:56 -08:00
|
|
|
gSystemMessenger.broadcastMessage("telephony-new-call", {});
|
2012-11-27 17:28:43 -08:00
|
|
|
},
|
|
|
|
|
2011-12-12 10:22:26 -08:00
|
|
|
/**
|
2012-01-09 14:28:47 -08:00
|
|
|
* Handle call state changes by updating our current state and the audio
|
|
|
|
* system.
|
2011-12-12 10:22:26 -08:00
|
|
|
*/
|
2012-01-09 14:28:47 -08:00
|
|
|
handleCallStateChange: function handleCallStateChange(call) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("handleCallStateChange: " + JSON.stringify(call));
|
2012-01-09 14:28:47 -08:00
|
|
|
call.state = convertRILCallState(call.state);
|
2012-08-30 20:06:42 -07:00
|
|
|
|
2013-03-06 01:53:23 -08:00
|
|
|
if (call.state == nsITelephonyProvider.CALL_STATE_DIALING) {
|
2012-11-28 11:23:56 -08:00
|
|
|
gSystemMessenger.broadcastMessage("telephony-new-call", {});
|
2012-08-30 20:06:42 -07:00
|
|
|
}
|
2012-12-02 19:25:28 -08:00
|
|
|
this.updateCallAudioState(call);
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.sendTelephonyMessage("RIL:CallStateChanged",
|
|
|
|
this.clientId, call);
|
2012-01-09 14:28:47 -08:00
|
|
|
},
|
2011-12-12 10:22:26 -08:00
|
|
|
|
2012-01-09 14:28:47 -08:00
|
|
|
/**
|
|
|
|
* Handle call disconnects by updating our current state and the audio system.
|
|
|
|
*/
|
2012-01-11 16:20:16 -08:00
|
|
|
handleCallDisconnected: function handleCallDisconnected(call) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("handleCallDisconnected: " + JSON.stringify(call));
|
2013-03-06 01:53:23 -08:00
|
|
|
call.state = nsITelephonyProvider.CALL_STATE_DISCONNECTED;
|
2012-12-18 05:54:18 -08:00
|
|
|
let duration = ("started" in call && typeof call.started == "number") ?
|
|
|
|
new Date().getTime() - call.started : 0;
|
|
|
|
let data = {
|
|
|
|
number: call.number,
|
|
|
|
duration: duration,
|
2013-05-08 03:39:05 -07:00
|
|
|
direction: call.isOutgoing ? "outgoing" : "incoming"
|
2012-12-18 05:54:18 -08:00
|
|
|
};
|
|
|
|
gSystemMessenger.broadcastMessage("telephony-call-ended", data);
|
2012-12-02 19:25:28 -08:00
|
|
|
this.updateCallAudioState(call);
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.sendTelephonyMessage("RIL:CallStateChanged",
|
|
|
|
this.clientId, call);
|
2012-01-09 14:28:47 -08:00
|
|
|
},
|
2011-12-12 10:22:26 -08:00
|
|
|
|
2012-01-09 14:28:47 -08:00
|
|
|
/**
|
|
|
|
* Handle calls delivered in response to a 'enumerateCalls' request.
|
|
|
|
*/
|
2012-08-16 20:46:34 -07:00
|
|
|
handleEnumerateCalls: function handleEnumerateCalls(options) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("handleEnumerateCalls: " + JSON.stringify(options));
|
2012-08-16 20:46:34 -07:00
|
|
|
for (let i in options.calls) {
|
|
|
|
options.calls[i].state = convertRILCallState(options.calls[i].state);
|
2012-12-26 23:23:46 -08:00
|
|
|
options.calls[i].isActive = this._activeCall ?
|
|
|
|
options.calls[i].callIndex == this._activeCall.callIndex : false;
|
2011-12-12 10:22:26 -08:00
|
|
|
}
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.sendRequestResults("RIL:EnumerateCalls", options);
|
2011-12-12 10:22:26 -08:00
|
|
|
},
|
|
|
|
|
2013-03-05 18:51:40 -08:00
|
|
|
handleReadIccContacts: function handleReadIccContacts(message) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("handleReadIccContacts: " + JSON.stringify(message));
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.sendRequestResults("RIL:ReadIccContacts", message);
|
2013-03-05 18:51:40 -08:00
|
|
|
},
|
|
|
|
|
2013-03-24 20:09:01 -07:00
|
|
|
handleUpdateIccContact: function handleUpdateIccContact(message) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("handleUpdateIccContact: " + JSON.stringify(message));
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.sendRequestResults("RIL:UpdateIccContact", message);
|
2013-03-05 18:12:23 -08:00
|
|
|
},
|
|
|
|
|
2013-02-25 01:27:26 -08:00
|
|
|
/**
|
|
|
|
* Open Logical UICC channel (aid) for Secure Element access
|
|
|
|
*/
|
|
|
|
handleIccOpenChannel: function handleIccOpenChannel(message) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("handleIccOpenChannel: " + JSON.stringify(message));
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.sendRequestResults("RIL:IccOpenChannel", message);
|
2013-02-25 01:27:26 -08:00
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Close Logical UICC channel
|
|
|
|
*/
|
|
|
|
handleIccCloseChannel: function handleIccCloseChannel(message) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("handleIccCloseChannel: " + JSON.stringify(message));
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.sendRequestResults("RIL:IccCloseChannel", message);
|
2013-02-25 01:27:26 -08:00
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Exchange APDU data on an open Logical UICC channel
|
|
|
|
*/
|
|
|
|
handleIccExchangeAPDU: function handleIccExchangeAPDU(message) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("handleIccExchangeAPDU: " + JSON.stringify(message));
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.sendRequestResults("RIL:IccExchangeAPDU", message);
|
2013-02-25 01:27:26 -08:00
|
|
|
},
|
|
|
|
|
2012-06-01 14:10:39 -07:00
|
|
|
/**
|
|
|
|
* Handle available networks returned by the 'getAvailableNetworks' request.
|
|
|
|
*/
|
|
|
|
handleGetAvailableNetworks: function handleGetAvailableNetworks(message) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("handleGetAvailableNetworks: " + JSON.stringify(message));
|
2012-06-01 14:10:39 -07:00
|
|
|
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.sendRequestResults("RIL:GetAvailableNetworks", message);
|
2012-06-01 14:10:39 -07:00
|
|
|
},
|
|
|
|
|
2012-06-19 15:52:06 -07:00
|
|
|
/**
|
|
|
|
* Update network selection mode
|
|
|
|
*/
|
|
|
|
updateNetworkSelectionMode: function updateNetworkSelectionMode(message) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("updateNetworkSelectionMode: " + JSON.stringify(message));
|
2013-03-28 19:56:07 -07:00
|
|
|
this.rilContext.networkSelectionMode = message.mode;
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.sendMobileConnectionMessage("RIL:NetworkSelectionModeChanged",
|
|
|
|
this.clientId, message);
|
2012-06-19 15:52:06 -07:00
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Handle "manual" network selection request.
|
|
|
|
*/
|
|
|
|
handleSelectNetwork: function handleSelectNetwork(message) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("handleSelectNetwork: " + JSON.stringify(message));
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.sendRequestResults("RIL:SelectNetwork", message);
|
2012-06-19 15:52:06 -07:00
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Handle "automatic" network selection request.
|
|
|
|
*/
|
|
|
|
handleSelectNetworkAuto: function handleSelectNetworkAuto(message) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("handleSelectNetworkAuto: " + JSON.stringify(message));
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.sendRequestResults("RIL:SelectNetworkAuto", message);
|
2012-06-19 15:52:06 -07:00
|
|
|
},
|
|
|
|
|
2012-05-14 21:13:06 -07:00
|
|
|
/**
|
|
|
|
* Handle call error.
|
|
|
|
*/
|
|
|
|
handleCallError: function handleCallError(message) {
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.sendTelephonyMessage("RIL:CallError",
|
|
|
|
this.clientId, message);
|
2012-05-14 21:13:06 -07:00
|
|
|
},
|
|
|
|
|
2012-06-03 22:04:28 -07:00
|
|
|
/**
|
|
|
|
* Handle WDP port push PDU. Constructor WDP bearer information and deliver
|
|
|
|
* to WapPushManager.
|
|
|
|
*
|
|
|
|
* @param message
|
|
|
|
* A SMS message.
|
|
|
|
*/
|
|
|
|
handleSmsWdpPortPush: function handleSmsWdpPortPush(message) {
|
|
|
|
if (message.encoding != RIL.PDU_DCS_MSG_CODING_8BITS_ALPHABET) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) {
|
|
|
|
this.debug("Got port addressed SMS but not encoded in 8-bit alphabet." +
|
|
|
|
" Drop!");
|
|
|
|
}
|
2012-06-03 22:04:28 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
let options = {
|
|
|
|
bearer: WAP.WDP_BEARER_GSM_SMS_GSM_MSISDN,
|
|
|
|
sourceAddress: message.sender,
|
|
|
|
sourcePort: message.header.originatorPort,
|
2013-01-10 08:18:54 -08:00
|
|
|
destinationAddress: this.rilContext.iccInfo.msisdn,
|
2012-06-03 22:04:28 -07:00
|
|
|
destinationPort: message.header.destinationPort,
|
|
|
|
};
|
|
|
|
WAP.WapPushManager.receiveWdpPDU(message.fullData, message.fullData.length,
|
|
|
|
0, options);
|
|
|
|
},
|
|
|
|
|
2013-03-22 05:16:43 -07:00
|
|
|
/**
|
|
|
|
* A helper to broadcast the system message to launch registered apps
|
|
|
|
* like Costcontrol, Notification and Message app... etc.
|
|
|
|
*
|
|
|
|
* @param aName
|
|
|
|
* The system message name.
|
|
|
|
* @param aDomMessage
|
|
|
|
* The nsIDOMMozSmsMessage object.
|
|
|
|
*/
|
|
|
|
broadcastSmsSystemMessage: function broadcastSmsSystemMessage(aName, aDomMessage) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("Broadcasting the SMS system message: " + aName);
|
2013-03-22 05:16:43 -07:00
|
|
|
|
|
|
|
// Sadly we cannot directly broadcast the aDomMessage object
|
|
|
|
// because the system message mechamism will rewrap the object
|
|
|
|
// based on the content window, which needs to know the properties.
|
|
|
|
gSystemMessenger.broadcastMessage(aName, {
|
|
|
|
type: aDomMessage.type,
|
|
|
|
id: aDomMessage.id,
|
2013-04-05 05:16:01 -07:00
|
|
|
threadId: aDomMessage.threadId,
|
2013-03-22 05:16:43 -07:00
|
|
|
delivery: aDomMessage.delivery,
|
|
|
|
deliveryStatus: aDomMessage.deliveryStatus,
|
|
|
|
sender: aDomMessage.sender,
|
|
|
|
receiver: aDomMessage.receiver,
|
|
|
|
body: aDomMessage.body,
|
|
|
|
messageClass: aDomMessage.messageClass,
|
2013-05-10 01:16:24 -07:00
|
|
|
timestamp: aDomMessage.timestamp,
|
2013-03-22 05:16:43 -07:00
|
|
|
read: aDomMessage.read
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
2012-04-23 16:43:32 -07:00
|
|
|
portAddressedSmsApps: null,
|
2011-12-23 21:02:52 -08:00
|
|
|
handleSmsReceived: function handleSmsReceived(message) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("handleSmsReceived: " + JSON.stringify(message));
|
2012-04-23 16:43:32 -07:00
|
|
|
|
2012-06-03 22:04:28 -07:00
|
|
|
// FIXME: Bug 737202 - Typed arrays become normal arrays when sent to/from workers
|
|
|
|
if (message.encoding == RIL.PDU_DCS_MSG_CODING_8BITS_ALPHABET) {
|
|
|
|
message.fullData = new Uint8Array(message.fullData);
|
|
|
|
}
|
|
|
|
|
2012-04-23 16:43:32 -07:00
|
|
|
// Dispatch to registered handler if application port addressing is
|
|
|
|
// available. Note that the destination port can possibly be zero when
|
|
|
|
// representing a UDP/TCP port.
|
2012-04-25 19:34:18 -07:00
|
|
|
if (message.header && message.header.destinationPort != null) {
|
2012-04-23 16:43:32 -07:00
|
|
|
let handler = this.portAddressedSmsApps[message.header.destinationPort];
|
|
|
|
if (handler) {
|
|
|
|
handler(message);
|
|
|
|
}
|
2013-02-17 23:11:13 -08:00
|
|
|
return true;
|
2012-04-23 16:43:32 -07:00
|
|
|
}
|
|
|
|
|
2012-04-23 16:43:32 -07:00
|
|
|
if (message.encoding == RIL.PDU_DCS_MSG_CODING_8BITS_ALPHABET) {
|
|
|
|
// Don't know how to handle binary data yet.
|
2013-02-17 23:11:13 -08:00
|
|
|
return true;
|
2012-04-23 16:43:32 -07:00
|
|
|
}
|
|
|
|
|
2013-02-08 02:45:04 -08:00
|
|
|
message.type = "sms";
|
|
|
|
message.sender = message.sender || null;
|
2013-07-02 02:36:47 -07:00
|
|
|
message.receiver = this.getMsisdn();
|
2013-02-08 02:45:04 -08:00
|
|
|
message.body = message.fullBody = message.fullBody || null;
|
2013-04-16 01:52:16 -07:00
|
|
|
message.timestamp = Date.now();
|
2013-02-08 02:45:04 -08:00
|
|
|
|
2013-07-29 15:50:22 -07:00
|
|
|
if (gSmsService.isSilentNumber(message.sender)) {
|
|
|
|
message.id = -1;
|
|
|
|
message.threadId = 0;
|
|
|
|
message.delivery = DOM_MOBILE_MESSAGE_DELIVERY_RECEIVED;
|
|
|
|
message.deliveryStatus = RIL.GECKO_SMS_DELIVERY_STATUS_SUCCESS;
|
|
|
|
message.read = false;
|
|
|
|
|
|
|
|
let domMessage =
|
|
|
|
gMobileMessageService.createSmsMessage(message.id,
|
|
|
|
message.threadId,
|
|
|
|
message.delivery,
|
|
|
|
message.deliveryStatus,
|
|
|
|
message.sender,
|
|
|
|
message.receiver,
|
|
|
|
message.body,
|
|
|
|
message.messageClass,
|
|
|
|
message.timestamp,
|
|
|
|
message.read);
|
|
|
|
|
|
|
|
Services.obs.notifyObservers(domMessage,
|
|
|
|
kSilentSmsReceivedObserverTopic,
|
|
|
|
null);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-07-18 20:27:08 -07:00
|
|
|
// TODO: Bug #768441
|
|
|
|
// For now we don't store indicators persistently. When the mwi.discard
|
|
|
|
// flag is false, we'll need to persist the indicator to EFmwis.
|
|
|
|
// See TS 23.040 9.2.3.24.2
|
|
|
|
|
|
|
|
let mwi = message.mwi;
|
|
|
|
if (mwi) {
|
2013-02-08 02:45:04 -08:00
|
|
|
mwi.returnNumber = message.sender;
|
|
|
|
mwi.returnMessage = message.fullBody;
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.sendVoicemailMessage("RIL:VoicemailNotification",
|
|
|
|
this.clientId, mwi);
|
2013-02-17 23:11:13 -08:00
|
|
|
return true;
|
2012-07-18 20:27:08 -07:00
|
|
|
}
|
|
|
|
|
2013-03-07 19:46:16 -08:00
|
|
|
let notifyReceived = function notifyReceived(rv, domMessage) {
|
2013-01-23 01:40:45 -08:00
|
|
|
let success = Components.isSuccessCode(rv);
|
|
|
|
|
|
|
|
// Acknowledge the reception of the SMS.
|
|
|
|
message.rilMessageType = "ackSMS";
|
|
|
|
if (!success) {
|
|
|
|
message.result = RIL.PDU_FCS_MEMORY_CAPACITY_EXCEEDED;
|
|
|
|
}
|
|
|
|
this.worker.postMessage(message);
|
|
|
|
|
|
|
|
if (!success) {
|
|
|
|
// At this point we could send a message to content to notify the user
|
|
|
|
// that storing an incoming SMS failed, most likely due to a full disk.
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) {
|
|
|
|
this.debug("Could not store SMS " + message.id + ", error code " + rv);
|
|
|
|
}
|
2013-01-23 01:40:45 -08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-03-22 05:16:43 -07:00
|
|
|
this.broadcastSmsSystemMessage("sms-received", domMessage);
|
2013-03-07 19:46:16 -08:00
|
|
|
Services.obs.notifyObservers(domMessage, kSmsReceivedObserverTopic, null);
|
2013-01-23 01:40:45 -08:00
|
|
|
}.bind(this);
|
|
|
|
|
2012-10-31 02:10:48 -07:00
|
|
|
if (message.messageClass != RIL.GECKO_SMS_MESSAGE_CLASSES[RIL.PDU_DCS_MSG_CLASS_0]) {
|
2013-02-08 02:45:04 -08:00
|
|
|
message.id = gMobileMessageDatabaseService.saveReceivedMessage(message,
|
|
|
|
notifyReceived);
|
2013-01-23 01:40:45 -08:00
|
|
|
} else {
|
|
|
|
message.id = -1;
|
2013-04-05 05:16:01 -07:00
|
|
|
message.threadId = 0;
|
2013-03-01 00:38:47 -08:00
|
|
|
message.delivery = DOM_MOBILE_MESSAGE_DELIVERY_RECEIVED;
|
2013-02-08 02:45:04 -08:00
|
|
|
message.deliveryStatus = RIL.GECKO_SMS_DELIVERY_STATUS_SUCCESS;
|
|
|
|
message.read = false;
|
|
|
|
|
2013-03-07 19:46:16 -08:00
|
|
|
let domMessage =
|
|
|
|
gMobileMessageService.createSmsMessage(message.id,
|
2013-04-05 05:16:01 -07:00
|
|
|
message.threadId,
|
2013-03-07 19:46:16 -08:00
|
|
|
message.delivery,
|
|
|
|
message.deliveryStatus,
|
|
|
|
message.sender,
|
|
|
|
message.receiver,
|
|
|
|
message.body,
|
|
|
|
message.messageClass,
|
|
|
|
message.timestamp,
|
|
|
|
message.read);
|
|
|
|
|
|
|
|
notifyReceived(Cr.NS_OK, domMessage);
|
2013-01-23 01:40:45 -08:00
|
|
|
}
|
2013-02-17 23:11:13 -08:00
|
|
|
|
|
|
|
// SMS ACK will be sent in notifyReceived. Return false here.
|
|
|
|
return false;
|
2011-12-23 21:02:52 -08:00
|
|
|
},
|
|
|
|
|
2012-04-05 14:16:56 -07:00
|
|
|
/**
|
|
|
|
* Local storage for sent SMS messages.
|
|
|
|
*/
|
|
|
|
_sentSmsEnvelopes: null,
|
|
|
|
createSmsEnvelope: function createSmsEnvelope(options) {
|
|
|
|
let i;
|
|
|
|
for (i = 1; this._sentSmsEnvelopes[i]; i++) {
|
|
|
|
// Do nothing.
|
|
|
|
}
|
|
|
|
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("createSmsEnvelope: assigned " + i);
|
2012-04-05 14:16:56 -07:00
|
|
|
this._sentSmsEnvelopes[i] = options;
|
2012-11-06 13:29:30 -08:00
|
|
|
return i;
|
2012-04-05 14:16:56 -07:00
|
|
|
},
|
|
|
|
|
2012-02-19 15:44:29 -08:00
|
|
|
handleSmsSent: function handleSmsSent(message) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("handleSmsSent: " + JSON.stringify(message));
|
2012-04-05 14:16:56 -07:00
|
|
|
|
|
|
|
let options = this._sentSmsEnvelopes[message.envelopeId];
|
|
|
|
if (!options) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-07-29 15:50:22 -07:00
|
|
|
if (options.silent) {
|
|
|
|
// There is no way to modify nsIDOMMozSmsMessage attributes as they are
|
|
|
|
// read only so we just create a new sms instance to send along with
|
|
|
|
// the notification.
|
|
|
|
let sms = options.sms;
|
|
|
|
options.request.notifyMessageSent(
|
|
|
|
gMobileMessageService.createSmsMessage(sms.id,
|
|
|
|
sms.threadId,
|
|
|
|
DOM_MOBILE_MESSAGE_DELIVERY_SENT,
|
|
|
|
sms.deliveryStatus,
|
|
|
|
sms.sender,
|
|
|
|
sms.receiver,
|
|
|
|
sms.body,
|
|
|
|
sms.messageClass,
|
|
|
|
sms.timestamp,
|
|
|
|
sms.read));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-02-05 03:10:39 -08:00
|
|
|
gMobileMessageDatabaseService.setMessageDelivery(options.sms.id,
|
2013-03-08 23:22:17 -08:00
|
|
|
null,
|
2013-03-01 00:38:47 -08:00
|
|
|
DOM_MOBILE_MESSAGE_DELIVERY_SENT,
|
2013-02-05 03:10:39 -08:00
|
|
|
options.sms.deliveryStatus,
|
2013-03-07 19:46:16 -08:00
|
|
|
function notifyResult(rv, domMessage) {
|
2013-03-22 04:29:25 -07:00
|
|
|
// TODO bug 832140 handle !Components.isSuccessCode(rv)
|
2013-03-22 05:16:43 -07:00
|
|
|
this.broadcastSmsSystemMessage("sms-sent", domMessage);
|
2013-01-23 01:40:45 -08:00
|
|
|
|
|
|
|
if (!options.requestStatusReport) {
|
|
|
|
// No more used if STATUS-REPORT not requested.
|
|
|
|
delete this._sentSmsEnvelopes[message.envelopeId];
|
|
|
|
} else {
|
2013-03-07 19:46:16 -08:00
|
|
|
options.sms = domMessage;
|
2013-01-23 01:40:45 -08:00
|
|
|
}
|
2012-04-05 14:16:56 -07:00
|
|
|
|
2013-03-07 19:46:16 -08:00
|
|
|
options.request.notifyMessageSent(domMessage);
|
|
|
|
Services.obs.notifyObservers(domMessage, kSmsSentObserverTopic, null);
|
2013-01-23 01:40:45 -08:00
|
|
|
}.bind(this));
|
2012-04-05 14:16:56 -07:00
|
|
|
},
|
|
|
|
|
2012-10-30 03:53:27 -07:00
|
|
|
handleSmsDelivery: function handleSmsDelivery(message) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("handleSmsDelivery: " + JSON.stringify(message));
|
2012-04-05 14:16:56 -07:00
|
|
|
|
|
|
|
let options = this._sentSmsEnvelopes[message.envelopeId];
|
|
|
|
if (!options) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
delete this._sentSmsEnvelopes[message.envelopeId];
|
|
|
|
|
2013-07-29 15:50:22 -07:00
|
|
|
if (options.silent) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-02-05 03:10:39 -08:00
|
|
|
gMobileMessageDatabaseService.setMessageDelivery(options.sms.id,
|
2013-03-08 23:22:17 -08:00
|
|
|
null,
|
2013-02-05 03:10:39 -08:00
|
|
|
options.sms.delivery,
|
|
|
|
message.deliveryStatus,
|
2013-03-07 19:46:16 -08:00
|
|
|
function notifyResult(rv, domMessage) {
|
2013-03-22 04:29:25 -07:00
|
|
|
// TODO bug 832140 handle !Components.isSuccessCode(rv)
|
2013-01-23 01:40:45 -08:00
|
|
|
let topic = (message.deliveryStatus == RIL.GECKO_SMS_DELIVERY_STATUS_SUCCESS)
|
|
|
|
? kSmsDeliverySuccessObserverTopic
|
|
|
|
: kSmsDeliveryErrorObserverTopic;
|
2013-03-07 19:46:16 -08:00
|
|
|
Services.obs.notifyObservers(domMessage, topic, null);
|
2013-02-08 02:45:04 -08:00
|
|
|
}.bind(this));
|
2012-02-19 15:44:29 -08:00
|
|
|
},
|
|
|
|
|
2012-04-05 14:16:56 -07:00
|
|
|
handleSmsSendFailed: function handleSmsSendFailed(message) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("handleSmsSendFailed: " + JSON.stringify(message));
|
2012-04-05 14:16:56 -07:00
|
|
|
|
|
|
|
let options = this._sentSmsEnvelopes[message.envelopeId];
|
|
|
|
if (!options) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
delete this._sentSmsEnvelopes[message.envelopeId];
|
|
|
|
|
2013-03-08 23:22:02 -08:00
|
|
|
let error = Ci.nsIMobileMessageCallback.UNKNOWN_ERROR;
|
2013-03-07 02:35:57 -08:00
|
|
|
switch (message.errorMsg) {
|
2012-04-05 14:16:56 -07:00
|
|
|
case RIL.ERROR_RADIO_NOT_AVAILABLE:
|
2013-03-08 23:22:02 -08:00
|
|
|
error = Ci.nsIMobileMessageCallback.NO_SIGNAL_ERROR;
|
2012-04-05 14:16:56 -07:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2013-07-29 15:50:22 -07:00
|
|
|
if (options.silent) {
|
|
|
|
options.request.notifySendMessageFailed(error);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-02-05 03:10:39 -08:00
|
|
|
gMobileMessageDatabaseService.setMessageDelivery(options.sms.id,
|
2013-03-08 23:22:17 -08:00
|
|
|
null,
|
2013-03-01 00:38:47 -08:00
|
|
|
DOM_MOBILE_MESSAGE_DELIVERY_ERROR,
|
2013-02-05 03:10:39 -08:00
|
|
|
RIL.GECKO_SMS_DELIVERY_STATUS_ERROR,
|
2013-03-07 19:46:16 -08:00
|
|
|
function notifyResult(rv, domMessage) {
|
2013-03-22 04:29:25 -07:00
|
|
|
// TODO bug 832140 handle !Components.isSuccessCode(rv)
|
2013-01-23 01:40:45 -08:00
|
|
|
options.request.notifySendMessageFailed(error);
|
2013-03-07 19:46:16 -08:00
|
|
|
Services.obs.notifyObservers(domMessage, kSmsFailedObserverTopic, null);
|
2013-02-08 02:45:04 -08:00
|
|
|
}.bind(this));
|
2012-04-05 14:16:56 -07:00
|
|
|
},
|
|
|
|
|
2012-01-17 17:34:09 -08:00
|
|
|
/**
|
|
|
|
* Handle data call state changes.
|
|
|
|
*/
|
2012-02-10 11:27:38 -08:00
|
|
|
handleDataCallState: function handleDataCallState(datacall) {
|
2012-06-21 17:22:47 -07:00
|
|
|
let data = this.rilContext.data;
|
2013-07-11 21:44:22 -07:00
|
|
|
let apnSetting = this.apnSettings.byType.default;
|
|
|
|
let dataCallConnected =
|
|
|
|
(datacall.state == RIL.GECKO_NETWORK_STATE_CONNECTED);
|
|
|
|
if (apnSetting && datacall.ifname) {
|
|
|
|
if (dataCallConnected && datacall.apn == apnSetting.apn &&
|
|
|
|
apnSetting.iface.inConnectedTypes("default")) {
|
|
|
|
data.connected = dataCallConnected;
|
|
|
|
gMessageManager.sendMobileConnectionMessage("RIL:DataInfoChanged",
|
|
|
|
this.clientId, data);
|
|
|
|
data.apn = datacall.apn;
|
|
|
|
} else if (!dataCallConnected && datacall.apn == data.apn) {
|
|
|
|
data.connected = dataCallConnected;
|
|
|
|
delete data.apn;
|
|
|
|
gMessageManager.sendMobileConnectionMessage("RIL:DataInfoChanged",
|
|
|
|
this.clientId, data);
|
2013-06-27 18:46:00 -07:00
|
|
|
}
|
2012-06-21 17:22:47 -07:00
|
|
|
}
|
|
|
|
|
2012-01-17 17:34:09 -08:00
|
|
|
this._deliverDataCallCallback("dataCallStateChanged",
|
2012-06-21 22:53:12 -07:00
|
|
|
[datacall]);
|
2012-01-17 17:34:09 -08:00
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Handle data call list.
|
|
|
|
*/
|
|
|
|
handleDataCallList: function handleDataCallList(message) {
|
|
|
|
this._deliverDataCallCallback("receiveDataCallList",
|
2012-06-21 22:53:12 -07:00
|
|
|
[message.datacalls, message.datacalls.length]);
|
2012-01-17 17:34:09 -08:00
|
|
|
},
|
|
|
|
|
2013-01-25 02:06:24 -08:00
|
|
|
/**
|
|
|
|
* Set the setting value of "time.nitz.available".
|
|
|
|
*/
|
|
|
|
setNitzAvailable: function setNitzAvailable(value) {
|
|
|
|
gSettingsService.createLock().set(kTimeNitzAvailable, value, null,
|
|
|
|
"fromInternalSetting");
|
|
|
|
},
|
|
|
|
|
2012-09-27 23:02:57 -07:00
|
|
|
/**
|
2012-10-23 00:15:53 -07:00
|
|
|
* Set the NITZ message in our system time.
|
2012-09-27 23:02:57 -07:00
|
|
|
*/
|
2012-10-23 00:15:53 -07:00
|
|
|
setNitzTime: function setNitzTime(message) {
|
2012-09-27 23:02:57 -07:00
|
|
|
// To set the system clock time. Note that there could be a time diff
|
|
|
|
// between when the NITZ was received and when the time is actually set.
|
|
|
|
gTimeService.set(
|
|
|
|
message.networkTimeInMS + (Date.now() - message.receiveTimeInMS));
|
|
|
|
|
|
|
|
// To set the sytem timezone. Note that we need to convert the time zone
|
|
|
|
// value to a UTC repesentation string in the format of "UTC(+/-)hh:mm".
|
|
|
|
// Ex, time zone -480 is "UTC-08:00"; time zone 630 is "UTC+10:30".
|
|
|
|
//
|
|
|
|
// We can unapply the DST correction if we want the raw time zone offset:
|
|
|
|
// message.networkTimeZoneInMinutes -= message.networkDSTInMinutes;
|
|
|
|
if (message.networkTimeZoneInMinutes != (new Date()).getTimezoneOffset()) {
|
|
|
|
let absTimeZoneInMinutes = Math.abs(message.networkTimeZoneInMinutes);
|
|
|
|
let timeZoneStr = "UTC";
|
|
|
|
timeZoneStr += (message.networkTimeZoneInMinutes >= 0 ? "+" : "-");
|
|
|
|
timeZoneStr += ("0" + Math.floor(absTimeZoneInMinutes / 60)).slice(-2);
|
|
|
|
timeZoneStr += ":";
|
|
|
|
timeZoneStr += ("0" + absTimeZoneInMinutes % 60).slice(-2);
|
|
|
|
gSettingsService.createLock().set("time.timezone", timeZoneStr, null);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2012-10-23 00:15:53 -07:00
|
|
|
/**
|
|
|
|
* Handle the NITZ message.
|
|
|
|
*/
|
|
|
|
handleNitzTime: function handleNitzTime(message) {
|
2013-01-25 02:06:24 -08:00
|
|
|
// Got the NITZ info received from the ril_worker.
|
|
|
|
this.setNitzAvailable(true);
|
|
|
|
|
2012-10-23 00:15:53 -07:00
|
|
|
// Cache the latest NITZ message whenever receiving it.
|
|
|
|
this._lastNitzMessage = message;
|
|
|
|
|
|
|
|
// Set the received NITZ time if the setting is enabled.
|
|
|
|
if (this._nitzAutomaticUpdateEnabled) {
|
|
|
|
this.setNitzTime(message);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2013-03-24 20:09:01 -07:00
|
|
|
handleIccMbdn: function handleIccMbdn(message) {
|
2012-12-26 02:49:08 -08:00
|
|
|
let voicemailInfo = this.voicemailInfo;
|
2012-11-22 20:09:01 -08:00
|
|
|
|
2012-12-26 02:49:08 -08:00
|
|
|
voicemailInfo.number = message.number;
|
|
|
|
voicemailInfo.displayName = message.alphaId;
|
2012-11-22 20:09:01 -08:00
|
|
|
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.sendVoicemailMessage("RIL:VoicemailInfoChanged",
|
|
|
|
this.clientId, voicemailInfo);
|
2012-11-22 20:09:01 -08:00
|
|
|
},
|
|
|
|
|
2013-03-24 20:09:01 -07:00
|
|
|
handleIccInfoChange: function handleIccInfoChange(message) {
|
2013-01-10 08:18:54 -08:00
|
|
|
let oldIccInfo = this.rilContext.iccInfo;
|
|
|
|
this.rilContext.iccInfo = message;
|
|
|
|
|
|
|
|
let iccInfoChanged = !oldIccInfo ||
|
|
|
|
oldIccInfo.iccid != message.iccid ||
|
|
|
|
oldIccInfo.mcc != message.mcc ||
|
|
|
|
oldIccInfo.mnc != message.mnc ||
|
|
|
|
oldIccInfo.spn != message.spn ||
|
|
|
|
oldIccInfo.isDisplayNetworkNameRequired != message.isDisplayNetworkNameRequired ||
|
|
|
|
oldIccInfo.isDisplaySpnRequired != message.isDisplaySpnRequired ||
|
|
|
|
oldIccInfo.msisdn != message.msisdn;
|
2012-09-14 03:30:44 -07:00
|
|
|
if (!iccInfoChanged) {
|
2012-09-03 14:43:59 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
// RIL:IccInfoChanged corresponds to a DOM event that gets fired only
|
|
|
|
// when the MCC or MNC codes have changed.
|
2013-05-30 04:14:39 -07:00
|
|
|
gMessageManager.sendIccMessage("RIL:IccInfoChanged",
|
|
|
|
this.clientId, message);
|
2013-01-04 00:44:20 -08:00
|
|
|
|
2013-07-18 13:17:41 -07:00
|
|
|
// Update lastKnownSimMcc.
|
|
|
|
if (message.mcc) {
|
|
|
|
try {
|
|
|
|
Services.prefs.setCharPref("ril.lastKnownSimMcc",
|
|
|
|
message.mcc.toString());
|
|
|
|
} catch (e) {}
|
|
|
|
}
|
|
|
|
|
2013-05-02 18:37:51 -07:00
|
|
|
// Update lastKnownHomeNetwork.
|
|
|
|
if (message.mcc && message.mnc) {
|
|
|
|
try {
|
|
|
|
Services.prefs.setCharPref("ril.lastKnownHomeNetwork",
|
|
|
|
message.mcc + "-" + message.mnc);
|
|
|
|
} catch (e) {}
|
|
|
|
}
|
|
|
|
|
2013-01-04 00:44:20 -08:00
|
|
|
// If spn becomes available, we should check roaming again.
|
2013-01-10 08:18:54 -08:00
|
|
|
let oldSpn = oldIccInfo ? oldIccInfo.spn : null;
|
2013-01-08 04:40:00 -08:00
|
|
|
if (!oldSpn && message.spn) {
|
2013-01-04 00:44:20 -08:00
|
|
|
let voice = this.rilContext.voice;
|
|
|
|
let data = this.rilContext.data;
|
|
|
|
let voiceRoaming = voice.roaming;
|
|
|
|
let dataRoaming = data.roaming;
|
|
|
|
this.checkRoamingBetweenOperators(voice);
|
|
|
|
this.checkRoamingBetweenOperators(data);
|
|
|
|
if (voiceRoaming != voice.roaming) {
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.sendMobileConnectionMessage("RIL:VoiceInfoChanged",
|
|
|
|
this.clientId, voice);
|
2013-01-04 00:44:20 -08:00
|
|
|
}
|
|
|
|
if (dataRoaming != data.roaming) {
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.sendMobileConnectionMessage("RIL:DataInfoChanged",
|
|
|
|
this.clientId, data);
|
2013-01-04 00:44:20 -08:00
|
|
|
}
|
|
|
|
}
|
2012-09-03 14:43:59 -07:00
|
|
|
},
|
|
|
|
|
2013-03-24 20:09:01 -07:00
|
|
|
handleIccCardLockResult: function handleIccCardLockResult(message) {
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.sendRequestResults("RIL:CardLockResult", message);
|
2012-04-11 21:01:49 -07:00
|
|
|
},
|
|
|
|
|
Bug 875710: Added getCardLockRetryCount to nsIIccProvider, r=vyang, sr=mounir
This patch adds getCardLockRetryCount to nsIIccProvider and its
implementations. This method allows callers to query the number
of remaining tries for unlocking a SIM-card lock. Supported locks
are 'pin', 'puk', 'pin2', 'puk2', 'nck', 'cck', and 'spck'. The
call returns a DOM request that returns the retry count in its
success handler, or signals an appropriate error.
Reading the retry count is an optional feature and may not be
supported for all lock types. In this case the DOM request receives
and error with the name GECKO_ERROR_NOT_SUPPORTED. For an invalid
lock type, the error name is GECKO_ERROR_GENERIC_FAILURE.
getCardLockRetryCount replaces retryCount in nsIDOMMobileConnection,
which is now deprecated.
--HG--
extra : rebase_source : d1d11612f836652dca85f7c701f09e7af962e3b7
2013-07-09 07:06:05 -07:00
|
|
|
handleIccCardLockRetryCount: function handleIccCardLockRetryCount(message) {
|
|
|
|
gMessageManager.sendRequestResults("RIL:CardLockRetryCount", message);
|
|
|
|
},
|
|
|
|
|
2012-06-09 14:07:18 -07:00
|
|
|
handleUSSDReceived: function handleUSSDReceived(ussd) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("handleUSSDReceived " + JSON.stringify(ussd));
|
2012-12-16 04:25:02 -08:00
|
|
|
gSystemMessenger.broadcastMessage("ussd-received", ussd);
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.sendMobileConnectionMessage("RIL:USSDReceived",
|
|
|
|
this.clientId, ussd);
|
2012-06-09 14:07:18 -07:00
|
|
|
},
|
|
|
|
|
2012-10-05 07:08:55 -07:00
|
|
|
handleSendMMI: function handleSendMMI(message) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("handleSendMMI " + JSON.stringify(message));
|
2012-10-05 07:08:55 -07:00
|
|
|
let messageType = message.success ? "RIL:SendMMI:Return:OK" :
|
|
|
|
"RIL:SendMMI:Return:KO";
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.sendRequestResults(messageType, message);
|
2012-06-09 14:07:18 -07:00
|
|
|
},
|
|
|
|
|
2012-10-05 07:08:55 -07:00
|
|
|
handleCancelMMI: function handleCancelMMI(message) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("handleCancelMMI " + JSON.stringify(message));
|
2012-10-05 07:08:55 -07:00
|
|
|
let messageType = message.success ? "RIL:CancelMMI:Return:OK" :
|
|
|
|
"RIL:CancelMMI:Return:KO";
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.sendRequestResults(messageType, message);
|
2012-06-09 14:07:18 -07:00
|
|
|
},
|
|
|
|
|
2012-04-10 05:04:27 -07:00
|
|
|
handleStkProactiveCommand: function handleStkProactiveCommand(message) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("handleStkProactiveCommand " + JSON.stringify(message));
|
2012-08-30 19:00:13 -07:00
|
|
|
gSystemMessenger.broadcastMessage("icc-stkcommand", message);
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.sendIccMessage("RIL:StkCommand", this.clientId, message);
|
2012-04-10 05:04:27 -07:00
|
|
|
},
|
|
|
|
|
2012-10-31 06:58:39 -07:00
|
|
|
handleQueryCallForwardStatus: function handleQueryCallForwardStatus(message) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("handleQueryCallForwardStatus: " + JSON.stringify(message));
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.sendRequestResults("RIL:GetCallForwardingOption", message);
|
2012-10-31 06:58:39 -07:00
|
|
|
},
|
|
|
|
|
|
|
|
handleSetCallForward: function handleSetCallForward(message) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("handleSetCallForward: " + JSON.stringify(message));
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.sendMobileConnectionMessage("RIL:CfStateChanged",
|
|
|
|
this.clientId, message);
|
2013-01-25 10:45:23 -08:00
|
|
|
|
|
|
|
let messageType;
|
|
|
|
if (message.isSendMMI) {
|
|
|
|
messageType = message.success ? "RIL:SendMMI:Return:OK" :
|
|
|
|
"RIL:SendMMI:Return:KO";
|
|
|
|
} else {
|
|
|
|
messageType = "RIL:SetCallForwardingOption";
|
|
|
|
}
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.sendRequestResults(messageType, message);
|
2012-10-31 06:58:39 -07:00
|
|
|
},
|
|
|
|
|
2013-05-20 22:13:37 -07:00
|
|
|
handleQueryCallBarringStatus: function handleQueryCallBarringStatus(message) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("handleQueryCallBarringStatus: " + JSON.stringify(message));
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.sendRequestResults("RIL:GetCallBarringOption", message);
|
2013-05-20 22:13:37 -07:00
|
|
|
},
|
|
|
|
|
|
|
|
handleSetCallBarring: function handleSetCallBarring(message) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("handleSetCallBarring: " + JSON.stringify(message));
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.sendRequestResults("RIL:SetCallBarringOption", message);
|
2013-05-20 22:13:37 -07:00
|
|
|
},
|
|
|
|
|
2013-04-18 05:18:50 -07:00
|
|
|
handleQueryCallWaiting: function handleQueryCallWaiting(message) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("handleQueryCallWaiting: " + JSON.stringify(message));
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.sendRequestResults("RIL:GetCallWaitingOption", message);
|
2013-04-18 05:18:50 -07:00
|
|
|
},
|
|
|
|
|
|
|
|
handleSetCallWaiting: function handleSetCallWaiting(message) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("handleSetCallWaiting: " + JSON.stringify(message));
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.sendRequestResults("RIL:SetCallWaitingOption", message);
|
2013-04-18 05:18:50 -07:00
|
|
|
},
|
2013-06-07 00:32:24 -07:00
|
|
|
|
2013-07-17 14:18:29 -07:00
|
|
|
handleGetCLIR: function handleGetCLIR(message) {
|
|
|
|
if (DEBUG) this.debug("handleGetCLIR: " + JSON.stringify(message));
|
|
|
|
gMessageManager.sendRequestResults("RIL:GetCallingLineIdRestriction",
|
|
|
|
message);
|
|
|
|
},
|
|
|
|
|
|
|
|
handleSetCLIR: function handleSetCLIR(message) {
|
|
|
|
if (DEBUG) this.debug("handleSetCLIR: " + JSON.stringify(message));
|
2013-07-31 00:56:43 -07:00
|
|
|
let messageType;
|
|
|
|
if (message.isSendMMI) {
|
|
|
|
messageType = message.success ? "RIL:SendMMI:Return:OK" :
|
|
|
|
"RIL:SendMMI:Return:KO";
|
|
|
|
} else {
|
|
|
|
messageType = "RIL:SetCallingLineIdRestriction";
|
|
|
|
}
|
|
|
|
if (message.success) {
|
|
|
|
try {
|
|
|
|
Services.prefs.setIntPref(kClirModePreference, message.clirMode);
|
|
|
|
Services.prefs.savePrefFile(null);
|
|
|
|
if (DEBUG) {
|
|
|
|
this.debug(kClirModePreference + " pref is now " + message.clirMode);
|
|
|
|
}
|
|
|
|
} catch (e) {}
|
|
|
|
}
|
|
|
|
gMessageManager.sendRequestResults(messageType, message);
|
2013-07-17 14:18:29 -07:00
|
|
|
},
|
|
|
|
|
2013-06-10 00:47:03 -07:00
|
|
|
handleSetRoamingPreference: function handleSetRoamingPreference(message) {
|
|
|
|
if (DEBUG) this.debug("handleSetRoamingPreference: " + JSON.stringify(message));
|
|
|
|
gMessageManager.sendRequestResults("RIL:SetRoamingPreference", message);
|
|
|
|
},
|
|
|
|
|
|
|
|
handleQueryRoamingPreference: function handleQueryRoamingPreference(message) {
|
|
|
|
if (DEBUG) this.debug("handleQueryRoamingPreference: " + JSON.stringify(message));
|
|
|
|
gMessageManager.sendRequestResults("RIL:GetRoamingPreference", message);
|
|
|
|
},
|
|
|
|
|
2012-04-19 14:33:25 -07:00
|
|
|
// nsIObserver
|
2012-03-12 16:45:57 -07:00
|
|
|
|
2012-04-19 14:33:25 -07:00
|
|
|
observe: function observe(subject, topic, data) {
|
2012-04-24 13:46:42 -07:00
|
|
|
switch (topic) {
|
2012-09-05 13:00:06 -07:00
|
|
|
case kSysMsgListenerReadyObserverTopic:
|
|
|
|
Services.obs.removeObserver(this, kSysMsgListenerReadyObserverTopic);
|
|
|
|
this._sysMsgListenerReady = true;
|
|
|
|
this._ensureRadioState();
|
|
|
|
break;
|
2012-04-24 13:46:42 -07:00
|
|
|
case kMozSettingsChangedObserverTopic:
|
|
|
|
let setting = JSON.parse(data);
|
2013-01-25 02:06:24 -08:00
|
|
|
this.handleSettingsChange(setting.key, setting.value, setting.message);
|
2012-04-24 13:46:42 -07:00
|
|
|
break;
|
2013-06-07 00:32:24 -07:00
|
|
|
case kPrefenceChangedObserverTopic:
|
2013-06-27 22:08:52 -07:00
|
|
|
if (data === kCellBroadcastDisabled) {
|
2013-06-07 00:32:24 -07:00
|
|
|
let value = false;
|
|
|
|
try {
|
|
|
|
value = Services.prefs.getBoolPref(kCellBroadcastDisabled);
|
|
|
|
} catch(e) {}
|
|
|
|
this.worker.postMessage({
|
|
|
|
rilMessageType: "setCellBroadcastDisabled",
|
|
|
|
disabled: value
|
|
|
|
});
|
|
|
|
}
|
|
|
|
break;
|
2012-04-24 13:46:42 -07:00
|
|
|
case "xpcom-shutdown":
|
2013-01-24 00:35:50 -08:00
|
|
|
// Cancel the timer for the call-ring wake lock.
|
|
|
|
this._cancelCallRingWakeLockTimer();
|
2012-09-26 05:52:21 -07:00
|
|
|
// Shutdown all RIL network interfaces
|
2013-07-11 21:44:22 -07:00
|
|
|
for each (let apnSetting in this.apnSettings.byAPN) {
|
|
|
|
if (apnSetting.iface) {
|
|
|
|
apnSetting.iface.shutdown();
|
|
|
|
}
|
|
|
|
}
|
2012-04-24 13:46:42 -07:00
|
|
|
Services.obs.removeObserver(this, "xpcom-shutdown");
|
|
|
|
Services.obs.removeObserver(this, kMozSettingsChangedObserverTopic);
|
2012-10-23 00:15:53 -07:00
|
|
|
Services.obs.removeObserver(this, kSysClockChangeObserverTopic);
|
2013-06-06 00:28:59 -07:00
|
|
|
Services.obs.removeObserver(this, kScreenStateChangedTopic);
|
2013-06-07 00:32:24 -07:00
|
|
|
Services.prefs.removeObserver(kCellBroadcastDisabled, this);
|
2012-10-23 00:15:53 -07:00
|
|
|
break;
|
|
|
|
case kSysClockChangeObserverTopic:
|
|
|
|
if (this._lastNitzMessage) {
|
|
|
|
this._lastNitzMessage.receiveTimeInMS += parseInt(data, 10);
|
|
|
|
}
|
2012-04-24 13:46:42 -07:00
|
|
|
break;
|
2013-06-06 00:28:59 -07:00
|
|
|
case kScreenStateChangedTopic:
|
|
|
|
this.setScreenState(data);
|
|
|
|
break;
|
2012-04-19 14:33:25 -07:00
|
|
|
}
|
2012-03-12 16:45:57 -07:00
|
|
|
},
|
|
|
|
|
2012-09-05 13:00:06 -07:00
|
|
|
// Flag to determine whether the UI's system app is ready to receive
|
|
|
|
// events yet.
|
|
|
|
_sysMsgListenerReady: false,
|
2012-05-23 22:12:07 -07:00
|
|
|
|
|
|
|
// Flag to determine the radio state to start with when we boot up. It
|
|
|
|
// corresponds to the 'ril.radio.disabled' setting from the UI.
|
|
|
|
_radioEnabled: null,
|
|
|
|
|
2012-09-27 19:53:29 -07:00
|
|
|
// Flag to ignore any radio power change requests during We're changing
|
|
|
|
// the radio power.
|
|
|
|
_changingRadioPower: false,
|
2013-01-23 01:40:45 -08:00
|
|
|
|
2013-07-11 21:44:22 -07:00
|
|
|
// Data calls setting.
|
2013-07-02 02:36:37 -07:00
|
|
|
dataCallSettings: null,
|
2013-07-11 21:44:22 -07:00
|
|
|
|
|
|
|
apnSettings: null,
|
2012-09-05 13:00:06 -07:00
|
|
|
|
2012-09-27 23:02:57 -07:00
|
|
|
// Flag to determine whether to use NITZ. It corresponds to the
|
|
|
|
// 'time.nitz.automatic-update.enabled' setting from the UI.
|
|
|
|
_nitzAutomaticUpdateEnabled: null,
|
2012-09-28 06:08:04 -07:00
|
|
|
|
2012-10-23 00:15:53 -07:00
|
|
|
// Remember the last NITZ message so that we can set the time based on
|
|
|
|
// the network immediately when users enable network-based time.
|
|
|
|
_lastNitzMessage: null,
|
|
|
|
|
2012-12-03 18:41:39 -08:00
|
|
|
// Cell Broadcast settings values.
|
|
|
|
_cellBroadcastSearchListStr: null,
|
|
|
|
|
2013-01-25 02:06:24 -08:00
|
|
|
handleSettingsChange: function handleSettingsChange(aName, aResult, aMessage) {
|
|
|
|
// Don't allow any content processes to modify the setting
|
|
|
|
// "time.nitz.available" except for the chrome process.
|
|
|
|
let isNitzAvailable = (this._lastNitzMessage !== null);
|
|
|
|
if (aName === kTimeNitzAvailable && aMessage !== "fromInternalSetting" &&
|
|
|
|
aResult !== isNitzAvailable) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) {
|
|
|
|
this.debug("Content processes cannot modify 'time.nitz.available'. Restore!");
|
|
|
|
}
|
2013-01-25 02:06:24 -08:00
|
|
|
// Restore the setting to the current value.
|
|
|
|
this.setNitzAvailable(isNitzAvailable);
|
|
|
|
}
|
|
|
|
|
|
|
|
this.handle(aName, aResult);
|
|
|
|
},
|
|
|
|
|
2012-09-27 23:02:57 -07:00
|
|
|
// nsISettingsServiceCallback
|
2012-05-23 22:12:07 -07:00
|
|
|
handle: function handle(aName, aResult) {
|
2012-08-01 07:54:04 -07:00
|
|
|
switch(aName) {
|
|
|
|
case "ril.radio.disabled":
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("'ril.radio.disabled' is now " + aResult);
|
2012-08-01 07:54:04 -07:00
|
|
|
this._radioEnabled = !aResult;
|
|
|
|
this._ensureRadioState();
|
|
|
|
break;
|
2012-09-27 20:45:06 -07:00
|
|
|
case "ril.radio.preferredNetworkType":
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("'ril.radio.preferredNetworkType' is now " + aResult);
|
2012-09-27 20:45:06 -07:00
|
|
|
this.setPreferredNetworkType(aResult);
|
|
|
|
break;
|
2012-08-01 07:54:04 -07:00
|
|
|
case "ril.data.enabled":
|
2013-07-11 21:44:22 -07:00
|
|
|
if (DEBUG) this.debug("'ril.data.enabled' is now " + aResult);
|
|
|
|
this.dataCallSettings.oldEnabled = this.dataCallSettings.enabled;
|
|
|
|
this.dataCallSettings.enabled = aResult;
|
|
|
|
this.updateRILNetworkInterface();
|
|
|
|
break;
|
2012-08-01 07:54:04 -07:00
|
|
|
case "ril.data.roaming_enabled":
|
2013-07-11 21:44:22 -07:00
|
|
|
if (DEBUG) this.debug("'ril.data.roaming_enabled' is now " + aResult);
|
|
|
|
this.dataCallSettings.roamingEnabled = aResult;
|
2012-08-01 07:54:04 -07:00
|
|
|
this.updateRILNetworkInterface();
|
|
|
|
break;
|
2013-07-11 21:44:22 -07:00
|
|
|
case "ril.data.apnSettings":
|
|
|
|
if (DEBUG) this.debug("'ril.data.apnSettings' is now " + JSON.stringify(aResult));
|
|
|
|
if (aResult) {
|
|
|
|
this.updateApnSettings(aResult);
|
|
|
|
this.updateRILNetworkInterface();
|
|
|
|
}
|
2012-09-26 05:57:37 -07:00
|
|
|
break;
|
2012-09-27 23:02:57 -07:00
|
|
|
case kTimeNitzAutomaticUpdateEnabled:
|
|
|
|
this._nitzAutomaticUpdateEnabled = aResult;
|
2012-10-23 00:15:53 -07:00
|
|
|
|
|
|
|
// Set the latest cached NITZ time if the setting is enabled.
|
|
|
|
if (this._nitzAutomaticUpdateEnabled && this._lastNitzMessage) {
|
|
|
|
this.setNitzTime(this._lastNitzMessage);
|
|
|
|
}
|
2012-09-27 23:02:57 -07:00
|
|
|
break;
|
2012-12-03 18:41:39 -08:00
|
|
|
case kCellBroadcastSearchList:
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) {
|
|
|
|
this.debug("'" + kCellBroadcastSearchList + "' is now " + aResult);
|
|
|
|
}
|
2012-12-03 18:41:39 -08:00
|
|
|
this.setCellBroadcastSearchList(aResult);
|
|
|
|
break;
|
2013-06-09 19:41:14 -07:00
|
|
|
}
|
2012-05-23 22:12:07 -07:00
|
|
|
},
|
2012-09-05 02:36:01 -07:00
|
|
|
|
2012-05-23 22:12:07 -07:00
|
|
|
handleError: function handleError(aErrorMessage) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("There was an error while reading RIL settings.");
|
2012-08-01 07:54:04 -07:00
|
|
|
|
|
|
|
// Default radio to on.
|
2012-05-23 22:12:07 -07:00
|
|
|
this._radioEnabled = true;
|
2012-05-25 10:37:37 -07:00
|
|
|
this._ensureRadioState();
|
2012-08-01 07:54:04 -07:00
|
|
|
|
2013-01-23 01:40:45 -08:00
|
|
|
// Clean data call setting.
|
2013-07-11 21:44:22 -07:00
|
|
|
this.dataCallSettings.oldEnabled = false;
|
2013-06-09 19:41:14 -07:00
|
|
|
this.dataCallSettings.enabled = false;
|
2013-07-11 21:44:22 -07:00
|
|
|
this.dataCallSettings.roamingEnabled = false;
|
|
|
|
this.apnSettings = {
|
|
|
|
byType: {},
|
|
|
|
byAPN: {},
|
|
|
|
};
|
2012-05-23 22:12:07 -07:00
|
|
|
},
|
|
|
|
|
2011-12-06 00:47:35 -08:00
|
|
|
// nsIRadioWorker
|
2011-12-04 23:58:27 -08:00
|
|
|
|
|
|
|
worker: null,
|
|
|
|
|
2013-07-02 02:36:37 -07:00
|
|
|
// nsIRadioInterface
|
2011-12-04 23:58:27 -08:00
|
|
|
|
2012-05-23 22:12:07 -07:00
|
|
|
setRadioEnabled: function setRadioEnabled(value) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("Setting radio power to " + value);
|
2012-09-27 19:53:29 -07:00
|
|
|
this._changingRadioPower = true;
|
2012-08-06 14:28:03 -07:00
|
|
|
this.worker.postMessage({rilMessageType: "setRadioPower", on: value});
|
2012-05-23 22:12:07 -07:00
|
|
|
},
|
|
|
|
|
2012-06-12 19:46:41 -07:00
|
|
|
rilContext: null,
|
2011-12-04 23:58:27 -08:00
|
|
|
|
2012-04-24 08:44:42 -07:00
|
|
|
// Handle phone functions of nsIRILContentHelper
|
|
|
|
|
2012-08-16 20:46:34 -07:00
|
|
|
enumerateCalls: function enumerateCalls(message) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("Requesting enumeration of calls for callback");
|
2012-08-16 20:46:34 -07:00
|
|
|
message.rilMessageType = "enumerateCalls";
|
|
|
|
this.worker.postMessage(message);
|
2012-04-24 08:44:42 -07:00
|
|
|
},
|
|
|
|
|
2013-03-08 07:08:55 -08:00
|
|
|
_validateNumber: function _validateNumber(number) {
|
|
|
|
// note: isPlainPhoneNumber also accepts USSD and SS numbers
|
|
|
|
if (PhoneNumberUtils.isPlainPhoneNumber(number)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.handleCallError({
|
|
|
|
callIndex: -1,
|
2013-03-26 21:37:01 -07:00
|
|
|
errorMsg: RIL.RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[RIL.CALL_FAIL_UNOBTAINABLE_NUMBER]
|
2013-03-08 07:08:55 -08:00
|
|
|
});
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) {
|
|
|
|
this.debug("Number '" + number + "' doesn't seem to be a viable number." +
|
|
|
|
" Drop.");
|
|
|
|
}
|
2013-03-08 07:08:55 -08:00
|
|
|
|
|
|
|
return false;
|
|
|
|
},
|
|
|
|
|
2011-12-04 23:58:27 -08:00
|
|
|
dial: function dial(number) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("Dialing " + number);
|
2013-03-08 07:08:55 -08:00
|
|
|
number = PhoneNumberUtils.normalize(number);
|
|
|
|
if (this._validateNumber(number)) {
|
|
|
|
this.worker.postMessage({rilMessageType: "dial",
|
|
|
|
number: number,
|
|
|
|
isDialEmergency: false});
|
2013-02-20 01:02:50 -08:00
|
|
|
}
|
2012-07-20 05:08:24 -07:00
|
|
|
},
|
|
|
|
|
|
|
|
dialEmergency: function dialEmergency(number) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("Dialing emergency " + number);
|
2013-03-08 07:08:55 -08:00
|
|
|
// we don't try to be too clever here, as the phone is probably in the
|
|
|
|
// locked state. Let's just check if it's a number without normalizing
|
|
|
|
if (this._validateNumber(number)) {
|
|
|
|
this.worker.postMessage({rilMessageType: "dial",
|
|
|
|
number: number,
|
|
|
|
isDialEmergency: true});
|
|
|
|
}
|
2011-12-04 23:58:27 -08:00
|
|
|
},
|
|
|
|
|
2011-12-06 22:57:19 -08:00
|
|
|
hangUp: function hangUp(callIndex) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("Hanging up call no. " + callIndex);
|
2012-08-06 14:28:03 -07:00
|
|
|
this.worker.postMessage({rilMessageType: "hangUp",
|
|
|
|
callIndex: callIndex});
|
2011-12-06 22:57:19 -08:00
|
|
|
},
|
2012-01-17 17:34:09 -08:00
|
|
|
|
2011-12-16 13:47:32 -08:00
|
|
|
startTone: function startTone(dtmfChar) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("Sending Tone for " + dtmfChar);
|
2012-08-06 14:28:03 -07:00
|
|
|
this.worker.postMessage({rilMessageType: "startTone",
|
|
|
|
dtmfChar: dtmfChar});
|
2011-12-16 13:47:32 -08:00
|
|
|
},
|
|
|
|
|
|
|
|
stopTone: function stopTone() {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("Stopping Tone");
|
2012-08-06 14:28:03 -07:00
|
|
|
this.worker.postMessage({rilMessageType: "stopTone"});
|
2011-12-16 13:47:32 -08:00
|
|
|
},
|
2011-12-06 22:57:19 -08:00
|
|
|
|
2012-01-09 14:28:47 -08:00
|
|
|
answerCall: function answerCall(callIndex) {
|
2012-08-06 14:28:03 -07:00
|
|
|
this.worker.postMessage({rilMessageType: "answerCall",
|
|
|
|
callIndex: callIndex});
|
2011-12-06 22:57:19 -08:00
|
|
|
},
|
|
|
|
|
2012-01-09 14:28:47 -08:00
|
|
|
rejectCall: function rejectCall(callIndex) {
|
2012-08-06 14:28:03 -07:00
|
|
|
this.worker.postMessage({rilMessageType: "rejectCall",
|
|
|
|
callIndex: callIndex});
|
2011-12-06 22:57:19 -08:00
|
|
|
},
|
2013-01-23 01:40:45 -08:00
|
|
|
|
2012-04-05 01:12:42 -07:00
|
|
|
holdCall: function holdCall(callIndex) {
|
2012-08-06 14:28:03 -07:00
|
|
|
this.worker.postMessage({rilMessageType: "holdCall",
|
|
|
|
callIndex: callIndex});
|
2012-04-05 01:12:42 -07:00
|
|
|
},
|
|
|
|
|
|
|
|
resumeCall: function resumeCall(callIndex) {
|
2012-08-06 14:28:03 -07:00
|
|
|
this.worker.postMessage({rilMessageType: "resumeCall",
|
|
|
|
callIndex: callIndex});
|
2012-04-05 01:12:42 -07:00
|
|
|
},
|
2011-12-06 22:57:19 -08:00
|
|
|
|
2012-06-01 14:10:39 -07:00
|
|
|
getAvailableNetworks: function getAvailableNetworks(requestId) {
|
2012-08-06 14:28:03 -07:00
|
|
|
this.worker.postMessage({rilMessageType: "getAvailableNetworks",
|
|
|
|
requestId: requestId});
|
2012-06-01 14:10:39 -07:00
|
|
|
},
|
|
|
|
|
2013-06-06 00:28:59 -07:00
|
|
|
setScreenState: function setScreenState(state) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("setScreenState: " + JSON.stringify(state));
|
2013-06-06 00:28:59 -07:00
|
|
|
this.worker.postMessage({
|
|
|
|
rilMessageType: "setScreenState",
|
|
|
|
on: (state === "on")
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
2012-10-05 07:08:55 -07:00
|
|
|
sendMMI: function sendMMI(message) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("SendMMI " + JSON.stringify(message));
|
2012-10-05 07:09:00 -07:00
|
|
|
message.rilMessageType = "sendMMI";
|
2012-06-09 14:07:18 -07:00
|
|
|
this.worker.postMessage(message);
|
|
|
|
},
|
|
|
|
|
2012-10-05 07:08:55 -07:00
|
|
|
cancelMMI: function cancelMMI(message) {
|
2012-10-05 07:09:00 -07:00
|
|
|
// Some MMI codes trigger radio operations, but unfortunately the RIL only
|
|
|
|
// supports cancelling USSD requests so far. Despite that, in order to keep
|
|
|
|
// the API uniformity, we are wrapping the cancelUSSD function within the
|
|
|
|
// cancelMMI funcion.
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("Cancel pending USSD");
|
2012-08-06 14:28:03 -07:00
|
|
|
message.rilMessageType = "cancelUSSD";
|
2012-06-09 14:07:18 -07:00
|
|
|
this.worker.postMessage(message);
|
|
|
|
},
|
|
|
|
|
2012-06-19 15:52:06 -07:00
|
|
|
selectNetworkAuto: function selectNetworkAuto(requestId) {
|
2012-08-06 14:28:03 -07:00
|
|
|
this.worker.postMessage({rilMessageType: "selectNetworkAuto",
|
|
|
|
requestId: requestId});
|
2012-06-19 15:52:06 -07:00
|
|
|
},
|
|
|
|
|
|
|
|
selectNetwork: function selectNetwork(message) {
|
2012-08-06 14:28:03 -07:00
|
|
|
message.rilMessageType = "selectNetwork";
|
2012-06-19 15:52:06 -07:00
|
|
|
this.worker.postMessage(message);
|
|
|
|
},
|
|
|
|
|
2012-04-10 05:04:27 -07:00
|
|
|
sendStkResponse: function sendStkResponse(message) {
|
|
|
|
message.rilMessageType = "sendStkTerminalResponse";
|
|
|
|
this.worker.postMessage(message);
|
|
|
|
},
|
|
|
|
|
|
|
|
sendStkMenuSelection: function sendStkMenuSelection(message) {
|
|
|
|
message.rilMessageType = "sendStkMenuSelection";
|
|
|
|
this.worker.postMessage(message);
|
2012-09-10 19:34:36 -07:00
|
|
|
},
|
|
|
|
|
2012-11-28 00:16:20 -08:00
|
|
|
sendStkTimerExpiration: function sendStkTimerExpiration(message) {
|
|
|
|
message.rilMessageType = "sendStkTimerExpiration";
|
|
|
|
this.worker.postMessage(message);
|
|
|
|
},
|
|
|
|
|
2012-09-10 19:34:36 -07:00
|
|
|
sendStkEventDownload: function sendStkEventDownload(message) {
|
|
|
|
message.rilMessageType = "sendStkEventDownload";
|
|
|
|
this.worker.postMessage(message);
|
2012-04-10 05:04:27 -07:00
|
|
|
},
|
2012-06-19 15:52:06 -07:00
|
|
|
|
2013-02-25 01:27:26 -08:00
|
|
|
iccOpenChannel: function iccOpenChannel(message) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("ICC Open Channel");
|
2013-02-25 01:27:26 -08:00
|
|
|
message.rilMessageType = "iccOpenChannel";
|
|
|
|
this.worker.postMessage(message);
|
|
|
|
},
|
|
|
|
|
|
|
|
iccCloseChannel: function iccCloseChannel(message) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("ICC Close Channel");
|
2013-02-25 01:27:26 -08:00
|
|
|
message.rilMessageType = "iccCloseChannel";
|
|
|
|
this.worker.postMessage(message);
|
|
|
|
},
|
|
|
|
|
|
|
|
iccExchangeAPDU: function iccExchangeAPDU(message) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("ICC Exchange APDU");
|
2013-02-25 01:27:26 -08:00
|
|
|
message.rilMessageType = "iccExchangeAPDU";
|
|
|
|
this.worker.postMessage(message);
|
|
|
|
},
|
|
|
|
|
2012-10-31 06:58:39 -07:00
|
|
|
setCallForwardingOption: function setCallForwardingOption(message) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("setCallForwardingOption: " + JSON.stringify(message));
|
2012-10-31 06:58:39 -07:00
|
|
|
message.rilMessageType = "setCallForward";
|
|
|
|
message.serviceClass = RIL.ICC_SERVICE_CLASS_VOICE;
|
|
|
|
this.worker.postMessage(message);
|
|
|
|
},
|
|
|
|
|
|
|
|
getCallForwardingOption: function getCallForwardingOption(message) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("getCallForwardingOption: " + JSON.stringify(message));
|
2012-10-31 06:58:39 -07:00
|
|
|
message.rilMessageType = "queryCallForwardStatus";
|
|
|
|
message.serviceClass = RIL.ICC_SERVICE_CLASS_NONE;
|
|
|
|
message.number = null;
|
|
|
|
this.worker.postMessage(message);
|
|
|
|
},
|
|
|
|
|
2013-05-20 22:13:37 -07:00
|
|
|
setCallBarringOption: function setCallBarringingOption(message) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("setCallBarringOption: " + JSON.stringify(message));
|
2013-05-20 22:13:37 -07:00
|
|
|
message.rilMessageType = "setCallBarring";
|
|
|
|
this.worker.postMessage(message);
|
|
|
|
},
|
|
|
|
|
|
|
|
getCallBarringOption: function getCallBarringOption(message) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("getCallBarringOption: " + JSON.stringify(message));
|
2013-05-20 22:13:37 -07:00
|
|
|
message.rilMessageType = "queryCallBarringStatus";
|
|
|
|
this.worker.postMessage(message);
|
|
|
|
},
|
|
|
|
|
2013-04-18 05:18:50 -07:00
|
|
|
setCallWaitingOption: function setCallWaitingOption(message) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("setCallWaitingOption: " + JSON.stringify(message));
|
2013-04-18 05:18:50 -07:00
|
|
|
message.rilMessageType = "setCallWaiting";
|
|
|
|
this.worker.postMessage(message);
|
|
|
|
},
|
|
|
|
|
|
|
|
getCallWaitingOption: function getCallWaitingOption(message) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("getCallWaitingOption: " + JSON.stringify(message));
|
2013-04-18 05:18:50 -07:00
|
|
|
message.rilMessageType = "queryCallWaiting";
|
|
|
|
this.worker.postMessage(message);
|
|
|
|
},
|
|
|
|
|
2013-07-17 14:18:29 -07:00
|
|
|
setCallingLineIdRestriction: function setCallingLineIdRestriction(message) {
|
|
|
|
if (DEBUG) {
|
|
|
|
this.debug("setCallingLineIdRestriction: " + JSON.stringify(message));
|
|
|
|
}
|
|
|
|
message.rilMessageType = "setCLIR";
|
|
|
|
this.worker.postMessage(message);
|
|
|
|
},
|
|
|
|
|
|
|
|
getCallingLineIdRestriction: function getCallingLineIdRestriction(message) {
|
|
|
|
if (DEBUG) {
|
|
|
|
this.debug("getCallingLineIdRestriction: " + JSON.stringify(message));
|
|
|
|
}
|
|
|
|
message.rilMessageType = "getCLIR";
|
|
|
|
this.worker.postMessage(message);
|
2013-06-10 00:47:03 -07:00
|
|
|
},
|
|
|
|
|
|
|
|
getRoamingPreference: function getRoamingPreference(message) {
|
|
|
|
if (DEBUG) this.debug("getRoamingPreference: " + JSON.stringify(message));
|
|
|
|
message.rilMessageType = "queryRoamingPreference";
|
|
|
|
this.worker.postMessage(message);
|
|
|
|
},
|
|
|
|
|
|
|
|
setRoamingPreference: function setRoamingPreference(message) {
|
|
|
|
if (DEBUG) this.debug("setRoamingPreference: " + JSON.stringify(message));
|
|
|
|
message.rilMessageType = "setRoamingPreference";
|
|
|
|
this.worker.postMessage(message);
|
2013-07-17 14:18:29 -07:00
|
|
|
},
|
|
|
|
|
2011-12-12 10:30:43 -08:00
|
|
|
get microphoneMuted() {
|
|
|
|
return gAudioManager.microphoneMuted;
|
|
|
|
},
|
|
|
|
set microphoneMuted(value) {
|
|
|
|
if (value == this.microphoneMuted) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
gAudioManager.microphoneMuted = value;
|
2012-05-14 21:13:06 -07:00
|
|
|
|
|
|
|
if (!this._activeCall) {
|
|
|
|
gAudioManager.phoneState = nsIAudioManager.PHONE_STATE_NORMAL;
|
|
|
|
}
|
2011-12-12 10:30:43 -08:00
|
|
|
},
|
|
|
|
|
|
|
|
get speakerEnabled() {
|
2012-01-09 14:28:47 -08:00
|
|
|
return (gAudioManager.getForceForUse(nsIAudioManager.USE_COMMUNICATION) ==
|
|
|
|
nsIAudioManager.FORCE_SPEAKER);
|
2011-12-12 10:30:43 -08:00
|
|
|
},
|
|
|
|
set speakerEnabled(value) {
|
|
|
|
if (value == this.speakerEnabled) {
|
|
|
|
return;
|
|
|
|
}
|
2012-01-09 14:28:47 -08:00
|
|
|
let force = value ? nsIAudioManager.FORCE_SPEAKER :
|
|
|
|
nsIAudioManager.FORCE_NONE;
|
2012-02-10 11:27:23 -08:00
|
|
|
gAudioManager.setForceForUse(nsIAudioManager.USE_COMMUNICATION, force);
|
2012-05-14 21:13:06 -07:00
|
|
|
|
|
|
|
if (!this._activeCall) {
|
|
|
|
gAudioManager.phoneState = nsIAudioManager.PHONE_STATE_NORMAL;
|
|
|
|
}
|
2011-12-12 10:30:43 -08:00
|
|
|
},
|
|
|
|
|
2012-03-16 16:47:21 -07:00
|
|
|
/**
|
|
|
|
* List of tuples of national language identifier pairs.
|
2012-03-16 16:57:41 -07:00
|
|
|
*
|
|
|
|
* TODO: Support static/runtime settings, see bug 733331.
|
2012-03-16 16:47:21 -07:00
|
|
|
*/
|
|
|
|
enabledGsmTableTuples: [
|
|
|
|
[RIL.PDU_NL_IDENTIFIER_DEFAULT, RIL.PDU_NL_IDENTIFIER_DEFAULT],
|
|
|
|
],
|
|
|
|
|
2012-03-16 16:57:41 -07:00
|
|
|
/**
|
|
|
|
* Use 16-bit reference number for concatenated outgoint messages.
|
|
|
|
*
|
|
|
|
* TODO: Support static/runtime settings, see bug 733331.
|
|
|
|
*/
|
|
|
|
segmentRef16Bit: false,
|
|
|
|
|
2012-03-16 16:59:35 -07:00
|
|
|
/**
|
|
|
|
* Get valid SMS concatenation reference number.
|
|
|
|
*/
|
|
|
|
_segmentRef: 0,
|
|
|
|
get nextSegmentRef() {
|
|
|
|
let ref = this._segmentRef++;
|
|
|
|
|
|
|
|
this._segmentRef %= (this.segmentRef16Bit ? 65535 : 255);
|
|
|
|
|
|
|
|
// 0 is not a valid SMS concatenation reference number.
|
|
|
|
return ref + 1;
|
|
|
|
},
|
|
|
|
|
2012-03-16 16:47:21 -07:00
|
|
|
/**
|
|
|
|
* Calculate encoded length using specified locking/single shift table
|
|
|
|
*
|
|
|
|
* @param message
|
|
|
|
* message string to be encoded.
|
|
|
|
* @param langTable
|
|
|
|
* locking shift table string.
|
|
|
|
* @param langShiftTable
|
|
|
|
* single shift table string.
|
2012-10-03 01:37:19 -07:00
|
|
|
* @param strict7BitEncoding
|
|
|
|
* Optional. Enable Latin characters replacement with corresponding
|
|
|
|
* ones in GSM SMS 7-bit default alphabet.
|
2012-03-16 16:47:21 -07:00
|
|
|
*
|
|
|
|
* @return encoded length in septets.
|
|
|
|
*
|
|
|
|
* @note that the algorithm used in this function must match exactly with
|
|
|
|
* GsmPDUHelper#writeStringAsSeptets.
|
|
|
|
*/
|
2012-10-03 01:37:19 -07:00
|
|
|
_countGsm7BitSeptets: function _countGsm7BitSeptets(message, langTable, langShiftTable, strict7BitEncoding) {
|
2012-03-16 16:47:21 -07:00
|
|
|
let length = 0;
|
|
|
|
for (let msgIndex = 0; msgIndex < message.length; msgIndex++) {
|
2012-10-03 01:37:19 -07:00
|
|
|
let c = message.charAt(msgIndex);
|
|
|
|
if (strict7BitEncoding) {
|
|
|
|
c = RIL.GSM_SMS_STRICT_7BIT_CHARMAP[c] || c;
|
|
|
|
}
|
|
|
|
|
|
|
|
let septet = langTable.indexOf(c);
|
2012-03-16 16:47:21 -07:00
|
|
|
|
|
|
|
// According to 3GPP TS 23.038, section 6.1.1 General notes, "The
|
|
|
|
// characters marked '1)' are not used but are displayed as a space."
|
|
|
|
if (septet == RIL.PDU_NL_EXTENDED_ESCAPE) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (septet >= 0) {
|
|
|
|
length++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2012-10-03 01:37:19 -07:00
|
|
|
septet = langShiftTable.indexOf(c);
|
2012-03-16 16:57:06 -07:00
|
|
|
if (septet < 0) {
|
2012-12-17 02:47:58 -08:00
|
|
|
if (!strict7BitEncoding) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Bug 816082, when strict7BitEncoding is enabled, we should replace
|
|
|
|
// characters that can't be encoded with GSM 7-Bit alphabets with '*'.
|
|
|
|
c = '*';
|
|
|
|
if (langTable.indexOf(c) >= 0) {
|
|
|
|
length++;
|
|
|
|
} else if (langShiftTable.indexOf(c) >= 0) {
|
|
|
|
length += 2;
|
|
|
|
} else {
|
|
|
|
// We can't even encode a '*' character with current configuration.
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
continue;
|
2012-03-16 16:47:21 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// According to 3GPP TS 23.038 B.2, "This code represents a control
|
|
|
|
// character and therefore must not be used for language specific
|
|
|
|
// characters."
|
|
|
|
if (septet == RIL.PDU_NL_RESERVED_CONTROL) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// The character is not found in locking shfit table, but could be
|
|
|
|
// encoded as <escape><char> with single shift table. Note that it's
|
|
|
|
// still possible for septet to has the value of PDU_NL_EXTENDED_ESCAPE,
|
|
|
|
// but we can display it as a space in this case as said in previous
|
|
|
|
// comment.
|
|
|
|
length += 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
return length;
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
2012-03-16 16:57:06 -07:00
|
|
|
* Calculate user data length of specified message string encoded in GSM 7Bit
|
|
|
|
* alphabets.
|
2012-03-16 16:47:21 -07:00
|
|
|
*
|
2012-03-16 16:57:06 -07:00
|
|
|
* @param message
|
|
|
|
* a message string to be encoded.
|
2012-10-03 01:37:19 -07:00
|
|
|
* @param strict7BitEncoding
|
|
|
|
* Optional. Enable Latin characters replacement with corresponding
|
|
|
|
* ones in GSM SMS 7-bit default alphabet.
|
2012-03-16 16:47:21 -07:00
|
|
|
*
|
2012-03-16 16:57:06 -07:00
|
|
|
* @return null or an options object with attributes `dcs`,
|
2012-03-16 16:59:35 -07:00
|
|
|
* `userDataHeaderLength`, `encodedFullBodyLength`, `langIndex`,
|
2012-03-16 16:57:41 -07:00
|
|
|
* `langShiftIndex`, `segmentMaxSeq` set.
|
2012-03-16 16:57:06 -07:00
|
|
|
*
|
|
|
|
* @see #_calculateUserDataLength().
|
2012-03-16 16:47:21 -07:00
|
|
|
*/
|
2012-10-03 01:37:19 -07:00
|
|
|
_calculateUserDataLength7Bit: function _calculateUserDataLength7Bit(message, strict7BitEncoding) {
|
2012-03-16 16:57:06 -07:00
|
|
|
let options = null;
|
2012-03-16 16:47:21 -07:00
|
|
|
let minUserDataSeptets = Number.MAX_VALUE;
|
|
|
|
for (let i = 0; i < this.enabledGsmTableTuples.length; i++) {
|
|
|
|
let [langIndex, langShiftIndex] = this.enabledGsmTableTuples[i];
|
|
|
|
|
|
|
|
const langTable = RIL.PDU_NL_LOCKING_SHIFT_TABLES[langIndex];
|
|
|
|
const langShiftTable = RIL.PDU_NL_SINGLE_SHIFT_TABLES[langShiftIndex];
|
|
|
|
|
2012-03-16 16:57:06 -07:00
|
|
|
let bodySeptets = this._countGsm7BitSeptets(message,
|
|
|
|
langTable,
|
2012-10-03 01:37:19 -07:00
|
|
|
langShiftTable,
|
|
|
|
strict7BitEncoding);
|
2012-03-16 16:47:21 -07:00
|
|
|
if (bodySeptets < 0) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
let headerLen = 0;
|
|
|
|
if (langIndex != RIL.PDU_NL_IDENTIFIER_DEFAULT) {
|
|
|
|
headerLen += 3; // IEI + len + langIndex
|
|
|
|
}
|
|
|
|
if (langShiftIndex != RIL.PDU_NL_IDENTIFIER_DEFAULT) {
|
|
|
|
headerLen += 3; // IEI + len + langShiftIndex
|
|
|
|
}
|
|
|
|
|
|
|
|
// Calculate full user data length, note the extra byte is for header len
|
|
|
|
let headerSeptets = Math.ceil((headerLen ? headerLen + 1 : 0) * 8 / 7);
|
2013-01-03 22:26:24 -08:00
|
|
|
let segmentSeptets = RIL.PDU_MAX_USER_DATA_7BIT;
|
|
|
|
if ((bodySeptets + headerSeptets) > segmentSeptets) {
|
|
|
|
headerLen += this.segmentRef16Bit ? 6 : 5;
|
2012-03-16 16:57:41 -07:00
|
|
|
headerSeptets = Math.ceil((headerLen + 1) * 8 / 7);
|
2013-01-03 22:26:24 -08:00
|
|
|
segmentSeptets -= headerSeptets;
|
2012-03-16 16:57:41 -07:00
|
|
|
}
|
|
|
|
|
2013-01-03 22:26:24 -08:00
|
|
|
let segments = Math.ceil(bodySeptets / segmentSeptets);
|
|
|
|
let userDataSeptets = bodySeptets + headerSeptets * segments;
|
2012-03-16 16:47:21 -07:00
|
|
|
if (userDataSeptets >= minUserDataSeptets) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
minUserDataSeptets = userDataSeptets;
|
|
|
|
|
2012-03-16 16:57:06 -07:00
|
|
|
options = {
|
|
|
|
dcs: RIL.PDU_DCS_MSG_CODING_7BITS_ALPHABET,
|
2012-03-16 16:59:35 -07:00
|
|
|
encodedFullBodyLength: bodySeptets,
|
2012-03-16 16:57:06 -07:00
|
|
|
userDataHeaderLength: headerLen,
|
|
|
|
langIndex: langIndex,
|
|
|
|
langShiftIndex: langShiftIndex,
|
2012-03-16 16:57:41 -07:00
|
|
|
segmentMaxSeq: segments,
|
2013-01-03 22:26:24 -08:00
|
|
|
segmentChars: segmentSeptets,
|
2012-03-16 16:57:06 -07:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
return options;
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Calculate user data length of specified message string encoded in UCS2.
|
|
|
|
*
|
|
|
|
* @param message
|
|
|
|
* a message string to be encoded.
|
|
|
|
*
|
|
|
|
* @return an options object with attributes `dcs`, `userDataHeaderLength`,
|
2012-03-16 16:59:35 -07:00
|
|
|
* `encodedFullBodyLength`, `segmentMaxSeq` set.
|
2012-03-16 16:57:06 -07:00
|
|
|
*
|
|
|
|
* @see #_calculateUserDataLength().
|
|
|
|
*/
|
|
|
|
_calculateUserDataLengthUCS2: function _calculateUserDataLengthUCS2(message) {
|
2012-03-16 16:57:41 -07:00
|
|
|
let bodyChars = message.length;
|
|
|
|
let headerLen = 0;
|
|
|
|
let headerChars = Math.ceil((headerLen ? headerLen + 1 : 0) / 2);
|
2013-01-03 22:26:24 -08:00
|
|
|
let segmentChars = RIL.PDU_MAX_USER_DATA_UCS2;
|
|
|
|
if ((bodyChars + headerChars) > segmentChars) {
|
|
|
|
headerLen += this.segmentRef16Bit ? 6 : 5;
|
2012-03-16 16:57:41 -07:00
|
|
|
headerChars = Math.ceil((headerLen + 1) / 2);
|
2013-01-03 22:26:24 -08:00
|
|
|
segmentChars -= headerChars;
|
2012-03-16 16:57:41 -07:00
|
|
|
}
|
|
|
|
|
2013-01-03 22:26:24 -08:00
|
|
|
let segments = Math.ceil(bodyChars / segmentChars);
|
|
|
|
|
2012-03-16 16:57:06 -07:00
|
|
|
return {
|
|
|
|
dcs: RIL.PDU_DCS_MSG_CODING_16BITS_ALPHABET,
|
2012-03-16 16:59:35 -07:00
|
|
|
encodedFullBodyLength: bodyChars * 2,
|
2012-03-16 16:57:41 -07:00
|
|
|
userDataHeaderLength: headerLen,
|
|
|
|
segmentMaxSeq: segments,
|
2013-01-03 22:26:24 -08:00
|
|
|
segmentChars: segmentChars,
|
2012-03-16 16:57:06 -07:00
|
|
|
};
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Calculate user data length and its encoding.
|
|
|
|
*
|
|
|
|
* @param message
|
|
|
|
* a message string to be encoded.
|
2012-10-03 01:37:19 -07:00
|
|
|
* @param strict7BitEncoding
|
|
|
|
* Optional. Enable Latin characters replacement with corresponding
|
|
|
|
* ones in GSM SMS 7-bit default alphabet.
|
2012-03-16 16:57:06 -07:00
|
|
|
*
|
|
|
|
* @return an options object with some or all of following attributes set:
|
|
|
|
*
|
|
|
|
* @param dcs
|
|
|
|
* Data coding scheme. One of the PDU_DCS_MSG_CODING_*BITS_ALPHABET
|
|
|
|
* constants.
|
|
|
|
* @param userDataHeaderLength
|
|
|
|
* Length of embedded user data header, in bytes. The whole header
|
|
|
|
* size will be userDataHeaderLength + 1; 0 for no header.
|
2012-03-16 16:59:35 -07:00
|
|
|
* @param encodedFullBodyLength
|
2012-03-16 16:57:06 -07:00
|
|
|
* Length of the message body when encoded with the given DCS. For
|
|
|
|
* UCS2, in bytes; for 7-bit, in septets.
|
|
|
|
* @param langIndex
|
|
|
|
* Table index used for normal 7-bit encoded character lookup.
|
|
|
|
* @param langShiftIndex
|
|
|
|
* Table index used for escaped 7-bit encoded character lookup.
|
2012-03-16 16:57:41 -07:00
|
|
|
* @param segmentMaxSeq
|
|
|
|
* Max sequence number of a multi-part messages, or 1 for single one.
|
|
|
|
* This number might not be accurate for a multi-part message until
|
|
|
|
* it's processed by #_fragmentText() again.
|
2012-03-16 16:57:06 -07:00
|
|
|
*/
|
2012-10-03 01:37:19 -07:00
|
|
|
_calculateUserDataLength: function _calculateUserDataLength(message, strict7BitEncoding) {
|
|
|
|
let options = this._calculateUserDataLength7Bit(message, strict7BitEncoding);
|
2012-03-16 16:57:06 -07:00
|
|
|
if (!options) {
|
|
|
|
options = this._calculateUserDataLengthUCS2(message);
|
2012-03-16 16:47:21 -07:00
|
|
|
}
|
|
|
|
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("_calculateUserDataLength: " + JSON.stringify(options));
|
2012-03-16 16:57:06 -07:00
|
|
|
return options;
|
2012-03-16 16:47:21 -07:00
|
|
|
},
|
|
|
|
|
2012-03-16 16:57:41 -07:00
|
|
|
/**
|
|
|
|
* Fragment GSM 7-Bit encodable string for transmission.
|
|
|
|
*
|
|
|
|
* @param text
|
|
|
|
* text string to be fragmented.
|
|
|
|
* @param langTable
|
|
|
|
* locking shift table string.
|
|
|
|
* @param langShiftTable
|
|
|
|
* single shift table string.
|
2013-01-03 22:26:24 -08:00
|
|
|
* @param segmentSeptets
|
|
|
|
* Number of available spetets per segment.
|
2012-10-03 01:37:19 -07:00
|
|
|
* @param strict7BitEncoding
|
|
|
|
* Optional. Enable Latin characters replacement with corresponding
|
|
|
|
* ones in GSM SMS 7-bit default alphabet.
|
2012-03-16 16:57:41 -07:00
|
|
|
*
|
|
|
|
* @return an array of objects. See #_fragmentText() for detailed definition.
|
|
|
|
*/
|
2013-01-03 22:26:24 -08:00
|
|
|
_fragmentText7Bit: function _fragmentText7Bit(text, langTable, langShiftTable, segmentSeptets, strict7BitEncoding) {
|
2012-03-16 16:57:41 -07:00
|
|
|
let ret = [];
|
2012-12-17 02:47:46 -08:00
|
|
|
let body = "", len = 0;
|
2012-03-16 16:57:41 -07:00
|
|
|
for (let i = 0, inc = 0; i < text.length; i++) {
|
2012-10-03 01:37:19 -07:00
|
|
|
let c = text.charAt(i);
|
|
|
|
if (strict7BitEncoding) {
|
|
|
|
c = RIL.GSM_SMS_STRICT_7BIT_CHARMAP[c] || c;
|
|
|
|
}
|
|
|
|
|
|
|
|
let septet = langTable.indexOf(c);
|
2012-03-16 16:57:41 -07:00
|
|
|
if (septet == RIL.PDU_NL_EXTENDED_ESCAPE) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (septet >= 0) {
|
|
|
|
inc = 1;
|
|
|
|
} else {
|
2012-10-03 01:37:19 -07:00
|
|
|
septet = langShiftTable.indexOf(c);
|
2012-03-16 16:57:41 -07:00
|
|
|
if (septet == RIL.PDU_NL_RESERVED_CONTROL) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
inc = 2;
|
2012-12-17 02:47:58 -08:00
|
|
|
if (septet < 0) {
|
|
|
|
if (!strict7BitEncoding) {
|
|
|
|
throw new Error("Given text cannot be encoded with GSM 7-bit Alphabet!");
|
|
|
|
}
|
|
|
|
|
|
|
|
// Bug 816082, when strict7BitEncoding is enabled, we should replace
|
|
|
|
// characters that can't be encoded with GSM 7-Bit alphabets with '*'.
|
|
|
|
c = '*';
|
|
|
|
if (langTable.indexOf(c) >= 0) {
|
|
|
|
inc = 1;
|
|
|
|
}
|
|
|
|
}
|
2012-03-16 16:57:41 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if ((len + inc) > segmentSeptets) {
|
|
|
|
ret.push({
|
2012-12-17 02:47:46 -08:00
|
|
|
body: body,
|
2012-03-16 16:57:41 -07:00
|
|
|
encodedBodyLength: len,
|
|
|
|
});
|
2012-12-17 02:47:46 -08:00
|
|
|
body = c;
|
|
|
|
len = inc;
|
|
|
|
} else {
|
|
|
|
body += c;
|
|
|
|
len += inc;
|
2012-03-16 16:57:41 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (len) {
|
|
|
|
ret.push({
|
2012-12-17 02:47:46 -08:00
|
|
|
body: body,
|
2012-03-16 16:57:41 -07:00
|
|
|
encodedBodyLength: len,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Fragment UCS2 encodable string for transmission.
|
|
|
|
*
|
|
|
|
* @param text
|
|
|
|
* text string to be fragmented.
|
2013-01-03 22:26:24 -08:00
|
|
|
* @param segmentChars
|
|
|
|
* Number of available characters per segment.
|
2012-03-16 16:57:41 -07:00
|
|
|
*
|
|
|
|
* @return an array of objects. See #_fragmentText() for detailed definition.
|
|
|
|
*/
|
2013-01-03 22:26:24 -08:00
|
|
|
_fragmentTextUCS2: function _fragmentTextUCS2(text, segmentChars) {
|
2012-03-16 16:57:41 -07:00
|
|
|
let ret = [];
|
|
|
|
for (let offset = 0; offset < text.length; offset += segmentChars) {
|
|
|
|
let str = text.substr(offset, segmentChars);
|
|
|
|
ret.push({
|
|
|
|
body: str,
|
|
|
|
encodedBodyLength: str.length * 2,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Fragment string for transmission.
|
|
|
|
*
|
|
|
|
* Fragment input text string into an array of objects that contains
|
|
|
|
* attributes `body`, substring for this segment, `encodedBodyLength`,
|
|
|
|
* length of the encoded segment body in septets.
|
|
|
|
*
|
|
|
|
* @param text
|
|
|
|
* Text string to be fragmented.
|
|
|
|
* @param options
|
|
|
|
* Optional pre-calculated option object. The output array will be
|
|
|
|
* stored at options.segments if there are multiple segments.
|
2012-10-03 01:37:19 -07:00
|
|
|
* @param strict7BitEncoding
|
|
|
|
* Optional. Enable Latin characters replacement with corresponding
|
|
|
|
* ones in GSM SMS 7-bit default alphabet.
|
2012-03-16 16:57:41 -07:00
|
|
|
*
|
|
|
|
* @return Populated options object.
|
|
|
|
*/
|
2012-10-03 01:37:19 -07:00
|
|
|
_fragmentText: function _fragmentText(text, options, strict7BitEncoding) {
|
2012-03-16 16:57:41 -07:00
|
|
|
if (!options) {
|
2012-10-03 01:37:19 -07:00
|
|
|
options = this._calculateUserDataLength(text, strict7BitEncoding);
|
2012-03-16 16:57:41 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if (options.dcs == RIL.PDU_DCS_MSG_CODING_7BITS_ALPHABET) {
|
|
|
|
const langTable = RIL.PDU_NL_LOCKING_SHIFT_TABLES[options.langIndex];
|
|
|
|
const langShiftTable = RIL.PDU_NL_SINGLE_SHIFT_TABLES[options.langShiftIndex];
|
2012-12-17 02:47:46 -08:00
|
|
|
options.segments = this._fragmentText7Bit(text,
|
2012-03-16 16:57:41 -07:00
|
|
|
langTable, langShiftTable,
|
2013-01-03 22:26:24 -08:00
|
|
|
options.segmentChars,
|
2012-12-17 02:47:46 -08:00
|
|
|
strict7BitEncoding);
|
2012-03-16 16:57:41 -07:00
|
|
|
} else {
|
2012-12-17 02:47:46 -08:00
|
|
|
options.segments = this._fragmentTextUCS2(text,
|
2013-01-03 22:26:24 -08:00
|
|
|
options.segmentChars);
|
2012-03-16 16:57:41 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// Re-sync options.segmentMaxSeq with actual length of returning array.
|
|
|
|
options.segmentMaxSeq = options.segments.length;
|
|
|
|
|
|
|
|
return options;
|
|
|
|
},
|
|
|
|
|
2013-01-03 22:26:24 -08:00
|
|
|
getSegmentInfoForText: function getSegmentInfoForText(text) {
|
2012-10-03 01:37:19 -07:00
|
|
|
let strict7BitEncoding;
|
|
|
|
try {
|
|
|
|
strict7BitEncoding = Services.prefs.getBoolPref("dom.sms.strict7BitEncoding");
|
|
|
|
} catch (e) {
|
|
|
|
strict7BitEncoding = false;
|
|
|
|
}
|
2013-01-03 22:26:24 -08:00
|
|
|
|
|
|
|
let options = this._fragmentText(text, null, strict7BitEncoding);
|
2013-05-23 04:42:29 -07:00
|
|
|
let charsInLastSegment;
|
|
|
|
if (options.segmentMaxSeq) {
|
|
|
|
let lastSegment = options.segments[options.segmentMaxSeq - 1];
|
|
|
|
charsInLastSegment = lastSegment.encodedBodyLength;
|
|
|
|
if (options.dcs == RIL.PDU_DCS_MSG_CODING_16BITS_ALPHABET) {
|
|
|
|
// In UCS2 encoding, encodedBodyLength is in octets.
|
|
|
|
charsInLastSegment /= 2;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
charsInLastSegment = 0;
|
2013-01-03 22:26:24 -08:00
|
|
|
}
|
|
|
|
|
2013-03-08 23:22:25 -08:00
|
|
|
let result = gMobileMessageService.createSmsSegmentInfo(options.segmentMaxSeq,
|
|
|
|
options.segmentChars,
|
|
|
|
options.segmentChars - charsInLastSegment);
|
2013-01-03 22:26:24 -08:00
|
|
|
return result;
|
2011-12-23 21:02:52 -08:00
|
|
|
},
|
|
|
|
|
2013-07-29 15:50:22 -07:00
|
|
|
sendSMS: function sendSMS(number, message, silent, request) {
|
2012-10-03 01:37:19 -07:00
|
|
|
let strict7BitEncoding;
|
|
|
|
try {
|
|
|
|
strict7BitEncoding = Services.prefs.getBoolPref("dom.sms.strict7BitEncoding");
|
|
|
|
} catch (e) {
|
|
|
|
strict7BitEncoding = false;
|
|
|
|
}
|
|
|
|
|
2012-12-17 02:47:46 -08:00
|
|
|
let options = this._fragmentText(message, null, strict7BitEncoding);
|
2012-08-06 14:28:03 -07:00
|
|
|
options.rilMessageType = "sendSMS";
|
2013-03-08 09:46:15 -08:00
|
|
|
options.number = PhoneNumberUtils.normalize(number);
|
2013-05-07 07:26:03 -07:00
|
|
|
let requestStatusReport;
|
|
|
|
try {
|
|
|
|
requestStatusReport =
|
|
|
|
Services.prefs.getBoolPref("dom.sms.requestStatusReport");
|
|
|
|
} catch (e) {
|
|
|
|
requestStatusReport = true;
|
|
|
|
}
|
|
|
|
options.requestStatusReport = requestStatusReport;
|
2012-03-16 16:59:35 -07:00
|
|
|
if (options.segmentMaxSeq > 1) {
|
|
|
|
options.segmentRef16Bit = this.segmentRef16Bit;
|
|
|
|
options.segmentRef = this.nextSegmentRef;
|
|
|
|
}
|
|
|
|
|
2013-07-29 15:50:22 -07:00
|
|
|
let notifyResult = (function notifyResult(rv, domMessage) {
|
|
|
|
// TODO bug 832140 handle !Components.isSuccessCode(rv)
|
|
|
|
if (!silent) {
|
|
|
|
Services.obs.notifyObservers(domMessage, kSmsSendingObserverTopic, null);
|
|
|
|
}
|
|
|
|
|
|
|
|
// If the radio is disabled or the SIM card is not ready, just directly
|
|
|
|
// return with the corresponding error code.
|
|
|
|
let errorCode;
|
|
|
|
if (!PhoneNumberUtils.isPlainPhoneNumber(options.number)) {
|
|
|
|
if (DEBUG) this.debug("Error! Address is invalid when sending SMS: " +
|
|
|
|
options.number);
|
|
|
|
errorCode = Ci.nsIMobileMessageCallback.INVALID_ADDRESS_ERROR;
|
|
|
|
} else if (!this._radioEnabled) {
|
|
|
|
if (DEBUG) this.debug("Error! Radio is disabled when sending SMS.");
|
|
|
|
errorCode = Ci.nsIMobileMessageCallback.RADIO_DISABLED_ERROR;
|
|
|
|
} else if (this.rilContext.cardState != "ready") {
|
|
|
|
if (DEBUG) this.debug("Error! SIM card is not ready when sending SMS.");
|
|
|
|
errorCode = Ci.nsIMobileMessageCallback.NO_SIM_CARD_ERROR;
|
|
|
|
}
|
|
|
|
if (errorCode) {
|
|
|
|
if (silent) {
|
|
|
|
request.notifySendMessageFailed(errorCode);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
gMobileMessageDatabaseService
|
|
|
|
.setMessageDelivery(domMessage.id,
|
|
|
|
null,
|
|
|
|
DOM_MOBILE_MESSAGE_DELIVERY_ERROR,
|
|
|
|
RIL.GECKO_SMS_DELIVERY_STATUS_ERROR,
|
|
|
|
function notifyResult(rv, domMessage) {
|
|
|
|
// TODO bug 832140 handle !Components.isSuccessCode(rv)
|
|
|
|
request.notifySendMessageFailed(errorCode);
|
|
|
|
Services.obs.notifyObservers(domMessage, kSmsFailedObserverTopic, null);
|
|
|
|
});
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Keep current SMS message info for sent/delivered notifications
|
|
|
|
options.envelopeId = this.createSmsEnvelope({
|
|
|
|
request: request,
|
|
|
|
sms: domMessage,
|
|
|
|
requestStatusReport: options.requestStatusReport,
|
|
|
|
silent: silent
|
|
|
|
});
|
|
|
|
|
|
|
|
// This is the entry point starting to send SMS.
|
|
|
|
this.worker.postMessage(options);
|
|
|
|
}).bind(this);
|
|
|
|
|
2013-02-08 02:45:04 -08:00
|
|
|
let sendingMessage = {
|
|
|
|
type: "sms",
|
2013-07-02 02:36:47 -07:00
|
|
|
sender: this.getMsisdn(),
|
2013-02-08 02:45:04 -08:00
|
|
|
receiver: number,
|
|
|
|
body: message,
|
2013-03-08 23:22:17 -08:00
|
|
|
deliveryStatusRequested: options.requestStatusReport,
|
|
|
|
timestamp: Date.now()
|
2013-02-08 02:45:04 -08:00
|
|
|
};
|
|
|
|
|
2013-07-29 15:50:22 -07:00
|
|
|
if (silent) {
|
|
|
|
let deliveryStatus = RIL.GECKO_SMS_DELIVERY_STATUS_PENDING;
|
|
|
|
let delivery = DOM_MOBILE_MESSAGE_DELIVERY_SENDING;
|
|
|
|
let domMessage =
|
|
|
|
gMobileMessageService.createSmsMessage(-1, // id
|
|
|
|
0, // threadId
|
|
|
|
delivery,
|
|
|
|
deliveryStatus,
|
|
|
|
sendingMessage.sender,
|
|
|
|
sendingMessage.receiver,
|
|
|
|
sendingMessage.body,
|
|
|
|
"normal", // message class
|
|
|
|
sendingMessage.timestamp,
|
|
|
|
false);
|
|
|
|
notifyResult(Cr.NS_OK, domMessage);
|
|
|
|
return;
|
|
|
|
}
|
2013-03-08 09:46:15 -08:00
|
|
|
|
2013-07-29 15:50:22 -07:00
|
|
|
let id = gMobileMessageDatabaseService.saveSendingMessage(
|
|
|
|
sendingMessage, notifyResult);
|
2011-12-23 21:02:52 -08:00
|
|
|
},
|
|
|
|
|
2012-01-17 17:34:09 -08:00
|
|
|
registerDataCallCallback: function registerDataCallCallback(callback) {
|
|
|
|
if (this._datacall_callbacks) {
|
|
|
|
if (this._datacall_callbacks.indexOf(callback) != -1) {
|
|
|
|
throw new Error("Already registered this callback!");
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
this._datacall_callbacks = [];
|
|
|
|
}
|
|
|
|
this._datacall_callbacks.push(callback);
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("Registering callback: " + callback);
|
2012-01-17 17:34:09 -08:00
|
|
|
},
|
|
|
|
|
|
|
|
unregisterDataCallCallback: function unregisterDataCallCallback(callback) {
|
|
|
|
if (!this._datacall_callbacks) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
let index = this._datacall_callbacks.indexOf(callback);
|
|
|
|
if (index != -1) {
|
|
|
|
this._datacall_callbacks.splice(index, 1);
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("Unregistering callback: " + callback);
|
2012-01-17 17:34:09 -08:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
_deliverDataCallCallback: function _deliverDataCallCallback(name, args) {
|
|
|
|
// We need to worry about callback registration state mutations during the
|
|
|
|
// callback firing. The behaviour we want is to *not* call any callbacks
|
|
|
|
// that are added during the firing and to *not* call any callbacks that are
|
|
|
|
// removed during the firing. To address this, we make a copy of the
|
|
|
|
// callback list before dispatching and then double-check that each callback
|
|
|
|
// is still registered before calling it.
|
|
|
|
if (!this._datacall_callbacks) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
let callbacks = this._datacall_callbacks.slice();
|
2013-06-09 19:41:14 -07:00
|
|
|
for (let callback of callbacks) {
|
2012-01-17 17:34:09 -08:00
|
|
|
if (this._datacall_callbacks.indexOf(callback) == -1) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
let handler = callback[name];
|
|
|
|
if (typeof handler != "function") {
|
|
|
|
throw new Error("No handler for " + name);
|
|
|
|
}
|
|
|
|
try {
|
|
|
|
handler.apply(callback, args);
|
|
|
|
} catch (e) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) {
|
|
|
|
this.debug("callback handler for " + name + " threw an exception: " + e);
|
|
|
|
}
|
2012-01-17 17:34:09 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2013-07-11 21:44:22 -07:00
|
|
|
setupDataCallByType: function setupDataCallByType(apntype) {
|
|
|
|
let apnSetting = this.apnSettings.byType[apntype];
|
|
|
|
if (!apnSetting) {
|
|
|
|
return;
|
2012-09-26 05:57:37 -07:00
|
|
|
}
|
|
|
|
|
2013-07-11 21:44:22 -07:00
|
|
|
let dataInfo = this.rilContext.data;
|
|
|
|
if (dataInfo.state != RIL.GECKO_MOBILE_CONNECTION_STATE_REGISTERED ||
|
|
|
|
dataInfo.type == RIL.GECKO_MOBILE_CONNECTION_STATE_UNKNOWN) {
|
|
|
|
return;
|
|
|
|
}
|
2013-06-27 18:46:00 -07:00
|
|
|
|
2013-07-11 21:44:22 -07:00
|
|
|
apnSetting.iface.connect(apntype);
|
2013-06-27 18:46:00 -07:00
|
|
|
// We just call connect() function, so this interface should be in
|
|
|
|
// connecting state. If this interface is already in connected state, we
|
|
|
|
// are sure that this interface have successfully established connection
|
|
|
|
// for other data call types before we call connect() function for current
|
|
|
|
// data call type. In this circumstance, we have to directly update the
|
|
|
|
// necessary data call and interface information to RILContentHelper
|
2013-07-11 21:44:22 -07:00
|
|
|
// and network manager for current data call type.
|
|
|
|
if (apnSetting.iface.connected) {
|
2013-06-27 18:46:00 -07:00
|
|
|
if (apntype == "default" && !dataInfo.connected) {
|
|
|
|
dataInfo.connected = true;
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.sendMobileConnectionMessage("RIL:DataInfoChanged",
|
|
|
|
this.clientId, dataInfo);
|
2013-06-27 18:46:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// Update the interface status via-registration if the interface has
|
|
|
|
// already been registered in the network manager.
|
2013-07-11 21:44:22 -07:00
|
|
|
if (apnSetting.iface.name in gNetworkManager.networkInterfaces) {
|
|
|
|
gNetworkManager.unregisterNetworkInterface(apnSetting.iface);
|
2013-06-27 18:46:00 -07:00
|
|
|
}
|
2013-07-11 21:44:22 -07:00
|
|
|
gNetworkManager.registerNetworkInterface(apnSetting.iface);
|
2013-06-27 18:46:00 -07:00
|
|
|
|
2013-07-11 21:44:22 -07:00
|
|
|
Services.obs.notifyObservers(apnSetting.iface,
|
2013-06-27 18:46:00 -07:00
|
|
|
kNetworkInterfaceStateChangedTopic,
|
|
|
|
null);
|
|
|
|
}
|
|
|
|
},
|
2013-01-22 20:05:34 -08:00
|
|
|
|
2013-07-11 21:44:22 -07:00
|
|
|
deactivateDataCallByType: function deactivateDataCallByType(apntype) {
|
|
|
|
let apnSetting = this.apnSettings.byType[apntype];
|
|
|
|
if (!apnSetting) {
|
2012-09-26 05:57:37 -07:00
|
|
|
return;
|
|
|
|
}
|
2013-06-27 18:46:00 -07:00
|
|
|
|
2013-07-11 21:44:22 -07:00
|
|
|
apnSetting.iface.disconnect(apntype);
|
2013-06-27 18:46:00 -07:00
|
|
|
// We just call disconnect() function, so this interface should be in
|
|
|
|
// disconnecting state. If this interface is still in connected state, we
|
|
|
|
// are sure that other data call types still need this connection of this
|
|
|
|
// interface. In this circumstance, we have to directly update the
|
|
|
|
// necessary data call and interface information to RILContentHelper
|
2013-07-11 21:44:22 -07:00
|
|
|
// and network manager for current data call type.
|
|
|
|
if (apnSetting.iface.connectedTypes.length && apnSetting.iface.connected) {
|
2013-06-27 18:46:00 -07:00
|
|
|
let dataInfo = this.rilContext.data;
|
|
|
|
if (apntype == "default" && dataInfo.connected) {
|
|
|
|
dataInfo.connected = false;
|
2013-07-02 02:36:40 -07:00
|
|
|
gMessageManager.sendMobileConnectionMessage("RIL:DataInfoChanged",
|
|
|
|
this.clientId, dataInfo);
|
2013-06-27 18:46:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// Update the interface status via-registration if the interface has
|
|
|
|
// already been registered in the network manager.
|
2013-07-11 21:44:22 -07:00
|
|
|
if (apnSetting.iface.name in gNetworkManager.networkInterfaces) {
|
|
|
|
gNetworkManager.unregisterNetworkInterface(apnSetting.iface);
|
2013-01-22 20:05:34 -08:00
|
|
|
}
|
2013-07-11 21:44:22 -07:00
|
|
|
gNetworkManager.registerNetworkInterface(apnSetting.iface);
|
2013-06-27 18:46:00 -07:00
|
|
|
|
2013-07-11 21:44:22 -07:00
|
|
|
Services.obs.notifyObservers(apnSetting.iface,
|
2013-06-27 18:46:00 -07:00
|
|
|
kNetworkInterfaceStateChangedTopic,
|
|
|
|
null);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2012-09-26 05:57:37 -07:00
|
|
|
getDataCallStateByType: function getDataCallStateByType(apntype) {
|
2013-07-11 21:44:22 -07:00
|
|
|
let apnSetting = this.apnSettings.byType[apntype];
|
|
|
|
if (!apnSetting) {
|
|
|
|
return RIL.GECKO_NETWORK_STATE_UNKNOWN;
|
|
|
|
}
|
|
|
|
if (!apnSetting.iface.inConnectedTypes(apntype)) {
|
|
|
|
return RIL.GECKO_NETWORK_STATE_DISCONNECTED;
|
2012-09-26 05:57:37 -07:00
|
|
|
}
|
2013-07-11 21:44:22 -07:00
|
|
|
return apnSetting.iface.state;
|
2012-09-26 05:57:37 -07:00
|
|
|
},
|
|
|
|
|
2012-02-10 11:27:38 -08:00
|
|
|
setupDataCall: function setupDataCall(radioTech, apn, user, passwd, chappap, pdptype) {
|
2012-08-06 14:28:03 -07:00
|
|
|
this.worker.postMessage({rilMessageType: "setupDataCall",
|
2012-01-17 17:34:09 -08:00
|
|
|
radioTech: radioTech,
|
|
|
|
apn: apn,
|
|
|
|
user: user,
|
|
|
|
passwd: passwd,
|
|
|
|
chappap: chappap,
|
|
|
|
pdptype: pdptype});
|
|
|
|
},
|
|
|
|
|
2012-02-10 11:27:38 -08:00
|
|
|
deactivateDataCall: function deactivateDataCall(cid, reason) {
|
2012-08-06 14:28:03 -07:00
|
|
|
this.worker.postMessage({rilMessageType: "deactivateDataCall",
|
2012-01-17 17:34:09 -08:00
|
|
|
cid: cid,
|
|
|
|
reason: reason});
|
|
|
|
},
|
|
|
|
|
|
|
|
getDataCallList: function getDataCallList() {
|
2012-08-06 14:28:03 -07:00
|
|
|
this.worker.postMessage({rilMessageType: "getDataCallList"});
|
2012-01-17 17:34:09 -08:00
|
|
|
},
|
|
|
|
|
2013-04-11 00:12:09 -07:00
|
|
|
getCardLockState: function getCardLockState(message) {
|
|
|
|
message.rilMessageType = "iccGetCardLockState";
|
2012-04-11 21:01:49 -07:00
|
|
|
this.worker.postMessage(message);
|
|
|
|
},
|
|
|
|
|
|
|
|
unlockCardLock: function unlockCardLock(message) {
|
2012-08-15 09:49:12 -07:00
|
|
|
message.rilMessageType = "iccUnlockCardLock";
|
2012-04-11 21:01:49 -07:00
|
|
|
this.worker.postMessage(message);
|
|
|
|
},
|
2011-12-04 23:58:27 -08:00
|
|
|
|
2012-04-11 21:01:49 -07:00
|
|
|
setCardLock: function setCardLock(message) {
|
2012-08-15 09:49:12 -07:00
|
|
|
message.rilMessageType = "iccSetCardLock";
|
2012-04-11 21:01:49 -07:00
|
|
|
this.worker.postMessage(message);
|
2012-05-07 11:53:42 -07:00
|
|
|
},
|
|
|
|
|
Bug 875710: Added getCardLockRetryCount to nsIIccProvider, r=vyang, sr=mounir
This patch adds getCardLockRetryCount to nsIIccProvider and its
implementations. This method allows callers to query the number
of remaining tries for unlocking a SIM-card lock. Supported locks
are 'pin', 'puk', 'pin2', 'puk2', 'nck', 'cck', and 'spck'. The
call returns a DOM request that returns the retry count in its
success handler, or signals an appropriate error.
Reading the retry count is an optional feature and may not be
supported for all lock types. In this case the DOM request receives
and error with the name GECKO_ERROR_NOT_SUPPORTED. For an invalid
lock type, the error name is GECKO_ERROR_GENERIC_FAILURE.
getCardLockRetryCount replaces retryCount in nsIDOMMobileConnection,
which is now deprecated.
--HG--
extra : rebase_source : d1d11612f836652dca85f7c701f09e7af962e3b7
2013-07-09 07:06:05 -07:00
|
|
|
getCardLockRetryCount: function getCardLockRetryCount(message) {
|
|
|
|
message.rilMessageType = "iccGetCardLockRetryCount";
|
|
|
|
this.worker.postMessage(message);
|
|
|
|
},
|
|
|
|
|
2013-03-05 18:51:40 -08:00
|
|
|
readIccContacts: function readIccContacts(message) {
|
|
|
|
message.rilMessageType = "readICCContacts";
|
|
|
|
this.worker.postMessage(message);
|
2012-12-27 19:11:36 -08:00
|
|
|
},
|
|
|
|
|
2013-03-24 20:09:01 -07:00
|
|
|
updateIccContact: function updateIccContact(message) {
|
2013-03-05 18:12:23 -08:00
|
|
|
message.rilMessageType = "updateICCContact";
|
|
|
|
this.worker.postMessage(message);
|
2012-12-27 19:11:36 -08:00
|
|
|
},
|
2012-04-11 21:01:49 -07:00
|
|
|
};
|
2012-03-12 16:46:08 -07:00
|
|
|
|
2013-07-11 21:44:22 -07:00
|
|
|
function RILNetworkInterface(radioInterface, apnSetting) {
|
2013-07-02 02:36:37 -07:00
|
|
|
this.radioInterface = radioInterface;
|
2013-07-11 21:44:22 -07:00
|
|
|
this.apnSetting = apnSetting;
|
2012-09-26 05:52:21 -07:00
|
|
|
}
|
2012-03-12 16:46:08 -07:00
|
|
|
|
2012-09-26 05:52:21 -07:00
|
|
|
RILNetworkInterface.prototype = {
|
|
|
|
classID: RILNETWORKINTERFACE_CID,
|
|
|
|
classInfo: XPCOMUtils.generateCI({classID: RILNETWORKINTERFACE_CID,
|
|
|
|
classDescription: "RILNetworkInterface",
|
|
|
|
interfaces: [Ci.nsINetworkInterface,
|
2013-02-05 21:12:25 -08:00
|
|
|
Ci.nsIRILDataCallback]}),
|
2012-04-19 14:33:25 -07:00
|
|
|
QueryInterface: XPCOMUtils.generateQI([Ci.nsINetworkInterface,
|
|
|
|
Ci.nsIRILDataCallback]),
|
2012-03-12 16:46:08 -07:00
|
|
|
|
2012-04-19 14:33:25 -07:00
|
|
|
// nsINetworkInterface
|
2012-03-12 16:46:08 -07:00
|
|
|
|
2012-04-19 14:33:25 -07:00
|
|
|
NETWORK_STATE_UNKNOWN: Ci.nsINetworkInterface.NETWORK_STATE_UNKNOWN,
|
|
|
|
NETWORK_STATE_CONNECTING: Ci.nsINetworkInterface.CONNECTING,
|
|
|
|
NETWORK_STATE_CONNECTED: Ci.nsINetworkInterface.CONNECTED,
|
|
|
|
NETWORK_STATE_DISCONNECTING: Ci.nsINetworkInterface.DISCONNECTING,
|
|
|
|
NETWORK_STATE_DISCONNECTED: Ci.nsINetworkInterface.DISCONNECTED,
|
2012-03-12 16:46:08 -07:00
|
|
|
|
2012-04-19 14:33:25 -07:00
|
|
|
state: Ci.nsINetworkInterface.NETWORK_STATE_UNKNOWN,
|
|
|
|
|
2012-08-30 09:57:33 -07:00
|
|
|
NETWORK_TYPE_WIFI: Ci.nsINetworkInterface.NETWORK_TYPE_WIFI,
|
|
|
|
NETWORK_TYPE_MOBILE: Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE,
|
|
|
|
NETWORK_TYPE_MOBILE_MMS: Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_MMS,
|
|
|
|
NETWORK_TYPE_MOBILE_SUPL: Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_SUPL,
|
2013-06-27 18:46:00 -07:00
|
|
|
// The network manager should only need to add the host route for "other"
|
|
|
|
// types, which is the same handling method as the supl type. So let the
|
|
|
|
// definition of other types to be the same as the one of supl type.
|
|
|
|
NETWORK_TYPE_MOBILE_OTHERS: Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_SUPL,
|
2012-04-19 14:33:25 -07:00
|
|
|
|
2012-06-01 14:09:59 -07:00
|
|
|
/**
|
|
|
|
* Standard values for the APN connection retry process
|
|
|
|
* Retry funcion: time(secs) = A * numer_of_retries^2 + B
|
|
|
|
*/
|
|
|
|
NETWORK_APNRETRY_FACTOR: 8,
|
|
|
|
NETWORK_APNRETRY_ORIGIN: 3,
|
|
|
|
NETWORK_APNRETRY_MAXRETRIES: 10,
|
|
|
|
|
|
|
|
// Event timer for connection retries
|
|
|
|
timer: null,
|
|
|
|
|
2013-06-27 18:46:00 -07:00
|
|
|
get type() {
|
|
|
|
if (this.connectedTypes.indexOf("default") != -1) {
|
|
|
|
return this.NETWORK_TYPE_MOBILE;
|
|
|
|
}
|
|
|
|
if (this.connectedTypes.indexOf("mms") != -1) {
|
|
|
|
return this.NETWORK_TYPE_MOBILE_MMS;
|
|
|
|
}
|
|
|
|
if (this.connectedTypes.indexOf("supl") != -1) {
|
|
|
|
return this.NETWORK_TYPE_MOBILE_SUPL;
|
|
|
|
}
|
|
|
|
return this.NETWORK_TYPE_MOBILE_OTHERS;
|
|
|
|
},
|
2012-04-19 14:33:25 -07:00
|
|
|
|
|
|
|
name: null,
|
|
|
|
|
|
|
|
dhcp: false,
|
2012-03-12 16:46:08 -07:00
|
|
|
|
2012-08-13 18:54:42 -07:00
|
|
|
ip: null,
|
|
|
|
|
|
|
|
netmask: null,
|
|
|
|
|
|
|
|
broadcast: null,
|
|
|
|
|
|
|
|
dns1: null,
|
|
|
|
|
|
|
|
dns2: null,
|
|
|
|
|
2013-07-11 21:44:22 -07:00
|
|
|
get httpProxyHost() {
|
|
|
|
return this.apnSetting.proxy || '';
|
|
|
|
},
|
2012-08-01 07:55:43 -07:00
|
|
|
|
2013-07-11 21:44:22 -07:00
|
|
|
get httpProxyPort() {
|
|
|
|
return this.apnSetting.port || '';
|
|
|
|
},
|
2012-08-01 07:55:43 -07:00
|
|
|
|
2013-07-02 02:36:58 -07:00
|
|
|
debug: function debug(s) {
|
2013-07-10 09:19:00 -07:00
|
|
|
dump("-*- RILNetworkInterface[" + this.radioInterface.clientId + ":" +
|
2013-07-02 02:36:58 -07:00
|
|
|
this.type + "]: " + s + "\n");
|
|
|
|
},
|
|
|
|
|
2012-03-12 16:46:08 -07:00
|
|
|
// nsIRILDataCallback
|
|
|
|
|
2012-09-26 05:52:21 -07:00
|
|
|
dataCallError: function dataCallError(message) {
|
2013-07-11 21:44:22 -07:00
|
|
|
if (message.apn != this.apnSetting.apn) {
|
2012-09-26 05:52:21 -07:00
|
|
|
return;
|
|
|
|
}
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("Data call error on APN: " + message.apn);
|
2012-09-26 05:52:21 -07:00
|
|
|
this.reset();
|
|
|
|
},
|
|
|
|
|
2012-06-21 22:53:12 -07:00
|
|
|
dataCallStateChanged: function dataCallStateChanged(datacall) {
|
2012-12-13 19:13:31 -08:00
|
|
|
if (this.cid && this.cid != datacall.cid) {
|
|
|
|
// If data call for this connection existed but cid mismatched,
|
|
|
|
// it means this datacall state change is not for us.
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// If data call for this connection does not exist, it could be state
|
|
|
|
// change for new data call. We only update data call state change
|
|
|
|
// if APN name matched.
|
2013-07-11 21:44:22 -07:00
|
|
|
if (!this.cid && datacall.apn != this.apnSetting.apn) {
|
2012-09-26 05:52:21 -07:00
|
|
|
return;
|
|
|
|
}
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) {
|
|
|
|
this.debug("Data call ID: " + datacall.cid + ", interface name: " +
|
|
|
|
datacall.ifname + ", APN name: " + datacall.apn);
|
|
|
|
}
|
2012-03-12 16:46:08 -07:00
|
|
|
if (this.connecting &&
|
2012-06-21 22:53:12 -07:00
|
|
|
(datacall.state == RIL.GECKO_NETWORK_STATE_CONNECTING ||
|
|
|
|
datacall.state == RIL.GECKO_NETWORK_STATE_CONNECTED)) {
|
2012-03-12 16:46:08 -07:00
|
|
|
this.connecting = false;
|
2012-06-21 22:53:12 -07:00
|
|
|
this.cid = datacall.cid;
|
|
|
|
this.name = datacall.ifname;
|
2012-08-13 18:54:42 -07:00
|
|
|
this.ip = datacall.ip;
|
|
|
|
this.netmask = datacall.netmask;
|
|
|
|
this.broadcast = datacall.broadcast;
|
|
|
|
this.gateway = datacall.gw;
|
2012-08-25 19:29:07 -07:00
|
|
|
if (datacall.dns) {
|
|
|
|
this.dns1 = datacall.dns[0];
|
|
|
|
this.dns2 = datacall.dns[1];
|
|
|
|
}
|
2012-04-19 14:33:25 -07:00
|
|
|
if (!this.registeredAsNetworkInterface) {
|
2012-09-26 05:52:21 -07:00
|
|
|
gNetworkManager.registerNetworkInterface(this);
|
2012-04-19 14:33:25 -07:00
|
|
|
this.registeredAsNetworkInterface = true;
|
|
|
|
}
|
2012-03-12 16:46:08 -07:00
|
|
|
}
|
2012-12-13 19:13:31 -08:00
|
|
|
// In current design, we don't update status of secondary APN if it shares
|
|
|
|
// same APN name with the default APN. In this condition, this.cid will
|
|
|
|
// not be set and we don't want to update its status.
|
|
|
|
if (this.cid == null) {
|
2012-03-12 16:46:08 -07:00
|
|
|
return;
|
|
|
|
}
|
2012-06-21 22:53:12 -07:00
|
|
|
if (this.state == datacall.state) {
|
2012-03-12 16:46:08 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-06-21 22:53:12 -07:00
|
|
|
this.state = datacall.state;
|
2012-09-26 05:52:21 -07:00
|
|
|
|
2012-09-26 06:05:28 -07:00
|
|
|
// In case the data setting changed while the datacall was being started or
|
|
|
|
// ended, let's re-check the setting and potentially adjust the datacall
|
|
|
|
// state again.
|
2013-07-11 21:44:22 -07:00
|
|
|
if (this.radioInterface.apnSettings.byType.default &&
|
|
|
|
(this.radioInterface.apnSettings.byType.default.apn ==
|
|
|
|
this.apnSetting.apn)) {
|
2013-07-02 02:36:37 -07:00
|
|
|
this.radioInterface.updateRILNetworkInterface();
|
2012-09-26 06:05:28 -07:00
|
|
|
}
|
|
|
|
|
2012-09-26 05:52:21 -07:00
|
|
|
if (this.state == RIL.GECKO_NETWORK_STATE_UNKNOWN &&
|
2013-07-11 21:44:22 -07:00
|
|
|
this.registeredAsNetworkInterface) {
|
2012-09-26 05:52:21 -07:00
|
|
|
gNetworkManager.unregisterNetworkInterface(this);
|
|
|
|
this.registeredAsNetworkInterface = false;
|
2012-12-13 19:13:31 -08:00
|
|
|
this.cid = null;
|
2013-06-27 18:46:00 -07:00
|
|
|
this.connectedTypes = [];
|
2012-09-26 05:52:21 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-04-19 14:33:25 -07:00
|
|
|
Services.obs.notifyObservers(this,
|
|
|
|
kNetworkInterfaceStateChangedTopic,
|
|
|
|
null);
|
2012-03-12 16:46:08 -07:00
|
|
|
},
|
|
|
|
|
|
|
|
receiveDataCallList: function receiveDataCallList(dataCalls, length) {
|
|
|
|
},
|
|
|
|
|
|
|
|
// Helpers
|
|
|
|
|
2012-04-19 14:33:25 -07:00
|
|
|
cid: null,
|
|
|
|
registeredAsDataCallCallback: false,
|
|
|
|
registeredAsNetworkInterface: false,
|
|
|
|
connecting: false,
|
2013-07-11 21:44:22 -07:00
|
|
|
apnSetting: {},
|
2012-04-19 14:33:25 -07:00
|
|
|
|
2012-06-01 14:09:59 -07:00
|
|
|
// APN failed connections. Retry counter
|
|
|
|
apnRetryCounter: 0,
|
|
|
|
|
2013-06-27 18:46:00 -07:00
|
|
|
connectedTypes: [],
|
|
|
|
|
|
|
|
inConnectedTypes: function inConnectedTypes(type) {
|
|
|
|
return this.connectedTypes.indexOf(type) != -1;
|
|
|
|
},
|
|
|
|
|
2012-04-24 13:46:42 -07:00
|
|
|
get connected() {
|
|
|
|
return this.state == RIL.GECKO_NETWORK_STATE_CONNECTED;
|
|
|
|
},
|
|
|
|
|
2013-07-11 21:44:22 -07:00
|
|
|
connect: function connect(apntype) {
|
2013-06-27 18:46:00 -07:00
|
|
|
if (apntype && !this.inConnectedTypes(apntype)) {
|
|
|
|
this.connectedTypes.push(apntype);
|
|
|
|
}
|
|
|
|
|
2012-08-28 07:37:43 -07:00
|
|
|
if (this.connecting || this.connected) {
|
2012-03-12 16:46:08 -07:00
|
|
|
return;
|
|
|
|
}
|
2012-08-01 07:54:04 -07:00
|
|
|
|
2013-06-27 18:46:00 -07:00
|
|
|
// When the retry mechanism is running in background and someone calls
|
|
|
|
// disconnect(), this.connectedTypes.length has chances to become 0.
|
|
|
|
if (!this.connectedTypes.length) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-03-12 16:46:08 -07:00
|
|
|
if (!this.registeredAsDataCallCallback) {
|
2013-07-02 02:36:37 -07:00
|
|
|
this.radioInterface.registerDataCallCallback(this);
|
2012-03-12 16:46:08 -07:00
|
|
|
this.registeredAsDataCallCallback = true;
|
|
|
|
}
|
|
|
|
|
2013-07-11 21:44:22 -07:00
|
|
|
if (!this.apnSetting.apn) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("APN name is empty, nothing to do.");
|
2012-09-26 05:57:37 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) {
|
|
|
|
this.debug("Going to set up data connection with APN " +
|
2013-07-11 21:44:22 -07:00
|
|
|
this.apnSetting.apn);
|
2013-07-02 02:36:58 -07:00
|
|
|
}
|
2013-07-02 02:36:37 -07:00
|
|
|
let radioTechType = this.radioInterface.rilContext.data.type;
|
2013-01-23 18:07:17 -08:00
|
|
|
let radioTechnology = RIL.GECKO_RADIO_TECH.indexOf(radioTechType);
|
2013-07-11 21:44:22 -07:00
|
|
|
let authType = RIL.RIL_DATACALL_AUTH_TO_GECKO.indexOf(this.apnSetting.authtype);
|
2013-05-06 01:58:56 -07:00
|
|
|
// Use the default authType if the value in database is invalid.
|
|
|
|
// For the case that user might not select the authentication type.
|
|
|
|
if (authType == -1) {
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) {
|
2013-07-11 21:44:22 -07:00
|
|
|
this.debug("Invalid authType " + this.apnSetting.authtype);
|
2013-07-02 02:36:58 -07:00
|
|
|
}
|
2013-05-06 01:58:56 -07:00
|
|
|
authType = RIL.RIL_DATACALL_AUTH_TO_GECKO.indexOf(RIL.GECKO_DATACALL_AUTH_DEFAULT);
|
|
|
|
}
|
2013-07-02 02:36:37 -07:00
|
|
|
this.radioInterface.setupDataCall(radioTechnology,
|
2013-07-11 21:44:22 -07:00
|
|
|
this.apnSetting.apn,
|
|
|
|
this.apnSetting.user,
|
|
|
|
this.apnSetting.password,
|
|
|
|
authType,
|
|
|
|
"IP");
|
2012-03-12 16:46:08 -07:00
|
|
|
this.connecting = true;
|
|
|
|
},
|
|
|
|
|
2012-06-01 14:09:59 -07:00
|
|
|
reset: function reset() {
|
|
|
|
let apnRetryTimer;
|
|
|
|
this.connecting = false;
|
|
|
|
// We will retry the connection in increasing times
|
|
|
|
// based on the function: time = A * numer_of_retries^2 + B
|
|
|
|
if (this.apnRetryCounter >= this.NETWORK_APNRETRY_MAXRETRIES) {
|
|
|
|
this.apnRetryCounter = 0;
|
|
|
|
this.timer = null;
|
2013-06-27 18:46:00 -07:00
|
|
|
this.connectedTypes = [];
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("Too many APN Connection retries - STOP retrying");
|
2012-06-01 14:09:59 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
apnRetryTimer = this.NETWORK_APNRETRY_FACTOR *
|
|
|
|
(this.apnRetryCounter * this.apnRetryCounter) +
|
|
|
|
this.NETWORK_APNRETRY_ORIGIN;
|
|
|
|
this.apnRetryCounter++;
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) {
|
|
|
|
this.debug("Data call - APN Connection Retry Timer (secs-counter): " +
|
|
|
|
apnRetryTimer + "-" + this.apnRetryCounter);
|
|
|
|
}
|
2012-06-01 14:09:59 -07:00
|
|
|
|
|
|
|
if (this.timer == null) {
|
|
|
|
// Event timer for connection retries
|
|
|
|
this.timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
|
|
|
}
|
|
|
|
this.timer.initWithCallback(this, apnRetryTimer * 1000,
|
|
|
|
Ci.nsITimer.TYPE_ONE_SHOT);
|
|
|
|
},
|
|
|
|
|
2013-06-27 18:46:00 -07:00
|
|
|
disconnect: function disconnect(apntype) {
|
|
|
|
let index = this.connectedTypes.indexOf(apntype);
|
|
|
|
if (index != -1) {
|
|
|
|
this.connectedTypes.splice(index, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.connectedTypes.length) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-04-24 13:46:42 -07:00
|
|
|
if (this.state == RIL.GECKO_NETWORK_STATE_DISCONNECTING ||
|
2013-07-11 21:44:22 -07:00
|
|
|
this.state == RIL.GECKO_NETWORK_STATE_DISCONNECTED ||
|
|
|
|
this.state == RIL.GECKO_NETWORK_STATE_UNKNOWN) {
|
2012-04-24 13:46:42 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
let reason = RIL.DATACALL_DEACTIVATE_NO_REASON;
|
2013-07-02 02:36:58 -07:00
|
|
|
if (DEBUG) this.debug("Going to disconnet data connection " + this.cid);
|
2013-07-02 02:36:37 -07:00
|
|
|
this.radioInterface.deactivateDataCall(this.cid, reason);
|
2012-03-12 16:46:08 -07:00
|
|
|
},
|
|
|
|
|
2012-06-01 14:09:59 -07:00
|
|
|
// Entry method for timer events. Used to reconnect to a failed APN
|
|
|
|
notify: function(timer) {
|
2012-09-26 05:52:21 -07:00
|
|
|
this.connect();
|
2012-06-01 14:09:59 -07:00
|
|
|
},
|
|
|
|
|
|
|
|
shutdown: function() {
|
|
|
|
this.timer = null;
|
|
|
|
}
|
|
|
|
|
2012-03-12 16:46:08 -07:00
|
|
|
};
|
|
|
|
|
2012-10-31 09:13:28 -07:00
|
|
|
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([RadioInterfaceLayer]);
|
2011-12-04 23:58:27 -08:00
|
|
|
|