Bug 866272 - expose privileged access to mcc+mnc pair for last home network and roaming network r=gal

This commit is contained in:
Fabrice Desré 2013-05-02 18:37:51 -07:00
parent 45ff1bf9a0
commit 699c83814d
6 changed files with 197 additions and 21 deletions

View File

@ -119,6 +119,11 @@ this.PermissionsTable = { geolocation: {
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
mobilenetwork: {
app: DENY_ACTION,
privileged: ALLOW_ACTION,
certified: ALLOW_ACTION
},
power: {
app: DENY_ACTION,
privileged: DENY_ACTION,

View File

@ -1361,7 +1361,8 @@ Navigator::GetMozMobileConnection(nsIDOMMozMobileConnection** aMobileConnection)
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_TRUE(window, NS_OK);
if (!CheckPermission("mobileconnection")) {
if (!CheckPermission("mobileconnection") &&
!CheckPermission("mobilenetwork")) {
return NS_OK;
}

View File

@ -13,7 +13,7 @@ interface nsIDOMMozMobileCellInfo;
interface nsIDOMMozIccManager;
interface nsIDOMMozMobileCFInfo;
[scriptable, builtinclass, uuid(bde7e16c-ff1f-4c7f-b1cd-480984cbb206)]
[scriptable, builtinclass, uuid(780de142-562c-4141-bd5c-5413fb1952d2)]
interface nsIDOMMozMobileConnection : nsIDOMEventTarget
{
const long ICC_SERVICE_CLASS_VOICE = (1 << 0);
@ -26,6 +26,13 @@ interface nsIDOMMozMobileConnection : nsIDOMEventTarget
const long ICC_SERVICE_CLASS_PAD = (1 << 7);
const long ICC_SERVICE_CLASS_MAX = (1 << 7);
/**
* These two fields can be accessed by privileged applications with the
* 'mobilenetwork' permission.
*/
readonly attribute DOMString lastKnownNetwork;
readonly attribute DOMString lastKnownHomeNetwork;
/**
* Indicates the state of the device's ICC card.
*

View File

@ -11,6 +11,8 @@
#include "nsIDOMCFStateChangeEvent.h"
#include "nsIDOMICCCardLockErrorEvent.h"
#include "GeneratedEvents.h"
#include "mozilla/Preferences.h"
#include "nsIPermissionManager.h"
#include "nsContentUtils.h"
#include "nsJSUtils.h"
@ -81,6 +83,7 @@ NS_IMPL_EVENT_HANDLER(MobileConnection, cfstatechange)
MobileConnection::MobileConnection()
{
mProvider = do_GetService(NS_RILCONTENTHELPER_CONTRACTID);
mWindow = nullptr;
// Not being able to acquire the provider isn't fatal since we check
// for it explicitly below.
@ -88,11 +91,6 @@ MobileConnection::MobileConnection()
NS_WARNING("Could not acquire nsIMobileConnectionProvider!");
return;
}
mListener = new Listener(this);
DebugOnly<nsresult> rv = mProvider->RegisterMobileConnectionMsg(mListener);
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv),
"Failed registering mobile connection messages with provider");
}
void
@ -100,8 +98,19 @@ MobileConnection::Init(nsPIDOMWindow* aWindow)
{
BindToOwner(aWindow);
mIccManager = new icc::IccManager();
mIccManager->Init(aWindow);
mWindow = do_GetWeakReference(aWindow);
mListener = new Listener(this);
if (!CheckPermission("mobilenetwork") &&
CheckPermission("mobileconnection")) {
DebugOnly<nsresult> rv = mProvider->RegisterMobileConnectionMsg(mListener);
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv),
"Failed registering mobile connection messages with provider");
mIccManager = new icc::IccManager();
mIccManager->Init(aWindow);
printf_stderr("MobileConnection & IccManager initialized");
}
}
void
@ -122,11 +131,55 @@ MobileConnection::Shutdown()
// nsIDOMMozMobileConnection
NS_IMETHODIMP
MobileConnection::GetLastKnownNetwork(nsAString& network)
{
network.SetIsVoid(true);
if (!CheckPermission("mobilenetwork")) {
return NS_OK;
}
network = mozilla::Preferences::GetString("ril.lastKnownNetwork");
return NS_OK;
}
NS_IMETHODIMP
MobileConnection::GetLastKnownHomeNetwork(nsAString& network)
{
network.SetIsVoid(true);
if (!CheckPermission("mobilenetwork")) {
return NS_OK;
}
network = mozilla::Preferences::GetString("ril.lastKnownHomeNetwork");
return NS_OK;
}
// All fields below require the "mobileconnection" permission.
bool
MobileConnection::CheckPermission(const char* type)
{
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_TRUE(window, false);
nsCOMPtr<nsIPermissionManager> permMgr =
do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
NS_ENSURE_TRUE(permMgr, false);
uint32_t permission = nsIPermissionManager::DENY_ACTION;
permMgr->TestPermissionFromWindow(window, type, &permission);
return permission == nsIPermissionManager::ALLOW_ACTION;
}
NS_IMETHODIMP
MobileConnection::GetCardState(nsAString& cardState)
{
if (!mProvider) {
cardState.SetIsVoid(true);
cardState.SetIsVoid(true);
if (!mProvider || !CheckPermission("mobileconnection")) {
return NS_OK;
}
return mProvider->GetCardState(cardState);
@ -135,8 +188,9 @@ MobileConnection::GetCardState(nsAString& cardState)
NS_IMETHODIMP
MobileConnection::GetIccInfo(nsIDOMMozMobileICCInfo** aIccInfo)
{
if (!mProvider) {
*aIccInfo = nullptr;
*aIccInfo = nullptr;
if (!mProvider || !CheckPermission("mobileconnection")) {
return NS_OK;
}
return mProvider->GetIccInfo(aIccInfo);
@ -145,8 +199,9 @@ MobileConnection::GetIccInfo(nsIDOMMozMobileICCInfo** aIccInfo)
NS_IMETHODIMP
MobileConnection::GetVoice(nsIDOMMozMobileConnectionInfo** voice)
{
if (!mProvider) {
*voice = nullptr;
*voice = nullptr;
if (!mProvider || !CheckPermission("mobileconnection")) {
return NS_OK;
}
return mProvider->GetVoiceConnectionInfo(voice);
@ -155,8 +210,9 @@ MobileConnection::GetVoice(nsIDOMMozMobileConnectionInfo** voice)
NS_IMETHODIMP
MobileConnection::GetData(nsIDOMMozMobileConnectionInfo** data)
{
if (!mProvider) {
*data = nullptr;
*data = nullptr;
if (!mProvider || !CheckPermission("mobileconnection")) {
return NS_OK;
}
return mProvider->GetDataConnectionInfo(data);
@ -165,9 +221,10 @@ MobileConnection::GetData(nsIDOMMozMobileConnectionInfo** data)
NS_IMETHODIMP
MobileConnection::GetNetworkSelectionMode(nsAString& networkSelectionMode)
{
if (!mProvider) {
networkSelectionMode.SetIsVoid(true);
return NS_OK;
networkSelectionMode.SetIsVoid(true);
if (!mProvider || !CheckPermission("mobileconnection")) {
return NS_OK;
}
return mProvider->GetNetworkSelectionMode(networkSelectionMode);
}
@ -175,6 +232,12 @@ MobileConnection::GetNetworkSelectionMode(nsAString& networkSelectionMode)
NS_IMETHODIMP
MobileConnection::GetIcc(nsIDOMMozIccManager** aIcc)
{
*aIcc = nullptr;
if (!CheckPermission("mobileconnection")) {
return NS_OK;
}
NS_IF_ADDREF(*aIcc = mIccManager);
return NS_OK;
}
@ -184,6 +247,10 @@ MobileConnection::GetNetworks(nsIDOMDOMRequest** request)
{
*request = nullptr;
if (!CheckPermission("mobileconnection")) {
return NS_OK;
}
if (!mProvider) {
return NS_ERROR_FAILURE;
}
@ -196,6 +263,10 @@ MobileConnection::SelectNetwork(nsIDOMMozMobileNetworkInfo* network, nsIDOMDOMRe
{
*request = nullptr;
if (!CheckPermission("mobileconnection")) {
return NS_OK;
}
if (!mProvider) {
return NS_ERROR_FAILURE;
}
@ -208,6 +279,10 @@ MobileConnection::SelectNetworkAutomatically(nsIDOMDOMRequest** request)
{
*request = nullptr;
if (!CheckPermission("mobileconnection")) {
return NS_OK;
}
if (!mProvider) {
return NS_ERROR_FAILURE;
}
@ -220,6 +295,10 @@ MobileConnection::GetCardLock(const nsAString& aLockType, nsIDOMDOMRequest** aDo
{
*aDomRequest = nullptr;
if (!CheckPermission("mobileconnection")) {
return NS_OK;
}
if (!mProvider) {
return NS_ERROR_FAILURE;
}
@ -233,6 +312,10 @@ MobileConnection::UnlockCardLock(const JS::Value& aInfo,
{
*aDomRequest = nullptr;
if (!CheckPermission("mobileconnection")) {
return NS_OK;
}
if (!mProvider) {
return NS_ERROR_FAILURE;
}
@ -246,6 +329,10 @@ MobileConnection::SetCardLock(const JS::Value& aInfo,
{
*aDomRequest = nullptr;
if (!CheckPermission("mobileconnection")) {
return NS_OK;
}
if (!mProvider) {
return NS_ERROR_FAILURE;
}
@ -257,6 +344,10 @@ NS_IMETHODIMP
MobileConnection::SendMMI(const nsAString& aMMIString,
nsIDOMDOMRequest** request)
{
if (!CheckPermission("mobileconnection")) {
return NS_OK;
}
if (!mProvider) {
return NS_ERROR_FAILURE;
}
@ -267,6 +358,10 @@ MobileConnection::SendMMI(const nsAString& aMMIString,
NS_IMETHODIMP
MobileConnection::CancelMMI(nsIDOMDOMRequest** request)
{
if (!CheckPermission("mobileconnection")) {
return NS_OK;
}
if (!mProvider) {
return NS_ERROR_FAILURE;
}
@ -280,6 +375,10 @@ MobileConnection::GetCallForwardingOption(uint16_t aReason,
{
*aRequest = nullptr;
if (!CheckPermission("mobileconnection")) {
return NS_OK;
}
if (!mProvider) {
return NS_ERROR_FAILURE;
}
@ -293,6 +392,10 @@ MobileConnection::SetCallForwardingOption(nsIDOMMozMobileCFInfo* aCFInfo,
{
*aRequest = nullptr;
if (!CheckPermission("mobileconnection")) {
return NS_OK;
}
if (!mProvider) {
return NS_ERROR_FAILURE;
}
@ -305,6 +408,10 @@ MobileConnection::GetCallWaitingOption(nsIDOMDOMRequest** aRequest)
{
*aRequest = nullptr;
if (!CheckPermission("mobileconnection")) {
return NS_OK;
}
if (!mProvider) {
return NS_ERROR_FAILURE;
}
@ -318,6 +425,10 @@ MobileConnection::SetCallWaitingOption(bool aEnabled,
{
*aRequest = nullptr;
if (!CheckPermission("mobileconnection")) {
return NS_OK;
}
if (!mProvider) {
return NS_ERROR_FAILURE;
}
@ -330,24 +441,40 @@ MobileConnection::SetCallWaitingOption(bool aEnabled,
NS_IMETHODIMP
MobileConnection::NotifyVoiceChanged()
{
if (!CheckPermission("mobileconnection")) {
return NS_OK;
}
return DispatchTrustedEvent(NS_LITERAL_STRING("voicechange"));
}
NS_IMETHODIMP
MobileConnection::NotifyDataChanged()
{
if (!CheckPermission("mobileconnection")) {
return NS_OK;
}
return DispatchTrustedEvent(NS_LITERAL_STRING("datachange"));
}
NS_IMETHODIMP
MobileConnection::NotifyCardStateChanged()
{
if (!CheckPermission("mobileconnection")) {
return NS_OK;
}
return DispatchTrustedEvent(NS_LITERAL_STRING("cardstatechange"));
}
NS_IMETHODIMP
MobileConnection::NotifyIccInfoChanged()
{
if (!CheckPermission("mobileconnection")) {
return NS_OK;
}
return DispatchTrustedEvent(NS_LITERAL_STRING("iccinfochange"));
}
@ -355,6 +482,10 @@ NS_IMETHODIMP
MobileConnection::NotifyUssdReceived(const nsAString& aMessage,
bool aSessionEnded)
{
if (!CheckPermission("mobileconnection")) {
return NS_OK;
}
nsCOMPtr<nsIDOMEvent> event;
NS_NewDOMUSSDReceivedEvent(getter_AddRefs(event), this, nullptr, nullptr);
@ -370,6 +501,10 @@ MobileConnection::NotifyUssdReceived(const nsAString& aMessage,
NS_IMETHODIMP
MobileConnection::NotifyDataError(const nsAString& aMessage)
{
if (!CheckPermission("mobileconnection")) {
return NS_OK;
}
nsCOMPtr<nsIDOMEvent> event;
NS_NewDOMDataErrorEvent(getter_AddRefs(event), this, nullptr, nullptr);
@ -385,6 +520,10 @@ NS_IMETHODIMP
MobileConnection::NotifyIccCardLockError(const nsAString& aLockType,
uint32_t aRetryCount)
{
if (!CheckPermission("mobileconnection")) {
return NS_OK;
}
nsCOMPtr<nsIDOMEvent> event;
NS_NewDOMICCCardLockErrorEvent(getter_AddRefs(event), this, nullptr, nullptr);
@ -405,6 +544,10 @@ MobileConnection::NotifyCFStateChange(bool aSuccess,
unsigned short aSeconds,
unsigned short aServiceClass)
{
if (!CheckPermission("mobileconnection")) {
return NS_OK;
}
nsCOMPtr<nsIDOMEvent> event;
NS_NewDOMCFStateChangeEvent(getter_AddRefs(event), this, nullptr, nullptr);

View File

@ -51,6 +51,9 @@ private:
nsCOMPtr<nsIMobileConnectionProvider> mProvider;
nsRefPtr<Listener> mListener;
nsRefPtr<icc::IccManager> mIccManager;
nsWeakPtr mWindow;
bool CheckPermission(const char* type);
};
} // namespace network

View File

@ -258,7 +258,8 @@ function RadioInterfaceLayer() {
};
try {
this.rilContext.voice.lastKnownMcc = Services.prefs.getCharPref("ril.lastKnownMcc");
this.rilContext.voice.lastKnownMcc =
Services.prefs.getCharPref("ril.lastKnownMcc");
} catch (e) {}
this.voicemailInfo = {
@ -1080,6 +1081,14 @@ RadioInterfaceLayer.prototype = {
}
}
// Update lastKnownNetwork
if (message.mcc && message.mnc) {
try {
Services.prefs.setCharPref("ril.lastKnownNetwork",
message.mcc + "-" + message.mnc);
} catch (e) {}
}
voice.network = message;
if (!message.batch) {
this._sendMobileConnectionMessage("RIL:VoiceInfoChanged", voice);
@ -1789,6 +1798,14 @@ RadioInterfaceLayer.prototype = {
// when the MCC or MNC codes have changed.
this._sendMobileConnectionMessage("RIL:IccInfoChanged", message);
// Update lastKnownHomeNetwork.
if (message.mcc && message.mnc) {
try {
Services.prefs.setCharPref("ril.lastKnownHomeNetwork",
message.mcc + "-" + message.mnc);
} catch (e) {}
}
// If spn becomes available, we should check roaming again.
let oldSpn = oldIccInfo ? oldIccInfo.spn : null;
if (!oldSpn && message.spn) {