Bug 744700 - B2G 3G: Notify connection errors in the WebMobileConnection API, r=philikon

This commit is contained in:
Fernando Rodríguez Sela 2012-09-07 12:48:26 -07:00
parent 73f1adeeac
commit 16df0d74d2
7 changed files with 116 additions and 9 deletions

View File

@ -658,6 +658,7 @@ GK_ATOM(oncontextmenu, "oncontextmenu")
GK_ATOM(oncopy, "oncopy")
GK_ATOM(oncut, "oncut")
GK_ATOM(ondatachange, "ondatachange")
GK_ATOM(ondataerror, "ondataerror")
GK_ATOM(ondblclick, "ondblclick")
GK_ATOM(ondelivered, "ondelivered")
GK_ATOM(ondevicedisappeared, "ondevicedisappeared")

View File

@ -12,7 +12,7 @@ interface nsIDOMMozMobileNetworkInfo;
interface nsIDOMMozMobileCellInfo;
interface nsIDOMMozIccManager;
[scriptable, builtinclass, uuid(d9009d90-a4b3-44fd-a592-42b09f330fe5)]
[scriptable, builtinclass, uuid(c07309ee-a424-11e1-a75c-00265511db39)]
interface nsIDOMMozMobileConnection : nsIDOMEventTarget
{
/**
@ -239,6 +239,12 @@ interface nsIDOMMozMobileConnection : nsIDOMEventTarget
* received.
*/
[implicit_jscontext] attribute jsval onussdreceived;
/**
* The 'dataerror' event is notified whenever the data connection object
* receives an error from the RIL
*/
[implicit_jscontext] attribute jsval ondataerror;
};
[scriptable, uuid(5ea0e4a9-4684-40da-9930-8ebb61d187f3)]

View File

@ -8,6 +8,7 @@
#include "nsDOMEvent.h"
#include "nsIObserverService.h"
#include "USSDReceivedEvent.h"
#include "DataErrorEvent.h"
#include "mozilla/Services.h"
#include "IccManager.h"
@ -18,6 +19,7 @@
#define CARDSTATECHANGE_EVENTNAME NS_LITERAL_STRING("cardstatechange")
#define ICCINFOCHANGE_EVENTNAME NS_LITERAL_STRING("iccinfochange")
#define USSDRECEIVED_EVENTNAME NS_LITERAL_STRING("ussdreceived")
#define DATAERROR_EVENTNAME NS_LITERAL_STRING("dataerror")
DOMCI_DATA(MozMobileConnection, mozilla::dom::network::MobileConnection)
@ -30,6 +32,7 @@ const char* kDataChangedTopic = "mobile-connection-data-changed";
const char* kCardStateChangedTopic = "mobile-connection-cardstate-changed";
const char* kIccInfoChangedTopic = "mobile-connection-iccinfo-changed";
const char* kUssdReceivedTopic = "mobile-connection-ussd-received";
const char* kDataErrorTopic = "mobile-connection-data-error";
NS_IMPL_CYCLE_COLLECTION_CLASS(MobileConnection)
@ -57,6 +60,7 @@ NS_IMPL_EVENT_HANDLER(MobileConnection, iccinfochange)
NS_IMPL_EVENT_HANDLER(MobileConnection, voicechange)
NS_IMPL_EVENT_HANDLER(MobileConnection, datachange)
NS_IMPL_EVENT_HANDLER(MobileConnection, ussdreceived)
NS_IMPL_EVENT_HANDLER(MobileConnection, dataerror)
MobileConnection::MobileConnection()
{
@ -85,6 +89,7 @@ MobileConnection::Init(nsPIDOMWindow* aWindow)
obs->AddObserver(this, kCardStateChangedTopic, false);
obs->AddObserver(this, kIccInfoChangedTopic, false);
obs->AddObserver(this, kUssdReceivedTopic, false);
obs->AddObserver(this, kDataErrorTopic, false);
mIccManager = new icc::IccManager();
mIccManager->Init(aWindow);
@ -104,6 +109,7 @@ MobileConnection::Shutdown()
obs->RemoveObserver(this, kCardStateChangedTopic);
obs->RemoveObserver(this, kIccInfoChangedTopic);
obs->RemoveObserver(this, kUssdReceivedTopic);
obs->RemoveObserver(this, kDataErrorTopic);
if (mIccManager) {
mIccManager->Shutdown();
@ -147,7 +153,18 @@ MobileConnection::Observe(nsISupports* aSubject,
nsresult rv =
event->Dispatch(ToIDOMEventTarget(), USSDRECEIVED_EVENTNAME);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
if (!strcmp(aTopic, kDataErrorTopic)) {
nsString dataerror;
dataerror.Assign(aData);
nsRefPtr<DataErrorEvent> event = DataErrorEvent::Create(dataerror);
NS_ASSERTION(event, "This should never fail!");
nsresult rv =
event->Dispatch(ToIDOMEventTarget(), DATAERROR_EVENTNAME);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}

View File

@ -61,7 +61,8 @@ const RIL_IPC_MSG_NAMES = [
"RIL:CancelUssd:Return:OK",
"RIL:CancelUssd:Return:KO",
"RIL:StkCommand",
"RIL:StkSessionEnd"
"RIL:StkSessionEnd",
"RIL:DataError"
];
const kVoiceChangedTopic = "mobile-connection-voice-changed";
@ -71,6 +72,7 @@ const kIccInfoChangedTopic = "mobile-connection-iccinfo-changed";
const kUssdReceivedTopic = "mobile-connection-ussd-received";
const kStkCommandTopic = "icc-manager-stk-command";
const kStkSessionEndTopic = "icc-manager-stk-session-end";
const kDataErrorTopic = "mobile-connection-data-error";
XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
"@mozilla.org/childprocessmessagemanager;1",
@ -692,7 +694,11 @@ RILContentHelper.prototype = {
break;
case "RIL:StkSessionEnd":
Services.obs.notifyObservers(null, kStkSessionEndTopic, null);
break;
break;
case "RIL:DataError":
this.updateConnectionInfo(msg.json, this.dataConnectionInfo);
Services.obs.notifyObservers(null, kDataErrorTopic, msg.json.error);
break;
}
},

View File

@ -380,10 +380,7 @@ RadioInterfaceLayer.prototype = {
this.updateDataConnection(message);
break;
case "datacallerror":
// 3G Network revoked the data connection, possible unavailable APN
debug("Received data registration error message. Failed APN " +
this.dataCallSettings["apn"]);
RILNetworkInterface.reset();
this.handleDataCallError(message);
break;
case "signalstrengthchange":
this.handleSignalStrengthChange(message);
@ -613,6 +610,20 @@ RadioInterfaceLayer.prototype = {
this.updateRILNetworkInterface();
},
/**
* Handle data errors
*/
handleDataCallError: function handleDataCallError(message) {
if (message.apn != this.dataCallSettings["apn"]) {
return;
}
// 3G Network revoked the data connection, possible unavailable APN
RILNetworkInterface.reset();
// Notify datacall error
ppmm.broadcastAsyncMessage("RIL:DataError", message);
},
handleSignalStrengthChange: function handleSignalStrengthChange(message) {
let voiceInfo = this.rilContext.voice;
// TODO CDMA, EVDO, LTE, etc. (see bug 726098)

View File

@ -1680,6 +1680,53 @@ RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_IMSI_UNKNOWN_IN_VLR] = GECKO_CA
RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_IMEI_NOT_ACCEPTED] = GECKO_CALL_ERROR_DEVICE_NOT_ACCEPTED;
RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_ERROR_UNSPECIFIED] = GECKO_CALL_ERROR_UNSPECIFIED;
const GECKO_DATACALL_ERROR_OPERATOR_BARRED = "OperatorBarredError";
const GECKO_DATACALL_ERROR_INSUFFICIENT_RESOURCES = "InsufficientResourcesError";
const GECKO_DATACALL_ERROR_MISSING_UKNOWN_APN = "MissingUnknownAPNError";
const GECKO_DATACALL_ERROR_UNKNOWN_PDP_ADDRESS_TYPE = "UnknownPDPAddressTypeError";
const GECKO_DATACALL_ERROR_USER_AUTHENTICATION = "UserAuthenticationError";
const GECKO_DATACALL_ERROR_ACTIVATION_REJECT_GGSN = "ActivationRejectGGSNError";
const GECKO_DATACALL_ERROR_ACTIVATION_REJECT_UNSPECIFIED = "ActivationRejectUnspecifiedError";
const GECKO_DATACALL_ERROR_SERVICE_OPTION_NOT_SUPPORTED = "ServiceOptionNotSupportedError";
const GECKO_DATACALL_ERROR_SERVICE_OPTION_NOT_SUBSCRIBED = "ServiceOptionNotSubscribedError";
const GECKO_DATACALL_ERROR_SERVICE_OPTION_OUT_OF_ORDER = "ServiceOptionOutOfOrderError";
const GECKO_DATACALL_ERROR_NSAPI_IN_USE = "NSAPIInUseError";
const GECKO_DATACALL_ERROR_ONLY_IPV4_ALLOWED = "OnlyIPv4Error";
const GECKO_DATACALL_ERROR_ONLY_IPV6_ALLOWED = "OnlyIPv6Error";
const GECKO_DATACALL_ERROR_ONLY_SINGLE_BEARER_ALLOWED = "OnlySingleBearerAllowedError";
const GECKO_DATACALL_ERROR_PROTOCOL_ERRORS = "ProtocolErrorsError";
const GECKO_DATACALL_ERROR_VOICE_REGISTRATION_FAIL = "VoiceRegistrationFailError";
const GECKO_DATACALL_ERROR_DATA_REGISTRATION_FAIL = "DataRegistrationFailError";
const GECKO_DATACALL_ERROR_SIGNAL_LOST = "SignalLostError";
const GECKO_DATACALL_ERROR_PREF_RADIO_TECH_CHANGED = "PrefRadioTechChangedError";
const GECKO_DATACALL_ERROR_RADIO_POWER_OFF = "RadioPowerOffError";
const GECKO_DATACALL_ERROR_TETHERED_CALL_ACTIVE = "TetheredCallActiveError";
const GECKO_DATACALL_ERROR_UNSPECIFIED = "UnspecifiedError";
const RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR = {};
RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_OPERATOR_BARRED] = GECKO_DATACALL_ERROR_OPERATOR_BARRED;
RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_INSUFFICIENT_RESOURCES] = GECKO_DATACALL_ERROR_INSUFFICIENT_RESOURCES;
RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_MISSING_UKNOWN_APN] = GECKO_DATACALL_ERROR_MISSING_UKNOWN_APN;
RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_UNKNOWN_PDP_ADDRESS_TYPE] = GECKO_DATACALL_ERROR_UNKNOWN_PDP_ADDRESS_TYPE;
RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_USER_AUTHENTICATION] = GECKO_DATACALL_ERROR_USER_AUTHENTICATION;
RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_ACTIVATION_REJECT_GGSN] = GECKO_DATACALL_ERROR_ACTIVATION_REJECT_GGSN;
RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_ACTIVATION_REJECT_UNSPECIFIED] = GECKO_DATACALL_ERROR_ACTIVATION_REJECT_UNSPECIFIED;
RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_SERVICE_OPTION_NOT_SUPPORTED] = GECKO_DATACALL_ERROR_SERVICE_OPTION_NOT_SUPPORTED;
RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_SERVICE_OPTION_NOT_SUBSCRIBED] = GECKO_DATACALL_ERROR_SERVICE_OPTION_NOT_SUBSCRIBED;
RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_SERVICE_OPTION_OUT_OF_ORDER] = GECKO_DATACALL_ERROR_SERVICE_OPTION_OUT_OF_ORDER;
RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_NSAPI_IN_USE] = GECKO_DATACALL_ERROR_NSAPI_IN_USE;
RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_ONLY_IPV4_ALLOWED] = GECKO_DATACALL_ERROR_ONLY_IPV4_ALLOWED;
RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_ONLY_IPV6_ALLOWED] = GECKO_DATACALL_ERROR_ONLY_IPV6_ALLOWED;
RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_ONLY_SINGLE_BEARER_ALLOWED] = GECKO_DATACALL_ERROR_ONLY_SINGLE_BEARER_ALLOWED;
RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_PROTOCOL_ERRORS] = GECKO_DATACALL_ERROR_PROTOCOL_ERRORS;
RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_VOICE_REGISTRATION_FAIL] = GECKO_DATACALL_ERROR_VOICE_REGISTRATION_FAIL;
RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_DATA_REGISTRATION_FAIL] = GECKO_DATACALL_ERROR_DATA_REGISTRATION_FAIL;
RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_SIGNAL_LOST] = GECKO_DATACALL_ERROR_SIGNAL_LOST;
RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_PREF_RADIO_TECH_CHANGED] = GECKO_DATACALL_ERROR_PREF_RADIO_TECH_CHANGED;
RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_RADIO_POWER_OFF] = GECKO_DATACALL_ERROR_RADIO_POWER_OFF;
RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_TETHERED_CALL_ACTIVE] = GECKO_DATACALL_ERROR_TETHERED_CALL_ACTIVE;
RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_ERROR_UNSPECIFIED] = GECKO_DATACALL_ERROR_UNSPECIFIED;
const GECKO_RADIO_TECH = [
null,
"gprs",

View File

@ -2762,7 +2762,26 @@ let RIL = {
}
},
_sendDataCallError: function _sendDataCallError(message, errorCode) {
message.rilMessageType = "datacallerror";
if (errorCode == ERROR_GENERIC_FAILURE) {
message.error = RIL_ERROR_TO_GECKO_ERROR[errorCode];
} else {
message.error = RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[errorCode];
}
this.sendDOMMessage(message);
},
_processDataCallList: function _processDataCallList(datacalls, newDataCallOptions) {
// Check for possible PDP errors: We check earlier because the datacall
// can be removed if is the same as the current one.
for each (let newDataCall in datacalls) {
if (newDataCall.status != DATACALL_FAIL_NONE) {
newDataCall.apn = newDataCallOptions.apn;
this._sendDataCallError(newDataCall, newDataCall.status);
}
}
for each (let currentDataCall in this.currentDataCalls) {
let updatedDataCall;
if (datacalls) {
@ -3562,8 +3581,8 @@ RIL.readSetupDataCall_v5 = function readSetupDataCall_v5(options) {
RIL[REQUEST_SETUP_DATA_CALL] = function REQUEST_SETUP_DATA_CALL(length, options) {
if (options.rilRequestError) {
options.rilMessageType = "datacallerror";
this.sendDOMMessage(options);
// On Data Call generic errors, we shall notify caller
this._sendDataCallError(options, options.rilRequestError);
return;
}