Bug 1087847 - Make sure the Icc status in MobileConnection and IccManager are synced. r=hsinyi,smaug

This commit is contained in:
Edgar Chen 2014-11-13 19:12:11 +08:00
parent dd84faa51e
commit 23f6b7be43
18 changed files with 168 additions and 119 deletions

View File

@ -130,12 +130,6 @@ MobileConnectionListener::NotifyOtaStatusChanged(const nsAString & status)
return NS_OK;
}
NS_IMETHODIMP
MobileConnectionListener::NotifyIccChanged()
{
return NS_OK;
}
NS_IMETHODIMP
MobileConnectionListener::NotifyRadioStateChanged()
{

View File

@ -130,12 +130,6 @@ MobileConnectionListener::NotifyOtaStatusChanged(const nsAString & status)
return NS_OK;
}
NS_IMETHODIMP
MobileConnectionListener::NotifyIccChanged()
{
return NS_OK;
}
NS_IMETHODIMP
MobileConnectionListener::NotifyRadioStateChanged()
{

View File

@ -6,6 +6,7 @@
#include "mozilla/dom/MozIccManagerBinding.h"
#include "Icc.h"
#include "IccListener.h"
#include "mozilla/AsyncEventDispatcher.h"
#include "mozilla/dom/IccChangeEvent.h"
#include "mozilla/Preferences.h"
#include "nsIIccInfo.h"
@ -74,8 +75,12 @@ IccManager::NotifyIccAdd(const nsAString& aIccId)
nsRefPtr<IccChangeEvent> event =
IccChangeEvent::Constructor(this, NS_LITERAL_STRING("iccdetected"), init);
event->SetTrusted(true);
return DispatchTrustedEvent(event);
nsRefPtr<AsyncEventDispatcher> asyncDispatcher =
new AsyncEventDispatcher(this, event);
return asyncDispatcher->PostDOMEvent();
}
nsresult
@ -90,8 +95,12 @@ IccManager::NotifyIccRemove(const nsAString& aIccId)
nsRefPtr<IccChangeEvent> event =
IccChangeEvent::Constructor(this, NS_LITERAL_STRING("iccundetected"), init);
event->SetTrusted(true);
return DispatchTrustedEvent(event);
nsRefPtr<AsyncEventDispatcher> asyncDispatcher =
new AsyncEventDispatcher(this, event);
return asyncDispatcher->PostDOMEvent();
}
// MozIccManager

View File

@ -13,8 +13,8 @@
namespace mozilla {
namespace dom {
class IccListener;
class Icc;
class IccListener;
class IccManager MOZ_FINAL : public DOMEventTargetHelper
{

View File

@ -34,6 +34,10 @@ taskHelper.push(function testIccUndetectedEvent() {
is(iccManager.getIccById(evt.iccId), null,
"should not get a valid icc object here");
// The mozMobileConnection.iccId should be in sync.
is(navigator.mozMobileConnections[0].iccId, null,
"check mozMobileConnection.iccId");
taskHelper.runNext();
});
});
@ -51,6 +55,10 @@ taskHelper.push(function testIccDetectedEvent() {
ok(iccManager.getIccById(evt.iccId) instanceof MozIcc,
"should get a valid icc object here");
// The mozMobileConnection.iccId should be in sync.
is(navigator.mozMobileConnections[0].iccId, iccId,
"check mozMobileConnection.iccId");
taskHelper.runNext();
});
});

View File

@ -5,6 +5,7 @@
#include "mozilla/dom/MobileConnection.h"
#include "MobileConnectionCallback.h"
#include "mozilla/AsyncEventDispatcher.h"
#include "mozilla/dom/CFStateChangeEvent.h"
#include "mozilla/dom/DataErrorEvent.h"
#include "mozilla/dom/MozClirModeEvent.h"
@ -18,8 +19,13 @@
#include "nsIVariant.h"
#include "nsJSON.h"
#include "nsJSUtils.h"
#include "nsRadioInterfaceLayer.h"
#include "nsServiceManagerUtils.h"
#ifdef MOZ_B2G_RIL
#include "nsIIccInfo.h"
#endif // MOZ_B2G_RIL
#define MOBILECONN_ERROR_INVALID_PARAMETER NS_LITERAL_STRING("InvalidParameter")
#define MOBILECONN_ERROR_INVALID_PASSWORD NS_LITERAL_STRING("InvalidPassword")
@ -43,12 +49,18 @@ using namespace mozilla::dom;
using namespace mozilla::dom::mobileconnection;
class MobileConnection::Listener MOZ_FINAL : public nsIMobileConnectionListener
#ifdef MOZ_B2G_RIL
, public nsIIccListener
#endif // MOZ_B2G_RIL
{
MobileConnection* mMobileConnection;
public:
NS_DECL_ISUPPORTS
NS_FORWARD_SAFE_NSIMOBILECONNECTIONLISTENER(mMobileConnection)
#ifdef MOZ_B2G_RIL
NS_FORWARD_SAFE_NSIICCLISTENER(mMobileConnection)
#endif // MOZ_B2G_RIL
explicit Listener(MobileConnection* aMobileConnection)
: mMobileConnection(aMobileConnection)
@ -69,7 +81,12 @@ private:
}
};
#ifdef MOZ_B2G_RIL
NS_IMPL_ISUPPORTS(MobileConnection::Listener, nsIMobileConnectionListener,
nsIIccListener)
#else
NS_IMPL_ISUPPORTS(MobileConnection::Listener, nsIMobileConnectionListener)
#endif // MOZ_B2G_RIL
NS_IMPL_CYCLE_COLLECTION_CLASS(MobileConnection)
@ -101,6 +118,7 @@ NS_IMPL_RELEASE_INHERITED(MobileConnection, DOMEventTargetHelper)
MobileConnection::MobileConnection(nsPIDOMWindow* aWindow, uint32_t aClientId)
: DOMEventTargetHelper(aWindow)
, mClientId(aClientId)
{
nsCOMPtr<nsIMobileConnectionService> service =
do_GetService(NS_MOBILE_CONNECTION_SERVICE_CONTRACTID);
@ -112,10 +130,17 @@ MobileConnection::MobileConnection(nsPIDOMWindow* aWindow, uint32_t aClientId)
return;
}
nsresult rv = service->GetItemByServiceId(aClientId,
nsresult rv = service->GetItemByServiceId(mClientId,
getter_AddRefs(mMobileConnection));
#ifdef MOZ_B2G_RIL
mIcc = do_GetService(NS_RILCONTENTHELPER_CONTRACTID);
if (NS_FAILED(rv) || !mMobileConnection || !mIcc) {
NS_WARNING("Could not acquire nsIMobileConnection or nsIIccProvider!");
#else
if (NS_FAILED(rv) || !mMobileConnection) {
NS_WARNING("Could not acquire nsIMobileConnection!");
#endif // MOZ_B2G_RIL
return;
}
@ -129,6 +154,13 @@ MobileConnection::MobileConnection(nsPIDOMWindow* aWindow, uint32_t aClientId)
"Failed registering mobile connection messages with service");
UpdateVoice();
UpdateData();
#ifdef MOZ_B2G_RIL
rv = mIcc->RegisterIccMsg(mClientId, mListener);
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv),
"Failed registering icc messages with service");
UpdateIccId();
#endif // MOZ_B2G_RIL
}
}
@ -140,6 +172,12 @@ MobileConnection::Shutdown()
mMobileConnection->UnregisterListener(mListener);
}
#ifdef MOZ_B2G_RIL
if (mIcc) {
mIcc->UnregisterIccMsg(mClientId, mListener);
}
#endif // MOZ_B2G_RIL
mListener->Disconnect();
mListener = nullptr;
}
@ -201,6 +239,29 @@ MobileConnection::UpdateData()
mData->Update(info);
}
bool
MobileConnection::UpdateIccId()
{
#ifdef MOZ_B2G_RIL
nsAutoString iccId;
nsCOMPtr<nsIIccInfo> iccInfo;
if (mIcc &&
NS_SUCCEEDED(mIcc->GetIccInfo(mClientId, getter_AddRefs(iccInfo))) &&
iccInfo) {
iccInfo->GetIccid(iccId);
} else {
iccId.SetIsVoid(true);
}
if (!mIccId.Equals(iccId)) {
mIccId = iccId;
return true;
}
#endif // MOZ_B2G_RIL
return false;
}
nsresult
MobileConnection::NotifyError(nsIDOMDOMRequest* aRequest, const nsAString& aMessage)
{
@ -322,13 +383,7 @@ MobileConnection::Data() const
void
MobileConnection::GetIccId(nsString& aRetVal) const
{
aRetVal.SetIsVoid(true);
if (!mMobileConnection) {
return;
}
mMobileConnection->GetIccId(aRetVal);
aRetVal = mIccId;
}
Nullable<MobileNetworkSelectionMode>
@ -1029,16 +1084,6 @@ MobileConnection::NotifyOtaStatusChanged(const nsAString& aStatus)
return DispatchTrustedEvent(event);
}
NS_IMETHODIMP
MobileConnection::NotifyIccChanged()
{
if (!CheckPermission("mobileconnection")) {
return NS_OK;
}
return DispatchTrustedEvent(NS_LITERAL_STRING("iccchange"));
}
NS_IMETHODIMP
MobileConnection::NotifyRadioStateChanged()
{
@ -1084,3 +1129,42 @@ MobileConnection::NotifyNetworkSelectionModeChanged()
{
return NS_OK;
}
#ifdef MOZ_B2G_RIL
// nsIIccListener
NS_IMETHODIMP
MobileConnection::NotifyStkCommand(const nsAString& aMessage)
{
return NS_OK;
}
NS_IMETHODIMP
MobileConnection::NotifyStkSessionEnd()
{
return NS_OK;
}
NS_IMETHODIMP
MobileConnection::NotifyCardStateChanged()
{
return NS_OK;
}
NS_IMETHODIMP
MobileConnection::NotifyIccInfoChanged()
{
if (!CheckPermission("mobileconnection")) {
return NS_OK;
}
if (!UpdateIccId()) {
return NS_OK;
}
nsRefPtr<AsyncEventDispatcher> asyncDispatcher =
new AsyncEventDispatcher(this, NS_LITERAL_STRING("iccchange"), false);
return asyncDispatcher->PostDOMEvent();
}
#endif // MOZ_B2G_RIL

View File

@ -14,11 +14,18 @@
#include "nsIMobileConnectionService.h"
#include "nsWeakPtr.h"
#ifdef MOZ_B2G_RIL
#include "nsIIccProvider.h"
#endif // MOZ_B2G_RIL
namespace mozilla {
namespace dom {
class MobileConnection MOZ_FINAL : public DOMEventTargetHelper,
private nsIMobileConnectionListener
class MobileConnection MOZ_FINAL : public DOMEventTargetHelper
, private nsIMobileConnectionListener
#ifdef MOZ_B2G_RIL
, private nsIIccListener
#endif // MOZ_B2G_RIL
{
/**
* Class MobileConnection doesn't actually expose
@ -33,6 +40,9 @@ class MobileConnection MOZ_FINAL : public DOMEventTargetHelper,
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIMOBILECONNECTIONLISTENER
#ifdef MOZ_B2G_RIL
NS_DECL_NSIICCLISTENER
#endif // MOZ_B2G_RIL
NS_REALLY_FORWARD_NSIDOMEVENTTARGET(DOMEventTargetHelper)
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(MobileConnection,
DOMEventTargetHelper)
@ -156,7 +166,12 @@ private:
~MobileConnection();
private:
uint32_t mClientId;
nsString mIccId;
nsCOMPtr<nsIMobileConnection> mMobileConnection;
#ifdef MOZ_B2G_RIL
nsCOMPtr<nsIIccProvider> mIcc;
#endif // MOZ_B2G_RIL
nsRefPtr<Listener> mListener;
nsRefPtr<MobileConnectionInfo> mVoice;
nsRefPtr<MobileConnectionInfo> mData;
@ -170,6 +185,9 @@ private:
void
UpdateData();
bool
UpdateIccId();
nsresult
NotifyError(nsIDOMDOMRequest* aRequest, const nsAString& aMessage);

View File

@ -305,7 +305,6 @@ MobileConnectionProvider.prototype = {
voice: null,
data: null,
iccId: null,
networkSelectionMode: Ci.nsIMobileConnection.NETWORK_SELECTION_MODE_UNKNOWN,
radioState: Ci.nsIMobileConnection.MOBILE_RADIO_STATE_UNKNOWN,
lastKnownNetwork: null,
@ -586,15 +585,6 @@ MobileConnectionProvider.prototype = {
}
},
updateIccId: function(aIccId) {
if (this.iccId === aIccId) {
return;
}
this.iccId = aIccId;
this.deliverListenerEvent("notifyIccChanged");
},
updateRadioState: function(aRadioState) {
if (this.radioState === aRadioState) {
return;
@ -1143,14 +1133,6 @@ MobileConnectionService.prototype = {
.deliverListenerEvent("notifyOtaStatusChanged", [aStatus]);
},
notifyIccChanged: function(aClientId, aIccId) {
if (DEBUG) {
debug("notifyIccChanged for " + aClientId + ": " + aIccId);
}
this.getItemByServiceId(aClientId).updateIccId(aIccId);
},
notifyRadioStateChanged: function(aClientId, aRadioState) {
if (DEBUG) {
debug("notifyRadioStateChanged for " + aClientId + ": " + aRadioState);

View File

@ -9,7 +9,7 @@
"@mozilla.org/mobileconnection/gonkmobileconnectionservice;1"
%}
[scriptable, uuid(ef49b866-85a0-11e4-b023-f73e02752840)]
[scriptable, uuid(3a7b8d47-d1c6-44c3-a312-df73fda1161e)]
interface nsIGonkMobileConnectionService : nsIMobileConnectionService
{
void notifyNetworkInfoChanged(in unsigned long clientId, in jsval networkInfo);
@ -33,8 +33,6 @@ interface nsIGonkMobileConnectionService : nsIMobileConnectionService
in boolean active,
in unsigned long timeoutMs);
void notifyIccChanged(in unsigned long clientId, in DOMString iccId);
void notifyNetworkSelectModeChanged(in unsigned long clientId,
in long mode);

View File

@ -12,7 +12,7 @@ interface nsIMobileNetworkInfo;
interface nsINeighboringCellIdsCallback;
interface nsIVariant;
[scriptable, uuid(6e6468a4-84fb-11e4-9b66-17dbe13c059e)]
[scriptable, uuid(d6827b51-61a7-4b7c-8454-42d0cffc1829)]
interface nsIMobileConnectionListener : nsISupports
{
/**
@ -75,11 +75,6 @@ interface nsIMobileConnectionListener : nsISupports
*/
void notifyOtaStatusChanged(in DOMString status);
/**
* Notify when icc id is changed.
*/
void notifyIccChanged();
/**
* Notify when radio state is changed.
*/
@ -168,7 +163,7 @@ already_AddRefed<nsIMobileConnectionService>
NS_CreateMobileConnectionService();
%}
[scriptable, uuid(2b3d0122-8054-11e4-964e-c727f38fd7e6)]
[scriptable, uuid(b9845f09-7cbb-46d0-b713-773d80844e0d)]
interface nsIMobileConnection : nsISupports
{
/*
@ -308,11 +303,6 @@ interface nsIMobileConnection : nsISupports
*/
readonly attribute nsIMobileConnectionInfo data;
/**
* The integrated circuit card identifier of the SIM.
*/
readonly attribute DOMString iccId;
/**
* The selection mode of the voice and data networks. One of the
* nsIMobileConnection.NETWORK_SELECTION_MODE_* values.

View File

@ -26,7 +26,7 @@ MobileConnectionChild::Init()
nsIMobileConnectionInfo* rawVoice;
nsIMobileConnectionInfo* rawData;
SendInit(&rawVoice, &rawData, &mLastNetwork, &mLastHomeNetwork, &mIccId,
SendInit(&rawVoice, &rawData, &mLastNetwork, &mLastHomeNetwork,
&mNetworkSelectionMode, &mRadioState, &mSupportedNetworkTypes);
// Use dont_AddRef here because this instances is already AddRef-ed in
@ -98,13 +98,6 @@ MobileConnectionChild::GetData(nsIMobileConnectionInfo** aData)
return NS_OK;
}
NS_IMETHODIMP
MobileConnectionChild::GetIccId(nsAString& aIccId)
{
aIccId = mIccId;
return NS_OK;
}
NS_IMETHODIMP
MobileConnectionChild::GetRadioState(int32_t* aRadioState)
{
@ -447,18 +440,6 @@ MobileConnectionChild::RecvNotifyOtaStatusChanged(const nsString& aStatus)
return true;
}
bool
MobileConnectionChild::RecvNotifyIccChanged(const nsString& aIccId)
{
mIccId.Assign(aIccId);
for (int32_t i = 0; i < mListeners.Count(); i++) {
mListeners[i]->NotifyIccChanged();
}
return true;
}
bool
MobileConnectionChild::RecvNotifyRadioStateChanged(const int32_t& aRadioState)
{

View File

@ -84,9 +84,6 @@ protected:
virtual bool
RecvNotifyOtaStatusChanged(const nsString& aStatus) MOZ_OVERRIDE;
virtual bool
RecvNotifyIccChanged(const nsString& aIccId) MOZ_OVERRIDE;
virtual bool
RecvNotifyRadioStateChanged(const int32_t& aRadioState) MOZ_OVERRIDE;
@ -108,7 +105,6 @@ private:
nsCOMArray<nsIMobileConnectionListener> mListeners;
nsRefPtr<MobileConnectionInfo> mVoice;
nsRefPtr<MobileConnectionInfo> mData;
nsString mIccId;
int32_t mRadioState;
nsString mLastNetwork;
nsString mLastHomeNetwork;

View File

@ -124,7 +124,6 @@ MobileConnectionParent::RecvInit(nsMobileConnectionInfo* aVoice,
nsMobileConnectionInfo* aData,
nsString* aLastKnownNetwork,
nsString* aLastKnownHomeNetwork,
nsString* aIccId,
int32_t* aNetworkSelectionMode,
int32_t* aRadioState,
nsTArray<int32_t>* aSupportedNetworkTypes)
@ -135,7 +134,6 @@ MobileConnectionParent::RecvInit(nsMobileConnectionInfo* aVoice,
NS_ENSURE_SUCCESS(mMobileConnection->GetData(aData), false);
NS_ENSURE_SUCCESS(mMobileConnection->GetLastKnownNetwork(*aLastKnownNetwork), false);
NS_ENSURE_SUCCESS(mMobileConnection->GetLastKnownHomeNetwork(*aLastKnownHomeNetwork), false);
NS_ENSURE_SUCCESS(mMobileConnection->GetIccId(*aIccId), false);
NS_ENSURE_SUCCESS(mMobileConnection->GetNetworkSelectionMode(aNetworkSelectionMode), false);
NS_ENSURE_SUCCESS(mMobileConnection->GetRadioState(aRadioState), false);
@ -228,17 +226,6 @@ MobileConnectionParent::NotifyOtaStatusChanged(const nsAString& aStatus)
? NS_OK : NS_ERROR_FAILURE;
}
NS_IMETHODIMP
MobileConnectionParent::NotifyIccChanged()
{
NS_ENSURE_TRUE(mLive, NS_ERROR_FAILURE);
nsAutoString iccId;
mMobileConnection->GetIccId(iccId);
return SendNotifyIccChanged(iccId) ? NS_OK : NS_ERROR_FAILURE;
}
NS_IMETHODIMP
MobileConnectionParent::NotifyRadioStateChanged()
{

View File

@ -51,8 +51,8 @@ protected:
virtual bool
RecvInit(nsMobileConnectionInfo* aVoice, nsMobileConnectionInfo* aData,
nsString* aLastKnownNetwork, nsString* aLastKnownHomeNetwork,
nsString* aIccId, int32_t* aNetworkSelectionMode,
int32_t* aRadioState, nsTArray<int32_t>* aSupportedNetworkTypes) MOZ_OVERRIDE;
int32_t* aNetworkSelectionMode, int32_t* aRadioState,
nsTArray<int32_t>* aSupportedNetworkTypes) MOZ_OVERRIDE;
private:
nsCOMPtr<nsIMobileConnection> mMobileConnection;

View File

@ -25,7 +25,6 @@ child:
uint16_t aTimeSeconds, uint16_t aServiceClass);
NotifyEmergencyCbModeChanged(bool aActive, uint32_t aTimeoutMs);
NotifyOtaStatusChanged(nsString aStatus);
NotifyIccChanged(nsString aIccId);
NotifyRadioStateChanged(int32_t aRadioState);
NotifyClirModeChanged(uint32_t aMode);
NotifyLastNetworkChanged(nsString aNetwork);
@ -49,8 +48,8 @@ parent:
sync Init()
returns (nsMobileConnectionInfo aVoice, nsMobileConnectionInfo aData,
nsString aLastKnownNetwork, nsString aLastKnownHomeNetwork,
nsString aIccId, int32_t aNetworkSelectionMode,
int32_t aRadioState, int32_t[] aSupportedNetworkTypes);
int32_t aNetworkSelectionMode, int32_t aRadioState,
int32_t[] aSupportedNetworkTypes);
};
/**

View File

@ -69,6 +69,10 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk' and CONFIG['MOZ_B2G_RIL']:
'gonk/MobileConnectionService.manifest',
]
LOCAL_INCLUDES += [
'/dom/system/gonk',
]
FAIL_ON_WARNINGS = True
include('/ipc/chromium/chromium-config.mozbuild')

View File

@ -17,17 +17,21 @@ function setRadioEnabledAndWaitIccChange(aEnabled) {
// Start tests
startTestCommon(function() {
log("Test initial iccId");
is(mobileConnection.iccId, ICCID);
is(mobileConnection.iccId, ICCID, "test initial iccId");
return setRadioEnabledAndWaitIccChange(false)
.then(() => {
is(mobileConnection.iccId, null);
is(mobileConnection.iccId, null, "mobileConnection.iccId");
})
// Restore radio state.
.then(() => setRadioEnabledAndWaitIccChange(true))
.then(() => {
is(mobileConnection.iccId, ICCID);
is(mobileConnection.iccId, ICCID, "mobileConnection.iccId");
// ICC object should be ready in mozIccManager.
let icc = getMozIccByIccId(mobileConnection.iccId);
ok(icc instanceof MozIcc, "icc should be an instance of MozIcc");
is(icc.iccInfo.iccid, mobileConnection.iccId, "icc.iccInfo.iccid");
});
});

View File

@ -2228,6 +2228,12 @@ RadioInterface.prototype = {
let oldSpn = this.rilContext.iccInfo ? this.rilContext.iccInfo.spn : null;
if (!message || !message.iccid) {
// If iccInfo is already `null`, don't have to clear it and send
// RIL:IccInfoChanged.
if (!this.rilContext.iccInfo) {
return;
}
// Card is not detected, clear iccInfo to null.
this.rilContext.iccInfo = null;
} else {
@ -2254,11 +2260,6 @@ RadioInterface.prototype = {
this.clientId,
message.iccid ? message : null);
// In bug 864489, icc related code will be move to gonk IccProvider, we may
// need a better way to notify icc change to MobileConnectionService.
gMobileConnectionService.notifyIccChanged(this.clientId,
message.iccid || null);
// Update lastKnownSimMcc.
if (message.mcc) {
try {