зеркало из https://github.com/mozilla/gecko-dev.git
481 строка
13 KiB
C++
481 строка
13 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
/* 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 "IccInfo.h"
|
|
#include "mozilla/dom/icc/IccChild.h"
|
|
#include "mozilla/dom/icc/IccIPCUtils.h"
|
|
#include "nsIStkCmdFactory.h"
|
|
#include "nsIStkProactiveCmd.h"
|
|
|
|
using mozilla::dom::IccInfo;
|
|
|
|
namespace mozilla {
|
|
namespace dom {
|
|
namespace icc {
|
|
|
|
/**
|
|
* PIccChild Implementation.
|
|
*/
|
|
|
|
IccChild::IccChild()
|
|
: mCardState(nsIIcc::CARD_STATE_UNKNOWN)
|
|
, mIsAlive(true)
|
|
{
|
|
MOZ_COUNT_CTOR(IccChild);
|
|
}
|
|
|
|
IccChild::~IccChild()
|
|
{
|
|
MOZ_COUNT_DTOR(IccChild);
|
|
}
|
|
|
|
void
|
|
IccChild::Init()
|
|
{
|
|
OptionalIccInfoData infoData;
|
|
|
|
bool rv = SendInit(&infoData, &mCardState);
|
|
NS_ENSURE_TRUE_VOID(rv);
|
|
|
|
UpdateIccInfo(infoData);
|
|
}
|
|
|
|
void
|
|
IccChild::Shutdown(){
|
|
if (mIsAlive) {
|
|
mIsAlive = false;
|
|
Send__delete__(this);
|
|
}
|
|
|
|
mListeners.Clear();
|
|
mIccInfo = nullptr;
|
|
mCardState = nsIIcc::CARD_STATE_UNKNOWN;
|
|
}
|
|
|
|
void
|
|
IccChild::ActorDestroy(ActorDestroyReason why)
|
|
{
|
|
mIsAlive = false;
|
|
}
|
|
|
|
bool
|
|
IccChild::RecvNotifyCardStateChanged(const uint32_t& aCardState)
|
|
{
|
|
mCardState = aCardState;
|
|
|
|
for (int32_t i = 0; i < mListeners.Count(); i++) {
|
|
mListeners[i]->NotifyCardStateChanged();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
IccChild::RecvNotifyIccInfoChanged(const OptionalIccInfoData& aInfoData)
|
|
{
|
|
UpdateIccInfo(aInfoData);
|
|
|
|
for (int32_t i = 0; i < mListeners.Count(); i++) {
|
|
mListeners[i]->NotifyIccInfoChanged();
|
|
}
|
|
|
|
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)
|
|
{
|
|
MOZ_CRASH("Caller is supposed to manually construct a request!");
|
|
}
|
|
|
|
bool
|
|
IccChild::DeallocPIccRequestChild(PIccRequestChild* aActor)
|
|
{
|
|
delete aActor;
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
IccChild::SendRequest(const IccRequest& aRequest, nsIIccCallback* aRequestReply)
|
|
{
|
|
NS_ENSURE_TRUE(mIsAlive, false);
|
|
|
|
// Deallocated in IccChild::DeallocPIccRequestChild().
|
|
IccRequestChild* actor = new IccRequestChild(aRequestReply);
|
|
SendPIccRequestConstructor(actor, aRequest);
|
|
|
|
return true;
|
|
}
|
|
|
|
void
|
|
IccChild::UpdateIccInfo(const OptionalIccInfoData& aInfoData) {
|
|
if (aInfoData.type() == OptionalIccInfoData::Tvoid_t) {
|
|
mIccInfo = nullptr;
|
|
return;
|
|
}
|
|
|
|
NS_ENSURE_TRUE_VOID(aInfoData.type() == OptionalIccInfoData::TIccInfoData);
|
|
|
|
nsRefPtr<IccInfo> iccInfo;
|
|
const IccInfoData& infoData = aInfoData.get_IccInfoData();
|
|
if (infoData.iccType().EqualsLiteral("sim")
|
|
|| infoData.iccType().EqualsLiteral("usim")) {
|
|
iccInfo = new GsmIccInfo(infoData);
|
|
} else if (infoData.iccType().EqualsLiteral("ruim")
|
|
|| infoData.iccType().EqualsLiteral("csim")){
|
|
iccInfo = new CdmaIccInfo(infoData);
|
|
} else {
|
|
iccInfo = new IccInfo(infoData);
|
|
}
|
|
|
|
// We update the orignal one instead of replacing with a new one
|
|
// if the IccType is the same.
|
|
if (mIccInfo) {
|
|
nsAutoString oldIccType;
|
|
nsAutoString newIccType;
|
|
mIccInfo->GetIccType(oldIccType);
|
|
iccInfo->GetIccType(newIccType);
|
|
|
|
if (oldIccType.Equals(newIccType)) {
|
|
mIccInfo->Update(iccInfo);
|
|
return;
|
|
}
|
|
}
|
|
|
|
mIccInfo = iccInfo;
|
|
}
|
|
|
|
/**
|
|
* nsIIcc Implementation.
|
|
*/
|
|
|
|
NS_IMPL_ISUPPORTS(IccChild, nsIIcc)
|
|
|
|
NS_IMETHODIMP
|
|
IccChild::RegisterListener(nsIIccListener *aListener)
|
|
{
|
|
NS_ENSURE_TRUE(!mListeners.Contains(aListener), NS_ERROR_UNEXPECTED);
|
|
|
|
mListeners.AppendObject(aListener);
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
IccChild::UnregisterListener(nsIIccListener *aListener)
|
|
{
|
|
NS_ENSURE_TRUE(mListeners.Contains(aListener), NS_ERROR_UNEXPECTED);
|
|
|
|
mListeners.RemoveObject(aListener);
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
IccChild::GetIccInfo(nsIIccInfo** aIccInfo)
|
|
{
|
|
nsCOMPtr<nsIIccInfo> info(mIccInfo);
|
|
info.forget(aIccInfo);
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
IccChild::GetCardState(uint32_t* aCardState)
|
|
{
|
|
*aCardState = mCardState;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
IccChild::GetImsi(nsAString & aImsi)
|
|
{
|
|
NS_WARNING("IMSI shall not directly be fetched in child process.");
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
IccChild::GetCardLockEnabled(uint32_t aLockType,
|
|
nsIIccCallback* aRequestReply)
|
|
{
|
|
return SendRequest(GetCardLockEnabledRequest(aLockType), aRequestReply)
|
|
? NS_OK : NS_ERROR_FAILURE;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
IccChild::UnlockCardLock(uint32_t aLockType,
|
|
const nsAString& aPassword,
|
|
const nsAString& aNewPin,
|
|
nsIIccCallback* aRequestReply)
|
|
{
|
|
return SendRequest(UnlockCardLockRequest(aLockType,
|
|
nsAutoString(aPassword),
|
|
nsAutoString(aNewPin)),
|
|
aRequestReply)
|
|
? NS_OK : NS_ERROR_FAILURE;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
IccChild::SetCardLockEnabled(uint32_t aLockType,
|
|
const nsAString& aPassword,
|
|
bool aEnabled,
|
|
nsIIccCallback* aRequestReply)
|
|
{
|
|
return SendRequest(SetCardLockEnabledRequest(aLockType,
|
|
nsAutoString(aPassword),
|
|
aEnabled),
|
|
aRequestReply)
|
|
? NS_OK : NS_ERROR_FAILURE;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
IccChild::ChangeCardLockPassword(uint32_t aLockType,
|
|
const nsAString& aPassword,
|
|
const nsAString& aNewPassword,
|
|
nsIIccCallback* aRequestReply)
|
|
{
|
|
return SendRequest(ChangeCardLockPasswordRequest(aLockType,
|
|
nsAutoString(aPassword),
|
|
nsAutoString(aNewPassword)),
|
|
aRequestReply)
|
|
? NS_OK : NS_ERROR_FAILURE;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
IccChild::GetCardLockRetryCount(uint32_t aLockType,
|
|
nsIIccCallback* aRequestReply)
|
|
{
|
|
return SendRequest(GetCardLockRetryCountRequest(aLockType), aRequestReply)
|
|
? NS_OK : NS_ERROR_FAILURE;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
IccChild::MatchMvno(uint32_t aMvnoType,
|
|
const nsAString& aMvnoData,
|
|
nsIIccCallback* aRequestReply)
|
|
{
|
|
return SendRequest(MatchMvnoRequest(aMvnoType, nsAutoString(aMvnoData)),
|
|
aRequestReply)
|
|
? NS_OK : NS_ERROR_FAILURE;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
IccChild::GetServiceStateEnabled(uint32_t aService,
|
|
nsIIccCallback* aRequestReply)
|
|
{
|
|
return SendRequest(GetServiceStateEnabledRequest(aService),
|
|
aRequestReply)
|
|
? NS_OK : NS_ERROR_FAILURE;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
IccChild::IccOpenChannel(const nsAString& aAid, nsIIccChannelCallback* aCallback)
|
|
{
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
IccChild::IccExchangeAPDU(int32_t aChannel, uint8_t aCla, uint8_t aIns, uint8_t aP1,
|
|
uint8_t aP2, int16_t aP3, const nsAString & aData,
|
|
nsIIccChannelCallback* aCallback)
|
|
{
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
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.
|
|
*/
|
|
|
|
IccRequestChild::IccRequestChild(nsIIccCallback* aRequestReply)
|
|
: mRequestReply(aRequestReply)
|
|
{
|
|
MOZ_COUNT_CTOR(IccRequestChild);
|
|
MOZ_ASSERT(aRequestReply);
|
|
}
|
|
|
|
bool
|
|
IccRequestChild::Recv__delete__(const IccReply& aResponse)
|
|
{
|
|
MOZ_ASSERT(mRequestReply);
|
|
|
|
switch(aResponse.type()) {
|
|
case IccReply::TIccReplySuccess:
|
|
return NS_SUCCEEDED(mRequestReply->NotifySuccess());
|
|
case IccReply::TIccReplySuccessWithBoolean: {
|
|
const IccReplySuccessWithBoolean& resultWithBoolean
|
|
= aResponse.get_IccReplySuccessWithBoolean();
|
|
return NS_SUCCEEDED(
|
|
mRequestReply->NotifySuccessWithBoolean(resultWithBoolean.result()));
|
|
}
|
|
case IccReply::TIccReplyCardLockRetryCount: {
|
|
const IccReplyCardLockRetryCount& retryCount
|
|
= aResponse.get_IccReplyCardLockRetryCount();
|
|
return NS_SUCCEEDED(
|
|
mRequestReply->NotifyGetCardLockRetryCount(retryCount.count()));
|
|
}
|
|
case IccReply::TIccReplyError: {
|
|
const IccReplyError& error = aResponse.get_IccReplyError();
|
|
return NS_SUCCEEDED(mRequestReply->NotifyError(error.message()));
|
|
}
|
|
case IccReply::TIccReplyCardLockError: {
|
|
const IccReplyCardLockError& error
|
|
= aResponse.get_IccReplyCardLockError();
|
|
return NS_SUCCEEDED(
|
|
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!");
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
} // namespace icc
|
|
} // namespace dom
|
|
} // namespace mozilla
|