import changes from `dev' branch of rmottola/Arctic-Fox:

- Bug 1146248 - Stop previous DHCP request when requesting a new one. r=vchang (1aae6f57d)
- Bug 1167466 - Prevent from previous failed DHCP callback interferring ongoing DHCP request. r=vchang. (35fc7df93)
- Bug 1167132 - Part 3: [NetworkManager] Move network information into a separate interface (Wifi). r=hchang (f44dc346d)
- Bug 1167132 - Part 4: [NetworkManager] Move network information into a separate interface (DataCall). r=echen (175ff98a6)
- Bug 1167132 - Part 5: [NetworkManager] Move network information into a separate interface (Tethering). r=echen (5bca84f68)
- Bug 1114938 - Part 1: Refactor StkProactiveCmdFactory.jsm into a XPCOM Service. r=echen (1701a4ac8)
- Bug 1114938 - Part 2.1: (Gonk) Refactor Stk Proactive Commands from IccProvider to IccService. r=echen (a541d04d6)
- Bug 1114938 - Part 2.2: (Gonk) Refactor Stk Request APIs from IccProvider to IccService. r=echen (6b72b6fd9)
- Bug 1114938 - Part 2.3: (Gonk) Remove Implementation from IccProvider. r=echen (5ef470e1a)
- Bug 1114938 - Part 3.1: (IPC) IPDL Declaration. r=echen (56dbb4563)
- Bug 1114938 - Part 3.2: (IPC) Add Helper to deflate/inflate XPCOM object to/from JSON for IPC. r=echen (fe30d9af9)
- Bug 1114938 - Part 4: (WebIDL) Type of MNC/MCC shall be the same to the one defined in MozMobileNetworkInfo. r=echen, r=htsai (62e7c23f2)
- Bug 1114937 - Part 1: Define new IDL for IccContacts. r=echen (04150be4c)
- Bug 1114937 - Part 2: IDL implementation in Gonk. r=echen (40c79e34a)
- Bug 1114937 - Part 3: Web API change to adopt IccService for IccContacts. r=echen, r=hsinyi (e55efbe8f)
- Bug 1114938 - Part 3.3: (IPC) IPDL Implementation. r=echen (2e695628e)
- Bug 1114937 - Part 4: IPDL Implementation. r=echen (a93612284)
- Bug 1114937 - Part 6: Deprecate RILContentHelper. r=echen (474dee728)
- Bug 1167132 - Part 6: [NetworkManager] Move network information into a separate interface (RadioInterface). r=echen (948f8674b)
- Bug 1167132 - Part 7: [NetworkManager] Move network information into a separate interface (MobileConnection). r=echen (ef6f47b08)
- missing bit of Bug 992772 (dcb2b8c2f)
- Bug 1182770 - Catch Rejected Promise Properly when Failed to ensure routing. r=echen (c1ec16c4d)
- Bug 1167132 - Part 8: [NetworkManager] Move network information into a separate interface (Mms). r=btseng (e6320c600)
- Bug 1167132 - Part 9: [NetworkManager] Move network information into a separate interface (shell). r=fabrice (f532dde13)
- Bug 1167132 - Part 10: [NetworkManager] Move network information into a separate interface (PushService). r=nsm (acb180630)
- Bug 1167132 - Part 11: [NetworkManager] Move network information into a separate interface (Gps). r=kanru (9debb66e7)
- Bug 1167132 - Part 12: [NetworkManager] Move network information into a separate interface (discovery). r=jryans (04249762c)
This commit is contained in:
2021-09-07 15:52:27 +08:00
parent abd7c7a44b
commit 38681ff9e3
58 changed files with 3565 additions and 2033 deletions
+3 -3
View File
@@ -183,9 +183,9 @@ var shell = {
debugCrashReport('Not online, postponing.');
Services.obs.addObserver(function observer(subject, topic, state) {
let network = subject.QueryInterface(Ci.nsINetworkInterface);
if (network.state == Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED
&& network.type == Ci.nsINetworkInterface.NETWORK_TYPE_WIFI) {
let network = subject.QueryInterface(Ci.nsINetworkInfo);
if (network.state == Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED
&& network.type == Ci.nsINetworkInfo.NETWORK_TYPE_WIFI) {
shell.submitQueuedCrashes();
Services.obs.removeObserver(observer, topic);
+2 -2
View File
@@ -504,8 +504,8 @@
@RESPATH@/components/SmsService.js
@RESPATH@/components/SmsService.manifest
#endif
@RESPATH@/components/RILContentHelper.js
@RESPATH@/components/RILContentHelper.manifest
@RESPATH@/components/StkCmdFactory.js
@RESPATH@/components/StkCmdFactory.manifest
@RESPATH@/components/RILSystemMessengerHelper.js
@RESPATH@/components/RILSystemMessengerHelper.manifest
@RESPATH@/components/TelephonyAudioService.js
+1 -1
View File
@@ -38,7 +38,7 @@ IccListener::NotifyIccInfoChanged()
}
NS_IMETHODIMP
IccListener::NotifyStkCommand(const nsAString & aMessage)
IccListener::NotifyStkCommand(nsIStkProactiveCmd *aStkProactiveCmd)
{
return NS_OK;
}
@@ -37,7 +37,7 @@ IccListener::NotifyIccInfoChanged()
}
NS_IMETHODIMP
IccListener::NotifyStkCommand(const nsAString & aMessage)
IccListener::NotifyStkCommand(nsIStkProactiveCmd *aStkProactiveCmd)
{
return NS_OK;
}
+109 -51
View File
@@ -7,19 +7,21 @@
#include "mozilla/dom/Icc.h"
#include "IccCallback.h"
#include "IccContact.h"
#include "mozilla/dom/ContactsBinding.h"
#include "mozilla/dom/DOMRequest.h"
#include "mozilla/dom/IccInfo.h"
#include "mozilla/dom/MozStkCommandEvent.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/ScriptSettings.h"
#include "nsIIccInfo.h"
#include "nsIIccProvider.h"
#include "nsIIccService.h"
#include "nsJSON.h"
#include "nsRadioInterfaceLayer.h"
#include "nsIStkCmdFactory.h"
#include "nsIStkProactiveCmd.h"
#include "nsServiceManagerUtils.h"
using mozilla::dom::icc::IccCallback;
using mozilla::dom::icc::IccContact;
namespace mozilla {
namespace dom {
@@ -56,25 +58,16 @@ NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
NS_IMPL_ADDREF_INHERITED(Icc, DOMEventTargetHelper)
NS_IMPL_RELEASE_INHERITED(Icc, DOMEventTargetHelper)
Icc::Icc(nsPIDOMWindow* aWindow, long aClientId, nsIIcc* aHandler, nsIIccInfo* aIccInfo)
Icc::Icc(nsPIDOMWindow* aWindow, nsIIcc* aHandler, nsIIccInfo* aIccInfo)
: mLive(true)
, mClientId(aClientId)
, mHandler(aHandler)
{
BindToOwner(aWindow);
mProvider = do_GetService(NS_RILCONTENTHELPER_CONTRACTID);
if (aIccInfo) {
aIccInfo->GetIccid(mIccId);
UpdateIccInfo(aIccInfo);
}
// Not being able to acquire the provider isn't fatal since we check
// for it explicitly below.
if (!mProvider) {
NS_WARNING("Could not acquire nsIIccProvider!");
}
}
Icc::~Icc()
@@ -85,7 +78,6 @@ void
Icc::Shutdown()
{
mIccInfo.SetNull();
mProvider = nullptr;
mHandler = nullptr;
mLive = false;
}
@@ -97,7 +89,7 @@ Icc::NotifyEvent(const nsAString& aName)
}
nsresult
Icc::NotifyStkEvent(const nsAString& aName, const nsAString& aMessage)
Icc::NotifyStkEvent(const nsAString& aName, nsIStkProactiveCmd* aStkProactiveCmd)
{
AutoJSAPI jsapi;
if (NS_WARN_IF(!jsapi.InitWithLegacyErrorReporting(GetOwner()))) {
@@ -106,13 +98,12 @@ Icc::NotifyStkEvent(const nsAString& aName, const nsAString& aMessage)
JSContext* cx = jsapi.cx();
JS::Rooted<JS::Value> value(cx);
if (!aMessage.IsEmpty()) {
nsCOMPtr<nsIJSON> json(new nsJSON());
nsresult rv = json->DecodeToJSVal(aMessage, cx, &value);
NS_ENSURE_SUCCESS(rv, rv);
} else {
value = JS::NullValue();
}
nsCOMPtr<nsIStkCmdFactory> cmdFactory =
do_GetService(ICC_STK_CMD_FACTORY_CONTRACTID);
NS_ENSURE_TRUE(cmdFactory, NS_ERROR_UNEXPECTED);
cmdFactory->CreateCommandMessage(aStkProactiveCmd, &value);
NS_ENSURE_TRUE(value.isObject(), NS_ERROR_UNEXPECTED);
MozStkCommandEventInit init;
init.mBubbles = false;
@@ -193,13 +184,33 @@ void
Icc::SendStkResponse(const JSContext* aCx, JS::Handle<JS::Value> aCommand,
JS::Handle<JS::Value> aResponse, ErrorResult& aRv)
{
if (!mProvider) {
if (!mHandler) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
nsresult rv = mProvider->SendStkResponse(mClientId, GetOwner(), aCommand,
aResponse);
nsCOMPtr<nsIStkCmdFactory> cmdFactory =
do_GetService(ICC_STK_CMD_FACTORY_CONTRACTID);
if (!cmdFactory) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
nsCOMPtr<nsIStkProactiveCmd> command;
cmdFactory->CreateCommand(aCommand, getter_AddRefs(command));
if (!command) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
nsCOMPtr<nsIStkTerminalResponse> response;
cmdFactory->CreateResponse(aResponse, getter_AddRefs(response));
if (!response) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
nsresult rv = mHandler->SendStkResponse(command, response);
if (NS_FAILED(rv)) {
aRv.Throw(rv);
}
@@ -209,15 +220,12 @@ void
Icc::SendStkMenuSelection(uint16_t aItemIdentifier, bool aHelpRequested,
ErrorResult& aRv)
{
if (!mProvider) {
if (!mHandler) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
nsresult rv = mProvider->SendStkMenuSelection(mClientId,
GetOwner(),
aItemIdentifier,
aHelpRequested);
nsresult rv = mHandler->SendStkMenuSelection(aItemIdentifier, aHelpRequested);
if (NS_FAILED(rv)) {
aRv.Throw(rv);
}
@@ -227,13 +235,38 @@ void
Icc::SendStkTimerExpiration(const JSContext* aCx, JS::Handle<JS::Value> aTimer,
ErrorResult& aRv)
{
if (!mProvider) {
if (!mHandler) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
nsresult rv = mProvider->SendStkTimerExpiration(mClientId, GetOwner(),
aTimer);
nsCOMPtr<nsIStkCmdFactory> cmdFactory =
do_GetService(ICC_STK_CMD_FACTORY_CONTRACTID);
if (!cmdFactory) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
nsCOMPtr<nsIStkTimer> timer;
cmdFactory->CreateTimer(aTimer, getter_AddRefs(timer));
if (!timer) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
uint16_t timerId;
nsresult rv = timer->GetTimerId(&timerId);
if (NS_FAILED(rv)) {
aRv.Throw(rv);
}
uint32_t timerValue;
rv = timer->GetTimerValue(&timerValue);
if (NS_FAILED(rv)) {
aRv.Throw(rv);
}
rv = mHandler->SendStkTimerExpiration(timerId, timerValue);
if (NS_FAILED(rv)) {
aRv.Throw(rv);
}
@@ -243,12 +276,26 @@ void
Icc::SendStkEventDownload(const JSContext* aCx, JS::Handle<JS::Value> aEvent,
ErrorResult& aRv)
{
if (!mProvider) {
if (!mHandler) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
nsresult rv = mProvider->SendStkEventDownload(mClientId, GetOwner(), aEvent);
nsCOMPtr<nsIStkCmdFactory> cmdFactory =
do_GetService(ICC_STK_CMD_FACTORY_CONTRACTID);
if (!cmdFactory) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
nsCOMPtr<nsIStkDownloadEvent> event;
cmdFactory->CreateEvent(aEvent, getter_AddRefs(event));
if (!event) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
nsresult rv = mHandler->SendStkEventDownload(event);
if (NS_FAILED(rv)) {
aRv.Throw(rv);
}
@@ -363,44 +410,55 @@ Icc::GetCardLockRetryCount(IccLockType aLockType, ErrorResult& aRv)
already_AddRefed<DOMRequest>
Icc::ReadContacts(IccContactType aContactType, ErrorResult& aRv)
{
if (!mProvider) {
if (!mHandler) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
nsRefPtr<nsIDOMDOMRequest> request;
nsresult rv = mProvider->ReadContacts(mClientId, GetOwner(),
static_cast<uint32_t>(aContactType),
getter_AddRefs(request));
nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
nsRefPtr<IccCallback> requestCallback =
new IccCallback(GetOwner(), request);
nsresult rv = mHandler->ReadContacts(static_cast<uint32_t>(aContactType),
requestCallback);
if (NS_FAILED(rv)) {
aRv.Throw(rv);
return nullptr;
}
return request.forget().downcast<DOMRequest>();
return request.forget();
}
already_AddRefed<DOMRequest>
Icc::UpdateContact(const JSContext* aCx, IccContactType aContactType,
JS::Handle<JS::Value> aContact, const nsAString& aPin2,
ErrorResult& aRv)
Icc::UpdateContact(IccContactType aContactType, mozContact& aContact,
const nsAString& aPin2, ErrorResult& aRv)
{
if (!mProvider) {
if (!mHandler) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
nsRefPtr<nsIDOMDOMRequest> request;
nsresult rv = mProvider->UpdateContact(mClientId, GetOwner(),
static_cast<uint32_t>(aContactType),
aContact, aPin2,
getter_AddRefs(request));
nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
nsRefPtr<IccCallback> requestCallback =
new IccCallback(GetOwner(), request);
nsCOMPtr<nsIIccContact> iccContact;
nsresult rv = IccContact::Create(aContact, getter_AddRefs(iccContact));
if (NS_FAILED(rv)) {
aRv.Throw(rv);
return nullptr;
}
return request.forget().downcast<DOMRequest>();
rv = mHandler->UpdateContact(static_cast<uint32_t>(aContactType),
iccContact,
aPin2,
requestCallback);
if (NS_FAILED(rv)) {
aRv.Throw(rv);
return nullptr;
}
return request.forget();
}
already_AddRefed<DOMRequest>
+6 -10
View File
@@ -13,12 +13,14 @@
class nsIIcc;
class nsIIccInfo;
class nsIIccProvider;
class nsIStkProactiveCmd;
namespace mozilla {
namespace dom {
class DOMRequest;
class OwningMozIccInfoOrMozGsmIccInfoOrMozCdmaIccInfo;
class mozContact;
class Promise;
class Icc final : public DOMEventTargetHelper
@@ -28,8 +30,7 @@ public:
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(Icc, DOMEventTargetHelper)
NS_REALLY_FORWARD_NSIDOMEVENTTARGET(DOMEventTargetHelper)
Icc(nsPIDOMWindow* aWindow, long aClientId,
nsIIcc* aHandler, nsIIccInfo* aIccInfo);
Icc(nsPIDOMWindow* aWindow, nsIIcc* aHandler, nsIIccInfo* aIccInfo);
void
Shutdown();
@@ -38,7 +39,7 @@ public:
NotifyEvent(const nsAString& aName);
nsresult
NotifyStkEvent(const nsAString& aName, const nsAString& aMessage);
NotifyStkEvent(const nsAString& aName, nsIStkProactiveCmd* aStkProactiveCmd);
nsString
GetIccId()
@@ -98,9 +99,8 @@ public:
ReadContacts(IccContactType aContactType, ErrorResult& aRv);
already_AddRefed<DOMRequest>
UpdateContact(const JSContext* aCx, IccContactType aContactType,
JS::Handle<JS::Value> aContact, const nsAString& aPin2,
ErrorResult& aRv);
UpdateContact(IccContactType aContactType, mozContact& aContact,
const nsAString& aPin2, ErrorResult& aRv);
already_AddRefed<DOMRequest>
MatchMvno(IccMvnoType aMvnoType, const nsAString& aMatchData,
@@ -121,11 +121,7 @@ private:
~Icc();
bool mLive;
uint32_t mClientId;
nsString mIccId;
// mProvider is a xpcom service and will be released at Shutdown(), so it
// doesn't need to be cycle collected.
nsCOMPtr<nsIIccProvider> mProvider;
// mHandler will be released at Shutdown(), so there is no need to join cycle
// collection.
nsCOMPtr<nsIIcc> mHandler;
+151
View File
@@ -6,10 +6,12 @@
#include "IccCallback.h"
#include "mozilla/dom/ContactsBinding.h"
#include "mozilla/dom/IccCardLockError.h"
#include "mozilla/dom/MozIccBinding.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/ToJSValue.h"
#include "nsIIccContact.h"
#include "nsJSUtils.h"
#include "nsServiceManagerUtils.h"
@@ -17,6 +19,97 @@ namespace mozilla {
namespace dom {
namespace icc {
namespace {
static nsresult
IccContactToMozContact(JSContext* aCx, GlobalObject& aGlobal,
nsIIccContact* aIccContact,
mozContact** aMozContact)
{
*aMozContact = nullptr;
ContactProperties properties;
// Names
char16_t** rawStringArray = nullptr;
uint32_t count = 0;
nsresult rv = aIccContact->GetNames(&count, &rawStringArray);
NS_ENSURE_SUCCESS(rv, rv);
if (count > 0) {
Sequence<nsString>& nameSeq = properties.mName.Construct().SetValue();
for (uint32_t i = 0; i < count; i++) {
nameSeq.AppendElement(nsDependentString(rawStringArray[i]), fallible);
}
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(count, rawStringArray);
}
// Numbers
rawStringArray = nullptr;
count = 0;
rv = aIccContact->GetNumbers(&count, &rawStringArray);
NS_ENSURE_SUCCESS(rv, rv);
if (count > 0) {
Sequence<ContactTelField>& numberSeq = properties.mTel.Construct().SetValue();
for (uint32_t i = 0; i < count; i++) {
ContactTelField number;
number.mValue.Construct() = nsDependentString(rawStringArray[i]);
numberSeq.AppendElement(number, fallible);
}
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(count, rawStringArray);
}
// Emails
rawStringArray = nullptr;
count = 0;
rv = aIccContact->GetEmails(&count, &rawStringArray);
NS_ENSURE_SUCCESS(rv, rv);
if (count > 0) {
Sequence<ContactField>& emailSeq = properties.mEmail.Construct().SetValue();
for (uint32_t i = 0; i < count; i++) {
ContactField email;
email.mValue.Construct() = nsDependentString(rawStringArray[i]);
emailSeq.AppendElement(email, fallible);
}
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(count, rawStringArray);
}
ErrorResult er;
nsRefPtr<mozContact> contact
= mozContact::Constructor(aGlobal, aCx, properties, er);
NS_ENSURE_FALSE(er.Failed(), er.StealNSResult());
nsAutoString contactId;
rv = aIccContact->GetId(contactId);
NS_ENSURE_SUCCESS(rv, rv);
contact->SetId(contactId, er);
NS_ENSURE_FALSE(er.Failed(), er.StealNSResult());
contact.forget(aMozContact);
return NS_OK;
}
static NS_IMETHODIMP
IccContactListToMozContactList(JSContext* aCx, GlobalObject& aGlobal,
nsIIccContact** aContacts, uint32_t aCount,
nsTArray<nsRefPtr<mozContact>>& aContactList)
{
aContactList.SetCapacity(aCount);
for (uint32_t i = 0; i < aCount ; i++) {
nsRefPtr<mozContact> contact;
nsresult rv =
IccContactToMozContact(aCx, aGlobal, aContacts[i], getter_AddRefs(contact));
NS_ENSURE_SUCCESS(rv, rv);
aContactList.AppendElement(contact);
}
return NS_OK;
}
} // anonymous namespace
NS_IMPL_ISUPPORTS(IccCallback, nsIIccCallback)
IccCallback::IccCallback(nsPIDOMWindow* aWindow, DOMRequest* aRequest,
@@ -132,6 +225,64 @@ IccCallback::NotifyCardLockError(const nsAString & aErrorMsg,
return NS_OK;
}
NS_IMETHODIMP
IccCallback::NotifyRetrievedIccContacts(nsIIccContact** aContacts,
uint32_t aCount)
{
MOZ_ASSERT(aContacts);
AutoJSAPI jsapi;
if (NS_WARN_IF(!jsapi.Init(mWindow))) {
return NS_ERROR_FAILURE;
}
JSContext* cx = jsapi.cx();
nsCOMPtr<nsIGlobalObject> go = do_QueryInterface(mWindow);
GlobalObject global(cx, go->GetGlobalJSObject());
nsTArray<nsRefPtr<mozContact>> contactList;
nsresult rv =
IccContactListToMozContactList(cx, global, aContacts, aCount, contactList);
NS_ENSURE_SUCCESS(rv, rv);
JS::Rooted<JS::Value> jsResult(cx);
if (!ToJSValue(cx, contactList, &jsResult)) {
return NS_ERROR_FAILURE;
}
return NotifySuccess(jsResult);
}
NS_IMETHODIMP
IccCallback::NotifyUpdatedIccContact(nsIIccContact* aContact)
{
MOZ_ASSERT(aContact);
AutoJSAPI jsapi;
if (NS_WARN_IF(!jsapi.Init(mWindow))) {
return NS_ERROR_FAILURE;
}
JSContext* cx = jsapi.cx();
nsCOMPtr<nsIGlobalObject> go = do_QueryInterface(mWindow);
GlobalObject global(cx, go->GetGlobalJSObject());
nsRefPtr<mozContact> mozContact;
nsresult rv =
IccContactToMozContact(cx, global, aContact, getter_AddRefs(mozContact));
NS_ENSURE_SUCCESS(rv, rv);
JS::Rooted<JS::Value> jsResult(cx);
if (!ToJSValue(cx, mozContact, &jsResult)) {
return NS_ERROR_FAILURE;
}
return NotifySuccess(jsResult);
}
} // namespace icc
} // namespace dom
} // namespace mozilla
+145
View File
@@ -0,0 +1,145 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "IccContact.h"
#include "mozilla/dom/ContactsBinding.h"
#include "nsReadableUtils.h"
using namespace mozilla::dom::icc;
using mozilla::dom::mozContact;
NS_IMPL_ISUPPORTS(IccContact, nsIIccContact)
/* static */ nsresult
IccContact::Create(mozContact& aMozContact, nsIIccContact** aIccContact)
{
*aIccContact = nullptr;
ErrorResult er;
// Id
nsAutoString id;
aMozContact.GetId(id, er);
NS_ENSURE_SUCCESS(er.StealNSResult(), NS_ERROR_FAILURE);
// Names
Nullable<nsTArray<nsString>> names;
aMozContact.GetName(names, er);
NS_ENSURE_SUCCESS(er.StealNSResult(), NS_ERROR_FAILURE);
if (names.IsNull()) {
// Set as Empty nsTarray<nsString> for IccContact constructor.
names.SetValue();
}
// Numbers
Nullable<nsTArray<ContactTelField>> nullableNumberList;
aMozContact.GetTel(nullableNumberList, er);
NS_ENSURE_SUCCESS(er.StealNSResult(), NS_ERROR_FAILURE);
nsTArray<nsString> numbers;
if (!nullableNumberList.IsNull()) {
const nsTArray<ContactTelField>& numberList = nullableNumberList.Value();
for (uint32_t i = 0; i < numberList.Length(); i++) {
if (numberList[i].mValue.WasPassed()) {
numbers.AppendElement(numberList[i].mValue.Value());
}
}
}
// Emails
Nullable<nsTArray<ContactField>> nullableEmailList;
aMozContact.GetEmail(nullableEmailList, er);
NS_ENSURE_SUCCESS(er.StealNSResult(), NS_ERROR_FAILURE);
nsTArray<nsString> emails;
if (!nullableEmailList.IsNull()) {
const nsTArray<ContactField>& emailList = nullableEmailList.Value();
for (uint32_t i = 0; i < emailList.Length(); i++) {
if (emailList[i].mValue.WasPassed()) {
emails.AppendElement(emailList[i].mValue.Value());
}
}
}
nsCOMPtr<nsIIccContact> iccContact = new IccContact(id,
names.Value(),
numbers,
emails);
iccContact.forget(aIccContact);
return NS_OK;
}
/*static*/ nsresult
IccContact::Create(const nsAString& aId,
const nsTArray<nsString>& aNames,
const nsTArray<nsString>& aNumbers,
const nsTArray<nsString>& aEmails,
nsIIccContact** aIccContact)
{
*aIccContact = nullptr;
nsCOMPtr<nsIIccContact> iccContact = new IccContact(aId,
aNames,
aNumbers,
aEmails);
iccContact.forget(aIccContact);
return NS_OK;
}
IccContact::IccContact(const nsAString& aId,
const nsTArray<nsString>& aNames,
const nsTArray<nsString>& aNumbers,
const nsTArray<nsString>& aEmails)
: mId(aId),
mNames(aNames),
mNumbers(aNumbers),
mEmails(aEmails)
{
}
// nsIIccInfo implementation.
NS_IMETHODIMP IccContact::GetId(nsAString & aId)
{
aId = mId;
return NS_OK;
}
#define ICCCONTACT_IMPL_GET_CONTACT_FIELD(_field) \
NS_IMETHODIMP IccContact::Get##_field(uint32_t* aCount, char16_t*** a##_field) \
{ \
NS_ENSURE_ARG_POINTER(aCount); \
NS_ENSURE_ARG_POINTER(a##_field); \
\
*aCount = 0; \
*a##_field = nullptr; \
\
uint32_t count = m##_field.Length(); \
if (count == 0) { \
return NS_OK; \
} \
char16_t** temp = \
static_cast<char16_t**>(moz_xmalloc(sizeof(char16_t*) * (count))); \
if (temp == nullptr) { \
return NS_ERROR_OUT_OF_MEMORY; \
} \
for (uint32_t i = 0; i < count; i++) { \
(temp)[i] = ToNewUnicode(m##_field[i]); \
if (!(temp)[i]) { \
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(i, temp); \
return NS_ERROR_OUT_OF_MEMORY; \
} \
} \
\
*aCount = count; \
*a##_field = temp; \
\
return NS_OK; \
}
ICCCONTACT_IMPL_GET_CONTACT_FIELD(Names)
ICCCONTACT_IMPL_GET_CONTACT_FIELD(Numbers)
ICCCONTACT_IMPL_GET_CONTACT_FIELD(Emails)
#undef ICCCONTACT_GET_CONTACT_FIELD
+50
View File
@@ -0,0 +1,50 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_icc_IccContact_h
#define mozilla_dom_icc_IccContact_h
#include "nsIIccContact.h"
namespace mozilla {
namespace dom {
class mozContact;
namespace icc {
class IccContact : public nsIIccContact
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIICCCONTACT
static nsresult
Create(mozContact& aMozContact,
nsIIccContact** aIccContact);
static nsresult
Create(const nsAString& aId,
const nsTArray<nsString>& aNames,
const nsTArray<nsString>& aNumbers,
const nsTArray<nsString>& aEmails,
nsIIccContact** aIccContact);
private:
IccContact(const nsAString& aId,
const nsTArray<nsString>& aNames,
const nsTArray<nsString>& aNumbers,
const nsTArray<nsString>& aEmails);
virtual ~IccContact() {}
nsString mId;
nsTArray<nsString> mNames;
nsTArray<nsString> mNumbers;
nsTArray<nsString> mEmails;
};
} // namespace icc
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_icc_IccContact_h
+4 -25
View File
@@ -10,7 +10,6 @@
#include "IccManager.h"
#include "nsIDOMClassInfo.h"
#include "nsIIccInfo.h"
#include "nsRadioInterfaceLayer.h"
using namespace mozilla::dom;
@@ -22,15 +21,6 @@ IccListener::IccListener(IccManager* aIccManager, uint32_t aClientId)
{
MOZ_ASSERT(mIccManager);
// TODO: Bug 1114938, Refactor STK in MozIcc.webidl with IPDL.
// Remove the registration to IccProvider.
mProvider = do_GetService(NS_RILCONTENTHELPER_CONTRACTID);
if (!mProvider) {
NS_WARNING("Could not acquire nsIIccProvider!");
return;
}
nsCOMPtr<nsIIccService> iccService = do_GetService(ICC_SERVICE_CONTRACTID);
if (!iccService) {
@@ -50,17 +40,13 @@ IccListener::IccListener(IccManager* aIccManager, uint32_t aClientId)
nsString iccId;
iccInfo->GetIccid(iccId);
if (!iccId.IsEmpty()) {
mIcc = new Icc(mIccManager->GetOwner(), mClientId, mHandler, iccInfo);
mIcc = new Icc(mIccManager->GetOwner(), mHandler, iccInfo);
}
}
DebugOnly<nsresult> rv = mHandler->RegisterListener(this);
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv),
"Failed registering icc listener with Icc Handler");
rv = mProvider->RegisterIccMsg(mClientId, this);
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv),
"Failed registering icc messages with provider");
}
IccListener::~IccListener()
@@ -71,13 +57,6 @@ IccListener::~IccListener()
void
IccListener::Shutdown()
{
// TODO: Bug 1114938, Refactor STK in MozIcc.webidl with IPDL.
// Remove the unregistration to IccProvider.
if (mProvider) {
mProvider->UnregisterIccMsg(mClientId, this);
mProvider = nullptr;
}
if (mHandler) {
mHandler->UnregisterListener(this);
mHandler = nullptr;
@@ -94,13 +73,13 @@ IccListener::Shutdown()
// nsIIccListener
NS_IMETHODIMP
IccListener::NotifyStkCommand(const nsAString& aMessage)
IccListener::NotifyStkCommand(nsIStkProactiveCmd *aStkProactiveCmd)
{
if (!mIcc) {
return NS_OK;
}
return mIcc->NotifyStkEvent(NS_LITERAL_STRING("stkcommand"), aMessage);
return mIcc->NotifyStkEvent(NS_LITERAL_STRING("stkcommand"), aStkProactiveCmd);
}
NS_IMETHODIMP
@@ -143,7 +122,7 @@ IccListener::NotifyIccInfoChanged()
nsString iccId;
iccInfo->GetIccid(iccId);
if (!iccId.IsEmpty()) {
mIcc = new Icc(mIccManager->GetOwner(), mClientId, mHandler, iccInfo);
mIcc = new Icc(mIccManager->GetOwner(), mHandler, iccInfo);
mIccManager->NotifyIccAdd(iccId);
mIcc->NotifyEvent(NS_LITERAL_STRING("iccinfochange"));
}
-4
View File
@@ -8,7 +8,6 @@
#define mozilla_dom_IccListener_h
#include "nsAutoPtr.h"
#include "nsIIccProvider.h"
#include "nsIIccService.h"
namespace mozilla {
@@ -45,9 +44,6 @@ private:
// IccListener, this will release the reference and break the cycle.
nsRefPtr<Icc> mIcc;
nsRefPtr<IccManager> mIccManager;
// mProvider is a xpcom service and will be released at Shutdown(), so it
// doesn't need to be cycle collected.
nsCOMPtr<nsIIccProvider> mProvider;
// mHandler will be released at Shutdown(), there is no need to join cycle
// collection.
nsCOMPtr<nsIIcc> mHandler;
+200 -1
View File
@@ -29,6 +29,14 @@ XPCOMUtils.defineLazyServiceGetter(this, "gMobileConnectionService",
"@mozilla.org/mobileconnection/mobileconnectionservice;1",
"nsIGonkMobileConnectionService");
XPCOMUtils.defineLazyServiceGetter(this, "gIccMessenger",
"@mozilla.org/ril/system-messenger-helper;1",
"nsIIccMessenger");
XPCOMUtils.defineLazyServiceGetter(this, "gStkCmdFactory",
"@mozilla.org/icc/stkcmdfactory;1",
"nsIStkCmdFactory");
let DEBUG = RIL.DEBUG_RIL;
function debug(s) {
dump("IccService: " + s);
@@ -72,6 +80,86 @@ CdmaIccInfo.prototype = {
prlVersion: 0
};
function IccContact(aContact) {
this.id = aContact.contactId || null;
this._names = [];
this._numbers = [];
this._emails = [];
if (aContact.alphaId) {
this._names.push(aContact.alphaId);
}
if (aContact.number) {
this._numbers.push(aContact.number);
}
let anrLen = aContact.anr ? aContact.anr.length : 0;
for (let i = 0; i < anrLen; i++) {
this._numbers.push(anr[i]);
}
if (aContact.email) {
this._emails.push(aContact.email);
}
}
IccContact.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIIccContact]),
_names: null,
_numbers: null,
_emails: null,
// nsIIccContact
id: null,
getNames: function(aCount) {
if (!this._names) {
if (aCount) {
aCount.value = 0;
}
return null;
}
if (aCount) {
aCount.value = this._names.length;
}
return this._names.slice();
},
getNumbers: function(aCount) {
if (!this._numbers) {
if (aCount) {
aCount.value = 0;
}
return null;
}
if (aCount) {
aCount.value = this._numbers.length;
}
return this._numbers.slice();
},
getEmails: function(aCount) {
if (!this._emails) {
if (aCount) {
aCount.value = 0;
}
return null;
}
if (aCount) {
aCount.value = this._emails.length;
}
return this._emails.slice();
},
};
function IccService() {
this._iccs = [];
@@ -124,6 +212,27 @@ IccService.prototype = {
/**
* nsIGonkIccService interface.
*/
notifyStkCommand: function(aServiceId, aStkcommand) {
if (DEBUG) {
debug("notifyStkCommand for service Id: " + aServiceId);
}
let icc = this.getIccByServiceId(aServiceId);
gIccMessenger.notifyStkProactiveCommand(icc.iccInfo.iccid, aStkcommand);
icc._deliverListenerEvent("notifyStkCommand", [aStkcommand]);
},
notifyStkSessionEnd: function(aServiceId) {
if (DEBUG) {
debug("notifyStkSessionEnd for service Id: " + aServiceId);
}
this.getIccByServiceId(aServiceId)
._deliverListenerEvent("notifyStkSessionEnd");
},
notifyCardStateChanged: function(aServiceId, aCardState) {
if (DEBUG) {
debug("notifyCardStateChanged for service Id: " + aServiceId +
@@ -536,7 +645,97 @@ Icc.prototype = {
aCallback.notifyCloseChannelSuccess();
});
}
},
sendStkResponse: function(aCommand, aResponse) {
let response = gStkCmdFactory.createResponseMessage(aResponse);
response.command = gStkCmdFactory.createCommandMessage(aCommand);
this._radioInterface.sendWorkerMessage("sendStkTerminalResponse", response);
},
sendStkMenuSelection: function(aItemIdentifier, aHelpRequested) {
this._radioInterface
.sendWorkerMessage("sendStkMenuSelection", {
itemIdentifier: aItemIdentifier,
helpRequested: aHelpRequested
});
},
sendStkTimerExpiration: function(aTimerId, aTimerValue) {
this._radioInterface
.sendWorkerMessage("sendStkTimerExpiration",{
timer: {
timerId: aTimerId,
timerValue: aTimerValue
}
});
},
sendStkEventDownload: function(aEvent) {
this._radioInterface
.sendWorkerMessage("sendStkEventDownload",
{ event: gStkCmdFactory.createEventMessage(aEvent) });
},
readContacts: function(aContactType, aCallback) {
this._radioInterface
.sendWorkerMessage("readICCContacts",
{ contactType: aContactType },
(aResponse) => {
if (aResponse.errorMsg) {
aCallback.notifyError(aResponse.errorMsg);
return;
}
let iccContacts = [];
aResponse.contacts.forEach(c => iccContacts.push(new IccContact(c)));
aCallback.notifyRetrievedIccContacts(iccContacts, iccContacts.length);
});
},
updateContact: function(aContactType, aContact, aPin2, aCallback) {
let iccContact = { contactId: aContact.id };
let count = { value: 0 };
let names = aContact.getNames(count);
if (count.value > 0) {
iccContact.alphaId = names[0];
}
let numbers = aContact.getNumbers(count);
if (count.value > 0) {
iccContact.number = numbers[0];
let anrArray = numbers.slice(1);
let length = anrArray.length;
if (length > 0) {
iccContact.anr = [];
for (let i = 0; i < length; i++) {
iccContact.anr.push(anrArray[i].value);
}
}
}
let emails = aContact.getEmails(count);
if (count.value > 0) {
iccContact.email = emails[0];
}
this._radioInterface
.sendWorkerMessage("updateICCContact",
{ contactType: aContactType,
contact: iccContact,
pin2: aPin2 },
(aResponse) => {
if (aResponse.errorMsg) {
aCallback.notifyError(aResponse.errorMsg);
return;
}
aCallback.notifyUpdatedIccContact(new IccContact(aResponse.contact));
});
},
};
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([IccService]);
@@ -11,6 +11,9 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
let RIL = {};
Cu.import("resource://gre/modules/ril_consts.js", RIL);
const GONK_STKCMDFACTORY_CONTRACTID = "@mozilla.org/icc/stkcmdfactory;1";
const GONK_STKCMDFACTORY_CID = Components.ID("{7a663440-e336-11e4-8fd5-c3140a7ff307}");
/**
* Helper Utilities to convert JS Objects to IDL Objects.
*/
@@ -64,7 +67,7 @@ function appendIconInfo(aTarget, aStkIconInfo) {
/**
* The implementation of the data types used in variant types of
* StkProactiveCommand.
* StkProactiveCommand, StkTerminalResponse, StkDownloadEvent.
*/
function StkDuration(aTimeUnit, aTimeInterval) {
@@ -177,11 +180,27 @@ StkTimer.prototype = {
// nsIStkTimer
timerId: 0,
timerValue: Ci.nsIStkTimer.TIMER_VALUE_INVALID,
timerAction: 0
timerAction: Ci.nsIStkTimer.TIMER_ACTION_INVALID
};
function StkLocationInfo(aMcc, aMnc, aGsmLocationAreaCode, aGsmCellId) {
this.mcc = aMcc;
this.mnc = aMnc;
this.gsmLocationAreaCode = aGsmLocationAreaCode;
this.gsmCellId = aGsmCellId;
}
StkLocationInfo.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIStkLocationInfo]),
// nsIStkLocationInfo
mcc: null,
mnc: null,
gsmLocationAreaCode: -1,
gsmCellId: -1
};
/**
* The implementation of nsIStkProactiveCommand Set and STK System Message Set.
* The implementation of nsIStkProactiveCommand set and paired JS object set.
*/
function StkProactiveCommand(aCommandDetails) {
this.commandNumber = aCommandDetails.commandNumber;
@@ -995,14 +1014,444 @@ QueriedIFs[RIL.STK_CMD_CLOSE_CHANNEL] = Ci.nsIStkTextMessageCmd;
QueriedIFs[RIL.STK_CMD_SEND_DATA] = Ci.nsIStkTextMessageCmd;
QueriedIFs[RIL.STK_CMD_RECEIVE_DATA] = Ci.nsIStkTextMessageCmd;
/**
* The implementation of nsIStkTerminalResponse set and paired JS object set.
*/
function StkTerminalResponse(aResponseMessage) {
this.resultCode = aResponseMessage.resultCode;
if (aResponseMessage.additionalInformation != undefined) {
this.additionalInformation = aResponseMessage.additionalInformation;
}
}
StkTerminalResponse.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIStkTerminalResponse]),
// nsIStkTerminalResponse
resultCode: 0,
additionalInformation: Ci.nsIStkTerminalResponse.ADDITIONAL_INFO_INVALID
};
function StkResponseMessage(aStkTerminalResponse) {
this.resultCode = aStkTerminalResponse.resultCode;
if (aStkTerminalResponse.additionalInformation
!== Ci.nsIStkTerminalResponse.ADDITIONAL_INFO_INVALID) {
this.additionalInformation = aStkTerminalResponse.additionalInformation;
}
}
StkResponseMessage.prototype = {
resultCode: Ci.nsIStkTerminalResponse.RESULT_OK
};
function StkSelectItemResponse(aStkSelectItemResponseMessage) {
// Call |StkTerminalResponse| constructor.
StkTerminalResponse.call(this, aStkSelectItemResponseMessage);
this.itemIdentifier = aStkSelectItemResponseMessage.itemIdentifier;
}
StkSelectItemResponse.prototype = Object.create(StkTerminalResponse.prototype, {
QueryInterface: {
value: XPCOMUtils.generateQI([Ci.nsIStkTerminalResponse,
Ci.nsIStkSelectItemResponse])
},
// nsIStkSelectItemResponse
itemIdentifier: { value: 0, writable: true }
});
function StkSelectItemResponseMessage(aStkSelectItemResponse) {
// Call |StkResponseMessage| constructor.
StkResponseMessage.call(this, aStkSelectItemResponse);
this.itemIdentifier = aStkSelectItemResponse.itemIdentifier;
}
StkSelectItemResponseMessage.prototype = Object.create(StkResponseMessage.prototype);
function StkGetInputResponse(aStkGetInputResponseMessage) {
// Call |StkTerminalResponse| constructor.
StkTerminalResponse.call(this, aStkGetInputResponseMessage);
if (aStkGetInputResponseMessage.isYesNo !== undefined) {
this.isYesNo = (aStkGetInputResponseMessage.isYesNo)
? Ci.nsIStkGetInputResponse.YES
: Ci.nsIStkGetInputResponse.NO;
}
if (aStkGetInputResponseMessage.input !== undefined) {
// We expect input to be "" if user confirmed the input with nothing,
// and we use null to present 'undefined' internally for the conversion
// between nsIStkTerminalResponse and JS objects.
this.input = aStkGetInputResponseMessage.input || "";
}
}
StkGetInputResponse.prototype = Object.create(StkTerminalResponse.prototype, {
QueryInterface: {
value: XPCOMUtils.generateQI([Ci.nsIStkTerminalResponse,
Ci.nsIStkGetInputResponse])
},
// nsIStkGetInputResponse
isYesNo: { value: Ci.nsIStkGetInputResponse.YES_NO_INVALID, writable: true },
input: { value: null, writable: true }
});
function StkGetInputResponseMessage(aStkGetInputResponse) {
// Call |StkResponseMessage| constructor.
StkResponseMessage.call(this, aStkGetInputResponse);
if (aStkGetInputResponse.isYesNo !== Ci.nsIStkGetInputResponse.YES_NO_INVALID) {
this.isYesNo = !!aStkGetInputResponse.isYesNo;
}
if (aStkGetInputResponse.input !== null) {
this.input = aStkGetInputResponse.input;
}
}
StkGetInputResponseMessage.prototype = Object.create(StkResponseMessage.prototype);
function StkCallSetupResponse(aStkCallSetupResponseMessage) {
// Call |StkTerminalResponse| constructor.
StkTerminalResponse.call(this, aStkCallSetupResponseMessage);
this.hasConfirmed = !! aStkCallSetupResponseMessage.hasConfirmed;
}
StkCallSetupResponse.prototype = Object.create(StkTerminalResponse.prototype, {
QueryInterface: {
value: XPCOMUtils.generateQI([Ci.nsIStkTerminalResponse,
Ci.nsIStkCallSetupResponse])
},
// nsIStkCallSetupResponse
hasConfirmed: { value: false, writable: true }
});
function StkCallSetupResponseMessage(aStkCallSetupResponse) {
// Call |StkResponseMessage| constructor.
StkResponseMessage.call(this, aStkCallSetupResponse);
this.hasConfirmed = aStkCallSetupResponse.hasConfirmed;
}
StkCallSetupResponseMessage.prototype = Object.create(StkResponseMessage.prototype);
function StkLocalInfoResponse(aStkLocalInfoResponseMessage) {
// Call |StkTerminalResponse| constructor.
StkTerminalResponse.call(this, aStkLocalInfoResponseMessage);
let localInfo = aStkLocalInfoResponseMessage.localInfo;
if (localInfo.imei) {
this.imei = localInfo.imei;
return;
}
if (localInfo.locationInfo) {
let info = localInfo.locationInfo;
this.locationInfo = new StkLocationInfo(info.mcc,
info.mnc,
info.gsmLocationAreaCode,
info.gsmCellId);
return;
}
if (localInfo.date) {
if (localInfo.date instanceof Date) {
this.date = localInfo.date.getTime();
} else {
// JSON is adopted as our IPDL protocol, so Date object will be presented as
// a String in ISO8601 format by JSON.
// For the conversion between Date and JSON, please see:
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toJSON#Example:_Using_toJSON
this.date = new Date(localInfo.date).getTime();
}
return;
}
if (localInfo.language) {
this.language = localInfo.language;
return;
}
}
StkLocalInfoResponse.prototype = Object.create(StkTerminalResponse.prototype, {
QueryInterface: {
value: XPCOMUtils.generateQI([Ci.nsIStkTerminalResponse,
Ci.nsIStkLocalInfoResponse])
},
// nsIStkLocalInfoResponse
imei: { value: null, writable: true },
locationInfo: { value: null, writable: true },
date: { value: Ci.nsIStkLocalInfoResponse.DATE_INVALID, writable: true },
language: { value: null, writable: true },
});
function StkLocalInfoResponseMessage(aStkLocalInfoResponse) {
// Call |StkResponseMessage| constructor.
StkResponseMessage.call(this, aStkLocalInfoResponse);
let localInfo = this.localInfo = {};
if (aStkLocalInfoResponse.imei) {
localInfo.imei = aStkLocalInfoResponse.imei;
return;
}
if (aStkLocalInfoResponse.locationInfo) {
let srcInfo = aStkLocalInfoResponse.locationInfo;
let destInfo = localInfo.locationInfo = {};
destInfo.mcc = srcInfo.mcc;
destInfo.mnc = srcInfo.mnc;
destInfo.gsmLocationAreaCode = srcInfo.gsmLocationAreaCode;
destInfo.gsmCellId = srcInfo.gsmCellId;
return;
}
if (aStkLocalInfoResponse.date !== Ci.nsIStkLocalInfoResponse.DATE_INVALID) {
localInfo.date = new Date(aStkLocalInfoResponse.date);
return;
}
if (aStkLocalInfoResponse.language) {
localInfo.language = aStkLocalInfoResponse.language;
return;
}
}
StkLocalInfoResponseMessage.prototype = Object.create(StkResponseMessage.prototype);
function StkTimerResponse(aStkTimerResponseMessage) {
// Call |StkTerminalResponse| constructor.
StkTerminalResponse.call(this, aStkTimerResponseMessage);
let timer = aStkTimerResponseMessage.timer;
// timerAction is useless in Terminal Response,
// so we always set it to TIMER_ACTION_INVALID.
this.timer = new StkTimer(timer.timerId,
Math.floor(timer.timerValue),
Ci.nsIStkTimer.TIMER_ACTION_INVALID);
}
StkTimerResponse.prototype = Object.create(StkTerminalResponse.prototype, {
QueryInterface: {
value: XPCOMUtils.generateQI([Ci.nsIStkTerminalResponse,
Ci.nsIStkTimerResponse])
},
// nsIStkTimerResponse
timer: { value: null, writable: true }
});
function StkTimerResponseMessage(aStkTimerResponse) {
// Call |StkResponseMessage| constructor.
StkResponseMessage.call(this, aStkTimerResponse);
let timer = this.timer = {};
// timerAction is meaningless for terminal response.
timer.timerId = aStkTimerResponse.timer.timerId;
timer.timerValue = aStkTimerResponse.timer.timerValue;
}
StkTimerResponseMessage.prototype = Object.create(StkResponseMessage.prototype);
/**
* The implementation of nsIStkDownloadEvent set and paired JS object set.
*/
function StkDownloadEvent(aEventMessage) {
this.eventType = aEventMessage.eventType;
}
StkDownloadEvent.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIStkDownloadEvent]),
// nsIStkDownloadEvent
eventType: 0
};
function StkEventMessage(aStkDownloadEvent) {
this.eventType = aStkDownloadEvent.eventType;
}
StkEventMessage.prototype = {
eventType: 0
};
function StkLocationEvent(aStkLocationEventMessage) {
// Call |StkDownloadEvent| constructor.
StkDownloadEvent.call(this, aStkLocationEventMessage);
this.locationStatus = aStkLocationEventMessage.locationStatus;
if (this.locationStatus == Ci.nsIStkLocationEvent.SERVICE_STATE_NORMAL &&
aStkLocationEventMessage.locationInfo) {
let info = aStkLocationEventMessage.locationInfo;
this.locationInfo = new StkLocationInfo(info.mcc,
info.mnc,
info.gsmLocationAreaCode,
info.gsmCellId);
}
}
StkLocationEvent.prototype = Object.create(StkDownloadEvent.prototype, {
QueryInterface: {
value: XPCOMUtils.generateQI([Ci.nsIStkDownloadEvent,
Ci.nsIStkLocationEvent])
},
// nsIStkLocationEvent
locationStatus: { value: Ci.nsIStkLocationEvent.SERVICE_STATE_UNAVAILABLE, writable: true },
locationInfo: { value: null, writable: true }
});
function StkLocationEventMessage(aStkLocationEvent) {
// Call |StkEventMessage| constructor.
StkEventMessage.call(this, aStkLocationEvent);
this.locationStatus = aStkLocationEvent.locationStatus;
if (aStkLocationEvent.locationInfo) {
let info = aStkLocationEvent.locationInfo;
this.locationInfo = new StkLocationInfo(info.mcc,
info.mnc,
info.gsmLocationAreaCode,
info.gsmCellId);
}
}
StkLocationEventMessage.prototype = Object.create(StkEventMessage.prototype);
function StkCallEvent(aStkCallEventMessage) {
// Call |StkDownloadEvent| constructor.
StkDownloadEvent.call(this, aStkCallEventMessage);
if (aStkCallEventMessage.number) {
this.number = aStkCallEventMessage.number;
}
this.isIssuedByRemote = !!aStkCallEventMessage.isIssuedByRemote;
if (aStkCallEventMessage.error) {
this.error = aStkCallEventMessage.error;
}
}
StkCallEvent.prototype = Object.create(StkDownloadEvent.prototype, {
QueryInterface: {
value: XPCOMUtils.generateQI([Ci.nsIStkDownloadEvent,
Ci.nsIStkCallEvent])
},
// nsIStkCallEvent
number: { value: null, writable: true },
isIssuedByRemote: { value: false, writable: true },
error: { value: null, writable: true }
});
function StkCallEventMessage(aStkCallEvent) {
// Call |StkEventMessage| constructor.
StkEventMessage.call(this, aStkCallEvent);
this.number = aStkCallEvent.number;
this.isIssuedByRemote = aStkCallEvent.isIssuedByRemote;
this.error = aStkCallEvent.error;
}
StkCallEventMessage.prototype = Object.create(StkEventMessage.prototype);
function StkLanguageSelectionEvent(aStkLanguageSelectionEventMessage) {
// Call |StkDownloadEvent| constructor.
StkDownloadEvent.call(this, aStkLanguageSelectionEventMessage);
if (aStkLanguageSelectionEventMessage.language) {
this.language = aStkLanguageSelectionEventMessage.language;
}
}
StkLanguageSelectionEvent.prototype = Object.create(StkDownloadEvent.prototype, {
QueryInterface: {
value: XPCOMUtils.generateQI([Ci.nsIStkDownloadEvent,
Ci.nsIStkLanguageSelectionEvent])
},
// nsIStkLanguageSelectionEvent
language: { value: null, writable: true }
});
function StkLanguageSelectionEventMessage(aStkLanguageSelectionEvent) {
// Call |StkEventMessage| constructor.
StkEventMessage.call(this, aStkLanguageSelectionEvent);
this.language = aStkLanguageSelectionEvent.language;
}
StkLanguageSelectionEventMessage.prototype = Object.create(StkEventMessage.prototype);
function StkBrowserTerminationEvent(aStkBrowserTerminationEventMessage) {
// Call |StkDownloadEvent| constructor.
StkDownloadEvent.call(this, aStkBrowserTerminationEventMessage);
if (aStkBrowserTerminationEventMessage.terminationCause) {
this.terminationCause = aStkBrowserTerminationEventMessage.terminationCause;
}
}
StkBrowserTerminationEvent.prototype = Object.create(StkDownloadEvent.prototype, {
QueryInterface: {
value: XPCOMUtils.generateQI([Ci.nsIStkDownloadEvent,
Ci.nsIStkBrowserTerminationEvent])
},
// nsIStkBrowserTerminationEvent
terminationCause: { value: Ci.nsIStkBrowserTerminationEvent.BROWSER_TERMINATION_CAUSE_USER, writable: true }
});
function StkBrowserTerminationEventMessage(aStkBrowserTerminationEvent) {
// Call |StkEventMessage| constructor.
StkEventMessage.call(this, aStkBrowserTerminationEvent);
this.terminationCause = aStkBrowserTerminationEvent.terminationCause;
}
StkBrowserTerminationEventMessage.prototype = Object.create(StkEventMessage.prototype);
/**
* Event Prototype Mappings.
*/
let EventPrototypes = {};
EventPrototypes[RIL.STK_EVENT_TYPE_USER_ACTIVITY] = StkDownloadEvent;
EventPrototypes[RIL.STK_EVENT_TYPE_IDLE_SCREEN_AVAILABLE] = StkDownloadEvent;
EventPrototypes[RIL.STK_EVENT_TYPE_MT_CALL] = StkCallEvent;
EventPrototypes[RIL.STK_EVENT_TYPE_CALL_CONNECTED] = StkCallEvent;
EventPrototypes[RIL.STK_EVENT_TYPE_CALL_DISCONNECTED] = StkCallEvent;
EventPrototypes[RIL.STK_EVENT_TYPE_LOCATION_STATUS] = StkLocationEvent;
EventPrototypes[RIL.STK_EVENT_TYPE_LANGUAGE_SELECTION] = StkLanguageSelectionEvent;
EventPrototypes[RIL.STK_EVENT_TYPE_BROWSER_TERMINATION] = StkBrowserTerminationEvent;
/**
* Event Message Prototype Mappings.
*/
let EventMsgPrototypes = {};
EventMsgPrototypes[RIL.STK_EVENT_TYPE_USER_ACTIVITY] = StkEventMessage;
EventMsgPrototypes[RIL.STK_EVENT_TYPE_IDLE_SCREEN_AVAILABLE] = StkEventMessage;
EventMsgPrototypes[RIL.STK_EVENT_TYPE_MT_CALL] = StkCallEventMessage;
EventMsgPrototypes[RIL.STK_EVENT_TYPE_CALL_CONNECTED] = StkCallEventMessage;
EventMsgPrototypes[RIL.STK_EVENT_TYPE_CALL_DISCONNECTED] = StkCallEventMessage;
EventMsgPrototypes[RIL.STK_EVENT_TYPE_LOCATION_STATUS] = StkLocationEventMessage;
EventMsgPrototypes[RIL.STK_EVENT_TYPE_LANGUAGE_SELECTION] = StkLanguageSelectionEventMessage;
EventMsgPrototypes[RIL.STK_EVENT_TYPE_BROWSER_TERMINATION] = StkBrowserTerminationEventMessage;
/**
* Event QueryInterface Mappings.
*/
let QueriedEventIFs = {};
QueriedEventIFs[RIL.STK_EVENT_TYPE_USER_ACTIVITY] = Ci.nsIStkDownloadEvent;
QueriedEventIFs[RIL.STK_EVENT_TYPE_IDLE_SCREEN_AVAILABLE] = Ci.nsIStkDownloadEvent;
QueriedEventIFs[RIL.STK_EVENT_TYPE_MT_CALL] = Ci.nsIStkCallEvent;
QueriedEventIFs[RIL.STK_EVENT_TYPE_CALL_CONNECTED] = Ci.nsIStkCallEvent;
QueriedEventIFs[RIL.STK_EVENT_TYPE_CALL_DISCONNECTED] = Ci.nsIStkCallEvent;
QueriedEventIFs[RIL.STK_EVENT_TYPE_LOCATION_STATUS] = Ci.nsIStkLocationEvent;
QueriedEventIFs[RIL.STK_EVENT_TYPE_LANGUAGE_SELECTION] = Ci.nsIStkLanguageSelectionEvent;
QueriedEventIFs[RIL.STK_EVENT_TYPE_BROWSER_TERMINATION] = Ci.nsIStkBrowserTerminationEvent;
/**
* StkProactiveCmdFactory
*/
this.StkProactiveCmdFactory = {
function StkProactiveCmdFactory() {
}
StkProactiveCmdFactory.prototype = {
classID: GONK_STKCMDFACTORY_CID,
classInfo: XPCOMUtils.generateCI({classID: GONK_STKCMDFACTORY_CID,
contractID: GONK_STKCMDFACTORY_CONTRACTID,
classDescription: "StkProactiveCmdFactory",
interfaces: [Ci.nsIStkCmdFactory],
flags: Ci.nsIClassInfo.SINGLETON}),
QueryInterface: XPCOMUtils.generateQI([Ci.nsIStkCmdFactory]),
/**
* @param aCommandDetails
* The CommandDetails decoded from ril_worker.js.
* @return a nsIStkProactiveCmd instance.
* nsIStkCmdFactory interface.
*/
createCommand: function(aCommandDetails) {
let cmdType = CmdPrototypes[aCommandDetails.typeOfCommand];
@@ -1014,10 +1463,6 @@ this.StkProactiveCmdFactory = {
return new cmdType(aCommandDetails);
},
/**
* @param nsIStkProactiveCmd instance.
* @return a Javascript object with the same structure to MozStkCommandEvent.
*/
createCommandMessage: function(aStkProactiveCmd) {
let cmd = null;
@@ -1037,8 +1482,135 @@ this.StkProactiveCmdFactory = {
return new msgType(cmd);
},
deflateCommand: function(aStkProactiveCmd) {
return JSON.stringify(this.createCommandMessage(aStkProactiveCmd));
},
inflateCommand: function(aJSON) {
return this.createCommand(JSON.parse(aJSON));
},
createResponse: function(aResponseMessage) {
if (!aResponseMessage || aResponseMessage.resultCode === undefined) {
throw new Error("Invalid response message: " + JSON.stringify(aResponseMessage));
}
if (aResponseMessage.itemIdentifier !== undefined) {
return new StkSelectItemResponse(aResponseMessage);
}
if (aResponseMessage.input !== undefined ||
aResponseMessage.isYesNo !== undefined) {
return new StkGetInputResponse(aResponseMessage);
}
if (aResponseMessage.hasConfirmed !== undefined) {
return new StkCallSetupResponse(aResponseMessage);
}
if (aResponseMessage.localInfo !== undefined) {
return new StkLocalInfoResponse(aResponseMessage);
}
if (aResponseMessage.timer !== undefined) {
return new StkTimerResponse(aResponseMessage);
}
return new StkTerminalResponse(aResponseMessage);
},
createResponseMessage: function(aStkTerminalResponse) {
if (!aStkTerminalResponse) {
throw new Error("Invalid terminal response: " + JSON.stringify(aStkTerminalResponse));
}
let response;
if (aStkTerminalResponse instanceof Ci.nsIStkSelectItemResponse) {
response = aStkTerminalResponse.QueryInterface(Ci.nsIStkSelectItemResponse);
return new StkSelectItemResponseMessage(response);
}
if (aStkTerminalResponse instanceof Ci.nsIStkGetInputResponse) {
response = aStkTerminalResponse.QueryInterface(Ci.nsIStkGetInputResponse);
return new StkGetInputResponseMessage(response);
}
if (aStkTerminalResponse instanceof Ci.nsIStkCallSetupResponse) {
response = aStkTerminalResponse.QueryInterface(Ci.nsIStkCallSetupResponse);
return new StkCallSetupResponseMessage(response);
}
if (aStkTerminalResponse instanceof Ci.nsIStkLocalInfoResponse) {
response = aStkTerminalResponse.QueryInterface(Ci.nsIStkLocalInfoResponse);
return new StkLocalInfoResponseMessage(response);
}
if (aStkTerminalResponse instanceof Ci.nsIStkTimerResponse) {
response = aStkTerminalResponse.QueryInterface(Ci.nsIStkTimerResponse);
return new StkTimerResponseMessage(response);
}
return new StkResponseMessage(aStkTerminalResponse);
},
deflateResponse: function(aStkTerminalResponse) {
return JSON.stringify(this.createResponseMessage(aStkTerminalResponse));
},
inflateResponse: function(aJSON) {
return this.createResponse(JSON.parse(aJSON));
},
createEvent: function(aEventMessage) {
let eventType = EventPrototypes[aEventMessage.eventType];
if (typeof eventType != "function") {
throw new Error("Unknown Event Type: " + aEventMessage.eventType);
}
return new eventType(aEventMessage);
},
createEventMessage: function(aStkDownloadEvent) {
let event = null;
let eventType = EventMsgPrototypes[aStkDownloadEvent.eventType];
if (typeof eventType != "function") {
throw new Error("Unknown Event Type: " + aStkDownloadEvent.eventType);
}
// convert aStkDownloadEvent to it's concrete interface before creating message.
try {
event = aStkDownloadEvent.QueryInterface(QueriedEventIFs[aStkDownloadEvent.eventType]);
} catch (e) {
throw new Error("Failed to convert event into concrete class: " + e);
}
return new eventType(event);
},
deflateDownloadEvent: function(aStkDownloadEvent) {
return JSON.stringify(this.createEventMessage(aStkDownloadEvent));
},
inflateDownloadEvent: function(aJSON) {
return this.createEvent(JSON.parse(aJSON));
},
createTimer: function(aStkTimerMessage) {
if (!aStkTimerMessage ||
aStkTimerMessage.timerId === undefined) {
throw new Error("Invalid timer object: " + JSON.stringify(aStkTimerMessage));
}
// timerAction is useless in TIMER EXPIRATION envelope,
// so we always set it to TIMER_ACTION_INVALID.
return new StkTimer(aStkTimerMessage.timerId,
Math.floor(aStkTimerMessage.timerValue),
Ci.nsIStkTimer.TIMER_ACTION_INVALID);
}
};
this.EXPORTED_SYMBOLS = [
'StkProactiveCmdFactory'
];
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([StkProactiveCmdFactory]);
+6
View File
@@ -0,0 +1,6 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
component {7a663440-e336-11e4-8fd5-c3140a7ff307} StkCmdFactory.js
contract @mozilla.org/icc/stkcmdfactory;1 {7a663440-e336-11e4-8fd5-c3140a7ff307}
+3 -1
View File
@@ -5,9 +5,11 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
XPIDL_SOURCES += [
'nsIIccContact.idl',
'nsIIccInfo.idl',
'nsIIccProvider.idl', # TODO: Bug 815526, deprecate RILContentHelper.
'nsIIccService.idl',
'nsIStkCmdFactory.idl',
'nsIStkProactiveCmd.idl',
]
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk' and CONFIG['MOZ_B2G_RIL']:
+3 -4
View File
@@ -9,12 +9,11 @@
"@mozilla.org/icc/gonkiccservice;1"
%}
[scriptable, uuid(a037b8a2-b027-11e4-9496-c3b7af59a512)]
[scriptable, uuid(cdcdd800-ef24-11e4-99e7-1f0f5f2576c5)]
interface nsIGonkIccService : nsIIccService
{
// TODO: Bug 1114938 - Refactor STK in MozIcc.webidl with IPDL:
// void notifyStkCommand(in unsigned long aServiceId, in jsval aStkcommand);
// void notifyStkSessionEnd(in unsigned long aServiceId);
void notifyStkCommand(in unsigned long aServiceId, in nsIStkProactiveCmd aStkcommand);
void notifyStkSessionEnd(in unsigned long aServiceId);
void notifyCardStateChanged(in unsigned long aServiceId, in unsigned long aCardState);
void notifyIccInfoChanged(in unsigned long aServiceId, in jsval aIccInfo);
void notifyImsiChanged(in unsigned long aServiceId, in DOMString aImsi);
+60
View File
@@ -0,0 +1,60 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsISupports.idl"
[scriptable, uuid(0f3dbcd1-9f7b-40a8-aa3c-b5701978ec53)]
interface nsIIccContact : nsISupports
{
/**
* The unique identifier of this ICC Contact.
*
* Note: This id is composed of the iccid and its record index of EF_ADN.
*/
readonly attribute DOMString id;
/**
* Name list.
*
* The container of Alpha-Id in EF_ADN and Second Name in EF_SNE of this contact,
* where EF_SNE provides the possibility to store a name in different language.
*
* @see 10.2.1 Support of two name fields per entry, 3GPP TS 21.111.
*
* @param aCount
* The number of names.
*
* @returns the array of names.
*/
void getNames([optional] out unsigned long aCount,
[array, size_is(aCount), retval] out wstring aNames);
/**
* Phone number list.
*
* The container of the dialing numbers of this contact in EF_ADN and EF_ANR.
*
* @see 10.2.2 Support of multiple phone numbers per entry, 3GPP TS 21.111.
*
* @param aCount
* The number of phone numbers.
*
* @returns the array of phone numbers.
*/
void getNumbers([optional] out unsigned long aCount,
[array, size_is(aCount), retval] out wstring aNumbers);
/**
* Email list.
*
* The container of the emails of this contact in EF_EMAIL.
*
* @param aCount
* The number of emails.
*
* @returns the array of emails.
*/
void getEmails([optional] out unsigned long aCount,
[array, size_is(aCount), retval] out wstring aEmails);
};
+1 -639
View File
@@ -4,645 +4,7 @@
#include "nsISupports.idl"
[scriptable, uuid(1510cf0c-5db6-11e4-9869-6bf419e26642)]
interface nsIStkDuration : nsISupports
{
/**
* The value of Time units defined in 12.8 Duration of TS 11.14.
*/
readonly attribute unsigned short timeUnit;
/**
* The length of time required, expressed in timeUnit.
*
* Note: the range is from 1 unit to 255 units.
*/
readonly attribute unsigned short timeInterval;
};
[scriptable, uuid(c7b6e57a-696d-11e4-bcaa-bfe8386e75a9)]
interface nsIStkIcon : nsISupports
{
/**
* The color coding schemes defined in 4.6.1.1 of TS 31.102.
*/
const unsigned short CODING_SCHEME_BASIC = 0x11;
const unsigned short CODING_SCHEME_COLOR = 0x21;
const unsigned short CODING_SCHEME_COLOR_TRANSPARENCY = 0x22;
/**
* Width of the icon.
*/
readonly attribute unsigned long width;
/**
* Height of the icon.
*/
readonly attribute unsigned long height;
/**
* Image coding scheme of the icon.
* One of CODING_SCHEME_*.
*/
readonly attribute unsigned short codingScheme;
/**
* Array of pixels. Each pixel represents a color in the RGBA format made up
* of four bytes, that is, the Red sample in the highest 8 bits, followed by
* the Green sample, Blue sample and the Alpha sample in the lowest 8 bits.
*
* @param aCount
* The number of pixels.
*
* @returns a copy of the array of pixels.
*/
void getPixels([optional] out unsigned long aCount,
[array, size_is(aCount), retval] out unsigned long aPixels);
};
[scriptable, uuid(4a6d173e-5e8b-11e4-9d78-071bb3d6ba8f)]
interface nsIStkIconInfo : nsISupports
{
/**
* Indicates how the icon is to be used.
*
* @see TS 11.14, clause 12.31, Icon Identifier.
*
* true: icon replaces the text string.
* false: icon shall be displayed together with the text string.
*/
readonly attribute boolean iconSelfExplanatory;
/**
* Icon(s) that replaces or accompanies the text string.
*
* @see TS 11.14, clause 12.31, Icon Identifier.
*
* Array of icons, basically of a same image, that may differ in size,
* resolution or coding scheme. The first icon should be the default one.
*
* @param aCount
* The number of icons.
*
* @returns a copy of the list of icons.
*/
void getIcons([optional] out unsigned long aCount,
[array, size_is(aCount), retval] out nsIStkIcon aIcons);
};
[scriptable, uuid(ea95d25c-5e84-11e4-bd96-07285c50c1f2)]
interface nsIStkItem : nsISupports
{
/**
* Identifier of item.
*
* The identifier is a single byte between '01' and 'FF'. Each item shall
* have a unique identifier within an Item list.
*/
readonly attribute unsigned short identifier;
/**
* Text string of item.
*/
readonly attribute DOMString text;
/**
* (Optional)
* Icon info of item.
*/
readonly attribute nsIStkIconInfo iconInfo;
};
[scriptable, uuid(222651f0-6976-11e4-accf-736a9c6e7d19)]
interface nsIStkTimer : nsISupports
{
/**
* Identifier of a timer.
*/
readonly attribute unsigned short timerId;
const unsigned long TIMER_VALUE_INVALID = 0xFFFFFFFF;
/**
* Length of time during which the timer has to run.
*
* The possible duration of a timer is between 1 s and 24 h.
* The resolution of a timer is 1 second.
*
* Note: In TS 11.14, clause 6.6.21 TIMER MANAGEMENT,
* "
* The SIM shall supply this data object only when a timer has to
* be started.
* "
* Hence, set to TIMER_VALUE_INVALID when |timerAction| is not equal to
* TIMER_ACTION_START.
*/
readonly attribute unsigned long timerValue;
/*
* Times actions defined in TS 11.14, clause 12.6,
* Command Qualifier, TIMER MANAGEMENT
*/
const unsigned short TIMER_ACTION_START = 0x00;
const unsigned short TIMER_ACTION_DEACTIVATE = 0x01;
const unsigned short TIMER_ACTION_GET_CURRENT_VALUE = 0x02;
/**
* The action requested from UICC.
* It shall be one of TIMER_ACTION_*.
*/
readonly attribute unsigned short timerAction;
};
/**
* The base class of all STK Proactive Commands.
*
* This interface is to be applied by the commands that provide info no more than:
* |commandNumber|, |typeOfCommand|, |commandQualifier|.
*
* The commands in this category are:
* - STK_CMD_REFRESH
* - STK_CMD_POLL_OFF
*/
[scriptable, uuid(f47f25b2-5d84-11e4-8637-7f59ea6da82f)]
interface nsIStkProactiveCmd : nsISupports
{
/**
* The number of command issued by ICC. And it is assigned
* by ICC may take any hexadecimal value betweean '01' and 'FE'.
*
* @see TS 11.14, clause 6.5.1
*/
readonly attribute unsigned short commandNumber;
/**
* The value of |Type of Command| defined in TS 11.14, clause 13.4
*/
readonly attribute unsigned short typeOfCommand;
/**
* Qualifiers specific to the command.
*/
readonly attribute unsigned short commandQualifier;
};
/**
* This interface is to be applied by STK_CMD_POLL_INTERVAL.
*/
[scriptable, uuid(0a27c090-5dbc-11e4-92eb-ebc26db3db29)]
interface nsIStkPollIntervalCmd : nsIStkProactiveCmd
{
/**
* The maximum interval between two STATUS commands related to
* Proactive Polling.
*
* Note: Mandatory for STK_CMD_POLL_INTERVAL.
*
* @See TS 11.14, clause 6.6.6 POLL INTERVAL
*/
readonly attribute nsIStkDuration duration;
};
/**
* This interface is to be applied by STK_CMD_PROVIDE_LOCAL_INFO.
*/
[scriptable, uuid(89a304ce-5dc6-11e4-8dce-23723fb242b4)]
interface nsIStkProvideLocalInfoCmd : nsIStkProactiveCmd
{
/**
* Values defined in TS 11.14, clause 12.6, Command Qualifier,
* PROVIDE LOCAL INFORMATION
*/
readonly attribute unsigned short localInfoType;
};
/**
* This interface is to be applied by STK_CMD_SET_UP_EVENT_LIST.
*/
[scriptable, uuid(5f796dec-5e6a-11e4-aaf3-bb675cb36df5)]
interface nsIStkSetupEventListCmd : nsIStkProactiveCmd
{
/**
* (Optional)
* Get the list of events.
* Each event could be one of values defined in TS 11.14, clause 8.25, Event list.
*
* Note: It could be null as an indication to the terminal to remove the
* existing list of events in the terminal.
*
* @param aCount
* The number of events.
*
* @returns a copy of the list of events.
*/
void getEventList([optional] out unsigned long aCount,
[array, size_is(aCount), retval] out unsigned short aEventList);
};
/**
* This interface is to be applied by STK_CMD_SET_UP_MENU.
*/
[scriptable, uuid(d7a66664-a602-11e4-9cc7-c7ce5fdade7d)]
interface nsIStkSetUpMenuCmd : nsIStkProactiveCmd
{
/**
* (Optional for STK_CMD_SELECT_ITEM)
* Title of the menu.
*/
readonly attribute DOMString title;
/**
* Get the list of menu items.
*
* Note: The minimal number of items is 1.
* See TS 11.14, clause 6.6.7 SET-UP MENU and 6.6.8 SELECT ITEM.
*
* @param aCount
* The number of items.
*
* @returns a copy of the list of menu items.
* For |SET-UP MENU|, the 1st item in |aItems| could be null as an
* indication to the ME to remove the existing menu from the menu
* system in the ME.
*/
void getItems([optional] out unsigned long aCount,
[array, size_is(aCount), retval] out nsIStkItem aItems);
/**
* (Optional)
* Get the list of Next Action Indicators.
*
* Each element should be the value of |Next Action Indicator| in TS 11.14,
* clause 13.4.
*
* @see TS 11.14, clause 12.24, Items Next Action Indicator.
*
* @param aCount
* The number of indicators.
*
* @returns a copy of the list of Next Action Indicators.
*/
void getNextActionList([optional] out unsigned long aCount,
[array, size_is(aCount), retval] out unsigned short aActions);
/**
* (Optional)
* Icon info of the menu.
*/
readonly attribute nsIStkIconInfo iconInfo;
/**
* Help information available or not.
*
* @see TS 11.14, clause 12.6, Command Qualifier, SET UP MENU, bit 8.
*
* true: help information available.
* false: no help information available.
*
*/
readonly attribute boolean isHelpAvailable;
};
/**
* This interface is to be applied by STK_CMD_SELECT_ITEM.
*/
[scriptable, uuid(eb71f0fa-a602-11e4-926f-a3814461d218)]
interface nsIStkSelectItemCmd : nsIStkSetUpMenuCmd
{
/**
* Presentation type, one of PRESENTATION_TYPE_*.
*
* @See TS 11.14, clause 12.6, Command Qualifier: Select Item
*/
const unsigned short PRESENTATION_TYPE_NOT_SPECIFIED = 0x00;
const unsigned short PRESENTATION_TYPE_DATA_VALUES = 0x01;
const unsigned short PRESENTATION_TYPE_NAVIGATION_OPTIONS = 0x03;
readonly attribute unsigned short presentationType;
const unsigned short DEFAULT_ITEM_INVALID = 0xFFFF;
/**
* (Optional)
* Default item identifier of the menu.
*
* Set to DEFAULT_ITEM_INVALID if null.
*/
readonly attribute unsigned short defaultItem;
};
/**
* This interface is to be applied by
* - STK_CMD_SET_UP_IDLE_MODE_TEXT
* - STK_CMD_SEND_{SS|USSD|SMS|DTMF}
* - STK_CMD_OPEN_CHANNEL
* - STK_CMD_CLOSE_CHANNEL
* - STK_CMD_SEND_DATA
* - STK_CMD_RECEIVE_DATA
*/
[scriptable, uuid(61c42b3c-6324-11e4-959e-7fb2dc9a3f0d)]
interface nsIStkTextMessageCmd : nsIStkProactiveCmd
{
/**
* Text String.
*/
readonly attribute DOMString text;
/**
* (Optional)
* Icon to be displayed.
*/
readonly attribute nsIStkIconInfo iconInfo;
};
/**
* This interface is to be applied by STK_CMD_DISPLAY_TEXT.
*/
[scriptable, uuid(66a83f0a-6322-11e4-a773-9382de87a74a)]
interface nsIStkDisplayTextCmd : nsIStkTextMessageCmd
{
/**
* (Optional)
* The length of time for which the ME shall display the dialog.
*/
readonly attribute nsIStkDuration duration;
/**
* Indicate this text message is high priority or normal priority.
*
* @see TS 11.14, clause 12.6, Command Qualifier, Display Text, bit 1.
*
* true: high priority
* false: normal priority
*/
readonly attribute boolean isHighPriority;
/**
* Need to wait for user to clear message or not.
*
* @see TS 11.14, clause 12.6, Command Qualifier, Display Text, bit 8.
*
* true: Wait for user to clear message.
* false: clear message after a delay.
*/
readonly attribute boolean userClear;
/**
* Need to response immediately or not.
*
* @see TS 11.14, clause 12.43, Immediate response.
*
* true: The terminal shall send response immediately.
* false: otherwise.
*/
readonly attribute boolean responseNeeded;
};
/**
* The base interface of nsIStkInputKeyCmd, nsIStkInputTextCmd.
*/
[scriptable, uuid(ed16a67e-6022-11e4-a8fd-c34fe6e6bb11)]
interface nsIStkInputCmd : nsIStkProactiveCmd
{
/**
* Text for the ME to display in conjunction with asking the user to respond.
*/
readonly attribute DOMString text;
/**
* (Optional)
* The length of time for which the ME shall display the dialog.
*/
readonly attribute nsIStkDuration duration;
/**
* Minimum length of response.
* Set to 1 for STK_CMD_GET_INKEY.
*/
readonly attribute unsigned short minLength;
/**
* Maximum length of response.
* Set to 1 for STK_CMD_GET_INKEY.
*/
readonly attribute unsigned short maxLength;
/**
* (Optional)
* Text for the ME to display, corresponds to a default text string offered
* by the ICC.
*/
readonly attribute DOMString defaultText;
/**
* Input format.
*
* @see TS 11.14, clause 12.6, Command Qualifier, GET INPUT/GET INKEY, bit 1.
*
* true: Alphabet set.
* false: Digits only.
*/
readonly attribute boolean isAlphabet;
/**
* Alphabet encoding.
*
* @see TS 11.14, clause 12.6, Command Qualifier, GET INPUT/GET INKEY, bit 2.
*
* true: UCS2 alphabet.
* false: default SMS alphabet.
*/
readonly attribute boolean isUCS2;
/**
* Help information available or not.
*
* @see TS 11.14, clause 12.6, Command Qualifier, GET INPUT/GET INKEY, bit 8.
*
* true: help information available.
* false: no help information available.
*/
readonly attribute boolean isHelpAvailable;
/**
* (Optional)
* Icon to be displayed.
*/
readonly attribute nsIStkIconInfo iconInfo;
};
/**
* This interface is to be applied by STK_CMD_GET_INKEY.
*/
[scriptable, uuid(27a4078a-6025-11e4-a9ab-bf39252bfaf1)]
interface nsIStkInputKeyCmd : nsIStkInputCmd
{
/**
* Yes/No response is requested.
*
* @see TS 11.14, clause 12.6, Command Qualifier, GET INKEY, bit 3.
*
* true: Yes/No response is requested, and character sets
* (Alphabet set and UCS2) are disabled.
* false: Character sets (Alphabet set and UCS2) are enabled.
*/
readonly attribute boolean isYesNoRequested;
};
/**
* This interface is to be applied by STK_CMD_GET_INPUT.
*/
[scriptable, uuid(f3c33ae8-60d4-11e4-9da8-4ff4cb8566c3)]
interface nsIStkInputTextCmd : nsIStkInputCmd
{
/**
* Visibility of input.
*
* @see TS 11.14, clause 12.6, Command Qualifier, GET INPUT, bit 3.
*
* true: User input shall not be revealed in any way.
* false: ME may echo user input on the display.
*/
readonly attribute boolean hideInput;
/**
* User input in packed or unpacked format.
*
* @see TS 11.14, clause 12.6, Command Qualifier, GET INPUT, bit 4.
*
* true: User input to be in SMS packed format.
* false: User input to be in unpacked format.
*/
readonly attribute boolean isPacked;
};
/**
* This interface is to be applied by STK_CMD_SET_UP_CALL.
*/
[scriptable, uuid(6abbf688-6956-11e4-a9d3-4b07f063ef21)]
interface nsIStkSetUpCallCmd : nsIStkProactiveCmd
{
/**
* The Dialling number.
*/
readonly attribute DOMString address;
/**
* (Optional)
* The text message used in user confirmation phase.
*/
readonly attribute DOMString confirmText;
/**
* (Optional)
* Icon to be displayed in user confirmation phase.
*/
readonly attribute nsIStkIconInfo confirmIconInfo;
/**
* (Optional)
* The text message used in call set up phase.
*/
readonly attribute DOMString callText;
/**
* (Optional)
* Icon to be displayed in call set up phase.
*/
readonly attribute nsIStkIconInfo callIconInfo;
/**
* (Optional)
* The maximum duration for the redial mechanism.
* The time elapsed since the first call set-up attempt has exceeded the duration
* requested by the UICC, the redial mechanism is terminated.
*/
readonly attribute nsIStkDuration duration;
};
/**
* This interface is to be applied by STK_CMD_LAUNCH_BROWSER.
*/
[scriptable, uuid(b9bca548-695b-11e4-8c1f-cfb850f421ab)]
interface nsIStkBrowserSettingCmd : nsIStkProactiveCmd
{
/**
* The URL to be opened by browser.
*/
readonly attribute DOMString url;
/**
* Browser launch mode.
* @See TS 11.14, clause 12.6, Command Qualifier, LAUNCH BROWSER.
*/
readonly attribute unsigned short mode;
/**
* (Optional)
* Confirm message to launch browser.
*/
readonly attribute DOMString confirmText;
/**
* (Optional)
* Icon to be displayed in user confirmation phase.
*/
readonly attribute nsIStkIconInfo confirmIconInfo;
};
/**
* This interface is to be applied by STK_CMD_PLAY_TONE.
*/
[scriptable, uuid(f49dd148-60ee-11e4-af46-6b938538de51)]
interface nsIStkPlayToneCmd : nsIStkProactiveCmd
{
const unsigned short TONE_TYPE_INVALID = 0xFFFF;
/**
* (Optional)
* Text String.
*/
readonly attribute DOMString text;
/**
* (Optional)
* One of the tone value coded in TS 11.14, clause 12.16, Tone.
*
* Set to TONE_TYPE_INVALID if null.
*/
readonly attribute unsigned short tone;
/**
* (Optional)
* The length of time for which the ME shall generate the tone.
*/
readonly attribute nsIStkDuration duration;
/**
* Need to vibrate or not.
* true: vibrate alert, if available, with the tone.
* false: use of vibrate alert is up to the ME.
*/
readonly attribute boolean isVibrate;
/**
* (Optional)
* Icon to be displayed.
*/
readonly attribute nsIStkIconInfo iconInfo;
};
/**
* This interface is to be applied by STK_CMD_TIMER_MANAGEMENT.
*/
[scriptable, uuid(e421b122-60f3-11e4-b8d7-bfe75825a796)]
interface nsIStkTimerManagementCmd : nsIStkProactiveCmd
{
/**
* Timer Information.
*/
readonly attribute nsIStkTimer timerInfo;
};
interface nsIStkProactiveCmd;
[scriptable, uuid(000696fe-5d85-11e4-8da2-2fdf3880276b)]
interface nsIIccMessenger : nsISupports
-55
View File
@@ -1,55 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsISupports.idl"
interface nsIDOMDOMRequest;
interface nsIDOMWindow;
interface nsIIccListener;
/**
* XPCOM component (in the content process) that provides the ICC information.
*/
[scriptable, uuid(2fbacfc4-f52d-11e4-9667-33b72f279d14)]
interface nsIIccProvider : nsISupports
{
/**
* Called when a content process registers receiving unsolicited messages from
* RadioInterfaceLayer in the chrome process. Only a content process that has
* the 'mobileconnection' permission is allowed to register.
*/
void registerIccMsg(in unsigned long clientId, in nsIIccListener listener);
void unregisterIccMsg(in unsigned long clientId, in nsIIccListener listener);
/**
* STK interfaces.
*/
void sendStkResponse(in unsigned long clientId,
in nsIDOMWindow window,
in jsval command,
in jsval response);
void sendStkMenuSelection(in unsigned long clientId,
in nsIDOMWindow window,
in unsigned short itemIdentifier,
in boolean helpRequested);
void sendStkTimerExpiration(in unsigned long clientId,
in nsIDOMWindow window,
in jsval timer);
void sendStkEventDownload(in unsigned long clientId,
in nsIDOMWindow window,
in jsval event);
/**
* Phonebook interfaces.
*/
nsIDOMDOMRequest readContacts(in unsigned long clientId,
in nsIDOMWindow window,
in unsigned long contactType);
nsIDOMDOMRequest updateContact(in unsigned long clientId,
in nsIDOMWindow window,
in unsigned long contactType,
in jsval contact,
in DOMString pin2);
};
+114 -5
View File
@@ -5,12 +5,16 @@
#include "nsISupports.idl"
interface nsIIcc;
interface nsIIccContact;
interface nsIIccInfo;
interface nsIStkDownloadEvent;
interface nsIStkProactiveCmd;
interface nsIStkTerminalResponse;
[scriptable, uuid(7c0ada3d-d8d4-493e-9243-fa3df39855e4)]
[scriptable, uuid(71b33012-eca2-11e4-a40d-9ff040a6fe2a)]
interface nsIIccListener : nsISupports
{
void notifyStkCommand(in DOMString aMessage);
void notifyStkCommand(in nsIStkProactiveCmd aStkProactiveCmd);
void notifyStkSessionEnd();
void notifyCardStateChanged();
void notifyIccInfoChanged();
@@ -19,7 +23,7 @@ interface nsIIccListener : nsISupports
/**
* A callback interface for handling asynchronous response.
*/
[scriptable, uuid(b0e2899a-adc3-11e4-89cf-1b60eaa35b06)]
[scriptable, uuid(b7b0623f-fb2c-4cec-b0dc-00ac2fe7b296)]
interface nsIIccCallback : nsISupports
{
/**
@@ -42,9 +46,28 @@ interface nsIIccCallback : nsISupports
*/
void notifyGetCardLockRetryCount(in long aCount);
/**
* The success callback of |readContacts|.
*
* @param aContacts
* The list of contacts retrieved from ICC.
* @param aCount
* The number of contacts retrieved from ICC.
*/
void notifyRetrievedIccContacts([array, size_is(aCount)] in nsIIccContact aContacts,
in uint32_t aCount);
/**
* The success callback of |updateContact|.
*
* @param aContact
* The contact with the updated result.
*/
void notifyUpdatedIccContact(in nsIIccContact aContact);
/**
* The error callback of |getCardLockEnabled|, |getCardLockRetryCount|,
* |matchMvno|, and |getServiceStateEnabled|.
* |matchMvno|, |getServiceStateEnabled|, |readContacts| and |updateContact|.
*
* @param aErrorMsg
* The error message.
@@ -135,7 +158,7 @@ NS_CreateIccService();
/**
* XPCOM component that provides the access to the selected ICC.
*/
[scriptable, uuid(6ad6b686-f52d-11e4-942d-db2884bd9242)]
[scriptable, uuid(1791f102-b081-4435-8555-37eb035fa4e2)]
interface nsIIcc : nsISupports
{
/**
@@ -232,6 +255,15 @@ interface nsIIcc : nsISupports
*/
const unsigned long CARD_SERVICE_FDN = 0;
/**
* Icc Contact Type Constants
*
* Note: MUST be matched with enum IccContactType in MozIcc.webidl!
*/
const unsigned long CONTACT_TYPE_ADN = 0;
const unsigned long CONTACT_TYPE_FDN = 1;
const unsigned long CONTACT_TYPE_SDN = 2;
/**
* Called to register icc-related changes.
*
@@ -426,4 +458,81 @@ interface nsIIcc : nsISupports
*/
void iccCloseChannel(in long aChannel,
in nsIIccChannelCallback aCallback);
/**
* Send STK terminal response to the received proactive command.
*
* @param aCommand
* The received proactive command.
* @param aResponse
* The response to be reply to the card application that issues
* this proactive command.
*/
void sendStkResponse(in nsIStkProactiveCmd aCommand,
in nsIStkTerminalResponse aResponse);
/**
* Send envelope to notify the selected item of the main STK menu.
*
* @param aItemIdentifier
* The identifier of the menu item.
* @param aHelpRequested
* True if help information of the selected item is requested by
* the user.
*/
void sendStkMenuSelection(in unsigned short aItemIdentifier,
in boolean aHelpRequested);
/**
* Send envelope to notify the expiration of a requested timer.
*
* @param aTimerId
* The TimerId provided from previous proactive command.
* @param aTimerValue
* The real used seconds when expired.
*/
void sendStkTimerExpiration(in unsigned short aTimerId,
in unsigned long aTimerValue);
/**
* Send "Event Download" envelope to the ICC.
*
* @param aEvent
* The event that ICC listening to in STK_CMD_SET_UP_EVENT_LIST.
*/
void sendStkEventDownload(in nsIStkDownloadEvent aEvent);
/**
* Read Specified type of Contact from ICC.
*
* @param aContactType
* One of CONTACT_TYPE_*.
*
* @param aCallback
* An instance of nsIIccCallback:
* nsIIccCallback::notifyRetrievedIccContacts() if success.
* nsIIccCallback::notifyError(), otherwise.
*/
void readContacts(in unsigned long aContactType,
in nsIIccCallback aCallback);
/**
* Update Specified type of Contact in ICC.
*
* @param aContactType
* One of CONTACT_TYPE_*.
* @param aContact
* an nsIIccContact instance with information to be updated.
* @param aPin2 (Optional)
* The PIN2 required to update FDN contact.
*
* @param aCallback
* An instance of nsIIccCallback:
* nsIIccCallback::notifyUpdatedIccContact() if success.
* nsIIccCallback::notifyError(), otherwise.
*/
void updateContact(in unsigned long aContactType,
in nsIIccContact aContact,
in DOMString aPin2,
in nsIIccCallback aCallback);
};
+140
View File
@@ -0,0 +1,140 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsISupports.idl"
%{C++
#define ICC_STK_CMD_FACTORY_CONTRACTID \
"@mozilla.org/icc/stkcmdfactory;1"
%}
interface nsIStkProactiveCmd;
interface nsIStkTerminalResponse;
interface nsIStkDownloadEvent;
interface nsIStkTimer;
/**
* This StkCmdFactory provides series factory methods to create objects defined
* in nsIStkProactiveCmd.idl and MozStkCommandEvent.webidl.
*/
[scriptable, uuid(743536c4-006f-11e5-a3f7-bf7a7fd59b9b)]
interface nsIStkCmdFactory : nsISupports
{
/**
* @param aCommandDetails
* A JS object which complies with 'dictionary MozStkCommand'
* in MozStkCommandEvent.webidl
*
* @return a nsIStkProactiveCmd instance.
*/
nsIStkProactiveCmd createCommand(in jsval aCommandDetails);
/**
* @param aStkProactiveCmd
* a nsIStkProactiveCmd instance.
*
* @return a JS object which complies with 'dictionary MozStkCommand'
* in MozStkCommandEvent.webidl
*/
jsval createCommandMessage(in nsIStkProactiveCmd aStkProactiveCmd);
/**
* @param aStkProactiveCmd
* a nsIStkProactiveCmd instance.
*
* @return a JSON string which complies with 'dictionary MozStkCommand'
* in MozStkCommandEvent.webidl
*/
AString deflateCommand(in nsIStkProactiveCmd aStkProactiveCmd);
/**
* @param a JSON string which complies with 'dictionary MozStkCommand'
* in MozStkCommandEvent.webidl
*
* @return a nsIStkProactiveCmd instance.
*/
nsIStkProactiveCmd inflateCommand(in AString aJSON);
/**
* @param aResponseMessage
* A JS object which complies with 'dictionary MozStkResponse'
* in MozStkCommandEvent.webidl
*
* @return a nsIStkTerminalResponse instance.
*/
nsIStkTerminalResponse createResponse(in jsval aResponseMessage);
/**
* @param aStkTerminalResponse
* a nsIStkTerminalResponse instance.
*
* @return a JS object which complies with 'dictionary MozStkResponse'
* in MozStkCommandEvent.webidl
*/
jsval createResponseMessage(in nsIStkTerminalResponse aStkTerminalResponse);
/**
* @param aStkTerminalResponse
* a nsIStkTerminalResponse instance.
*
* @return a JSON string which complies with 'dictionary MozStkResponse'
* in MozStkCommandEvent.webidl
*/
AString deflateResponse(in nsIStkTerminalResponse aStkTerminalResponse);
/**
* @param a JSON string which complies with 'dictionary MozStkResponse'
* in MozStkCommandEvent.webidl
*
* @return a nsIStkTerminalResponse instance.
*/
nsIStkTerminalResponse inflateResponse(in AString aJSON);
/**
* @param aEventMessage
* A JS object which complies with 'dictionary MozStkXxxEvent'
* in MozStkCommandEvent.webidl
*
* @return a nsIStkDownloadEvent instance.
*/
nsIStkDownloadEvent createEvent(in jsval aEventMessage);
/**
* @param aStkDownloadEvent
* a nsIStkDownloadEvent instance.
*
* @return a JS object which complies with 'dictionary MozStkXxxEvent'
* in MozStkCommandEvent.webidl
*/
jsval createEventMessage(in nsIStkDownloadEvent aStkDownloadEvent);
/**
* @param aStkDownloadEvent
* a nsIStkDownloadEvent instance.
*
* @return a JSON string which complies with 'dictionary MozStkXxxEvent'
* in MozStkCommandEvent.webidl
*/
AString deflateDownloadEvent(in nsIStkDownloadEvent aStkDownloadEvent);
/**
* @param a JSON string which complies with 'dictionary MozStkXxxEvent'
* in MozStkCommandEvent.webidl
*
* @return a nsIStkDownloadEvent instance.
*/
nsIStkDownloadEvent inflateDownloadEvent(in AString aJSON);
/**
* @param aStkTimerMessage
* a JS object which complies with 'dictionary MozStkTimer'
* in MozStkCommandEvent.webidl
*
* @return an instance of nsIStkTimer with the same timerId and timerValue
* from aStkTimerMessage.
*
* Note: This API is specific to nsIIcc::sendStkTimerExpiration().
*/
nsIStkTimer createTimer(in jsval aStkTimerMessage);
};
File diff suppressed because it is too large Load Diff
+151 -9
View File
@@ -4,8 +4,11 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/icc/IccChild.h"
#include "IccInfo.h"
#include "mozilla/dom/icc/IccChild.h"
#include "mozilla/dom/icc/IccIPCUtils.h"
#include "nsIStkCmdFactory.h"
#include "nsIStkProactiveCmd.h"
using mozilla::dom::IccInfo;
@@ -82,6 +85,35 @@ IccChild::RecvNotifyIccInfoChanged(const OptionalIccInfoData& aInfoData)
return true;
}
bool
IccChild::RecvNotifyStkCommand(const nsString& aStkProactiveCmd)
{
nsCOMPtr<nsIStkCmdFactory> cmdFactory =
do_GetService(ICC_STK_CMD_FACTORY_CONTRACTID);
NS_ENSURE_TRUE(cmdFactory, false);
nsCOMPtr<nsIStkProactiveCmd> cmd;
cmdFactory->InflateCommand(aStkProactiveCmd, getter_AddRefs(cmd));
NS_ENSURE_TRUE(cmd, false);
for (int32_t i = 0; i < mListeners.Count(); i++) {
mListeners[i]->NotifyStkCommand(cmd);
}
return true;
}
bool
IccChild::RecvNotifyStkSessionEnd()
{
for (int32_t i = 0; i < mListeners.Count(); i++) {
mListeners[i]->NotifyStkSessionEnd();
}
return true;
}
PIccRequestChild*
IccChild::AllocPIccRequestChild(const IccRequest& aRequest)
{
@@ -131,8 +163,8 @@ IccChild::UpdateIccInfo(const OptionalIccInfoData& aInfoData) {
// We update the orignal one instead of replacing with a new one
// if the IccType is the same.
if (mIccInfo) {
nsString oldIccType;
nsString newIccType;
nsAutoString oldIccType;
nsAutoString newIccType;
mIccInfo->GetIccType(oldIccType);
iccInfo->GetIccType(newIccType);
@@ -206,8 +238,8 @@ IccChild::UnlockCardLock(uint32_t aLockType,
nsIIccCallback* aRequestReply)
{
return SendRequest(UnlockCardLockRequest(aLockType,
nsString(aPassword),
nsString(aNewPin)),
nsAutoString(aPassword),
nsAutoString(aNewPin)),
aRequestReply)
? NS_OK : NS_ERROR_FAILURE;
}
@@ -219,7 +251,7 @@ IccChild::SetCardLockEnabled(uint32_t aLockType,
nsIIccCallback* aRequestReply)
{
return SendRequest(SetCardLockEnabledRequest(aLockType,
nsString(aPassword),
nsAutoString(aPassword),
aEnabled),
aRequestReply)
? NS_OK : NS_ERROR_FAILURE;
@@ -232,8 +264,8 @@ IccChild::ChangeCardLockPassword(uint32_t aLockType,
nsIIccCallback* aRequestReply)
{
return SendRequest(ChangeCardLockPasswordRequest(aLockType,
nsString(aPassword),
nsString(aNewPassword)),
nsAutoString(aPassword),
nsAutoString(aNewPassword)),
aRequestReply)
? NS_OK : NS_ERROR_FAILURE;
}
@@ -251,7 +283,7 @@ IccChild::MatchMvno(uint32_t aMvnoType,
const nsAString& aMvnoData,
nsIIccCallback* aRequestReply)
{
return SendRequest(MatchMvnoRequest(aMvnoType, nsString(aMvnoData)),
return SendRequest(MatchMvnoRequest(aMvnoType, nsAutoString(aMvnoData)),
aRequestReply)
? NS_OK : NS_ERROR_FAILURE;
}
@@ -285,6 +317,80 @@ IccChild::IccCloseChannel(int32_t aChannel, nsIIccChannelCallback* aCallback)
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
IccChild::SendStkResponse(nsIStkProactiveCmd* aCommand, nsIStkTerminalResponse* aResponse)
{
nsCOMPtr<nsIStkCmdFactory> cmdFactory =
do_GetService(ICC_STK_CMD_FACTORY_CONTRACTID);
NS_ENSURE_TRUE(cmdFactory, NS_ERROR_FAILURE);
nsAutoString cmd, response;
nsresult rv = cmdFactory->DeflateCommand(aCommand, cmd);
NS_ENSURE_SUCCESS(rv, rv);
rv = cmdFactory->DeflateResponse(aResponse, response);
NS_ENSURE_SUCCESS(rv, rv);
return PIccChild::SendStkResponse(cmd, response) ? NS_OK : NS_ERROR_FAILURE;
}
NS_IMETHODIMP
IccChild::SendStkMenuSelection(uint16_t aItemIdentifier, bool aHelpRequested)
{
return PIccChild::SendStkMenuSelection(aItemIdentifier, aHelpRequested)
? NS_OK : NS_ERROR_FAILURE;
}
NS_IMETHODIMP
IccChild::SendStkTimerExpiration(uint16_t aTimerId, uint32_t aTimerValue)
{
return PIccChild::SendStkTimerExpiration(aTimerId, aTimerValue)
? NS_OK : NS_ERROR_FAILURE;
}
NS_IMETHODIMP
IccChild::SendStkEventDownload(nsIStkDownloadEvent* aEvent)
{
MOZ_ASSERT(aEvent);
nsCOMPtr<nsIStkCmdFactory> cmdFactory =
do_GetService(ICC_STK_CMD_FACTORY_CONTRACTID);
NS_ENSURE_TRUE(cmdFactory, NS_ERROR_FAILURE);
nsAutoString event;
nsresult rv = cmdFactory->DeflateDownloadEvent(aEvent, event);
NS_ENSURE_SUCCESS(rv, rv);
return PIccChild::SendStkEventDownload(event) ? NS_OK : NS_ERROR_FAILURE;
}
NS_IMETHODIMP
IccChild::ReadContacts(uint32_t aContactType, nsIIccCallback* aRequestReply)
{
return SendRequest(ReadContactsRequest(aContactType),
aRequestReply)
? NS_OK : NS_ERROR_FAILURE;
}
NS_IMETHODIMP
IccChild::UpdateContact(uint32_t aContactType, nsIIccContact* aContact,
const nsAString& aPin2,
nsIIccCallback* aRequestReply)
{
MOZ_ASSERT(aContact);
IccContactData contactData;
IccIPCUtils::GetIccContactDataFromIccContact(aContact, contactData);
return SendRequest(UpdateContactRequest(aContactType,
nsAutoString(aPin2),
contactData),
aRequestReply)
? NS_OK : NS_ERROR_FAILURE;
}
/**
* PIccRequestChild Implementation.
*/
@@ -327,6 +433,42 @@ IccRequestChild::Recv__delete__(const IccReply& aResponse)
mRequestReply->NotifyCardLockError(error.message(),
error.retryCount()));
}
case IccReply::TIccReplyReadContacts: {
const nsTArray<IccContactData>& data
= aResponse.get_IccReplyReadContacts().contacts();
uint32_t count = data.Length();
nsCOMArray<nsIIccContact> contactList;
nsresult rv;
for (uint32_t i = 0; i < count; i++) {
nsCOMPtr<nsIIccContact> contact;
rv = IccContact::Create(data[i].id(),
data[i].names(),
data[i].numbers(),
data[i].emails(),
getter_AddRefs(contact));
NS_ENSURE_SUCCESS(rv, false);
contactList.AppendElement(contact);
}
rv = mRequestReply->NotifyRetrievedIccContacts(contactList.Elements(),
count);
return NS_SUCCEEDED(rv);
}
case IccReply::TIccReplyUpdateContact: {
IccContactData data
= aResponse.get_IccReplyUpdateContact().contact();
nsCOMPtr<nsIIccContact> contact;
IccContact::Create(data.id(),
data.names(),
data.numbers(),
data.emails(),
getter_AddRefs(contact));
return NS_SUCCEEDED(
mRequestReply->NotifyUpdatedIccContact(contact));
}
default:
MOZ_CRASH("Received invalid response type!");
}
+6
View File
@@ -49,6 +49,12 @@ protected:
virtual bool
RecvNotifyIccInfoChanged(const OptionalIccInfoData& aInfoData) override;
virtual bool
RecvNotifyStkCommand(const nsString& aStkProactiveCmd) override;
virtual bool
RecvNotifyStkSessionEnd() override;
private:
~IccChild();
+86
View File
@@ -0,0 +1,86 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/icc/IccIPCUtils.h"
#include "mozilla/dom/icc/PIccTypes.h"
#include "nsIIccContact.h"
#include "nsIIccInfo.h"
namespace mozilla {
namespace dom {
namespace icc {
/*static*/ void
IccIPCUtils::GetIccInfoDataFromIccInfo(nsIIccInfo* aInInfo,
IccInfoData& aOutData)
{
aInInfo->GetIccType(aOutData.iccType());
aInInfo->GetIccid(aOutData.iccid());
aInInfo->GetMcc(aOutData.mcc());
aInInfo->GetMnc(aOutData.mnc());
aInInfo->GetSpn(aOutData.spn());
aInInfo->GetIsDisplayNetworkNameRequired(
&aOutData.isDisplayNetworkNameRequired());
aInInfo->GetIsDisplaySpnRequired(
&aOutData.isDisplaySpnRequired());
nsCOMPtr<nsIGsmIccInfo> gsmIccInfo(do_QueryInterface(aInInfo));
if (gsmIccInfo) {
gsmIccInfo->GetMsisdn(aOutData.phoneNumber());
}
nsCOMPtr<nsICdmaIccInfo> cdmaIccInfo(do_QueryInterface(aInInfo));
if (cdmaIccInfo) {
cdmaIccInfo->GetMdn(aOutData.phoneNumber());
cdmaIccInfo->GetPrlVersion(&aOutData.prlVersion());
}
}
/*static*/ void
IccIPCUtils::GetIccContactDataFromIccContact(nsIIccContact* aContact,
IccContactData& aOutData){
// Id
nsresult rv = aContact->GetId(aOutData.id());
NS_ENSURE_SUCCESS_VOID(rv);
// Names
char16_t** rawStringArray = nullptr;
uint32_t count = 0;
rv = aContact->GetNames(&count, &rawStringArray);
NS_ENSURE_SUCCESS_VOID(rv);
if (count > 0) {
for (uint32_t i = 0; i < count; i++) {
aOutData.names().AppendElement(nsDependentString(rawStringArray[i]));
}
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(count, rawStringArray);
}
// Numbers
rawStringArray = nullptr;
count = 0;
rv = aContact->GetNumbers(&count, &rawStringArray);
NS_ENSURE_SUCCESS_VOID(rv);
if (count > 0) {
for (uint32_t i = 0; i < count; i++) {
aOutData.numbers().AppendElement(nsDependentString(rawStringArray[i]));
}
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(count, rawStringArray);
}
// Emails
rawStringArray = nullptr;
count = 0;
rv = aContact->GetEmails(&count, &rawStringArray);
NS_ENSURE_SUCCESS_VOID(rv);
if (count > 0) {
for (uint32_t i = 0; i < count; i++) {
aOutData.emails().AppendElement(nsDependentString(rawStringArray[i]));
}
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(count, rawStringArray);
}
}
} // namespace icc
} // namespace dom
} // namespace mozilla
+35
View File
@@ -0,0 +1,35 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_icc_IccIPCUtils_h
#define mozilla_dom_icc_IccIPCUtils_h
class nsIIccContact;
class nsIIccInfo;
namespace mozilla {
namespace dom {
namespace icc {
class IccInfoData;
class IccContactData;
class IccIPCUtils
{
public:
static void GetIccInfoDataFromIccInfo(nsIIccInfo* aInInfo,
IccInfoData& aOutData);
static void GetIccContactDataFromIccContact(nsIIccContact* aContact,
IccContactData& aOutData);
private:
IccIPCUtils() {}
virtual ~IccIPCUtils() {}
};
} // namespace icc
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_icc_IccIPCUtils_h
+143 -41
View File
@@ -4,44 +4,16 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/icc/IccIPCUtils.h"
#include "mozilla/dom/icc/IccParent.h"
#include "nsIIccService.h"
#include "IccInfo.h"
using mozilla::dom::IccInfo;
#include "nsIStkCmdFactory.h"
#include "nsIStkProactiveCmd.h"
namespace mozilla {
namespace dom {
namespace icc {
namespace {
static void
GetIccInfoDataFromIccInfo(nsIIccInfo* aInInfo, IccInfoData& aOutData) {
aInInfo->GetIccType(aOutData.iccType());
aInInfo->GetIccid(aOutData.iccid());
aInInfo->GetMcc(aOutData.mcc());
aInInfo->GetMnc(aOutData.mnc());
aInInfo->GetSpn(aOutData.spn());
aInInfo->GetIsDisplayNetworkNameRequired(
&aOutData.isDisplayNetworkNameRequired());
aInInfo->GetIsDisplaySpnRequired(
&aOutData.isDisplaySpnRequired());
nsCOMPtr<nsIGsmIccInfo> gsmIccInfo(do_QueryInterface(aInInfo));
if (gsmIccInfo) {
gsmIccInfo->GetMsisdn(aOutData.phoneNumber());
}
nsCOMPtr<nsICdmaIccInfo> cdmaIccInfo(do_QueryInterface(aInInfo));
if (cdmaIccInfo) {
cdmaIccInfo->GetMdn(aOutData.phoneNumber());
cdmaIccInfo->GetPrlVersion(&aOutData.prlVersion());
}
}
} // anonymous namespace
/**
* PIccParent Implementation.
*/
@@ -86,7 +58,7 @@ IccParent::RecvInit(OptionalIccInfoData* aInfoData,
if (iccInfo) {
IccInfoData data;
GetIccInfoDataFromIccInfo(iccInfo, data);
IccIPCUtils::GetIccInfoDataFromIccInfo(iccInfo, data);
*aInfoData = OptionalIccInfoData(data);
return true;
@@ -97,6 +69,72 @@ IccParent::RecvInit(OptionalIccInfoData* aInfoData,
return true;
}
bool
IccParent::RecvStkResponse(const nsString& aCmd, const nsString& aResponse)
{
NS_ENSURE_TRUE(mIcc, false);
nsCOMPtr<nsIStkCmdFactory> cmdFactory =
do_GetService(ICC_STK_CMD_FACTORY_CONTRACTID);
NS_ENSURE_TRUE(cmdFactory, false);
nsCOMPtr<nsIStkProactiveCmd> cmd;
cmdFactory->InflateCommand(aCmd, getter_AddRefs(cmd));
NS_ENSURE_TRUE(cmd, false);
nsCOMPtr<nsIStkTerminalResponse> response;
cmdFactory->InflateResponse(aResponse, getter_AddRefs(response));
NS_ENSURE_TRUE(response, false);
nsresult rv = mIcc->SendStkResponse(cmd, response);
NS_ENSURE_SUCCESS(rv, false);
return true;
}
bool
IccParent::RecvStkMenuSelection(const uint16_t& aItemIdentifier,
const bool& aHelpRequested)
{
NS_ENSURE_TRUE(mIcc, false);
nsresult rv = mIcc->SendStkMenuSelection(aItemIdentifier, aHelpRequested);
NS_ENSURE_SUCCESS(rv, false);
return true;
}
bool
IccParent::RecvStkTimerExpiration(const uint16_t& aTimerId,
const uint32_t& aTimerValue)
{
NS_ENSURE_TRUE(mIcc, false);
nsresult rv = mIcc->SendStkTimerExpiration(aTimerId, aTimerValue);
NS_ENSURE_SUCCESS(rv, false);
return true;
}
bool
IccParent::RecvStkEventDownload(const nsString& aEvent)
{
NS_ENSURE_TRUE(mIcc, false);
nsCOMPtr<nsIStkCmdFactory> cmdFactory =
do_GetService(ICC_STK_CMD_FACTORY_CONTRACTID);
NS_ENSURE_TRUE(cmdFactory, false);
nsCOMPtr<nsIStkDownloadEvent> event;
cmdFactory->InflateDownloadEvent(aEvent, getter_AddRefs(event));
NS_ENSURE_TRUE(event, false);
nsresult rv = mIcc->SendStkEventDownload(event);
NS_ENSURE_SUCCESS(rv, false);
return true;
}
PIccRequestParent*
IccParent::AllocPIccRequestParent(const IccRequest& aRequest)
{
@@ -140,6 +178,10 @@ IccParent::RecvPIccRequestConstructor(PIccRequestParent* aActor,
return actor->DoRequest(aRequest.get_MatchMvnoRequest());
case IccRequest::TGetServiceStateEnabledRequest:
return actor->DoRequest(aRequest.get_GetServiceStateEnabledRequest());
case IccRequest::TReadContactsRequest:
return actor->DoRequest(aRequest.get_ReadContactsRequest());
case IccRequest::TUpdateContactRequest:
return actor->DoRequest(aRequest.get_UpdateContactRequest());
default:
MOZ_CRASH("Received invalid request type!");
}
@@ -154,17 +196,23 @@ IccParent::RecvPIccRequestConstructor(PIccRequestParent* aActor,
NS_IMPL_ISUPPORTS(IccParent, nsIIccListener)
NS_IMETHODIMP
IccParent::NotifyStkCommand(const nsAString & aMessage)
IccParent::NotifyStkCommand(nsIStkProactiveCmd *aStkProactiveCmd)
{
// Bug 1114938 - [B2G][ICC] Refactor STK in MozIcc.webidl with IPDL.
return NS_ERROR_NOT_IMPLEMENTED;
nsCOMPtr<nsIStkCmdFactory> cmdFactory =
do_GetService(ICC_STK_CMD_FACTORY_CONTRACTID);
NS_ENSURE_TRUE(cmdFactory, NS_ERROR_UNEXPECTED);
nsAutoString cmd;
nsresult rv = cmdFactory->DeflateCommand(aStkProactiveCmd, cmd);
NS_ENSURE_SUCCESS(rv, rv);
return SendNotifyStkCommand(cmd) ? NS_OK : NS_ERROR_FAILURE;
}
NS_IMETHODIMP
IccParent::NotifyStkSessionEnd()
{
// Bug 1114938 - [B2G][ICC] Refactor STK in MozIcc.webidl with IPDL.
return NS_ERROR_NOT_IMPLEMENTED;
return SendNotifyStkSessionEnd() ? NS_OK : NS_ERROR_FAILURE;;
}
NS_IMETHODIMP
@@ -194,7 +242,7 @@ IccParent::NotifyIccInfoChanged()
}
IccInfoData data;
GetIccInfoDataFromIccInfo(iccInfo, data);
IccIPCUtils::GetIccInfoDataFromIccInfo(iccInfo, data);
return SendNotifyIccInfoChanged(OptionalIccInfoData(data))
? NS_OK : NS_ERROR_FAILURE;
@@ -272,6 +320,30 @@ IccRequestParent::DoRequest(const GetServiceStateEnabledRequest& aRequest)
this));
}
bool
IccRequestParent::DoRequest(const ReadContactsRequest& aRequest)
{
return NS_SUCCEEDED(mIcc->ReadContacts(aRequest.contactType(),
this));
}
bool
IccRequestParent::DoRequest(const UpdateContactRequest& aRequest)
{
nsCOMPtr<nsIIccContact> contact;
nsresult rv = IccContact::Create(aRequest.contact().id(),
aRequest.contact().names(),
aRequest.contact().numbers(),
aRequest.contact().emails(),
getter_AddRefs(contact));
NS_ENSURE_SUCCESS(rv, false);
return NS_SUCCEEDED(mIcc->UpdateContact(aRequest.contactType(),
contact,
aRequest.pin2(),
this));
}
nsresult
IccRequestParent::SendReply(const IccReply& aReply)
{
@@ -307,16 +379,46 @@ IccRequestParent::NotifyGetCardLockRetryCount(int32_t aCount)
NS_IMETHODIMP
IccRequestParent::NotifyError(const nsAString & aErrorMsg)
{
return SendReply(IccReplyError(nsString(aErrorMsg)));
return SendReply(IccReplyError(nsAutoString(aErrorMsg)));
}
NS_IMETHODIMP
IccRequestParent::NotifyCardLockError(const nsAString & aErrorMsg,
int32_t aRetryCount)
{
return SendReply(IccReplyCardLockError(aRetryCount, nsString(aErrorMsg)));
return SendReply(IccReplyCardLockError(aRetryCount, nsAutoString(aErrorMsg)));
}
NS_IMETHODIMP
IccRequestParent::NotifyRetrievedIccContacts(nsIIccContact** aContacts,
unsigned int aCount)
{
nsTArray<IccContactData> contacts;
for (uint32_t i = 0; i < aCount; i++) {
MOZ_ASSERT(aContacts[i]);
IccContactData contactData;
IccIPCUtils::GetIccContactDataFromIccContact(aContacts[i], contactData);
contacts.AppendElement(contactData);
}
return SendReply(IccReplyReadContacts(contacts));
}
NS_IMETHODIMP
IccRequestParent::NotifyUpdatedIccContact(nsIIccContact* aContact)
{
MOZ_ASSERT(aContact);
IccContactData contactData;
IccIPCUtils::GetIccContactDataFromIccContact(aContact, contactData);
return SendReply(IccReplyUpdateContact(contactData));
}
} // namespace icc
} // namespace dom
} // namespace mozilla
} // namespace mozilla
+20
View File
@@ -39,6 +39,20 @@ protected:
OptionalIccInfoData* aInfoData,
uint32_t* aCardState) override;
virtual bool
RecvStkResponse(const nsString& aCmd, const nsString& aResponse) override;
virtual bool
RecvStkMenuSelection(const uint16_t& aItemIdentifier,
const bool& aHelpRequested) override;
virtual bool
RecvStkTimerExpiration(const uint16_t& aTimerId,
const uint32_t& aTimerValue) override;
virtual bool
RecvStkEventDownload(const nsString& aEvent) override;
virtual PIccRequestParent*
AllocPIccRequestParent(const IccRequest& aRequest) override;
@@ -96,6 +110,12 @@ private:
bool
DoRequest(const GetServiceStateEnabledRequest& aRequest);
bool
DoRequest(const ReadContactsRequest& aRequest);
bool
DoRequest(const UpdateContactRequest& aRequest);
nsresult
SendReply(const IccReply& aReply);
+55
View File
@@ -60,6 +60,18 @@ struct GetServiceStateEnabledRequest
uint32_t service;
};
struct ReadContactsRequest
{
uint32_t contactType;
};
struct UpdateContactRequest
{
uint32_t contactType;
nsString pin2;
IccContactData contact;
};
union IccRequest
{
GetCardLockEnabledRequest;
@@ -69,6 +81,8 @@ union IccRequest
GetCardLockRetryCountRequest;
MatchMvnoRequest;
GetServiceStateEnabledRequest;
ReadContactsRequest;
UpdateContactRequest;
};
sync protocol PIcc
@@ -87,6 +101,19 @@ child:
*/
NotifyIccInfoChanged(OptionalIccInfoData aInfoData);
/**
* Notify STK proactive command issue by selected UICC.
*
* @param aStkProactiveCmd
* a MozStkCommand instance serialized in JSON.
*/
NotifyStkCommand(nsString aStkProactiveCmd);
/**
* Notify that STK session is ended by selected UICC.
*/
NotifyStkSessionEnd();
parent:
/**
* Sent when the child no longer needs to use PIcc.
@@ -98,6 +125,34 @@ parent:
*/
PIccRequest(IccRequest aRequest);
/**
* Send STK response to the selected UICC.
*
* @param aCommand
* a MozStkCommand instance serialized in JSON.
* @param aResponse
* a MozStkResponse instance serialized in JSON.
*/
StkResponse(nsString aCommand, nsString aResponse);
/**
* Send STK Menu Selection to the selected UICC.
*/
StkMenuSelection(uint16_t aItemIdentifier, bool aHelpRequested);
/**
* Send STK Timer Expiration to the selected UICC.
*/
StkTimerExpiration(uint16_t aTimerId, uint32_t aTimerValue);
/**
* Send STK Event Download to the selected UICC.
*
* @param aEvent
* a MozStkXxxEvent instance serialized in JSON.
*/
StkEventDownload(nsString aEvent);
/**
* Sync call to initialize the updated IccInfo/CardState.
*/
+12
View File
@@ -34,12 +34,24 @@ struct IccReplyCardLockError
nsString message;
};
struct IccReplyReadContacts
{
IccContactData[] contacts;
};
struct IccReplyUpdateContact
{
IccContactData contact;
};
union IccReply
{
// Success
IccReplySuccess;
IccReplySuccessWithBoolean;
IccReplyCardLockRetryCount;
IccReplyReadContacts;
IccReplyUpdateContact;
// Error
IccReplyError;
IccReplyCardLockError;
+8
View File
@@ -19,6 +19,14 @@ struct IccInfoData
int32_t prlVersion;
};
struct IccContactData
{
nsString id;
nsString[] names;
nsString[] numbers;
nsString[] emails;
};
} // namespace icc
} // namespace dom
} // namespace mozilla
+6 -4
View File
@@ -15,7 +15,8 @@ EXPORTS.mozilla.dom += [
EXPORTS.mozilla.dom.icc += [
'ipc/IccChild.h',
'ipc/IccParent.h',
'ipc/IccIPCUtils.h',
'ipc/IccParent.h'
]
UNIFIED_SOURCES += [
@@ -23,11 +24,13 @@ UNIFIED_SOURCES += [
'Icc.cpp',
'IccCallback.cpp',
'IccCardLockError.cpp',
'IccContact.cpp',
"IccInfo.cpp",
'IccListener.cpp',
'IccManager.cpp',
'ipc/IccChild.cpp',
'ipc/IccIPCService.cpp',
'ipc/IccIPCUtils.cpp',
'ipc/IccParent.cpp',
]
@@ -38,12 +41,11 @@ IPDL_SOURCES += [
]
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk' and CONFIG['MOZ_B2G_RIL']:
EXTRA_JS_MODULES += [
'gonk/StkProactiveCmdFactory.jsm',
]
EXTRA_COMPONENTS += [
'gonk/IccService.js',
'gonk/IccService.manifest',
'gonk/StkCmdFactory.js',
'gonk/StkCmdFactory.manifest'
]
FAIL_ON_WARNINGS = True
+1 -2
View File
@@ -22,7 +22,6 @@
#include "nsIVariant.h"
#include "nsJSON.h"
#include "nsJSUtils.h"
#include "nsRadioInterfaceLayer.h"
#include "nsServiceManagerUtils.h"
#define MOBILECONN_ERROR_INVALID_PARAMETER NS_LITERAL_STRING("InvalidParameter")
@@ -1129,7 +1128,7 @@ MobileConnection::NotifyNetworkSelectionModeChanged()
// nsIIccListener
NS_IMETHODIMP
MobileConnection::NotifyStkCommand(const nsAString& aMessage)
MobileConnection::NotifyStkCommand(nsIStkProactiveCmd *aStkProactiveCmd)
{
return NS_OK;
}
@@ -537,10 +537,10 @@ MobileConnectionProvider.prototype = {
updateDataInfo: function(aNewInfo, aBatch = false) {
// For the data connection, the `connected` flag indicates whether
// there's an active data call. We get correct `connected` state here.
let active = gNetworkManager.active;
let active = gNetworkManager.activeNetworkInfo;
aNewInfo.connected = false;
if (active &&
active.type === Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE &&
active.type === Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE &&
active.serviceId === this._clientId) {
aNewInfo.connected = true;
}
@@ -1422,11 +1422,10 @@ MobileConnectionService.prototype = {
}
break;
case NS_DATA_CALL_ERROR_TOPIC_ID:
let network = aSubject;
try {
if (network instanceof Ci.nsIRilNetworkInterface) {
let rilNetwork = network.QueryInterface(Ci.nsIRilNetworkInterface);
this.notifyDataError(rilNetwork.serviceId, rilNetwork);
if (aSubject instanceof Ci.nsIRilNetworkInfo) {
let rilInfo = aSubject.QueryInterface(Ci.nsIRilNetworkInfo);
this.notifyDataError(rilInfo.serviceId, aData);
}
} catch (e) {}
break;
+29 -29
View File
@@ -232,10 +232,10 @@ MmsConnection.prototype = {
mmsProxy: "",
mmsPort: -1,
setApnSetting: function(network) {
this.mmsc = network.mmsc;
this.mmsProxy = network.mmsProxy;
this.mmsPort = network.mmsPort;
setApnSetting: function(networkInfo) {
this.mmsc = networkInfo.mmsc;
this.mmsProxy = networkInfo.mmsProxy;
this.mmsPort = networkInfo.mmsPort;
},
get proxyInfo() {
@@ -273,8 +273,8 @@ MmsConnection.prototype = {
// cache of hosts to be accessed when this connection is alive.
hostsToRoute: null,
// cache of the networkInterface acquired during this connection.
networkInterface: null,
// cache of the networkInfo acquired during this connection.
networkInfo: null,
connectTimer: null,
@@ -308,14 +308,14 @@ MmsConnection.prototype = {
// Clear cache.
this.hostsToRoute = [];
this.networkInterface = null;
this.networkInfo = null;
this.radioInterface.deactivateDataCallByType(Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_MMS);
this.radioInterface.deactivateDataCallByType(Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_MMS);
};
let promises =
this.hostsToRoute.map((aHost) => {
return gNetworkManager.removeHostRoute(this.networkInterface, aHost);
return gNetworkManager.removeHostRoute(this.networkInfo, aHost);
});
return Promise.all(promises)
@@ -447,7 +447,7 @@ MmsConnection.prototype = {
// Bug 1059110: Ensure all the initialization are done before setup data call.
if (DEBUG) debug("acquire: buffer the MMS request and setup the MMS data call.");
this.radioInterface.setupDataCallByType(Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_MMS);
this.radioInterface.setupDataCallByType(Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_MMS);
return false;
}
@@ -499,7 +499,7 @@ MmsConnection.prototype = {
host = uri.host;
} catch (e) {}
return gNetworkManager.addHostRoute(this.networkInterface, host)
return gNetworkManager.addHostRoute(this.networkInfo, host)
.then(() => {
if (this.hostsToRoute.indexOf(host) < 0) {
this.hostsToRoute.push(host);
@@ -522,20 +522,20 @@ MmsConnection.prototype = {
observe: function(subject, topic, data) {
switch (topic) {
case kNetworkConnStateChangedTopic: {
// The network for MMS connection must be nsIRilNetworkInterface.
if (!(subject instanceof Ci.nsIRilNetworkInterface)) {
// The network info for MMS connection must be nsIRilNetworkInfo.
if (!(subject instanceof Ci.nsIRilNetworkInfo)) {
return;
}
// Check if the network state change belongs to this service.
let network = subject.QueryInterface(Ci.nsIRilNetworkInterface);
if (network.serviceId != this.serviceId ||
network.type != Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_MMS) {
let networkInfo = subject.QueryInterface(Ci.nsIRilNetworkInfo);
if (networkInfo.serviceId != this.serviceId ||
networkInfo.type != Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_MMS) {
return;
}
let connected =
network.state == Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED;
networkInfo.state == Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED;
// Return if the MMS network state doesn't change, where the network
// state change can come from other non-MMS networks.
@@ -546,16 +546,16 @@ MmsConnection.prototype = {
this.connected = connected;
if (!this.connected) {
this.hostsToRoute = [];
this.networkInterface = null;
this.networkInfo = null;
return;
}
// Set up the MMS APN setting based on the connected MMS network,
// which is going to be used for the HTTP requests later.
this.setApnSetting(network);
this.setApnSetting(networkInfo);
// Cache connected network.
this.networkInterface = network;
// Cache connected network info.
this.networkInfo = networkInfo;
if (DEBUG) debug("Got the MMS network connected! Resend the buffered " +
"MMS requests: number: " + this.pendingCallbacks.length);
@@ -741,18 +741,18 @@ XPCOMUtils.defineLazyGetter(this, "gMmsTransactionHelper", function() {
cancellable.done(aHttpStatus, aData));
};
mmsConnection.ensureRouting(url)
.then(() => startTransaction(),
(aError) => {
debug("Failed to ensureRouting: " + aError);
let onRejected = aReason => {
debug('Failed to start a transaction: ' + aReason);
mmsConnection.release();
cancellable.done(_HTTP_STATUS_FAILED_TO_ROUTE, null);
};
// TODO: |getNetId| will be implemented as a sync call in nsINetworkManager
// once Bug 1141903 is landed.
mmsConnection.ensureRouting(url)
.then(() => gNetworkService.getNetId(mmsConnection.networkInterface.name),
(aReason) => onRejected('Failed to ensureRouting: ' + aReason))
.then((netId) => startTransaction(netId),
(aReason) => onRejected('Failed to getNetId: ' + aReason));
.then(() => gNetworkService.getNetId(mmsConnection.networkInfo.name))
.then((netId) => startTransaction(netId))
.catch((aReason) => onRejected(aReason));
});
return cancellable;
+3 -3
View File
@@ -1331,8 +1331,8 @@ let PushNetworkInfo = {
let nm = Cc["@mozilla.org/network/manager;1"]
.getService(Ci.nsINetworkManager);
if (nm.active &&
nm.active.type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE) {
if (nm.activeNetworkInfo &&
nm.activeNetworkInfo.type == Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE) {
let iccService = Cc["@mozilla.org/icc/iccservice;1"]
.getService(Ci.nsIIccService);
// TODO: Bug 927721 - PushService for multi-sim
@@ -1348,7 +1348,7 @@ let PushNetworkInfo = {
let ips = {};
let prefixLengths = {};
nm.active.getAddresses(ips, prefixLengths);
nm.activeNetworkInfo.getAddresses(ips, prefixLengths);
return {
mcc: iccInfo.mcc,
+3 -2
View File
@@ -1774,7 +1774,8 @@ this.PushService = {
}
let nm = Cc["@mozilla.org/network/manager;1"].getService(Ci.nsINetworkManager);
if (nm.active && nm.active.type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE) {
if (nm.activeNetworkInfo &&
nm.activeNetworkInfo.type == Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE) {
let iccService = Cc["@mozilla.org/icc/iccservice;1"].getService(Ci.nsIIccService);
// TODO: Bug 927721 - PushService for multi-sim
// In Multi-sim, there is more than one client in iccService. Each
@@ -1789,7 +1790,7 @@ this.PushService = {
let ips = {};
let prefixLengths = {};
nm.active.getAddresses(ips, prefixLengths);
nm.activeNetworkInfo.getAddresses(ips, prefixLengths);
return {
mcc: iccInfo.mcc,
+119 -91
View File
@@ -53,7 +53,9 @@ const DATACALLMANAGER_CID =
const DATACALLHANDLER_CID =
Components.ID("{132b650f-c4d8-4731-96c5-83785cb31dee}");
const RILNETWORKINTERFACE_CID =
Components.ID("{8c11bef9-9b4f-4d96-bed7-f5a1f48eabda}");
Components.ID("{9574ee84-5d0d-4814-b9e6-8b279e03dcf4}");
const RILNETWORKINFO_CID =
Components.ID("{dd6cf2f0-f0e3-449f-a69e-7c34fdcb8d4b}");
const TOPIC_XPCOM_SHUTDOWN = "xpcom-shutdown";
const TOPIC_MOZSETTINGS_CHANGED = "mozsettings-changed";
@@ -61,20 +63,20 @@ const TOPIC_PREF_CHANGED = "nsPref:changed";
const TOPIC_DATA_CALL_ERROR = "data-call-error";
const PREF_RIL_DEBUG_ENABLED = "ril.debugging.enabled";
const NETWORK_TYPE_UNKNOWN = Ci.nsINetworkInterface.NETWORK_TYPE_UNKNOWN;
const NETWORK_TYPE_WIFI = Ci.nsINetworkInterface.NETWORK_TYPE_WIFI;
const NETWORK_TYPE_MOBILE = Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE;
const NETWORK_TYPE_MOBILE_MMS = Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_MMS;
const NETWORK_TYPE_MOBILE_SUPL = Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_SUPL;
const NETWORK_TYPE_MOBILE_IMS = Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_IMS;
const NETWORK_TYPE_MOBILE_DUN = Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_DUN;
const NETWORK_TYPE_MOBILE_FOTA = Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_FOTA;
const NETWORK_TYPE_UNKNOWN = Ci.nsINetworkInfo.NETWORK_TYPE_UNKNOWN;
const NETWORK_TYPE_WIFI = Ci.nsINetworkInfo.NETWORK_TYPE_WIFI;
const NETWORK_TYPE_MOBILE = Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE;
const NETWORK_TYPE_MOBILE_MMS = Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_MMS;
const NETWORK_TYPE_MOBILE_SUPL = Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_SUPL;
const NETWORK_TYPE_MOBILE_IMS = Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_IMS;
const NETWORK_TYPE_MOBILE_DUN = Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_DUN;
const NETWORK_TYPE_MOBILE_FOTA = Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_FOTA;
const NETWORK_STATE_UNKNOWN = Ci.nsINetworkInterface.NETWORK_STATE_UNKNOWN;
const NETWORK_STATE_CONNECTING = Ci.nsINetworkInterface.NETWORK_STATE_CONNECTING;
const NETWORK_STATE_CONNECTED = Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED;
const NETWORK_STATE_DISCONNECTING = Ci.nsINetworkInterface.NETWORK_STATE_DISCONNECTING;
const NETWORK_STATE_DISCONNECTED = Ci.nsINetworkInterface.NETWORK_STATE_DISCONNECTED;
const NETWORK_STATE_UNKNOWN = Ci.nsINetworkInfo.NETWORK_STATE_UNKNOWN;
const NETWORK_STATE_CONNECTING = Ci.nsINetworkInfo.NETWORK_STATE_CONNECTING;
const NETWORK_STATE_CONNECTED = Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED;
const NETWORK_STATE_DISCONNECTING = Ci.nsINetworkInfo.NETWORK_STATE_DISCONNECTING;
const NETWORK_STATE_DISCONNECTED = Ci.nsINetworkInfo.NETWORK_STATE_DISCONNECTED;
const INT32_MAX = 2147483647;
@@ -415,7 +417,7 @@ DataCallHandler.prototype = {
this._dataCalls = [];
this.clientId = null;
this.dataCallinterface.unregisterListener(this);
this.dataCallInterface.unregisterListener(this);
this.dataCallInterface = null;
let mobileConnection =
@@ -625,8 +627,8 @@ DataCallHandler.prototype = {
return;
}
let wifi_active = false;
if (gNetworkManager.active &&
gNetworkManager.active.type == NETWORK_TYPE_WIFI) {
if (gNetworkManager.activeNetworkInfo &&
gNetworkManager.activeNetworkInfo.type == NETWORK_TYPE_WIFI) {
wifi_active = true;
}
@@ -709,7 +711,7 @@ DataCallHandler.prototype = {
if (!networkInterface) {
return NETWORK_STATE_UNKNOWN;
}
return networkInterface.state;
return networkInterface.info.state;
},
setupDataCallByType: function(aNetworkType) {
@@ -760,8 +762,8 @@ DataCallHandler.prototype = {
let dataDisconnecting = false;
this.dataNetworkInterfaces.forEach(function(networkInterface) {
if (networkInterface.enabled) {
if (networkInterface.state != NETWORK_STATE_UNKNOWN &&
networkInterface.state != NETWORK_STATE_DISCONNECTED) {
if (networkInterface.info.state != NETWORK_STATE_UNKNOWN &&
networkInterface.info.state != NETWORK_STATE_DISCONNECTED) {
dataDisconnecting = true;
}
networkInterface.disconnect();
@@ -836,23 +838,14 @@ DataCallHandler.prototype = {
/**
* Notify about data call setup error, called from DataCall.
*/
notifyDataCallError: function(aMessage) {
notifyDataCallError: function(aDataCall, aErrorMsg) {
// Notify data call error only for data APN
let networkInterface = this.dataNetworkInterfaces.get(NETWORK_TYPE_MOBILE);
if (networkInterface && networkInterface.enabled) {
let dataCall = networkInterface.dataCall;
// If there is a cid, compare cid; otherwise it is probably an error on
// data call setup.
if (aMessage.cid !== undefined) {
if (aMessage.linkInfo.cid == dataCall.linkInfo.cid) {
Services.obs.notifyObservers(networkInterface, TOPIC_DATA_CALL_ERROR,
null);
}
} else {
if (this._compareDataCallOptions(dataCall, aMessage)) {
Services.obs.notifyObservers(networkInterface, TOPIC_DATA_CALL_ERROR,
null);
}
if (this._compareDataCallOptions(dataCall, aDataCall)) {
Services.obs.notifyObservers(networkInterface.info,
TOPIC_DATA_CALL_ERROR, aErrorMsg);
}
}
},
@@ -1065,7 +1058,7 @@ DataCall.prototype = {
}
// Let DataCallHandler notify MobileConnectionService
this.dataCallHandler.notifyDataCallError(this);
this.dataCallHandler.notifyDataCallError(this, errorMsg);
// For suggestedRetryTime, the value of INT32_MAX(0x7fffffff) means no retry.
if (aDataCall.suggestedRetryTime === INT32_MAX ||
@@ -1242,7 +1235,7 @@ DataCall.prototype = {
inRequestedTypes: function(aType) {
for (let i = 0; i < this.requestedNetworkIfaces.length; i++) {
if (this.requestedNetworkIfaces[i].type == aType) {
if (this.requestedNetworkIfaces[i].info.type == aType) {
return true;
}
}
@@ -1279,7 +1272,7 @@ DataCall.prototype = {
},
connect: function(aNetworkInterface) {
if (DEBUG) this.debug("connect: " + aNetworkInterface.type);
if (DEBUG) this.debug("connect: " + aNetworkInterface.info.type);
if (this.requestedNetworkIfaces.indexOf(aNetworkInterface) == -1) {
this.requestedNetworkIfaces.push(aNetworkInterface);
@@ -1295,7 +1288,7 @@ DataCall.prototype = {
Services.tm.currentThread.dispatch(() => {
// Do not notify if state changed while this event was being dispatched,
// the state probably was notified already or need not to be notified.
if (aNetworkInterface.state == RIL.GECKO_NETWORK_STATE_CONNECTED) {
if (aNetworkInterface.info.state == RIL.GECKO_NETWORK_STATE_CONNECTED) {
aNetworkInterface.notifyRILNetworkInterface();
}
}, Ci.nsIEventTarget.DISPATCH_NORMAL);
@@ -1405,7 +1398,7 @@ DataCall.prototype = {
},
disconnect: function(aNetworkInterface) {
if (DEBUG) this.debug("disconnect: " + aNetworkInterface.type);
if (DEBUG) this.debug("disconnect: " + aNetworkInterface.info.type);
let index = this.requestedNetworkIfaces.indexOf(aNetworkInterface);
if (index != -1) {
@@ -1426,7 +1419,7 @@ DataCall.prototype = {
Services.tm.currentThread.dispatch(() => {
// Do not notify if state changed while this event was being dispatched,
// the state probably was notified already or need not to be notified.
if (aNetworkInterface.state == RIL.GECKO_NETWORK_STATE_DISCONNECTED) {
if (aNetworkInterface.info.state == RIL.GECKO_NETWORK_STATE_DISCONNECTED) {
aNetworkInterface.notifyRILNetworkInterface();
// Clear link info after notifying NetworkManager.
@@ -1449,7 +1442,7 @@ DataCall.prototype = {
},
deactivate: function() {
let reason = Ci.nsINetworkInterface.DATACALL_DEACTIVATE_NO_REASON;
let reason = Ci.nsIDataCallInterface.DATACALL_DEACTIVATE_NO_REASON;
if (DEBUG) {
this.debug("Going to disconnect data connection cid " + this.linkInfo.cid);
}
@@ -1481,61 +1474,56 @@ DataCall.prototype = {
}
};
function RILNetworkInterface(aDataCallHandler, aType, aApnSetting, aDataCall) {
if (!aDataCall) {
throw new Error("No dataCall for RILNetworkInterface: " + type);
}
this.dataCallHandler = aDataCallHandler;
function RILNetworkInfo(aClientId, aType, aNetworkInterface)
{
this.serviceId = aClientId;
this.type = aType;
this.apnSetting = aApnSetting;
this.dataCall = aDataCall;
this.enabled = false;
this.networkInterface = aNetworkInterface;
}
RILNetworkInfo.prototype = {
classID: RILNETWORKINFO_CID,
classInfo: XPCOMUtils.generateCI({classID: RILNETWORKINFO_CID,
classDescription: "RILNetworkInfo",
interfaces: [Ci.nsINetworkInfo,
Ci.nsIRilNetworkInfo]}),
QueryInterface: XPCOMUtils.generateQI([Ci.nsINetworkInfo,
Ci.nsIRilNetworkInfo]),
RILNetworkInterface.prototype = {
classID: RILNETWORKINTERFACE_CID,
classInfo: XPCOMUtils.generateCI({classID: RILNETWORKINTERFACE_CID,
classDescription: "RILNetworkInterface",
interfaces: [Ci.nsINetworkInterface,
Ci.nsIRilNetworkInterface]}),
QueryInterface: XPCOMUtils.generateQI([Ci.nsINetworkInterface,
Ci.nsIRilNetworkInterface]),
networkInterface: null,
// Hold reference to DataCall object which is determined at initilization.
dataCall: null,
getDataCall: function() {
return this.networkInterface.dataCall;
},
// If this RILNetworkInterface type is enabled or not.
enabled: null,
getApnSetting: function() {
return this.networkInterface.apnSetting;
},
debug: function(aMsg) {
dump("-*- RILNetworkInfo[" + this.serviceId + ":" + this.type + "]: " +
aMsg + "\n");
},
/**
* nsINetworkInterface Implementation
* nsINetworkInfo Implementation
*/
get state() {
if (!this.dataCall.inRequestedTypes(this.type)) {
let dataCall = this.getDataCall();
if (!dataCall.inRequestedTypes(this.type)) {
return NETWORK_STATE_DISCONNECTED;
}
return this.dataCall.state;
return dataCall.state;
},
type: null,
get name() {
return this.dataCall.linkInfo.ifname;
},
get httpProxyHost() {
return this.apnSetting.proxy || "";
},
get httpProxyPort() {
return this.apnSetting.port || "";
return this.getDataCall().linkInfo.ifname;
},
getAddresses: function(aIps, aPrefixLengths) {
let addresses = this.dataCall.linkInfo.addresses;
let addresses = this.getDataCall().linkInfo.addresses;
let ips = [];
let prefixLengths = [];
@@ -1552,33 +1540,33 @@ RILNetworkInterface.prototype = {
},
getGateways: function(aCount) {
let linkInfo = this.dataCall.linkInfo;
let linkInfo = this.getDataCall().linkInfo;
if (aCount) {
aCount.value = linkInfo.gateways.length;
}
return linkInfo.gateways.slice();
},
getDnses: function(aCount) {
let linkInfo = this.dataCall.linkInfo;
let linkInfo = this.getDataCall().linkInfo;
if (aCount) {
aCount.value = linkInfo.dnses.length;
}
return linkInfo.dnses.slice();
},
/**
* nsIRilNetworkInterface Implementation
* nsIRilNetworkInfo Implementation
*/
get serviceId() {
return this.dataCallHandler.clientId;
},
serviceId: 0,
get iccId() {
let icc = gIccService.getIccByServiceId(this.dataCallHandler.clientId);
let icc = gIccService.getIccByServiceId(this.serviceId);
let iccInfo = icc && icc.iccInfo;
return iccInfo && iccInfo.iccid;
@@ -1590,7 +1578,7 @@ RILNetworkInterface.prototype = {
throw Cr.NS_ERROR_UNEXPECTED;
}
return this.apnSetting.mmsc || "";
return this.getApnSetting().mmsc || "";
},
get mmsProxy() {
@@ -1599,7 +1587,7 @@ RILNetworkInterface.prototype = {
throw Cr.NS_ERROR_UNEXPECTED;
}
return this.apnSetting.mmsproxy || "";
return this.getApnSetting().mmsproxy || "";
},
get mmsPort() {
@@ -1610,26 +1598,66 @@ RILNetworkInterface.prototype = {
// Note: Port 0 is reserved, so we treat it as invalid as well.
// See http://www.iana.org/assignments/port-numbers
return this.apnSetting.mmsport || -1;
return this.getApnSetting().mmsport || -1;
},
};
function RILNetworkInterface(aDataCallHandler, aType, aApnSetting, aDataCall) {
if (!aDataCall) {
throw new Error("No dataCall for RILNetworkInterface: " + type);
}
this.dataCallHandler = aDataCallHandler;
this.enabled = false;
this.dataCall = aDataCall;
this.apnSetting = aApnSetting;
this.info = new RILNetworkInfo(aDataCallHandler.clientId, aType, this);
}
RILNetworkInterface.prototype = {
classID: RILNETWORKINTERFACE_CID,
classInfo: XPCOMUtils.generateCI({classID: RILNETWORKINTERFACE_CID,
classDescription: "RILNetworkInterface",
interfaces: [Ci.nsINetworkInterface]}),
QueryInterface: XPCOMUtils.generateQI([Ci.nsINetworkInterface]),
// If this RILNetworkInterface type is enabled or not.
enabled: null,
apnSetting: null,
dataCall: null,
/**
* nsINetworkInterface Implementation
*/
info: null,
get httpProxyHost() {
return this.apnSetting.proxy || "";
},
get httpProxyPort() {
return this.apnSetting.port || "";
},
// Helpers
debug: function(aMsg) {
dump("-*- RILNetworkInterface[" + this.dataCallHandler.clientId + ":" +
this.type + "]: " + aMsg + "\n");
this.info.type + "]: " + aMsg + "\n");
},
apnSetting: null,
get connected() {
return this.state == NETWORK_STATE_CONNECTED;
return this.info.state == NETWORK_STATE_CONNECTED;
},
notifyRILNetworkInterface: function() {
if (DEBUG) {
this.debug("notifyRILNetworkInterface type: " + this.type + ", state: " +
this.state);
this.debug("notifyRILNetworkInterface type: " + this.info.type +
", state: " + this.info.state);
}
gNetworkManager.updateNetworkInterface(this);
+21 -21
View File
@@ -25,7 +25,7 @@
#include "nsContentUtils.h"
#include "nsGeoPosition.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsINetworkManager.h"
#include "nsINetworkInterface.h"
#include "nsIObserverService.h"
#include "nsJSUtils.h"
#include "nsPrintfCString.h"
@@ -354,12 +354,12 @@ int32_t
GonkGPSGeolocationProvider::GetDataConnectionState()
{
if (!mRadioInterface) {
return nsINetworkInterface::NETWORK_STATE_UNKNOWN;
return nsINetworkInfo::NETWORK_STATE_UNKNOWN;
}
int32_t state;
mRadioInterface->GetDataCallStateByType(
nsINetworkInterface::NETWORK_TYPE_MOBILE_SUPL, &state);
nsINetworkInfo::NETWORK_TYPE_MOBILE_SUPL, &state);
return state;
}
@@ -378,7 +378,7 @@ GonkGPSGeolocationProvider::SetAGpsDataConn(nsAString& aApn)
int32_t connectionState = GetDataConnectionState();
NS_ConvertUTF16toUTF8 apn(aApn);
if (connectionState == nsINetworkInterface::NETWORK_STATE_CONNECTED) {
if (connectionState == nsINetworkInfo::NETWORK_STATE_CONNECTED) {
// The definition of availability is
// 1. The device is connected to the home network
// 2. The device is connected to a foreign network and data
@@ -395,7 +395,7 @@ GonkGPSGeolocationProvider::SetAGpsDataConn(nsAString& aApn)
#else
mAGpsInterface->data_conn_open(apn.get());
#endif
} else if (connectionState == nsINetworkInterface::NETWORK_STATE_DISCONNECTED) {
} else if (connectionState == nsINetworkInfo::NETWORK_STATE_DISCONNECTED) {
if (hasUpdateNetworkAvailability) {
mAGpsRilInterface->update_network_availability(false, apn.get());
}
@@ -445,12 +445,12 @@ GonkGPSGeolocationProvider::RequestDataConnection()
return;
}
if (GetDataConnectionState() == nsINetworkInterface::NETWORK_STATE_CONNECTED) {
if (GetDataConnectionState() == nsINetworkInfo::NETWORK_STATE_CONNECTED) {
// Connection is already established, we don't need to setup again.
// We just get supl APN and make AGPS data connection state updated.
RequestSettingValue("ril.supl.apn");
} else {
mRadioInterface->SetupDataCallByType(nsINetworkInterface::NETWORK_TYPE_MOBILE_SUPL);
mRadioInterface->SetupDataCallByType(nsINetworkInfo::NETWORK_TYPE_MOBILE_SUPL);
}
}
@@ -463,7 +463,7 @@ GonkGPSGeolocationProvider::ReleaseDataConnection()
return;
}
mRadioInterface->DeactivateDataCallByType(nsINetworkInterface::NETWORK_TYPE_MOBILE_SUPL);
mRadioInterface->DeactivateDataCallByType(nsINetworkInfo::NETWORK_TYPE_MOBILE_SUPL);
}
void
@@ -976,15 +976,15 @@ int
ConvertToGpsNetworkType(int aNetworkInterfaceType)
{
switch (aNetworkInterfaceType) {
case nsINetworkInterface::NETWORK_TYPE_WIFI:
case nsINetworkInfo::NETWORK_TYPE_WIFI:
return AGPS_RIL_NETWORK_TYPE_WIFI;
case nsINetworkInterface::NETWORK_TYPE_MOBILE:
case nsINetworkInfo::NETWORK_TYPE_MOBILE:
return AGPS_RIL_NETWORK_TYPE_MOBILE;
case nsINetworkInterface::NETWORK_TYPE_MOBILE_MMS:
case nsINetworkInfo::NETWORK_TYPE_MOBILE_MMS:
return AGPS_RIL_NETWORK_TYPE_MOBILE_MMS;
case nsINetworkInterface::NETWORK_TYPE_MOBILE_SUPL:
case nsINetworkInfo::NETWORK_TYPE_MOBILE_SUPL:
return AGPS_RIL_NETWORK_TYPE_MOBILE_SUPL;
case nsINetworkInterface::NETWORK_TYPE_MOBILE_DUN:
case nsINetworkInfo::NETWORK_TYPE_MOBILE_DUN:
return AGPS_RIL_NETWORK_TTYPE_MOBILE_DUN;
default:
NS_WARNING(nsPrintfCString("Unknown network type mapping %d",
@@ -1003,21 +1003,21 @@ GonkGPSGeolocationProvider::Observe(nsISupports* aSubject,
#ifdef MOZ_B2G_RIL
if (!strcmp(aTopic, kNetworkConnStateChangedTopic)) {
nsCOMPtr<nsINetworkInterface> iface = do_QueryInterface(aSubject);
if (!iface) {
nsCOMPtr<nsINetworkInfo> info = do_QueryInterface(aSubject);
if (!info) {
return NS_OK;
}
nsCOMPtr<nsIRilNetworkInterface> rilface = do_QueryInterface(aSubject);
nsCOMPtr<nsIRilNetworkInfo> rilInfo = do_QueryInterface(aSubject);
if (mAGpsRilInterface && mAGpsRilInterface->update_network_state) {
int32_t state;
int32_t type;
iface->GetState(&state);
iface->GetType(&type);
bool connected = (state == nsINetworkInterface::NETWORK_STATE_CONNECTED);
info->GetState(&state);
info->GetType(&type);
bool connected = (state == nsINetworkInfo::NETWORK_STATE_CONNECTED);
bool roaming = false;
int gpsNetworkType = ConvertToGpsNetworkType(type);
if (gpsNetworkType >= 0) {
if (rilface) {
if (rilInfo) {
do {
nsCOMPtr<nsIMobileConnectionService> service =
do_GetService(NS_MOBILE_CONNECTION_SERVICE_CONTRACTID);
@@ -1048,7 +1048,7 @@ GonkGPSGeolocationProvider::Observe(nsISupports* aSubject,
}
}
// No data connection
if (!rilface) {
if (!rilInfo) {
return NS_OK;
}
-474
View File
@@ -1,474 +0,0 @@
/* 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.
*/
"use strict";
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
/* global RIL */
XPCOMUtils.defineLazyGetter(this, "RIL", function () {
let obj = {};
Cu.import("resource://gre/modules/ril_consts.js", obj);
return obj;
});
const NS_XPCOM_SHUTDOWN_OBSERVER_ID = "xpcom-shutdown";
const NS_PREFBRANCH_PREFCHANGE_TOPIC_ID = "nsPref:changed";
const kPrefRilNumRadioInterfaces = "ril.numRadioInterfaces";
const kPrefRilDebuggingEnabled = "ril.debugging.enabled";
let DEBUG;
function debug(s) {
dump("-*- RILContentHelper: " + s + "\n");
}
const RILCONTENTHELPER_CID =
Components.ID("{472816e1-1fd6-4405-996c-806f9ea68174}");
const RIL_IPC_MSG_NAMES = [
"RIL:StkCommand",
"RIL:StkSessionEnd",
"RIL:ReadIccContacts",
"RIL:UpdateIccContact",
];
/* global cpmm */
XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
"@mozilla.org/childprocessmessagemanager;1",
"nsISyncMessageSender");
/* global UUIDGenerator */
XPCOMUtils.defineLazyServiceGetter(this, "UUIDGenerator",
"@mozilla.org/uuid-generator;1",
"nsIUUIDGenerator");
/* global gNumRadioInterfaces */
XPCOMUtils.defineLazyGetter(this, "gNumRadioInterfaces", function() {
let appInfo = Cc["@mozilla.org/xre/app-info;1"];
let isParentProcess = !appInfo || appInfo.getService(Ci.nsIXULRuntime)
.processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
if (isParentProcess) {
let ril = { numRadioInterfaces: 0 };
try {
ril = Cc["@mozilla.org/ril;1"].getService(Ci.nsIRadioInterfaceLayer);
} catch(e) {}
return ril.numRadioInterfaces;
}
return Services.prefs.getIntPref(kPrefRilNumRadioInterfaces);
});
function RILContentHelper() {
this.updateDebugFlag();
this.numClients = gNumRadioInterfaces;
if (DEBUG) debug("Number of clients: " + this.numClients);
this.initDOMRequestHelper(/* aWindow */ null, RIL_IPC_MSG_NAMES);
this._windowsMap = [];
this._iccListeners = [];
Services.obs.addObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
Services.prefs.addObserver(kPrefRilDebuggingEnabled, this, false);
}
RILContentHelper.prototype = {
__proto__: DOMRequestIpcHelper.prototype,
QueryInterface: XPCOMUtils.generateQI([Ci.nsIIccProvider,
Ci.nsIObserver,
Ci.nsISupportsWeakReference]),
classID: RILCONTENTHELPER_CID,
classInfo: XPCOMUtils.generateCI({classID: RILCONTENTHELPER_CID,
classDescription: "RILContentHelper",
interfaces: [Ci.nsIIccProvider]}),
updateDebugFlag: function() {
try {
DEBUG = RIL.DEBUG_CONTENT_HELPER ||
Services.prefs.getBoolPref(kPrefRilDebuggingEnabled);
} catch (e) {}
},
_windowsMap: null,
/**
* nsIIccProvider
*/
sendStkResponse: function(clientId, window, command, response) {
if (window == null) {
throw Components.Exception("Can't get window object",
Cr.NS_ERROR_UNEXPECTED);
}
response.command = command;
cpmm.sendAsyncMessage("RIL:SendStkResponse", {
clientId: clientId,
data: response
});
},
sendStkMenuSelection: function(clientId, window, itemIdentifier,
helpRequested) {
if (window == null) {
throw Components.Exception("Can't get window object",
Cr.NS_ERROR_UNEXPECTED);
}
cpmm.sendAsyncMessage("RIL:SendStkMenuSelection", {
clientId: clientId,
data: {
itemIdentifier: itemIdentifier,
helpRequested: helpRequested
}
});
},
sendStkTimerExpiration: function(clientId, window, timer) {
if (window == null) {
throw Components.Exception("Can't get window object",
Cr.NS_ERROR_UNEXPECTED);
}
cpmm.sendAsyncMessage("RIL:SendStkTimerExpiration", {
clientId: clientId,
data: {
timer: timer
}
});
},
sendStkEventDownload: function(clientId, window, event) {
if (window == null) {
throw Components.Exception("Can't get window object",
Cr.NS_ERROR_UNEXPECTED);
}
cpmm.sendAsyncMessage("RIL:SendStkEventDownload", {
clientId: clientId,
data: {
event: event
}
});
},
readContacts: function(clientId, window, contactType) {
if (window == null) {
throw Components.Exception("Can't get window object",
Cr.NS_ERROR_UNEXPECTED);
}
let request = Services.DOMRequest.createRequest(window);
let requestId = this.getRequestId(request);
this._windowsMap[requestId] = window;
cpmm.sendAsyncMessage("RIL:ReadIccContacts", {
clientId: clientId,
data: {
requestId: requestId,
contactType: contactType
}
});
return request;
},
updateContact: function(clientId, window, contactType, contact, pin2) {
if (window == null) {
throw Components.Exception("Can't get window object",
Cr.NS_ERROR_UNEXPECTED);
}
let request = Services.DOMRequest.createRequest(window);
let requestId = this.getRequestId(request);
this._windowsMap[requestId] = window;
// Parsing nsDOMContact to Icc Contact format
let iccContact = {};
if (Array.isArray(contact.name) && contact.name[0]) {
iccContact.alphaId = contact.name[0];
}
if (Array.isArray(contact.tel)) {
iccContact.number = contact.tel[0] && contact.tel[0].value;
let telArray = contact.tel.slice(1);
let length = telArray.length;
if (length > 0) {
iccContact.anr = [];
}
for (let i = 0; i < telArray.length; i++) {
iccContact.anr.push(telArray[i].value);
}
}
if (Array.isArray(contact.email) && contact.email[0]) {
iccContact.email = contact.email[0].value;
}
iccContact.contactId = contact.id;
cpmm.sendAsyncMessage("RIL:UpdateIccContact", {
clientId: clientId,
data: {
requestId: requestId,
contactType: contactType,
contact: iccContact,
pin2: pin2
}
});
return request;
},
_iccListeners: null,
registerListener: function(listenerType, clientId, listener) {
if (!this[listenerType]) {
return;
}
let listeners = this[listenerType][clientId];
if (!listeners) {
listeners = this[listenerType][clientId] = [];
}
if (listeners.indexOf(listener) != -1) {
throw new Error("Already registered this listener!");
}
listeners.push(listener);
if (DEBUG) debug("Registered " + listenerType + " listener: " + listener);
},
unregisterListener: function(listenerType, clientId, listener) {
if (!this[listenerType]) {
return;
}
let listeners = this[listenerType][clientId];
if (!listeners) {
return;
}
let index = listeners.indexOf(listener);
if (index != -1) {
listeners.splice(index, 1);
if (DEBUG) debug("Unregistered listener: " + listener);
}
},
registerIccMsg: function(clientId, listener) {
if (DEBUG) debug("Registering for ICC related messages");
this.registerListener("_iccListeners", clientId, listener);
cpmm.sendAsyncMessage("RIL:RegisterIccMsg");
},
unregisterIccMsg: function(clientId, listener) {
this.unregisterListener("_iccListeners", clientId, listener);
},
// nsIObserver
observe: function(subject, topic, data) {
switch (topic) {
case NS_PREFBRANCH_PREFCHANGE_TOPIC_ID:
if (data == kPrefRilDebuggingEnabled) {
this.updateDebugFlag();
}
break;
case NS_XPCOM_SHUTDOWN_OBSERVER_ID:
this.destroyDOMRequestHelper();
Services.obs.removeObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
break;
}
},
// nsIMessageListener
fireRequestSuccess: function(requestId, result) {
let request = this.takeRequest(requestId);
if (!request) {
if (DEBUG) {
debug("not firing success for id: " + requestId +
", result: " + JSON.stringify(result));
}
return;
}
if (DEBUG) {
debug("fire request success, id: " + requestId +
", result: " + JSON.stringify(result));
}
Services.DOMRequest.fireSuccess(request, result);
},
dispatchFireRequestSuccess: function(requestId, result) {
let currentThread = Services.tm.currentThread;
currentThread.dispatch(this.fireRequestSuccess.bind(this, requestId, result),
Ci.nsIThread.DISPATCH_NORMAL);
},
fireRequestError: function(requestId, error) {
let request = this.takeRequest(requestId);
if (!request) {
if (DEBUG) {
debug("not firing error for id: " + requestId +
", error: " + JSON.stringify(error));
}
return;
}
if (DEBUG) {
debug("fire request error, id: " + requestId +
", result: " + JSON.stringify(error));
}
Services.DOMRequest.fireError(request, error);
},
dispatchFireRequestError: function(requestId, error) {
let currentThread = Services.tm.currentThread;
currentThread.dispatch(this.fireRequestError.bind(this, requestId, error),
Ci.nsIThread.DISPATCH_NORMAL);
},
fireRequestDetailedError: function(requestId, detailedError) {
let request = this.takeRequest(requestId);
if (!request) {
if (DEBUG) {
debug("not firing detailed error for id: " + requestId +
", detailedError: " + JSON.stringify(detailedError));
}
return;
}
Services.DOMRequest.fireDetailedError(request, detailedError);
},
receiveMessage: function(msg) {
let request;
if (DEBUG) {
debug("Received message '" + msg.name + "': " + JSON.stringify(msg.json));
}
let data = msg.json.data;
let clientId = msg.json.clientId;
switch (msg.name) {
case "RIL:StkCommand":
this._deliverEvent(clientId, "_iccListeners", "notifyStkCommand",
[JSON.stringify(data)]);
break;
case "RIL:StkSessionEnd":
this._deliverEvent(clientId, "_iccListeners", "notifyStkSessionEnd", null);
break;
case "RIL:ReadIccContacts":
this.handleReadIccContacts(data);
break;
case "RIL:UpdateIccContact":
this.handleUpdateIccContact(data);
break;
}
},
handleReadIccContacts: function(message) {
if (message.errorMsg) {
this.fireRequestError(message.requestId, message.errorMsg);
return;
}
let window = this._windowsMap[message.requestId];
delete this._windowsMap[message.requestId];
let contacts = message.contacts;
let result = new window.Array();
contacts.forEach(function(c) {
let prop = {name: [c.alphaId], tel: [{value: c.number}]};
if (c.email) {
prop.email = [{value: c.email}];
}
// ANR - Additional Number
let anrLen = c.anr ? c.anr.length : 0;
for (let i = 0; i < anrLen; i++) {
prop.tel.push({value: c.anr[i]});
}
let contact = new window.mozContact(prop);
contact.id = c.contactId;
result.push(contact);
});
this.fireRequestSuccess(message.requestId, result);
},
handleUpdateIccContact: function(message) {
if (message.errorMsg) {
this.fireRequestError(message.requestId, message.errorMsg);
return;
}
let window = this._windowsMap[message.requestId];
delete this._windowsMap[message.requestId];
let iccContact = message.contact;
let prop = {name: [iccContact.alphaId], tel: [{value: iccContact.number}]};
if (iccContact.email) {
prop.email = [{value: iccContact.email}];
}
// ANR - Additional Number
let anrLen = iccContact.anr ? iccContact.anr.length : 0;
for (let i = 0; i < anrLen; i++) {
prop.tel.push({value: iccContact.anr[i]});
}
let contact = new window.mozContact(prop);
contact.id = iccContact.contactId;
this.fireRequestSuccess(message.requestId, contact);
},
_deliverEvent: function(clientId, listenerType, name, args) {
if (!this[listenerType]) {
return;
}
let thisListeners = this[listenerType][clientId];
if (!thisListeners) {
return;
}
let listeners = thisListeners.slice();
for (let listener of listeners) {
if (thisListeners.indexOf(listener) == -1) {
continue;
}
let handler = listener[name];
if (typeof handler != "function") {
throw new Error("No handler for " + name);
}
try {
handler.apply(listener, args);
} catch (e) {
if (DEBUG) debug("listener for " + name + " threw an exception: " + e);
}
}
}
};
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([RILContentHelper]);
-20
View File
@@ -1,20 +0,0 @@
# 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.
# RILContentHelper.js
# TODO: Bug 815526, deprecate RILContentHelper:
# To be removed from b2g/installer/package-manifest.in as well.
component {472816e1-1fd6-4405-996c-806f9ea68174} RILContentHelper.js
contract @mozilla.org/ril/content-helper;1 {472816e1-1fd6-4405-996c-806f9ea68174}
category profile-after-change RILContentHelper @mozilla.org/ril/content-helper;1
+13 -7
View File
@@ -14,12 +14,6 @@ XPCOMUtils.defineLazyGetter(this, "RIL", function () {
return obj;
});
XPCOMUtils.defineLazyGetter(this, "gStkCmdFactory", function() {
let stk = {};
Cu.import("resource://gre/modules/StkProactiveCmdFactory.jsm", stk);
return stk.StkProactiveCmdFactory;
});
/**
* RILSystemMessenger
*/
@@ -38,6 +32,18 @@ RILSystemMessenger.prototype = {
// Function stub to be replaced by the owner of this messenger.
},
/**
* Hook of the function to create MozStkCommand message.
* @param aStkProactiveCmd
* nsIStkProactiveCmd instance.
*
* @return a JS object which complies the dictionary of MozStkCommand defined
* in MozStkCommandEvent.webidl
*/
createCommandMessage: function(aStkProactiveCmd) {
// Function stub to be replaced by the owner of this messenger.
},
/**
* Wrapper to send "telephony-new-call" system message.
*/
@@ -322,7 +328,7 @@ RILSystemMessenger.prototype = {
notifyStkProactiveCommand: function(aIccId, aCommand) {
this.broadcastMessage("icc-stkcommand", {
iccId: aIccId,
command: gStkCmdFactory.createCommandMessage(aCommand)
command: this.createCommandMessage(aCommand)
});
}
};
@@ -21,6 +21,10 @@ XPCOMUtils.defineLazyServiceGetter(this, "gSystemMessenger",
"@mozilla.org/system-message-internal;1",
"nsISystemMessagesInternal");
XPCOMUtils.defineLazyServiceGetter(this, "gStkCmdFactory",
"@mozilla.org/icc/stkcmdfactory;1",
"nsIStkCmdFactory");
let DEBUG = false;
function debug(s) {
dump("-@- RILSystemMessenger: " + s + "\n");
@@ -45,6 +49,10 @@ function RILSystemMessengerHelper() {
gSystemMessenger.broadcastMessage(aType, aMessage);
};
this.messenger.createCommandMessage = (aStkProactiveCmd) => {
return gStkCmdFactory.createCommandMessage(aStkProactiveCmd);
};
}
RILSystemMessengerHelper.prototype = {
+19 -312
View File
@@ -75,19 +75,8 @@ const kPrefRilDebuggingEnabled = "ril.debugging.enabled";
const RADIO_POWER_OFF_TIMEOUT = 30000;
const HW_DEFAULT_CLIENT_ID = 0;
const NETWORK_TYPE_WIFI = Ci.nsINetworkInterface.NETWORK_TYPE_WIFI;
const NETWORK_TYPE_MOBILE = Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE;
// TODO: Bug 815526, deprecate RILContentHelper.
const RIL_IPC_ICCMANAGER_MSG_NAMES = [
"RIL:SendStkResponse",
"RIL:SendStkMenuSelection",
"RIL:SendStkTimerExpiration",
"RIL:SendStkEventDownload",
"RIL:ReadIccContacts",
"RIL:UpdateIccContact",
"RIL:RegisterIccMsg",
];
const NETWORK_TYPE_WIFI = Ci.nsINetworkInfo.NETWORK_TYPE_WIFI;
const NETWORK_TYPE_MOBILE = Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE;
// set to true in ril_consts.js to see debug messages
var DEBUG = RIL.DEBUG_RIL;
@@ -152,10 +141,6 @@ XPCOMUtils.defineLazyServiceGetter(this, "gCellBroadcastService",
"@mozilla.org/cellbroadcast/cellbroadcastservice;1",
"nsIGonkCellBroadcastService");
XPCOMUtils.defineLazyServiceGetter(this, "gIccMessenger",
"@mozilla.org/ril/system-messenger-helper;1",
"nsIIccMessenger");
XPCOMUtils.defineLazyServiceGetter(this, "gDataCallManager",
"@mozilla.org/datacall/manager;1",
"nsIDataCallManager");
@@ -164,215 +149,9 @@ XPCOMUtils.defineLazyServiceGetter(this, "gDataCallInterfaceService",
"@mozilla.org/datacall/interfaceservice;1",
"nsIGonkDataCallInterfaceService");
XPCOMUtils.defineLazyGetter(this, "gStkCmdFactory", function() {
let stk = {};
Cu.import("resource://gre/modules/StkProactiveCmdFactory.jsm", stk);
return stk.StkProactiveCmdFactory;
});
// TODO: Bug 815526, deprecate RILContentHelper.
XPCOMUtils.defineLazyGetter(this, "gMessageManager", function() {
return {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIMessageListener,
Ci.nsIObserver]),
ril: null,
// Manage message targets in terms of topic. Only the authorized and
// registered contents can receive related messages.
targetsByTopic: {},
topics: [],
targetMessageQueue: [],
ready: false,
init: function(ril) {
this.ril = ril;
Services.obs.addObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
Services.obs.addObserver(this, kSysMsgListenerReadyObserverTopic, false);
this._registerMessageListeners();
},
_shutdown: function() {
this.ril = null;
Services.obs.removeObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
this._unregisterMessageListeners();
},
_registerMessageListeners: function() {
ppmm.addMessageListener("child-process-shutdown", this);
for (let msgName of RIL_IPC_ICCMANAGER_MSG_NAMES) {
ppmm.addMessageListener(msgName, this);
}
},
_unregisterMessageListeners: function() {
ppmm.removeMessageListener("child-process-shutdown", this);
for (let msgName of RIL_IPC_ICCMANAGER_MSG_NAMES) {
ppmm.removeMessageListener(msgName, this);
}
ppmm = null;
},
_registerMessageTarget: function(topic, target) {
let targets = this.targetsByTopic[topic];
if (!targets) {
targets = this.targetsByTopic[topic] = [];
let list = this.topics;
if (list.indexOf(topic) == -1) {
list.push(topic);
}
}
if (targets.indexOf(target) != -1) {
if (DEBUG) debug("Already registered this target!");
return;
}
targets.push(target);
if (DEBUG) debug("Registered " + topic + " target: " + target);
},
_unregisterMessageTarget: function(topic, target) {
if (topic == null) {
// Unregister the target for every topic when no topic is specified.
for (let type of this.topics) {
this._unregisterMessageTarget(type, target);
}
return;
}
// Unregister the target for a specified topic.
let targets = this.targetsByTopic[topic];
if (!targets) {
return;
}
let index = targets.indexOf(target);
if (index != -1) {
targets.splice(index, 1);
if (DEBUG) debug("Unregistered " + topic + " target: " + target);
}
},
_enqueueTargetMessage: function(topic, message, options) {
let msg = { topic : topic,
message : message,
options : options };
// Remove previous queued message with the same message type and client Id
// , only one message per (message type + client Id) is allowed in queue.
let messageQueue = this.targetMessageQueue;
for(let i = 0; i < messageQueue.length; i++) {
if (messageQueue[i].message === message &&
messageQueue[i].options.clientId === options.clientId) {
messageQueue.splice(i, 1);
break;
}
}
messageQueue.push(msg);
},
_sendTargetMessage: function(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() {
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(msg) {
if (DEBUG) debug("Received '" + msg.name + "' message from content process");
if (msg.name == "child-process-shutdown") {
// By the time we receive child-process-shutdown, the child process has
// already forgotten its permissions so we need to unregister the target
// for every permission.
this._unregisterMessageTarget(null, msg.target);
return null;
}
if (RIL_IPC_ICCMANAGER_MSG_NAMES.indexOf(msg.name) != -1) {
if (!msg.target.assertPermission("mobileconnection")) {
if (DEBUG) {
debug("IccManager message " + msg.name +
" from a content process with no 'mobileconnection' privileges.");
}
return null;
}
} else {
if (DEBUG) debug("Ignoring unknown message type: " + msg.name);
return null;
}
switch (msg.name) {
case "RIL:RegisterIccMsg":
this._registerMessageTarget("icc", msg.target);
return null;
}
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(subject, topic, data) {
switch (topic) {
case kSysMsgListenerReadyObserverTopic:
Services.obs.removeObserver(this, kSysMsgListenerReadyObserverTopic);
this._resendQueuedTargetMessage();
break;
case NS_XPCOM_SHUTDOWN_OBSERVER_ID:
this._shutdown();
break;
}
},
sendIccMessage: function(message, clientId, data) {
this._sendTargetMessage("icc", message, {
clientId: clientId,
data: data
});
}
};
});
XPCOMUtils.defineLazyServiceGetter(this, "gStkCmdFactory",
"@mozilla.org/icc/stkcmdfactory;1",
"nsIStkCmdFactory");
XPCOMUtils.defineLazyGetter(this, "gRadioEnabledController", function() {
let _ril = null;
@@ -646,7 +425,6 @@ function RadioInterfaceLayer() {
Services.obs.addObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
Services.prefs.addObserver(kPrefRilDebuggingEnabled, this, false);
gMessageManager.init(this); // TODO: Bug 815526, deprecate RILContentHelper.
gRadioEnabledController.init(this);
}
RadioInterfaceLayer.prototype = {
@@ -870,39 +648,13 @@ WorkerMessenger.prototype = {
message.rilMessageType = rilMessageType;
this.worker.postMessage(message);
},
/**
* Send message to worker and return worker reply to RILContentHelper.
*
* @param msg
* A message object from ppmm.
* @param rilMessageType
* A text string for worker message type.
* @param ipcType [optinal]
* A text string for ipc message type. "msg.name" if omitted.
*
* @TODO: Bug 815526 - deprecate RILContentHelper.
*/
sendWithIPCMessage: function(clientId, msg, rilMessageType, ipcType) {
this.send(clientId, rilMessageType, msg.json.data, (function(reply) {
ipcType = ipcType || msg.name;
msg.target.sendAsyncMessage(ipcType, {
clientId: clientId,
data: reply
});
return false;
}).bind(this));
}
};
function RadioInterface(aClientId, aWorkerMessenger) {
this.clientId = aClientId;
this.workerMessenger = {
send: aWorkerMessenger.send.bind(aWorkerMessenger, aClientId),
// TODO: Bug 815526, deprecate RILContentHelper.
sendWithIPCMessage:
aWorkerMessenger.sendWithIPCMessage.bind(aWorkerMessenger, aClientId),
send: aWorkerMessenger.send.bind(aWorkerMessenger, aClientId)
};
aWorkerMessenger.registerClient(aClientId, this);
@@ -963,11 +715,6 @@ RadioInterface.prototype = {
Services.obs.removeObserver(this, kNetworkConnStateChangedTopic);
},
getIccInfo: function() {
let icc = gIccService.getIccByServiceId(this.clientId);
return icc ? icc.iccInfo : null;
},
isCardPresent: function() {
let icc = gIccService.getIccByServiceId(this.clientId);
let cardState = icc ? icc.cardState : Ci.nsIIcc.CARD_STATE_UNKNOWN;
@@ -975,35 +722,6 @@ RadioInterface.prototype = {
cardState !== Ci.nsIIcc.CARD_STATE_UNKNOWN;
},
/**
* Process a message from the content process.
*
* TODO: Bug 815526, deprecate RILContentHelper
*/
receiveMessage: function(msg) {
switch (msg.name) {
case "RIL:SendStkResponse":
this.workerMessenger.send("sendStkTerminalResponse", msg.json.data);
break;
case "RIL:SendStkMenuSelection":
this.workerMessenger.send("sendStkMenuSelection", msg.json.data);
break;
case "RIL:SendStkTimerExpiration":
this.workerMessenger.send("sendStkTimerExpiration", msg.json.data);
break;
case "RIL:SendStkEventDownload":
this.workerMessenger.send("sendStkEventDownload", msg.json.data);
break;
case "RIL:ReadIccContacts":
this.workerMessenger.sendWithIPCMessage(msg, "readICCContacts");
break;
case "RIL:UpdateIccContact":
this.workerMessenger.sendWithIPCMessage(msg, "updateICCContact");
break;
}
return null;
},
handleUnsolicitedWorkerMessage: function(message) {
switch (message.rilMessageType) {
case "callRing":
@@ -1094,11 +812,11 @@ RadioInterface.prototype = {
this.handleIccMwis(message.mwi);
break;
case "stkcommand":
this.handleStkProactiveCommand(message);
gIccService.notifyStkCommand(this.clientId,
gStkCmdFactory.createCommand(message));
break;
case "stksessionend":
// TODO: Bug 815526, deprecate RILContentHelper.
gMessageManager.sendIccMessage("RIL:StkSessionEnd", this.clientId, null);
gIccService.notifyStkSessionEnd(this.clientId);
break;
case "cdma-info-rec-received":
this.handleCdmaInformationRecords(message.records);
@@ -1287,18 +1005,6 @@ RadioInterface.prototype = {
null, null);
},
handleStkProactiveCommand: function(message) {
if (DEBUG) this.debug("handleStkProactiveCommand " + JSON.stringify(message));
let iccInfo = this.getIccInfo();
if (iccInfo && iccInfo.iccid) {
gIccMessenger
.notifyStkProactiveCommand(iccInfo.iccid,
gStkCmdFactory.createCommand(message));
}
// TODO: Bug 815526, deprecate RILContentHelper.
gMessageManager.sendIccMessage("RIL:StkCommand", this.clientId, message);
},
_convertCbGsmGeographicalScope: function(aGeographicalScope) {
return (aGeographicalScope != null)
? aGeographicalScope
@@ -1454,21 +1160,21 @@ RadioInterface.prototype = {
this._sntp.updateOffset(offset);
break;
case kNetworkConnStateChangedTopic:
let network = subject.QueryInterface(Ci.nsINetworkInterface);
if (network.state != Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED) {
let networkInfo = subject.QueryInterface(Ci.nsINetworkInfo);
if (networkInfo.state != Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED) {
return;
}
// SNTP can only update when we have mobile or Wifi connections.
if (network.type != NETWORK_TYPE_WIFI &&
network.type != NETWORK_TYPE_MOBILE) {
if (networkInfo.type != NETWORK_TYPE_WIFI &&
networkInfo.type != NETWORK_TYPE_MOBILE) {
return;
}
// If the network comes from RIL, make sure the RIL service is matched.
if (subject instanceof Ci.nsIRilNetworkInterface) {
network = subject.QueryInterface(Ci.nsIRilNetworkInterface);
if (network.serviceId != this.clientId) {
if (subject instanceof Ci.nsIRilNetworkInfo) {
networkInfo = subject.QueryInterface(Ci.nsIRilNetworkInfo);
if (networkInfo.serviceId != this.clientId) {
return;
}
}
@@ -1548,8 +1254,9 @@ RadioInterface.prototype = {
// Set the latest cached NITZ time if it's available.
if (this._lastNitzMessage) {
this.setClockByNitz(this._lastNitzMessage);
} else if (gNetworkManager.active && gNetworkManager.active.state ==
Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED) {
} else if (gNetworkManager.activeNetworkInfo &&
gNetworkManager.activeNetworkInfo.state ==
Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED) {
// Set the latest cached SNTP time if it's available.
if (!this._sntp.isExpired()) {
this.setClockBySntp(this._sntp.getOffset());
-1
View File
@@ -35,7 +35,6 @@
#include "nsIObserverService.h"
#include "nsServiceManagerUtils.h"
#include "nsThreadUtils.h"
#include "nsRadioInterfaceLayer.h"
#include "WifiWorker.h"
#include "mozilla/Services.h"
+41 -38
View File
@@ -252,7 +252,7 @@ TetheringService.prototype = {
this.handle(aSubject.key, aSubject.value);
break;
case TOPIC_CONNECTION_STATE_CHANGED:
network = aSubject.QueryInterface(Ci.nsINetworkInterface);
network = aSubject.QueryInterface(Ci.nsINetworkInfo);
debug("Network " + network.type + "/" + network.name +
" changed state to " + network.state);
this.onConnectionChanged(network);
@@ -360,18 +360,18 @@ TetheringService.prototype = {
libcutils.property_get("ro.tethering.dun_required") === "1";
},
getNetworkInterface: function(aType, aServiceId) {
for each (let network in gNetworkManager.networkInterfaces) {
if (network.type == aType) {
getNetworkInfo: function(aType, aServiceId) {
for each (let networkInfo in gNetworkManager.allNetworkInfo) {
if (networkInfo.type == aType) {
try {
if (network instanceof Ci.nsIRilNetworkInterface) {
let rilNetwork = network.QueryInterface(Ci.nsIRilNetworkInterface);
if (networkInfo instanceof Ci.nsIRilNetworkInfo) {
let rilNetwork = networkInfo.QueryInterface(Ci.nsIRilNetworkInfo);
if (rilNetwork.serviceId != aServiceId) {
continue;
}
}
} catch (e) {}
return network;
return networkInfo;
}
}
return null;
@@ -427,7 +427,7 @@ TetheringService.prototype = {
let ril = gRil.getRadioInterface(this._dataDefaultServiceId);
this.dunRetryTimes = 0;
ril.setupDataCallByType(Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_DUN);
ril.setupDataCallByType(Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_DUN);
this.dunConnectTimer.cancel();
this.dunConnectTimer.
initWithCallback(this.onDunConnectTimerTimeout.bind(this),
@@ -452,8 +452,8 @@ TetheringService.prototype = {
_dunActiveUsers: 0,
handleDunConnection: function(aEnable, aCallback) {
debug("handleDunConnection: " + aEnable);
let dun = this.getNetworkInterface(
Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_DUN, this._dataDefaultServiceId);
let dun = this.getNetworkInfo(
Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_DUN, this._dataDefaultServiceId);
if (!aEnable) {
this._dunActiveUsers--;
@@ -467,15 +467,15 @@ TetheringService.prototype = {
this.dunConnectTimer.cancel();
this._pendingTetheringRequests = [];
if (dun && (dun.state == Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED)) {
if (dun && (dun.state == Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED)) {
gRil.getRadioInterface(this._dataDefaultServiceId)
.deactivateDataCallByType(Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_DUN);
.deactivateDataCallByType(Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_DUN);
}
return;
}
this._dunActiveUsers++;
if (!dun || (dun.state != Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED)) {
if (!dun || (dun.state != Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED)) {
debug("DUN data call inactive, setup dun data call!")
this._pendingTetheringRequests.push(aCallback);
this.dunRetryTimes = 0;
@@ -517,23 +517,24 @@ TetheringService.prototype = {
this._usbTetheringAction = TETHERING_STATE_ONGOING;
if (this.tetheringSettings[SETTINGS_DUN_REQUIRED]) {
this.handleDunConnection(true, (aNetwork) => {
if (!aNetwork){
this.handleDunConnection(true, (aNetworkInfo) => {
if (!aNetworkInfo){
this.usbTetheringResultReport(aEnable, "Dun connection failed");
return;
}
this._tetheringInterface[TETHERING_TYPE_USB].externalInterface = aNetwork.name;
this._tetheringInterface[TETHERING_TYPE_USB].externalInterface =
aNetworkInfo.name;
gNetworkService.enableUsbRndis(true, this.enableUsbRndisResult.bind(this));
});
return;
}
if (gNetworkManager.active) {
if (gNetworkManager.activeNetworkInfo) {
this._tetheringInterface[TETHERING_TYPE_USB].externalInterface =
gNetworkManager.active.name;
gNetworkManager.activeNetworkInfo.name;
} else {
let mobile = this.getNetworkInterface(
Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE, this._dataDefaultServiceId);
let mobile = this.getNetworkInfo(
Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE, this._dataDefaultServiceId);
if (mobile && mobile.name) {
this._tetheringInterface[TETHERING_TYPE_USB].externalInterface = mobile.name;
}
@@ -621,10 +622,10 @@ TetheringService.prototype = {
},
// Enable/disable WiFi tethering by sending commands to netd.
setWifiTethering: function(aEnable, aNetwork, aConfig, aCallback) {
setWifiTethering: function(aEnable, aInterfaceName, aConfig, aCallback) {
debug("setWifiTethering: " + aEnable);
if (!aNetwork) {
this.notifyError(true, aCallback, "invalid network information");
if (!aInterfaceName) {
this.notifyError(true, aCallback, "invalid network interface name");
return;
}
@@ -648,22 +649,24 @@ TetheringService.prototype = {
return;
}
this._tetheringInterface[TETHERING_TYPE_WIFI].internalInterface = aNetwork.name;
this._tetheringInterface[TETHERING_TYPE_WIFI].internalInterface =
aInterfaceName;
if (this.tetheringSettings[SETTINGS_DUN_REQUIRED]) {
this.handleDunConnection(true, (aNetwork) => {
if (!aNetwork) {
this.handleDunConnection(true, (aNetworkInfo) => {
if (!aNetworkInfo) {
this.notifyError(true, aCallback, "Dun connection failed");
return;
}
this._tetheringInterface[TETHERING_TYPE_WIFI].externalInterface = aNetwork.name;
this._tetheringInterface[TETHERING_TYPE_WIFI].externalInterface =
aNetworkInfo.name;
this.enableWifiTethering(true, aConfig, aCallback);
});
return;
}
let mobile = this.getNetworkInterface(
Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE, this._dataDefaultServiceId);
let mobile = this.getNetworkInfo(
Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE, this._dataDefaultServiceId);
// Update the real interface name
if (mobile && mobile.name) {
this._tetheringInterface[TETHERING_TYPE_WIFI].externalInterface = mobile.name;
@@ -763,20 +766,20 @@ TetheringService.prototype = {
}
},
onConnectionChanged: function(aNetwork) {
if (aNetwork.state != Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED) {
onConnectionChanged: function(aNetworkInfo) {
if (aNetworkInfo.state != Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED) {
debug("We are only interested in CONNECTED event");
return;
}
if (this.tetheringSettings[SETTINGS_DUN_REQUIRED] &&
aNetwork.type === Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_DUN) {
aNetworkInfo.type === Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_DUN) {
this.dunConnectTimer.cancel();
debug("DUN data call connected, process callbacks.");
while (this._pendingTetheringRequests.length > 0) {
let callback = this._pendingTetheringRequests.shift();
if (typeof callback === 'function') {
callback(aNetwork);
callback(aNetworkInfo);
}
}
return;
@@ -788,15 +791,15 @@ TetheringService.prototype = {
}
if (this.tetheringSettings[SETTINGS_DUN_REQUIRED] &&
aNetwork.type === Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_DUN &&
aNetworkInfo.type === Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_DUN &&
this._tetheringInterface[TETHERING_TYPE_USB].externalInterface ===
aNetwork.name) {
aNetworkInfo.name) {
debug("Dun required and dun interface is the same");
return;
}
if (this._tetheringInterface[TETHERING_TYPE_USB].externalInterface ===
gNetworkManager.active.name) {
gNetworkManager.activeNetworkInfo.name) {
debug("The active interface is the same");
return;
}
@@ -808,12 +811,12 @@ TetheringService.prototype = {
let current = {
internalIfname: this._tetheringInterface[TETHERING_TYPE_USB].internalInterface,
externalIfname: aNetwork.name
externalIfname: aNetworkInfo.name
};
let callback = (() => {
// Update external network interface.
debug("Update upstream interface to " + aNetwork.name);
debug("Update upstream interface to " + aNetworkInfo.name);
gNetworkService.updateUpStream(previous, current,
this.onConnectionChangedReport.bind(this));
});
-2
View File
@@ -97,8 +97,6 @@ if CONFIG['MOZ_B2G_RIL']:
EXTRA_COMPONENTS += [
'DataCallManager.js',
'DataCallManager.manifest',
'RILContentHelper.js', # TODO: Bug 815526, deprecate RILContentHelper.
'RILContentHelper.manifest', # TODO: Bug 815526, deprecate RILContentHelper.
'RILSystemMessengerHelper.js',
'RILSystemMessengerHelper.manifest',
]
@@ -35,6 +35,13 @@ interface nsIRadioInterface : nsISupports
[optional] in nsIRilSendWorkerMessageCallback callback);
};
%{C++
#define NS_RADIOINTERFACELAYER_CID \
{ 0x2d831c8d, 0x6017, 0x435b, \
{ 0xa8, 0x0c, 0xe5, 0xd4, 0x22, 0x81, 0x0c, 0xea } }
#define NS_RADIOINTERFACELAYER_CONTRACTID "@mozilla.org/ril;1"
%}
[scriptable, uuid(78b65e8c-68e7-4510-9a05-65bba12b283e)]
interface nsIRadioInterfaceLayer : nsISupports
{
+4 -4
View File
@@ -7,7 +7,7 @@
interface nsINetworkInterface;
interface nsIWifiTetheringCallback;
[scriptable, uuid(80d65940-bd99-458f-8529-e438c7348087)]
[scriptable, uuid(993b79df-f10e-4697-a5dc-5981cf8ff7e6)]
interface nsITetheringService : nsISupports
{
/**
@@ -16,15 +16,15 @@ interface nsITetheringService : nsISupports
* @param enabled
* Boolean that indicates whether tethering should be enabled (true) or
* disabled (false).
* @param networkInterface
* The Wifi network interface with at least name of network interface.
* @param interfaceName
* The Wifi network interface name for internal interface.
* @param config
* The Wifi Tethering configuration from settings db.
* @param callback
* Callback function used to report status to WifiManager.
*/
void setWifiTethering(in boolean enabled,
in nsINetworkInterface networkInterface,
in DOMString interfaceName,
in jsval config,
in nsIWifiTetheringCallback callback);
};
-16
View File
@@ -1,16 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// These must always match the values given in RadioInterfaceLayer.manifest!
#define NS_RADIOINTERFACELAYER_CID \
{ 0x2d831c8d, 0x6017, 0x435b, \
{ 0xa8, 0x0c, 0xe5, 0xd4, 0x22, 0x81, 0x0c, 0xea } }
#define NS_RILCONTENTHELPER_CID \
{ 0x472816e1, 0x1fd6, 0x4405, \
{ 0x99, 0x6c, 0x80, 0x6f, 0x9e, 0xa6, 0x81, 0x74 } }
#define NS_RADIOINTERFACELAYER_CONTRACTID "@mozilla.org/ril;1"
#define NS_RILCONTENTHELPER_CONTRACTID "@mozilla.org/ril/content-helper;1"
@@ -2,7 +2,6 @@
The test performs the static code analysis check by JSHint.
Target js files:
- RILContentHelper.js TODO: Bug 815526, deprecate RILContentHelper.
- RadioInterfaceLayer.js
- ril_worker.js
- ril_consts.js
@@ -100,7 +99,6 @@ class ResourceUriFileReader:
URI_PREFIX = 'resource://gre/'
URI_PATH = {
'RILContentHelper.js': 'components/RILContentHelper.js', #TODO: Bug 815526, deprecate RILContentHelper.
'RadioInterfaceLayer.js': 'components/RadioInterfaceLayer.js',
'ril_worker.js': 'modules/ril_worker.js',
'ril_consts.js': 'modules/ril_consts.js',
@@ -354,10 +352,6 @@ class TestRILCodeQuality(MarionetteTestCase):
def tearDown(self):
MarionetteTestCase.tearDown(self)
# TODO: Bug 815526, deprecate RILContentHelper.
def test_RILContentHelper(self):
self._check('RILContentHelper.js')
def test_RadioInterfaceLayer(self):
self._check('RadioInterfaceLayer.js')
@@ -8,11 +8,9 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
let RIL = {};
Cu.import("resource://gre/modules/ril_consts.js", RIL);
XPCOMUtils.defineLazyGetter(this, "gStkCmdFactory", function() {
let stk = {};
Cu.import("resource://gre/modules/StkProactiveCmdFactory.jsm", stk);
return stk.StkProactiveCmdFactory;
});
XPCOMUtils.defineLazyServiceGetter(this, "gStkCmdFactory",
"@mozilla.org/icc/stkcmdfactory;1",
"nsIStkCmdFactory");
/**
* Name space for RILSystemMessenger.jsm. Only initialized after first call to
@@ -40,6 +38,10 @@ function newRILSystemMessenger() {
gReceivedMessage = aMessage;
};
rsm.createCommandMessage = (aStkProactiveCmd) => {
return gStkCmdFactory.createCommandMessage(aStkProactiveCmd);
};
return rsm;
}
@@ -541,7 +543,8 @@ add_test(function test_icc_stk_cmd_factory_create_command_error() {
ok(false, "Failed to verify the protection of createCommand()!");
} catch (e) {
equal(e.message, "Unknown Command Type: " + RIL.STK_CMD_MORE_TIME);
ok(e.message.indexOf("Unknown Command Type") !== -1,
"Invalid typeOfCommand!");
}
run_next_test();
@@ -567,7 +570,8 @@ add_test(function test_icc_stk_cmd_factory_create_system_msg_invalid_cmd_type()
ok(false, "Failed to identify invalid typeOfCommand!");
} catch (e) {
equal(e.message, "Unknown Command Type: " + RIL.STK_CMD_MORE_TIME);
ok(e.message.indexOf("Unknown Command Type") !== -1,
"Invalid typeOfCommand!");
}
run_next_test();
+1 -1
View File
@@ -333,7 +333,7 @@ interface MozIcc : EventTarget
*/
[Throws]
DOMRequest updateContact(IccContactType contactType,
any contact,
mozContact contact,
optional DOMString? pin2 = null);
// Integrated Circuit Card Helpers.
+2 -2
View File
@@ -342,12 +342,12 @@ dictionary MozStkLocationInfo
/**
* Mobile Country Code (MCC) of the current serving operator.
*/
unsigned short mcc;
DOMString mcc;
/**
* Mobile Network Code (MNC) of the current serving operator.
*/
unsigned short mnc;
DOMString mnc;
/**
* Mobile Location Area Code (LAC) for the current serving operator.
+17 -4
View File
@@ -30,9 +30,13 @@ this.WifiNetUtil = function(controlMessage) {
var util = {};
util.runDhcp = function (ifname, callback) {
gNetworkService.dhcpRequest(ifname, function(success, dhcpInfo) {
util.runIpConfig(ifname, dhcpInfo, callback);
util.runDhcp = function (ifname, gen, callback) {
util.stopDhcp(ifname, function() {
gNetworkService.dhcpRequest(ifname, function(success, dhcpInfo) {
util.runIpConfig(ifname, dhcpInfo, function(data) {
callback(data, gen);
});
});
});
};
@@ -44,7 +48,16 @@ this.WifiNetUtil = function(controlMessage) {
let dhcpService = DHCP_PROP + "_" + ifname;
let suffix = (ifname.substr(0, 3) === "p2p") ? "p2p" : ifname;
let processName = DHCP + "_" + suffix;
stopProcess(dhcpService, processName, callback);
// The implementation of |dhcp_do_request| would wait until the
// |result_prop_name| (e.g. dhcp.wlan0.result) to be non-null
// or 30 second timeout. So we manually change the result property
// to 'ko' to avoid timeout.
//
// http://androidxref.com/4.4.4_r1/xref/system/core/libnetutils/dhcp_utils.c#234
setProperty('dhcp.' + suffix + '.result', 'ko', function() {
stopProcess(dhcpService, processName, callback);
});
};
util.startDhcpServer = function (config, callback) {
+50 -45
View File
@@ -490,39 +490,44 @@ function P2pStateMachine(aP2pCommand, aNetUtil) {
let _p2pNetworkInterface = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsINetworkInterface]),
state: Ci.nsINetworkInterface.NETWORK_STATE_DISCONNECTED,
type: Ci.nsINetworkInterface.NETWORK_TYPE_WIFI_P2P,
name: P2P_INTERFACE_NAME,
ips: [],
prefixLengths: [],
dnses: [],
gateways: [],
info: {
QueryInterface: XPCOMUtils.generateQI([Ci.nsINetworkInfo]),
state: Ci.nsINetworkInfo.NETWORK_STATE_DISCONNECTED,
type: Ci.nsINetworkInfo.NETWORK_TYPE_WIFI_P2P,
name: P2P_INTERFACE_NAME,
ips: [],
prefixLengths: [],
dnses: [],
gateways: [],
getAddresses: function (ips, prefixLengths) {
ips.value = this.ips.slice();
prefixLengths.value = this.prefixLengths.slice();
return this.ips.length;
},
getGateways: function (count) {
if (count) {
count.value = this.gateways.length;
}
return this.gateways.slice();
},
getDnses: function (count) {
if (count) {
count.value = this.dnses.length;
}
return this.dnses.slice();
}
},
httpProxyHost: null,
httpProxyPort: null,
// help
registered: false,
getAddresses: function (ips, prefixLengths) {
ips.value = this.ips.slice();
prefixLengths.value = this.prefixLengths.slice();
return this.ips.length;
},
getGateways: function (count) {
if (count) {
count.value = this.gateways.length;
}
return this.gateways.slice();
},
getDnses: function (count) {
if (count) {
count.value = this.dnses.length;
}
return this.dnses.slice();
}
registered: false
};
//---------------------------------------------------------
@@ -1419,10 +1424,10 @@ function P2pStateMachine(aP2pCommand, aNetUtil) {
}
// Update p2p network interface.
_p2pNetworkInterface.state = Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED;
_p2pNetworkInterface.ips = [GO_NETWORK_INTERFACE.ip];
_p2pNetworkInterface.prefixLengths = [GO_NETWORK_INTERFACE.maskLength];
_p2pNetworkInterface.gateways = [GO_NETWORK_INTERFACE.ip];
_p2pNetworkInterface.info.state = Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED;
_p2pNetworkInterface.info.ips = [GO_NETWORK_INTERFACE.ip];
_p2pNetworkInterface.info.prefixLengths = [GO_NETWORK_INTERFACE.maskLength];
_p2pNetworkInterface.info.gateways = [GO_NETWORK_INTERFACE.ip];
handleP2pNetworkInterfaceStateChanged();
_groupInfo.networkInterface = _p2pNetworkInterface;
@@ -1454,18 +1459,18 @@ function P2pStateMachine(aP2pCommand, aNetUtil) {
if (!maskLength) {
maskLength = 32; // max prefix for IPv4.
}
_p2pNetworkInterface.state = Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED;
_p2pNetworkInterface.ips = [dhcpData.info.ipaddr_str];
_p2pNetworkInterface.prefixLengths = [maskLength];
_p2pNetworkInterface.info.state = Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED;
_p2pNetworkInterface.info.ips = [dhcpData.info.ipaddr_str];
_p2pNetworkInterface.info.prefixLengths = [maskLength];
if (typeof dhcpData.info.dns1_str == "string" &&
dhcpData.info.dns1_str.length) {
_p2pNetworkInterface.dnses.push(dhcpData.info.dns1_str);
_p2pNetworkInterface.info.dnses.push(dhcpData.info.dns1_str);
}
if (typeof dhcpData.info.dns2_str == "string" &&
dhcpData.info.dns2_str.length) {
_p2pNetworkInterface.dnses.push(dhcpData.info.dns2_str);
_p2pNetworkInterface.info.dnses.push(dhcpData.info.dns2_str);
}
_p2pNetworkInterface.gateways = [dhcpData.info.gateway_str];
_p2pNetworkInterface.info.gateways = [dhcpData.info.gateway_str];
handleP2pNetworkInterfaceStateChanged();
_groupInfo.networkInterface = _p2pNetworkInterface;
@@ -1476,11 +1481,11 @@ function P2pStateMachine(aP2pCommand, aNetUtil) {
}
function resetP2pNetworkInterface() {
_p2pNetworkInterface.state = Ci.nsINetworkInterface.NETWORK_STATE_DISCONNECTED;
_p2pNetworkInterface.ips = [];
_p2pNetworkInterface.prefixLengths = [];
_p2pNetworkInterface.dnses = [];
_p2pNetworkInterface.gateways = [];
_p2pNetworkInterface.info.state = Ci.nsINetworkInfo.NETWORK_STATE_DISCONNECTED;
_p2pNetworkInterface.info.ips = [];
_p2pNetworkInterface.info.prefixLengths = [];
_p2pNetworkInterface.info.dnses = [];
_p2pNetworkInterface.info.gateways = [];
}
function registerP2pNetworkInteface() {
@@ -1523,7 +1528,7 @@ function P2pStateMachine(aP2pCommand, aNetUtil) {
}
// Update p2p network interface.
_p2pNetworkInterface.state = Ci.nsINetworkInterface.NETWORK_STATE_DISCONNECTED;
_p2pNetworkInterface.info.state = Ci.nsINetworkInfo.NETWORK_STATE_DISCONNECTED;
handleP2pNetworkInterfaceStateChanged();
if (P2P_ROLE_GO === aInfo.role) {
+81 -64
View File
@@ -403,8 +403,8 @@ var WifiManager = (function() {
WifiNetworkInterface.httpProxyHost = network.httpProxyHost;
WifiNetworkInterface.httpProxyPort = network.httpProxyPort;
if (WifiNetworkInterface.state ==
Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED) {
if (WifiNetworkInterface.info.state ==
Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED) {
gNetworkManager.updateNetworkInterface(WifiNetworkInterface);
}
}
@@ -633,6 +633,8 @@ var WifiManager = (function() {
wifiCommand.connectToSupplicant(connectCallback);
}
let dhcpRequestGen = 0;
function onconnected() {
// For now we do our own DHCP. In the future, this should be handed
// off to the Network Manager.
@@ -648,9 +650,14 @@ var WifiManager = (function() {
runStaticIp(manager.ifname, key);
return;
}
netUtil.runDhcp(manager.ifname, function(data) {
netUtil.runDhcp(manager.ifname, dhcpRequestGen++, function(data, gen) {
dhcpInfo = data.info;
debug('dhcpRequestGen: ' + dhcpRequestGen + ', gen: ' + gen);
if (!dhcpInfo) {
if (gen + 1 < dhcpRequestGen) {
debug('Do not bother younger DHCP request.');
return;
}
if (++manager.dhcpFailuresCount >= MAX_RETRIES_ON_DHCP_FAILURE) {
manager.dhcpFailuresCount = 0;
notify("disconnected", {connectionInfo: manager.connectionInfo});
@@ -993,16 +1000,17 @@ var WifiManager = (function() {
if (enabled) {
manager.state = "INITIALIZING";
// Register as network interface.
WifiNetworkInterface.name = manager.ifname;
WifiNetworkInterface.info.name = manager.ifname;
if (!WifiNetworkInterface.registered) {
gNetworkManager.registerNetworkInterface(WifiNetworkInterface);
WifiNetworkInterface.registered = true;
}
WifiNetworkInterface.state = Ci.nsINetworkInterface.NETWORK_STATE_DISCONNECTED;
WifiNetworkInterface.ips = [];
WifiNetworkInterface.prefixLengths = [];
WifiNetworkInterface.gateways = [];
WifiNetworkInterface.dnses = [];
WifiNetworkInterface.info.state =
Ci.nsINetworkInfo.NETWORK_STATE_DISCONNECTED;
WifiNetworkInterface.info.ips = [];
WifiNetworkInterface.info.prefixLengths = [];
WifiNetworkInterface.info.gateways = [];
WifiNetworkInterface.info.dnses = [];
gNetworkManager.updateNetworkInterface(WifiNetworkInterface);
prepareForStartup(function() {
@@ -1147,8 +1155,10 @@ var WifiManager = (function() {
function doStartWifiTethering() {
cancelWaitForDriverReadyTimer();
WifiNetworkInterface.name = libcutils.property_get("wifi.tethering.interface", manager.ifname);
gTetheringService.setWifiTethering(enabled, WifiNetworkInterface,
WifiNetworkInterface.info.name =
libcutils.property_get("wifi.tethering.interface", manager.ifname);
gTetheringService.setWifiTethering(enabled,
WifiNetworkInterface.info.name,
configuration, function(result) {
if (result) {
manager.tetheringState = "UNINITIALIZED";
@@ -1762,55 +1772,59 @@ let WifiNetworkInterface = {
// nsINetworkInterface
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,
NETWORK_STATE_UNKNOWN: Ci.nsINetworkInfo.NETWORK_STATE_UNKNOWN,
NETWORK_STATE_CONNECTING: Ci.nsINetworkInfo.CONNECTING,
NETWORK_STATE_CONNECTED: Ci.nsINetworkInfo.CONNECTED,
NETWORK_STATE_DISCONNECTING: Ci.nsINetworkInfo.DISCONNECTING,
NETWORK_STATE_DISCONNECTED: Ci.nsINetworkInfo.DISCONNECTED,
state: Ci.nsINetworkInterface.NETWORK_STATE_UNKNOWN,
NETWORK_TYPE_WIFI: Ci.nsINetworkInfo.NETWORK_TYPE_WIFI,
NETWORK_TYPE_MOBILE: Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE,
NETWORK_TYPE_MOBILE_MMS: Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_MMS,
NETWORK_TYPE_MOBILE_SUPL: Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_SUPL,
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,
info: {
QueryInterface: XPCOMUtils.generateQI([Ci.nsINetworkInfo]),
type: Ci.nsINetworkInterface.NETWORK_TYPE_WIFI,
state: Ci.nsINetworkInfo.NETWORK_STATE_UNKNOWN,
name: null,
type: Ci.nsINetworkInfo.NETWORK_TYPE_WIFI,
ips: [],
name: null,
prefixLengths: [],
ips: [],
dnses: [],
prefixLengths: [],
gateways: [],
dnses: [],
gateways: [],
getAddresses: function (ips, prefixLengths) {
ips.value = this.ips.slice();
prefixLengths.value = this.prefixLengths.slice();
return this.ips.length;
},
getGateways: function (count) {
if (count) {
count.value = this.gateways.length;
}
return this.gateways.slice();
},
getDnses: function (count) {
if (count) {
count.value = this.dnses.length;
}
return this.dnses.slice();
}
},
httpProxyHost: null,
httpProxyPort: null,
getAddresses: function (ips, prefixLengths) {
ips.value = this.ips.slice();
prefixLengths.value = this.prefixLengths.slice();
return this.ips.length;
},
getGateways: function (count) {
if (count) {
count.value = this.gateways.length;
}
return this.gateways.slice();
},
getDnses: function (count) {
if (count) {
count.value = this.dnses.length;
}
return this.dnses.slice();
}
httpProxyPort: null
};
function WifiScanResult() {}
@@ -2228,8 +2242,8 @@ function WifiWorker() {
case "DISCONNECTED":
// wpa_supplicant may give us a "DISCONNECTED" event even if
// we are already in "DISCONNECTED" state.
if ((WifiNetworkInterface.state ===
Ci.nsINetworkInterface.NETWORK_STATE_DISCONNECTED) &&
if ((WifiNetworkInterface.info.state ===
Ci.nsINetworkInfo.NETWORK_STATE_DISCONNECTED) &&
(this.prevState === "INITIALIZING" ||
this.prevState === "DISCONNECTED" ||
this.prevState === "INTERFACE_DISABLED" ||
@@ -2261,13 +2275,16 @@ function WifiWorker() {
}
});
WifiNetworkInterface.state =
Ci.nsINetworkInterface.NETWORK_STATE_DISCONNECTED;
WifiNetworkInterface.ips = [];
WifiNetworkInterface.prefixLengths = [];
WifiNetworkInterface.gateways = [];
WifiNetworkInterface.dnses = [];
WifiNetworkInterface.info.state =
Ci.nsINetworkInfo.NETWORK_STATE_DISCONNECTED;
// Update network infterface first then clear properties.
gNetworkManager.updateNetworkInterface(WifiNetworkInterface);
WifiNetworkInterface.info.ips = [];
WifiNetworkInterface.info.prefixLengths = [];
WifiNetworkInterface.info.gateways = [];
WifiNetworkInterface.info.dnses = [];
break;
case "WPS_TIMEOUT":
@@ -2309,18 +2326,18 @@ function WifiWorker() {
WifiNetworkInterface.httpProxyPort = netConnect.httpProxyPort;
}
WifiNetworkInterface.state =
Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED;
WifiNetworkInterface.ips = [this.info.ipaddr_str];
WifiNetworkInterface.prefixLengths = [maskLength];
WifiNetworkInterface.gateways = [this.info.gateway_str];
WifiNetworkInterface.info.state =
Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED;
WifiNetworkInterface.info.ips = [this.info.ipaddr_str];
WifiNetworkInterface.info.prefixLengths = [maskLength];
WifiNetworkInterface.info.gateways = [this.info.gateway_str];
if (typeof this.info.dns1_str == "string" &&
this.info.dns1_str.length) {
WifiNetworkInterface.dnses.push(this.info.dns1_str);
WifiNetworkInterface.info.dnses.push(this.info.dns1_str);
}
if (typeof this.info.dns2_str == "string" &&
this.info.dns2_str.length) {
WifiNetworkInterface.dnses.push(this.info.dns2_str);
WifiNetworkInterface.info.dnses.push(this.info.dns2_str);
}
gNetworkManager.updateNetworkInterface(WifiNetworkInterface);
+6 -6
View File
@@ -381,16 +381,16 @@ Discovery.prototype = {
if (topic !== "network-active-changed") {
return;
}
let activeNetwork = subject;
if (!activeNetwork) {
log("No active network");
let activeNetworkInfo = subject;
if (!activeNetworkInfo) {
log("No active network info");
return;
}
activeNetwork = activeNetwork.QueryInterface(Ci.nsINetworkInterface);
log("Active network changed to: " + activeNetwork.type);
activeNetworkInfo = activeNetworkInfo.QueryInterface(Ci.nsINetworkInfo);
log("Active network changed to: " + activeNetworkInfo.type);
// UDP sockets go down when the device goes offline, so we'll restart them
// when the active network goes back to WiFi.
if (activeNetwork.type === Ci.nsINetworkInterface.NETWORK_TYPE_WIFI) {
if (activeNetworkInfo.type === Ci.nsINetworkInfo.NETWORK_TYPE_WIFI) {
this._restartListening();
}
},