Bug 843452 - Part 3-2: IPDL implementation for MobileConnection. r=smaug

This commit is contained in:
Edgar Chen 2014-07-01 18:28:18 +08:00
Родитель 6feea5c427
Коммит 88d3252f85
12 изменённых файлов: 1891 добавлений и 1 удалений

Просмотреть файл

@ -154,6 +154,11 @@
#include "mozilla/net/NeckoMessageUtils.h"
#include "mozilla/RemoteSpellCheckEngineChild.h"
#ifdef MOZ_B2G_RIL
#include "mozilla/dom/mobileconnection/MobileConnectionChild.h"
using namespace mozilla::dom::mobileconnection;
#endif
using namespace base;
using namespace mozilla;
using namespace mozilla::docshell;
@ -1222,6 +1227,43 @@ ContentChild::DeallocPFileSystemRequestChild(PFileSystemRequestChild* aFileSyste
return true;
}
PMobileConnectionChild*
ContentChild::SendPMobileConnectionConstructor(PMobileConnectionChild* aActor,
const uint32_t& aClientId)
{
#ifdef MOZ_B2G_RIL
// Add an extra ref for IPDL. Will be released in
// ContentChild::DeallocPMobileConnectionChild().
static_cast<MobileConnectionChild*>(aActor)->AddRef();
return PContentChild::SendPMobileConnectionConstructor(aActor, aClientId);
#else
MOZ_CRASH("No support for mobileconnection on this platform!");;
#endif
}
PMobileConnectionChild*
ContentChild::AllocPMobileConnectionChild(const uint32_t& aClientId)
{
#ifdef MOZ_B2G_RIL
NS_NOTREACHED("No one should be allocating PMobileConnectionChild actors");
return nullptr;
#else
MOZ_CRASH("No support for mobileconnection on this platform!");;
#endif
}
bool
ContentChild::DeallocPMobileConnectionChild(PMobileConnectionChild* aActor)
{
#ifdef MOZ_B2G_RIL
// MobileConnectionChild is refcounted, must not be freed manually.
static_cast<MobileConnectionChild*>(aActor)->Release();
return true;
#else
MOZ_CRASH("No support for mobileconnection on this platform!");
#endif
}
PNeckoChild*
ContentChild::AllocPNeckoChild()
{

Просмотреть файл

@ -191,6 +191,14 @@ public:
virtual bool RecvPTestShellConstructor(PTestShellChild*) MOZ_OVERRIDE;
jsipc::JavaScriptChild *GetCPOWManager();
PMobileConnectionChild*
SendPMobileConnectionConstructor(PMobileConnectionChild* aActor,
const uint32_t& aClientId);
virtual PMobileConnectionChild*
AllocPMobileConnectionChild(const uint32_t& aClientId) MOZ_OVERRIDE;
virtual bool
DeallocPMobileConnectionChild(PMobileConnectionChild* aActor) MOZ_OVERRIDE;
virtual PNeckoChild* AllocPNeckoChild() MOZ_OVERRIDE;
virtual bool DeallocPNeckoChild(PNeckoChild*) MOZ_OVERRIDE;

Просмотреть файл

@ -177,6 +177,11 @@ using namespace mozilla::system;
#include "nsIIPCBackgroundChildCreateCallback.h"
#endif
#ifdef MOZ_B2G_RIL
#include "mozilla/dom/mobileconnection/MobileConnectionParent.h"
using namespace mozilla::dom::mobileconnection;
#endif
#if defined(MOZ_CONTENT_SANDBOX) && defined(XP_LINUX)
#include "mozilla/Sandbox.h"
#endif
@ -3094,6 +3099,32 @@ ContentParent::DeallocPTestShellParent(PTestShellParent* shell)
return true;
}
PMobileConnectionParent*
ContentParent::AllocPMobileConnectionParent(const uint32_t& aClientId)
{
#ifdef MOZ_B2G_RIL
nsRefPtr<MobileConnectionParent> parent = new MobileConnectionParent(aClientId);
// We release this ref in DeallocPMobileConnectionParent().
parent->AddRef();
return parent;
#else
MOZ_CRASH("No support for mobileconnection on this platform!");
#endif
}
bool
ContentParent::DeallocPMobileConnectionParent(PMobileConnectionParent* aActor)
{
#ifdef MOZ_B2G_RIL
// MobileConnectionParent is refcounted, must not be freed manually.
static_cast<MobileConnectionParent*>(aActor)->Release();
return true;
#else
MOZ_CRASH("No support for mobileconnection on this platform!");
#endif
}
PNeckoParent*
ContentParent::AllocPNeckoParent()
{

Просмотреть файл

@ -463,6 +463,9 @@ private:
virtual PTestShellParent* AllocPTestShellParent() MOZ_OVERRIDE;
virtual bool DeallocPTestShellParent(PTestShellParent* shell) MOZ_OVERRIDE;
virtual PMobileConnectionParent* AllocPMobileConnectionParent(const uint32_t& aClientId) MOZ_OVERRIDE;
virtual bool DeallocPMobileConnectionParent(PMobileConnectionParent* aActor) MOZ_OVERRIDE;
virtual bool DeallocPNeckoParent(PNeckoParent* necko) MOZ_OVERRIDE;
virtual PExternalHelperAppParent* AllocPExternalHelperAppParent(

Просмотреть файл

@ -22,6 +22,138 @@ MobileConnectionCallback::MobileConnectionCallback(nsPIDOMWindow* aWindow,
{
}
/**
* Notify Success for Send/CancelMmi.
*/
nsresult
MobileConnectionCallback::NotifySendCancelMmiSuccess(const nsAString& aServiceCode,
const nsAString& aStatusMessage)
{
MozMMIResult result;
result.mServiceCode.Assign(aServiceCode);
result.mStatusMessage.Assign(aStatusMessage);
return NotifySendCancelMmiSuccess(result);
}
nsresult
MobileConnectionCallback::NotifySendCancelMmiSuccess(const nsAString& aServiceCode,
const nsAString& aStatusMessage,
JS::Handle<JS::Value> aAdditionalInformation)
{
AutoJSAPI jsapi;
if (!NS_WARN_IF(jsapi.Init(mWindow))) {
return NS_ERROR_FAILURE;
}
JSContext* cx = jsapi.cx();
RootedDictionary<MozMMIResult> result(cx);
result.mServiceCode.Assign(aServiceCode);
result.mStatusMessage.Assign(aStatusMessage);
result.mAdditionalInformation.Construct().SetAsObject() = &aAdditionalInformation.toObject();
return NotifySendCancelMmiSuccess(result);
}
nsresult
MobileConnectionCallback::NotifySendCancelMmiSuccess(const nsAString& aServiceCode,
const nsAString& aStatusMessage,
uint16_t aAdditionalInformation)
{
MozMMIResult result;
result.mServiceCode.Assign(aServiceCode);
result.mStatusMessage.Assign(aStatusMessage);
result.mAdditionalInformation.Construct().SetAsUnsignedShort() = aAdditionalInformation;
return NotifySendCancelMmiSuccess(result);
}
nsresult
MobileConnectionCallback::NotifySendCancelMmiSuccess(const nsAString& aServiceCode,
const nsAString& aStatusMessage,
const nsTArray<nsString>& aAdditionalInformation)
{
AutoJSAPI jsapi;
if (!NS_WARN_IF(jsapi.Init(mWindow))) {
return NS_ERROR_FAILURE;
}
JSContext* cx = jsapi.cx();
JS::Rooted<JS::Value> additionalInformation(cx);
if (!ToJSValue(cx, aAdditionalInformation, &additionalInformation)) {
JS_ClearPendingException(cx);
return NS_ERROR_TYPE_ERR;
}
return NotifySendCancelMmiSuccess(aServiceCode, aStatusMessage,
additionalInformation);
}
nsresult
MobileConnectionCallback::NotifySendCancelMmiSuccess(const nsAString& aServiceCode,
const nsAString& aStatusMessage,
const nsTArray<IPC::MozCallForwardingOptions>& aAdditionalInformation)
{
AutoJSAPI jsapi;
if (!NS_WARN_IF(jsapi.Init(mWindow))) {
return NS_ERROR_FAILURE;
}
JSContext* cx = jsapi.cx();
JS::Rooted<JS::Value> additionalInformation(cx);
if (!ToJSValue(cx, aAdditionalInformation, &additionalInformation)) {
JS_ClearPendingException(cx);
return NS_ERROR_TYPE_ERR;
}
return NotifySendCancelMmiSuccess(aServiceCode, aStatusMessage,
additionalInformation);
}
nsresult
MobileConnectionCallback::NotifySendCancelMmiSuccess(const MozMMIResult& aResult)
{
AutoJSAPI jsapi;
if (!NS_WARN_IF(jsapi.Init(mWindow))) {
return NS_ERROR_FAILURE;
}
JSContext* cx = jsapi.cx();
JS::Rooted<JS::Value> jsResult(cx);
if (!ToJSValue(cx, aResult, &jsResult)) {
JS_ClearPendingException(cx);
return NS_ERROR_TYPE_ERR;
}
return NotifySuccess(jsResult);
}
/**
* Notify Success for GetCallForwarding.
*/
nsresult
MobileConnectionCallback::NotifyGetCallForwardingSuccess(const nsTArray<IPC::MozCallForwardingOptions>& aResults)
{
AutoJSAPI jsapi;
if (!NS_WARN_IF(jsapi.Init(mWindow))) {
return NS_ERROR_FAILURE;
}
JSContext* cx = jsapi.cx();
JS::Rooted<JS::Value> jsResult(cx);
if (!ToJSValue(cx, aResults, &jsResult)) {
JS_ClearPendingException(cx);
return NS_ERROR_TYPE_ERR;
}
return NotifySuccess(jsResult);
}
/**
* Notify Success.
*/

Просмотреть файл

@ -6,6 +6,7 @@
#define mozilla_dom_MobileConnectionCallback_h
#include "mozilla/dom/DOMRequest.h"
#include "mozilla/dom/MobileConnectionIPCSerializer.h"
#include "nsCOMPtr.h"
#include "nsIMobileConnectionService.h"
@ -30,6 +31,37 @@ public:
MobileConnectionCallback(nsPIDOMWindow* aWindow, DOMRequest* aRequest);
/**
* Notify Success for Send/CancelMmi.
*/
nsresult
NotifySendCancelMmiSuccess(const nsAString& aServiceCode,
const nsAString& aStatusMessage);
nsresult
NotifySendCancelMmiSuccess(const nsAString& aServiceCode,
const nsAString& aStatusMessage,
JS::Handle<JS::Value> aAdditionalInformation);
nsresult
NotifySendCancelMmiSuccess(const nsAString& aServiceCode,
const nsAString& aStatusMessage,
uint16_t aAdditionalInformation);
nsresult
NotifySendCancelMmiSuccess(const nsAString& aServiceCode,
const nsAString& aStatusMessage,
const nsTArray<nsString>& aAdditionalInformation);
nsresult
NotifySendCancelMmiSuccess(const nsAString& aServiceCode,
const nsAString& aStatusMessage,
const nsTArray<IPC::MozCallForwardingOptions>& aAdditionalInformation);
nsresult
NotifySendCancelMmiSuccess(const MozMMIResult& aResult);
/**
* Notify Success for GetCallForwarding.
*/
nsresult
NotifyGetCallForwardingSuccess(const nsTArray<IPC::MozCallForwardingOptions>& aResults);
private:
~MobileConnectionCallback() {}

Просмотреть файл

@ -119,7 +119,11 @@ interface nsIMobileConnectionListener : nsISupports
void notifyNetworkSelectionModeChanged();
};
[scriptable, builtinclass, uuid(eea91fcf-6bde-43be-aa01-d6cdfaad26e1)]
%{C++
#define NO_ADDITIONAL_INFORMATION 0
%}
[scriptable, builtinclass, uuid(e9d7c247-34c6-42bf-875b-f99b19db394f)]
interface nsIMobileConnectionCallback : nsISupports
{
/**
@ -152,6 +156,40 @@ interface nsIMobileConnectionCallback : nsISupports
[optional] in DOMString message,
[optional] in DOMString serviceCode,
[optional] in unsigned short additionalInformation);
%{C++
// non-virtual so it won't affect the vtable
inline nsresult NotifyError(const nsAString& aName)
{
return NotifyError(aName, EmptyString(), EmptyString(),
NO_ADDITIONAL_INFORMATION, 0 /* ARGC = 0 */);
}
// non-virtual so it won't affect the vtable
inline nsresult NotifyError(const nsAString& aName,
const nsAString& aMessage)
{
return NotifyError(aName, aMessage, EmptyString(), NO_ADDITIONAL_INFORMATION,
1 /* ARGC = 1 */);
}
// non-virtual so it won't affect the vtable
inline nsresult NotifyError(const nsAString& aName,
const nsAString& aMessage,
const nsAString& aServiceCode)
{
return NotifyError(aName, aMessage, aServiceCode, NO_ADDITIONAL_INFORMATION,
2 /* ARGC = 2 */);
}
// non-virtual so it won't affect the vtable
inline nsresult NotifyError(const nsAString& aName,
const nsAString& aMessage,
const nsAString& aServiceCode,
uint16_t aAdditionInformation)
{
return NotifyError(aName, aMessage, aServiceCode, aAdditionInformation,
3 /* ARGC = 3 */);
}
%}
};
%{C++

Просмотреть файл

@ -0,0 +1,471 @@
/* 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 "MobileConnectionChild.h"
#include "MobileConnectionCallback.h"
#include "mozilla/dom/MozMobileConnectionBinding.h"
#include "nsComponentManagerUtils.h"
using namespace mozilla::dom;
using namespace mozilla::dom::mobileconnection;
void
MobileConnectionChild::Init()
{
nsIMobileConnectionInfo* rawVoice;
nsIMobileConnectionInfo* rawData;
nsTArray<nsString> types;
SendInit(&rawVoice, &rawData, &mLastNetwork, &mLastHomeNetwork, &mIccId,
&mNetworkSelectionMode, &mRadioState, &types);
// Use dont_AddRef here because this instances is already AddRef-ed in
// MobileConnectionIPCSerializer.h
nsCOMPtr<nsIMobileConnectionInfo> voice = dont_AddRef(rawVoice);
mVoice = new MobileConnectionInfo(nullptr);
mVoice->Update(voice);
// Use dont_AddRef here because this instances is already AddRef-ed in
// MobileConnectionIPCSerializer.h
nsCOMPtr<nsIMobileConnectionInfo> data = dont_AddRef(rawData);
mData = new MobileConnectionInfo(nullptr);
mData->Update(data);
// Initial SupportedNetworkTypes
nsresult rv;
mSupportedNetworkTypes = do_CreateInstance(NS_VARIANT_CONTRACTID, &rv);
if (NS_FAILED(rv)) {
return;
}
uint32_t arrayLen = types.Length();
if (arrayLen == 0) {
mSupportedNetworkTypes->SetAsEmptyArray();
} else {
// Note: The resulting nsIVariant dupes both the array and its elements.
const char16_t** array = reinterpret_cast<const char16_t**>
(NS_Alloc(arrayLen * sizeof(const char16_t***)));
if (array) {
for (uint32_t i = 0; i < arrayLen; ++i) {
array[i] = types[i].get();
}
mSupportedNetworkTypes->SetAsArray(nsIDataType::VTYPE_WCHAR_STR,
nullptr,
arrayLen,
reinterpret_cast<void*>(array));
NS_Free(array);
}
}
}
void
MobileConnectionChild::Shutdown()
{
if (mLive) {
mLive = false;
Send__delete__(this);
}
mListeners.Clear();
mVoice = nullptr;
mData = nullptr;
mSupportedNetworkTypes = nullptr;
}
void
MobileConnectionChild::RegisterListener(nsIMobileConnectionListener* aListener)
{
if (!mListeners.Contains(aListener)) {
mListeners.AppendObject(aListener);
}
}
void
MobileConnectionChild::UnregisterListener(nsIMobileConnectionListener* aListener)
{
mListeners.RemoveObject(aListener);
}
MobileConnectionInfo*
MobileConnectionChild::GetVoiceInfo()
{
return mVoice;
}
MobileConnectionInfo*
MobileConnectionChild::GetDataInfo()
{
return mData;
}
void
MobileConnectionChild::GetIccId(nsAString& aIccId)
{
aIccId = mIccId;
}
void
MobileConnectionChild::GetRadioState(nsAString& aRadioState)
{
aRadioState = mRadioState;
}
nsIVariant*
MobileConnectionChild::GetSupportedNetworkTypes()
{
return mSupportedNetworkTypes;
}
void
MobileConnectionChild::GetLastNetwork(nsAString& aNetwork)
{
aNetwork = mLastNetwork;
}
void
MobileConnectionChild::GetLastHomeNetwork(nsAString& aNetwork)
{
aNetwork = mLastHomeNetwork;
}
void
MobileConnectionChild::GetNetworkSelectionMode(nsAString& aMode)
{
aMode = mNetworkSelectionMode;
}
void
MobileConnectionChild::ActorDestroy(ActorDestroyReason why)
{
mLive = false;
}
PMobileConnectionRequestChild*
MobileConnectionChild::AllocPMobileConnectionRequestChild(const MobileConnectionRequest& request)
{
MOZ_CRASH("Caller is supposed to manually construct a request!");
}
bool
MobileConnectionChild::DeallocPMobileConnectionRequestChild(PMobileConnectionRequestChild* aActor)
{
delete aActor;
return true;
}
bool
MobileConnectionChild::RecvNotifyVoiceInfoChanged(nsIMobileConnectionInfo* const& aInfo)
{
// Use dont_AddRef here because this instances is already AddRef-ed in
// MobileConnectionIPCSerializer.h
nsCOMPtr<nsIMobileConnectionInfo> voice = dont_AddRef(aInfo);
mVoice->Update(voice);
for (int32_t i = 0; i < mListeners.Count(); i++) {
mListeners[i]->NotifyVoiceChanged();
}
return true;
}
bool
MobileConnectionChild::RecvNotifyDataInfoChanged(nsIMobileConnectionInfo* const& aInfo)
{
// Use dont_AddRef here because this instances is already AddRef-ed in
// MobileConnectionIPCSerializer.h
nsCOMPtr<nsIMobileConnectionInfo> data = dont_AddRef(aInfo);
mData->Update(data);
for (int32_t i = 0; i < mListeners.Count(); i++) {
mListeners[i]->NotifyDataChanged();
}
return true;
}
bool
MobileConnectionChild::RecvNotifyUssdReceived(const nsString& aMessage,
const bool& aSessionEnd)
{
for (int32_t i = 0; i < mListeners.Count(); i++) {
mListeners[i]->NotifyUssdReceived(aMessage, aSessionEnd);
}
return true;
}
bool
MobileConnectionChild::RecvNotifyDataError(const nsString& aMessage)
{
for (int32_t i = 0; i < mListeners.Count(); i++) {
mListeners[i]->NotifyDataError(aMessage);
}
return true;
}
bool
MobileConnectionChild::RecvNotifyCFStateChanged(const bool& aSuccess,
const uint16_t& aAction,
const uint16_t& aReason,
const nsString& aNumber,
const uint16_t& aTimeSeconds,
const uint16_t& aServiceClass)
{
for (int32_t i = 0; i < mListeners.Count(); i++) {
mListeners[i]->NotifyCFStateChanged(aSuccess, aAction, aReason, aNumber,
aTimeSeconds, aServiceClass);
}
return true;
}
bool
MobileConnectionChild::RecvNotifyEmergencyCbModeChanged(const bool& aActive,
const uint32_t& aTimeoutMs)
{
for (int32_t i = 0; i < mListeners.Count(); i++) {
mListeners[i]->NotifyEmergencyCbModeChanged(aActive, aTimeoutMs);
}
return true;
}
bool
MobileConnectionChild::RecvNotifyOtaStatusChanged(const nsString& aStatus)
{
for (int32_t i = 0; i < mListeners.Count(); i++) {
mListeners[i]->NotifyOtaStatusChanged(aStatus);
}
return true;
}
bool
MobileConnectionChild::RecvNotifyIccChanged(const nsString& aIccId)
{
mIccId.Assign(aIccId);
for (int32_t i = 0; i < mListeners.Count(); i++) {
mListeners[i]->NotifyIccChanged();
}
return true;
}
bool
MobileConnectionChild::RecvNotifyRadioStateChanged(const nsString& aRadioState)
{
mRadioState.Assign(aRadioState);
for (int32_t i = 0; i < mListeners.Count(); i++) {
mListeners[i]->NotifyRadioStateChanged();
}
return true;
}
bool
MobileConnectionChild::RecvNotifyClirModeChanged(const uint32_t& aMode)
{
for (int32_t i = 0; i < mListeners.Count(); i++) {
mListeners[i]->NotifyClirModeChanged(aMode);
}
return true;
}
bool
MobileConnectionChild::RecvNotifyLastNetworkChanged(const nsString& aNetwork)
{
mLastNetwork.Assign(aNetwork);
return true;
}
bool
MobileConnectionChild::RecvNotifyLastHomeNetworkChanged(const nsString& aNetwork)
{
mLastHomeNetwork.Assign(aNetwork);
return true;
}
bool
MobileConnectionChild::RecvNotifyNetworkSelectionModeChanged(const nsString& aMode)
{
mNetworkSelectionMode.Assign(aMode);
return true;
}
/******************************************************************************
* MobileConnectionRequestChild
******************************************************************************/
void
MobileConnectionRequestChild::ActorDestroy(ActorDestroyReason why)
{
mRequestCallback = nullptr;
}
bool
MobileConnectionRequestChild::DoReply(const MobileConnectionReplySuccess& aReply)
{
return NS_SUCCEEDED(mRequestCallback->NotifySuccess());
}
bool
MobileConnectionRequestChild::DoReply(const MobileConnectionReplySuccessString& aReply)
{
return NS_SUCCEEDED(mRequestCallback->NotifySuccessWithString(aReply.result()));
}
bool
MobileConnectionRequestChild::DoReply(const MobileConnectionReplySuccessBoolean& aReply)
{
return NS_SUCCEEDED(mRequestCallback->NotifySuccessWithBoolean(aReply.result()));
}
bool
MobileConnectionRequestChild::DoReply(const MobileConnectionReplySuccessNetworks& aReply)
{
uint32_t count = aReply.results().Length();
nsTArray<nsCOMPtr<nsIMobileNetworkInfo>> results;
for (uint32_t i = 0; i < count; i++) {
// Use dont_AddRef here because these instances are already AddRef-ed in
// MobileConnectionIPCSerializer.h
nsCOMPtr<nsIMobileNetworkInfo> item = dont_AddRef(aReply.results()[i]);
results.AppendElement(item);
}
return NS_SUCCEEDED(mRequestCallback->NotifyGetNetworksSuccess(count,
const_cast<nsIMobileNetworkInfo**>(aReply.results().Elements())));
}
bool
MobileConnectionRequestChild::DoReply(const MobileConnectionReplySuccessMmi& aReply)
{
nsAutoString serviceCode(aReply.serviceCode());
nsAutoString statusMessage(aReply.statusMessage());
AdditionalInformation info(aReply.additionalInformation());
nsRefPtr<MobileConnectionCallback> callback = static_cast<MobileConnectionCallback*>(mRequestCallback.get());
// Handle union types
switch (info.type()) {
case AdditionalInformation::Tvoid_t:
return NS_SUCCEEDED(callback->NotifySendCancelMmiSuccess(serviceCode,
statusMessage));
case AdditionalInformation::Tuint16_t:
return NS_SUCCEEDED(callback->NotifySendCancelMmiSuccess(serviceCode,
statusMessage,
info.get_uint16_t()));
case AdditionalInformation::TArrayOfnsString:
return NS_SUCCEEDED(callback->NotifySendCancelMmiSuccess(serviceCode,
statusMessage,
info.get_ArrayOfnsString()));
case AdditionalInformation::TArrayOfMozCallForwardingOptions:
return NS_SUCCEEDED(callback->NotifySendCancelMmiSuccess(serviceCode,
statusMessage,
info.get_ArrayOfMozCallForwardingOptions()));
default:
MOZ_CRASH("Received invalid type!");
}
return false;
}
bool
MobileConnectionRequestChild::DoReply(const MobileConnectionReplySuccessCallForwarding& aReply)
{
nsRefPtr<MobileConnectionCallback> callback = static_cast<MobileConnectionCallback*>(mRequestCallback.get());
return NS_SUCCEEDED(callback->NotifyGetCallForwardingSuccess(aReply.results()));
}
bool
MobileConnectionRequestChild::DoReply(const MobileConnectionReplySuccessCallBarring& aReply)
{
return NS_SUCCEEDED(mRequestCallback->NotifyGetCallBarringSuccess(aReply.program(),
aReply.enabled(),
aReply.serviceClass()));
}
bool
MobileConnectionRequestChild::DoReply(const MobileConnectionReplySuccessClirStatus& aReply)
{
return NS_SUCCEEDED(mRequestCallback->NotifyGetClirStatusSuccess(aReply.n(),
aReply.m()));
}
bool
MobileConnectionRequestChild::DoReply(const MobileConnectionReplyError& aReply)
{
return NS_SUCCEEDED(mRequestCallback->NotifyError(aReply.message()));
}
bool
MobileConnectionRequestChild::DoReply(const MobileConnectionReplyErrorMmi& aReply)
{
nsAutoString name(aReply.name());
nsAutoString message(aReply.message());
nsAutoString serviceCode(aReply.serviceCode());
AdditionalInformation info(aReply.additionalInformation());
// Handle union types
switch (info.type()) {
case AdditionalInformation::Tuint16_t:
return NS_SUCCEEDED(mRequestCallback->NotifyError(name,
message,
serviceCode,
info.get_uint16_t()));
case AdditionalInformation::Tvoid_t:
default:
// If additionInfomation is not uint16_t, handle it as void_t.
return NS_SUCCEEDED(mRequestCallback->NotifyError(name,
message,
serviceCode));
}
return false;
}
bool
MobileConnectionRequestChild::Recv__delete__(const MobileConnectionReply& aReply)
{
MOZ_ASSERT(mRequestCallback);
switch (aReply.type()) {
case MobileConnectionReply::TMobileConnectionReplySuccess:
return DoReply(aReply.get_MobileConnectionReplySuccess());
case MobileConnectionReply::TMobileConnectionReplySuccessString:
return DoReply(aReply.get_MobileConnectionReplySuccessString());
case MobileConnectionReply::TMobileConnectionReplySuccessBoolean:
return DoReply(aReply.get_MobileConnectionReplySuccessBoolean());
case MobileConnectionReply::TMobileConnectionReplySuccessNetworks:
return DoReply(aReply.get_MobileConnectionReplySuccessNetworks());
case MobileConnectionReply::TMobileConnectionReplySuccessMmi:
return DoReply(aReply.get_MobileConnectionReplySuccessMmi());
case MobileConnectionReply::TMobileConnectionReplySuccessCallForwarding:
return DoReply(aReply.get_MobileConnectionReplySuccessCallForwarding());
case MobileConnectionReply::TMobileConnectionReplySuccessCallBarring:
return DoReply(aReply.get_MobileConnectionReplySuccessCallBarring());
case MobileConnectionReply::TMobileConnectionReplySuccessClirStatus:
return DoReply(aReply.get_MobileConnectionReplySuccessClirStatus());
case MobileConnectionReply::TMobileConnectionReplyError:
return DoReply(aReply.get_MobileConnectionReplyError());
case MobileConnectionReply::TMobileConnectionReplyErrorMmi:
return DoReply(aReply.get_MobileConnectionReplyErrorMmi());
default:
MOZ_CRASH("Received invalid response type!");
}
return false;
}

Просмотреть файл

@ -0,0 +1,217 @@
/* 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_mobileconnection_MobileConnectionChild_h
#define mozilla_dom_mobileconnection_MobileConnectionChild_h
#include "mozilla/dom/MobileConnectionCallback.h"
#include "mozilla/dom/MobileConnectionInfo.h"
#include "mozilla/dom/PMobileConnectionChild.h"
#include "mozilla/dom/PMobileConnectionRequestChild.h"
#include "nsCOMArray.h"
#include "nsCOMPtr.h"
#include "nsIMobileConnectionService.h"
#include "nsIVariant.h"
namespace mozilla {
namespace dom {
namespace mobileconnection {
/**
* Child actor of PMobileConnection. The object is created by
* MobileConnectionIPCService and destroyed after MobileConnectionIPCService is
* shutdown. For multi-sim device, more than one instance will
* be created and each instance represents a sim slot.
*/
class MobileConnectionChild : public PMobileConnectionChild
{
NS_INLINE_DECL_REFCOUNTING(MobileConnectionChild)
public:
MobileConnectionChild()
: mLive(true)
{
MOZ_COUNT_CTOR(MobileConnectionChild);
}
void
Init();
void
Shutdown();
void
RegisterListener(nsIMobileConnectionListener* aListener);
void
UnregisterListener(nsIMobileConnectionListener* aListener);
MobileConnectionInfo*
GetVoiceInfo();
MobileConnectionInfo*
GetDataInfo();
void
GetIccId(nsAString& aIccId);
void
GetRadioState(nsAString& aRadioState);
nsIVariant*
GetSupportedNetworkTypes();
void
GetLastNetwork(nsAString& aNetwork);
void
GetLastHomeNetwork(nsAString& aNetwork);
void
GetNetworkSelectionMode(nsAString& aMode);
protected:
virtual
~MobileConnectionChild()
{
MOZ_COUNT_DTOR(MobileConnectionChild);
Shutdown();
}
virtual void
ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;
virtual PMobileConnectionRequestChild*
AllocPMobileConnectionRequestChild(const MobileConnectionRequest& request) MOZ_OVERRIDE;
virtual bool
DeallocPMobileConnectionRequestChild(PMobileConnectionRequestChild* aActor) MOZ_OVERRIDE;
virtual bool
RecvNotifyVoiceInfoChanged(nsIMobileConnectionInfo* const& aInfo) MOZ_OVERRIDE;
virtual bool
RecvNotifyDataInfoChanged(nsIMobileConnectionInfo* const& aInfo) MOZ_OVERRIDE;
virtual bool
RecvNotifyUssdReceived(const nsString& aMessage,
const bool& aSessionEnd) MOZ_OVERRIDE;
virtual bool
RecvNotifyDataError(const nsString& aMessage) MOZ_OVERRIDE;
virtual bool
RecvNotifyCFStateChanged(const bool& aSuccess, const uint16_t& aAction,
const uint16_t& aReason, const nsString& aNumber,
const uint16_t& aTimeSeconds, const uint16_t& aServiceClass) MOZ_OVERRIDE;
virtual bool
RecvNotifyEmergencyCbModeChanged(const bool& aActive,
const uint32_t& aTimeoutMs) MOZ_OVERRIDE;
virtual bool
RecvNotifyOtaStatusChanged(const nsString& aStatus) MOZ_OVERRIDE;
virtual bool
RecvNotifyIccChanged(const nsString& aIccId) MOZ_OVERRIDE;
virtual bool
RecvNotifyRadioStateChanged(const nsString& aRadioState) MOZ_OVERRIDE;
virtual bool
RecvNotifyClirModeChanged(const uint32_t& aMode) MOZ_OVERRIDE;
virtual bool
RecvNotifyLastNetworkChanged(const nsString& aNetwork) MOZ_OVERRIDE;
virtual bool
RecvNotifyLastHomeNetworkChanged(const nsString& aNetwork) MOZ_OVERRIDE;
virtual bool
RecvNotifyNetworkSelectionModeChanged(const nsString& aMode) MOZ_OVERRIDE;
private:
bool mLive;
nsCOMArray<nsIMobileConnectionListener> mListeners;
nsCOMPtr<nsIWritableVariant> mSupportedNetworkTypes;
nsRefPtr<MobileConnectionInfo> mVoice;
nsRefPtr<MobileConnectionInfo> mData;
nsString mIccId;
nsString mRadioState;
nsString mLastNetwork;
nsString mLastHomeNetwork;
nsString mNetworkSelectionMode;
};
/******************************************************************************
* PMobileConnectionRequestChild
******************************************************************************/
/**
* Child actor of PMobileConnectionRequest. The object is created when an
* asynchronous request is made and destroyed after receiving the response sent
* by parent actor.
*/
class MobileConnectionRequestChild : public PMobileConnectionRequestChild
{
public:
MobileConnectionRequestChild(nsIMobileConnectionCallback* aRequestCallback)
: mRequestCallback(aRequestCallback)
{
MOZ_COUNT_CTOR(MobileConnectionRequestChild);
MOZ_ASSERT(mRequestCallback);
}
bool
DoReply(const MobileConnectionReplySuccess& aReply);
bool
DoReply(const MobileConnectionReplySuccessString& aReply);
bool
DoReply(const MobileConnectionReplySuccessBoolean& aReply);
bool
DoReply(const MobileConnectionReplySuccessNetworks& aReply);
bool
DoReply(const MobileConnectionReplySuccessMmi& aReply);
bool
DoReply(const MobileConnectionReplySuccessCallForwarding& aReply);
bool
DoReply(const MobileConnectionReplySuccessCallBarring& aReply);
bool
DoReply(const MobileConnectionReplySuccessClirStatus& aReply);
bool
DoReply(const MobileConnectionReplyError& aReply);
bool
DoReply(const MobileConnectionReplyErrorMmi& aReply);
protected:
virtual
~MobileConnectionRequestChild()
{
MOZ_COUNT_DTOR(MobileConnectionRequestChild);
}
virtual void
ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;
virtual bool
Recv__delete__(const MobileConnectionReply& aReply) MOZ_OVERRIDE;
private:
nsCOMPtr<nsIMobileConnectionCallback> mRequestCallback;
};
} // namespace mobileconnection
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_mobileconnection_MobileConnectionChild_h

Просмотреть файл

@ -0,0 +1,729 @@
/* 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 "MobileConnectionParent.h"
#include "mozilla/AppProcessChecker.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/MobileConnectionIPCSerializer.h"
#include "mozilla/dom/MozMobileConnectionBinding.h"
#include "mozilla/dom/ToJSValue.h"
#include "nsIVariant.h"
#include "nsJSUtils.h"
using namespace mozilla;
using namespace mozilla::dom;
using namespace mozilla::dom::mobileconnection;
MobileConnectionParent::MobileConnectionParent(uint32_t aClientId)
: mClientId(aClientId)
, mLive(true)
{
MOZ_COUNT_CTOR(MobileConnectionParent);
mService = do_GetService(NS_MOBILE_CONNECTION_SERVICE_CONTRACTID);
NS_ASSERTION(mService, "This shouldn't fail!");
if (mService) {
mService->RegisterListener(mClientId, this);
}
}
void
MobileConnectionParent::ActorDestroy(ActorDestroyReason why)
{
mLive = false;
if (mService) {
mService->UnregisterListener(mClientId, this);
mService = nullptr;
}
}
bool
MobileConnectionParent::RecvPMobileConnectionRequestConstructor(PMobileConnectionRequestParent* aActor,
const MobileConnectionRequest& aRequest)
{
MobileConnectionRequestParent* actor = static_cast<MobileConnectionRequestParent*>(aActor);
switch (aRequest.type()) {
case MobileConnectionRequest::TGetNetworksRequest:
return actor->DoRequest(aRequest.get_GetNetworksRequest());
case MobileConnectionRequest::TSelectNetworkRequest:
return actor->DoRequest(aRequest.get_SelectNetworkRequest());
case MobileConnectionRequest::TSelectNetworkAutoRequest:
return actor->DoRequest(aRequest.get_SelectNetworkAutoRequest());
case MobileConnectionRequest::TSetPreferredNetworkTypeRequest:
return actor->DoRequest(aRequest.get_SetPreferredNetworkTypeRequest());
case MobileConnectionRequest::TGetPreferredNetworkTypeRequest:
return actor->DoRequest(aRequest.get_GetPreferredNetworkTypeRequest());
case MobileConnectionRequest::TSetRoamingPreferenceRequest:
return actor->DoRequest(aRequest.get_SetRoamingPreferenceRequest());
case MobileConnectionRequest::TGetRoamingPreferenceRequest:
return actor->DoRequest(aRequest.get_GetRoamingPreferenceRequest());
case MobileConnectionRequest::TSetVoicePrivacyModeRequest:
return actor->DoRequest(aRequest.get_SetVoicePrivacyModeRequest());
case MobileConnectionRequest::TGetVoicePrivacyModeRequest:
return actor->DoRequest(aRequest.get_GetVoicePrivacyModeRequest());
case MobileConnectionRequest::TSendMmiRequest:
return actor->DoRequest(aRequest.get_SendMmiRequest());
case MobileConnectionRequest::TCancelMmiRequest:
return actor->DoRequest(aRequest.get_CancelMmiRequest());
case MobileConnectionRequest::TSetCallForwardingRequest:
return actor->DoRequest(aRequest.get_SetCallForwardingRequest());
case MobileConnectionRequest::TGetCallForwardingRequest:
return actor->DoRequest(aRequest.get_GetCallForwardingRequest());
case MobileConnectionRequest::TSetCallBarringRequest:
return actor->DoRequest(aRequest.get_SetCallBarringRequest());
case MobileConnectionRequest::TGetCallBarringRequest:
return actor->DoRequest(aRequest.get_GetCallBarringRequest());
case MobileConnectionRequest::TChangeCallBarringPasswordRequest:
return actor->DoRequest(aRequest.get_ChangeCallBarringPasswordRequest());
case MobileConnectionRequest::TSetCallWaitingRequest:
return actor->DoRequest(aRequest.get_SetCallWaitingRequest());
case MobileConnectionRequest::TGetCallWaitingRequest:
return actor->DoRequest(aRequest.get_GetCallWaitingRequest());
case MobileConnectionRequest::TSetCallingLineIdRestrictionRequest:
return actor->DoRequest(aRequest.get_SetCallingLineIdRestrictionRequest());
case MobileConnectionRequest::TGetCallingLineIdRestrictionRequest:
return actor->DoRequest(aRequest.get_GetCallingLineIdRestrictionRequest());
case MobileConnectionRequest::TExitEmergencyCbModeRequest:
return actor->DoRequest(aRequest.get_ExitEmergencyCbModeRequest());
case MobileConnectionRequest::TSetRadioEnabledRequest:
return actor->DoRequest(aRequest.get_SetRadioEnabledRequest());
default:
MOZ_CRASH("Received invalid request type!");
}
return false;
}
PMobileConnectionRequestParent*
MobileConnectionParent::AllocPMobileConnectionRequestParent(const MobileConnectionRequest& request)
{
if (!AssertAppProcessPermission(Manager(), "mobileconnection")) {
return nullptr;
}
MobileConnectionRequestParent* actor = new MobileConnectionRequestParent(mClientId);
// Add an extra ref for IPDL. Will be released in
// MobileConnectionParent::DeallocPMobileConnectionRequestParent().
actor->AddRef();
return actor;
}
bool
MobileConnectionParent::DeallocPMobileConnectionRequestParent(PMobileConnectionRequestParent* aActor)
{
// MobileConnectionRequestParent is refcounted, must not be freed manually.
static_cast<MobileConnectionRequestParent*>(aActor)->Release();
return true;
}
bool
MobileConnectionParent::RecvInit(nsMobileConnectionInfo* aVoice,
nsMobileConnectionInfo* aData,
nsString* aLastKnownNetwork,
nsString* aLastKnownHomeNetwork,
nsString* aIccId,
nsString* aNetworkSelectionMode,
nsString* aRadioState,
nsTArray<nsString>* aSupportedNetworkTypes)
{
NS_ENSURE_TRUE(mService, false);
NS_ENSURE_SUCCESS(mService->GetVoiceConnectionInfo(mClientId, aVoice), false);
NS_ENSURE_SUCCESS(mService->GetDataConnectionInfo(mClientId, aData), false);
NS_ENSURE_SUCCESS(mService->GetLastKnownNetwork(mClientId, *aLastKnownNetwork), false);
NS_ENSURE_SUCCESS(mService->GetLastKnownHomeNetwork(mClientId, *aLastKnownHomeNetwork), false);
NS_ENSURE_SUCCESS(mService->GetIccId(mClientId, *aIccId), false);
NS_ENSURE_SUCCESS(mService->GetNetworkSelectionMode(mClientId, *aNetworkSelectionMode), false);
NS_ENSURE_SUCCESS(mService->GetRadioState(mClientId, *aRadioState), false);
nsCOMPtr<nsIVariant> variant;
mService->GetSupportedNetworkTypes(mClientId, getter_AddRefs(variant));
uint16_t type;
nsIID iid;
uint32_t count;
void* data;
if (NS_FAILED(variant->GetAsArray(&type, &iid, &count, &data))) {
return false;
}
// We expect the element type is wstring.
if (type == nsIDataType::VTYPE_WCHAR_STR) {
char16_t** rawArray = reinterpret_cast<char16_t**>(data);
for (uint32_t i = 0; i < count; ++i) {
nsDependentString networkType(rawArray[i]);
aSupportedNetworkTypes->AppendElement(networkType);
}
}
NS_Free(data);
return true;
}
// nsIMobileConnectionListener
NS_IMPL_ISUPPORTS(MobileConnectionParent, nsIMobileConnectionListener)
NS_IMETHODIMP
MobileConnectionParent::NotifyVoiceChanged()
{
NS_ENSURE_TRUE(mLive, NS_ERROR_FAILURE);
nsresult rv;
nsCOMPtr<nsIMobileConnectionInfo> info;
rv = mService->GetVoiceConnectionInfo(mClientId, getter_AddRefs(info));
NS_ENSURE_SUCCESS(rv, rv);
// We release the ref after serializing process is finished in
// MobileConnectionIPCSerializer.
return SendNotifyVoiceInfoChanged(info.forget().take()) ? NS_OK : NS_ERROR_FAILURE;
}
NS_IMETHODIMP
MobileConnectionParent::NotifyDataChanged()
{
NS_ENSURE_TRUE(mLive, NS_ERROR_FAILURE);
nsresult rv;
nsCOMPtr<nsIMobileConnectionInfo> info;
rv = mService->GetDataConnectionInfo(mClientId, getter_AddRefs(info));
NS_ENSURE_SUCCESS(rv, rv);
// We release the ref after serializing process is finished in
// MobileConnectionIPCSerializer.
return SendNotifyDataInfoChanged(info.forget().take()) ? NS_OK : NS_ERROR_FAILURE;
}
NS_IMETHODIMP
MobileConnectionParent::NotifyUssdReceived(const nsAString& aMessage,
bool aSessionEnded)
{
NS_ENSURE_TRUE(mLive, NS_ERROR_FAILURE);
return SendNotifyUssdReceived(nsAutoString(aMessage), aSessionEnded)
? NS_OK : NS_ERROR_FAILURE;
}
NS_IMETHODIMP
MobileConnectionParent::NotifyDataError(const nsAString& aMessage)
{
NS_ENSURE_TRUE(mLive, NS_ERROR_FAILURE);
return SendNotifyDataError(nsAutoString(aMessage)) ? NS_OK : NS_ERROR_FAILURE;
}
NS_IMETHODIMP
MobileConnectionParent::NotifyCFStateChanged(bool aSuccess,
uint16_t aAction,
uint16_t aReason,
const nsAString &aNumber,
uint16_t aTimeSeconds,
uint16_t aServiceClass)
{
NS_ENSURE_TRUE(mLive, NS_ERROR_FAILURE);
return SendNotifyCFStateChanged(aSuccess, aAction, aReason,
nsAutoString(aNumber), aTimeSeconds,
aServiceClass) ? NS_OK : NS_ERROR_FAILURE;
}
NS_IMETHODIMP
MobileConnectionParent::NotifyEmergencyCbModeChanged(bool aActive,
uint32_t aTimeoutMs)
{
NS_ENSURE_TRUE(mLive, NS_ERROR_FAILURE);
return SendNotifyEmergencyCbModeChanged(aActive, aTimeoutMs)
? NS_OK : NS_ERROR_FAILURE;
}
NS_IMETHODIMP
MobileConnectionParent::NotifyOtaStatusChanged(const nsAString& aStatus)
{
NS_ENSURE_TRUE(mLive, NS_ERROR_FAILURE);
return SendNotifyOtaStatusChanged(nsAutoString(aStatus))
? NS_OK : NS_ERROR_FAILURE;
}
NS_IMETHODIMP
MobileConnectionParent::NotifyIccChanged()
{
NS_ENSURE_TRUE(mLive, NS_ERROR_FAILURE);
nsAutoString iccId;
mService->GetIccId(mClientId, iccId);
return SendNotifyIccChanged(iccId) ? NS_OK : NS_ERROR_FAILURE;
}
NS_IMETHODIMP
MobileConnectionParent::NotifyRadioStateChanged()
{
NS_ENSURE_TRUE(mLive, NS_ERROR_FAILURE);
nsresult rv;
nsAutoString radioState;
rv = mService->GetRadioState(mClientId, radioState);
NS_ENSURE_SUCCESS(rv, rv);
return SendNotifyRadioStateChanged(radioState) ? NS_OK : NS_ERROR_FAILURE;
}
NS_IMETHODIMP
MobileConnectionParent::NotifyClirModeChanged(uint32_t aMode)
{
NS_ENSURE_TRUE(mLive, NS_ERROR_FAILURE);
return SendNotifyClirModeChanged(aMode) ? NS_OK : NS_ERROR_FAILURE;
}
NS_IMETHODIMP
MobileConnectionParent::NotifyLastKnownNetworkChanged()
{
NS_ENSURE_TRUE(mLive, NS_ERROR_FAILURE);
nsresult rv;
nsAutoString network;
rv = mService->GetLastKnownNetwork(mClientId, network);
NS_ENSURE_SUCCESS(rv, rv);
return SendNotifyLastNetworkChanged(network) ? NS_OK : NS_ERROR_FAILURE;
}
NS_IMETHODIMP
MobileConnectionParent::NotifyLastKnownHomeNetworkChanged()
{
NS_ENSURE_TRUE(mLive, NS_ERROR_FAILURE);
nsresult rv;
nsAutoString network;
rv = mService->GetLastKnownHomeNetwork(mClientId, network);
NS_ENSURE_SUCCESS(rv, rv);
return SendNotifyLastHomeNetworkChanged(network) ? NS_OK : NS_ERROR_FAILURE;
}
NS_IMETHODIMP
MobileConnectionParent::NotifyNetworkSelectionModeChanged()
{
NS_ENSURE_TRUE(mLive, NS_ERROR_FAILURE);
nsresult rv;
nsAutoString mode;
rv = mService->GetNetworkSelectionMode(mClientId, mode);
NS_ENSURE_SUCCESS(rv, rv);
return SendNotifyNetworkSelectionModeChanged(mode) ? NS_OK : NS_ERROR_FAILURE;
}
/******************************************************************************
* PMobileConnectionRequestParent
******************************************************************************/
void
MobileConnectionRequestParent::ActorDestroy(ActorDestroyReason why)
{
mLive = false;
mService = nullptr;
}
bool
MobileConnectionRequestParent::DoRequest(const GetNetworksRequest& aRequest)
{
NS_ENSURE_TRUE(mService, false);
return NS_SUCCEEDED(mService->GetNetworks(mClientId, this));
}
bool
MobileConnectionRequestParent::DoRequest(const SelectNetworkRequest& aRequest)
{
NS_ENSURE_TRUE(mService, false);
// Use dont_AddRef here because this instances is already AddRef-ed in
// MobileConnectionIPCSerializer.h
nsCOMPtr<nsIMobileNetworkInfo> network = dont_AddRef(aRequest.network());
return NS_SUCCEEDED(mService->SelectNetwork(mClientId, network, this));
}
bool
MobileConnectionRequestParent::DoRequest(const SelectNetworkAutoRequest& aRequest)
{
NS_ENSURE_TRUE(mService, false);
return NS_SUCCEEDED(mService->SelectNetworkAutomatically(mClientId, this));
}
bool
MobileConnectionRequestParent::DoRequest(const SetPreferredNetworkTypeRequest& aRequest)
{
NS_ENSURE_TRUE(mService, false);
return NS_SUCCEEDED(mService->SetPreferredNetworkType(mClientId, aRequest.type(), this));
}
bool
MobileConnectionRequestParent::DoRequest(const GetPreferredNetworkTypeRequest& aRequest)
{
NS_ENSURE_TRUE(mService, false);
return NS_SUCCEEDED(mService->GetPreferredNetworkType(mClientId, this));
}
bool
MobileConnectionRequestParent::DoRequest(const SetRoamingPreferenceRequest& aRequest)
{
NS_ENSURE_TRUE(mService, false);
return NS_SUCCEEDED(mService->SetRoamingPreference(mClientId, aRequest.mode(), this));
}
bool
MobileConnectionRequestParent::DoRequest(const GetRoamingPreferenceRequest& aRequest)
{
NS_ENSURE_TRUE(mService, false);
return NS_SUCCEEDED(mService->GetRoamingPreference(mClientId, this));
}
bool
MobileConnectionRequestParent::DoRequest(const SetVoicePrivacyModeRequest& aRequest)
{
NS_ENSURE_TRUE(mService, false);
return NS_SUCCEEDED(mService->SetVoicePrivacyMode(mClientId, aRequest.enabled(), this));
}
bool
MobileConnectionRequestParent::DoRequest(const GetVoicePrivacyModeRequest& aRequest)
{
NS_ENSURE_TRUE(mService, false);
return NS_SUCCEEDED(mService->GetVoicePrivacyMode(mClientId, this));
}
bool
MobileConnectionRequestParent::DoRequest(const SendMmiRequest& aRequest)
{
NS_ENSURE_TRUE(mService, false);
return NS_SUCCEEDED(mService->SendMMI(mClientId, aRequest.mmi(), this));
}
bool
MobileConnectionRequestParent::DoRequest(const CancelMmiRequest& aRequest)
{
NS_ENSURE_TRUE(mService, false);
return NS_SUCCEEDED(mService->CancelMMI(mClientId, this));
}
bool
MobileConnectionRequestParent::DoRequest(const SetCallForwardingRequest& aRequest)
{
NS_ENSURE_TRUE(mService, false);
AutoSafeJSContext cx;
JS::Rooted<JS::Value> options(cx);
if (!ToJSValue(cx, aRequest.options(), &options)) {
JS_ClearPendingException(cx);
return false;
}
return NS_SUCCEEDED(mService->SetCallForwarding(mClientId, options, this));
}
bool
MobileConnectionRequestParent::DoRequest(const GetCallForwardingRequest& aRequest)
{
NS_ENSURE_TRUE(mService, false);
return NS_SUCCEEDED(mService->GetCallForwarding(mClientId, aRequest.reason(), this));
}
bool
MobileConnectionRequestParent::DoRequest(const SetCallBarringRequest& aRequest)
{
NS_ENSURE_TRUE(mService, false);
AutoSafeJSContext cx;
JS::Rooted<JS::Value> options(cx);
if (!ToJSValue(cx, aRequest.options(), &options)) {
JS_ClearPendingException(cx);
return false;
}
return NS_SUCCEEDED(mService->SetCallBarring(mClientId, options, this));
}
bool
MobileConnectionRequestParent::DoRequest(const GetCallBarringRequest& aRequest)
{
NS_ENSURE_TRUE(mService, false);
AutoSafeJSContext cx;
JS::Rooted<JS::Value> options(cx);
if (!ToJSValue(cx, aRequest.options(), &options)) {
JS_ClearPendingException(cx);
return false;
}
return NS_SUCCEEDED(mService->GetCallBarring(mClientId, options, this));
}
bool
MobileConnectionRequestParent::DoRequest(const ChangeCallBarringPasswordRequest& aRequest)
{
NS_ENSURE_TRUE(mService, false);
AutoSafeJSContext cx;
JS::Rooted<JS::Value> options(cx);
if (!ToJSValue(cx, aRequest.options(), &options)) {
JS_ClearPendingException(cx);
return false;
}
return NS_SUCCEEDED(mService->ChangeCallBarringPassword(mClientId, options, this));
}
bool
MobileConnectionRequestParent::DoRequest(const SetCallWaitingRequest& aRequest)
{
NS_ENSURE_TRUE(mService, false);
return NS_SUCCEEDED(mService->SetCallWaiting(mClientId, aRequest.enabled(), this));
}
bool
MobileConnectionRequestParent::DoRequest(const GetCallWaitingRequest& aRequest)
{
NS_ENSURE_TRUE(mService, false);
return NS_SUCCEEDED(mService->GetCallWaiting(mClientId, this));
}
bool
MobileConnectionRequestParent::DoRequest(const SetCallingLineIdRestrictionRequest& aRequest)
{
NS_ENSURE_TRUE(mService, false);
return NS_SUCCEEDED(mService->SetCallingLineIdRestriction(mClientId, aRequest.mode(), this));
}
bool
MobileConnectionRequestParent::DoRequest(const GetCallingLineIdRestrictionRequest& aRequest)
{
NS_ENSURE_TRUE(mService, false);
return NS_SUCCEEDED(mService->GetCallingLineIdRestriction(mClientId, this));
}
bool
MobileConnectionRequestParent::DoRequest(const ExitEmergencyCbModeRequest& aRequest)
{
NS_ENSURE_TRUE(mService, false);
return NS_SUCCEEDED(mService->ExitEmergencyCbMode(mClientId, this));
}
bool
MobileConnectionRequestParent::DoRequest(const SetRadioEnabledRequest& aRequest)
{
NS_ENSURE_TRUE(mService, false);
return NS_SUCCEEDED(mService->SetRadioEnabled(mClientId, aRequest.enabled(), this));
}
nsresult
MobileConnectionRequestParent::SendReply(const MobileConnectionReply& aReply)
{
NS_ENSURE_TRUE(mLive, NS_ERROR_FAILURE);
return Send__delete__(this, aReply) ? NS_OK : NS_ERROR_FAILURE;
}
// nsIMobileConnectionListener
NS_IMPL_ISUPPORTS(MobileConnectionRequestParent, nsIMobileConnectionCallback);
NS_IMETHODIMP
MobileConnectionRequestParent::NotifySuccess()
{
return SendReply(MobileConnectionReplySuccess());
}
NS_IMETHODIMP
MobileConnectionRequestParent::NotifySuccessWithString(const nsAString& aResult)
{
return SendReply(MobileConnectionReplySuccessString(nsAutoString(aResult)));
}
NS_IMETHODIMP
MobileConnectionRequestParent::NotifySuccessWithBoolean(bool aResult)
{
return SendReply(MobileConnectionReplySuccessBoolean(aResult));
}
NS_IMETHODIMP
MobileConnectionRequestParent::NotifyGetNetworksSuccess(uint32_t aCount,
nsIMobileNetworkInfo** aNetworks)
{
nsTArray<nsIMobileNetworkInfo*> networks;
for (uint32_t i = 0; i < aCount; i++) {
nsCOMPtr<nsIMobileNetworkInfo> network = aNetworks[i];
// We release the ref after serializing process is finished in
// MobileConnectionIPCSerializer.
networks.AppendElement(network.forget().take());
}
return SendReply(MobileConnectionReplySuccessNetworks(networks));
}
NS_IMETHODIMP
MobileConnectionRequestParent::NotifySendCancelMmiSuccess(JS::Handle<JS::Value> aResult)
{
AutoSafeJSContext cx;
RootedDictionary<MozMMIResult> result(cx);
if (!result.Init(cx, aResult)) {
return NS_ERROR_TYPE_ERR;
}
// No additionInformation passed
if (!result.mAdditionalInformation.WasPassed()) {
return SendReply(MobileConnectionReplySuccessMmi(result.mServiceCode,
result.mStatusMessage,
AdditionalInformation(mozilla::void_t())));
}
OwningUnsignedShortOrObject& additionInformation = result.mAdditionalInformation.Value();
if (additionInformation.IsUnsignedShort()) {
return SendReply(MobileConnectionReplySuccessMmi(result.mServiceCode,
result.mStatusMessage,
AdditionalInformation(uint16_t(additionInformation.GetAsUnsignedShort()))));
}
if (additionInformation.IsObject()) {
uint32_t length;
JS::Rooted<JS::Value> value(cx);
JS::Rooted<JSObject*> object(cx, additionInformation.GetAsObject());
if (!JS_IsArrayObject(cx, object) ||
!JS_GetArrayLength(cx, object, &length) || length <= 0 ||
// Check first element to decide the format of array.
!JS_GetElement(cx, object, 0, &value)) {
return NS_ERROR_TYPE_ERR;
}
// Check first element to decide the format of array.
if (value.isString()) {
// String[]
nsTArray<nsString> infos;
for (uint32_t i = 0; i < length; i++) {
if (!JS_GetElement(cx, object, i, &value) || !value.isString()) {
return NS_ERROR_TYPE_ERR;
}
nsAutoJSString str;
if (!str.init(cx, value.toString())) {
return NS_ERROR_FAILURE;
}
infos.AppendElement(str);
}
return SendReply(MobileConnectionReplySuccessMmi(result.mServiceCode,
result.mStatusMessage,
AdditionalInformation(infos)));
} else {
// IPC::MozCallForwardingOptions[]
nsTArray<IPC::MozCallForwardingOptions> infos;
for (uint32_t i = 0; i < length; i++) {
IPC::MozCallForwardingOptions info;
if (!JS_GetElement(cx, object, i, &value) || !info.Init(cx, value)) {
return NS_ERROR_TYPE_ERR;
}
infos.AppendElement(info);
}
return SendReply(MobileConnectionReplySuccessMmi(result.mServiceCode,
result.mStatusMessage,
AdditionalInformation(infos)));
}
}
return NS_ERROR_TYPE_ERR;
}
NS_IMETHODIMP
MobileConnectionRequestParent::NotifyGetCallForwardingSuccess(JS::Handle<JS::Value> aResults)
{
uint32_t length;
AutoSafeJSContext cx;
JS::Rooted<JSObject*> object(cx, &aResults.toObject());
nsTArray<IPC::MozCallForwardingOptions> results;
if (!JS_IsArrayObject(cx, object) ||
!JS_GetArrayLength(cx, object, &length)) {
return NS_ERROR_TYPE_ERR;
}
for (uint32_t i = 0; i < length; i++) {
JS::Rooted<JS::Value> entry(cx);
IPC::MozCallForwardingOptions info;
if (!JS_GetElement(cx, object, i, &entry) || !info.Init(cx, entry)) {
return NS_ERROR_TYPE_ERR;
}
results.AppendElement(info);
}
return SendReply(MobileConnectionReplySuccessCallForwarding(results));
}
NS_IMETHODIMP
MobileConnectionRequestParent::NotifyGetCallBarringSuccess(uint16_t aProgram,
bool aEnabled,
uint16_t aServiceClass)
{
return SendReply(MobileConnectionReplySuccessCallBarring(aProgram, aEnabled,
aServiceClass));
}
NS_IMETHODIMP
MobileConnectionRequestParent::NotifyGetClirStatusSuccess(uint16_t aN,
uint16_t aM)
{
return SendReply(MobileConnectionReplySuccessClirStatus(aN, aM));
}
NS_IMETHODIMP
MobileConnectionRequestParent::NotifyError(const nsAString& aName,
const nsAString& aMessage,
const nsAString& aServiceCode,
uint16_t aInfo,
uint8_t aArgc)
{
if (aArgc == 0) {
nsAutoString error(aName);
return SendReply(MobileConnectionReplyError(error));
}
nsAutoString name(aName);
nsAutoString message(aMessage);
nsAutoString serviceCode(aServiceCode);
if (aArgc < 3) {
return SendReply(MobileConnectionReplyErrorMmi(name, message, serviceCode,
AdditionalInformation(mozilla::void_t())));
}
return SendReply(MobileConnectionReplyErrorMmi(name, message, serviceCode,
AdditionalInformation(aInfo)));
}

Просмотреть файл

@ -0,0 +1,180 @@
/* 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_mobileconnection_MobileConnectionParent_h
#define mozilla_dom_mobileconnection_MobileConnectionParent_h
#include "mozilla/dom/PMobileConnectionParent.h"
#include "mozilla/dom/PMobileConnectionRequestParent.h"
#include "nsIMobileConnectionInfo.h"
#include "nsIMobileConnectionService.h"
#include "nsServiceManagerUtils.h"
namespace mozilla {
namespace dom {
namespace mobileconnection {
/**
* Parent actor of PMobileConnection. This object is created/destroyed along
* with child actor.
*/
class MobileConnectionParent : public PMobileConnectionParent
, public nsIMobileConnectionListener
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIMOBILECONNECTIONLISTENER
MobileConnectionParent(uint32_t aClientId);
protected:
virtual
~MobileConnectionParent()
{
MOZ_COUNT_DTOR(MobileConnectionParent);
}
virtual void
ActorDestroy(ActorDestroyReason why);
virtual bool
RecvPMobileConnectionRequestConstructor(PMobileConnectionRequestParent* aActor,
const MobileConnectionRequest& aRequest) MOZ_OVERRIDE;
virtual PMobileConnectionRequestParent*
AllocPMobileConnectionRequestParent(const MobileConnectionRequest& request) MOZ_OVERRIDE;
virtual bool
DeallocPMobileConnectionRequestParent(PMobileConnectionRequestParent* aActor) MOZ_OVERRIDE;
virtual bool
RecvInit(nsMobileConnectionInfo* aVoice, nsMobileConnectionInfo* aData,
nsString* aLastKnownNetwork, nsString* aLastKnownHomeNetwork,
nsString* aIccId, nsString* aNetworkSelectionMode,
nsString* aRadioState, nsTArray<nsString>* aSupportedNetworkTypes) MOZ_OVERRIDE;
private:
uint32_t mClientId;
bool mLive;
nsCOMPtr<nsIMobileConnectionService> mService;
};
/******************************************************************************
* PMobileConnectionRequestParent
******************************************************************************/
/**
* Parent actor of PMobileConnectionRequestParent. The object is created along
* with child actor and destroyed after the callback function of
* nsIMobileConnectionCallback is called. Child actor might be destroyed before
* any callback is triggered. So we use mLive to maintain the status of child
* actor in order to present sending data to a dead one.
*/
class MobileConnectionRequestParent : public PMobileConnectionRequestParent
, public nsIMobileConnectionCallback
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIMOBILECONNECTIONCALLBACK
MobileConnectionRequestParent(uint32_t aClientId)
: mClientId(aClientId)
, mLive(true)
{
MOZ_COUNT_CTOR(MobileConnectionRequestParent);
mService = do_GetService(NS_MOBILE_CONNECTION_SERVICE_CONTRACTID);
NS_ASSERTION(mService, "This shouldn't fail!");
}
bool
DoRequest(const GetNetworksRequest& aRequest);
bool
DoRequest(const SelectNetworkRequest& aRequest);
bool
DoRequest(const SelectNetworkAutoRequest& aRequest);
bool
DoRequest(const SetPreferredNetworkTypeRequest& aRequest);
bool
DoRequest(const GetPreferredNetworkTypeRequest& aRequest);
bool
DoRequest(const SetRoamingPreferenceRequest& aRequest);
bool
DoRequest(const GetRoamingPreferenceRequest& aRequest);
bool
DoRequest(const SetVoicePrivacyModeRequest& aRequest);
bool
DoRequest(const GetVoicePrivacyModeRequest& aRequest);
bool
DoRequest(const SendMmiRequest& aRequest);
bool
DoRequest(const CancelMmiRequest& aRequest);
bool
DoRequest(const SetCallForwardingRequest& aRequest);
bool
DoRequest(const GetCallForwardingRequest& aRequest);
bool
DoRequest(const SetCallBarringRequest& aRequest);
bool
DoRequest(const GetCallBarringRequest& aRequest);
bool
DoRequest(const ChangeCallBarringPasswordRequest& aRequest);
bool
DoRequest(const SetCallWaitingRequest& aRequest);
bool
DoRequest(const GetCallWaitingRequest& aRequest);
bool
DoRequest(const SetCallingLineIdRestrictionRequest& aRequest);
bool
DoRequest(const GetCallingLineIdRestrictionRequest& aRequest);
bool
DoRequest(const ExitEmergencyCbModeRequest& aRequest);
bool
DoRequest(const SetRadioEnabledRequest& aRequest);
protected:
virtual
~MobileConnectionRequestParent()
{
MOZ_COUNT_DTOR(MobileConnectionRequestParent);
}
virtual void
ActorDestroy(ActorDestroyReason why);
nsresult
SendReply(const MobileConnectionReply& aReply);
private:
uint32_t mClientId;
bool mLive;
nsCOMPtr<nsIMobileConnectionService> mService;
};
} // namespace mobileconnection
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_mobileconnection_MobileConnectionParent_h

Просмотреть файл

@ -19,8 +19,15 @@ EXPORTS.mozilla.dom += [
'MobileNetworkInfo.h',
]
EXPORTS.mozilla.dom.mobileconnection += [
'ipc/MobileConnectionChild.h',
'ipc/MobileConnectionParent.h',
]
SOURCES += [
'DOMMMIError.cpp',
'ipc/MobileConnectionChild.cpp',
'ipc/MobileConnectionParent.cpp',
'MobileCellInfo.cpp',
'MobileConnection.cpp',
'MobileConnectionArray.cpp',