From 2037e5406886b95b7b8a59153a7fb6e20610dc61 Mon Sep 17 00:00:00 2001 From: Vicamo Yang Date: Wed, 4 Sep 2013 15:53:27 +0800 Subject: [PATCH 001/171] Bug 864485 - 1/3: B2G Telephony - move to IPDL. Interface changes. sr=sicking, r=hsinyi,khuey --- dom/ipc/PContent.ipdl | 4 ++ dom/telephony/ipc/PTelephony.ipdl | 83 ++++++++++++++++++++++++ dom/telephony/ipc/PTelephonyRequest.ipdl | 30 +++++++++ dom/telephony/ipc/TelephonyTypes.ipdlh | 24 +++++++ dom/telephony/nsITelephonyProvider.idl | 34 ++++++---- 5 files changed, 161 insertions(+), 14 deletions(-) create mode 100644 dom/telephony/ipc/PTelephony.ipdl create mode 100644 dom/telephony/ipc/PTelephonyRequest.ipdl create mode 100644 dom/telephony/ipc/TelephonyTypes.ipdlh diff --git a/dom/ipc/PContent.ipdl b/dom/ipc/PContent.ipdl index eb706f624d4..a4f5e80d1e1 100644 --- a/dom/ipc/PContent.ipdl +++ b/dom/ipc/PContent.ipdl @@ -20,6 +20,7 @@ include protocol PNecko; include protocol PSms; include protocol PSpeechSynthesis; include protocol PStorage; +include protocol PTelephony; include protocol PTestShell; include protocol PJavaScript; include DOMTypes; @@ -197,6 +198,7 @@ rpc protocol PContent manages PSms; manages PSpeechSynthesis; manages PStorage; + manages PTelephony; manages PTestShell; manages PJavaScript; @@ -353,6 +355,8 @@ parent: PStorage(); + PTelephony(); + PBluetooth(); PFMRadio(); diff --git a/dom/telephony/ipc/PTelephony.ipdl b/dom/telephony/ipc/PTelephony.ipdl new file mode 100644 index 00000000000..d82044401ef --- /dev/null +++ b/dom/telephony/ipc/PTelephony.ipdl @@ -0,0 +1,83 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set sw=2 ts=8 et ft=cpp : */ +/* 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 protocol PContent; +include protocol PTelephonyRequest; +include TelephonyTypes; + +namespace mozilla { +namespace dom { +namespace telephony { + +sync protocol PTelephony { + manager PContent; + manages PTelephonyRequest; + +child: + NotifyCallError(int32_t aCallIndex, nsString aError); + + NotifyCallStateChanged(IPCCallStateData aData); + + NotifyCdmaCallWaiting(nsString aNumber); + + NotifyConferenceCallStateChanged(uint16_t aCallState); + + NotifySupplementaryService(int32_t aCallIndex, uint16_t aNotification); + +parent: + /** + * Sent when the child no longer needs to use PTelephony. + */ + __delete__(); + + /** + * Sent when the child makes an asynchronous request to the parent. It's + * currently only for request call enumeration. + */ + PTelephonyRequest(); + + RegisterListener(); + + UnregisterListener(); + + DialCall(nsString aNumber, bool aIsEmergency); + + HangUpCall(uint32_t aCallIndex); + + AnswerCall(uint32_t aCallIndex); + + RejectCall(uint32_t aCallIndex); + + HoldCall(uint32_t aCallIndex); + + ResumeCall(uint32_t aCallIndex); + + ConferenceCall(); + + SeparateCall(uint32_t aCallIndex); + + HoldConference(); + + ResumeConference(); + + StartTone(nsString aTone); + + StopTone(); + + sync GetMicrophoneMuted() + returns (bool aMuted); + + SetMicrophoneMuted(bool aMuted); + + sync GetSpeakerEnabled() + returns (bool aEnabled); + + SetSpeakerEnabled(bool aEnabled); +}; + +} /* namespace telephony */ +} /* namespace dom */ +} /* namespace mozilla */ diff --git a/dom/telephony/ipc/PTelephonyRequest.ipdl b/dom/telephony/ipc/PTelephonyRequest.ipdl new file mode 100644 index 00000000000..05f708ffc6a --- /dev/null +++ b/dom/telephony/ipc/PTelephonyRequest.ipdl @@ -0,0 +1,30 @@ +/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ +/* vim: set ts=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 protocol PTelephony; +include TelephonyTypes; + +namespace mozilla { +namespace dom { +namespace telephony { + +protocol PTelephonyRequest +{ + manager PTelephony; + +child: + NotifyEnumerateCallState(IPCCallStateData aData); + + /** + * Sent when the asynchronous request has completed. It's currently only for + * request call enumeration. + */ + __delete__(); +}; + +} /* namespace telephony */ +} /* namespace dom */ +} /* namespace mozilla */ diff --git a/dom/telephony/ipc/TelephonyTypes.ipdlh b/dom/telephony/ipc/TelephonyTypes.ipdlh new file mode 100644 index 00000000000..5a46e4ace56 --- /dev/null +++ b/dom/telephony/ipc/TelephonyTypes.ipdlh @@ -0,0 +1,24 @@ +/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ +/* vim: set ts=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/. */ + +namespace mozilla { +namespace dom { +namespace telephony { + +struct IPCCallStateData +{ + uint32_t callIndex; + uint16_t callState; + nsString number; + bool isActive; + bool isOutGoing; + bool isEmergency; + bool isConference; +}; + +} /* namespace telephony */ +} /* namespace dom */ +} /* namespace mozilla */ diff --git a/dom/telephony/nsITelephonyProvider.idl b/dom/telephony/nsITelephonyProvider.idl index 8076ac3c5a4..d8cb28adc70 100644 --- a/dom/telephony/nsITelephonyProvider.idl +++ b/dom/telephony/nsITelephonyProvider.idl @@ -4,7 +4,7 @@ #include "nsISupports.idl" -[scriptable, uuid(a5818719-e1b6-4fdc-8551-006055fa9996)] +[scriptable, uuid(3aa42e77-7c2b-43a1-b105-7be094b0817a)] interface nsITelephonyListener : nsISupports { /** @@ -67,15 +67,14 @@ interface nsITelephonyListener : nsISupports * Indicates whether this call is outgoing or incoming. * @param isConference * Indicates whether this call is a conference call. - * @return true to continue enumeration or false to cancel. */ - boolean enumerateCallState(in unsigned long callIndex, - in unsigned short callState, - in AString number, - in boolean isActive, - in boolean isOutgoing, - in boolean isEmergency, - in boolean isConference); + void enumerateCallState(in unsigned long callIndex, + in unsigned short callState, + in AString number, + in boolean isActive, + in boolean isOutgoing, + in boolean isEmergency, + in boolean isConference); /** * Notify when RIL receives supplementary service notification. @@ -108,11 +107,18 @@ interface nsITelephonyListener : nsISupports void notifyCdmaCallWaiting(in AString number); }; +%{C++ +#define TELEPHONY_PROVIDER_CID \ + { 0x9cf8aa52, 0x7c1c, 0x4cde, { 0x97, 0x4e, 0xed, 0x2a, 0xa0, 0xe7, 0x35, 0xfa } } +#define TELEPHONY_PROVIDER_CONTRACTID \ + "@mozilla.org/telephony/telephonyprovider;1" +%} + /** * XPCOM component (in the content process) that provides the telephony * information. */ -[scriptable, uuid(45a2f856-4e07-499a-94c6-624f90c3345b)] +[scriptable, uuid(effca006-1ca8-47f7-9bab-1323f90a14ec)] interface nsITelephonyProvider : nsISupports { const unsigned short CALL_STATE_UNKNOWN = 0; @@ -135,8 +141,8 @@ interface nsITelephonyProvider : nsISupports * RadioInterfaceLayer in the chrome process. Only a content process that has * the 'telephony' permission is allowed to register. */ - void registerTelephonyMsg(in nsITelephonyListener listener); - void unregisterTelephonyMsg(in nsITelephonyListener listener); + void registerListener(in nsITelephonyListener listener); + void unregisterListener(in nsITelephonyListener listener); /** * Will continue calling listener.enumerateCallState until the listener @@ -147,8 +153,8 @@ interface nsITelephonyProvider : nsISupports /** * Functionality for making and managing phone calls. */ - void dial(in DOMString number); - void dialEmergency(in DOMString number); + void dial(in DOMString number, + in boolean isEmergency); void hangUp(in unsigned long callIndex); void startTone(in DOMString dtmfChar); From f58d71463a7a95e682673a862aca6b85b120e6eb Mon Sep 17 00:00:00 2001 From: Vicamo Yang Date: Wed, 4 Sep 2013 15:53:30 +0800 Subject: [PATCH 002/171] Bug 864485 - 2/3: DOM & IPC. r=khuey --- b2g/installer/package-manifest.in | 2 +- browser/installer/package-manifest.in | 2 +- dom/base/Navigator.cpp | 2 +- dom/bindings/Bindings.conf | 10 +- dom/bluetooth/BluetoothHfpManager.cpp | 2 +- dom/bluetooth/BluetoothTelephonyListener.cpp | 12 +- dom/dom-config.mk | 1 - dom/ipc/ContentChild.cpp | 15 + dom/ipc/ContentChild.h | 3 + dom/ipc/ContentParent.cpp | 21 + dom/ipc/ContentParent.h | 3 + dom/mobilemessage/src/Makefile.in | 1 - dom/moz.build | 4 +- dom/system/gonk/Makefile.in | 1 - dom/telephony/CallEvent.cpp | 1 + dom/telephony/Makefile.in | 11 +- dom/telephony/Telephony.cpp | 23 +- dom/telephony/TelephonyCall.cpp | 1 + dom/telephony/TelephonyCallGroup.cpp | 1 + dom/telephony/TelephonyFactory.cpp | 23 + dom/telephony/TelephonyFactory.h | 24 + dom/telephony/ipc/TelephonyChild.cpp | 130 ++++++ dom/telephony/ipc/TelephonyChild.h | 77 ++++ dom/telephony/ipc/TelephonyIPCProvider.cpp | 258 +++++++++++ dom/telephony/ipc/TelephonyIPCProvider.h | 37 ++ dom/telephony/ipc/TelephonyParent.cpp | 448 +++++++++++++++++++ dom/telephony/ipc/TelephonyParent.h | 128 ++++++ dom/telephony/moz.build | 23 +- dom/webidl/WebIDL.mk | 10 +- layout/build/Makefile.in | 2 +- layout/build/nsLayoutModule.cpp | 9 + 31 files changed, 1240 insertions(+), 45 deletions(-) create mode 100644 dom/telephony/TelephonyFactory.cpp create mode 100644 dom/telephony/TelephonyFactory.h create mode 100644 dom/telephony/ipc/TelephonyChild.cpp create mode 100644 dom/telephony/ipc/TelephonyChild.h create mode 100644 dom/telephony/ipc/TelephonyIPCProvider.cpp create mode 100644 dom/telephony/ipc/TelephonyIPCProvider.h create mode 100644 dom/telephony/ipc/TelephonyParent.cpp create mode 100644 dom/telephony/ipc/TelephonyParent.h diff --git a/b2g/installer/package-manifest.in b/b2g/installer/package-manifest.in index 2553cf7659a..adf1200a495 100644 --- a/b2g/installer/package-manifest.in +++ b/b2g/installer/package-manifest.in @@ -164,7 +164,6 @@ @BINPATH@/components/dom_base.xpt @BINPATH@/components/dom_system.xpt #ifdef MOZ_B2G_RIL -@BINPATH@/components/dom_telephony.xpt @BINPATH@/components/dom_voicemail.xpt @BINPATH@/components/dom_wifi.xpt @BINPATH@/components/dom_system_gonk.xpt @@ -203,6 +202,7 @@ @BINPATH@/components/dom_mobilemessage.xpt @BINPATH@/components/dom_storage.xpt @BINPATH@/components/dom_stylesheets.xpt +@BINPATH@/components/dom_telephony.xpt @BINPATH@/components/dom_threads.xpt @BINPATH@/components/dom_traversal.xpt @BINPATH@/components/dom_views.xpt diff --git a/browser/installer/package-manifest.in b/browser/installer/package-manifest.in index 7842047d3bc..387a7915c87 100644 --- a/browser/installer/package-manifest.in +++ b/browser/installer/package-manifest.in @@ -176,7 +176,6 @@ @BINPATH@/components/dom_base.xpt @BINPATH@/components/dom_system.xpt #ifdef MOZ_B2G_RIL -@BINPATH@/components/dom_telephony.xpt @BINPATH@/components/dom_voicemail.xpt @BINPATH@/components/dom_wifi.xpt @BINPATH@/components/dom_system_gonk.xpt @@ -212,6 +211,7 @@ @BINPATH@/components/dom_mobilemessage.xpt @BINPATH@/components/dom_storage.xpt @BINPATH@/components/dom_stylesheets.xpt +@BINPATH@/components/dom_telephony.xpt @BINPATH@/components/dom_traversal.xpt #ifdef MOZ_WEBSPEECH @BINPATH@/components/dom_webspeechrecognition.xpt diff --git a/dom/base/Navigator.cpp b/dom/base/Navigator.cpp index 45ba553271b..afca9c5111e 100644 --- a/dom/base/Navigator.cpp +++ b/dom/base/Navigator.cpp @@ -54,7 +54,7 @@ #include "MediaManager.h" #endif #ifdef MOZ_B2G_RIL -#include "Telephony.h" +#include "mozilla/dom/telephony/Telephony.h" #endif #ifdef MOZ_B2G_BT #include "BluetoothManager.h" diff --git a/dom/bindings/Bindings.conf b/dom/bindings/Bindings.conf index 280dec64d94..28f4b4d783d 100644 --- a/dom/bindings/Bindings.conf +++ b/dom/bindings/Bindings.conf @@ -168,12 +168,12 @@ DOMInterfaces = { 'CallEvent': { 'nativeType': 'mozilla::dom::telephony::CallEvent', - 'headerFile': 'CallEvent.h', + 'headerFile': 'mozilla/dom/telephony/CallEvent.h', }, 'CallsList': { 'nativeType': 'mozilla::dom::telephony::CallsList', - 'headerFile': 'CallsList.h', + 'headerFile': 'mozilla/dom/telephony/CallsList.h', }, 'CameraControl': { @@ -1162,17 +1162,17 @@ DOMInterfaces = { 'Telephony' : { 'nativeType': 'mozilla::dom::telephony::Telephony', - 'headerFile': 'Telephony.h', + 'headerFile': 'mozilla/dom/telephony/Telephony.h', }, 'TelephonyCall' : { 'nativeType': 'mozilla::dom::telephony::TelephonyCall', - 'headerFile': 'TelephonyCall.h', + 'headerFile': 'mozilla/dom/telephony/TelephonyCall.h', }, 'TelephonyCallGroup' : { 'nativeType': 'mozilla::dom::telephony::TelephonyCallGroup', - 'headerFile': 'TelephonyCallGroup.h', + 'headerFile': 'mozilla/dom/telephony/TelephonyCallGroup.h', }, 'Text': { diff --git a/dom/bluetooth/BluetoothHfpManager.cpp b/dom/bluetooth/BluetoothHfpManager.cpp index 99a7d68d741..2df32818d00 100644 --- a/dom/bluetooth/BluetoothHfpManager.cpp +++ b/dom/bluetooth/BluetoothHfpManager.cpp @@ -1479,7 +1479,7 @@ BluetoothHfpManager::OnConnectSuccess(BluetoothSocket* aSocket) } nsCOMPtr provider = - do_GetService(NS_RILCONTENTHELPER_CONTRACTID); + do_GetService(TELEPHONY_PROVIDER_CONTRACTID); NS_ENSURE_TRUE_VOID(provider); provider->EnumerateCalls(mListener->GetListener()); diff --git a/dom/bluetooth/BluetoothTelephonyListener.cpp b/dom/bluetooth/BluetoothTelephonyListener.cpp index eac3a431ba0..93bfc84e676 100644 --- a/dom/bluetooth/BluetoothTelephonyListener.cpp +++ b/dom/bluetooth/BluetoothTelephonyListener.cpp @@ -61,13 +61,11 @@ TelephonyListener::EnumerateCallState(uint32_t aCallIndex, bool aIsActive, bool aIsOutgoing, bool aIsEmergency, - bool aIsConference, - bool* aResult) + bool aIsConference) { BluetoothHfpManager* hfp = BluetoothHfpManager::Get(); hfp->HandleCallStateChanged(aCallIndex, aCallState, EmptyString(), aNumber, aIsOutgoing, false); - *aResult = true; return NS_OK; } @@ -117,10 +115,10 @@ bool BluetoothTelephonyListener::StartListening() { nsCOMPtr provider = - do_GetService(NS_RILCONTENTHELPER_CONTRACTID); + do_GetService(TELEPHONY_PROVIDER_CONTRACTID); NS_ENSURE_TRUE(provider, false); - nsresult rv = provider->RegisterTelephonyMsg(mTelephonyListener); + nsresult rv = provider->RegisterListener(mTelephonyListener); NS_ENSURE_SUCCESS(rv, false); return true; @@ -130,10 +128,10 @@ bool BluetoothTelephonyListener::StopListening() { nsCOMPtr provider = - do_GetService(NS_RILCONTENTHELPER_CONTRACTID); + do_GetService(TELEPHONY_PROVIDER_CONTRACTID); NS_ENSURE_TRUE(provider, false); - nsresult rv = provider->UnregisterTelephonyMsg(mTelephonyListener); + nsresult rv = provider->UnregisterListener(mTelephonyListener); return NS_FAILED(rv) ? false : true; } diff --git a/dom/dom-config.mk b/dom/dom-config.mk index b001fc9d378..6450d3c92a0 100644 --- a/dom/dom-config.mk +++ b/dom/dom-config.mk @@ -40,7 +40,6 @@ DOM_SRCDIRS = \ ifdef MOZ_B2G_RIL DOM_SRCDIRS += \ dom/system/gonk \ - dom/telephony \ dom/wifi \ dom/icc/src \ $(NULL) diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp index f1afd28ea2d..ceb98dd23f1 100644 --- a/dom/ipc/ContentChild.cpp +++ b/dom/ipc/ContentChild.cpp @@ -96,6 +96,7 @@ #include "mozilla/dom/indexedDB/PIndexedDBChild.h" #include "mozilla/dom/mobilemessage/SmsChild.h" +#include "mozilla/dom/telephony/TelephonyChild.h" #include "mozilla/dom/devicestorage/DeviceStorageRequestChild.h" #include "mozilla/dom/bluetooth/PBluetoothChild.h" #include "mozilla/dom/PFMRadioChild.h" @@ -126,6 +127,7 @@ using namespace mozilla::dom::devicestorage; using namespace mozilla::dom::ipc; using namespace mozilla::dom::mobilemessage; using namespace mozilla::dom::indexedDB; +using namespace mozilla::dom::telephony; using namespace mozilla::hal_sandbox; using namespace mozilla::ipc; using namespace mozilla::layers; @@ -919,6 +921,19 @@ ContentChild::DeallocPSmsChild(PSmsChild* aSms) return true; } +PTelephonyChild* +ContentChild::AllocPTelephonyChild() +{ + MOZ_CRASH("No one should be allocating PTelephonyChild actors"); +} + +bool +ContentChild::DeallocPTelephonyChild(PTelephonyChild* aActor) +{ + delete aActor; + return true; +} + PStorageChild* ContentChild::AllocPStorageChild() { diff --git a/dom/ipc/ContentChild.h b/dom/ipc/ContentChild.h index 279af64fb61..4dd4d77e20b 100644 --- a/dom/ipc/ContentChild.h +++ b/dom/ipc/ContentChild.h @@ -152,6 +152,9 @@ public: virtual PSmsChild* AllocPSmsChild(); virtual bool DeallocPSmsChild(PSmsChild*); + virtual PTelephonyChild* AllocPTelephonyChild(); + virtual bool DeallocPTelephonyChild(PTelephonyChild*); + virtual PStorageChild* AllocPStorageChild(); virtual bool DeallocPStorageChild(PStorageChild* aActor); diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index 320e465a627..7c2552b3cbb 100644 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -34,6 +34,7 @@ #include "mozilla/dom/bluetooth/PBluetoothParent.h" #include "mozilla/dom/PFMRadioParent.h" #include "mozilla/dom/devicestorage/DeviceStorageRequestParent.h" +#include "mozilla/dom/telephony/TelephonyParent.h" #include "SmsParent.h" #include "mozilla/Hal.h" #include "mozilla/hal_sandbox/PHalParent.h" @@ -147,6 +148,7 @@ using namespace mozilla::dom::devicestorage; using namespace mozilla::dom::indexedDB; using namespace mozilla::dom::power; using namespace mozilla::dom::mobilemessage; +using namespace mozilla::dom::telephony; using namespace mozilla::hal; using namespace mozilla::idl; using namespace mozilla::ipc; @@ -2246,6 +2248,25 @@ ContentParent::DeallocPSmsParent(PSmsParent* aSms) return true; } +PTelephonyParent* +ContentParent::AllocPTelephonyParent() +{ + if (!AssertAppProcessPermission(this, "telephony")) { + return nullptr; + } + + TelephonyParent* actor = new TelephonyParent(); + NS_ADDREF(actor); + return actor; +} + +bool +ContentParent::DeallocPTelephonyParent(PTelephonyParent* aActor) +{ + static_cast(aActor)->Release(); + return true; +} + PStorageParent* ContentParent::AllocPStorageParent() { diff --git a/dom/ipc/ContentParent.h b/dom/ipc/ContentParent.h index 5bfa77b18d1..252e0235c90 100644 --- a/dom/ipc/ContentParent.h +++ b/dom/ipc/ContentParent.h @@ -321,6 +321,9 @@ private: virtual PSmsParent* AllocPSmsParent(); virtual bool DeallocPSmsParent(PSmsParent*); + virtual PTelephonyParent* AllocPTelephonyParent(); + virtual bool DeallocPTelephonyParent(PTelephonyParent*); + virtual PStorageParent* AllocPStorageParent(); virtual bool DeallocPStorageParent(PStorageParent* aActor); diff --git a/dom/mobilemessage/src/Makefile.in b/dom/mobilemessage/src/Makefile.in index 4dfe608bd89..e45e9b971de 100644 --- a/dom/mobilemessage/src/Makefile.in +++ b/dom/mobilemessage/src/Makefile.in @@ -33,7 +33,6 @@ LOCAL_INCLUDES += $(VPATH:%=-I%) ifdef MOZ_B2G_RIL LOCAL_INCLUDES += \ - -I$(topsrcdir)/dom/telephony \ -I$(topsrcdir)/dom/system/gonk \ $(NULL) endif diff --git a/dom/moz.build b/dom/moz.build index 5aeb1ba6a7a..4c87f43ef34 100644 --- a/dom/moz.build +++ b/dom/moz.build @@ -72,7 +72,8 @@ PARALLEL_DIRS += [ 'camera', 'audiochannel', 'promise', - 'wappush' + 'wappush', + 'telephony', ] if CONFIG['OS_ARCH'] == 'WINNT': @@ -80,7 +81,6 @@ if CONFIG['OS_ARCH'] == 'WINNT': if CONFIG['MOZ_B2G_RIL']: PARALLEL_DIRS += [ - 'telephony', 'wifi', 'icc', 'cellbroadcast', diff --git a/dom/system/gonk/Makefile.in b/dom/system/gonk/Makefile.in index d648d2d7407..d19b0731f1f 100644 --- a/dom/system/gonk/Makefile.in +++ b/dom/system/gonk/Makefile.in @@ -26,7 +26,6 @@ include $(topsrcdir)/dom/dom-config.mk LOCAL_INCLUDES = \ -I$(topsrcdir)/dom/base \ -I$(topsrcdir)/dom/src/geolocation \ - -I$(topsrcdir)/dom/telephony \ -I$(topsrcdir)/dom/wifi \ -I$(topsrcdir)/dom/bluetooth \ -I$(topsrcdir)/content/events/src \ diff --git a/dom/telephony/CallEvent.cpp b/dom/telephony/CallEvent.cpp index 30ab81aee46..580750f0608 100644 --- a/dom/telephony/CallEvent.cpp +++ b/dom/telephony/CallEvent.cpp @@ -11,6 +11,7 @@ USING_TELEPHONY_NAMESPACE using namespace mozilla::dom; +using mozilla::ErrorResult; /* static */ already_AddRefed diff --git a/dom/telephony/Makefile.in b/dom/telephony/Makefile.in index 143590c476a..cf24906409e 100644 --- a/dom/telephony/Makefile.in +++ b/dom/telephony/Makefile.in @@ -5,11 +5,18 @@ DEPTH = @DEPTH@ topsrcdir = @top_srcdir@ srcdir = @srcdir@ -VPATH = @srcdir@ +VPATH = \ + $(srcdir) \ + $(srcdir)/ipc \ + $(NULL) include $(DEPTH)/config/autoconf.mk include $(topsrcdir)/dom/dom-config.mk -include $(topsrcdir)/config/rules.mk +# Add VPATH to LOCAL_INCLUDES so we are going to include the correct backend +# subdirectory (and the ipc one). +LOCAL_INCLUDES = $(VPATH:%=-I%) +include $(topsrcdir)/config/rules.mk +include $(topsrcdir)/ipc/chromium/chromium-config.mk diff --git a/dom/telephony/Telephony.cpp b/dom/telephony/Telephony.cpp index 430242e65c6..95749b0fb6f 100644 --- a/dom/telephony/Telephony.cpp +++ b/dom/telephony/Telephony.cpp @@ -24,10 +24,9 @@ #include "TelephonyCall.h" #include "TelephonyCallGroup.h" -#define NS_RILCONTENTHELPER_CONTRACTID "@mozilla.org/ril/content-helper;1" - USING_TELEPHONY_NAMESPACE using namespace mozilla::dom; +using mozilla::ErrorResult; namespace { @@ -51,6 +50,8 @@ public: MOZ_ASSERT(mTelephony); } + virtual ~Listener() {} + void Disconnect() { @@ -111,7 +112,7 @@ Telephony::Shutdown() mListener->Disconnect(); if (mProvider) { - mProvider->UnregisterTelephonyMsg(mListener); + mProvider->UnregisterListener(mListener); mProvider = nullptr; } @@ -132,7 +133,7 @@ Telephony::Create(nsPIDOMWindow* aOwner, ErrorResult& aRv) NS_ASSERTION(aOwner, "Null owner!"); nsCOMPtr ril = - do_GetService(NS_RILCONTENTHELPER_CONTRACTID); + do_GetService(TELEPHONY_PROVIDER_CONTRACTID); if (!ril) { aRv.Throw(NS_ERROR_UNEXPECTED); return nullptr; @@ -165,7 +166,7 @@ Telephony::Create(nsPIDOMWindow* aOwner, ErrorResult& aRv) return nullptr; } - rv = ril->RegisterTelephonyMsg(telephony->mListener); + rv = ril->RegisterListener(telephony->mListener); if (NS_FAILED(rv)) { aRv.Throw(rv); return nullptr; @@ -222,12 +223,7 @@ Telephony::DialInternal(bool isEmergency, } } - nsresult rv; - if (isEmergency) { - rv = mProvider->DialEmergency(aNumber); - } else { - rv = mProvider->Dial(aNumber); - } + nsresult rv = mProvider->Dial(aNumber, isEmergency); if (NS_FAILED(rv)) { aRv.Throw(rv); return nullptr; @@ -591,7 +587,7 @@ NS_IMETHODIMP Telephony::EnumerateCallState(uint32_t aCallIndex, uint16_t aCallState, const nsAString& aNumber, bool aIsActive, bool aIsOutgoing, bool aIsEmergency, - bool aIsConference, bool* aContinue) + bool aIsConference) { nsRefPtr call; @@ -603,12 +599,10 @@ Telephony::EnumerateCallState(uint32_t aCallIndex, uint16_t aCallState, call = aIsConference ? mGroup->GetCall(aCallIndex) : GetCall(aCallIndex); if (call) { // We have the call either in mCalls or in mGroup. Skip it. - *aContinue = true; return NS_OK; } if (MoveCall(aCallIndex, aIsConference)) { - *aContinue = true; return NS_OK; } @@ -622,7 +616,6 @@ Telephony::EnumerateCallState(uint32_t aCallIndex, uint16_t aCallState, mCalls.Contains(call), "Should have auto-added new call!"); - *aContinue = true; return NS_OK; } diff --git a/dom/telephony/TelephonyCall.cpp b/dom/telephony/TelephonyCall.cpp index f90389da17a..23868f82964 100644 --- a/dom/telephony/TelephonyCall.cpp +++ b/dom/telephony/TelephonyCall.cpp @@ -15,6 +15,7 @@ USING_TELEPHONY_NAMESPACE using namespace mozilla::dom; +using mozilla::ErrorResult; // static already_AddRefed diff --git a/dom/telephony/TelephonyCallGroup.cpp b/dom/telephony/TelephonyCallGroup.cpp index 0e71643afba..d5571a657ac 100644 --- a/dom/telephony/TelephonyCallGroup.cpp +++ b/dom/telephony/TelephonyCallGroup.cpp @@ -13,6 +13,7 @@ USING_TELEPHONY_NAMESPACE using namespace mozilla::dom; +using mozilla::ErrorResult; TelephonyCallGroup::TelephonyCallGroup() : mCallState(nsITelephonyProvider::CALL_STATE_UNKNOWN) diff --git a/dom/telephony/TelephonyFactory.cpp b/dom/telephony/TelephonyFactory.cpp new file mode 100644 index 00000000000..cdb2b88dd86 --- /dev/null +++ b/dom/telephony/TelephonyFactory.cpp @@ -0,0 +1,23 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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/telephony/TelephonyFactory.h" +#include "nsServiceManagerUtils.h" +#include "nsXULAppAPI.h" +#include "TelephonyIPCProvider.h" + +USING_TELEPHONY_NAMESPACE + +/* static */ already_AddRefed +TelephonyFactory::CreateTelephonyProvider() +{ + nsCOMPtr provider; + + if (XRE_GetProcessType() == GeckoProcessType_Content) { + provider = new TelephonyIPCProvider(); + } + + return provider.forget(); +} diff --git a/dom/telephony/TelephonyFactory.h b/dom/telephony/TelephonyFactory.h new file mode 100644 index 00000000000..07e3f779304 --- /dev/null +++ b/dom/telephony/TelephonyFactory.h @@ -0,0 +1,24 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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_telephony_TelephonyFactory_h +#define mozilla_dom_telephony_TelephonyFactory_h + +#include "nsCOMPtr.h" +#include "mozilla/dom/telephony/TelephonyCommon.h" + +class nsITelephonyProvider; + +BEGIN_TELEPHONY_NAMESPACE + +class TelephonyFactory +{ +public: + static already_AddRefed CreateTelephonyProvider(); +}; + +END_TELEPHONY_NAMESPACE + +#endif // mozilla_dom_telephony_TelephonyFactory_h diff --git a/dom/telephony/ipc/TelephonyChild.cpp b/dom/telephony/ipc/TelephonyChild.cpp new file mode 100644 index 00000000000..a4c85f241ca --- /dev/null +++ b/dom/telephony/ipc/TelephonyChild.cpp @@ -0,0 +1,130 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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 "TelephonyChild.h" + +USING_TELEPHONY_NAMESPACE + +/******************************************************************************* + * TelephonyChild + ******************************************************************************/ + +TelephonyChild::TelephonyChild(nsITelephonyListener* aListener) + : mListener(aListener) +{ + MOZ_ASSERT(aListener); +} + +void +TelephonyChild::ActorDestroy(ActorDestroyReason aWhy) +{ + mListener = nullptr; +} + +PTelephonyRequestChild* +TelephonyChild::AllocPTelephonyRequestChild() +{ + MOZ_CRASH("Caller is supposed to manually construct a request!"); +} + +bool +TelephonyChild::DeallocPTelephonyRequestChild(PTelephonyRequestChild* aActor) +{ + delete aActor; + return true; +} + +bool +TelephonyChild::RecvNotifyCallError(const int32_t& aCallIndex, + const nsString& aError) +{ + MOZ_ASSERT(mListener); + + mListener->NotifyError(aCallIndex, aError); + return true; +} + +bool +TelephonyChild::RecvNotifyCallStateChanged(const IPCCallStateData& aData) +{ + MOZ_ASSERT(mListener); + + mListener->CallStateChanged(aData.callIndex(), + aData.callState(), + aData.number(), + aData.isActive(), + aData.isOutGoing(), + aData.isEmergency(), + aData.isConference()); + return true; +} + +bool +TelephonyChild::RecvNotifyCdmaCallWaiting(const nsString& aNumber) +{ + MOZ_ASSERT(mListener); + + mListener->NotifyCdmaCallWaiting(aNumber); + return true; +} + +bool +TelephonyChild::RecvNotifyConferenceCallStateChanged(const uint16_t& aCallState) +{ + MOZ_ASSERT(mListener); + + mListener->ConferenceCallStateChanged(aCallState); + return true; +} + +bool +TelephonyChild::RecvNotifySupplementaryService(const int32_t& aCallIndex, + const uint16_t& aNotification) +{ + MOZ_ASSERT(mListener); + + mListener->SupplementaryServiceNotification(aCallIndex, aNotification); + return true; +} + +/******************************************************************************* + * TelephonyRequestChild + ******************************************************************************/ + +TelephonyRequestChild::TelephonyRequestChild(nsITelephonyListener* aListener) + : mListener(aListener) +{ + MOZ_ASSERT(aListener); +} + +void +TelephonyRequestChild::ActorDestroy(ActorDestroyReason aWhy) +{ + mListener = nullptr; +} + +bool +TelephonyRequestChild::Recv__delete__() +{ + MOZ_ASSERT(mListener); + + mListener->EnumerateCallStateComplete(); + return true; +} + +bool +TelephonyRequestChild::RecvNotifyEnumerateCallState(const IPCCallStateData& aData) +{ + MOZ_ASSERT(mListener); + + mListener->EnumerateCallState(aData.callIndex(), + aData.callState(), + aData.number(), + aData.isActive(), + aData.isOutGoing(), + aData.isEmergency(), + aData.isConference()); + return true; +} diff --git a/dom/telephony/ipc/TelephonyChild.h b/dom/telephony/ipc/TelephonyChild.h new file mode 100644 index 00000000000..91eb1f8d2a5 --- /dev/null +++ b/dom/telephony/ipc/TelephonyChild.h @@ -0,0 +1,77 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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_telephony_TelephonyChild_h +#define mozilla_dom_telephony_TelephonyChild_h + +#include "mozilla/dom/telephony/TelephonyCommon.h" +#include "mozilla/dom/telephony/PTelephonyChild.h" +#include "mozilla/dom/telephony/PTelephonyRequestChild.h" +#include "nsITelephonyProvider.h" + +BEGIN_TELEPHONY_NAMESPACE + +class TelephonyChild : public PTelephonyChild +{ +public: + TelephonyChild(nsITelephonyListener* aListener); + +protected: + virtual ~TelephonyChild() {} + + virtual void + ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE; + + virtual PTelephonyRequestChild* + AllocPTelephonyRequestChild() MOZ_OVERRIDE; + + virtual bool + DeallocPTelephonyRequestChild(PTelephonyRequestChild* aActor) MOZ_OVERRIDE; + + virtual bool + RecvNotifyCallError(const int32_t& aCallIndex, + const nsString& aError) MOZ_OVERRIDE; + + virtual bool + RecvNotifyCallStateChanged(const IPCCallStateData& aData) MOZ_OVERRIDE; + + virtual bool + RecvNotifyCdmaCallWaiting(const nsString& aNumber) MOZ_OVERRIDE; + + virtual bool + RecvNotifyConferenceCallStateChanged(const uint16_t& aCallState) MOZ_OVERRIDE; + + virtual bool + RecvNotifySupplementaryService(const int32_t& aCallIndex, + const uint16_t& aNotification) MOZ_OVERRIDE; + +private: + nsCOMPtr mListener; +}; + +class TelephonyRequestChild : public PTelephonyRequestChild +{ +public: + TelephonyRequestChild(nsITelephonyListener* aListener); + +protected: + virtual ~TelephonyRequestChild() {} + + virtual void + ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE; + + virtual bool + Recv__delete__() MOZ_OVERRIDE; + + virtual bool + RecvNotifyEnumerateCallState(const IPCCallStateData& aData) MOZ_OVERRIDE; + +private: + nsCOMPtr mListener; +}; + +END_TELEPHONY_NAMESPACE + +#endif // mozilla_dom_telephony_TelephonyChild_h diff --git a/dom/telephony/ipc/TelephonyIPCProvider.cpp b/dom/telephony/ipc/TelephonyIPCProvider.cpp new file mode 100644 index 00000000000..93843d5e956 --- /dev/null +++ b/dom/telephony/ipc/TelephonyIPCProvider.cpp @@ -0,0 +1,258 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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/ContentChild.h" +#include "TelephonyChild.h" +#include "TelephonyIPCProvider.h" + +USING_TELEPHONY_NAMESPACE +using namespace mozilla::dom; + +NS_IMPL_ISUPPORTS2(TelephonyIPCProvider, + nsITelephonyProvider, + nsITelephonyListener) + +TelephonyIPCProvider::TelephonyIPCProvider() +{ + // Deallocated in ContentChild::DeallocPTelephonyChild(). + mPTelephonyChild = new TelephonyChild(this); + ContentChild::GetSingleton()->SendPTelephonyConstructor(mPTelephonyChild); +} + +TelephonyIPCProvider::~TelephonyIPCProvider() +{ + mPTelephonyChild->Send__delete__(mPTelephonyChild); + mPTelephonyChild = nullptr; +} + +/* + * Implementation of nsITelephonyProvider. + */ + +NS_IMETHODIMP +TelephonyIPCProvider::RegisterListener(nsITelephonyListener *aListener) +{ + MOZ_ASSERT(!mListeners.Contains(aListener)); + + // nsTArray doesn't fail. + mListeners.AppendElement(aListener); + + if (mListeners.Length() == 1) { + mPTelephonyChild->SendRegisterListener(); + } + return NS_OK; +} + +NS_IMETHODIMP +TelephonyIPCProvider::UnregisterListener(nsITelephonyListener *aListener) +{ + MOZ_ASSERT(mListeners.Contains(aListener)); + + // We always have the element here, so it can't fail. + mListeners.RemoveElement(aListener); + + if (!mListeners.Length()) { + mPTelephonyChild->SendUnregisterListener(); + } + return NS_OK; +} + +NS_IMETHODIMP +TelephonyIPCProvider::EnumerateCalls(nsITelephonyListener *aListener) +{ + // Life time of newly allocated TelephonyRequestChild instance is managed by + // IPDL itself. + TelephonyRequestChild* actor = new TelephonyRequestChild(aListener); + mPTelephonyChild->SendPTelephonyRequestConstructor(actor); + return NS_OK; +} + +NS_IMETHODIMP +TelephonyIPCProvider::Dial(const nsAString& aNumber, + bool aIsEmergency) +{ + mPTelephonyChild->SendDialCall(nsString(aNumber), aIsEmergency); + return NS_OK; +} + +NS_IMETHODIMP +TelephonyIPCProvider::HangUp(uint32_t aCallIndex) +{ + mPTelephonyChild->SendHangUpCall(aCallIndex); + return NS_OK; +} + +NS_IMETHODIMP +TelephonyIPCProvider::AnswerCall(uint32_t aCallIndex) +{ + mPTelephonyChild->SendAnswerCall(aCallIndex); + return NS_OK; +} + +NS_IMETHODIMP +TelephonyIPCProvider::RejectCall(uint32_t aCallIndex) +{ + mPTelephonyChild->SendRejectCall(aCallIndex); + return NS_OK; +} + +NS_IMETHODIMP +TelephonyIPCProvider::HoldCall(uint32_t aCallIndex) +{ + mPTelephonyChild->SendHoldCall(aCallIndex); + return NS_OK; +} + +NS_IMETHODIMP +TelephonyIPCProvider::ResumeCall(uint32_t aCallIndex) +{ + mPTelephonyChild->SendResumeCall(aCallIndex); + return NS_OK; +} + +NS_IMETHODIMP +TelephonyIPCProvider::ConferenceCall() +{ + mPTelephonyChild->SendConferenceCall(); + return NS_OK; +} + +NS_IMETHODIMP +TelephonyIPCProvider::SeparateCall(uint32_t aCallIndex) +{ + mPTelephonyChild->SendSeparateCall(aCallIndex); + return NS_OK; +} + +NS_IMETHODIMP +TelephonyIPCProvider::HoldConference() +{ + mPTelephonyChild->SendHoldConference(); + return NS_OK; +} + +NS_IMETHODIMP +TelephonyIPCProvider::ResumeConference() +{ + mPTelephonyChild->SendResumeConference(); + return NS_OK; +} + +NS_IMETHODIMP +TelephonyIPCProvider::StartTone(const nsAString& aDtmfChar) +{ + mPTelephonyChild->SendStartTone(nsString(aDtmfChar)); + return NS_OK; +} + +NS_IMETHODIMP +TelephonyIPCProvider::StopTone() +{ + mPTelephonyChild->SendStopTone(); + return NS_OK; +} + +NS_IMETHODIMP +TelephonyIPCProvider::GetMicrophoneMuted(bool* aMuted) +{ + mPTelephonyChild->SendGetMicrophoneMuted(aMuted); + return NS_OK; +} + +NS_IMETHODIMP +TelephonyIPCProvider::SetMicrophoneMuted(bool aMuted) +{ + mPTelephonyChild->SendSetMicrophoneMuted(aMuted); + return NS_OK; +} + +NS_IMETHODIMP +TelephonyIPCProvider::GetSpeakerEnabled(bool* aEnabled) +{ + mPTelephonyChild->SendGetSpeakerEnabled(aEnabled); + return NS_OK; +} + +NS_IMETHODIMP +TelephonyIPCProvider::SetSpeakerEnabled(bool aEnabled) +{ + mPTelephonyChild->SendSetSpeakerEnabled(aEnabled); + return NS_OK; +} + +// nsITelephonyListener + +NS_IMETHODIMP +TelephonyIPCProvider::CallStateChanged(uint32_t aCallIndex, + uint16_t aCallState, + const nsAString& aNumber, + bool aIsActive, + bool aIsOutgoing, + bool aIsEmergency, + bool aIsConference) +{ + for (uint32_t i = 0; i < mListeners.Length(); i++) { + mListeners[i]->CallStateChanged(aCallIndex, aCallState, aNumber, + aIsActive, aIsOutgoing, aIsEmergency, + aIsConference); + } + return NS_OK; +} + +NS_IMETHODIMP +TelephonyIPCProvider::ConferenceCallStateChanged(uint16_t aCallState) +{ + for (uint32_t i = 0; i < mListeners.Length(); i++) { + mListeners[i]->ConferenceCallStateChanged(aCallState); + } + return NS_OK; +} + +NS_IMETHODIMP +TelephonyIPCProvider::EnumerateCallStateComplete() +{ + MOZ_CRASH("Not a EnumerateCalls request!"); +} + +NS_IMETHODIMP +TelephonyIPCProvider::EnumerateCallState(uint32_t aCallIndex, + uint16_t aCallState, + const nsAString& aNumber, + bool aIsActive, + bool aIsOutgoing, + bool aIsEmergency, + bool aIsConference) +{ + MOZ_CRASH("Not a EnumerateCalls request!"); +} + +NS_IMETHODIMP +TelephonyIPCProvider::NotifyCdmaCallWaiting(const nsAString& aNumber) +{ + for (uint32_t i = 0; i < mListeners.Length(); i++) { + mListeners[i]->NotifyCdmaCallWaiting(aNumber); + } + return NS_OK; +} + +NS_IMETHODIMP +TelephonyIPCProvider::NotifyError(int32_t aCallIndex, + const nsAString& aError) +{ + for (uint32_t i = 0; i < mListeners.Length(); i++) { + mListeners[i]->NotifyError(aCallIndex, aError); + } + return NS_OK; +} + +NS_IMETHODIMP +TelephonyIPCProvider::SupplementaryServiceNotification(int32_t aCallIndex, + uint16_t aNotification) +{ + for (uint32_t i = 0; i < mListeners.Length(); i++) { + mListeners[i]->SupplementaryServiceNotification(aCallIndex, aNotification); + } + return NS_OK; +} diff --git a/dom/telephony/ipc/TelephonyIPCProvider.h b/dom/telephony/ipc/TelephonyIPCProvider.h new file mode 100644 index 00000000000..928fd1d6567 --- /dev/null +++ b/dom/telephony/ipc/TelephonyIPCProvider.h @@ -0,0 +1,37 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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_telephony_TelephonyIPCProvider_h +#define mozilla_dom_telephony_TelephonyIPCProvider_h + +#include "mozilla/dom/telephony/TelephonyCommon.h" +#include "mozilla/Attributes.h" +#include "nsITelephonyProvider.h" + +BEGIN_TELEPHONY_NAMESPACE + +class PTelephonyChild; + +class TelephonyIPCProvider MOZ_FINAL : public nsITelephonyProvider + , public nsITelephonyListener +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSITELEPHONYPROVIDER + NS_DECL_NSITELEPHONYLISTENER + + TelephonyIPCProvider(); + +protected: + virtual ~TelephonyIPCProvider(); + +private: + nsTArray > mListeners; + PTelephonyChild* mPTelephonyChild; +}; + +END_TELEPHONY_NAMESPACE + +#endif // mozilla_dom_telephony_TelephonyIPCProvider_h diff --git a/dom/telephony/ipc/TelephonyParent.cpp b/dom/telephony/ipc/TelephonyParent.cpp new file mode 100644 index 00000000000..3e82f86836e --- /dev/null +++ b/dom/telephony/ipc/TelephonyParent.cpp @@ -0,0 +1,448 @@ +/* -*- Mode: C++ tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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 "TelephonyParent.h" + +USING_TELEPHONY_NAMESPACE + +/******************************************************************************* + * TelephonyParent + ******************************************************************************/ + +NS_IMPL_ISUPPORTS1(TelephonyParent, nsITelephonyListener) + +TelephonyParent::TelephonyParent() + : mActorDestroyed(false) + , mRegistered(false) +{ +} + +void +TelephonyParent::ActorDestroy(ActorDestroyReason why) +{ + // The child process could die before this asynchronous notification, in which + // case ActorDestroy() was called and mActorDestroyed is set to true. Return + // an error here to avoid sending a message to the dead process. + mActorDestroyed = true; + + // Try to unregister listener if we're still registered. + RecvUnregisterListener(); +} + +bool +TelephonyParent::RecvPTelephonyRequestConstructor(PTelephonyRequestParent* aActor) +{ + TelephonyRequestParent* actor = static_cast(aActor); + + return actor->DoRequest(); +} + +PTelephonyRequestParent* +TelephonyParent::AllocPTelephonyRequestParent() +{ + TelephonyRequestParent* actor = new TelephonyRequestParent(); + // Add an extra ref for IPDL. Will be released in + // TelephonyParent::DeallocPTelephonyRequestParent(). + NS_ADDREF(actor); + + return actor; +} + +bool +TelephonyParent::DeallocPTelephonyRequestParent(PTelephonyRequestParent* aActor) +{ + // TelephonyRequestParent is refcounted, must not be freed manually. + static_cast(aActor)->Release(); + return true; +} + +bool +TelephonyParent::Recv__delete__() +{ + return true; // Unregister listener in TelephonyParent::ActorDestroy(). +} + +bool +TelephonyParent::RecvRegisterListener() +{ + NS_ENSURE_TRUE(!mRegistered, true); + + nsCOMPtr provider = + do_GetService(TELEPHONY_PROVIDER_CONTRACTID); + NS_ENSURE_TRUE(provider, true); + + mRegistered = NS_SUCCEEDED(provider->RegisterListener(this)); + return true; +} + +bool +TelephonyParent::RecvUnregisterListener() +{ + NS_ENSURE_TRUE(mRegistered, true); + + nsCOMPtr provider = + do_GetService(TELEPHONY_PROVIDER_CONTRACTID); + NS_ENSURE_TRUE(provider, true); + + mRegistered = !NS_SUCCEEDED(provider->UnregisterListener(this)); + return true; +} + +bool +TelephonyParent::RecvDialCall(const nsString& aNumber, + const bool& aIsEmergency) +{ + nsCOMPtr provider = + do_GetService(TELEPHONY_PROVIDER_CONTRACTID); + NS_ENSURE_TRUE(provider, true); + + provider->Dial(aNumber, aIsEmergency); + return true; +} + +bool +TelephonyParent::RecvHangUpCall(const uint32_t& aCallIndex) +{ + nsCOMPtr provider = + do_GetService(TELEPHONY_PROVIDER_CONTRACTID); + NS_ENSURE_TRUE(provider, true); + + provider->HangUp(aCallIndex); + return true; +} + +bool +TelephonyParent::RecvAnswerCall(const uint32_t& aCallIndex) +{ + nsCOMPtr provider = + do_GetService(TELEPHONY_PROVIDER_CONTRACTID); + NS_ENSURE_TRUE(provider, true); + + provider->AnswerCall(aCallIndex); + return true; +} + +bool +TelephonyParent::RecvRejectCall(const uint32_t& aCallIndex) +{ + nsCOMPtr provider = + do_GetService(TELEPHONY_PROVIDER_CONTRACTID); + NS_ENSURE_TRUE(provider, true); + + provider->RejectCall(aCallIndex); + return true; +} + +bool +TelephonyParent::RecvHoldCall(const uint32_t& aCallIndex) +{ + nsCOMPtr provider = + do_GetService(TELEPHONY_PROVIDER_CONTRACTID); + NS_ENSURE_TRUE(provider, true); + + provider->HoldCall(aCallIndex); + return true; +} + +bool +TelephonyParent::RecvResumeCall(const uint32_t& aCallIndex) +{ + nsCOMPtr provider = + do_GetService(TELEPHONY_PROVIDER_CONTRACTID); + NS_ENSURE_TRUE(provider, true); + + provider->ResumeCall(aCallIndex); + return true; +} + +bool +TelephonyParent::RecvConferenceCall() +{ + nsCOMPtr provider = + do_GetService(TELEPHONY_PROVIDER_CONTRACTID); + NS_ENSURE_TRUE(provider, true); + + provider->ConferenceCall(); + return true; +} + +bool +TelephonyParent::RecvSeparateCall(const uint32_t& aCallState) +{ + nsCOMPtr provider = + do_GetService(TELEPHONY_PROVIDER_CONTRACTID); + NS_ENSURE_TRUE(provider, true); + + provider->SeparateCall(aCallState); + return true; +} + +bool +TelephonyParent::RecvHoldConference() +{ + nsCOMPtr provider = + do_GetService(TELEPHONY_PROVIDER_CONTRACTID); + NS_ENSURE_TRUE(provider, true); + + provider->HoldConference(); + return true; +} + +bool +TelephonyParent::RecvResumeConference() +{ + nsCOMPtr provider = + do_GetService(TELEPHONY_PROVIDER_CONTRACTID); + NS_ENSURE_TRUE(provider, true); + + provider->ResumeConference(); + return true; +} + +bool +TelephonyParent::RecvStartTone(const nsString& aTone) +{ + nsCOMPtr provider = + do_GetService(TELEPHONY_PROVIDER_CONTRACTID); + NS_ENSURE_TRUE(provider, true); + + provider->StartTone(aTone); + return true; +} + +bool +TelephonyParent::RecvStopTone() +{ + nsCOMPtr provider = + do_GetService(TELEPHONY_PROVIDER_CONTRACTID); + NS_ENSURE_TRUE(provider, true); + + provider->StopTone(); + return true; +} + +bool +TelephonyParent::RecvGetMicrophoneMuted(bool* aMuted) +{ + *aMuted = false; + + nsCOMPtr provider = + do_GetService(TELEPHONY_PROVIDER_CONTRACTID); + NS_ENSURE_TRUE(provider, true); + + provider->GetMicrophoneMuted(aMuted); + return true; +} + +bool +TelephonyParent::RecvSetMicrophoneMuted(const bool& aMuted) +{ + nsCOMPtr provider = + do_GetService(TELEPHONY_PROVIDER_CONTRACTID); + NS_ENSURE_TRUE(provider, true); + + provider->SetMicrophoneMuted(aMuted); + return true; +} + +bool +TelephonyParent::RecvGetSpeakerEnabled(bool* aEnabled) +{ + *aEnabled = false; + + nsCOMPtr provider = + do_GetService(TELEPHONY_PROVIDER_CONTRACTID); + NS_ENSURE_TRUE(provider, true); + + provider->GetSpeakerEnabled(aEnabled); + return true; +} + +bool +TelephonyParent::RecvSetSpeakerEnabled(const bool& aEnabled) +{ + nsCOMPtr provider = + do_GetService(TELEPHONY_PROVIDER_CONTRACTID); + NS_ENSURE_TRUE(provider, true); + + provider->SetSpeakerEnabled(aEnabled); + return true; +} + +// nsITelephonyListener + +NS_IMETHODIMP +TelephonyParent::CallStateChanged(uint32_t aCallIndex, + uint16_t aCallState, + const nsAString& aNumber, + bool aIsActive, + bool aIsOutgoing, + bool aIsEmergency, + bool aIsConference) +{ + NS_ENSURE_TRUE(!mActorDestroyed, NS_ERROR_FAILURE); + + IPCCallStateData data(aCallIndex, aCallState, nsString(aNumber), aIsActive, + aIsOutgoing, aIsEmergency, aIsConference); + return SendNotifyCallStateChanged(data) ? NS_OK : NS_ERROR_FAILURE; +} + +NS_IMETHODIMP +TelephonyParent::ConferenceCallStateChanged(uint16_t aCallState) +{ + NS_ENSURE_TRUE(!mActorDestroyed, NS_ERROR_FAILURE); + + return SendNotifyConferenceCallStateChanged(aCallState) ? NS_OK + : NS_ERROR_FAILURE; +} + +NS_IMETHODIMP +TelephonyParent::EnumerateCallStateComplete() +{ + MOZ_CRASH("Not a EnumerateCalls request!"); +} + +NS_IMETHODIMP +TelephonyParent::EnumerateCallState(uint32_t aCallIndex, + uint16_t aCallState, + const nsAString& aNumber, + bool aIsActive, + bool aIsOutgoing, + bool aIsEmergency, + bool aIsConference) +{ + MOZ_CRASH("Not a EnumerateCalls request!"); +} + +NS_IMETHODIMP +TelephonyParent::NotifyCdmaCallWaiting(const nsAString& aNumber) +{ + NS_ENSURE_TRUE(!mActorDestroyed, NS_ERROR_FAILURE); + + return SendNotifyCdmaCallWaiting(nsString(aNumber)) ? NS_OK + : NS_ERROR_FAILURE; +} + +NS_IMETHODIMP +TelephonyParent::NotifyError(int32_t aCallIndex, + const nsAString& aError) +{ + NS_ENSURE_TRUE(!mActorDestroyed, NS_ERROR_FAILURE); + + return SendNotifyCallError(aCallIndex, nsString(aError)) ? NS_OK + : NS_ERROR_FAILURE; +} + +NS_IMETHODIMP +TelephonyParent::SupplementaryServiceNotification(int32_t aCallIndex, + uint16_t aNotification) +{ + NS_ENSURE_TRUE(!mActorDestroyed, NS_ERROR_FAILURE); + + return SendNotifySupplementaryService(aCallIndex, aNotification) + ? NS_OK : NS_ERROR_FAILURE; +} + +/******************************************************************************* + * TelephonyRequestParent + ******************************************************************************/ + +NS_IMPL_ISUPPORTS1(TelephonyRequestParent, nsITelephonyListener) + +TelephonyRequestParent::TelephonyRequestParent() + : mActorDestroyed(false) +{ +} + +void +TelephonyRequestParent::ActorDestroy(ActorDestroyReason why) +{ + // The child process could die before this asynchronous notification, in which + // case ActorDestroy() was called and mActorDestroyed is set to true. Return + // an error here to avoid sending a message to the dead process. + mActorDestroyed = true; +} + +bool +TelephonyRequestParent::DoRequest() +{ + nsresult rv = NS_ERROR_FAILURE; + + nsCOMPtr provider = + do_GetService(TELEPHONY_PROVIDER_CONTRACTID); + if (provider) { + rv = provider->EnumerateCalls(this); + } + + if (NS_FAILED(rv)) { + return NS_SUCCEEDED(EnumerateCallStateComplete()); + } + + return true; +} + +// nsITelephonyListener + +NS_IMETHODIMP +TelephonyRequestParent::CallStateChanged(uint32_t aCallIndex, + uint16_t aCallState, + const nsAString& aNumber, + bool aIsActive, + bool aIsOutgoing, + bool aIsEmergency, + bool aIsConference) +{ + MOZ_CRASH("Not a TelephonyParent!"); +} + +NS_IMETHODIMP +TelephonyRequestParent::ConferenceCallStateChanged(uint16_t aCallState) +{ + MOZ_CRASH("Not a TelephonyParent!"); +} + +NS_IMETHODIMP +TelephonyRequestParent::EnumerateCallStateComplete() +{ + NS_ENSURE_TRUE(!mActorDestroyed, NS_ERROR_FAILURE); + + return Send__delete__(this) ? NS_OK : NS_ERROR_FAILURE; +} + +NS_IMETHODIMP +TelephonyRequestParent::EnumerateCallState(uint32_t aCallIndex, + uint16_t aCallState, + const nsAString& aNumber, + bool aIsActive, + bool aIsOutgoing, + bool aIsEmergency, + bool aIsConference) +{ + NS_ENSURE_TRUE(!mActorDestroyed, NS_ERROR_FAILURE); + + IPCCallStateData data(aCallIndex, aCallState, nsString(aNumber), aIsActive, + aIsOutgoing, aIsEmergency, aIsConference); + return SendNotifyEnumerateCallState(data) ? NS_OK : NS_ERROR_FAILURE; +} + +NS_IMETHODIMP +TelephonyRequestParent::NotifyCdmaCallWaiting(const nsAString& aNumber) +{ + MOZ_CRASH("Not a TelephonyParent!"); +} + +NS_IMETHODIMP +TelephonyRequestParent::NotifyError(int32_t aCallIndex, + const nsAString& aError) +{ + MOZ_CRASH("Not a TelephonyParent!"); +} + +NS_IMETHODIMP +TelephonyRequestParent::SupplementaryServiceNotification(int32_t aCallIndex, + uint16_t aNotification) +{ + MOZ_CRASH("Not a TelephonyParent!"); +} diff --git a/dom/telephony/ipc/TelephonyParent.h b/dom/telephony/ipc/TelephonyParent.h new file mode 100644 index 00000000000..ac508c264be --- /dev/null +++ b/dom/telephony/ipc/TelephonyParent.h @@ -0,0 +1,128 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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_telephony_TelephonyParent_h +#define mozilla_dom_telephony_TelephonyParent_h + +#include "mozilla/dom/telephony/TelephonyCommon.h" +#include "mozilla/dom/telephony/PTelephonyParent.h" +#include "mozilla/dom/telephony/PTelephonyRequestParent.h" +#include "nsITelephonyProvider.h" + +BEGIN_TELEPHONY_NAMESPACE + +class TelephonyParent : public PTelephonyParent + , public nsITelephonyListener +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSITELEPHONYLISTENER + + TelephonyParent(); + +protected: + virtual ~TelephonyParent() {} + + virtual void + ActorDestroy(ActorDestroyReason why); + + virtual bool + RecvPTelephonyRequestConstructor(PTelephonyRequestParent* aActor) MOZ_OVERRIDE; + + virtual PTelephonyRequestParent* + AllocPTelephonyRequestParent() MOZ_OVERRIDE; + + virtual bool + DeallocPTelephonyRequestParent(PTelephonyRequestParent* aActor) MOZ_OVERRIDE; + + virtual bool + Recv__delete__() MOZ_OVERRIDE; + + virtual bool + RecvRegisterListener() MOZ_OVERRIDE; + + virtual bool + RecvUnregisterListener() MOZ_OVERRIDE; + + virtual bool + RecvDialCall(const nsString& aNumber, + const bool& aIsEmergency) MOZ_OVERRIDE; + + virtual bool + RecvHangUpCall(const uint32_t& aCallIndex) MOZ_OVERRIDE; + + virtual bool + RecvAnswerCall(const uint32_t& aCallIndex) MOZ_OVERRIDE; + + virtual bool + RecvRejectCall(const uint32_t& aCallIndex) MOZ_OVERRIDE; + + virtual bool + RecvHoldCall(const uint32_t& aCallIndex) MOZ_OVERRIDE; + + virtual bool + RecvResumeCall(const uint32_t& aCallIndex) MOZ_OVERRIDE; + + virtual bool + RecvConferenceCall() MOZ_OVERRIDE; + + virtual bool + RecvSeparateCall(const uint32_t& callIndex) MOZ_OVERRIDE; + + virtual bool + RecvHoldConference() MOZ_OVERRIDE; + + virtual bool + RecvResumeConference() MOZ_OVERRIDE; + + virtual bool + RecvStartTone(const nsString& aTone) MOZ_OVERRIDE; + + virtual bool + RecvStopTone() MOZ_OVERRIDE; + + virtual bool + RecvGetMicrophoneMuted(bool* aMuted) MOZ_OVERRIDE; + + virtual bool + RecvSetMicrophoneMuted(const bool& aMuted) MOZ_OVERRIDE; + + virtual bool + RecvGetSpeakerEnabled(bool* aEnabled) MOZ_OVERRIDE; + + virtual bool + RecvSetSpeakerEnabled(const bool& aEnabled) MOZ_OVERRIDE; + +private: + bool mActorDestroyed; + bool mRegistered; +}; + +class TelephonyRequestParent : public PTelephonyRequestParent + , public nsITelephonyListener +{ + friend class TelephonyParent; + +public: + NS_DECL_ISUPPORTS + NS_DECL_NSITELEPHONYLISTENER + +protected: + TelephonyRequestParent(); + virtual ~TelephonyRequestParent() {} + + virtual void + ActorDestroy(ActorDestroyReason why); + +private: + bool mActorDestroyed; + + bool + DoRequest(); +}; + +END_TELEPHONY_NAMESPACE + +#endif /* mozilla_dom_telephony_TelephonyParent_h */ diff --git a/dom/telephony/moz.build b/dom/telephony/moz.build index 8910a24c887..e15bf63810e 100644 --- a/dom/telephony/moz.build +++ b/dom/telephony/moz.build @@ -12,12 +12,34 @@ XPIDL_MODULE = 'dom_telephony' MODULE = 'dom' +EXPORTS.mozilla.dom.telephony += [ + 'CallEvent.h', + 'CallsList.h', + 'Telephony.h', + 'TelephonyCall.h', + 'TelephonyCallGroup.h', + 'TelephonyCommon.h', + 'TelephonyFactory.h', + 'ipc/TelephonyChild.h', + 'ipc/TelephonyParent.h', +] + CPP_SOURCES += [ 'CallEvent.cpp', 'CallsList.cpp', 'Telephony.cpp', 'TelephonyCall.cpp', 'TelephonyCallGroup.cpp', + 'TelephonyChild.cpp', + 'TelephonyFactory.cpp', + 'TelephonyIPCProvider.cpp', + 'TelephonyParent.cpp', +] + +IPDL_SOURCES += [ + 'ipc/PTelephony.ipdl', + 'ipc/PTelephonyRequest.ipdl', + 'ipc/TelephonyTypes.ipdlh' ] FAIL_ON_WARNINGS = True @@ -25,4 +47,3 @@ FAIL_ON_WARNINGS = True LIBXUL_LIBRARY = True LIBRARY_NAME = 'domtelephony_s' - diff --git a/dom/webidl/WebIDL.mk b/dom/webidl/WebIDL.mk index f18ce2bddd4..b5d7dafa936 100644 --- a/dom/webidl/WebIDL.mk +++ b/dom/webidl/WebIDL.mk @@ -34,6 +34,8 @@ webidl_files = \ BiquadFilterNode.webidl \ Blob.webidl \ BrowserElementDictionaries.webidl \ + CallEvent.webidl \ + CallsList.webidl \ CameraControl.webidl \ CameraManager.webidl \ CanvasRenderingContext2D.webidl \ @@ -359,6 +361,9 @@ webidl_files = \ SVGViewElement.webidl \ SVGZoomAndPan.webidl \ SVGZoomEvent.webidl \ + Telephony.webidl \ + TelephonyCall.webidl \ + TelephonyCallGroup.webidl \ Text.webidl \ TextDecoder.webidl \ TextEncoder.webidl \ @@ -445,12 +450,8 @@ endif ifdef MOZ_B2G_RIL webidl_files += \ - CallsList.webidl \ MozStkCommandEvent.webidl \ MozVoicemail.webidl \ - Telephony.webidl \ - TelephonyCall.webidl \ - TelephonyCallGroup.webidl \ $(NULL) endif @@ -495,7 +496,6 @@ endif ifdef MOZ_B2G_RIL webidl_files += \ - CallEvent.webidl \ CFStateChangeEvent.webidl \ DataErrorEvent.webidl \ IccCardLockErrorEvent.webidl \ diff --git a/layout/build/Makefile.in b/layout/build/Makefile.in index 0db2d8428cf..baf892dab18 100644 --- a/layout/build/Makefile.in +++ b/layout/build/Makefile.in @@ -66,6 +66,7 @@ SHARED_LIBRARY_LIBS = \ $(DEPTH)/dom/promise/$(LIB_PREFIX)dompromise_s.$(LIB_SUFFIX) \ $(DEPTH)/dom/src/notification/$(LIB_PREFIX)jsdomnotification_s.$(LIB_SUFFIX) \ $(DEPTH)/dom/system/$(LIB_PREFIX)domsystem_s.$(LIB_SUFFIX) \ + $(DEPTH)/dom/telephony/$(LIB_PREFIX)domtelephony_s.$(LIB_SUFFIX) \ $(DEPTH)/dom/workers/$(LIB_PREFIX)domworkers_s.$(LIB_SUFFIX) \ $(DEPTH)/dom/indexedDB/$(LIB_PREFIX)dom_indexeddb_s.$(LIB_SUFFIX) \ $(DEPTH)/dom/indexedDB/ipc/$(LIB_PREFIX)dom_indexeddb_ipc_s.$(LIB_SUFFIX) \ @@ -136,7 +137,6 @@ SHARED_LIBRARY_LIBS += $(DEPTH)/dom/camera/$(LIB_PREFIX)domcamera_s.$(LIB_SUFFIX ifdef MOZ_B2G_RIL #{ SHARED_LIBRARY_LIBS += \ $(DEPTH)/dom/system/gonk/$(LIB_PREFIX)domsystemgonk_s.$(LIB_SUFFIX) \ - $(DEPTH)/dom/telephony/$(LIB_PREFIX)domtelephony_s.$(LIB_SUFFIX) \ $(DEPTH)/dom/icc/src/$(LIB_PREFIX)dom_icc_s.$(LIB_SUFFIX) \ $(DEPTH)/dom/cellbroadcast/src/$(LIB_PREFIX)dom_cellbroadcast_s.$(LIB_SUFFIX) \ $(DEPTH)/dom/voicemail/$(LIB_PREFIX)domvoicemail_s.$(LIB_SUFFIX) \ diff --git a/layout/build/nsLayoutModule.cpp b/layout/build/nsLayoutModule.cpp index 1d55dd37446..6278d4b8352 100644 --- a/layout/build/nsLayoutModule.cpp +++ b/layout/build/nsLayoutModule.cpp @@ -230,6 +230,9 @@ static void Shutdown(); #include "mozilla/dom/alarm/AlarmHalService.h" #include "mozilla/dom/time/TimeService.h" +#include "mozilla/dom/telephony/TelephonyFactory.h" +#include "nsITelephonyProvider.h" + #ifdef MOZ_WIDGET_GONK #include "GonkGPSGeolocationProvider.h" #endif @@ -238,6 +241,7 @@ static void Shutdown(); using namespace mozilla; using namespace mozilla::dom; using namespace mozilla::dom::mobilemessage; +using namespace mozilla::dom::telephony; using mozilla::dom::alarm::AlarmHalService; using mozilla::dom::indexedDB::IndexedDatabaseManager; using mozilla::dom::power::PowerManagerService; @@ -338,6 +342,8 @@ NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsVolumeService, #endif NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsIMediaManagerService, MediaManager::GetInstance) +NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsITelephonyProvider, + TelephonyFactory::CreateTelephonyProvider) //----------------------------------------------------------------------------- @@ -811,6 +817,7 @@ NS_DEFINE_NAMED_CID(NS_SYNTHVOICEREGISTRY_CID); #ifdef ACCESSIBILITY NS_DEFINE_NAMED_CID(NS_ACCESSIBILITY_SERVICE_CID); #endif +NS_DEFINE_NAMED_CID(TELEPHONY_PROVIDER_CID); static nsresult CreateWindowCommandTableConstructor(nsISupports *aOuter, @@ -1093,6 +1100,7 @@ static const mozilla::Module::CIDEntry kLayoutCIDs[] = { #ifdef ACCESSIBILITY { &kNS_ACCESSIBILITY_SERVICE_CID, false, NULL, CreateA11yService }, #endif + { &kTELEPHONY_PROVIDER_CID, false, NULL, nsITelephonyProviderConstructor }, { NULL } }; @@ -1248,6 +1256,7 @@ static const mozilla::Module::ContractIDEntry kLayoutContracts[] = { { "@mozilla.org/accessibilityService;1", &kNS_ACCESSIBILITY_SERVICE_CID }, { "@mozilla.org/accessibleRetrieval;1", &kNS_ACCESSIBILITY_SERVICE_CID }, #endif + { TELEPHONY_PROVIDER_CONTRACTID, &kTELEPHONY_PROVIDER_CID }, { NULL } }; From 8fa136fecdad102c8e05285526db665c671f332c Mon Sep 17 00:00:00 2001 From: Vicamo Yang Date: Wed, 4 Sep 2013 15:53:34 +0800 Subject: [PATCH 003/171] Bug 864485 - 3/3: Gonk backend specific. r=hsinyi --- b2g/installer/package-manifest.in | 2 + dom/system/gonk/RILContentHelper.js | 231 -------- dom/system/gonk/RadioInterfaceLayer.js | 455 +-------------- dom/system/gonk/nsIRadioInterfaceLayer.idl | 12 +- dom/telephony/TelephonyFactory.cpp | 7 + dom/telephony/gonk/TelephonyProvider.js | 525 ++++++++++++++++++ dom/telephony/gonk/TelephonyProvider.manifest | 2 + dom/telephony/moz.build | 9 + dom/telephony/nsIGonkTelephonyProvider.idl | 31 ++ 9 files changed, 608 insertions(+), 666 deletions(-) create mode 100644 dom/telephony/gonk/TelephonyProvider.js create mode 100644 dom/telephony/gonk/TelephonyProvider.manifest create mode 100644 dom/telephony/nsIGonkTelephonyProvider.idl diff --git a/b2g/installer/package-manifest.in b/b2g/installer/package-manifest.in index adf1200a495..f358d9f1007 100644 --- a/b2g/installer/package-manifest.in +++ b/b2g/installer/package-manifest.in @@ -471,6 +471,8 @@ @BINPATH@/components/NetworkStatsManager.manifest @BINPATH@/components/NetworkInterfaceListService.manifest @BINPATH@/components/NetworkInterfaceListService.js +@BINPATH@/components/TelephonyProvider.manifest +@BINPATH@/components/TelephonyProvider.js #endif #ifdef MOZ_ENABLE_DBUS @BINPATH@/components/@DLL_PREFIX@dbusservice@DLL_SUFFIX@ diff --git a/dom/system/gonk/RILContentHelper.js b/dom/system/gonk/RILContentHelper.js index c0c8356895e..9edac38f150 100644 --- a/dom/system/gonk/RILContentHelper.js +++ b/dom/system/gonk/RILContentHelper.js @@ -69,17 +69,13 @@ const RIL_IPC_MSG_NAMES = [ "RIL:IccInfoChanged", "RIL:VoiceInfoChanged", "RIL:DataInfoChanged", - "RIL:EnumerateCalls", "RIL:GetAvailableNetworks", "RIL:NetworkSelectionModeChanged", "RIL:SelectNetwork", "RIL:SelectNetworkAuto", - "RIL:CallStateChanged", "RIL:EmergencyCbModeChanged", "RIL:VoicemailNotification", "RIL:VoicemailInfoChanged", - "RIL:CallError", - "RIL:SuppSvcNotification", "RIL:CardLockResult", "RIL:CardLockRetryCount", "RIL:USSDReceived", @@ -106,11 +102,9 @@ const RIL_IPC_MSG_NAMES = [ "RIL:UpdateIccContact", "RIL:SetRoamingPreference", "RIL:GetRoamingPreference", - "RIL:CdmaCallWaiting", "RIL:ExitEmergencyCbMode", "RIL:SetVoicePrivacyMode", "RIL:GetVoicePrivacyMode", - "RIL:ConferenceCallStateChanged", "RIL:OtaStatusChanged" ]; @@ -118,10 +112,6 @@ XPCOMUtils.defineLazyServiceGetter(this, "cpmm", "@mozilla.org/childprocessmessagemanager;1", "nsISyncMessageSender"); -XPCOMUtils.defineLazyServiceGetter(this, "gUUIDGenerator", - "@mozilla.org/uuid-generator;1", - "nsIUUIDGenerator"); - function MobileIccCardLockResult(options) { this.lockType = options.lockType; this.enabled = options.enabled; @@ -421,7 +411,6 @@ RILContentHelper.prototype = { QueryInterface: XPCOMUtils.generateQI([Ci.nsIMobileConnectionProvider, Ci.nsICellBroadcastProvider, Ci.nsIVoicemailProvider, - Ci.nsITelephonyProvider, Ci.nsIIccProvider, Ci.nsIObserver, Ci.nsISupportsWeakReference]), @@ -431,7 +420,6 @@ RILContentHelper.prototype = { interfaces: [Ci.nsIMobileConnectionProvider, Ci.nsICellBroadcastProvider, Ci.nsIVoicemailProvider, - Ci.nsITelephonyProvider, Ci.nsIIccProvider]}), // An utility function to copy objects. @@ -1224,11 +1212,9 @@ RILContentHelper.prototype = { }, _mobileConnectionListeners: null, - _telephonyListeners: null, _cellBroadcastListeners: null, _voicemailListeners: null, _iccListeners: null, - _enumerateTelephonyCallbacks: null, voicemailStatus: null, @@ -1290,24 +1276,6 @@ RILContentHelper.prototype = { this.unregisterListener("_mobileConnectionListeners", listener); }, - registerTelephonyMsg: function registerTelephonyMsg(listener) { - debug("Registering for telephony-related messages"); - this.registerListener("_telephonyListeners", listener); - cpmm.sendAsyncMessage("RIL:RegisterTelephonyMsg"); - }, - - unregisterTelephonyMsg: function unregisteTelephonyMsg(listener) { - this.unregisterListener("_telephonyListeners", listener); - - // We also need to make sure the listener is removed from - // _enumerateTelephonyCallbacks. - let index = this._enumerateTelephonyCallbacks.indexOf(listener); - if (index != -1) { - this._enumerateTelephonyCallbacks.splice(index, 1); - if (DEBUG) debug("Unregistered enumerateTelephony callback: " + listener); - } - }, - registerVoicemailMsg: function registerVoicemailMsg(listener) { debug("Registering for voicemail-related messages"); this.registerListener("_voicemailListeners", listener); @@ -1338,135 +1306,6 @@ RILContentHelper.prototype = { this.unregisterListener("_iccListeners", listener); }, - enumerateCalls: function enumerateCalls(callback) { - debug("Requesting enumeration of calls for callback: " + callback); - // We need 'requestId' to meet the 'RILContentHelper <--> RadioInterfaceLayer' - // protocol. - let requestId = this._getRandomId(); - cpmm.sendAsyncMessage("RIL:EnumerateCalls", { - clientId: 0, - data: { - requestId: requestId - } - }); - if (!this._enumerateTelephonyCallbacks) { - this._enumerateTelephonyCallbacks = []; - } - this._enumerateTelephonyCallbacks.push(callback); - }, - - startTone: function startTone(dtmfChar) { - debug("Sending Tone for " + dtmfChar); - cpmm.sendAsyncMessage("RIL:StartTone", { - clientId: 0, - data: dtmfChar - }); - }, - - stopTone: function stopTone() { - debug("Stopping Tone"); - cpmm.sendAsyncMessage("RIL:StopTone", {clientId: 0}); - }, - - dial: function dial(number) { - debug("Dialing " + number); - cpmm.sendAsyncMessage("RIL:Dial", { - clientId: 0, - data: number - }); - }, - - dialEmergency: function dialEmergency(number) { - debug("Dialing emergency " + number); - cpmm.sendAsyncMessage("RIL:DialEmergency", { - clientId: 0, - data: number - }); - }, - - hangUp: function hangUp(callIndex) { - debug("Hanging up call no. " + callIndex); - cpmm.sendAsyncMessage("RIL:HangUp", { - clientId: 0, - data: callIndex - }); - }, - - answerCall: function answerCall(callIndex) { - cpmm.sendAsyncMessage("RIL:AnswerCall", { - clientId: 0, - data: callIndex - }); - }, - - rejectCall: function rejectCall(callIndex) { - cpmm.sendAsyncMessage("RIL:RejectCall", { - clientId: 0, - data: callIndex - }); - }, - - holdCall: function holdCall(callIndex) { - cpmm.sendAsyncMessage("RIL:HoldCall", { - clientId: 0, - data: callIndex - }); - }, - - resumeCall: function resumeCall(callIndex) { - cpmm.sendAsyncMessage("RIL:ResumeCall", { - clientId: 0, - data: callIndex - }); - }, - - conferenceCall: function conferenceCall() { - cpmm.sendAsyncMessage("RIL:ConferenceCall", { - clientId: 0 - }); - }, - - separateCall: function separateCall(callIndex) { - cpmm.sendAsyncMessage("RIL:SeparateCall", { - clientId: 0, - data: callIndex - }); - }, - - holdConference: function holdConference() { - cpmm.sendAsyncMessage("RIL:HoldConference", { - clientId: 0 - }); - }, - - resumeConference: function resumeConference() { - cpmm.sendAsyncMessage("RIL:ResumeConference", { - clientId: 0 - }); - }, - - get microphoneMuted() { - return cpmm.sendSyncMessage("RIL:GetMicrophoneMuted", {clientId: 0})[0]; - }, - - set microphoneMuted(value) { - cpmm.sendAsyncMessage("RIL:SetMicrophoneMuted", { - clientId: 0, - data: value - }); - }, - - get speakerEnabled() { - return cpmm.sendSyncMessage("RIL:GetSpeakerEnabled", {clientId: 0})[0]; - }, - - set speakerEnabled(value) { - cpmm.sendAsyncMessage("RIL:SetSpeakerEnabled", { - clientId: 0, - data: value - }); - }, - // nsIObserver observe: function observe(subject, topic, data) { @@ -1563,9 +1402,6 @@ RILContentHelper.prototype = { "notifyOtaStatusChanged", [msg.json.data]); break; - case "RIL:EnumerateCalls": - this.handleEnumerateCalls(msg.json.calls); - break; case "RIL:GetAvailableNetworks": this.handleGetAvailableNetworks(msg.json); break; @@ -1580,35 +1416,6 @@ RILContentHelper.prototype = { this.handleSelectNetwork(msg.json, RIL.GECKO_NETWORK_SELECTION_AUTOMATIC); break; - case "RIL:CallStateChanged": { - let data = msg.json.data; - this._deliverEvent("_telephonyListeners", - "callStateChanged", - [data.callIndex, data.state, - data.number, data.isActive, - data.isOutgoing, data.isEmergency, - data.isConference]); - break; - } - case "RIL:ConferenceCallStateChanged": { - let data = msg.json.data; - this._deliverEvent("_telephonyListeners", - "conferenceCallStateChanged", - [data]); - break; - } - case "RIL:CallError": { - let data = msg.json.data; - this._deliverEvent("_telephonyListeners", - "notifyError", - [data.callIndex, data.errorMsg]); - break; - } - case "RIL:SuppSvcNotification": - this._deliverEvent("_telephonyListeners", - "supplementaryServiceNotification", - [msg.json.callIndex, msg.json.notification]); - break; case "RIL:VoicemailNotification": this.handleVoicemailNotification(msg.json.data); break; @@ -1729,11 +1536,6 @@ RILContentHelper.prototype = { this.handleSimpleRequest(msg.json.requestId, msg.json.errorMsg, msg.json.mode); break; - case "RIL:CdmaCallWaiting": - this._deliverEvent("_telephonyListeners", - "notifyCdmaCallWaiting", - [msg.json.data]); - break; case "RIL:ExitEmergencyCbMode": this.handleExitEmergencyCbMode(msg.json); break; @@ -1753,35 +1555,6 @@ RILContentHelper.prototype = { } }, - handleEnumerateCalls: function handleEnumerateCalls(calls) { - debug("handleEnumerateCalls: " + JSON.stringify(calls)); - let callback = this._enumerateTelephonyCallbacks.shift(); - if (!calls.length) { - callback.enumerateCallStateComplete(); - return; - } - - for (let i in calls) { - let call = calls[i]; - let keepGoing; - try { - keepGoing = - callback.enumerateCallState(call.callIndex, call.state, call.number, - call.isActive, call.isOutgoing, - call.isEmergency, call.isConference); - } catch (e) { - debug("callback handler for 'enumerateCallState' threw an " + - " exception: " + e); - keepGoing = true; - } - if (!keepGoing) { - break; - } - } - - callback.enumerateCallStateComplete(); - }, - handleSimpleRequest: function handleSimpleRequest(requestId, errorMsg, result) { if (errorMsg) { this.fireRequestError(requestId, errorMsg); @@ -1994,10 +1767,6 @@ RILContentHelper.prototype = { } }, - _getRandomId: function _getRandomId() { - return gUUIDGenerator.generateUUID().toString(); - }, - _deliverEvent: function _deliverEvent(listenerType, name, args) { let thisListeners = this[listenerType]; if (!thisListeners) { diff --git a/dom/system/gonk/RadioInterfaceLayer.js b/dom/system/gonk/RadioInterfaceLayer.js index fb5c06529fc..937a033c4b9 100644 --- a/dom/system/gonk/RadioInterfaceLayer.js +++ b/dom/system/gonk/RadioInterfaceLayer.js @@ -46,9 +46,6 @@ const RADIOINTERFACE_CID = const RILNETWORKINTERFACE_CID = Components.ID("{3bdd52a9-3965-4130-b569-0ac5afed045e}"); -const nsIAudioManager = Ci.nsIAudioManager; -const nsITelephonyProvider = Ci.nsITelephonyProvider; - const kNetworkInterfaceStateChangedTopic = "network-interface-state-changed"; const kSmsReceivedObserverTopic = "sms-received"; const kSilentSmsReceivedObserverTopic = "silent-sms-received"; @@ -73,30 +70,7 @@ const DOM_MOBILE_MESSAGE_DELIVERY_SENDING = "sending"; const DOM_MOBILE_MESSAGE_DELIVERY_SENT = "sent"; const DOM_MOBILE_MESSAGE_DELIVERY_ERROR = "error"; -const CALL_WAKELOCK_TIMEOUT = 5000; -const RADIO_POWER_OFF_TIMEOUT = 30000; - -const RIL_IPC_TELEPHONY_MSG_NAMES = [ - "RIL:EnumerateCalls", - "RIL:GetMicrophoneMuted", - "RIL:SetMicrophoneMuted", - "RIL:GetSpeakerEnabled", - "RIL:SetSpeakerEnabled", - "RIL:StartTone", - "RIL:StopTone", - "RIL:Dial", - "RIL:DialEmergency", - "RIL:HangUp", - "RIL:AnswerCall", - "RIL:RejectCall", - "RIL:HoldCall", - "RIL:ResumeCall", - "RIL:RegisterTelephonyMsg", - "RIL:ConferenceCall", - "RIL:SeparateCall", - "RIL:HoldConference", - "RIL:ResumeConference" -]; +const RADIO_POWER_OFF_TIMEOUT = 30000; const RIL_IPC_MOBILECONNECTION_MSG_NAMES = [ "RIL:GetRilContext", @@ -188,6 +162,10 @@ XPCOMUtils.defineLazyServiceGetter(this, "gSystemWorkerManager", "@mozilla.org/telephony/system-worker-manager;1", "nsISystemWorkerManager"); +XPCOMUtils.defineLazyServiceGetter(this, "gTelephonyProvider", + "@mozilla.org/telephony/telephonyprovider;1", + "nsIGonkTelephonyProvider"); + XPCOMUtils.defineLazyGetter(this, "WAP", function () { let wap = {}; Cu.import("resource://gre/modules/WapPushManager.js", wap); @@ -200,64 +178,6 @@ XPCOMUtils.defineLazyGetter(this, "PhoneNumberUtils", function () { return ns.PhoneNumberUtils; }); -function convertRILCallState(state) { - switch (state) { - case RIL.CALL_STATE_ACTIVE: - return nsITelephonyProvider.CALL_STATE_CONNECTED; - case RIL.CALL_STATE_HOLDING: - return nsITelephonyProvider.CALL_STATE_HELD; - case RIL.CALL_STATE_DIALING: - return nsITelephonyProvider.CALL_STATE_DIALING; - case RIL.CALL_STATE_ALERTING: - return nsITelephonyProvider.CALL_STATE_ALERTING; - case RIL.CALL_STATE_INCOMING: - case RIL.CALL_STATE_WAITING: - return nsITelephonyProvider.CALL_STATE_INCOMING; - default: - throw new Error("Unknown rilCallState: " + state); - } -} - -function convertRILSuppSvcNotification(notification) { - switch (notification) { - case RIL.GECKO_SUPP_SVC_NOTIFICATION_REMOTE_HELD: - return nsITelephonyProvider.NOTIFICATION_REMOTE_HELD; - case RIL.GECKO_SUPP_SVC_NOTIFICATION_REMOTE_RESUMED: - return nsITelephonyProvider.NOTIFICATION_REMOTE_RESUMED; - default: - throw new Error("Unknown rilSuppSvcNotification: " + notification); - } -} - -/** - * Fake nsIAudioManager implementation so that we can run the telephony - * code in a non-Gonk build. - */ -let FakeAudioManager = { - microphoneMuted: false, - masterVolume: 1.0, - masterMuted: false, - phoneState: nsIAudioManager.PHONE_STATE_CURRENT, - _forceForUse: {}, - setForceForUse: function setForceForUse(usage, force) { - this._forceForUse[usage] = force; - }, - getForceForUse: function setForceForUse(usage) { - return this._forceForUse[usage] || nsIAudioManager.FORCE_NONE; - } -}; - -XPCOMUtils.defineLazyGetter(this, "gAudioManager", function getAudioManager() { - try { - return Cc["@mozilla.org/telephony/audiomanager;1"] - .getService(nsIAudioManager); - } catch (ex) { - //TODO on the phone this should not fall back as silently. - if (DEBUG) debug("Using fake audio manager."); - return FakeAudioManager; - } -}); - XPCOMUtils.defineLazyGetter(this, "gMessageManager", function () { return { QueryInterface: XPCOMUtils.generateQI([Ci.nsIMessageListener, @@ -290,9 +210,6 @@ XPCOMUtils.defineLazyGetter(this, "gMessageManager", function () { _registerMessageListeners: function _registerMessageListeners() { ppmm.addMessageListener("child-process-shutdown", this); - for (let msgname of RIL_IPC_TELEPHONY_MSG_NAMES) { - ppmm.addMessageListener(msgname, this); - } for (let msgname of RIL_IPC_MOBILECONNECTION_MSG_NAMES) { ppmm.addMessageListener(msgname, this); } @@ -309,9 +226,6 @@ XPCOMUtils.defineLazyGetter(this, "gMessageManager", function () { _unregisterMessageListeners: function _unregisterMessageListeners() { ppmm.removeMessageListener("child-process-shutdown", this); - for (let msgname of RIL_IPC_TELEPHONY_MSG_NAMES) { - ppmm.removeMessageListener(msgname, this); - } for (let msgname of RIL_IPC_MOBILECONNECTION_MSG_NAMES) { ppmm.removeMessageListener(msgname, this); } @@ -430,15 +344,7 @@ XPCOMUtils.defineLazyGetter(this, "gMessageManager", function () { return; } - if (RIL_IPC_TELEPHONY_MSG_NAMES.indexOf(msg.name) != -1) { - if (!msg.target.assertPermission("telephony")) { - if (DEBUG) { - debug("Telephony message " + msg.name + - " from a content process with no 'telephony' privileges."); - } - return null; - } - } else if (RIL_IPC_MOBILECONNECTION_MSG_NAMES.indexOf(msg.name) != -1) { + if (RIL_IPC_MOBILECONNECTION_MSG_NAMES.indexOf(msg.name) != -1) { if (!msg.target.assertPermission("mobileconnection")) { if (DEBUG) { debug("MobileConnection message " + msg.name + @@ -476,9 +382,6 @@ XPCOMUtils.defineLazyGetter(this, "gMessageManager", function () { } switch (msg.name) { - case "RIL:RegisterTelephonyMsg": - this._registerMessageTarget("telephony", msg.target); - return; case "RIL:RegisterMobileConnectionMsg": this._registerMessageTarget("mobileconnection", msg.target); return; @@ -519,13 +422,6 @@ XPCOMUtils.defineLazyGetter(this, "gMessageManager", function () { } }, - sendTelephonyMessage: function sendTelephonyMessage(message, clientId, data) { - this._sendTargetMessage("telephony", message, { - clientId: clientId, - data: data - }); - }, - sendMobileConnectionMessage: function sendMobileConnectionMessage(message, clientId, data) { this._sendTargetMessage("mobileconnection", message, { clientId: clientId, @@ -894,61 +790,6 @@ RadioInterface.prototype = { case "RIL:GetRilContext": // This message is sync. return this.rilContext; - case "RIL:EnumerateCalls": - this.enumerateCalls(msg.target, msg.json.data); - break; - case "RIL:GetMicrophoneMuted": - // This message is sync. - return this.microphoneMuted; - case "RIL:SetMicrophoneMuted": - this.microphoneMuted = msg.json.data; - break; - case "RIL:GetSpeakerEnabled": - // This message is sync. - return this.speakerEnabled; - case "RIL:SetSpeakerEnabled": - this.speakerEnabled = msg.json.data; - break; - case "RIL:StartTone": - this.workerMessenger.send("startTone", { dtmfChar: msg.json.data }); - break; - case "RIL:StopTone": - this.workerMessenger.send("stopTone"); - break; - case "RIL:Dial": - this.dial(msg.json.data); - break; - case "RIL:DialEmergency": - this.dialEmergency(msg.json.data); - break; - case "RIL:HangUp": - this.workerMessenger.send("hangUp", { callIndex: msg.json.data }); - break; - case "RIL:AnswerCall": - this.workerMessenger.send("answerCall", { callIndex: msg.json.data }); - break; - case "RIL:RejectCall": - this.workerMessenger.send("rejectCall", { callIndex: msg.json.data }); - break; - case "RIL:HoldCall": - this.workerMessenger.send("holdCall", { callIndex: msg.json.data }); - break; - case "RIL:ResumeCall": - this.workerMessenger.send("resumeCall", { callIndex: msg.json.data }); - break; - case "RIL:ConferenceCall": - this.workerMessenger.send("conferenceCall"); - break; - case "RIL:SeparateCall": - this.workerMessenger.send("separateCall", - { callIndex: msg.json.data }); - break; - case "RIL:HoldConference": - this.workerMessenger.send("holdConference"); - break; - case "RIL:ResumeConference": - this.workerMessenger.send("resumeConference"); - break; case "RIL:GetAvailableNetworks": this.workerMessenger.sendWithIPCMessage(msg, "getAvailableNetworks"); break; @@ -1058,28 +899,26 @@ RadioInterface.prototype = { handleUnsolicitedWorkerMessage: function handleUnsolicitedWorkerMessage(message) { switch (message.rilMessageType) { case "callRing": - this.handleCallRing(); + gTelephonyProvider.notifyCallRing(); break; case "callStateChange": - // This one will handle its own notifications. - this.handleCallStateChange(message.call); + gTelephonyProvider.notifyCallStateChanged(message.call); break; case "callDisconnected": - // This one will handle its own notifications. - this.handleCallDisconnected(message.call); + gTelephonyProvider.notifyCallDisconnected(message.call); break; case "conferenceCallStateChanged": - this.handleConferenceCallStateChanged(message.state); + gTelephonyProvider.notifyConferenceCallStateChanged(message.state); break; case "cdmaCallWaiting": - gMessageManager.sendTelephonyMessage("RIL:CdmaCallWaiting", - this.clientId, message.number); + gTelephonyProvider.notifyCdmaCallWaiting(message.number); break; case "callError": - this.handleCallError(message); + gTelephonyProvider.notifyCallError(message.callIndex, message.errorMsg); break; case "suppSvcNotification": - this.handleSuppSvcNotification(message); + gTelephonyProvider.notifySupplementaryService(message.callIndex, + message.notification); break; case "emergencyCbModeChange": this.handleEmergencyCbModeChange(message); @@ -1727,165 +1566,6 @@ RadioInterface.prototype = { this.setupDataCallByType("default"); }, - /** - * Track the active call and update the audio system as its state changes. - */ - _activeCall: null, - updateCallAudioState: function updateCallAudioState(options) { - if (options.conferenceState === nsITelephonyProvider.CALL_STATE_CONNECTED) { - gAudioManager.phoneState = nsIAudioManager.PHONE_STATE_IN_CALL; - if (this.speakerEnabled) { - gAudioManager.setForceForUse(nsIAudioManager.USE_COMMUNICATION, - nsIAudioManager.FORCE_SPEAKER); - } - return; - } - if (options.conferenceState === nsITelephonyProvider.CALL_STATE_UNKNOWN || - options.conferenceState === nsITelephonyProvider.CALL_STATE_HELD) { - if (!this._activeCall) { - gAudioManager.phoneState = nsIAudioManager.PHONE_STATE_NORMAL; - } - return; - } - - if (!options.call) { - return; - } - - if (options.call.isConference) { - if (this._activeCall && this._activeCall.callIndex == options.call.callIndex) { - this._activeCall = null; - } - return; - } - - let call = options.call; - switch (call.state) { - case nsITelephonyProvider.CALL_STATE_DIALING: // Fall through... - case nsITelephonyProvider.CALL_STATE_ALERTING: - case nsITelephonyProvider.CALL_STATE_CONNECTED: - call.isActive = true; - this._activeCall = call; - gAudioManager.phoneState = nsIAudioManager.PHONE_STATE_IN_CALL; - if (this.speakerEnabled) { - gAudioManager.setForceForUse(nsIAudioManager.USE_COMMUNICATION, - nsIAudioManager.FORCE_SPEAKER); - } - if (DEBUG) { - this.debug("Active call, put audio system into PHONE_STATE_IN_CALL: " - + gAudioManager.phoneState); - } - break; - case nsITelephonyProvider.CALL_STATE_INCOMING: - call.isActive = false; - if (!this._activeCall) { - // We can change the phone state into RINGTONE only when there's - // no active call. - gAudioManager.phoneState = nsIAudioManager.PHONE_STATE_RINGTONE; - if (DEBUG) { - this.debug("Incoming call, put audio system into " + - "PHONE_STATE_RINGTONE: " + gAudioManager.phoneState); - } - } - break; - case nsITelephonyProvider.CALL_STATE_HELD: // Fall through... - case nsITelephonyProvider.CALL_STATE_DISCONNECTED: - call.isActive = false; - if (this._activeCall && - this._activeCall.callIndex == call.callIndex) { - // Previously active call is not active now. - this._activeCall = null; - } - - if (!this._activeCall) { - // No active call. Disable the audio. - gAudioManager.phoneState = nsIAudioManager.PHONE_STATE_NORMAL; - if (DEBUG) { - this.debug("No active call, put audio system into " + - "PHONE_STATE_NORMAL: " + gAudioManager.phoneState); - } - } - break; - } - }, - - _callRingWakeLock: null, - _callRingWakeLockTimer: null, - _cancelCallRingWakeLockTimer: function _cancelCallRingWakeLockTimer() { - if (this._callRingWakeLockTimer) { - this._callRingWakeLockTimer.cancel(); - } - if (this._callRingWakeLock) { - this._callRingWakeLock.unlock(); - this._callRingWakeLock = null; - } - }, - - /** - * Handle an incoming call. - * - * Not much is known about this call at this point, but it's enough - * to start bringing up the Phone app already. - */ - handleCallRing: function handleCallRing() { - if (!this._callRingWakeLock) { - this._callRingWakeLock = gPowerManagerService.newWakeLock("cpu"); - } - if (!this._callRingWakeLockTimer) { - this._callRingWakeLockTimer = - Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - } - this._callRingWakeLockTimer - .initWithCallback(this._cancelCallRingWakeLockTimer.bind(this), - CALL_WAKELOCK_TIMEOUT, Ci.nsITimer.TYPE_ONE_SHOT); - - gSystemMessenger.broadcastMessage("telephony-new-call", {}); - }, - - /** - * Handle call state changes by updating our current state and the audio - * system. - */ - handleCallStateChange: function handleCallStateChange(call) { - if (DEBUG) this.debug("handleCallStateChange: " + JSON.stringify(call)); - call.state = convertRILCallState(call.state); - - if (call.state == nsITelephonyProvider.CALL_STATE_DIALING) { - gSystemMessenger.broadcastMessage("telephony-new-call", {}); - } - this.updateCallAudioState({call: call}); - gMessageManager.sendTelephonyMessage("RIL:CallStateChanged", - this.clientId, call); - }, - - /** - * Handle call disconnects by updating our current state and the audio system. - */ - handleCallDisconnected: function handleCallDisconnected(call) { - if (DEBUG) this.debug("handleCallDisconnected: " + JSON.stringify(call)); - call.state = nsITelephonyProvider.CALL_STATE_DISCONNECTED; - let duration = ("started" in call && typeof call.started == "number") ? - new Date().getTime() - call.started : 0; - let data = { - number: call.number, - duration: duration, - direction: call.isOutgoing ? "outgoing" : "incoming" - }; - gSystemMessenger.broadcastMessage("telephony-call-ended", data); - this.updateCallAudioState({call: call}); - gMessageManager.sendTelephonyMessage("RIL:CallStateChanged", - this.clientId, call); - }, - - handleConferenceCallStateChanged: function handleConferenceCallStateChanged(state) { - debug("handleConferenceCallStateChanged: " + state); - state = state != null ? convertRILCallState(state) : - nsITelephonyProvider.CALL_STATE_UNKNOWN; - this.updateCallAudioState({conferenceState: state}); - gMessageManager.sendTelephonyMessage("RIL:ConferenceCallStateChanged", - this.clientId, state); - }, - /** * Update network selection mode */ @@ -1905,23 +1585,6 @@ RadioInterface.prototype = { this.clientId, message); }, - /** - * Handle call error. - */ - handleCallError: function handleCallError(message) { - gMessageManager.sendTelephonyMessage("RIL:CallError", - this.clientId, message); - }, - - /** - * Handle supplementary service notification. - */ - handleSuppSvcNotification: function handleSuppSvcNotification(message) { - message.notification = convertRILSuppSvcNotification(message.notification); - gMessageManager.sendTelephonyMessage("RIL:SuppSvcNotification", - this.clientId, message); - }, - /** * Handle WDP port push PDU. Constructor WDP bearer information and deliver * to WapPushManager. @@ -2316,8 +1979,6 @@ RadioInterface.prototype = { } break; case "xpcom-shutdown": - // Cancel the timer for the call-ring wake lock. - this._cancelCallRingWakeLockTimer(); // Shutdown all RIL network interfaces for each (let apnSetting in this.apnSettings.byAPN) { if (apnSetting.iface) { @@ -2467,56 +2128,6 @@ RadioInterface.prototype = { // Handle phone functions of nsIRILContentHelper - enumerateCalls: function enumerateCalls(target, message) { - if (DEBUG) this.debug("Requesting enumeration of calls for callback"); - this.workerMessenger.send("enumerateCalls", message, (function(response) { - for (let call of response.calls) { - call.state = convertRILCallState(call.state); - call.isActive = this._activeCall ? - call.callIndex == this._activeCall.callIndex : false; - } - target.sendAsyncMessage("RIL:EnumerateCalls", response); - return false; - }).bind(this)); - }, - - _validateNumber: function _validateNumber(number) { - // note: isPlainPhoneNumber also accepts USSD and SS numbers - if (PhoneNumberUtils.isPlainPhoneNumber(number)) { - return true; - } - - this.handleCallError({ - callIndex: -1, - errorMsg: RIL.RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[RIL.CALL_FAIL_UNOBTAINABLE_NUMBER] - }); - if (DEBUG) { - this.debug("Number '" + number + "' doesn't seem to be a viable number." + - " Drop."); - } - - return false; - }, - - dial: function dial(number) { - if (DEBUG) this.debug("Dialing " + number); - number = PhoneNumberUtils.normalize(number); - if (this._validateNumber(number)) { - this.workerMessenger.send("dial", { number: number, - isDialEmergency: false }); - } - }, - - dialEmergency: function dialEmergency(number) { - if (DEBUG) this.debug("Dialing emergency " + number); - // we don't try to be too clever here, as the phone is probably in the - // locked state. Let's just check if it's a number without normalizing - if (this._validateNumber(number)) { - this.workerMessenger.send("dial", { number: number, - isDialEmergency: true }); - } - }, - _sendCfStateChanged: function _sendCfStateChanged(message) { gMessageManager.sendMobileConnectionMessage("RIL:CfStateChanged", this.clientId, message); @@ -2571,37 +2182,6 @@ RadioInterface.prototype = { }).bind(this)); }, - get microphoneMuted() { - return gAudioManager.microphoneMuted; - }, - set microphoneMuted(value) { - if (value == this.microphoneMuted) { - return; - } - gAudioManager.microphoneMuted = value; - - if (!this._activeCall) { - gAudioManager.phoneState = nsIAudioManager.PHONE_STATE_NORMAL; - } - }, - - get speakerEnabled() { - return (gAudioManager.getForceForUse(nsIAudioManager.USE_COMMUNICATION) == - nsIAudioManager.FORCE_SPEAKER); - }, - set speakerEnabled(value) { - if (value == this.speakerEnabled) { - return; - } - let force = value ? nsIAudioManager.FORCE_SPEAKER : - nsIAudioManager.FORCE_NONE; - gAudioManager.setForceForUse(nsIAudioManager.USE_COMMUNICATION, force); - - if (!this._activeCall) { - gAudioManager.phoneState = nsIAudioManager.PHONE_STATE_NORMAL; - } - }, - /** * List of tuples of national language identifier pairs. * @@ -3368,6 +2948,13 @@ RadioInterface.prototype = { this.workerMessenger.send("deactivateDataCall", { cid: cid, reason: reason }); }, + + sendWorkerMessage: function sendWorkerMessage(rilMessageType, message, + callback) { + this.workerMessenger.send(rilMessageType, message, function (response) { + return callback.handleResponse(response); + }); + } }; function RILNetworkInterface(radioInterface, apnSetting) { diff --git a/dom/system/gonk/nsIRadioInterfaceLayer.idl b/dom/system/gonk/nsIRadioInterfaceLayer.idl index 3b226a1eee4..c9c7eeb51ae 100644 --- a/dom/system/gonk/nsIRadioInterfaceLayer.idl +++ b/dom/system/gonk/nsIRadioInterfaceLayer.idl @@ -79,7 +79,13 @@ interface nsIRilContext : nsISupports readonly attribute nsIDOMMozMobileConnectionInfo data; }; -[scriptable, uuid(5efcd358-080e-46d6-a7f7-4f36c204eec3)] +[scriptable, function, uuid(3bc96351-53b0-47a1-a888-c74c64b60f25)] +interface nsIRilSendWorkerMessageCallback : nsISupports +{ + boolean handleResponse(in jsval response); +}; + +[scriptable, uuid(61a8ca67-6113-4cd0-b443-e045f09863ed)] interface nsIRadioInterface : nsISupports { readonly attribute nsIRilContext rilContext; @@ -105,6 +111,10 @@ interface nsIRadioInterface : nsISupports in DOMString message, in boolean silent, in nsIMobileMessageCallback request); + + void sendWorkerMessage(in DOMString type, + [optional] in jsval message, + [optional] in nsIRilSendWorkerMessageCallback callback); }; [scriptable, uuid(44b03951-1444-4c03-bd37-0bcb3a01b56f)] diff --git a/dom/telephony/TelephonyFactory.cpp b/dom/telephony/TelephonyFactory.cpp index cdb2b88dd86..dacfb001836 100644 --- a/dom/telephony/TelephonyFactory.cpp +++ b/dom/telephony/TelephonyFactory.cpp @@ -4,6 +4,9 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "mozilla/dom/telephony/TelephonyFactory.h" +#ifdef MOZ_WIDGET_GONK +#include "nsIGonkTelephonyProvider.h" +#endif #include "nsServiceManagerUtils.h" #include "nsXULAppAPI.h" #include "TelephonyIPCProvider.h" @@ -17,6 +20,10 @@ TelephonyFactory::CreateTelephonyProvider() if (XRE_GetProcessType() == GeckoProcessType_Content) { provider = new TelephonyIPCProvider(); +#ifdef MOZ_WIDGET_GONK + } else { + provider = do_CreateInstance(GONK_TELEPHONY_PROVIDER_CONTRACTID); +#endif } return provider.forget(); diff --git a/dom/telephony/gonk/TelephonyProvider.js b/dom/telephony/gonk/TelephonyProvider.js new file mode 100644 index 00000000000..0629f5cdea5 --- /dev/null +++ b/dom/telephony/gonk/TelephonyProvider.js @@ -0,0 +1,525 @@ +/* -*- Mode: js; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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/. */ + +"use strict"; + +const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; + +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); +Cu.import("resource://gre/modules/Services.jsm"); + +var RIL = {}; +Cu.import("resource://gre/modules/ril_consts.js", RIL); + +const GONK_TELEPHONYPROVIDER_CONTRACTID = + "@mozilla.org/telephony/gonktelephonyprovider;1"; +const GONK_TELEPHONYPROVIDER_CID = + Components.ID("{67d26434-d063-4d28-9f48-5b3189788155}"); + +const kPrefenceChangedObserverTopic = "nsPref:changed"; +const kXpcomShutdownObserverTopic = "xpcom-shutdown"; + +const nsIAudioManager = Ci.nsIAudioManager; +const nsITelephonyProvider = Ci.nsITelephonyProvider; + +const CALL_WAKELOCK_TIMEOUT = 5000; + +let DEBUG; +function debug(s) { + dump("TelephonyProvider: " + s + "\n"); +} + +XPCOMUtils.defineLazyGetter(this, "gAudioManager", function getAudioManager() { + try { + return Cc["@mozilla.org/telephony/audiomanager;1"] + .getService(nsIAudioManager); + } catch (ex) { + //TODO on the phone this should not fall back as silently. + + // Fake nsIAudioManager implementation so that we can run the telephony + // code in a non-Gonk build. + if (DEBUG) debug("Using fake audio manager."); + return { + microphoneMuted: false, + masterVolume: 1.0, + masterMuted: false, + phoneState: nsIAudioManager.PHONE_STATE_CURRENT, + _forceForUse: {}, + + setForceForUse: function setForceForUse(usage, force) { + this._forceForUse[usage] = force; + }, + + getForceForUse: function setForceForUse(usage) { + return this._forceForUse[usage] || nsIAudioManager.FORCE_NONE; + } + }; + } +}); + +XPCOMUtils.defineLazyServiceGetter(this, "gPowerManagerService", + "@mozilla.org/power/powermanagerservice;1", + "nsIPowerManagerService"); + +XPCOMUtils.defineLazyServiceGetter(this, "gSystemMessenger", + "@mozilla.org/system-message-internal;1", + "nsISystemMessagesInternal"); + +XPCOMUtils.defineLazyGetter(this, "gRadioInterface", function () { + let ril = Cc["@mozilla.org/ril;1"].getService(Ci["nsIRadioInterfaceLayer"]); + // TODO: Bug 854326 - B2G Multi-SIM: support multiple SIM cards for SMS/MMS + return ril.getRadioInterface(0); +}); + +XPCOMUtils.defineLazyGetter(this, "gPhoneNumberUtils", function () { + let ns = {}; + Cu.import("resource://gre/modules/PhoneNumberUtils.jsm", ns); + return ns.PhoneNumberUtils; +}); + +function TelephonyProvider() { + this._listeners = []; + + this._updateDebugFlag(); + + Services.obs.addObserver(this, kPrefenceChangedObserverTopic, false); + Services.obs.addObserver(this, kXpcomShutdownObserverTopic, false); +} +TelephonyProvider.prototype = { + classID: GONK_TELEPHONYPROVIDER_CID, + classInfo: XPCOMUtils.generateCI({classID: GONK_TELEPHONYPROVIDER_CID, + contractID: GONK_TELEPHONYPROVIDER_CONTRACTID, + classDescription: "TelephonyProvider", + interfaces: [Ci.nsITelephonyProvider, + Ci.nsIGonkTelephonyProvider], + flags: Ci.nsIClassInfo.SINGLETON}), + QueryInterface: XPCOMUtils.generateQI([Ci.nsITelephonyProvider, + Ci.nsIGonkTelephonyProvider, + Ci.nsIObserver]), + + _callRingWakeLock: null, + _callRingWakeLockTimer: null, + _cancelCallRingWakeLockTimer: function _cancelCallRingWakeLockTimer() { + if (this._callRingWakeLockTimer) { + this._callRingWakeLockTimer.cancel(); + } + if (this._callRingWakeLock) { + this._callRingWakeLock.unlock(); + this._callRingWakeLock = null; + } + }, + + // An array of nsITelephonyListener instances. + _listeners: null, + _notifyAllListeners: function _notifyAllListeners(aMethodName, aArgs) { + let listeners = this._listeners.slice(); + for (let listener of listeners) { + if (this._listeners.indexOf(listener) == -1) { + // Listener has been unregistered in previous run. + continue; + } + + let handler = listener[aMethodName]; + try { + handler.apply(listener, aArgs); + } catch (e) { + debug("listener for " + aMethodName + " threw an exception: " + e); + } + } + }, + + /** + * Track the active call and update the audio system as its state changes. + */ + _activeCall: null, + _updateCallAudioState: function _updateCallAudioState(aCall, + aConferenceState) { + if (aConferenceState === nsITelephonyProvider.CALL_STATE_CONNECTED) { + gAudioManager.phoneState = nsIAudioManager.PHONE_STATE_IN_CALL; + if (this.speakerEnabled) { + gAudioManager.setForceForUse(nsIAudioManager.USE_COMMUNICATION, + nsIAudioManager.FORCE_SPEAKER); + } + return; + } + if (aConferenceState === nsITelephonyProvider.CALL_STATE_UNKNOWN || + aConferenceState === nsITelephonyProvider.CALL_STATE_HELD) { + if (!this._activeCall) { + gAudioManager.phoneState = nsIAudioManager.PHONE_STATE_NORMAL; + } + return; + } + + if (!aCall) { + return; + } + + if (aCall.isConference) { + if (this._activeCall && this._activeCall.callIndex == aCall.callIndex) { + this._activeCall = null; + } + return; + } + + switch (aCall.state) { + case nsITelephonyProvider.CALL_STATE_DIALING: // Fall through... + case nsITelephonyProvider.CALL_STATE_ALERTING: + case nsITelephonyProvider.CALL_STATE_CONNECTED: + aCall.isActive = true; + this._activeCall = aCall; + gAudioManager.phoneState = nsIAudioManager.PHONE_STATE_IN_CALL; + if (this.speakerEnabled) { + gAudioManager.setForceForUse(nsIAudioManager.USE_COMMUNICATION, + nsIAudioManager.FORCE_SPEAKER); + } + if (DEBUG) { + debug("Active call, put audio system into PHONE_STATE_IN_CALL: " + + gAudioManager.phoneState); + } + break; + + case nsITelephonyProvider.CALL_STATE_INCOMING: + aCall.isActive = false; + if (!this._activeCall) { + // We can change the phone state into RINGTONE only when there's + // no active call. + gAudioManager.phoneState = nsIAudioManager.PHONE_STATE_RINGTONE; + if (DEBUG) { + debug("Incoming call, put audio system into PHONE_STATE_RINGTONE: " + + gAudioManager.phoneState); + } + } + break; + + case nsITelephonyProvider.CALL_STATE_HELD: // Fall through... + case nsITelephonyProvider.CALL_STATE_DISCONNECTED: + aCall.isActive = false; + if (this._activeCall && + this._activeCall.callIndex == aCall.callIndex) { + // Previously active call is not active now. + this._activeCall = null; + } + + if (!this._activeCall) { + // No active call. Disable the audio. + gAudioManager.phoneState = nsIAudioManager.PHONE_STATE_NORMAL; + if (DEBUG) { + debug("No active call, put audio system into PHONE_STATE_NORMAL: " + + gAudioManager.phoneState); + } + } + break; + } + }, + + _convertRILCallState: function _convertRILCallState(aState) { + switch (aState) { + case RIL.CALL_STATE_ACTIVE: + return nsITelephonyProvider.CALL_STATE_CONNECTED; + case RIL.CALL_STATE_HOLDING: + return nsITelephonyProvider.CALL_STATE_HELD; + case RIL.CALL_STATE_DIALING: + return nsITelephonyProvider.CALL_STATE_DIALING; + case RIL.CALL_STATE_ALERTING: + return nsITelephonyProvider.CALL_STATE_ALERTING; + case RIL.CALL_STATE_INCOMING: + case RIL.CALL_STATE_WAITING: + return nsITelephonyProvider.CALL_STATE_INCOMING; + default: + throw new Error("Unknown rilCallState: " + aState); + } + }, + + _convertRILSuppSvcNotification: function _convertRILSuppSvcNotification(aNotification) { + switch (aNotification) { + case RIL.GECKO_SUPP_SVC_NOTIFICATION_REMOTE_HELD: + return nsITelephonyProvider.NOTIFICATION_REMOTE_HELD; + case RIL.GECKO_SUPP_SVC_NOTIFICATION_REMOTE_RESUMED: + return nsITelephonyProvider.NOTIFICATION_REMOTE_RESUMED; + default: + throw new Error("Unknown rilSuppSvcNotification: " + aNotification); + } + }, + + _validateNumber: function _validateNumber(aNumber) { + // note: isPlainPhoneNumber also accepts USSD and SS numbers + if (gPhoneNumberUtils.isPlainPhoneNumber(aNumber)) { + return true; + } + + let errorMsg = RIL.RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[RIL.CALL_FAIL_UNOBTAINABLE_NUMBER]; + let currentThread = Services.tm.currentThread; + currentThread.dispatch(this.notifyCallError.bind(this, -1, errorMsg), + Ci.nsIThread.DISPATCH_NORMAL); + if (DEBUG) { + debug("Number '" + aNumber + "' doesn't seem to be a viable number. Drop."); + } + + return false; + }, + + _updateDebugFlag: function _updateDebugFlag() { + try { + DEBUG = RIL.DEBUG_RIL || + Services.prefs.getBoolPref("ril.debugging.enabled"); + } catch (e) {} + }, + + /** + * nsITelephonyProvider interface. + */ + + registerListener: function(aListener) { + if (this._listeners.indexOf(aListener) >= 0) { + throw Cr.NS_ERROR_UNEXPECTED; + } + + this._listeners.push(aListener); + }, + + unregisterListener: function(aListener) { + let index = this._listeners.indexOf(aListener); + if (index < 0) { + throw Cr.NS_ERROR_UNEXPECTED; + } + + this._listeners.splice(index, 1); + }, + + enumerateCalls: function(aListener) { + if (DEBUG) debug("Requesting enumeration of calls for callback"); + gRadioInterface.sendWorkerMessage("enumerateCalls", null, + (function(response) { + for (let call of response.calls) { + call.state = this._convertRILCallState(call.state); + call.isActive = this._activeCall ? + (call.callIndex == this._activeCall.callIndex) : false; + + aListener.enumerateCallState(call.callIndex, call.state, call.number, + call.isActive, call.isOutgoing, + call.isEmergency, call.isConference); + } + aListener.enumerateCallStateComplete(); + + return false; + }).bind(this)); + }, + + dial: function(aNumber, aIsEmergency) { + if (DEBUG) debug("Dialing " + (aIsEmergency ? "emergency " : "") + aNumber); + // we don't try to be too clever here, as the phone is probably in the + // locked state. Let's just check if it's a number without normalizing + if (!aIsEmergency) { + aNumber = gPhoneNumberUtils.normalize(aNumber); + } + if (this._validateNumber(aNumber)) { + gRadioInterface.sendWorkerMessage("dial", { number: aNumber, + isDialEmergency: aIsEmergency }); + } + }, + + hangUp: function(aCallIndex) { + gRadioInterface.sendWorkerMessage("hangUp", { callIndex: aCallIndex }); + }, + + startTone: function(aDtmfChar) { + gRadioInterface.sendWorkerMessage("startTone", { dtmfChar: aDtmfChar }); + }, + + stopTone: function() { + gRadioInterface.sendWorkerMessage("stopTone"); + }, + + answerCall: function(aCallIndex) { + gRadioInterface.sendWorkerMessage("answerCall", { callIndex: aCallIndex }); + }, + + rejectCall: function(aCallIndex) { + gRadioInterface.sendWorkerMessage("rejectCall", { callIndex: aCallIndex }); + }, + + holdCall: function(aCallIndex) { + gRadioInterface.sendWorkerMessage("holdCall", { callIndex: aCallIndex }); + }, + + resumeCall: function(aCallIndex) { + gRadioInterface.sendWorkerMessage("resumeCall", { callIndex: aCallIndex }); + }, + + conferenceCall: function conferenceCall() { + gRadioInterface.sendWorkerMessage("conferenceCall"); + }, + + separateCall: function separateCall(aCallIndex) { + gRadioInterface.sendWorkerMessage("separateCall", { callIndex: aCallIndex }); + }, + + holdConference: function holdConference() { + gRadioInterface.sendWorkerMessage("holdConference"); + }, + + resumeConference: function resumeConference() { + gRadioInterface.sendWorkerMessage("resumeConference"); + }, + + get microphoneMuted() { + return gAudioManager.microphoneMuted; + }, + + set microphoneMuted(aMuted) { + if (aMuted == this.microphoneMuted) { + return; + } + gAudioManager.microphoneMuted = aMuted; + + if (!this._activeCall) { + gAudioManager.phoneState = nsIAudioManager.PHONE_STATE_NORMAL; + } + }, + + get speakerEnabled() { + let force = gAudioManager.getForceForUse(nsIAudioManager.USE_COMMUNICATION); + return (force == nsIAudioManager.FORCE_SPEAKER); + }, + + set speakerEnabled(aEnabled) { + if (aEnabled == this.speakerEnabled) { + return; + } + let force = aEnabled ? nsIAudioManager.FORCE_SPEAKER : + nsIAudioManager.FORCE_NONE; + gAudioManager.setForceForUse(nsIAudioManager.USE_COMMUNICATION, force); + + if (!this._activeCall) { + gAudioManager.phoneState = nsIAudioManager.PHONE_STATE_NORMAL; + } + }, + + /** + * nsIGonkTelephonyProvider interface. + */ + + /** + * Handle call disconnects by updating our current state and the audio system. + */ + notifyCallDisconnected: function notifyCallDisconnected(aCall) { + if (DEBUG) debug("handleCallDisconnected: " + JSON.stringify(aCall)); + + aCall.state = nsITelephonyProvider.CALL_STATE_DISCONNECTED; + let duration = ("started" in aCall && typeof aCall.started == "number") ? + new Date().getTime() - aCall.started : 0; + let data = { + number: aCall.number, + duration: duration, + direction: aCall.isOutgoing ? "outgoing" : "incoming" + }; + gSystemMessenger.broadcastMessage("telephony-call-ended", data); + + this._updateCallAudioState(aCall, null); + + this._notifyAllListeners("callStateChanged", [aCall.callIndex, + aCall.state, + aCall.number, + aCall.isActive, + aCall.isOutgoing, + aCall.isEmergency, + aCall.isConference]); + }, + + /** + * Handle call error. + */ + notifyCallError: function notifyCallError(aCallIndex, aErrorMsg) { + this._notifyAllListeners("notifyError", [aCallIndex, aErrorMsg]); + }, + + /** + * Handle an incoming call. + * + * Not much is known about this call at this point, but it's enough + * to start bringing up the Phone app already. + */ + notifyCallRing: function notifyCallRing() { + if (!this._callRingWakeLock) { + this._callRingWakeLock = gPowerManagerService.newWakeLock("cpu"); + } + if (!this._callRingWakeLockTimer) { + this._callRingWakeLockTimer = + Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); + } + this._callRingWakeLockTimer + .initWithCallback(this._cancelCallRingWakeLockTimer.bind(this), + CALL_WAKELOCK_TIMEOUT, Ci.nsITimer.TYPE_ONE_SHOT); + + gSystemMessenger.broadcastMessage("telephony-new-call", {}); + }, + + /** + * Handle call state changes by updating our current state and the audio + * system. + */ + notifyCallStateChanged: function notifyCallStateChanged(aCall) { + if (DEBUG) debug("handleCallStateChange: " + JSON.stringify(aCall)); + + aCall.state = this._convertRILCallState(aCall.state); + if (aCall.state == nsITelephonyProvider.CALL_STATE_DIALING) { + gSystemMessenger.broadcastMessage("telephony-new-call", {}); + } + + this._updateCallAudioState(aCall, null); + + this._notifyAllListeners("callStateChanged", [aCall.callIndex, + aCall.state, + aCall.number, + aCall.isActive, + aCall.isOutgoing, + aCall.isEmergency, + aCall.isConference]); + }, + + notifyCdmaCallWaiting: function notifyCdmaCallWaiting(aNumber) { + this._notifyAllListeners("notifyCdmaCallWaiting", [aNumber]); + }, + + notifySupplementaryService: function notifySupplementaryService(aCallIndex, + aNotification) { + let notification = this._convertRILSuppSvcNotification(aNotification); + this._notifyAllListeners("supplementaryServiceNotification", + [aCallIndex, notification]); + }, + + notifyConferenceCallStateChanged: function notifyConferenceCallStateChanged(aState) { + if (DEBUG) debug("handleConferenceCallStateChanged: " + aState); + aState = aState != null ? convertRILCallState(aState) : + nsITelephonyProvider.CALL_STATE_UNKNOWN; + this._updateCallAudioState(null, aState); + + this._notifyAllListeners("conferenceCallStateChanged", [aState]); + }, + + /** + * nsIObserver interface. + */ + + observe: function observe(aSubject, aTopic, aData) { + switch (aTopic) { + case kPrefenceChangedObserverTopic: + if (aData === "ril.debugging.enabled") { + this._updateDebugFlag(); + } + break; + + case kXpcomShutdownObserverTopic: + // Cancel the timer for the call-ring wake lock. + this._cancelCallRingWakeLockTimer(); + + Services.obs.removeObserver(this, kPrefenceChangedObserverTopic); + Services.obs.removeObserver(this, kXpcomShutdownObserverTopic); + break; + } + } +}; + +this.NSGetFactory = XPCOMUtils.generateNSGetFactory([TelephonyProvider]); diff --git a/dom/telephony/gonk/TelephonyProvider.manifest b/dom/telephony/gonk/TelephonyProvider.manifest new file mode 100644 index 00000000000..06cfba0c798 --- /dev/null +++ b/dom/telephony/gonk/TelephonyProvider.manifest @@ -0,0 +1,2 @@ +component {67d26434-d063-4d28-9f48-5b3189788155} TelephonyProvider.js +contract @mozilla.org/telephony/gonktelephonyprovider;1 {67d26434-d063-4d28-9f48-5b3189788155} diff --git a/dom/telephony/moz.build b/dom/telephony/moz.build index e15bf63810e..d2a457fa92f 100644 --- a/dom/telephony/moz.build +++ b/dom/telephony/moz.build @@ -42,6 +42,15 @@ IPDL_SOURCES += [ 'ipc/TelephonyTypes.ipdlh' ] +if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk': + XPIDL_SOURCES += [ + 'nsIGonkTelephonyProvider.idl', + ] + EXTRA_COMPONENTS += [ + 'gonk/TelephonyProvider.js', + 'gonk/TelephonyProvider.manifest', + ] + FAIL_ON_WARNINGS = True LIBXUL_LIBRARY = True diff --git a/dom/telephony/nsIGonkTelephonyProvider.idl b/dom/telephony/nsIGonkTelephonyProvider.idl new file mode 100644 index 00000000000..934f57d25c2 --- /dev/null +++ b/dom/telephony/nsIGonkTelephonyProvider.idl @@ -0,0 +1,31 @@ +/* -*- Mode: idl; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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 "nsITelephonyProvider.idl" + +%{C++ +#define GONK_TELEPHONY_PROVIDER_CONTRACTID \ + "@mozilla.org/telephony/gonktelephonyprovider;1" +%} + +[scriptable, uuid(0d106c7e-ba47-48ee-ba48-c92002d401b6)] +interface nsIGonkTelephonyProvider : nsITelephonyProvider +{ + void notifyCallDisconnected(in jsval call); + + void notifyCallError(in long callIndex, + in AString error); + + void notifyCallRing(); + + void notifyCallStateChanged(in jsval call); + + void notifyCdmaCallWaiting(in AString number); + + void notifySupplementaryService(in long callIndex, + in AString notification); + + void notifyConferenceCallStateChanged(in unsigned short state); +}; From c858cf5319605325c1bb123efa7a6896d97eaa2c Mon Sep 17 00:00:00 2001 From: Vicamo Yang Date: Wed, 4 Sep 2013 15:53:39 +0800 Subject: [PATCH 004/171] Bug 907585 [1/3]: B2G RIL - share RilMessageManager. Move to RilMessageManager.jsm. r=yoshi,hsinyi --- dom/system/gonk/RadioInterfaceLayer.js | 278 +---------------------- dom/system/gonk/RilMessageManager.jsm | 302 +++++++++++++++++++++++++ dom/system/gonk/moz.build | 1 + 3 files changed, 306 insertions(+), 275 deletions(-) create mode 100644 dom/system/gonk/RilMessageManager.jsm diff --git a/dom/system/gonk/RadioInterfaceLayer.js b/dom/system/gonk/RadioInterfaceLayer.js index 937a033c4b9..153e86db50f 100644 --- a/dom/system/gonk/RadioInterfaceLayer.js +++ b/dom/system/gonk/RadioInterfaceLayer.js @@ -138,10 +138,6 @@ XPCOMUtils.defineLazyServiceGetter(this, "gMobileMessageDatabaseService", "@mozilla.org/mobilemessage/rilmobilemessagedatabaseservice;1", "nsIRilMobileMessageDatabaseService"); -XPCOMUtils.defineLazyServiceGetter(this, "ppmm", - "@mozilla.org/parentprocessmessagemanager;1", - "nsIMessageBroadcaster"); - XPCOMUtils.defineLazyServiceGetter(this, "gSettingsService", "@mozilla.org/settingsService;1", "nsISettingsService"); @@ -179,277 +175,9 @@ XPCOMUtils.defineLazyGetter(this, "PhoneNumberUtils", function () { }); 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 init(ril) { - this.ril = ril; - - Services.obs.addObserver(this, "xpcom-shutdown", false); - Services.obs.addObserver(this, kSysMsgListenerReadyObserverTopic, false); - this._registerMessageListeners(); - }, - - _shutdown: function _shutdown() { - this.ril = null; - - Services.obs.removeObserver(this, "xpcom-shutdown"); - this._unregisterMessageListeners(); - }, - - _registerMessageListeners: function _registerMessageListeners() { - ppmm.addMessageListener("child-process-shutdown", this); - for (let msgname of RIL_IPC_MOBILECONNECTION_MSG_NAMES) { - ppmm.addMessageListener(msgname, this); - } - for (let msgName of RIL_IPC_ICCMANAGER_MSG_NAMES) { - ppmm.addMessageListener(msgName, this); - } - for (let msgname of RIL_IPC_VOICEMAIL_MSG_NAMES) { - ppmm.addMessageListener(msgname, this); - } - for (let msgname of RIL_IPC_CELLBROADCAST_MSG_NAMES) { - ppmm.addMessageListener(msgname, this); - } - }, - - _unregisterMessageListeners: function _unregisterMessageListeners() { - ppmm.removeMessageListener("child-process-shutdown", this); - for (let msgname of RIL_IPC_MOBILECONNECTION_MSG_NAMES) { - ppmm.removeMessageListener(msgname, this); - } - for (let msgName of RIL_IPC_ICCMANAGER_MSG_NAMES) { - ppmm.removeMessageListener(msgName, this); - } - for (let msgname of RIL_IPC_VOICEMAIL_MSG_NAMES) { - ppmm.removeMessageListener(msgname, this); - } - for (let msgname of RIL_IPC_CELLBROADCAST_MSG_NAMES) { - ppmm.removeMessageListener(msgname, this); - } - ppmm = null; - }, - - _registerMessageTarget: function _registerMessageTarget(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 _unregisterMessageTarget(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 _enqueueTargetMessage(topic, message, options) { - let msg = { topic : topic, - message : message, - options : options }; - // Remove previous queued message of same message type, only one message - // per message type is allowed in queue. - let messageQueue = this.targetMessageQueue; - for(let i = 0; i < messageQueue.length; i++) { - if (messageQueue[i].message === message) { - messageQueue.splice(i, 1); - break; - } - } - - messageQueue.push(msg); - }, - - _sendTargetMessage: function _sendTargetMessage(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 _resendQueuedTargetMessage() { - 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 receiveMessage(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; - } - - if (RIL_IPC_MOBILECONNECTION_MSG_NAMES.indexOf(msg.name) != -1) { - if (!msg.target.assertPermission("mobileconnection")) { - if (DEBUG) { - debug("MobileConnection message " + msg.name + - " from a content process with no 'mobileconnection' privileges."); - } - return null; - } - } else 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 (RIL_IPC_VOICEMAIL_MSG_NAMES.indexOf(msg.name) != -1) { - if (!msg.target.assertPermission("voicemail")) { - if (DEBUG) { - debug("Voicemail message " + msg.name + - " from a content process with no 'voicemail' privileges."); - } - return null; - } - } else if (RIL_IPC_CELLBROADCAST_MSG_NAMES.indexOf(msg.name) != -1) { - if (!msg.target.assertPermission("cellbroadcast")) { - if (DEBUG) { - debug("Cell Broadcast message " + msg.name + - " from a content process with no 'cellbroadcast' privileges."); - } - return null; - } - } else { - if (DEBUG) debug("Ignoring unknown message type: " + msg.name); - return null; - } - - switch (msg.name) { - case "RIL:RegisterMobileConnectionMsg": - this._registerMessageTarget("mobileconnection", msg.target); - return; - case "RIL:RegisterIccMsg": - this._registerMessageTarget("icc", msg.target); - return; - case "RIL:RegisterVoicemailMsg": - this._registerMessageTarget("voicemail", msg.target); - return; - case "RIL:RegisterCellBroadcastMsg": - this._registerMessageTarget("cellbroadcast", msg.target); - return; - } - - 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 observe(subject, topic, data) { - switch (topic) { - case kSysMsgListenerReadyObserverTopic: - Services.obs.removeObserver(this, kSysMsgListenerReadyObserverTopic); - this._resendQueuedTargetMessage(); - break; - case "xpcom-shutdown": - this._shutdown(); - break; - } - }, - - sendMobileConnectionMessage: function sendMobileConnectionMessage(message, clientId, data) { - this._sendTargetMessage("mobileconnection", message, { - clientId: clientId, - data: data - }); - }, - - sendVoicemailMessage: function sendVoicemailMessage(message, clientId, data) { - this._sendTargetMessage("voicemail", message, { - clientId: clientId, - data: data - }); - }, - - sendCellBroadcastMessage: function sendCellBroadcastMessage(message, clientId, data) { - this._sendTargetMessage("cellbroadcast", message, { - clientId: clientId, - data: data - }); - }, - - sendIccMessage: function sendIccMessage(message, clientId, data) { - this._sendTargetMessage("icc", message, { - clientId: clientId, - data: data - }); - } - }; + let ns = {}; + Cu.import("resource://gre/modules/RilMessageManager.jsm", ns); + return ns.RilMessageManager; }); function RadioInterfaceLayer() { diff --git a/dom/system/gonk/RilMessageManager.jsm b/dom/system/gonk/RilMessageManager.jsm new file mode 100644 index 00000000000..3f8c0f418bd --- /dev/null +++ b/dom/system/gonk/RilMessageManager.jsm @@ -0,0 +1,302 @@ +/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ +/* 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/. */ + +"use strict"; + +const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; + +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); +Cu.import("resource://gre/modules/Services.jsm"); + +XPCOMUtils.defineLazyServiceGetter(this, "ppmm", + "@mozilla.org/parentprocessmessagemanager;1", + "nsIMessageBroadcaster"); + +// Observer topics. +const kSysMsgListenerReadyObserverTopic = "system-message-listener-ready"; + +let DEBUG; +function debug(s) { + dump("RilMessageManager: " + s + "\n"); +} + +this.RilMessageManager = { + 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 init(ril) { + this.ril = ril; + + Services.obs.addObserver(this, "xpcom-shutdown", false); + Services.obs.addObserver(this, kSysMsgListenerReadyObserverTopic, false); + this._registerMessageListeners(); + }, + + _shutdown: function _shutdown() { + this.ril = null; + + Services.obs.removeObserver(this, "xpcom-shutdown"); + this._unregisterMessageListeners(); + }, + + _registerMessageListeners: function _registerMessageListeners() { + ppmm.addMessageListener("child-process-shutdown", this); + for (let msgname of RIL_IPC_MOBILECONNECTION_MSG_NAMES) { + ppmm.addMessageListener(msgname, this); + } + for (let msgName of RIL_IPC_ICCMANAGER_MSG_NAMES) { + ppmm.addMessageListener(msgName, this); + } + for (let msgname of RIL_IPC_VOICEMAIL_MSG_NAMES) { + ppmm.addMessageListener(msgname, this); + } + for (let msgname of RIL_IPC_CELLBROADCAST_MSG_NAMES) { + ppmm.addMessageListener(msgname, this); + } + }, + + _unregisterMessageListeners: function _unregisterMessageListeners() { + ppmm.removeMessageListener("child-process-shutdown", this); + for (let msgname of RIL_IPC_MOBILECONNECTION_MSG_NAMES) { + ppmm.removeMessageListener(msgname, this); + } + for (let msgName of RIL_IPC_ICCMANAGER_MSG_NAMES) { + ppmm.removeMessageListener(msgName, this); + } + for (let msgname of RIL_IPC_VOICEMAIL_MSG_NAMES) { + ppmm.removeMessageListener(msgname, this); + } + for (let msgname of RIL_IPC_CELLBROADCAST_MSG_NAMES) { + ppmm.removeMessageListener(msgname, this); + } + ppmm = null; + }, + + _registerMessageTarget: function _registerMessageTarget(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 _unregisterMessageTarget(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 _enqueueTargetMessage(topic, name, options) { + let msg = { topic : topic, + name : name, + options : options }; + // Remove previous queued message of same message name, only one message + // per message name is allowed in queue. + let messageQueue = this.targetMessageQueue; + for (let i = 0; i < messageQueue.length; i++) { + if (messageQueue[i].name === name) { + messageQueue.splice(i, 1); + break; + } + } + + messageQueue.push(msg); + }, + + _sendTargetMessage: function _sendTargetMessage(topic, name, options) { + if (!this.ready) { + this._enqueueTargetMessage(topic, name, options); + return; + } + + let targets = this.targetsByTopic[topic]; + if (!targets) { + return; + } + + for (let target of targets) { + target.sendAsyncMessage(name, options); + } + }, + + _resendQueuedTargetMessage: function _resendQueuedTargetMessage() { + 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 (let msg of this.targetMessageQueue) { + this._sendTargetMessage(msg.topic, msg.name, msg.options); + } + this.targetMessageQueue = null; + }, + + /** + * nsIMessageListener interface methods. + */ + + receiveMessage: function receiveMessage(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; + } + + if (RIL_IPC_MOBILECONNECTION_MSG_NAMES.indexOf(msg.name) != -1) { + if (!msg.target.assertPermission("mobileconnection")) { + if (DEBUG) { + debug("MobileConnection message " + msg.name + + " from a content process with no 'mobileconnection' privileges."); + } + return null; + } + } else 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 (RIL_IPC_VOICEMAIL_MSG_NAMES.indexOf(msg.name) != -1) { + if (!msg.target.assertPermission("voicemail")) { + if (DEBUG) { + debug("Voicemail message " + msg.name + + " from a content process with no 'voicemail' privileges."); + } + return null; + } + } else if (RIL_IPC_CELLBROADCAST_MSG_NAMES.indexOf(msg.name) != -1) { + if (!msg.target.assertPermission("cellbroadcast")) { + if (DEBUG) { + debug("Cell Broadcast message " + msg.name + + " from a content process with no 'cellbroadcast' privileges."); + } + return null; + } + } else { + if (DEBUG) debug("Ignoring unknown message type: " + msg.name); + return null; + } + + switch (msg.name) { + case "RIL:RegisterMobileConnectionMsg": + this._registerMessageTarget("mobileconnection", msg.target); + return; + case "RIL:RegisterIccMsg": + this._registerMessageTarget("icc", msg.target); + return; + case "RIL:RegisterVoicemailMsg": + this._registerMessageTarget("voicemail", msg.target); + return; + case "RIL:RegisterCellBroadcastMsg": + this._registerMessageTarget("cellbroadcast", msg.target); + return; + } + + 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 observe(subject, topic, data) { + switch (topic) { + case kSysMsgListenerReadyObserverTopic: + Services.obs.removeObserver(this, kSysMsgListenerReadyObserverTopic); + this._resendQueuedTargetMessage(); + break; + case "xpcom-shutdown": + this._shutdown(); + break; + } + }, + + /** + * Public methods. + */ + + sendMobileConnectionMessage: function sendMobileConnectionMessage(name, clientId, data) { + this._sendTargetMessage("mobileconnection", name, { + clientId: clientId, + data: data + }); + }, + + sendVoicemailMessage: function sendVoicemailMessage(name, clientId, data) { + this._sendTargetMessage("voicemail", name, { + clientId: clientId, + data: data + }); + }, + + sendCellBroadcastMessage: function sendCellBroadcastMessage(name, clientId, data) { + this._sendTargetMessage("cellbroadcast", name, { + clientId: clientId, + data: data + }); + }, + + sendIccMessage: function sendIccMessage(name, clientId, data) { + this._sendTargetMessage("icc", name, { + clientId: clientId, + data: data + }); + } +}; + +this.EXPORTED_SYMBOLS = ["RilMessageManager"]; diff --git a/dom/system/gonk/moz.build b/dom/system/gonk/moz.build index 694b01a0217..e4d53da7f57 100644 --- a/dom/system/gonk/moz.build +++ b/dom/system/gonk/moz.build @@ -74,6 +74,7 @@ EXTRA_COMPONENTS += [ ] EXTRA_JS_MODULES += [ + 'RilMessageManager.jsm', 'net_worker.js', 'ril_consts.js', 'ril_worker.js', From 6337f9189f3e3c17c54d8b862d30a6394498ca5f Mon Sep 17 00:00:00 2001 From: Vicamo Yang Date: Wed, 4 Sep 2013 15:53:42 +0800 Subject: [PATCH 005/171] Bug 907585 [2/3]: Re-implement message listener registration. r=yoshi --- dom/system/gonk/RadioInterfaceLayer.js | 31 +++-- dom/system/gonk/RilMessageManager.jsm | 171 ++++++++++++------------- 2 files changed, 103 insertions(+), 99 deletions(-) diff --git a/dom/system/gonk/RadioInterfaceLayer.js b/dom/system/gonk/RadioInterfaceLayer.js index 153e86db50f..ee6547120ac 100644 --- a/dom/system/gonk/RadioInterfaceLayer.js +++ b/dom/system/gonk/RadioInterfaceLayer.js @@ -79,7 +79,6 @@ const RIL_IPC_MOBILECONNECTION_MSG_NAMES = [ "RIL:SelectNetworkAuto", "RIL:SendMMI", "RIL:CancelMMI", - "RIL:RegisterMobileConnectionMsg", "RIL:SetCallForwardingOption", "RIL:GetCallForwardingOption", "RIL:SetCallBarringOption", @@ -109,19 +108,13 @@ const RIL_IPC_ICCMANAGER_MSG_NAMES = [ "RIL:IccExchangeAPDU", "RIL:IccCloseChannel", "RIL:ReadIccContacts", - "RIL:UpdateIccContact", - "RIL:RegisterIccMsg" + "RIL:UpdateIccContact" ]; const RIL_IPC_VOICEMAIL_MSG_NAMES = [ - "RIL:RegisterVoicemailMsg", "RIL:GetVoicemailInfo" ]; -const RIL_IPC_CELLBROADCAST_MSG_NAMES = [ - "RIL:RegisterCellBroadcastMsg" -]; - XPCOMUtils.defineLazyServiceGetter(this, "gPowerManagerService", "@mozilla.org/power/powermanagerservice;1", "nsIPowerManagerService"); @@ -181,7 +174,16 @@ XPCOMUtils.defineLazyGetter(this, "gMessageManager", function () { }); function RadioInterfaceLayer() { - gMessageManager.init(this); + let callback = this._receiveMessage.bind(this); + gMessageManager.registerMessageListeners("icc", + RIL_IPC_ICCMANAGER_MSG_NAMES, + callback); + gMessageManager.registerMessageListeners("mobileconnection", + RIL_IPC_MOBILECONNECTION_MSG_NAMES, + callback); + gMessageManager.registerMessageListeners("voicemail", + RIL_IPC_VOICEMAIL_MSG_NAMES, + callback); let options = { debug: debugPref, @@ -216,6 +218,17 @@ RadioInterfaceLayer.prototype = { QueryInterface: XPCOMUtils.generateQI([Ci.nsIRadioInterfaceLayer, Ci.nsIObserver]), + _receiveMessage: function _receiveMessage(topic, msg) { + let clientId = msg.json.clientId || 0; + let radioInterface = this.getRadioInterface(clientId); + if (!radioInterface) { + if (DEBUG) debug("No such radio interface: " + clientId); + return null; + } + + return radioInterface.receiveMessage(msg); + }, + /** * nsIObserver interface methods. */ diff --git a/dom/system/gonk/RilMessageManager.jsm b/dom/system/gonk/RilMessageManager.jsm index 3f8c0f418bd..d0bb414d595 100644 --- a/dom/system/gonk/RilMessageManager.jsm +++ b/dom/system/gonk/RilMessageManager.jsm @@ -27,7 +27,20 @@ this.RilMessageManager = { QueryInterface: XPCOMUtils.generateQI([Ci.nsIMessageListener, Ci.nsIObserver]), - ril: null, + topicRegistrationNames: { + cellbroadcast: "RIL:RegisterCellBroadcastMsg", + icc: "RIL:RegisterIccMsg", + mobileconnection: "RIL:RegisterMobileConnectionMsg", + voicemail: "RIL:RegisterVoicemailMsg", + }, + + /** + * this.callbacksByName[< A string message name>] = { + * topic: , + * callback: , + * } + */ + callbacksByName: {}, // Manage message targets in terms of topic. Only the authorized and // registered contents can receive related messages. @@ -37,55 +50,32 @@ this.RilMessageManager = { targetMessageQueue: [], ready: false, - init: function init(ril) { - this.ril = ril; - + _init: function _init() { Services.obs.addObserver(this, "xpcom-shutdown", false); Services.obs.addObserver(this, kSysMsgListenerReadyObserverTopic, false); - this._registerMessageListeners(); + + ppmm.addMessageListener("child-process-shutdown", this); + + let callback = this._registerMessageTarget.bind(this); + for (let topic in this.topicRegistrationNames) { + let name = this.topicRegistrationNames[topic]; + this.registerMessageListeners(topic, [name], callback); + } }, _shutdown: function _shutdown() { - this.ril = null; - Services.obs.removeObserver(this, "xpcom-shutdown"); - this._unregisterMessageListeners(); - }, - _registerMessageListeners: function _registerMessageListeners() { - ppmm.addMessageListener("child-process-shutdown", this); - for (let msgname of RIL_IPC_MOBILECONNECTION_MSG_NAMES) { - ppmm.addMessageListener(msgname, this); + for (let name in this.callbacksByName) { + ppmm.removeMessageListener(name, this); } - for (let msgName of RIL_IPC_ICCMANAGER_MSG_NAMES) { - ppmm.addMessageListener(msgName, this); - } - for (let msgname of RIL_IPC_VOICEMAIL_MSG_NAMES) { - ppmm.addMessageListener(msgname, this); - } - for (let msgname of RIL_IPC_CELLBROADCAST_MSG_NAMES) { - ppmm.addMessageListener(msgname, this); - } - }, + this.callbacksByName = null; - _unregisterMessageListeners: function _unregisterMessageListeners() { ppmm.removeMessageListener("child-process-shutdown", this); - for (let msgname of RIL_IPC_MOBILECONNECTION_MSG_NAMES) { - ppmm.removeMessageListener(msgname, this); - } - for (let msgName of RIL_IPC_ICCMANAGER_MSG_NAMES) { - ppmm.removeMessageListener(msgName, this); - } - for (let msgname of RIL_IPC_VOICEMAIL_MSG_NAMES) { - ppmm.removeMessageListener(msgname, this); - } - for (let msgname of RIL_IPC_CELLBROADCAST_MSG_NAMES) { - ppmm.removeMessageListener(msgname, this); - } ppmm = null; }, - _registerMessageTarget: function _registerMessageTarget(topic, target) { + _registerMessageTarget: function _registerMessageTarget(topic, msg) { let targets = this.targetsByTopic[topic]; if (!targets) { targets = this.targetsByTopic[topic] = []; @@ -95,6 +85,7 @@ this.RilMessageManager = { } } + let target = msg.target; if (targets.indexOf(target) != -1) { if (DEBUG) debug("Already registered this target!"); return; @@ -188,66 +179,21 @@ this.RilMessageManager = { return; } - if (RIL_IPC_MOBILECONNECTION_MSG_NAMES.indexOf(msg.name) != -1) { - if (!msg.target.assertPermission("mobileconnection")) { - if (DEBUG) { - debug("MobileConnection message " + msg.name + - " from a content process with no 'mobileconnection' privileges."); - } - return null; - } - } else 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 (RIL_IPC_VOICEMAIL_MSG_NAMES.indexOf(msg.name) != -1) { - if (!msg.target.assertPermission("voicemail")) { - if (DEBUG) { - debug("Voicemail message " + msg.name + - " from a content process with no 'voicemail' privileges."); - } - return null; - } - } else if (RIL_IPC_CELLBROADCAST_MSG_NAMES.indexOf(msg.name) != -1) { - if (!msg.target.assertPermission("cellbroadcast")) { - if (DEBUG) { - debug("Cell Broadcast message " + msg.name + - " from a content process with no 'cellbroadcast' privileges."); - } - return null; - } - } else { + let entry = this.callbacksByName[msg.name]; + if (!entry) { if (DEBUG) debug("Ignoring unknown message type: " + msg.name); return null; } - switch (msg.name) { - case "RIL:RegisterMobileConnectionMsg": - this._registerMessageTarget("mobileconnection", msg.target); - return; - case "RIL:RegisterIccMsg": - this._registerMessageTarget("icc", msg.target); - return; - case "RIL:RegisterVoicemailMsg": - this._registerMessageTarget("voicemail", msg.target); - return; - case "RIL:RegisterCellBroadcastMsg": - this._registerMessageTarget("cellbroadcast", msg.target); - return; - } - - let clientId = msg.json.clientId || 0; - let radioInterface = this.ril.getRadioInterface(clientId); - if (!radioInterface) { - if (DEBUG) debug("No such radio interface: " + clientId); + if (entry.topic && !msg.target.assertPermission(entry.topic)) { + if (DEBUG) { + debug("Message " + msg.name + " from a content process with no '" + + entry.topic + "' privileges."); + } return null; } - return radioInterface.receiveMessage(msg); + return entry.callback(entry.topic, msg); }, /** @@ -270,6 +216,49 @@ this.RilMessageManager = { * Public methods. */ + /** + * @param topic + * A string for the topic of the registrating names. Also the + * permission to listen messages of these names. + * @param names + * An array of string message names to listen. + * @param callback + * A callback that accepts two parameters -- topic and msg. + */ + registerMessageListeners: function registerMessageListeners(topic, names, + callback) { + for (let name of names) { + if (this.callbacksByName[name]) { + if (DEBUG) { + debug("Message name '" + name + "' was already registered. Ignored."); + } + continue; + } + + this.callbacksByName[name] = { topic: topic, callback: callback }; + ppmm.addMessageListener(name, this); + } + }, + + /** + * Remove all listening names with specified callback. + * + * @param callback + * The callback previously registered for messages. + */ + unregisterMessageListeners: function unregisterMessageListeners(callback) { + let remains = {}; + for (let name in this.callbacksByName) { + let entry = this.callbacksByName[name]; + if (entry.callback != callback) { + remains[name] = entry; + } else { + ppmm.removeMessageListener(name, this); + } + } + this.callbacksByName = remains; + }, + sendMobileConnectionMessage: function sendMobileConnectionMessage(name, clientId, data) { this._sendTargetMessage("mobileconnection", name, { clientId: clientId, @@ -299,4 +288,6 @@ this.RilMessageManager = { } }; +RilMessageManager._init(); + this.EXPORTED_SYMBOLS = ["RilMessageManager"]; From 594c8fc4bb57b26a6d254b76aeb221326d815bea Mon Sep 17 00:00:00 2001 From: Vicamo Yang Date: Wed, 4 Sep 2013 15:53:45 +0800 Subject: [PATCH 006/171] Bug 907585 [3/3]: some small refinements. r=yoshi --- dom/system/gonk/RilMessageManager.jsm | 67 +++++++++++++++++++++------ 1 file changed, 52 insertions(+), 15 deletions(-) diff --git a/dom/system/gonk/RilMessageManager.jsm b/dom/system/gonk/RilMessageManager.jsm index d0bb414d595..fece7a68fc3 100644 --- a/dom/system/gonk/RilMessageManager.jsm +++ b/dom/system/gonk/RilMessageManager.jsm @@ -16,7 +16,15 @@ XPCOMUtils.defineLazyServiceGetter(this, "ppmm", "nsIMessageBroadcaster"); // Observer topics. +const kPrefenceChangedObserverTopic = "nsPref:changed"; const kSysMsgListenerReadyObserverTopic = "system-message-listener-ready"; +const kXpcomShutdownObserverTopic = "xpcom-shutdown"; + +// Preference keys. +const kPrefKeyRilDebuggingEnabled = "ril.debugging.enabled"; + +// Frame message names. +const kMsgNameChildProcessShutdown = "child-process-shutdown"; let DEBUG; function debug(s) { @@ -51,10 +59,13 @@ this.RilMessageManager = { ready: false, _init: function _init() { - Services.obs.addObserver(this, "xpcom-shutdown", false); - Services.obs.addObserver(this, kSysMsgListenerReadyObserverTopic, false); + this._updateDebugFlag(); - ppmm.addMessageListener("child-process-shutdown", this); + Services.obs.addObserver(this, kPrefenceChangedObserverTopic, false); + Services.obs.addObserver(this, kSysMsgListenerReadyObserverTopic, false); + Services.obs.addObserver(this, kXpcomShutdownObserverTopic, false); + + ppmm.addMessageListener(kMsgNameChildProcessShutdown, this); let callback = this._registerMessageTarget.bind(this); for (let topic in this.topicRegistrationNames) { @@ -64,15 +75,22 @@ this.RilMessageManager = { }, _shutdown: function _shutdown() { - Services.obs.removeObserver(this, "xpcom-shutdown"); + if (!this.ready) { + Services.obs.removeObserver(this, kSysMsgListenerReadyObserverTopic); + } + Services.obs.removeObserver(this, kPrefenceChangedObserverTopic); + Services.obs.removeObserver(this, kXpcomShutdownObserverTopic); for (let name in this.callbacksByName) { ppmm.removeMessageListener(name, this); } this.callbacksByName = null; - ppmm.removeMessageListener("child-process-shutdown", this); + ppmm.removeMessageListener(kMsgNameChildProcessShutdown, this); ppmm = null; + + this.targetsByTopic = null; + this.targetMessageQueue = null; }, _registerMessageTarget: function _registerMessageTarget(topic, msg) { @@ -151,12 +169,9 @@ this.RilMessageManager = { }, _resendQueuedTargetMessage: function _resendQueuedTargetMessage() { - 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. + // 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 (let msg of this.targetMessageQueue) { @@ -165,13 +180,23 @@ this.RilMessageManager = { this.targetMessageQueue = null; }, + _updateDebugFlag: function _updateDebugFlag() { + try { + DEBUG = RIL.DEBUG_RIL || + Services.prefs.getBoolPref(kPrefKeyRilDebuggingEnabled); + } catch(e) {} + }, + /** * nsIMessageListener interface methods. */ receiveMessage: function receiveMessage(msg) { - if (DEBUG) debug("Received '" + msg.name + "' message from content process"); - if (msg.name == "child-process-shutdown") { + if (DEBUG) { + debug("Received '" + msg.name + "' message from content process"); + } + + if (msg.name == kMsgNameChildProcessShutdown) { // 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. @@ -203,10 +228,19 @@ this.RilMessageManager = { observe: function observe(subject, topic, data) { switch (topic) { case kSysMsgListenerReadyObserverTopic: + this.ready = true; Services.obs.removeObserver(this, kSysMsgListenerReadyObserverTopic); + this._resendQueuedTargetMessage(); break; - case "xpcom-shutdown": + + case kPrefenceChangedObserverTopic: + if (data === kPrefKeyRilDebuggingEnabled) { + this._updateDebugFlag(); + } + break; + + case kXpcomShutdownObserverTopic: this._shutdown(); break; } @@ -259,7 +293,9 @@ this.RilMessageManager = { this.callbacksByName = remains; }, - sendMobileConnectionMessage: function sendMobileConnectionMessage(name, clientId, data) { + sendMobileConnectionMessage: function sendMobileConnectionMessage(name, + clientId, + data) { this._sendTargetMessage("mobileconnection", name, { clientId: clientId, data: data @@ -273,7 +309,8 @@ this.RilMessageManager = { }); }, - sendCellBroadcastMessage: function sendCellBroadcastMessage(name, clientId, data) { + sendCellBroadcastMessage: function sendCellBroadcastMessage(name, clientId, + data) { this._sendTargetMessage("cellbroadcast", name, { clientId: clientId, data: data From 9ec5a297b342465b5127538a04c6d037b0626a2f Mon Sep 17 00:00:00 2001 From: Vicamo Yang Date: Wed, 4 Sep 2013 15:53:50 +0800 Subject: [PATCH 007/171] Bug 873351 - B2G SMS: move SMS code out of RadioInterfaceLayer to SmsService. r=gene --- b2g/installer/package-manifest.in | 2 + browser/installer/package-manifest.in | 2 + dom/mobilemessage/interfaces/moz.build | 1 + .../interfaces/nsIRilSmsService.idl | 11 + .../interfaces/nsISmsService.idl | 3 +- dom/mobilemessage/src/Makefile.in | 6 - dom/mobilemessage/src/SmsServicesFactory.cpp | 13 +- dom/mobilemessage/src/android/SmsService.cpp | 8 - dom/mobilemessage/src/fallback/SmsService.cpp | 8 - dom/mobilemessage/src/gonk/SmsService.cpp | 85 -- dom/mobilemessage/src/gonk/SmsService.h | 35 - dom/mobilemessage/src/gonk/SmsService.js | 994 ++++++++++++++++++ .../src/gonk/SmsService.manifest | 3 + dom/mobilemessage/src/ipc/SmsIPCService.cpp | 8 - dom/mobilemessage/src/moz.build | 4 +- dom/system/gonk/RadioInterfaceLayer.js | 841 +-------------- dom/system/gonk/nsIRadioInterfaceLayer.idl | 14 +- 17 files changed, 1032 insertions(+), 1006 deletions(-) create mode 100644 dom/mobilemessage/interfaces/nsIRilSmsService.idl delete mode 100644 dom/mobilemessage/src/gonk/SmsService.cpp delete mode 100644 dom/mobilemessage/src/gonk/SmsService.h create mode 100644 dom/mobilemessage/src/gonk/SmsService.js create mode 100644 dom/mobilemessage/src/gonk/SmsService.manifest diff --git a/b2g/installer/package-manifest.in b/b2g/installer/package-manifest.in index f358d9f1007..e0e660cdbc5 100644 --- a/b2g/installer/package-manifest.in +++ b/b2g/installer/package-manifest.in @@ -460,6 +460,8 @@ @BINPATH@/components/RadioInterfaceLayer.js @BINPATH@/components/MmsService.manifest @BINPATH@/components/MmsService.js +@BINPATH@/components/SmsService.manifest +@BINPATH@/components/SmsService.js @BINPATH@/components/RILContentHelper.js @BINPATH@/components/MobileMessageDatabaseService.manifest @BINPATH@/components/MobileMessageDatabaseService.js diff --git a/browser/installer/package-manifest.in b/browser/installer/package-manifest.in index 387a7915c87..71b851364de 100644 --- a/browser/installer/package-manifest.in +++ b/browser/installer/package-manifest.in @@ -446,6 +446,8 @@ @BINPATH@/components/RadioInterfaceLayer.js @BINPATH@/components/MmsService.manifest @BINPATH@/components/MmsService.js +@BINPATH@/components/SmsService.manifest +@BINPATH@/components/SmsService.js @BINPATH@/components/RILContentHelper.js @BINPATH@/components/MobileMessageDatabaseService.manifest @BINPATH@/components/MobileMessageDatabaseService.js diff --git a/dom/mobilemessage/interfaces/moz.build b/dom/mobilemessage/interfaces/moz.build index 52cc79b9288..dd41f43b776 100644 --- a/dom/mobilemessage/interfaces/moz.build +++ b/dom/mobilemessage/interfaces/moz.build @@ -25,6 +25,7 @@ XPIDL_SOURCES += [ if CONFIG['MOZ_B2G_RIL']: XPIDL_SOURCES += [ 'nsIRilMobileMessageDatabaseService.idl', + 'nsIRilSmsService.idl', ] XPIDL_MODULE = 'dom_mobilemessage' diff --git a/dom/mobilemessage/interfaces/nsIRilSmsService.idl b/dom/mobilemessage/interfaces/nsIRilSmsService.idl new file mode 100644 index 00000000000..ef2e853d8a5 --- /dev/null +++ b/dom/mobilemessage/interfaces/nsIRilSmsService.idl @@ -0,0 +1,11 @@ +/* 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 "nsISmsService.idl" + +[scriptable, uuid(f216903c-bdf5-4988-b894-f62fd91df114)] +interface nsIRilSmsService : nsISmsService +{ + void notifyMessageReceived(in jsval message); +}; diff --git a/dom/mobilemessage/interfaces/nsISmsService.idl b/dom/mobilemessage/interfaces/nsISmsService.idl index 0623d62ef78..2250e46a2e1 100644 --- a/dom/mobilemessage/interfaces/nsISmsService.idl +++ b/dom/mobilemessage/interfaces/nsISmsService.idl @@ -13,7 +13,7 @@ interface nsIMobileMessageCallback; #define SMS_SERVICE_CONTRACTID "@mozilla.org/sms/smsservice;1" %} -[scriptable, builtinclass, uuid(f0d5d11b-0326-4cb1-bb76-a3f912212287)] +[scriptable, uuid(7ef8e361-9db6-46ed-badc-2901e1049e5d)] interface nsISmsService : nsISupports { boolean hasSupport(); @@ -25,7 +25,6 @@ interface nsISmsService : nsISupports in boolean silent, in nsIMobileMessageCallback request); - boolean isSilentNumber(in DOMString number); void addSilentNumber(in DOMString number); void removeSilentNumber(in DOMString number); }; diff --git a/dom/mobilemessage/src/Makefile.in b/dom/mobilemessage/src/Makefile.in index e45e9b971de..ae94f960a3c 100644 --- a/dom/mobilemessage/src/Makefile.in +++ b/dom/mobilemessage/src/Makefile.in @@ -31,11 +31,5 @@ LOCAL_INCLUDES = \ # subdirectory (and the ipc one). LOCAL_INCLUDES += $(VPATH:%=-I%) -ifdef MOZ_B2G_RIL -LOCAL_INCLUDES += \ - -I$(topsrcdir)/dom/system/gonk \ - $(NULL) -endif - include $(topsrcdir)/config/rules.mk include $(topsrcdir)/ipc/chromium/chromium-config.mk diff --git a/dom/mobilemessage/src/SmsServicesFactory.cpp b/dom/mobilemessage/src/SmsServicesFactory.cpp index efcf0171834..94ffef77b92 100644 --- a/dom/mobilemessage/src/SmsServicesFactory.cpp +++ b/dom/mobilemessage/src/SmsServicesFactory.cpp @@ -5,16 +5,18 @@ #include "SmsServicesFactory.h" #include "nsXULAppAPI.h" -#include "SmsService.h" #include "SmsIPCService.h" #ifndef MOZ_B2G_RIL #include "MobileMessageDatabaseService.h" #include "MmsService.h" +#include "SmsService.h" #endif #include "nsServiceManagerUtils.h" #define RIL_MMSSERVICE_CONTRACTID "@mozilla.org/mms/rilmmsservice;1" -#define RIL_MOBILE_MESSAGE_DATABASE_SERVICE_CONTRACTID "@mozilla.org/mobilemessage/rilmobilemessagedatabaseservice;1" +#define RIL_MOBILE_MESSAGE_DATABASE_SERVICE_CONTRACTID \ + "@mozilla.org/mobilemessage/rilmobilemessagedatabaseservice;1" +#define RIL_SMSSERVICE_CONTRACTID "@mozilla.org/sms/rilsmsservice;1" namespace mozilla { namespace dom { @@ -28,7 +30,11 @@ SmsServicesFactory::CreateSmsService() if (XRE_GetProcessType() == GeckoProcessType_Content) { smsService = new SmsIPCService(); } else { +#ifdef MOZ_B2G_RIL + smsService = do_GetService(RIL_SMSSERVICE_CONTRACTID); +#else smsService = new SmsService(); +#endif } return smsService.forget(); @@ -42,7 +48,8 @@ SmsServicesFactory::CreateMobileMessageDatabaseService() mobileMessageDBService = new SmsIPCService(); } else { #ifdef MOZ_B2G_RIL - mobileMessageDBService = do_GetService(RIL_MOBILE_MESSAGE_DATABASE_SERVICE_CONTRACTID); + mobileMessageDBService = + do_GetService(RIL_MOBILE_MESSAGE_DATABASE_SERVICE_CONTRACTID); #else mobileMessageDBService = new MobileMessageDatabaseService(); #endif diff --git a/dom/mobilemessage/src/android/SmsService.cpp b/dom/mobilemessage/src/android/SmsService.cpp index 146190766fa..c5a67319984 100644 --- a/dom/mobilemessage/src/android/SmsService.cpp +++ b/dom/mobilemessage/src/android/SmsService.cpp @@ -53,14 +53,6 @@ SmsService::Send(const nsAString& aNumber, return NS_OK; } -NS_IMETHODIMP -SmsService::IsSilentNumber(const nsAString& aNumber, - bool* aIsSilent) -{ - NS_NOTYETIMPLEMENTED("Implement me!"); - return NS_ERROR_NOT_IMPLEMENTED; -} - NS_IMETHODIMP SmsService::AddSilentNumber(const nsAString& aNumber) { diff --git a/dom/mobilemessage/src/fallback/SmsService.cpp b/dom/mobilemessage/src/fallback/SmsService.cpp index 5df3504226b..430edab6f15 100644 --- a/dom/mobilemessage/src/fallback/SmsService.cpp +++ b/dom/mobilemessage/src/fallback/SmsService.cpp @@ -39,14 +39,6 @@ SmsService::Send(const nsAString& aNumber, return NS_ERROR_FAILURE; } -NS_IMETHODIMP -SmsService::IsSilentNumber(const nsAString& aNumber, - bool* aIsSilent) -{ - NS_ERROR("We should not be here!"); - return NS_ERROR_FAILURE; -} - NS_IMETHODIMP SmsService::AddSilentNumber(const nsAString& aNumber) { diff --git a/dom/mobilemessage/src/gonk/SmsService.cpp b/dom/mobilemessage/src/gonk/SmsService.cpp deleted file mode 100644 index 484dd94091a..00000000000 --- a/dom/mobilemessage/src/gonk/SmsService.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* 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 "SmsMessage.h" -#include "SmsService.h" -#include "jsapi.h" -#include "SmsSegmentInfo.h" - -namespace mozilla { -namespace dom { -namespace mobilemessage { - -NS_IMPL_ISUPPORTS1(SmsService, nsISmsService) - -SmsService::SmsService() -{ - nsCOMPtr ril = do_GetService("@mozilla.org/ril;1"); - if (ril) { - ril->GetRadioInterface(0, getter_AddRefs(mRadioInterface)); - } - NS_WARN_IF_FALSE(mRadioInterface, "This shouldn't fail!"); -} - -NS_IMETHODIMP -SmsService::HasSupport(bool* aHasSupport) -{ - *aHasSupport = true; - return NS_OK; -} - -NS_IMETHODIMP -SmsService::GetSegmentInfoForText(const nsAString & aText, - nsIDOMMozSmsSegmentInfo** aResult) -{ - NS_ENSURE_TRUE(mRadioInterface, NS_ERROR_FAILURE); - - return mRadioInterface->GetSegmentInfoForText(aText, aResult); -} - -NS_IMETHODIMP -SmsService::Send(const nsAString& aNumber, - const nsAString& aMessage, - const bool aSilent, - nsIMobileMessageCallback* aRequest) -{ - NS_ENSURE_TRUE(mRadioInterface, NS_ERROR_FAILURE); - - return mRadioInterface->SendSMS(aNumber, aMessage, aSilent, aRequest); -} - -NS_IMETHODIMP -SmsService::IsSilentNumber(const nsAString& aNumber, - bool* aIsSilent) -{ - *aIsSilent = mSilentNumbers.Contains(aNumber); - return NS_OK; -} - -NS_IMETHODIMP -SmsService::AddSilentNumber(const nsAString& aNumber) -{ - if (mSilentNumbers.Contains(aNumber)) { - return NS_ERROR_UNEXPECTED; - } - - NS_ENSURE_TRUE(mSilentNumbers.AppendElement(aNumber), NS_ERROR_FAILURE); - return NS_OK; -} - -NS_IMETHODIMP -SmsService::RemoveSilentNumber(const nsAString& aNumber) -{ - if (!mSilentNumbers.Contains(aNumber)) { - return NS_ERROR_INVALID_ARG; - } - - NS_ENSURE_TRUE(mSilentNumbers.RemoveElement(aNumber), NS_ERROR_FAILURE); - return NS_OK; -} - -} // namespace mobilemessage -} // namespace dom -} // namespace mozilla diff --git a/dom/mobilemessage/src/gonk/SmsService.h b/dom/mobilemessage/src/gonk/SmsService.h deleted file mode 100644 index 940cbf2fa81..00000000000 --- a/dom/mobilemessage/src/gonk/SmsService.h +++ /dev/null @@ -1,35 +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/. */ - -#ifndef mozilla_dom_mobilemessage_SmsService_h -#define mozilla_dom_mobilemessage_SmsService_h - -#include "nsISmsService.h" -#include "nsCOMPtr.h" -#include "nsIRadioInterfaceLayer.h" -#include "nsTArray.h" -#include "nsString.h" - -namespace mozilla { -namespace dom { -namespace mobilemessage { - -class SmsService : public nsISmsService -{ -public: - NS_DECL_ISUPPORTS - NS_DECL_NSISMSSERVICE - SmsService(); - -protected: - // TODO: Bug 854326 - B2G Multi-SIM: support multiple SIM cards for SMS/MMS - nsCOMPtr mRadioInterface; - nsTArray mSilentNumbers; -}; - -} // namespace mobilemessage -} // namespace dom -} // namespace mozilla - -#endif // mozilla_dom_mobilemessage_SmsService_h diff --git a/dom/mobilemessage/src/gonk/SmsService.js b/dom/mobilemessage/src/gonk/SmsService.js new file mode 100644 index 00000000000..853b66e04b9 --- /dev/null +++ b/dom/mobilemessage/src/gonk/SmsService.js @@ -0,0 +1,994 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * vim: sw=2 ts=2 sts=2 et filetype=javascript + * 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/. */ + +"use strict"; + +const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; + +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); +Cu.import("resource://gre/modules/Services.jsm"); + +var RIL = {}; +Cu.import("resource://gre/modules/ril_consts.js", RIL); + +const RIL_SMSSERVICE_CONTRACTID = "@mozilla.org/sms/rilsmsservice;1"; +const RIL_SMSSERVICE_CID = + Components.ID("{46a9ed78-3574-40a1-9f12-ea179942d67f}"); + +const DELIVERY_STATE_RECEIVED = "received"; +const DELIVERY_STATE_SENDING = "sending"; +const DELIVERY_STATE_SENT = "sent"; +const DELIVERY_STATE_ERROR = "error"; + +// Observer topics to send. +const kSmsReceivedObserverTopic = "sms-received"; +const kSmsSendingObserverTopic = "sms-sending"; +const kSmsSentObserverTopic = "sms-sent"; +const kSmsFailedObserverTopic = "sms-failed"; +const kSmsDeliverySuccessObserverTopic = "sms-delivery-success"; +const kSmsDeliveryErrorObserverTopic = "sms-delivery-error"; +const kSilentSmsReceivedObserverTopic = "silent-sms-received"; + +// Observer topics to watch. +const kPrefenceChangedObserverTopic = "nsPref:changed"; +const kXpcomShutdownObserverTopic = "xpcom-shutdown"; + +// Preference keys. +const kPrefKeyRilDebuggingEnabled = "ril.debugging.enabled"; + +XPCOMUtils.defineLazyServiceGetter(this, "gMobileMessageDatabaseService", + "@mozilla.org/mobilemessage/rilmobilemessagedatabaseservice;1", + "nsIRilMobileMessageDatabaseService"); + +XPCOMUtils.defineLazyServiceGetter(this, "gMobileMessageService", + "@mozilla.org/mobilemessage/mobilemessageservice;1", + "nsIMobileMessageService"); + +XPCOMUtils.defineLazyServiceGetter(this, "gSystemMessenger", + "@mozilla.org/system-message-internal;1", + "nsISystemMessagesInternal"); + +XPCOMUtils.defineLazyGetter(this, "gRadioInterface", function () { + let ril = Cc["@mozilla.org/ril;1"].getService(Ci["nsIRadioInterfaceLayer"]); + // TODO: Bug 854326 - B2G Multi-SIM: support multiple SIM cards for SMS/MMS + return ril.getRadioInterface(0); +}); + +XPCOMUtils.defineLazyGetter(this, "gPhoneNumberUtils", function () { + let ns = {}; + Cu.import("resource://gre/modules/PhoneNumberUtils.jsm", ns); + return ns.PhoneNumberUtils; +}); + +XPCOMUtils.defineLazyGetter(this, "WAP", function () { + let WAP = {}; + Cu.import("resource://gre/modules/WapPushManager.js", WAP); + return WAP; +}); + +XPCOMUtils.defineLazyGetter(this, "gMessageManager", function () { + let ns = {}; + Cu.import("resource://gre/modules/RilMessageManager.jsm", ns); + return ns.RilMessageManager; +}); + +let DEBUG; +function debug(s) { + dump("SmsService: " + s + "\n"); +} + +/** + * SmsService + */ +function SmsService() { + // Update |DEBUG|. + this.observe(null, kPrefenceChangedObserverTopic, + kPrefKeyRilDebuggingEnabled); + + this.silentNumbers = []; + + this.portAddressedSmsApps = {}; + this.portAddressedSmsApps[WAP.WDP_PORT_PUSH] = + this._handleSmsWdpPortPush.bind(this); + + Services.obs.addObserver(this, kPrefenceChangedObserverTopic, false); + Services.obs.addObserver(this, kXpcomShutdownObserverTopic, false); +} +SmsService.prototype = { + + classID: RIL_SMSSERVICE_CID, + classInfo: XPCOMUtils.generateCI({classID: RIL_SMSSERVICE_CID, + contractID: RIL_SMSSERVICE_CONTRACTID, + classDescription: "SmsService", + interfaces: [Ci.nsIRilSmsService, + Ci.nsISmsService], + flags: Ci.nsIClassInfo.SINGLETON}), + QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, + Ci.nsIRilSmsService, + Ci.nsISmsService]), + + /** + * List of tuples of national language identifier pairs. + * + * TODO: Support static/runtime settings, see bug 733331. + */ + enabledGsmTableTuples: [ + [RIL.PDU_NL_IDENTIFIER_DEFAULT, RIL.PDU_NL_IDENTIFIER_DEFAULT], + ], + + /** + * Use 16-bit reference number for concatenated outgoint messages. + * + * TODO: Support static/runtime settings, see bug 733331. + */ + segmentRef16Bit: false, + + /** + * Get valid SMS concatenation reference number. + */ + segmentRef: 0, + get nextSegmentRef() { + let ref = this.segmentRef++; + + this.segmentRef %= (this.segmentRef16Bit ? 65535 : 255); + + // 0 is not a valid SMS concatenation reference number. + return ref + 1; + }, + + statusReportPendingMessageIds: null, + + portAddressedSmsApps: null, + + silentNumbers: null, + + _getStrict7BitEncoding: function _getStrict7BitEncoding() { + try { + return Services.prefs.getBoolPref("dom.sms.strict7BitEncoding"); + } catch (e) { + return false; + } + }, + + _getRequestStatusReport: function _getRequestStatusReport() { + try { + return Services.prefs.getBoolPref("dom.sms.requestStatusReport"); + } catch (e) { + return true; + } + }, + + _getMsisdn: function _getMsisdn() { + let iccInfo = gRadioInterface.rilContext.iccInfo; + let number = iccInfo ? iccInfo.msisdn : null; + + // Workaround an xpconnect issue with undefined string objects. + // See bug 808220 + if (number === undefined || number === "undefined") { + return null; + } + return number; + }, + + /** + * Calculate encoded length using specified locking/single shift table + * + * @param message + * message string to be encoded. + * @param langTable + * locking shift table string. + * @param langShiftTable + * single shift table string. + * @param strict7BitEncoding + * Optional. Enable Latin characters replacement with corresponding + * ones in GSM SMS 7-bit default alphabet. + * + * @return encoded length in septets. + * + * @note that the algorithm used in this function must match exactly with + * GsmPDUHelper#writeStringAsSeptets. + */ + _countGsm7BitSeptets: function _countGsm7BitSeptets(message, + langTable, + langShiftTable, + strict7BitEncoding) { + let length = 0; + for (let msgIndex = 0; msgIndex < message.length; msgIndex++) { + let c = message.charAt(msgIndex); + if (strict7BitEncoding) { + c = RIL.GSM_SMS_STRICT_7BIT_CHARMAP[c] || c; + } + + let septet = langTable.indexOf(c); + + // According to 3GPP TS 23.038, section 6.1.1 General notes, "The + // characters marked '1)' are not used but are displayed as a space." + if (septet == RIL.PDU_NL_EXTENDED_ESCAPE) { + continue; + } + + if (septet >= 0) { + length++; + continue; + } + + septet = langShiftTable.indexOf(c); + if (septet < 0) { + if (!strict7BitEncoding) { + return -1; + } + + // Bug 816082, when strict7BitEncoding is enabled, we should replace + // characters that can't be encoded with GSM 7-Bit alphabets with '*'. + c = '*'; + if (langTable.indexOf(c) >= 0) { + length++; + } else if (langShiftTable.indexOf(c) >= 0) { + length += 2; + } else { + // We can't even encode a '*' character with current configuration. + return -1; + } + + continue; + } + + // According to 3GPP TS 23.038 B.2, "This code represents a control + // character and therefore must not be used for language specific + // characters." + if (septet == RIL.PDU_NL_RESERVED_CONTROL) { + continue; + } + + // The character is not found in locking shfit table, but could be + // encoded as with single shift table. Note that it's + // still possible for septet to has the value of PDU_NL_EXTENDED_ESCAPE, + // but we can display it as a space in this case as said in previous + // comment. + length += 2; + } + + return length; + }, + + /** + * Calculate user data length of specified message string encoded in GSM 7Bit + * alphabets. + * + * @param message + * a message string to be encoded. + * @param strict7BitEncoding + * Optional. Enable Latin characters replacement with corresponding + * ones in GSM SMS 7-bit default alphabet. + * + * @return null or an options object with attributes `dcs`, + * `userDataHeaderLength`, `encodedFullBodyLength`, `langIndex`, + * `langShiftIndex`, `segmentMaxSeq` set. + * + * @see #_calculateUserDataLength(). + */ + _calculateUserDataLength7Bit: function _calculateUserDataLength7Bit(message, + strict7BitEncoding) { + let options = null; + let minUserDataSeptets = Number.MAX_VALUE; + for (let i = 0; i < this.enabledGsmTableTuples.length; i++) { + let [langIndex, langShiftIndex] = this.enabledGsmTableTuples[i]; + + const langTable = RIL.PDU_NL_LOCKING_SHIFT_TABLES[langIndex]; + const langShiftTable = RIL.PDU_NL_SINGLE_SHIFT_TABLES[langShiftIndex]; + + let bodySeptets = this._countGsm7BitSeptets(message, + langTable, + langShiftTable, + strict7BitEncoding); + if (bodySeptets < 0) { + continue; + } + + let headerLen = 0; + if (langIndex != RIL.PDU_NL_IDENTIFIER_DEFAULT) { + headerLen += 3; // IEI + len + langIndex + } + if (langShiftIndex != RIL.PDU_NL_IDENTIFIER_DEFAULT) { + headerLen += 3; // IEI + len + langShiftIndex + } + + // Calculate full user data length, note the extra byte is for header len + let headerSeptets = Math.ceil((headerLen ? headerLen + 1 : 0) * 8 / 7); + let segmentSeptets = RIL.PDU_MAX_USER_DATA_7BIT; + if ((bodySeptets + headerSeptets) > segmentSeptets) { + headerLen += this.segmentRef16Bit ? 6 : 5; + headerSeptets = Math.ceil((headerLen + 1) * 8 / 7); + segmentSeptets -= headerSeptets; + } + + let segments = Math.ceil(bodySeptets / segmentSeptets); + let userDataSeptets = bodySeptets + headerSeptets * segments; + if (userDataSeptets >= minUserDataSeptets) { + continue; + } + + minUserDataSeptets = userDataSeptets; + + options = { + dcs: RIL.PDU_DCS_MSG_CODING_7BITS_ALPHABET, + encodedFullBodyLength: bodySeptets, + userDataHeaderLength: headerLen, + langIndex: langIndex, + langShiftIndex: langShiftIndex, + segmentMaxSeq: segments, + segmentChars: segmentSeptets, + }; + } + + return options; + }, + + /** + * Calculate user data length of specified message string encoded in UCS2. + * + * @param message + * a message string to be encoded. + * + * @return an options object with attributes `dcs`, `userDataHeaderLength`, + * `encodedFullBodyLength`, `segmentMaxSeq` set. + * + * @see #_calculateUserDataLength(). + */ + _calculateUserDataLengthUCS2: function _calculateUserDataLengthUCS2(message) { + let bodyChars = message.length; + let headerLen = 0; + let headerChars = Math.ceil((headerLen ? headerLen + 1 : 0) / 2); + let segmentChars = RIL.PDU_MAX_USER_DATA_UCS2; + if ((bodyChars + headerChars) > segmentChars) { + headerLen += this.segmentRef16Bit ? 6 : 5; + headerChars = Math.ceil((headerLen + 1) / 2); + segmentChars -= headerChars; + } + + let segments = Math.ceil(bodyChars / segmentChars); + + return { + dcs: RIL.PDU_DCS_MSG_CODING_16BITS_ALPHABET, + encodedFullBodyLength: bodyChars * 2, + userDataHeaderLength: headerLen, + segmentMaxSeq: segments, + segmentChars: segmentChars, + }; + }, + + /** + * Calculate user data length and its encoding. + * + * @param message + * a message string to be encoded. + * @param strict7BitEncoding + * Optional. Enable Latin characters replacement with corresponding + * ones in GSM SMS 7-bit default alphabet. + * + * @return an options object with some or all of following attributes set: + * + * @param dcs + * Data coding scheme. One of the PDU_DCS_MSG_CODING_*BITS_ALPHABET + * constants. + * @param userDataHeaderLength + * Length of embedded user data header, in bytes. The whole header + * size will be userDataHeaderLength + 1; 0 for no header. + * @param encodedFullBodyLength + * Length of the message body when encoded with the given DCS. For + * UCS2, in bytes; for 7-bit, in septets. + * @param langIndex + * Table index used for normal 7-bit encoded character lookup. + * @param langShiftIndex + * Table index used for escaped 7-bit encoded character lookup. + * @param segmentMaxSeq + * Max sequence number of a multi-part messages, or 1 for single one. + * This number might not be accurate for a multi-part message until + * it's processed by #_fragmentText() again. + */ + _calculateUserDataLength: function _calculateUserDataLength(message, + strict7BitEncoding) { + let options = this._calculateUserDataLength7Bit(message, strict7BitEncoding); + if (!options) { + options = this._calculateUserDataLengthUCS2(message); + } + + if (DEBUG) debug("_calculateUserDataLength: " + JSON.stringify(options)); + return options; + }, + + /** + * Fragment GSM 7-Bit encodable string for transmission. + * + * @param text + * text string to be fragmented. + * @param langTable + * locking shift table string. + * @param langShiftTable + * single shift table string. + * @param segmentSeptets + * Number of available spetets per segment. + * @param strict7BitEncoding + * Optional. Enable Latin characters replacement with corresponding + * ones in GSM SMS 7-bit default alphabet. + * + * @return an array of objects. See #_fragmentText() for detailed definition. + */ + _fragmentText7Bit: function _fragmentText7Bit(text, langTable, langShiftTable, + segmentSeptets, + strict7BitEncoding) { + let ret = []; + let body = "", len = 0; + for (let i = 0, inc = 0; i < text.length; i++) { + let c = text.charAt(i); + if (strict7BitEncoding) { + c = RIL.GSM_SMS_STRICT_7BIT_CHARMAP[c] || c; + } + + let septet = langTable.indexOf(c); + if (septet == RIL.PDU_NL_EXTENDED_ESCAPE) { + continue; + } + + if (septet >= 0) { + inc = 1; + } else { + septet = langShiftTable.indexOf(c); + if (septet == RIL.PDU_NL_RESERVED_CONTROL) { + continue; + } + + inc = 2; + if (septet < 0) { + if (!strict7BitEncoding) { + throw new Error("Given text cannot be encoded with GSM 7-bit Alphabet!"); + } + + // Bug 816082, when strict7BitEncoding is enabled, we should replace + // characters that can't be encoded with GSM 7-Bit alphabets with '*'. + c = '*'; + if (langTable.indexOf(c) >= 0) { + inc = 1; + } + } + } + + if ((len + inc) > segmentSeptets) { + ret.push({ + body: body, + encodedBodyLength: len, + }); + body = c; + len = inc; + } else { + body += c; + len += inc; + } + } + + if (len) { + ret.push({ + body: body, + encodedBodyLength: len, + }); + } + + return ret; + }, + + /** + * Fragment UCS2 encodable string for transmission. + * + * @param text + * text string to be fragmented. + * @param segmentChars + * Number of available characters per segment. + * + * @return an array of objects. See #_fragmentText() for detailed definition. + */ + _fragmentTextUCS2: function _fragmentTextUCS2(text, segmentChars) { + let ret = []; + for (let offset = 0; offset < text.length; offset += segmentChars) { + let str = text.substr(offset, segmentChars); + ret.push({ + body: str, + encodedBodyLength: str.length * 2, + }); + } + + return ret; + }, + + /** + * Fragment string for transmission. + * + * Fragment input text string into an array of objects that contains + * attributes `body`, substring for this segment, `encodedBodyLength`, + * length of the encoded segment body in septets. + * + * @param text + * Text string to be fragmented. + * @param options + * Optional pre-calculated option object. The output array will be + * stored at options.segments if there are multiple segments. + * @param strict7BitEncoding + * Optional. Enable Latin characters replacement with corresponding + * ones in GSM SMS 7-bit default alphabet. + * + * @return Populated options object. + */ + _fragmentText: function _fragmentText(text, options, strict7BitEncoding) { + if (!options) { + options = this._calculateUserDataLength(text, strict7BitEncoding); + } + + if (options.dcs == RIL.PDU_DCS_MSG_CODING_7BITS_ALPHABET) { + const langTable = RIL.PDU_NL_LOCKING_SHIFT_TABLES[options.langIndex]; + const langShiftTable = RIL.PDU_NL_SINGLE_SHIFT_TABLES[options.langShiftIndex]; + options.segments = this._fragmentText7Bit(text, + langTable, langShiftTable, + options.segmentChars, + strict7BitEncoding); + } else { + options.segments = this._fragmentTextUCS2(text, + options.segmentChars); + } + + // Re-sync options.segmentMaxSeq with actual length of returning array. + options.segmentMaxSeq = options.segments.length; + + return options; + }, + + /** + * A helper to broadcast the system message to launch registered apps + * like Costcontrol, Notification and Message app... etc. + * + * @param aName + * The system message name. + * @param aDomMessage + * The nsIDOMMozSmsMessage object. + */ + _broadcastSystemMessage: function _broadcastSystemMessage(aName, aDomMessage) { + if (DEBUG) debug("Broadcasting the SMS system message: " + aName); + + // Sadly we cannot directly broadcast the aDomMessage object + // because the system message mechamism will rewrap the object + // based on the content window, which needs to know the properties. + gSystemMessenger.broadcastMessage(aName, { + type: aDomMessage.type, + id: aDomMessage.id, + threadId: aDomMessage.threadId, + delivery: aDomMessage.delivery, + deliveryStatus: aDomMessage.deliveryStatus, + sender: aDomMessage.sender, + receiver: aDomMessage.receiver, + body: aDomMessage.body, + messageClass: aDomMessage.messageClass, + timestamp: aDomMessage.timestamp, + read: aDomMessage.read + }); + }, + + /** + * Handle WDP port push PDU. Constructor WDP bearer information and deliver + * to WapPushManager. + * + * @param message + * A SMS message. + */ + _handleSmsWdpPortPush: function _handleSmsWdpPortPush(message) { + if (message.encoding != RIL.PDU_DCS_MSG_CODING_8BITS_ALPHABET) { + if (DEBUG) { + debug("Got port addressed SMS but not encoded in 8-bit alphabet." + + " Drop!"); + } + return; + } + + let options = { + bearer: WAP.WDP_BEARER_GSM_SMS_GSM_MSISDN, + sourceAddress: message.sender, + sourcePort: message.header.originatorPort, + destinationAddress: this.rilContext.iccInfo.msisdn, + destinationPort: message.header.destinationPort, + }; + WAP.WapPushManager.receiveWdpPDU(message.fullData, message.fullData.length, + 0, options); + }, + + _isSilentNumber: function _isSilentNumber(number) { + return this.silentNumbers.indexOf(number) >= 0; + }, + + /** + * nsISmsService methods. + */ + + // TODO: Bug 859616 - WebSMS: return undefined if the API is unsupported on + // the platform, not null + hasSupport: function hasSupport() { + return true; + }, + + getSegmentInfoForText: function getSegmentInfoForText(text) { + let strict7BitEncoding = this._getStrict7BitEncoding(); + + let options = this._fragmentText(text, null, strict7BitEncoding); + let charsInLastSegment; + if (options.segmentMaxSeq) { + let lastSegment = options.segments[options.segmentMaxSeq - 1]; + charsInLastSegment = lastSegment.encodedBodyLength; + if (options.dcs == RIL.PDU_DCS_MSG_CODING_16BITS_ALPHABET) { + // In UCS2 encoding, encodedBodyLength is in octets. + charsInLastSegment /= 2; + } + } else { + charsInLastSegment = 0; + } + + let result = gMobileMessageService.createSmsSegmentInfo(options.segmentMaxSeq, + options.segmentChars, + options.segmentChars - charsInLastSegment); + return result; + }, + + send: function send(number, message, silent, request) { + let strict7BitEncoding = this._getStrict7BitEncoding(); + let requestStatusReport = this._getRequestStatusReport(); + + let options = this._fragmentText(message, null, strict7BitEncoding); + options.number = gPhoneNumberUtils.normalize(number); + options.requestStatusReport = requestStatusReport && !silent; + if (options.segmentMaxSeq > 1) { + options.segmentRef16Bit = this.segmentRef16Bit; + options.segmentRef = this.nextSegmentRef; + } + + let notifyResult = (function notifyResult(rv, domMessage) { + // TODO bug 832140 handle !Components.isSuccessCode(rv) + if (!silent) { + Services.obs.notifyObservers(domMessage, kSmsSendingObserverTopic, null); + } + + // If the radio is disabled or the SIM card is not ready, just directly + // return with the corresponding error code. + let errorCode; + if (!gPhoneNumberUtils.isPlainPhoneNumber(options.number)) { + if (DEBUG) debug("Error! Address is invalid when sending SMS: " + + options.number); + errorCode = Ci.nsIMobileMessageCallback.INVALID_ADDRESS_ERROR; + } else if (gRadioInterface.rilContext.radioState != + RIL.GECKO_RADIOSTATE_READY) { + if (DEBUG) debug("Error! Radio is disabled when sending SMS."); + errorCode = Ci.nsIMobileMessageCallback.RADIO_DISABLED_ERROR; + } else if (gRadioInterface.rilContext.cardState != + RIL.GECKO_CARDSTATE_READY) { + if (DEBUG) debug("Error! SIM card is not ready when sending SMS."); + errorCode = Ci.nsIMobileMessageCallback.NO_SIM_CARD_ERROR; + } + if (errorCode) { + if (silent) { + request.notifySendMessageFailed(errorCode); + return; + } + + gMobileMessageDatabaseService + .setMessageDeliveryByMessageId(domMessage.id, + null, + DELIVERY_STATE_ERROR, + RIL.GECKO_SMS_DELIVERY_STATUS_ERROR, + null, + function notifyResult(rv, domMessage) { + // TODO bug 832140 handle !Components.isSuccessCode(rv) + request.notifySendMessageFailed(errorCode); + Services.obs.notifyObservers(domMessage, kSmsFailedObserverTopic, null); + }); + return; + } + + // Keep current SMS message info for sent/delivered notifications + let context = { + request: request, + sms: domMessage, + requestStatusReport: options.requestStatusReport, + silent: silent + }; + + // This is the entry point starting to send SMS. + gRadioInterface.sendWorkerMessage("sendSMS", options, + (function(context, response) { + if (response.errorMsg) { + // Failed to send SMS out. + let error = Ci.nsIMobileMessageCallback.UNKNOWN_ERROR; + switch (message.errorMsg) { + case RIL.ERROR_RADIO_NOT_AVAILABLE: + error = Ci.nsIMobileMessageCallback.NO_SIGNAL_ERROR; + break; + } + + if (context.silent) { + context.request.notifySendMessageFailed(error); + return false; + } + + gMobileMessageDatabaseService + .setMessageDeliveryByMessageId(context.sms.id, + null, + DELIVERY_STATE_ERROR, + RIL.GECKO_SMS_DELIVERY_STATUS_ERROR, + null, + function notifyResult(rv, domMessage) { + // TODO bug 832140 handle !Components.isSuccessCode(rv) + context.request.notifySendMessageFailed(error); + Services.obs.notifyObservers(domMessage, kSmsFailedObserverTopic, null); + }); + return false; + } // End of send failure. + + if (response.deliveryStatus) { + // Message delivery. + gMobileMessageDatabaseService + .setMessageDeliveryByMessageId(context.sms.id, + null, + context.sms.delivery, + message.deliveryStatus, + null, + function notifyResult(rv, domMessage) { + // TODO bug 832140 handle !Components.isSuccessCode(rv) + let topic = (message.deliveryStatus == RIL.GECKO_SMS_DELIVERY_STATUS_SUCCESS) + ? kSmsDeliverySuccessObserverTopic + : kSmsDeliveryErrorObserverTopic; + Services.obs.notifyObservers(domMessage, topic, null); + }); + + // Send transaction has ended completely. + return false; + } // End of message delivery. + + // Message sent. + if (context.silent) { + // There is no way to modify nsIDOMMozSmsMessage attributes as they are + // read only so we just create a new sms instance to send along with + // the notification. + let sms = context.sms; + context.request.notifyMessageSent( + gMobileMessageService.createSmsMessage(sms.id, + sms.threadId, + DELIVERY_STATE_SENT, + sms.deliveryStatus, + sms.sender, + sms.receiver, + sms.body, + sms.messageClass, + sms.timestamp, + sms.read)); + // We don't wait for SMS-DELIVER-REPORT for silent one. + return false; + } + + gMobileMessageDatabaseService + .setMessageDeliveryByMessageId(context.sms.id, + null, + DELIVERY_STATE_SENT, + context.sms.deliveryStatus, + null, + (function notifyResult(rv, domMessage) { + // TODO bug 832140 handle !Components.isSuccessCode(rv) + this._broadcastSystemMessage("sms-sent", domMessage); + + if (context.requestStatusReport) { + context.sms = domMessage; + } + + context.request.notifyMessageSent(domMessage); + Services.obs.notifyObservers(domMessage, kSmsSentObserverTopic, null); + }).bind(this)); + + // Only keep current context if we have requested for delivery report. + return context.requestStatusReport; + }).bind(this, context)); // End of |sendWorkerMessage| callback. + }).bind(this); // End of DB saveSendingMessage callback. + + let sendingMessage = { + type: "sms", + sender: this._getMsisdn(), + receiver: number, + body: message, + deliveryStatusRequested: options.requestStatusReport, + timestamp: Date.now() + }; + + if (silent) { + let deliveryStatus = RIL.GECKO_SMS_DELIVERY_STATUS_PENDING; + let delivery = DELIVERY_STATE_SENDING; + let domMessage = + gMobileMessageService.createSmsMessage(-1, // id + 0, // threadId + delivery, + deliveryStatus, + sendingMessage.sender, + sendingMessage.receiver, + sendingMessage.body, + "normal", // message class + sendingMessage.timestamp, + false); + notifyResult(Cr.NS_OK, domMessage); + return; + } + + let id = gMobileMessageDatabaseService.saveSendingMessage( + sendingMessage, notifyResult); + }, + + addSilentNumber: function addSilentNumber(number) { + if (this._isSilentNumber(number)) { + throw Cr.NS_ERROR_UNEXPECTED; + } + + this.silentNumbers.push(number); + }, + + removeSilentNumber: function removeSilentNumber(number) { + let index = this.silentNumbers.indexOf(number); + if (index < 0) { + throw Cr.NS_ERROR_INVALID_ARG; + } + + this.silentNumbers.splice(index, 1); + }, + + /** + * nsIRilSmsService methods. + */ + + notifyMessageReceived: function notifyMessageReceived(message) { + if (DEBUG) debug("notifyMessageReceived: " + JSON.stringify(message)); + + // FIXME: Bug 737202 - Typed arrays become normal arrays when sent to/from workers + if (message.encoding == RIL.PDU_DCS_MSG_CODING_8BITS_ALPHABET) { + message.fullData = new Uint8Array(message.fullData); + } + + // Dispatch to registered handler if application port addressing is + // available. Note that the destination port can possibly be zero when + // representing a UDP/TCP port. + if (message.header && message.header.destinationPort != null) { + let handler = this.portAddressedSmsApps[message.header.destinationPort]; + if (handler) { + handler(message); + } + gRadioInterface.sendWorkerMessage("ackSMS", { result: RIL.PDU_FCS_OK }); + return; + } + + if (message.encoding == RIL.PDU_DCS_MSG_CODING_8BITS_ALPHABET) { + // Don't know how to handle binary data yet. + gRadioInterface.sendWorkerMessage("ackSMS", { result: RIL.PDU_FCS_OK }); + return; + } + + message.type = "sms"; + message.sender = message.sender || null; + message.receiver = this._getMsisdn(); + message.body = message.fullBody = message.fullBody || null; + message.timestamp = Date.now(); + + if (this._isSilentNumber(message.sender)) { + message.id = -1; + message.threadId = 0; + message.delivery = DELIVERY_STATE_RECEIVED; + message.deliveryStatus = RIL.GECKO_SMS_DELIVERY_STATUS_SUCCESS; + message.read = false; + + let domMessage = + gMobileMessageService.createSmsMessage(message.id, + message.threadId, + message.delivery, + message.deliveryStatus, + message.sender, + message.receiver, + message.body, + message.messageClass, + message.timestamp, + message.read); + + Services.obs.notifyObservers(domMessage, + kSilentSmsReceivedObserverTopic, + null); + gRadioInterface.sendWorkerMessage("ackSMS", { result: RIL.PDU_FCS_OK }); + return; + } + + // TODO: Bug #768441 + // For now we don't store indicators persistently. When the mwi.discard + // flag is false, we'll need to persist the indicator to EFmwis. + // See TS 23.040 9.2.3.24.2 + + let mwi = message.mwi; + if (mwi) { + mwi.returnNumber = message.sender; + mwi.returnMessage = message.fullBody; + gMessageManager.sendVoicemailMessage("RIL:VoicemailNotification", + this.clientId, mwi); + gRadioInterface.sendWorkerMessage("ackSMS", { result: RIL.PDU_FCS_OK }); + return; + } + + let notifyReceived = function notifyReceived(rv, domMessage) { + let success = Components.isSuccessCode(rv); + + // Acknowledge the reception of the SMS. + gRadioInterface.sendWorkerMessage("ackSMS", { + result: (success ? RIL.PDU_FCS_OK + : RIL.PDU_FCS_MEMORY_CAPACITY_EXCEEDED) + }); + + if (!success) { + // At this point we could send a message to content to notify the user + // that storing an incoming SMS failed, most likely due to a full disk. + if (DEBUG) { + debug("Could not store SMS " + message.id + ", error code " + rv); + } + return; + } + + this._broadcastSystemMessage("sms-received", domMessage); + Services.obs.notifyObservers(domMessage, kSmsReceivedObserverTopic, null); + }.bind(this); + + if (message.messageClass == RIL.GECKO_SMS_MESSAGE_CLASSES[RIL.PDU_DCS_MSG_CLASS_0]) { + message.id = -1; + message.threadId = 0; + message.delivery = DELIVERY_STATE_RECEIVED; + message.deliveryStatus = RIL.GECKO_SMS_DELIVERY_STATUS_SUCCESS; + message.read = false; + + let domMessage = + gMobileMessageService.createSmsMessage(message.id, + message.threadId, + message.delivery, + message.deliveryStatus, + message.sender, + message.receiver, + message.body, + message.messageClass, + message.timestamp, + message.read); + + notifyReceived(Cr.NS_OK, domMessage); + return; + } + + message.id = + gMobileMessageDatabaseService.saveReceivedMessage(message, + notifyReceived); + }, + + /** + * nsIObserver methods. + */ + + observe: function observe(subject, topic, data) { + switch (topic) { + case kPrefenceChangedObserverTopic: + if (data === "ril.debugging.enabled") { + try { + DEBUG = RIL.DEBUG_RIL || + Services.prefs.getBoolPref("ril.debugging.enabled"); + } catch(e) {} + } + break; + + case kXpcomShutdownObserverTopic: + Services.obs.removeObserver(this, kPrefenceChangedObserverTopic); + Services.obs.removeObserver(this, kXpcomShutdownObserverTopic); + break; + } + } +}; + +this.NSGetFactory = XPCOMUtils.generateNSGetFactory([SmsService]); diff --git a/dom/mobilemessage/src/gonk/SmsService.manifest b/dom/mobilemessage/src/gonk/SmsService.manifest new file mode 100644 index 00000000000..0275b5a2be3 --- /dev/null +++ b/dom/mobilemessage/src/gonk/SmsService.manifest @@ -0,0 +1,3 @@ +# SmsService.js +component {46a9ed78-3574-40a1-9f12-ea179942d67f} SmsService.js +contract @mozilla.org/sms/rilsmsservice;1 {46a9ed78-3574-40a1-9f12-ea179942d67f} diff --git a/dom/mobilemessage/src/ipc/SmsIPCService.cpp b/dom/mobilemessage/src/ipc/SmsIPCService.cpp index eebcbdc9a4e..0dd5d26d29d 100644 --- a/dom/mobilemessage/src/ipc/SmsIPCService.cpp +++ b/dom/mobilemessage/src/ipc/SmsIPCService.cpp @@ -123,14 +123,6 @@ SmsIPCService::Send(const nsAString& aNumber, aRequest); } -NS_IMETHODIMP -SmsIPCService::IsSilentNumber(const nsAString& aNumber, - bool* aIsSilent) -{ - NS_ERROR("We should not be here!"); - return NS_ERROR_FAILURE; -} - NS_IMETHODIMP SmsIPCService::AddSilentNumber(const nsAString& aNumber) { diff --git a/dom/mobilemessage/src/moz.build b/dom/mobilemessage/src/moz.build index 505fddd8242..fa72d68ae99 100644 --- a/dom/mobilemessage/src/moz.build +++ b/dom/mobilemessage/src/moz.build @@ -36,6 +36,7 @@ else: CPP_SOURCES += [ 'MobileMessageDatabaseService.cpp', 'MmsService.cpp', + 'SmsService.cpp', ] EXPORTS.mozilla.dom += [ @@ -60,7 +61,6 @@ CPP_SOURCES += [ 'SmsMessage.cpp', 'SmsParent.cpp', 'SmsSegmentInfo.cpp', - 'SmsService.cpp', 'SmsServicesFactory.cpp', ] @@ -70,6 +70,8 @@ if CONFIG['MOZ_B2G_RIL']: 'gonk/MmsService.manifest', 'gonk/MobileMessageDatabaseService.js', 'gonk/MobileMessageDatabaseService.manifest', + 'gonk/SmsService.js', + 'gonk/SmsService.manifest', ] IPDL_SOURCES += [ diff --git a/dom/system/gonk/RadioInterfaceLayer.js b/dom/system/gonk/RadioInterfaceLayer.js index ee6547120ac..3857aeb5090 100644 --- a/dom/system/gonk/RadioInterfaceLayer.js +++ b/dom/system/gonk/RadioInterfaceLayer.js @@ -47,13 +47,6 @@ const RILNETWORKINTERFACE_CID = Components.ID("{3bdd52a9-3965-4130-b569-0ac5afed045e}"); const kNetworkInterfaceStateChangedTopic = "network-interface-state-changed"; -const kSmsReceivedObserverTopic = "sms-received"; -const kSilentSmsReceivedObserverTopic = "silent-sms-received"; -const kSmsSendingObserverTopic = "sms-sending"; -const kSmsSentObserverTopic = "sms-sent"; -const kSmsFailedObserverTopic = "sms-failed"; -const kSmsDeliverySuccessObserverTopic = "sms-delivery-success"; -const kSmsDeliveryErrorObserverTopic = "sms-delivery-error"; const kMozSettingsChangedObserverTopic = "mozsettings-changed"; const kSysMsgListenerReadyObserverTopic = "system-message-listener-ready"; const kSysClockChangeObserverTopic = "system-clock-change"; @@ -119,17 +112,9 @@ XPCOMUtils.defineLazyServiceGetter(this, "gPowerManagerService", "@mozilla.org/power/powermanagerservice;1", "nsIPowerManagerService"); -XPCOMUtils.defineLazyServiceGetter(this, "gMobileMessageService", - "@mozilla.org/mobilemessage/mobilemessageservice;1", - "nsIMobileMessageService"); - XPCOMUtils.defineLazyServiceGetter(this, "gSmsService", - "@mozilla.org/sms/smsservice;1", - "nsISmsService"); - -XPCOMUtils.defineLazyServiceGetter(this, "gMobileMessageDatabaseService", - "@mozilla.org/mobilemessage/rilmobilemessagedatabaseservice;1", - "nsIRilMobileMessageDatabaseService"); + "@mozilla.org/sms/rilsmsservice;1", + "nsIRilSmsService"); XPCOMUtils.defineLazyServiceGetter(this, "gSettingsService", "@mozilla.org/settingsService;1", @@ -155,12 +140,6 @@ XPCOMUtils.defineLazyServiceGetter(this, "gTelephonyProvider", "@mozilla.org/telephony/telephonyprovider;1", "nsIGonkTelephonyProvider"); -XPCOMUtils.defineLazyGetter(this, "WAP", function () { - let wap = {}; - Cu.import("resource://gre/modules/WapPushManager.js", wap); - return wap; -}); - XPCOMUtils.defineLazyGetter(this, "PhoneNumberUtils", function () { let ns = {}; Cu.import("resource://gre/modules/PhoneNumberUtils.jsm", ns); @@ -467,9 +446,6 @@ function RadioInterface(options) { Services.obs.addObserver(this, kScreenStateChangedTopic, false); Services.prefs.addObserver(kCellBroadcastDisabled, this, false); - - this.portAddressedSmsApps = {}; - this.portAddressedSmsApps[WAP.WDP_PORT_PUSH] = this.handleSmsWdpPortPush.bind(this); } RadioInterface.prototype = { @@ -697,11 +673,8 @@ RadioInterface.prototype = { this.clientId, message); break; case "sms-received": - let ackOk = this.handleSmsReceived(message); - if (ackOk) { - this.workerMessenger.send("ackSMS", { result: RIL.PDU_FCS_OK }); - } - return; + gSmsService.notifyMessageReceived(message); + break; case "cellbroadcast-received": message.timestamp = Date.now(); gMessageManager.sendCellBroadcastMessage("RIL:CellBroadcastReceived", @@ -748,18 +721,6 @@ RadioInterface.prototype = { } }, - getMsisdn: function getMsisdn() { - let iccInfo = this.rilContext.iccInfo; - let number = iccInfo ? iccInfo.msisdn : null; - - // Workaround an xpconnect issue with undefined string objects. - // See bug 808220 - if (number === undefined || number === "undefined") { - return null; - } - return number; - }, - updateNetworkInfo: function updateNetworkInfo(message) { let voiceMessage = message[RIL.NETWORK_INFO_VOICE_REGISTRATION_STATE]; let dataMessage = message[RIL.NETWORK_INFO_DATA_REGISTRATION_STATE]; @@ -1326,184 +1287,6 @@ RadioInterface.prototype = { this.clientId, message); }, - /** - * Handle WDP port push PDU. Constructor WDP bearer information and deliver - * to WapPushManager. - * - * @param message - * A SMS message. - */ - handleSmsWdpPortPush: function handleSmsWdpPortPush(message) { - if (message.encoding != RIL.PDU_DCS_MSG_CODING_8BITS_ALPHABET) { - if (DEBUG) { - this.debug("Got port addressed SMS but not encoded in 8-bit alphabet." + - " Drop!"); - } - return; - } - - let options = { - bearer: WAP.WDP_BEARER_GSM_SMS_GSM_MSISDN, - sourceAddress: message.sender, - sourcePort: message.header.originatorPort, - destinationAddress: this.rilContext.iccInfo.msisdn, - destinationPort: message.header.destinationPort, - }; - WAP.WapPushManager.receiveWdpPDU(message.fullData, message.fullData.length, - 0, options); - }, - - /** - * A helper to broadcast the system message to launch registered apps - * like Costcontrol, Notification and Message app... etc. - * - * @param aName - * The system message name. - * @param aDomMessage - * The nsIDOMMozSmsMessage object. - */ - broadcastSmsSystemMessage: function broadcastSmsSystemMessage(aName, aDomMessage) { - if (DEBUG) this.debug("Broadcasting the SMS system message: " + aName); - - // Sadly we cannot directly broadcast the aDomMessage object - // because the system message mechamism will rewrap the object - // based on the content window, which needs to know the properties. - gSystemMessenger.broadcastMessage(aName, { - type: aDomMessage.type, - id: aDomMessage.id, - threadId: aDomMessage.threadId, - delivery: aDomMessage.delivery, - deliveryStatus: aDomMessage.deliveryStatus, - sender: aDomMessage.sender, - receiver: aDomMessage.receiver, - body: aDomMessage.body, - messageClass: aDomMessage.messageClass, - timestamp: aDomMessage.timestamp, - read: aDomMessage.read - }); - }, - - portAddressedSmsApps: null, - handleSmsReceived: function handleSmsReceived(message) { - if (DEBUG) this.debug("handleSmsReceived: " + JSON.stringify(message)); - - // FIXME: Bug 737202 - Typed arrays become normal arrays when sent to/from workers - if (message.encoding == RIL.PDU_DCS_MSG_CODING_8BITS_ALPHABET) { - message.fullData = new Uint8Array(message.fullData); - } - - // Dispatch to registered handler if application port addressing is - // available. Note that the destination port can possibly be zero when - // representing a UDP/TCP port. - if (message.header && message.header.destinationPort != null) { - let handler = this.portAddressedSmsApps[message.header.destinationPort]; - if (handler) { - handler(message); - } - return true; - } - - if (message.encoding == RIL.PDU_DCS_MSG_CODING_8BITS_ALPHABET) { - // Don't know how to handle binary data yet. - return true; - } - - message.type = "sms"; - message.sender = message.sender || null; - message.receiver = this.getMsisdn(); - message.body = message.fullBody = message.fullBody || null; - message.timestamp = Date.now(); - - if (gSmsService.isSilentNumber(message.sender)) { - message.id = -1; - message.threadId = 0; - message.delivery = DOM_MOBILE_MESSAGE_DELIVERY_RECEIVED; - message.deliveryStatus = RIL.GECKO_SMS_DELIVERY_STATUS_SUCCESS; - message.read = false; - - let domMessage = - gMobileMessageService.createSmsMessage(message.id, - message.threadId, - message.delivery, - message.deliveryStatus, - message.sender, - message.receiver, - message.body, - message.messageClass, - message.timestamp, - message.read); - - Services.obs.notifyObservers(domMessage, - kSilentSmsReceivedObserverTopic, - null); - return true; - } - - // TODO: Bug #768441 - // For now we don't store indicators persistently. When the mwi.discard - // flag is false, we'll need to persist the indicator to EFmwis. - // See TS 23.040 9.2.3.24.2 - - let mwi = message.mwi; - if (mwi) { - mwi.returnNumber = message.sender; - mwi.returnMessage = message.fullBody; - gMessageManager.sendVoicemailMessage("RIL:VoicemailNotification", - this.clientId, mwi); - return true; - } - - let notifyReceived = function notifyReceived(rv, domMessage) { - let success = Components.isSuccessCode(rv); - - // Acknowledge the reception of the SMS. - this.workerMessenger.send("ackSMS", { - result: (success ? RIL.PDU_FCS_OK - : RIL.PDU_FCS_MEMORY_CAPACITY_EXCEEDED) - }); - - if (!success) { - // At this point we could send a message to content to notify the user - // that storing an incoming SMS failed, most likely due to a full disk. - if (DEBUG) { - this.debug("Could not store SMS " + message.id + ", error code " + rv); - } - return; - } - - this.broadcastSmsSystemMessage("sms-received", domMessage); - Services.obs.notifyObservers(domMessage, kSmsReceivedObserverTopic, null); - }.bind(this); - - if (message.messageClass != RIL.GECKO_SMS_MESSAGE_CLASSES[RIL.PDU_DCS_MSG_CLASS_0]) { - message.id = gMobileMessageDatabaseService.saveReceivedMessage(message, - notifyReceived); - } else { - message.id = -1; - message.threadId = 0; - message.delivery = DOM_MOBILE_MESSAGE_DELIVERY_RECEIVED; - message.deliveryStatus = RIL.GECKO_SMS_DELIVERY_STATUS_SUCCESS; - message.read = false; - - let domMessage = - gMobileMessageService.createSmsMessage(message.id, - message.threadId, - message.delivery, - message.deliveryStatus, - message.sender, - message.receiver, - message.body, - message.messageClass, - message.timestamp, - message.read); - - notifyReceived(Cr.NS_OK, domMessage); - } - - // SMS ACK will be sent in notifyReceived. Return false here. - return false; - }, - /** * Handle data call state changes. */ @@ -1923,622 +1706,6 @@ RadioInterface.prototype = { }).bind(this)); }, - /** - * List of tuples of national language identifier pairs. - * - * TODO: Support static/runtime settings, see bug 733331. - */ - enabledGsmTableTuples: [ - [RIL.PDU_NL_IDENTIFIER_DEFAULT, RIL.PDU_NL_IDENTIFIER_DEFAULT], - ], - - /** - * Use 16-bit reference number for concatenated outgoint messages. - * - * TODO: Support static/runtime settings, see bug 733331. - */ - segmentRef16Bit: false, - - /** - * Get valid SMS concatenation reference number. - */ - _segmentRef: 0, - get nextSegmentRef() { - let ref = this._segmentRef++; - - this._segmentRef %= (this.segmentRef16Bit ? 65535 : 255); - - // 0 is not a valid SMS concatenation reference number. - return ref + 1; - }, - - /** - * Calculate encoded length using specified locking/single shift table - * - * @param message - * message string to be encoded. - * @param langTable - * locking shift table string. - * @param langShiftTable - * single shift table string. - * @param strict7BitEncoding - * Optional. Enable Latin characters replacement with corresponding - * ones in GSM SMS 7-bit default alphabet. - * - * @return encoded length in septets. - * - * @note that the algorithm used in this function must match exactly with - * GsmPDUHelper#writeStringAsSeptets. - */ - _countGsm7BitSeptets: function _countGsm7BitSeptets(message, langTable, langShiftTable, strict7BitEncoding) { - let length = 0; - for (let msgIndex = 0; msgIndex < message.length; msgIndex++) { - let c = message.charAt(msgIndex); - if (strict7BitEncoding) { - c = RIL.GSM_SMS_STRICT_7BIT_CHARMAP[c] || c; - } - - let septet = langTable.indexOf(c); - - // According to 3GPP TS 23.038, section 6.1.1 General notes, "The - // characters marked '1)' are not used but are displayed as a space." - if (septet == RIL.PDU_NL_EXTENDED_ESCAPE) { - continue; - } - - if (septet >= 0) { - length++; - continue; - } - - septet = langShiftTable.indexOf(c); - if (septet < 0) { - if (!strict7BitEncoding) { - return -1; - } - - // Bug 816082, when strict7BitEncoding is enabled, we should replace - // characters that can't be encoded with GSM 7-Bit alphabets with '*'. - c = '*'; - if (langTable.indexOf(c) >= 0) { - length++; - } else if (langShiftTable.indexOf(c) >= 0) { - length += 2; - } else { - // We can't even encode a '*' character with current configuration. - return -1; - } - - continue; - } - - // According to 3GPP TS 23.038 B.2, "This code represents a control - // character and therefore must not be used for language specific - // characters." - if (septet == RIL.PDU_NL_RESERVED_CONTROL) { - continue; - } - - // The character is not found in locking shfit table, but could be - // encoded as with single shift table. Note that it's - // still possible for septet to has the value of PDU_NL_EXTENDED_ESCAPE, - // but we can display it as a space in this case as said in previous - // comment. - length += 2; - } - - return length; - }, - - /** - * Calculate user data length of specified message string encoded in GSM 7Bit - * alphabets. - * - * @param message - * a message string to be encoded. - * @param strict7BitEncoding - * Optional. Enable Latin characters replacement with corresponding - * ones in GSM SMS 7-bit default alphabet. - * - * @return null or an options object with attributes `dcs`, - * `userDataHeaderLength`, `encodedFullBodyLength`, `langIndex`, - * `langShiftIndex`, `segmentMaxSeq` set. - * - * @see #_calculateUserDataLength(). - */ - _calculateUserDataLength7Bit: function _calculateUserDataLength7Bit(message, strict7BitEncoding) { - let options = null; - let minUserDataSeptets = Number.MAX_VALUE; - for (let i = 0; i < this.enabledGsmTableTuples.length; i++) { - let [langIndex, langShiftIndex] = this.enabledGsmTableTuples[i]; - - const langTable = RIL.PDU_NL_LOCKING_SHIFT_TABLES[langIndex]; - const langShiftTable = RIL.PDU_NL_SINGLE_SHIFT_TABLES[langShiftIndex]; - - let bodySeptets = this._countGsm7BitSeptets(message, - langTable, - langShiftTable, - strict7BitEncoding); - if (bodySeptets < 0) { - continue; - } - - let headerLen = 0; - if (langIndex != RIL.PDU_NL_IDENTIFIER_DEFAULT) { - headerLen += 3; // IEI + len + langIndex - } - if (langShiftIndex != RIL.PDU_NL_IDENTIFIER_DEFAULT) { - headerLen += 3; // IEI + len + langShiftIndex - } - - // Calculate full user data length, note the extra byte is for header len - let headerSeptets = Math.ceil((headerLen ? headerLen + 1 : 0) * 8 / 7); - let segmentSeptets = RIL.PDU_MAX_USER_DATA_7BIT; - if ((bodySeptets + headerSeptets) > segmentSeptets) { - headerLen += this.segmentRef16Bit ? 6 : 5; - headerSeptets = Math.ceil((headerLen + 1) * 8 / 7); - segmentSeptets -= headerSeptets; - } - - let segments = Math.ceil(bodySeptets / segmentSeptets); - let userDataSeptets = bodySeptets + headerSeptets * segments; - if (userDataSeptets >= minUserDataSeptets) { - continue; - } - - minUserDataSeptets = userDataSeptets; - - options = { - dcs: RIL.PDU_DCS_MSG_CODING_7BITS_ALPHABET, - encodedFullBodyLength: bodySeptets, - userDataHeaderLength: headerLen, - langIndex: langIndex, - langShiftIndex: langShiftIndex, - segmentMaxSeq: segments, - segmentChars: segmentSeptets, - }; - } - - return options; - }, - - /** - * Calculate user data length of specified message string encoded in UCS2. - * - * @param message - * a message string to be encoded. - * - * @return an options object with attributes `dcs`, `userDataHeaderLength`, - * `encodedFullBodyLength`, `segmentMaxSeq` set. - * - * @see #_calculateUserDataLength(). - */ - _calculateUserDataLengthUCS2: function _calculateUserDataLengthUCS2(message) { - let bodyChars = message.length; - let headerLen = 0; - let headerChars = Math.ceil((headerLen ? headerLen + 1 : 0) / 2); - let segmentChars = RIL.PDU_MAX_USER_DATA_UCS2; - if ((bodyChars + headerChars) > segmentChars) { - headerLen += this.segmentRef16Bit ? 6 : 5; - headerChars = Math.ceil((headerLen + 1) / 2); - segmentChars -= headerChars; - } - - let segments = Math.ceil(bodyChars / segmentChars); - - return { - dcs: RIL.PDU_DCS_MSG_CODING_16BITS_ALPHABET, - encodedFullBodyLength: bodyChars * 2, - userDataHeaderLength: headerLen, - segmentMaxSeq: segments, - segmentChars: segmentChars, - }; - }, - - /** - * Calculate user data length and its encoding. - * - * @param message - * a message string to be encoded. - * @param strict7BitEncoding - * Optional. Enable Latin characters replacement with corresponding - * ones in GSM SMS 7-bit default alphabet. - * - * @return an options object with some or all of following attributes set: - * - * @param dcs - * Data coding scheme. One of the PDU_DCS_MSG_CODING_*BITS_ALPHABET - * constants. - * @param userDataHeaderLength - * Length of embedded user data header, in bytes. The whole header - * size will be userDataHeaderLength + 1; 0 for no header. - * @param encodedFullBodyLength - * Length of the message body when encoded with the given DCS. For - * UCS2, in bytes; for 7-bit, in septets. - * @param langIndex - * Table index used for normal 7-bit encoded character lookup. - * @param langShiftIndex - * Table index used for escaped 7-bit encoded character lookup. - * @param segmentMaxSeq - * Max sequence number of a multi-part messages, or 1 for single one. - * This number might not be accurate for a multi-part message until - * it's processed by #_fragmentText() again. - */ - _calculateUserDataLength: function _calculateUserDataLength(message, strict7BitEncoding) { - let options = this._calculateUserDataLength7Bit(message, strict7BitEncoding); - if (!options) { - options = this._calculateUserDataLengthUCS2(message); - } - - if (DEBUG) this.debug("_calculateUserDataLength: " + JSON.stringify(options)); - return options; - }, - - /** - * Fragment GSM 7-Bit encodable string for transmission. - * - * @param text - * text string to be fragmented. - * @param langTable - * locking shift table string. - * @param langShiftTable - * single shift table string. - * @param segmentSeptets - * Number of available spetets per segment. - * @param strict7BitEncoding - * Optional. Enable Latin characters replacement with corresponding - * ones in GSM SMS 7-bit default alphabet. - * - * @return an array of objects. See #_fragmentText() for detailed definition. - */ - _fragmentText7Bit: function _fragmentText7Bit(text, langTable, langShiftTable, segmentSeptets, strict7BitEncoding) { - let ret = []; - let body = "", len = 0; - for (let i = 0, inc = 0; i < text.length; i++) { - let c = text.charAt(i); - if (strict7BitEncoding) { - c = RIL.GSM_SMS_STRICT_7BIT_CHARMAP[c] || c; - } - - let septet = langTable.indexOf(c); - if (septet == RIL.PDU_NL_EXTENDED_ESCAPE) { - continue; - } - - if (septet >= 0) { - inc = 1; - } else { - septet = langShiftTable.indexOf(c); - if (septet == RIL.PDU_NL_RESERVED_CONTROL) { - continue; - } - - inc = 2; - if (septet < 0) { - if (!strict7BitEncoding) { - throw new Error("Given text cannot be encoded with GSM 7-bit Alphabet!"); - } - - // Bug 816082, when strict7BitEncoding is enabled, we should replace - // characters that can't be encoded with GSM 7-Bit alphabets with '*'. - c = '*'; - if (langTable.indexOf(c) >= 0) { - inc = 1; - } - } - } - - if ((len + inc) > segmentSeptets) { - ret.push({ - body: body, - encodedBodyLength: len, - }); - body = c; - len = inc; - } else { - body += c; - len += inc; - } - } - - if (len) { - ret.push({ - body: body, - encodedBodyLength: len, - }); - } - - return ret; - }, - - /** - * Fragment UCS2 encodable string for transmission. - * - * @param text - * text string to be fragmented. - * @param segmentChars - * Number of available characters per segment. - * - * @return an array of objects. See #_fragmentText() for detailed definition. - */ - _fragmentTextUCS2: function _fragmentTextUCS2(text, segmentChars) { - let ret = []; - for (let offset = 0; offset < text.length; offset += segmentChars) { - let str = text.substr(offset, segmentChars); - ret.push({ - body: str, - encodedBodyLength: str.length * 2, - }); - } - - return ret; - }, - - /** - * Fragment string for transmission. - * - * Fragment input text string into an array of objects that contains - * attributes `body`, substring for this segment, `encodedBodyLength`, - * length of the encoded segment body in septets. - * - * @param text - * Text string to be fragmented. - * @param options - * Optional pre-calculated option object. The output array will be - * stored at options.segments if there are multiple segments. - * @param strict7BitEncoding - * Optional. Enable Latin characters replacement with corresponding - * ones in GSM SMS 7-bit default alphabet. - * - * @return Populated options object. - */ - _fragmentText: function _fragmentText(text, options, strict7BitEncoding) { - if (!options) { - options = this._calculateUserDataLength(text, strict7BitEncoding); - } - - if (options.dcs == RIL.PDU_DCS_MSG_CODING_7BITS_ALPHABET) { - const langTable = RIL.PDU_NL_LOCKING_SHIFT_TABLES[options.langIndex]; - const langShiftTable = RIL.PDU_NL_SINGLE_SHIFT_TABLES[options.langShiftIndex]; - options.segments = this._fragmentText7Bit(text, - langTable, langShiftTable, - options.segmentChars, - strict7BitEncoding); - } else { - options.segments = this._fragmentTextUCS2(text, - options.segmentChars); - } - - // Re-sync options.segmentMaxSeq with actual length of returning array. - options.segmentMaxSeq = options.segments.length; - - return options; - }, - - getSegmentInfoForText: function getSegmentInfoForText(text) { - let strict7BitEncoding; - try { - strict7BitEncoding = Services.prefs.getBoolPref("dom.sms.strict7BitEncoding"); - } catch (e) { - strict7BitEncoding = false; - } - - let options = this._fragmentText(text, null, strict7BitEncoding); - let charsInLastSegment; - if (options.segmentMaxSeq) { - let lastSegment = options.segments[options.segmentMaxSeq - 1]; - charsInLastSegment = lastSegment.encodedBodyLength; - if (options.dcs == RIL.PDU_DCS_MSG_CODING_16BITS_ALPHABET) { - // In UCS2 encoding, encodedBodyLength is in octets. - charsInLastSegment /= 2; - } - } else { - charsInLastSegment = 0; - } - - let result = gMobileMessageService.createSmsSegmentInfo(options.segmentMaxSeq, - options.segmentChars, - options.segmentChars - charsInLastSegment); - return result; - }, - - sendSMS: function sendSMS(number, message, silent, request) { - let strict7BitEncoding; - try { - strict7BitEncoding = Services.prefs.getBoolPref("dom.sms.strict7BitEncoding"); - } catch (e) { - strict7BitEncoding = false; - } - - let options = this._fragmentText(message, null, strict7BitEncoding); - options.number = PhoneNumberUtils.normalize(number); - let requestStatusReport; - try { - requestStatusReport = - Services.prefs.getBoolPref("dom.sms.requestStatusReport"); - } catch (e) { - requestStatusReport = true; - } - options.requestStatusReport = requestStatusReport && !silent; - if (options.segmentMaxSeq > 1) { - options.segmentRef16Bit = this.segmentRef16Bit; - options.segmentRef = this.nextSegmentRef; - } - - let notifyResult = (function notifyResult(rv, domMessage) { - // TODO bug 832140 handle !Components.isSuccessCode(rv) - if (!silent) { - Services.obs.notifyObservers(domMessage, kSmsSendingObserverTopic, null); - } - - // If the radio is disabled or the SIM card is not ready, just directly - // return with the corresponding error code. - let errorCode; - if (!PhoneNumberUtils.isPlainPhoneNumber(options.number)) { - if (DEBUG) this.debug("Error! Address is invalid when sending SMS: " + - options.number); - errorCode = Ci.nsIMobileMessageCallback.INVALID_ADDRESS_ERROR; - } else if (!this._radioEnabled) { - if (DEBUG) this.debug("Error! Radio is disabled when sending SMS."); - errorCode = Ci.nsIMobileMessageCallback.RADIO_DISABLED_ERROR; - } else if (this.rilContext.cardState != "ready") { - if (DEBUG) this.debug("Error! SIM card is not ready when sending SMS."); - errorCode = Ci.nsIMobileMessageCallback.NO_SIM_CARD_ERROR; - } - if (errorCode) { - if (silent) { - request.notifySendMessageFailed(errorCode); - return; - } - - gMobileMessageDatabaseService - .setMessageDeliveryByMessageId(domMessage.id, - null, - DOM_MOBILE_MESSAGE_DELIVERY_ERROR, - RIL.GECKO_SMS_DELIVERY_STATUS_ERROR, - null, - function notifyResult(rv, domMessage) { - // TODO bug 832140 handle !Components.isSuccessCode(rv) - request.notifySendMessageFailed(errorCode); - Services.obs.notifyObservers(domMessage, kSmsFailedObserverTopic, null); - }); - return; - } - - // Keep current SMS message info for sent/delivered notifications - let context = { - request: request, - sms: domMessage, - requestStatusReport: options.requestStatusReport, - silent: silent - }; - - // This is the entry point starting to send SMS. - this.workerMessenger.send("sendSMS", options, - (function(context, response) { - if (response.errorMsg) { - // Failed to send SMS out. - let error = Ci.nsIMobileMessageCallback.UNKNOWN_ERROR; - switch (message.errorMsg) { - case RIL.ERROR_RADIO_NOT_AVAILABLE: - error = Ci.nsIMobileMessageCallback.NO_SIGNAL_ERROR; - break; - } - - if (context.silent) { - context.request.notifySendMessageFailed(error); - return false; - } - - gMobileMessageDatabaseService - .setMessageDeliveryByMessageId(context.sms.id, - null, - DOM_MOBILE_MESSAGE_DELIVERY_ERROR, - RIL.GECKO_SMS_DELIVERY_STATUS_ERROR, - null, - function notifyResult(rv, domMessage) { - // TODO bug 832140 handle !Components.isSuccessCode(rv) - context.request.notifySendMessageFailed(error); - Services.obs.notifyObservers(domMessage, kSmsFailedObserverTopic, null); - }); - return false; - } // End of send failure. - - if (response.deliveryStatus) { - // Message delivery. - gMobileMessageDatabaseService - .setMessageDeliveryByMessageId(context.sms.id, - null, - context.sms.delivery, - response.deliveryStatus, - null, - function notifyResult(rv, domMessage) { - // TODO bug 832140 handle !Components.isSuccessCode(rv) - let topic = (response.deliveryStatus == RIL.GECKO_SMS_DELIVERY_STATUS_SUCCESS) - ? kSmsDeliverySuccessObserverTopic - : kSmsDeliveryErrorObserverTopic; - Services.obs.notifyObservers(domMessage, topic, null); - }); - - // Send transaction has ended completely. - return false; - } // End of message delivery. - - // Message sent. - if (context.silent) { - // There is no way to modify nsIDOMMozSmsMessage attributes as they are - // read only so we just create a new sms instance to send along with - // the notification. - let sms = context.sms; - context.request.notifyMessageSent( - gMobileMessageService.createSmsMessage(sms.id, - sms.threadId, - DOM_MOBILE_MESSAGE_DELIVERY_SENT, - sms.deliveryStatus, - sms.sender, - sms.receiver, - sms.body, - sms.messageClass, - sms.timestamp, - sms.read)); - // We don't wait for SMS-DELIVER-REPORT for silent one. - return false; - } - - gMobileMessageDatabaseService - .setMessageDeliveryByMessageId(context.sms.id, - null, - DOM_MOBILE_MESSAGE_DELIVERY_SENT, - context.sms.deliveryStatus, - null, - (function notifyResult(rv, domMessage) { - // TODO bug 832140 handle !Components.isSuccessCode(rv) - this.broadcastSmsSystemMessage("sms-sent", domMessage); - - if (context.requestStatusReport) { - context.sms = domMessage; - } - - context.request.notifyMessageSent(domMessage); - Services.obs.notifyObservers(domMessage, kSmsSentObserverTopic, null); - }).bind(this)); - - // Only keep current context if we have requested for delivery report. - return context.requestStatusReport; - }).bind(this, context)); // End of |workerMessenger.send| callback. - }).bind(this); // End of DB saveSendingMessage callback. - - let sendingMessage = { - type: "sms", - sender: this.getMsisdn(), - receiver: number, - body: message, - deliveryStatusRequested: options.requestStatusReport, - timestamp: Date.now() - }; - - if (silent) { - let deliveryStatus = RIL.GECKO_SMS_DELIVERY_STATUS_PENDING; - let delivery = DOM_MOBILE_MESSAGE_DELIVERY_SENDING; - let domMessage = - gMobileMessageService.createSmsMessage(-1, // id - 0, // threadId - delivery, - deliveryStatus, - sendingMessage.sender, - sendingMessage.receiver, - sendingMessage.body, - "normal", // message class - sendingMessage.timestamp, - false); - notifyResult(Cr.NS_OK, domMessage); - return; - } - - let id = gMobileMessageDatabaseService.saveSendingMessage( - sendingMessage, notifyResult); - }, - registerDataCallCallback: function registerDataCallCallback(callback) { if (this._datacall_callbacks) { if (this._datacall_callbacks.indexOf(callback) != -1) { diff --git a/dom/system/gonk/nsIRadioInterfaceLayer.idl b/dom/system/gonk/nsIRadioInterfaceLayer.idl index c9c7eeb51ae..770c1e1acf7 100644 --- a/dom/system/gonk/nsIRadioInterfaceLayer.idl +++ b/dom/system/gonk/nsIRadioInterfaceLayer.idl @@ -6,8 +6,6 @@ interface nsIDOMMozIccInfo; interface nsIDOMMozMobileConnectionInfo; -interface nsIDOMMozSmsSegmentInfo; -interface nsIMobileMessageCallback; [scriptable, uuid(1e602d20-d066-4399-8997-daf36b3158ef)] interface nsIRILDataCallInfo : nsISupports @@ -85,7 +83,7 @@ interface nsIRilSendWorkerMessageCallback : nsISupports boolean handleResponse(in jsval response); }; -[scriptable, uuid(61a8ca67-6113-4cd0-b443-e045f09863ed)] +[scriptable, uuid(b1af7aad-6547-427c-a878-e2ebf98a14d6)] interface nsIRadioInterface : nsISupports { readonly attribute nsIRilContext rilContext; @@ -102,16 +100,6 @@ interface nsIRadioInterface : nsISupports void updateRILNetworkInterface(); - /** - * SMS-related functionality. - */ - nsIDOMMozSmsSegmentInfo getSegmentInfoForText(in DOMString text); - - void sendSMS(in DOMString number, - in DOMString message, - in boolean silent, - in nsIMobileMessageCallback request); - void sendWorkerMessage(in DOMString type, [optional] in jsval message, [optional] in nsIRilSendWorkerMessageCallback callback); From 0b11c21fcc1f737ea337b2e7b338ba6f4eda5d5f Mon Sep 17 00:00:00 2001 From: Gaia Pushbot Date: Wed, 4 Sep 2013 01:05:21 -0700 Subject: [PATCH 008/171] Bumping gaia.json for 4 gaia-central revision(s) ======== https://hg.mozilla.org/integration/gaia-central/rev/1070079a0891 Author: Sam Joch Desc: Merge pull request #11891 from pivanov/bug-907672 Bug 907672 - [HD][Settings] Locked Wifi Connection icon jumps r=samjoch ======== https://hg.mozilla.org/integration/gaia-central/rev/919a94bc9779 Author: Pavel Ivanov Desc: Bug 907672 - [HD][Settings] Locked Wifi Connection icon jumps ======== https://hg.mozilla.org/integration/gaia-central/rev/126b0c924243 Author: Sam Joch Desc: Merge pull request #11892 from pivanov/bug-907729 Bug 907729 - [HD][FTU] Locked Wifi Icons Jump when connecting r=samjoch ======== https://hg.mozilla.org/integration/gaia-central/rev/935699cbb51f Author: Pavel Ivanov Desc: Bug 907729 - [HD][FTU] Locked Wifi Icons Jump when connecting --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 40bb561fb88..147da773a1e 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,4 +1,4 @@ { - "revision": "752ced5b3cc3208f79806eccf8d8768910f17f2b", + "revision": "1070079a0891d8aec9f1e9fff1a1e41bc96c3313", "repo_path": "/integration/gaia-central" } From 82ba8da58bc54d472b4f74fc30fd250b2e79451d Mon Sep 17 00:00:00 2001 From: Chia-hung Tai Date: Wed, 4 Sep 2013 14:50:27 +0800 Subject: [PATCH 009/171] Bug 907140 - [B2G][MMS] Block sending email from MMS until we supported this feature. r=vyang --- dom/mobilemessage/src/gonk/MmsPduHelper.jsm | 33 +++++++++++++++++++++ dom/mobilemessage/src/gonk/MmsService.js | 24 ++++++++------- 2 files changed, 47 insertions(+), 10 deletions(-) diff --git a/dom/mobilemessage/src/gonk/MmsPduHelper.jsm b/dom/mobilemessage/src/gonk/MmsPduHelper.jsm index bf9b8edd8a7..993cabd1c63 100644 --- a/dom/mobilemessage/src/gonk/MmsPduHelper.jsm +++ b/dom/mobilemessage/src/gonk/MmsPduHelper.jsm @@ -11,6 +11,8 @@ Cu.import("resource://gre/modules/WspPduHelper.jsm", WSP); Cu.import("resource://gre/modules/mms_consts.js"); +Cu.import("resource://gre/modules/PhoneNumberUtils.jsm"); + let DEBUG; // set to true to see debug messages this.MMS_VERSION = (function () { @@ -178,6 +180,33 @@ this.Address = { EncodedStringValue.encode(data, str); }, + + /** + * @param address + * Address string which want to find the type. + * + * @return Address type. + */ + resolveType: function resolveType(address) { + if (address.match(this.REGEXP_EMAIL)) { + return "email"; + } + + if (address.match(this.REGEXP_IPV4)) { + return "IPv4"; + } + + if (address.match(this.REGEXP_IPV6)) { + return "IPv6"; + } + + let normalizedAddress = PhoneNumberUtils.normalize(address, false); + if (PhoneNumberUtils.isPlainPhoneNumber(normalizedAddress)) { + return "PLMN"; + } + + return "Others"; + }, }; defineLazyRegExp(Address, "REGEXP_DECODE_PLMN", "^(\\+?[\\d.-]+)\\/TYPE=(PLMN)$"); @@ -191,6 +220,10 @@ defineLazyRegExp(Address, "REGEXP_ENCODE_CUSTOM_TYPE", "^\\w+$"); defineLazyRegExp(Address, "REGEXP_ENCODE_CUSTOM_ADDR", "^[\\w\\+\\-.%]+$"); defineLazyRegExp(Address, "REGEXP_NUM", "^[\\+*#]\\d+$"); defineLazyRegExp(Address, "REGEXP_ALPHANUM", "^\\w+$"); +defineLazyRegExp(Address, "REGEXP_PLMN", "^\\?[\\d.-]$"); +defineLazyRegExp(Address, "REGEXP_IPV4", "^\\d{1,3}(?:\\.\\d{1,3}){3}$"); +defineLazyRegExp(Address, "REGEXP_IPV6", "^[\\da-fA-F]{4}(?::[\\da-fA-F]{4}){7}$"); +defineLazyRegExp(Address, "REGEXP_EMAIL", "@"); /** * Header-field = MMS-header | Application-header diff --git a/dom/mobilemessage/src/gonk/MmsService.js b/dom/mobilemessage/src/gonk/MmsService.js index ef218167eee..d6fa07851f4 100644 --- a/dom/mobilemessage/src/gonk/MmsService.js +++ b/dom/mobilemessage/src/gonk/MmsService.js @@ -1687,18 +1687,22 @@ MmsService.prototype = { if (receivers.length != 0) { let headersTo = headers["to"] = []; for (let i = 0; i < receivers.length; i++) { - let normalizedAddress = PhoneNumberUtils.normalize(receivers[i], false); - if (DEBUG) debug("createSavableFromParams: normalize phone number " + - "from " + receivers[i] + " to " + normalizedAddress); - - headersTo.push({"address": normalizedAddress, "type": "PLMN"}); - - // Check if the address is valid to send MMS. - if (!PhoneNumberUtils.isPlainPhoneNumber(normalizedAddress)) { - if (DEBUG) debug("Error! Address is invalid to send MMS: " + - normalizedAddress); + let receiver = receivers[i]; + let type = MMS.Address.resolveType(receiver); + let address; + if (type == "PLMN") { + address = PhoneNumberUtils.normalize(receiver, false); + if (!PhoneNumberUtils.isPlainPhoneNumber(address)) { + isAddrValid = false; + } + if (DEBUG) debug("createSavableFromParams: normalize phone number " + + "from " + receiver + " to " + address); + } else { + address = receiver; isAddrValid = false; + if (DEBUG) debug("Error! Address is invalid to send MMS: " + address); } + headersTo.push({"address": address, "type": type}); } } if (aParams.subject) { From ba379b46b548d2fe325fb39921dcb3dc99c4fd03 Mon Sep 17 00:00:00 2001 From: Gaia Pushbot Date: Wed, 4 Sep 2013 01:16:28 -0700 Subject: [PATCH 010/171] Bumping gaia.json for 1 gaia-central revision(s) ======== https://hg.mozilla.org/integration/gaia-central/rev/6c97f155b0f2 Author: b2gautomation Desc: Bug 907941 - gaia-ui-tests-pushbot (see bug) --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 147da773a1e..68d50dd519b 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,4 +1,4 @@ { - "revision": "1070079a0891d8aec9f1e9fff1a1e41bc96c3313", + "revision": "6c97f155b0f2453de6e27b2b01abc80d62aefe32", "repo_path": "/integration/gaia-central" } From f99d657159169365f33050218d0800d87df67fef Mon Sep 17 00:00:00 2001 From: Ed Morley Date: Wed, 4 Sep 2013 09:30:38 +0100 Subject: [PATCH 011/171] Bug 907585 - Touch clobber file due to IDL file change --- CLOBBER | 1 + 1 file changed, 1 insertion(+) diff --git a/CLOBBER b/CLOBBER index d694d03373b..a26c16d5ffc 100644 --- a/CLOBBER +++ b/CLOBBER @@ -19,3 +19,4 @@ # Bug 627487 - random test failures caused by bookmark JSON changes +Bug 873351 & bug 907585 changed IDL files which requires a clobber on Windows From 94bff192db94263e13a64b759408a8dc2b18b25c Mon Sep 17 00:00:00 2001 From: Gaia Pushbot Date: Wed, 4 Sep 2013 02:05:25 -0700 Subject: [PATCH 012/171] Bumping gaia.json for 2 gaia-central revision(s) ======== https://hg.mozilla.org/integration/gaia-central/rev/138d0f2c4d3a Author: Arthur Chen Desc: Merge pull request #11715 from crh0716/891743 Bug 891743 - Add voice privacy mode for CDMA r=evelyn ======== https://hg.mozilla.org/integration/gaia-central/rev/de97091310f0 Author: Arthur Chen Desc: Bug 891743 - Add voice privacy mode for CDMA --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 68d50dd519b..434d24887c4 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,4 +1,4 @@ { - "revision": "6c97f155b0f2453de6e27b2b01abc80d62aefe32", + "revision": "138d0f2c4d3a864adc92b36a05b0bfd74a140e4b", "repo_path": "/integration/gaia-central" } From 7818ac47ada7a671cfb1b512023cfedd61b03248 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Thu, 29 Aug 2013 01:21:52 +0200 Subject: [PATCH 013/171] Bug 853550: Fix whitespace errors, r=echou --- dom/bluetooth/BluetoothService.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/dom/bluetooth/BluetoothService.h b/dom/bluetooth/BluetoothService.h index 184335a40a1..0b2c4f8e2ee 100644 --- a/dom/bluetooth/BluetoothService.h +++ b/dom/bluetooth/BluetoothService.h @@ -47,7 +47,7 @@ public: NS_DECL_ISUPPORTS NS_DECL_NSIOBSERVER - /** + /** * Add a message handler object from message distribution observer. * Must be called from the main thread. * @@ -58,7 +58,7 @@ public: RegisterBluetoothSignalHandler(const nsAString& aNodeName, BluetoothSignalObserver* aMsgHandler); - /** + /** * Remove a message handler object from message distribution observer. * Must be called from the main thread. * @@ -69,7 +69,7 @@ public: UnregisterBluetoothSignalHandler(const nsAString& aNodeName, BluetoothSignalObserver* aMsgHandler); - /** + /** * Remove a message handlers for the given observer. * Must be called from the main thread. * @@ -78,7 +78,7 @@ public: void UnregisterAllSignalHandlers(BluetoothSignalObserver* aMsgHandler); - /** + /** * Distribute a signal to the observer list * * @param aSignal Signal object to distribute @@ -150,7 +150,7 @@ public: virtual nsresult StopDiscoveryInternal(BluetoothReplyRunnable* aRunnable) = 0; - /** + /** * Start device discovery (platform specific implementation) * * @return NS_OK if discovery stopped correctly, false otherwise @@ -328,7 +328,7 @@ protected: nsresult StartStopBluetooth(bool aStart, bool aIsStartup); - /** + /** * Platform specific startup functions go here. Usually deals with member * variables, so not static. Guaranteed to be called outside of main thread. * From fc9e6580229e03cf162c97521c8147d37ca638f9 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Fri, 30 Aug 2013 20:18:40 +0200 Subject: [PATCH 014/171] Bug 853550: Cleanup DBus thread handling, r=qdot For replacing the Bluetooth command thread with a LazyIdleThread, we need to make sure that the DBus service thread is shutdown from within the main thread. This patch changes the DBus stop code to cleanup the DBusThread structure from the service thread to prevent race conditions during shutdown. The DBus service thread itself gets shutdown from the main thread to fulfill the requirements of LazyIdleThread. The patch also makes sure that it's not possible to accidently dispatch a runnable while the DBus thread terminates. --- ipc/dbus/DBusThread.cpp | 42 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/ipc/dbus/DBusThread.cpp b/ipc/dbus/DBusThread.cpp index a6c77c64612..d896519279e 100644 --- a/ipc/dbus/DBusThread.cpp +++ b/ipc/dbus/DBusThread.cpp @@ -479,11 +479,13 @@ public: } } + mConnection->CleanUp(); + return NS_OK; } private: - DBusThread* mConnection; + nsRefPtr mConnection; }; static StaticRefPtr gDBusThread; @@ -532,30 +534,23 @@ StopDBus() MOZ_ASSERT(!NS_IsMainThread()); NS_ENSURE_TRUE(gDBusServiceThread, true); - if (gDBusThread) { + nsRefPtr dbusThread(gDBusThread); + gDBusThread = nullptr; + + if (dbusThread) { static const char data = DBUS_EVENT_LOOP_EXIT; - ssize_t wret = TEMP_FAILURE_RETRY(write(gDBusThread->mControlFdW.get(), + ssize_t wret = TEMP_FAILURE_RETRY(write(dbusThread->mControlFdW.get(), &data, sizeof(data))); NS_ENSURE_TRUE(wret == 1, false); } -#ifdef DEBUG - LOG("DBus Thread Joining\n"); -#endif - - if (NS_FAILED(gDBusServiceThread->Shutdown())) { - NS_WARNING("DBus thread shutdown failed!"); - } + nsRefPtr dbusServiceThread(gDBusServiceThread); gDBusServiceThread = nullptr; -#ifdef DEBUG - LOG("DBus Thread Joined\n"); -#endif - - if (gDBusThread) { - gDBusThread->CleanUp(); - gDBusThread = nullptr; - } + nsRefPtr runnable = + NS_NewRunnableMethod(dbusServiceThread, &nsIThread::Shutdown); + nsresult rv = NS_DispatchToMainThread(runnable); + NS_ENSURE_SUCCESS(rv, false); return true; } @@ -563,13 +558,16 @@ StopDBus() nsresult DispatchToDBusThread(nsIRunnable* event) { - MOZ_ASSERT(gDBusServiceThread); - MOZ_ASSERT(gDBusThread); + nsRefPtr dbusServiceThread(gDBusServiceThread); + nsRefPtr dbusThread(gDBusThread); - nsresult rv = gDBusServiceThread->Dispatch(event, NS_DISPATCH_NORMAL); + NS_ENSURE_TRUE(dbusServiceThread.get() && dbusThread.get(), + NS_ERROR_NOT_INITIALIZED); + + nsresult rv = dbusServiceThread->Dispatch(event, NS_DISPATCH_NORMAL); NS_ENSURE_SUCCESS(rv, rv); - gDBusThread->WakeUp(); + dbusThread->WakeUp(); return NS_OK; } From 26fc503b83ad49838ac450aa044d3f408f47b2ca Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Fri, 30 Aug 2013 20:18:43 +0200 Subject: [PATCH 015/171] Bug 853550: Replace Bluetooth command thread, r=echou,gyeh Starting and stopping Bluetooth support can block the executing thread for an indefinite amount of time. In most cases these operations are only performed when Gecko starts and stops, so we don't want to keep a separate Bluetooth command thread for this. This patch replaces the Bluetooth command thread by a LazyIdleThread, which only consumes resources while it executes actual code. After a timeout period, the LazyIdleThread cleans up its internal state. The timeout is currently 3 seconds, which has been choosen arbitrarily. Thanks to bent for helping with the details of LazyIdleThread. --- dom/bluetooth/BluetoothService.cpp | 46 ++++++++---------------------- dom/bluetooth/BluetoothService.h | 26 ++++++----------- 2 files changed, 21 insertions(+), 51 deletions(-) diff --git a/dom/bluetooth/BluetoothService.cpp b/dom/bluetooth/BluetoothService.cpp index 0faae5a577b..4a6f3a1ca60 100644 --- a/dom/bluetooth/BluetoothService.cpp +++ b/dom/bluetooth/BluetoothService.cpp @@ -25,6 +25,7 @@ #include "mozilla/dom/ContentParent.h" #include "mozilla/dom/bluetooth/BluetoothTypes.h" #include "mozilla/ipc/UnixSocket.h" +#include "mozilla/LazyIdleThread.h" #include "nsContentUtils.h" #include "nsCxPusher.h" #include "nsIObserverService.h" @@ -54,6 +55,7 @@ #define PROP_BLUETOOTH_ENABLED "bluetooth.isEnabled" +#define DEFAULT_THREAD_TIMEOUT_MS 3000 #define DEFAULT_SHUTDOWN_TIMER_MS 5000 bool gBluetoothDebugFlag = false; @@ -145,19 +147,8 @@ public: gBluetoothService->DistributeSignal(signal); } - if (!mEnabled || gInShutdown) { - // Shut down the command thread if it still exists. - if (gBluetoothService->mBluetoothCommandThread) { - nsCOMPtr thread; - gBluetoothService->mBluetoothCommandThread.swap(thread); - if (NS_FAILED(thread->Shutdown())) { - NS_WARNING("Failed to shut down the bluetooth command thread!"); - } - } - - if (gInShutdown) { - gBluetoothService = nullptr; - } + if (gInShutdown) { + gBluetoothService = nullptr; } return NS_OK; @@ -461,22 +452,13 @@ BluetoothService::StartStopBluetooth(bool aStart, bool aIsStartup) return NS_ERROR_FAILURE; } - if (!mBluetoothCommandThread) { + if (!mBluetoothThread) { // Don't create a new thread after we've begun shutdown since bluetooth // can't be running. return NS_OK; } } - nsresult rv; - if (!mBluetoothCommandThread) { - MOZ_ASSERT(!gInShutdown); - - rv = NS_NewNamedThread("BluetoothCmd", - getter_AddRefs(mBluetoothCommandThread)); - NS_ENSURE_SUCCESS(rv, rv); - } - if (!aStart) { BluetoothHfpManager* hfp = BluetoothHfpManager::Get(); hfp->Disconnect(); @@ -485,8 +467,14 @@ BluetoothService::StartStopBluetooth(bool aStart, bool aIsStartup) opp->Disconnect(); } + if (!mBluetoothThread) { + mBluetoothThread = new LazyIdleThread(DEFAULT_THREAD_TIMEOUT_MS, + NS_LITERAL_CSTRING("Bluetooth"), + LazyIdleThread::ManualShutdown); + } + nsCOMPtr runnable = new ToggleBtTask(aStart, aIsStartup); - rv = mBluetoothCommandThread->Dispatch(runnable, NS_DISPATCH_NORMAL); + nsresult rv = mBluetoothThread->Dispatch(runnable, NS_DISPATCH_NORMAL); NS_ENSURE_SUCCESS(rv, rv); return NS_OK; @@ -814,13 +802,3 @@ BluetoothService::Notify(const BluetoothSignal& aData) OBJECT_TO_JSVAL(obj), JS::UndefinedValue()); } - -void -BluetoothService::DispatchToCommandThread(nsRunnable* aRunnable) -{ - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(aRunnable); - MOZ_ASSERT(mBluetoothCommandThread); - - mBluetoothCommandThread->Dispatch(aRunnable, NS_DISPATCH_NORMAL); -} diff --git a/dom/bluetooth/BluetoothService.h b/dom/bluetooth/BluetoothService.h index 0b2c4f8e2ee..c754958f8db 100644 --- a/dom/bluetooth/BluetoothService.h +++ b/dom/bluetooth/BluetoothService.h @@ -307,9 +307,6 @@ public: void RemoveObserverFromTable(const nsAString& key); - void - DispatchToCommandThread(nsRunnable* aRunnable); - protected: BluetoothService() : mEnabled(false) @@ -387,26 +384,21 @@ protected: static BluetoothService* Create(); - /** - * Due to the fact that some operations require multiple calls, a - * CommandThread is created that can run blocking, platform-specific calls - * where either no asynchronous equivilent exists, or else where multiple - * asynchronous calls would require excessive runnable bouncing between main - * thread and IO thread. - * - * For instance, when we retrieve an Adapter object, we would like it to come - * with all of its properties filled in and registered as an agent, which - * requires a minimum of 3 calls to platform specific code on some platforms. - * - */ - nsCOMPtr mBluetoothCommandThread; - typedef nsClassHashtable BluetoothSignalObserverTable; BluetoothSignalObserverTable mBluetoothSignalObserverTable; bool mEnabled; + +private: + /** + * Due to the fact that the startup and shutdown of the Bluetooth system + * can take an indefinite amount of time, a command thread is created + * that can run blocking calls. The thread is not intended for regular + * Bluetooth operations though. + */ + nsCOMPtr mBluetoothThread; }; END_BLUETOOTH_NAMESPACE From b3bb1b01acefc52eb93e6d0447b0397f7e5f64a4 Mon Sep 17 00:00:00 2001 From: Gaia Pushbot Date: Wed, 4 Sep 2013 02:50:22 -0700 Subject: [PATCH 016/171] Bumping gaia.json for 1 gaia-central revision(s) ======== https://hg.mozilla.org/integration/gaia-central/rev/2f96b4d19593 Author: b2gautomation Desc: Bug 907941 - gaia-ui-tests-pushbot (see bug) --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 434d24887c4..80b111fc043 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,4 +1,4 @@ { - "revision": "138d0f2c4d3a864adc92b36a05b0bfd74a140e4b", + "revision": "2f96b4d195932089990516bf168a886918331ca8", "repo_path": "/integration/gaia-central" } From 1897376e702376a040691adc5a1560c9c382ec82 Mon Sep 17 00:00:00 2001 From: Gaia Pushbot Date: Wed, 4 Sep 2013 03:40:44 -0700 Subject: [PATCH 017/171] Bumping gaia.json for 1 gaia-central revision(s) ======== https://hg.mozilla.org/integration/gaia-central/rev/ddbce8d8bd5a Author: b2gautomation Desc: Bug 907941 - gaia-ui-tests-pushbot (see bug) --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 80b111fc043..f4d999f9b49 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,4 +1,4 @@ { - "revision": "2f96b4d195932089990516bf168a886918331ca8", + "revision": "ddbce8d8bd5a2f49c29531e7af636fce5266b0d5", "repo_path": "/integration/gaia-central" } From e793b4ce5b2ba4a6294c9c6d956ae69dc98e3a14 Mon Sep 17 00:00:00 2001 From: Ed Morley Date: Wed, 4 Sep 2013 11:50:42 +0100 Subject: [PATCH 018/171] Backed out changeset 679f571996e8 (bug 907585) --- CLOBBER | 1 - 1 file changed, 1 deletion(-) diff --git a/CLOBBER b/CLOBBER index a26c16d5ffc..d694d03373b 100644 --- a/CLOBBER +++ b/CLOBBER @@ -19,4 +19,3 @@ # Bug 627487 - random test failures caused by bookmark JSON changes -Bug 873351 & bug 907585 changed IDL files which requires a clobber on Windows From 19e0e1f7ed4bb3d387d4cb4fd72679bad4370d00 Mon Sep 17 00:00:00 2001 From: Ed Morley Date: Wed, 4 Sep 2013 11:50:46 +0100 Subject: [PATCH 019/171] Backed out changeset 8b6235d4c2ac (bug 873351) --- b2g/installer/package-manifest.in | 2 - browser/installer/package-manifest.in | 2 - dom/mobilemessage/interfaces/moz.build | 1 - .../interfaces/nsIRilSmsService.idl | 11 - .../interfaces/nsISmsService.idl | 3 +- dom/mobilemessage/src/Makefile.in | 6 + dom/mobilemessage/src/SmsServicesFactory.cpp | 13 +- dom/mobilemessage/src/android/SmsService.cpp | 8 + dom/mobilemessage/src/fallback/SmsService.cpp | 8 + dom/mobilemessage/src/gonk/SmsService.cpp | 85 ++ dom/mobilemessage/src/gonk/SmsService.h | 35 + dom/mobilemessage/src/gonk/SmsService.js | 994 ------------------ .../src/gonk/SmsService.manifest | 3 - dom/mobilemessage/src/ipc/SmsIPCService.cpp | 8 + dom/mobilemessage/src/moz.build | 4 +- dom/system/gonk/RadioInterfaceLayer.js | 841 ++++++++++++++- dom/system/gonk/nsIRadioInterfaceLayer.idl | 14 +- 17 files changed, 1006 insertions(+), 1032 deletions(-) delete mode 100644 dom/mobilemessage/interfaces/nsIRilSmsService.idl create mode 100644 dom/mobilemessage/src/gonk/SmsService.cpp create mode 100644 dom/mobilemessage/src/gonk/SmsService.h delete mode 100644 dom/mobilemessage/src/gonk/SmsService.js delete mode 100644 dom/mobilemessage/src/gonk/SmsService.manifest diff --git a/b2g/installer/package-manifest.in b/b2g/installer/package-manifest.in index e0e660cdbc5..f358d9f1007 100644 --- a/b2g/installer/package-manifest.in +++ b/b2g/installer/package-manifest.in @@ -460,8 +460,6 @@ @BINPATH@/components/RadioInterfaceLayer.js @BINPATH@/components/MmsService.manifest @BINPATH@/components/MmsService.js -@BINPATH@/components/SmsService.manifest -@BINPATH@/components/SmsService.js @BINPATH@/components/RILContentHelper.js @BINPATH@/components/MobileMessageDatabaseService.manifest @BINPATH@/components/MobileMessageDatabaseService.js diff --git a/browser/installer/package-manifest.in b/browser/installer/package-manifest.in index 71b851364de..387a7915c87 100644 --- a/browser/installer/package-manifest.in +++ b/browser/installer/package-manifest.in @@ -446,8 +446,6 @@ @BINPATH@/components/RadioInterfaceLayer.js @BINPATH@/components/MmsService.manifest @BINPATH@/components/MmsService.js -@BINPATH@/components/SmsService.manifest -@BINPATH@/components/SmsService.js @BINPATH@/components/RILContentHelper.js @BINPATH@/components/MobileMessageDatabaseService.manifest @BINPATH@/components/MobileMessageDatabaseService.js diff --git a/dom/mobilemessage/interfaces/moz.build b/dom/mobilemessage/interfaces/moz.build index dd41f43b776..52cc79b9288 100644 --- a/dom/mobilemessage/interfaces/moz.build +++ b/dom/mobilemessage/interfaces/moz.build @@ -25,7 +25,6 @@ XPIDL_SOURCES += [ if CONFIG['MOZ_B2G_RIL']: XPIDL_SOURCES += [ 'nsIRilMobileMessageDatabaseService.idl', - 'nsIRilSmsService.idl', ] XPIDL_MODULE = 'dom_mobilemessage' diff --git a/dom/mobilemessage/interfaces/nsIRilSmsService.idl b/dom/mobilemessage/interfaces/nsIRilSmsService.idl deleted file mode 100644 index ef2e853d8a5..00000000000 --- a/dom/mobilemessage/interfaces/nsIRilSmsService.idl +++ /dev/null @@ -1,11 +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 "nsISmsService.idl" - -[scriptable, uuid(f216903c-bdf5-4988-b894-f62fd91df114)] -interface nsIRilSmsService : nsISmsService -{ - void notifyMessageReceived(in jsval message); -}; diff --git a/dom/mobilemessage/interfaces/nsISmsService.idl b/dom/mobilemessage/interfaces/nsISmsService.idl index 2250e46a2e1..0623d62ef78 100644 --- a/dom/mobilemessage/interfaces/nsISmsService.idl +++ b/dom/mobilemessage/interfaces/nsISmsService.idl @@ -13,7 +13,7 @@ interface nsIMobileMessageCallback; #define SMS_SERVICE_CONTRACTID "@mozilla.org/sms/smsservice;1" %} -[scriptable, uuid(7ef8e361-9db6-46ed-badc-2901e1049e5d)] +[scriptable, builtinclass, uuid(f0d5d11b-0326-4cb1-bb76-a3f912212287)] interface nsISmsService : nsISupports { boolean hasSupport(); @@ -25,6 +25,7 @@ interface nsISmsService : nsISupports in boolean silent, in nsIMobileMessageCallback request); + boolean isSilentNumber(in DOMString number); void addSilentNumber(in DOMString number); void removeSilentNumber(in DOMString number); }; diff --git a/dom/mobilemessage/src/Makefile.in b/dom/mobilemessage/src/Makefile.in index ae94f960a3c..e45e9b971de 100644 --- a/dom/mobilemessage/src/Makefile.in +++ b/dom/mobilemessage/src/Makefile.in @@ -31,5 +31,11 @@ LOCAL_INCLUDES = \ # subdirectory (and the ipc one). LOCAL_INCLUDES += $(VPATH:%=-I%) +ifdef MOZ_B2G_RIL +LOCAL_INCLUDES += \ + -I$(topsrcdir)/dom/system/gonk \ + $(NULL) +endif + include $(topsrcdir)/config/rules.mk include $(topsrcdir)/ipc/chromium/chromium-config.mk diff --git a/dom/mobilemessage/src/SmsServicesFactory.cpp b/dom/mobilemessage/src/SmsServicesFactory.cpp index 94ffef77b92..efcf0171834 100644 --- a/dom/mobilemessage/src/SmsServicesFactory.cpp +++ b/dom/mobilemessage/src/SmsServicesFactory.cpp @@ -5,18 +5,16 @@ #include "SmsServicesFactory.h" #include "nsXULAppAPI.h" +#include "SmsService.h" #include "SmsIPCService.h" #ifndef MOZ_B2G_RIL #include "MobileMessageDatabaseService.h" #include "MmsService.h" -#include "SmsService.h" #endif #include "nsServiceManagerUtils.h" #define RIL_MMSSERVICE_CONTRACTID "@mozilla.org/mms/rilmmsservice;1" -#define RIL_MOBILE_MESSAGE_DATABASE_SERVICE_CONTRACTID \ - "@mozilla.org/mobilemessage/rilmobilemessagedatabaseservice;1" -#define RIL_SMSSERVICE_CONTRACTID "@mozilla.org/sms/rilsmsservice;1" +#define RIL_MOBILE_MESSAGE_DATABASE_SERVICE_CONTRACTID "@mozilla.org/mobilemessage/rilmobilemessagedatabaseservice;1" namespace mozilla { namespace dom { @@ -30,11 +28,7 @@ SmsServicesFactory::CreateSmsService() if (XRE_GetProcessType() == GeckoProcessType_Content) { smsService = new SmsIPCService(); } else { -#ifdef MOZ_B2G_RIL - smsService = do_GetService(RIL_SMSSERVICE_CONTRACTID); -#else smsService = new SmsService(); -#endif } return smsService.forget(); @@ -48,8 +42,7 @@ SmsServicesFactory::CreateMobileMessageDatabaseService() mobileMessageDBService = new SmsIPCService(); } else { #ifdef MOZ_B2G_RIL - mobileMessageDBService = - do_GetService(RIL_MOBILE_MESSAGE_DATABASE_SERVICE_CONTRACTID); + mobileMessageDBService = do_GetService(RIL_MOBILE_MESSAGE_DATABASE_SERVICE_CONTRACTID); #else mobileMessageDBService = new MobileMessageDatabaseService(); #endif diff --git a/dom/mobilemessage/src/android/SmsService.cpp b/dom/mobilemessage/src/android/SmsService.cpp index c5a67319984..146190766fa 100644 --- a/dom/mobilemessage/src/android/SmsService.cpp +++ b/dom/mobilemessage/src/android/SmsService.cpp @@ -53,6 +53,14 @@ SmsService::Send(const nsAString& aNumber, return NS_OK; } +NS_IMETHODIMP +SmsService::IsSilentNumber(const nsAString& aNumber, + bool* aIsSilent) +{ + NS_NOTYETIMPLEMENTED("Implement me!"); + return NS_ERROR_NOT_IMPLEMENTED; +} + NS_IMETHODIMP SmsService::AddSilentNumber(const nsAString& aNumber) { diff --git a/dom/mobilemessage/src/fallback/SmsService.cpp b/dom/mobilemessage/src/fallback/SmsService.cpp index 430edab6f15..5df3504226b 100644 --- a/dom/mobilemessage/src/fallback/SmsService.cpp +++ b/dom/mobilemessage/src/fallback/SmsService.cpp @@ -39,6 +39,14 @@ SmsService::Send(const nsAString& aNumber, return NS_ERROR_FAILURE; } +NS_IMETHODIMP +SmsService::IsSilentNumber(const nsAString& aNumber, + bool* aIsSilent) +{ + NS_ERROR("We should not be here!"); + return NS_ERROR_FAILURE; +} + NS_IMETHODIMP SmsService::AddSilentNumber(const nsAString& aNumber) { diff --git a/dom/mobilemessage/src/gonk/SmsService.cpp b/dom/mobilemessage/src/gonk/SmsService.cpp new file mode 100644 index 00000000000..484dd94091a --- /dev/null +++ b/dom/mobilemessage/src/gonk/SmsService.cpp @@ -0,0 +1,85 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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 "SmsMessage.h" +#include "SmsService.h" +#include "jsapi.h" +#include "SmsSegmentInfo.h" + +namespace mozilla { +namespace dom { +namespace mobilemessage { + +NS_IMPL_ISUPPORTS1(SmsService, nsISmsService) + +SmsService::SmsService() +{ + nsCOMPtr ril = do_GetService("@mozilla.org/ril;1"); + if (ril) { + ril->GetRadioInterface(0, getter_AddRefs(mRadioInterface)); + } + NS_WARN_IF_FALSE(mRadioInterface, "This shouldn't fail!"); +} + +NS_IMETHODIMP +SmsService::HasSupport(bool* aHasSupport) +{ + *aHasSupport = true; + return NS_OK; +} + +NS_IMETHODIMP +SmsService::GetSegmentInfoForText(const nsAString & aText, + nsIDOMMozSmsSegmentInfo** aResult) +{ + NS_ENSURE_TRUE(mRadioInterface, NS_ERROR_FAILURE); + + return mRadioInterface->GetSegmentInfoForText(aText, aResult); +} + +NS_IMETHODIMP +SmsService::Send(const nsAString& aNumber, + const nsAString& aMessage, + const bool aSilent, + nsIMobileMessageCallback* aRequest) +{ + NS_ENSURE_TRUE(mRadioInterface, NS_ERROR_FAILURE); + + return mRadioInterface->SendSMS(aNumber, aMessage, aSilent, aRequest); +} + +NS_IMETHODIMP +SmsService::IsSilentNumber(const nsAString& aNumber, + bool* aIsSilent) +{ + *aIsSilent = mSilentNumbers.Contains(aNumber); + return NS_OK; +} + +NS_IMETHODIMP +SmsService::AddSilentNumber(const nsAString& aNumber) +{ + if (mSilentNumbers.Contains(aNumber)) { + return NS_ERROR_UNEXPECTED; + } + + NS_ENSURE_TRUE(mSilentNumbers.AppendElement(aNumber), NS_ERROR_FAILURE); + return NS_OK; +} + +NS_IMETHODIMP +SmsService::RemoveSilentNumber(const nsAString& aNumber) +{ + if (!mSilentNumbers.Contains(aNumber)) { + return NS_ERROR_INVALID_ARG; + } + + NS_ENSURE_TRUE(mSilentNumbers.RemoveElement(aNumber), NS_ERROR_FAILURE); + return NS_OK; +} + +} // namespace mobilemessage +} // namespace dom +} // namespace mozilla diff --git a/dom/mobilemessage/src/gonk/SmsService.h b/dom/mobilemessage/src/gonk/SmsService.h new file mode 100644 index 00000000000..940cbf2fa81 --- /dev/null +++ b/dom/mobilemessage/src/gonk/SmsService.h @@ -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_mobilemessage_SmsService_h +#define mozilla_dom_mobilemessage_SmsService_h + +#include "nsISmsService.h" +#include "nsCOMPtr.h" +#include "nsIRadioInterfaceLayer.h" +#include "nsTArray.h" +#include "nsString.h" + +namespace mozilla { +namespace dom { +namespace mobilemessage { + +class SmsService : public nsISmsService +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSISMSSERVICE + SmsService(); + +protected: + // TODO: Bug 854326 - B2G Multi-SIM: support multiple SIM cards for SMS/MMS + nsCOMPtr mRadioInterface; + nsTArray mSilentNumbers; +}; + +} // namespace mobilemessage +} // namespace dom +} // namespace mozilla + +#endif // mozilla_dom_mobilemessage_SmsService_h diff --git a/dom/mobilemessage/src/gonk/SmsService.js b/dom/mobilemessage/src/gonk/SmsService.js deleted file mode 100644 index 853b66e04b9..00000000000 --- a/dom/mobilemessage/src/gonk/SmsService.js +++ /dev/null @@ -1,994 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: sw=2 ts=2 sts=2 et filetype=javascript - * 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/. */ - -"use strict"; - -const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); - -var RIL = {}; -Cu.import("resource://gre/modules/ril_consts.js", RIL); - -const RIL_SMSSERVICE_CONTRACTID = "@mozilla.org/sms/rilsmsservice;1"; -const RIL_SMSSERVICE_CID = - Components.ID("{46a9ed78-3574-40a1-9f12-ea179942d67f}"); - -const DELIVERY_STATE_RECEIVED = "received"; -const DELIVERY_STATE_SENDING = "sending"; -const DELIVERY_STATE_SENT = "sent"; -const DELIVERY_STATE_ERROR = "error"; - -// Observer topics to send. -const kSmsReceivedObserverTopic = "sms-received"; -const kSmsSendingObserverTopic = "sms-sending"; -const kSmsSentObserverTopic = "sms-sent"; -const kSmsFailedObserverTopic = "sms-failed"; -const kSmsDeliverySuccessObserverTopic = "sms-delivery-success"; -const kSmsDeliveryErrorObserverTopic = "sms-delivery-error"; -const kSilentSmsReceivedObserverTopic = "silent-sms-received"; - -// Observer topics to watch. -const kPrefenceChangedObserverTopic = "nsPref:changed"; -const kXpcomShutdownObserverTopic = "xpcom-shutdown"; - -// Preference keys. -const kPrefKeyRilDebuggingEnabled = "ril.debugging.enabled"; - -XPCOMUtils.defineLazyServiceGetter(this, "gMobileMessageDatabaseService", - "@mozilla.org/mobilemessage/rilmobilemessagedatabaseservice;1", - "nsIRilMobileMessageDatabaseService"); - -XPCOMUtils.defineLazyServiceGetter(this, "gMobileMessageService", - "@mozilla.org/mobilemessage/mobilemessageservice;1", - "nsIMobileMessageService"); - -XPCOMUtils.defineLazyServiceGetter(this, "gSystemMessenger", - "@mozilla.org/system-message-internal;1", - "nsISystemMessagesInternal"); - -XPCOMUtils.defineLazyGetter(this, "gRadioInterface", function () { - let ril = Cc["@mozilla.org/ril;1"].getService(Ci["nsIRadioInterfaceLayer"]); - // TODO: Bug 854326 - B2G Multi-SIM: support multiple SIM cards for SMS/MMS - return ril.getRadioInterface(0); -}); - -XPCOMUtils.defineLazyGetter(this, "gPhoneNumberUtils", function () { - let ns = {}; - Cu.import("resource://gre/modules/PhoneNumberUtils.jsm", ns); - return ns.PhoneNumberUtils; -}); - -XPCOMUtils.defineLazyGetter(this, "WAP", function () { - let WAP = {}; - Cu.import("resource://gre/modules/WapPushManager.js", WAP); - return WAP; -}); - -XPCOMUtils.defineLazyGetter(this, "gMessageManager", function () { - let ns = {}; - Cu.import("resource://gre/modules/RilMessageManager.jsm", ns); - return ns.RilMessageManager; -}); - -let DEBUG; -function debug(s) { - dump("SmsService: " + s + "\n"); -} - -/** - * SmsService - */ -function SmsService() { - // Update |DEBUG|. - this.observe(null, kPrefenceChangedObserverTopic, - kPrefKeyRilDebuggingEnabled); - - this.silentNumbers = []; - - this.portAddressedSmsApps = {}; - this.portAddressedSmsApps[WAP.WDP_PORT_PUSH] = - this._handleSmsWdpPortPush.bind(this); - - Services.obs.addObserver(this, kPrefenceChangedObserverTopic, false); - Services.obs.addObserver(this, kXpcomShutdownObserverTopic, false); -} -SmsService.prototype = { - - classID: RIL_SMSSERVICE_CID, - classInfo: XPCOMUtils.generateCI({classID: RIL_SMSSERVICE_CID, - contractID: RIL_SMSSERVICE_CONTRACTID, - classDescription: "SmsService", - interfaces: [Ci.nsIRilSmsService, - Ci.nsISmsService], - flags: Ci.nsIClassInfo.SINGLETON}), - QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, - Ci.nsIRilSmsService, - Ci.nsISmsService]), - - /** - * List of tuples of national language identifier pairs. - * - * TODO: Support static/runtime settings, see bug 733331. - */ - enabledGsmTableTuples: [ - [RIL.PDU_NL_IDENTIFIER_DEFAULT, RIL.PDU_NL_IDENTIFIER_DEFAULT], - ], - - /** - * Use 16-bit reference number for concatenated outgoint messages. - * - * TODO: Support static/runtime settings, see bug 733331. - */ - segmentRef16Bit: false, - - /** - * Get valid SMS concatenation reference number. - */ - segmentRef: 0, - get nextSegmentRef() { - let ref = this.segmentRef++; - - this.segmentRef %= (this.segmentRef16Bit ? 65535 : 255); - - // 0 is not a valid SMS concatenation reference number. - return ref + 1; - }, - - statusReportPendingMessageIds: null, - - portAddressedSmsApps: null, - - silentNumbers: null, - - _getStrict7BitEncoding: function _getStrict7BitEncoding() { - try { - return Services.prefs.getBoolPref("dom.sms.strict7BitEncoding"); - } catch (e) { - return false; - } - }, - - _getRequestStatusReport: function _getRequestStatusReport() { - try { - return Services.prefs.getBoolPref("dom.sms.requestStatusReport"); - } catch (e) { - return true; - } - }, - - _getMsisdn: function _getMsisdn() { - let iccInfo = gRadioInterface.rilContext.iccInfo; - let number = iccInfo ? iccInfo.msisdn : null; - - // Workaround an xpconnect issue with undefined string objects. - // See bug 808220 - if (number === undefined || number === "undefined") { - return null; - } - return number; - }, - - /** - * Calculate encoded length using specified locking/single shift table - * - * @param message - * message string to be encoded. - * @param langTable - * locking shift table string. - * @param langShiftTable - * single shift table string. - * @param strict7BitEncoding - * Optional. Enable Latin characters replacement with corresponding - * ones in GSM SMS 7-bit default alphabet. - * - * @return encoded length in septets. - * - * @note that the algorithm used in this function must match exactly with - * GsmPDUHelper#writeStringAsSeptets. - */ - _countGsm7BitSeptets: function _countGsm7BitSeptets(message, - langTable, - langShiftTable, - strict7BitEncoding) { - let length = 0; - for (let msgIndex = 0; msgIndex < message.length; msgIndex++) { - let c = message.charAt(msgIndex); - if (strict7BitEncoding) { - c = RIL.GSM_SMS_STRICT_7BIT_CHARMAP[c] || c; - } - - let septet = langTable.indexOf(c); - - // According to 3GPP TS 23.038, section 6.1.1 General notes, "The - // characters marked '1)' are not used but are displayed as a space." - if (septet == RIL.PDU_NL_EXTENDED_ESCAPE) { - continue; - } - - if (septet >= 0) { - length++; - continue; - } - - septet = langShiftTable.indexOf(c); - if (septet < 0) { - if (!strict7BitEncoding) { - return -1; - } - - // Bug 816082, when strict7BitEncoding is enabled, we should replace - // characters that can't be encoded with GSM 7-Bit alphabets with '*'. - c = '*'; - if (langTable.indexOf(c) >= 0) { - length++; - } else if (langShiftTable.indexOf(c) >= 0) { - length += 2; - } else { - // We can't even encode a '*' character with current configuration. - return -1; - } - - continue; - } - - // According to 3GPP TS 23.038 B.2, "This code represents a control - // character and therefore must not be used for language specific - // characters." - if (septet == RIL.PDU_NL_RESERVED_CONTROL) { - continue; - } - - // The character is not found in locking shfit table, but could be - // encoded as with single shift table. Note that it's - // still possible for septet to has the value of PDU_NL_EXTENDED_ESCAPE, - // but we can display it as a space in this case as said in previous - // comment. - length += 2; - } - - return length; - }, - - /** - * Calculate user data length of specified message string encoded in GSM 7Bit - * alphabets. - * - * @param message - * a message string to be encoded. - * @param strict7BitEncoding - * Optional. Enable Latin characters replacement with corresponding - * ones in GSM SMS 7-bit default alphabet. - * - * @return null or an options object with attributes `dcs`, - * `userDataHeaderLength`, `encodedFullBodyLength`, `langIndex`, - * `langShiftIndex`, `segmentMaxSeq` set. - * - * @see #_calculateUserDataLength(). - */ - _calculateUserDataLength7Bit: function _calculateUserDataLength7Bit(message, - strict7BitEncoding) { - let options = null; - let minUserDataSeptets = Number.MAX_VALUE; - for (let i = 0; i < this.enabledGsmTableTuples.length; i++) { - let [langIndex, langShiftIndex] = this.enabledGsmTableTuples[i]; - - const langTable = RIL.PDU_NL_LOCKING_SHIFT_TABLES[langIndex]; - const langShiftTable = RIL.PDU_NL_SINGLE_SHIFT_TABLES[langShiftIndex]; - - let bodySeptets = this._countGsm7BitSeptets(message, - langTable, - langShiftTable, - strict7BitEncoding); - if (bodySeptets < 0) { - continue; - } - - let headerLen = 0; - if (langIndex != RIL.PDU_NL_IDENTIFIER_DEFAULT) { - headerLen += 3; // IEI + len + langIndex - } - if (langShiftIndex != RIL.PDU_NL_IDENTIFIER_DEFAULT) { - headerLen += 3; // IEI + len + langShiftIndex - } - - // Calculate full user data length, note the extra byte is for header len - let headerSeptets = Math.ceil((headerLen ? headerLen + 1 : 0) * 8 / 7); - let segmentSeptets = RIL.PDU_MAX_USER_DATA_7BIT; - if ((bodySeptets + headerSeptets) > segmentSeptets) { - headerLen += this.segmentRef16Bit ? 6 : 5; - headerSeptets = Math.ceil((headerLen + 1) * 8 / 7); - segmentSeptets -= headerSeptets; - } - - let segments = Math.ceil(bodySeptets / segmentSeptets); - let userDataSeptets = bodySeptets + headerSeptets * segments; - if (userDataSeptets >= minUserDataSeptets) { - continue; - } - - minUserDataSeptets = userDataSeptets; - - options = { - dcs: RIL.PDU_DCS_MSG_CODING_7BITS_ALPHABET, - encodedFullBodyLength: bodySeptets, - userDataHeaderLength: headerLen, - langIndex: langIndex, - langShiftIndex: langShiftIndex, - segmentMaxSeq: segments, - segmentChars: segmentSeptets, - }; - } - - return options; - }, - - /** - * Calculate user data length of specified message string encoded in UCS2. - * - * @param message - * a message string to be encoded. - * - * @return an options object with attributes `dcs`, `userDataHeaderLength`, - * `encodedFullBodyLength`, `segmentMaxSeq` set. - * - * @see #_calculateUserDataLength(). - */ - _calculateUserDataLengthUCS2: function _calculateUserDataLengthUCS2(message) { - let bodyChars = message.length; - let headerLen = 0; - let headerChars = Math.ceil((headerLen ? headerLen + 1 : 0) / 2); - let segmentChars = RIL.PDU_MAX_USER_DATA_UCS2; - if ((bodyChars + headerChars) > segmentChars) { - headerLen += this.segmentRef16Bit ? 6 : 5; - headerChars = Math.ceil((headerLen + 1) / 2); - segmentChars -= headerChars; - } - - let segments = Math.ceil(bodyChars / segmentChars); - - return { - dcs: RIL.PDU_DCS_MSG_CODING_16BITS_ALPHABET, - encodedFullBodyLength: bodyChars * 2, - userDataHeaderLength: headerLen, - segmentMaxSeq: segments, - segmentChars: segmentChars, - }; - }, - - /** - * Calculate user data length and its encoding. - * - * @param message - * a message string to be encoded. - * @param strict7BitEncoding - * Optional. Enable Latin characters replacement with corresponding - * ones in GSM SMS 7-bit default alphabet. - * - * @return an options object with some or all of following attributes set: - * - * @param dcs - * Data coding scheme. One of the PDU_DCS_MSG_CODING_*BITS_ALPHABET - * constants. - * @param userDataHeaderLength - * Length of embedded user data header, in bytes. The whole header - * size will be userDataHeaderLength + 1; 0 for no header. - * @param encodedFullBodyLength - * Length of the message body when encoded with the given DCS. For - * UCS2, in bytes; for 7-bit, in septets. - * @param langIndex - * Table index used for normal 7-bit encoded character lookup. - * @param langShiftIndex - * Table index used for escaped 7-bit encoded character lookup. - * @param segmentMaxSeq - * Max sequence number of a multi-part messages, or 1 for single one. - * This number might not be accurate for a multi-part message until - * it's processed by #_fragmentText() again. - */ - _calculateUserDataLength: function _calculateUserDataLength(message, - strict7BitEncoding) { - let options = this._calculateUserDataLength7Bit(message, strict7BitEncoding); - if (!options) { - options = this._calculateUserDataLengthUCS2(message); - } - - if (DEBUG) debug("_calculateUserDataLength: " + JSON.stringify(options)); - return options; - }, - - /** - * Fragment GSM 7-Bit encodable string for transmission. - * - * @param text - * text string to be fragmented. - * @param langTable - * locking shift table string. - * @param langShiftTable - * single shift table string. - * @param segmentSeptets - * Number of available spetets per segment. - * @param strict7BitEncoding - * Optional. Enable Latin characters replacement with corresponding - * ones in GSM SMS 7-bit default alphabet. - * - * @return an array of objects. See #_fragmentText() for detailed definition. - */ - _fragmentText7Bit: function _fragmentText7Bit(text, langTable, langShiftTable, - segmentSeptets, - strict7BitEncoding) { - let ret = []; - let body = "", len = 0; - for (let i = 0, inc = 0; i < text.length; i++) { - let c = text.charAt(i); - if (strict7BitEncoding) { - c = RIL.GSM_SMS_STRICT_7BIT_CHARMAP[c] || c; - } - - let septet = langTable.indexOf(c); - if (septet == RIL.PDU_NL_EXTENDED_ESCAPE) { - continue; - } - - if (septet >= 0) { - inc = 1; - } else { - septet = langShiftTable.indexOf(c); - if (septet == RIL.PDU_NL_RESERVED_CONTROL) { - continue; - } - - inc = 2; - if (septet < 0) { - if (!strict7BitEncoding) { - throw new Error("Given text cannot be encoded with GSM 7-bit Alphabet!"); - } - - // Bug 816082, when strict7BitEncoding is enabled, we should replace - // characters that can't be encoded with GSM 7-Bit alphabets with '*'. - c = '*'; - if (langTable.indexOf(c) >= 0) { - inc = 1; - } - } - } - - if ((len + inc) > segmentSeptets) { - ret.push({ - body: body, - encodedBodyLength: len, - }); - body = c; - len = inc; - } else { - body += c; - len += inc; - } - } - - if (len) { - ret.push({ - body: body, - encodedBodyLength: len, - }); - } - - return ret; - }, - - /** - * Fragment UCS2 encodable string for transmission. - * - * @param text - * text string to be fragmented. - * @param segmentChars - * Number of available characters per segment. - * - * @return an array of objects. See #_fragmentText() for detailed definition. - */ - _fragmentTextUCS2: function _fragmentTextUCS2(text, segmentChars) { - let ret = []; - for (let offset = 0; offset < text.length; offset += segmentChars) { - let str = text.substr(offset, segmentChars); - ret.push({ - body: str, - encodedBodyLength: str.length * 2, - }); - } - - return ret; - }, - - /** - * Fragment string for transmission. - * - * Fragment input text string into an array of objects that contains - * attributes `body`, substring for this segment, `encodedBodyLength`, - * length of the encoded segment body in septets. - * - * @param text - * Text string to be fragmented. - * @param options - * Optional pre-calculated option object. The output array will be - * stored at options.segments if there are multiple segments. - * @param strict7BitEncoding - * Optional. Enable Latin characters replacement with corresponding - * ones in GSM SMS 7-bit default alphabet. - * - * @return Populated options object. - */ - _fragmentText: function _fragmentText(text, options, strict7BitEncoding) { - if (!options) { - options = this._calculateUserDataLength(text, strict7BitEncoding); - } - - if (options.dcs == RIL.PDU_DCS_MSG_CODING_7BITS_ALPHABET) { - const langTable = RIL.PDU_NL_LOCKING_SHIFT_TABLES[options.langIndex]; - const langShiftTable = RIL.PDU_NL_SINGLE_SHIFT_TABLES[options.langShiftIndex]; - options.segments = this._fragmentText7Bit(text, - langTable, langShiftTable, - options.segmentChars, - strict7BitEncoding); - } else { - options.segments = this._fragmentTextUCS2(text, - options.segmentChars); - } - - // Re-sync options.segmentMaxSeq with actual length of returning array. - options.segmentMaxSeq = options.segments.length; - - return options; - }, - - /** - * A helper to broadcast the system message to launch registered apps - * like Costcontrol, Notification and Message app... etc. - * - * @param aName - * The system message name. - * @param aDomMessage - * The nsIDOMMozSmsMessage object. - */ - _broadcastSystemMessage: function _broadcastSystemMessage(aName, aDomMessage) { - if (DEBUG) debug("Broadcasting the SMS system message: " + aName); - - // Sadly we cannot directly broadcast the aDomMessage object - // because the system message mechamism will rewrap the object - // based on the content window, which needs to know the properties. - gSystemMessenger.broadcastMessage(aName, { - type: aDomMessage.type, - id: aDomMessage.id, - threadId: aDomMessage.threadId, - delivery: aDomMessage.delivery, - deliveryStatus: aDomMessage.deliveryStatus, - sender: aDomMessage.sender, - receiver: aDomMessage.receiver, - body: aDomMessage.body, - messageClass: aDomMessage.messageClass, - timestamp: aDomMessage.timestamp, - read: aDomMessage.read - }); - }, - - /** - * Handle WDP port push PDU. Constructor WDP bearer information and deliver - * to WapPushManager. - * - * @param message - * A SMS message. - */ - _handleSmsWdpPortPush: function _handleSmsWdpPortPush(message) { - if (message.encoding != RIL.PDU_DCS_MSG_CODING_8BITS_ALPHABET) { - if (DEBUG) { - debug("Got port addressed SMS but not encoded in 8-bit alphabet." + - " Drop!"); - } - return; - } - - let options = { - bearer: WAP.WDP_BEARER_GSM_SMS_GSM_MSISDN, - sourceAddress: message.sender, - sourcePort: message.header.originatorPort, - destinationAddress: this.rilContext.iccInfo.msisdn, - destinationPort: message.header.destinationPort, - }; - WAP.WapPushManager.receiveWdpPDU(message.fullData, message.fullData.length, - 0, options); - }, - - _isSilentNumber: function _isSilentNumber(number) { - return this.silentNumbers.indexOf(number) >= 0; - }, - - /** - * nsISmsService methods. - */ - - // TODO: Bug 859616 - WebSMS: return undefined if the API is unsupported on - // the platform, not null - hasSupport: function hasSupport() { - return true; - }, - - getSegmentInfoForText: function getSegmentInfoForText(text) { - let strict7BitEncoding = this._getStrict7BitEncoding(); - - let options = this._fragmentText(text, null, strict7BitEncoding); - let charsInLastSegment; - if (options.segmentMaxSeq) { - let lastSegment = options.segments[options.segmentMaxSeq - 1]; - charsInLastSegment = lastSegment.encodedBodyLength; - if (options.dcs == RIL.PDU_DCS_MSG_CODING_16BITS_ALPHABET) { - // In UCS2 encoding, encodedBodyLength is in octets. - charsInLastSegment /= 2; - } - } else { - charsInLastSegment = 0; - } - - let result = gMobileMessageService.createSmsSegmentInfo(options.segmentMaxSeq, - options.segmentChars, - options.segmentChars - charsInLastSegment); - return result; - }, - - send: function send(number, message, silent, request) { - let strict7BitEncoding = this._getStrict7BitEncoding(); - let requestStatusReport = this._getRequestStatusReport(); - - let options = this._fragmentText(message, null, strict7BitEncoding); - options.number = gPhoneNumberUtils.normalize(number); - options.requestStatusReport = requestStatusReport && !silent; - if (options.segmentMaxSeq > 1) { - options.segmentRef16Bit = this.segmentRef16Bit; - options.segmentRef = this.nextSegmentRef; - } - - let notifyResult = (function notifyResult(rv, domMessage) { - // TODO bug 832140 handle !Components.isSuccessCode(rv) - if (!silent) { - Services.obs.notifyObservers(domMessage, kSmsSendingObserverTopic, null); - } - - // If the radio is disabled or the SIM card is not ready, just directly - // return with the corresponding error code. - let errorCode; - if (!gPhoneNumberUtils.isPlainPhoneNumber(options.number)) { - if (DEBUG) debug("Error! Address is invalid when sending SMS: " + - options.number); - errorCode = Ci.nsIMobileMessageCallback.INVALID_ADDRESS_ERROR; - } else if (gRadioInterface.rilContext.radioState != - RIL.GECKO_RADIOSTATE_READY) { - if (DEBUG) debug("Error! Radio is disabled when sending SMS."); - errorCode = Ci.nsIMobileMessageCallback.RADIO_DISABLED_ERROR; - } else if (gRadioInterface.rilContext.cardState != - RIL.GECKO_CARDSTATE_READY) { - if (DEBUG) debug("Error! SIM card is not ready when sending SMS."); - errorCode = Ci.nsIMobileMessageCallback.NO_SIM_CARD_ERROR; - } - if (errorCode) { - if (silent) { - request.notifySendMessageFailed(errorCode); - return; - } - - gMobileMessageDatabaseService - .setMessageDeliveryByMessageId(domMessage.id, - null, - DELIVERY_STATE_ERROR, - RIL.GECKO_SMS_DELIVERY_STATUS_ERROR, - null, - function notifyResult(rv, domMessage) { - // TODO bug 832140 handle !Components.isSuccessCode(rv) - request.notifySendMessageFailed(errorCode); - Services.obs.notifyObservers(domMessage, kSmsFailedObserverTopic, null); - }); - return; - } - - // Keep current SMS message info for sent/delivered notifications - let context = { - request: request, - sms: domMessage, - requestStatusReport: options.requestStatusReport, - silent: silent - }; - - // This is the entry point starting to send SMS. - gRadioInterface.sendWorkerMessage("sendSMS", options, - (function(context, response) { - if (response.errorMsg) { - // Failed to send SMS out. - let error = Ci.nsIMobileMessageCallback.UNKNOWN_ERROR; - switch (message.errorMsg) { - case RIL.ERROR_RADIO_NOT_AVAILABLE: - error = Ci.nsIMobileMessageCallback.NO_SIGNAL_ERROR; - break; - } - - if (context.silent) { - context.request.notifySendMessageFailed(error); - return false; - } - - gMobileMessageDatabaseService - .setMessageDeliveryByMessageId(context.sms.id, - null, - DELIVERY_STATE_ERROR, - RIL.GECKO_SMS_DELIVERY_STATUS_ERROR, - null, - function notifyResult(rv, domMessage) { - // TODO bug 832140 handle !Components.isSuccessCode(rv) - context.request.notifySendMessageFailed(error); - Services.obs.notifyObservers(domMessage, kSmsFailedObserverTopic, null); - }); - return false; - } // End of send failure. - - if (response.deliveryStatus) { - // Message delivery. - gMobileMessageDatabaseService - .setMessageDeliveryByMessageId(context.sms.id, - null, - context.sms.delivery, - message.deliveryStatus, - null, - function notifyResult(rv, domMessage) { - // TODO bug 832140 handle !Components.isSuccessCode(rv) - let topic = (message.deliveryStatus == RIL.GECKO_SMS_DELIVERY_STATUS_SUCCESS) - ? kSmsDeliverySuccessObserverTopic - : kSmsDeliveryErrorObserverTopic; - Services.obs.notifyObservers(domMessage, topic, null); - }); - - // Send transaction has ended completely. - return false; - } // End of message delivery. - - // Message sent. - if (context.silent) { - // There is no way to modify nsIDOMMozSmsMessage attributes as they are - // read only so we just create a new sms instance to send along with - // the notification. - let sms = context.sms; - context.request.notifyMessageSent( - gMobileMessageService.createSmsMessage(sms.id, - sms.threadId, - DELIVERY_STATE_SENT, - sms.deliveryStatus, - sms.sender, - sms.receiver, - sms.body, - sms.messageClass, - sms.timestamp, - sms.read)); - // We don't wait for SMS-DELIVER-REPORT for silent one. - return false; - } - - gMobileMessageDatabaseService - .setMessageDeliveryByMessageId(context.sms.id, - null, - DELIVERY_STATE_SENT, - context.sms.deliveryStatus, - null, - (function notifyResult(rv, domMessage) { - // TODO bug 832140 handle !Components.isSuccessCode(rv) - this._broadcastSystemMessage("sms-sent", domMessage); - - if (context.requestStatusReport) { - context.sms = domMessage; - } - - context.request.notifyMessageSent(domMessage); - Services.obs.notifyObservers(domMessage, kSmsSentObserverTopic, null); - }).bind(this)); - - // Only keep current context if we have requested for delivery report. - return context.requestStatusReport; - }).bind(this, context)); // End of |sendWorkerMessage| callback. - }).bind(this); // End of DB saveSendingMessage callback. - - let sendingMessage = { - type: "sms", - sender: this._getMsisdn(), - receiver: number, - body: message, - deliveryStatusRequested: options.requestStatusReport, - timestamp: Date.now() - }; - - if (silent) { - let deliveryStatus = RIL.GECKO_SMS_DELIVERY_STATUS_PENDING; - let delivery = DELIVERY_STATE_SENDING; - let domMessage = - gMobileMessageService.createSmsMessage(-1, // id - 0, // threadId - delivery, - deliveryStatus, - sendingMessage.sender, - sendingMessage.receiver, - sendingMessage.body, - "normal", // message class - sendingMessage.timestamp, - false); - notifyResult(Cr.NS_OK, domMessage); - return; - } - - let id = gMobileMessageDatabaseService.saveSendingMessage( - sendingMessage, notifyResult); - }, - - addSilentNumber: function addSilentNumber(number) { - if (this._isSilentNumber(number)) { - throw Cr.NS_ERROR_UNEXPECTED; - } - - this.silentNumbers.push(number); - }, - - removeSilentNumber: function removeSilentNumber(number) { - let index = this.silentNumbers.indexOf(number); - if (index < 0) { - throw Cr.NS_ERROR_INVALID_ARG; - } - - this.silentNumbers.splice(index, 1); - }, - - /** - * nsIRilSmsService methods. - */ - - notifyMessageReceived: function notifyMessageReceived(message) { - if (DEBUG) debug("notifyMessageReceived: " + JSON.stringify(message)); - - // FIXME: Bug 737202 - Typed arrays become normal arrays when sent to/from workers - if (message.encoding == RIL.PDU_DCS_MSG_CODING_8BITS_ALPHABET) { - message.fullData = new Uint8Array(message.fullData); - } - - // Dispatch to registered handler if application port addressing is - // available. Note that the destination port can possibly be zero when - // representing a UDP/TCP port. - if (message.header && message.header.destinationPort != null) { - let handler = this.portAddressedSmsApps[message.header.destinationPort]; - if (handler) { - handler(message); - } - gRadioInterface.sendWorkerMessage("ackSMS", { result: RIL.PDU_FCS_OK }); - return; - } - - if (message.encoding == RIL.PDU_DCS_MSG_CODING_8BITS_ALPHABET) { - // Don't know how to handle binary data yet. - gRadioInterface.sendWorkerMessage("ackSMS", { result: RIL.PDU_FCS_OK }); - return; - } - - message.type = "sms"; - message.sender = message.sender || null; - message.receiver = this._getMsisdn(); - message.body = message.fullBody = message.fullBody || null; - message.timestamp = Date.now(); - - if (this._isSilentNumber(message.sender)) { - message.id = -1; - message.threadId = 0; - message.delivery = DELIVERY_STATE_RECEIVED; - message.deliveryStatus = RIL.GECKO_SMS_DELIVERY_STATUS_SUCCESS; - message.read = false; - - let domMessage = - gMobileMessageService.createSmsMessage(message.id, - message.threadId, - message.delivery, - message.deliveryStatus, - message.sender, - message.receiver, - message.body, - message.messageClass, - message.timestamp, - message.read); - - Services.obs.notifyObservers(domMessage, - kSilentSmsReceivedObserverTopic, - null); - gRadioInterface.sendWorkerMessage("ackSMS", { result: RIL.PDU_FCS_OK }); - return; - } - - // TODO: Bug #768441 - // For now we don't store indicators persistently. When the mwi.discard - // flag is false, we'll need to persist the indicator to EFmwis. - // See TS 23.040 9.2.3.24.2 - - let mwi = message.mwi; - if (mwi) { - mwi.returnNumber = message.sender; - mwi.returnMessage = message.fullBody; - gMessageManager.sendVoicemailMessage("RIL:VoicemailNotification", - this.clientId, mwi); - gRadioInterface.sendWorkerMessage("ackSMS", { result: RIL.PDU_FCS_OK }); - return; - } - - let notifyReceived = function notifyReceived(rv, domMessage) { - let success = Components.isSuccessCode(rv); - - // Acknowledge the reception of the SMS. - gRadioInterface.sendWorkerMessage("ackSMS", { - result: (success ? RIL.PDU_FCS_OK - : RIL.PDU_FCS_MEMORY_CAPACITY_EXCEEDED) - }); - - if (!success) { - // At this point we could send a message to content to notify the user - // that storing an incoming SMS failed, most likely due to a full disk. - if (DEBUG) { - debug("Could not store SMS " + message.id + ", error code " + rv); - } - return; - } - - this._broadcastSystemMessage("sms-received", domMessage); - Services.obs.notifyObservers(domMessage, kSmsReceivedObserverTopic, null); - }.bind(this); - - if (message.messageClass == RIL.GECKO_SMS_MESSAGE_CLASSES[RIL.PDU_DCS_MSG_CLASS_0]) { - message.id = -1; - message.threadId = 0; - message.delivery = DELIVERY_STATE_RECEIVED; - message.deliveryStatus = RIL.GECKO_SMS_DELIVERY_STATUS_SUCCESS; - message.read = false; - - let domMessage = - gMobileMessageService.createSmsMessage(message.id, - message.threadId, - message.delivery, - message.deliveryStatus, - message.sender, - message.receiver, - message.body, - message.messageClass, - message.timestamp, - message.read); - - notifyReceived(Cr.NS_OK, domMessage); - return; - } - - message.id = - gMobileMessageDatabaseService.saveReceivedMessage(message, - notifyReceived); - }, - - /** - * nsIObserver methods. - */ - - observe: function observe(subject, topic, data) { - switch (topic) { - case kPrefenceChangedObserverTopic: - if (data === "ril.debugging.enabled") { - try { - DEBUG = RIL.DEBUG_RIL || - Services.prefs.getBoolPref("ril.debugging.enabled"); - } catch(e) {} - } - break; - - case kXpcomShutdownObserverTopic: - Services.obs.removeObserver(this, kPrefenceChangedObserverTopic); - Services.obs.removeObserver(this, kXpcomShutdownObserverTopic); - break; - } - } -}; - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([SmsService]); diff --git a/dom/mobilemessage/src/gonk/SmsService.manifest b/dom/mobilemessage/src/gonk/SmsService.manifest deleted file mode 100644 index 0275b5a2be3..00000000000 --- a/dom/mobilemessage/src/gonk/SmsService.manifest +++ /dev/null @@ -1,3 +0,0 @@ -# SmsService.js -component {46a9ed78-3574-40a1-9f12-ea179942d67f} SmsService.js -contract @mozilla.org/sms/rilsmsservice;1 {46a9ed78-3574-40a1-9f12-ea179942d67f} diff --git a/dom/mobilemessage/src/ipc/SmsIPCService.cpp b/dom/mobilemessage/src/ipc/SmsIPCService.cpp index 0dd5d26d29d..eebcbdc9a4e 100644 --- a/dom/mobilemessage/src/ipc/SmsIPCService.cpp +++ b/dom/mobilemessage/src/ipc/SmsIPCService.cpp @@ -123,6 +123,14 @@ SmsIPCService::Send(const nsAString& aNumber, aRequest); } +NS_IMETHODIMP +SmsIPCService::IsSilentNumber(const nsAString& aNumber, + bool* aIsSilent) +{ + NS_ERROR("We should not be here!"); + return NS_ERROR_FAILURE; +} + NS_IMETHODIMP SmsIPCService::AddSilentNumber(const nsAString& aNumber) { diff --git a/dom/mobilemessage/src/moz.build b/dom/mobilemessage/src/moz.build index fa72d68ae99..505fddd8242 100644 --- a/dom/mobilemessage/src/moz.build +++ b/dom/mobilemessage/src/moz.build @@ -36,7 +36,6 @@ else: CPP_SOURCES += [ 'MobileMessageDatabaseService.cpp', 'MmsService.cpp', - 'SmsService.cpp', ] EXPORTS.mozilla.dom += [ @@ -61,6 +60,7 @@ CPP_SOURCES += [ 'SmsMessage.cpp', 'SmsParent.cpp', 'SmsSegmentInfo.cpp', + 'SmsService.cpp', 'SmsServicesFactory.cpp', ] @@ -70,8 +70,6 @@ if CONFIG['MOZ_B2G_RIL']: 'gonk/MmsService.manifest', 'gonk/MobileMessageDatabaseService.js', 'gonk/MobileMessageDatabaseService.manifest', - 'gonk/SmsService.js', - 'gonk/SmsService.manifest', ] IPDL_SOURCES += [ diff --git a/dom/system/gonk/RadioInterfaceLayer.js b/dom/system/gonk/RadioInterfaceLayer.js index 3857aeb5090..ee6547120ac 100644 --- a/dom/system/gonk/RadioInterfaceLayer.js +++ b/dom/system/gonk/RadioInterfaceLayer.js @@ -47,6 +47,13 @@ const RILNETWORKINTERFACE_CID = Components.ID("{3bdd52a9-3965-4130-b569-0ac5afed045e}"); const kNetworkInterfaceStateChangedTopic = "network-interface-state-changed"; +const kSmsReceivedObserverTopic = "sms-received"; +const kSilentSmsReceivedObserverTopic = "silent-sms-received"; +const kSmsSendingObserverTopic = "sms-sending"; +const kSmsSentObserverTopic = "sms-sent"; +const kSmsFailedObserverTopic = "sms-failed"; +const kSmsDeliverySuccessObserverTopic = "sms-delivery-success"; +const kSmsDeliveryErrorObserverTopic = "sms-delivery-error"; const kMozSettingsChangedObserverTopic = "mozsettings-changed"; const kSysMsgListenerReadyObserverTopic = "system-message-listener-ready"; const kSysClockChangeObserverTopic = "system-clock-change"; @@ -112,9 +119,17 @@ XPCOMUtils.defineLazyServiceGetter(this, "gPowerManagerService", "@mozilla.org/power/powermanagerservice;1", "nsIPowerManagerService"); +XPCOMUtils.defineLazyServiceGetter(this, "gMobileMessageService", + "@mozilla.org/mobilemessage/mobilemessageservice;1", + "nsIMobileMessageService"); + XPCOMUtils.defineLazyServiceGetter(this, "gSmsService", - "@mozilla.org/sms/rilsmsservice;1", - "nsIRilSmsService"); + "@mozilla.org/sms/smsservice;1", + "nsISmsService"); + +XPCOMUtils.defineLazyServiceGetter(this, "gMobileMessageDatabaseService", + "@mozilla.org/mobilemessage/rilmobilemessagedatabaseservice;1", + "nsIRilMobileMessageDatabaseService"); XPCOMUtils.defineLazyServiceGetter(this, "gSettingsService", "@mozilla.org/settingsService;1", @@ -140,6 +155,12 @@ XPCOMUtils.defineLazyServiceGetter(this, "gTelephonyProvider", "@mozilla.org/telephony/telephonyprovider;1", "nsIGonkTelephonyProvider"); +XPCOMUtils.defineLazyGetter(this, "WAP", function () { + let wap = {}; + Cu.import("resource://gre/modules/WapPushManager.js", wap); + return wap; +}); + XPCOMUtils.defineLazyGetter(this, "PhoneNumberUtils", function () { let ns = {}; Cu.import("resource://gre/modules/PhoneNumberUtils.jsm", ns); @@ -446,6 +467,9 @@ function RadioInterface(options) { Services.obs.addObserver(this, kScreenStateChangedTopic, false); Services.prefs.addObserver(kCellBroadcastDisabled, this, false); + + this.portAddressedSmsApps = {}; + this.portAddressedSmsApps[WAP.WDP_PORT_PUSH] = this.handleSmsWdpPortPush.bind(this); } RadioInterface.prototype = { @@ -673,8 +697,11 @@ RadioInterface.prototype = { this.clientId, message); break; case "sms-received": - gSmsService.notifyMessageReceived(message); - break; + let ackOk = this.handleSmsReceived(message); + if (ackOk) { + this.workerMessenger.send("ackSMS", { result: RIL.PDU_FCS_OK }); + } + return; case "cellbroadcast-received": message.timestamp = Date.now(); gMessageManager.sendCellBroadcastMessage("RIL:CellBroadcastReceived", @@ -721,6 +748,18 @@ RadioInterface.prototype = { } }, + getMsisdn: function getMsisdn() { + let iccInfo = this.rilContext.iccInfo; + let number = iccInfo ? iccInfo.msisdn : null; + + // Workaround an xpconnect issue with undefined string objects. + // See bug 808220 + if (number === undefined || number === "undefined") { + return null; + } + return number; + }, + updateNetworkInfo: function updateNetworkInfo(message) { let voiceMessage = message[RIL.NETWORK_INFO_VOICE_REGISTRATION_STATE]; let dataMessage = message[RIL.NETWORK_INFO_DATA_REGISTRATION_STATE]; @@ -1287,6 +1326,184 @@ RadioInterface.prototype = { this.clientId, message); }, + /** + * Handle WDP port push PDU. Constructor WDP bearer information and deliver + * to WapPushManager. + * + * @param message + * A SMS message. + */ + handleSmsWdpPortPush: function handleSmsWdpPortPush(message) { + if (message.encoding != RIL.PDU_DCS_MSG_CODING_8BITS_ALPHABET) { + if (DEBUG) { + this.debug("Got port addressed SMS but not encoded in 8-bit alphabet." + + " Drop!"); + } + return; + } + + let options = { + bearer: WAP.WDP_BEARER_GSM_SMS_GSM_MSISDN, + sourceAddress: message.sender, + sourcePort: message.header.originatorPort, + destinationAddress: this.rilContext.iccInfo.msisdn, + destinationPort: message.header.destinationPort, + }; + WAP.WapPushManager.receiveWdpPDU(message.fullData, message.fullData.length, + 0, options); + }, + + /** + * A helper to broadcast the system message to launch registered apps + * like Costcontrol, Notification and Message app... etc. + * + * @param aName + * The system message name. + * @param aDomMessage + * The nsIDOMMozSmsMessage object. + */ + broadcastSmsSystemMessage: function broadcastSmsSystemMessage(aName, aDomMessage) { + if (DEBUG) this.debug("Broadcasting the SMS system message: " + aName); + + // Sadly we cannot directly broadcast the aDomMessage object + // because the system message mechamism will rewrap the object + // based on the content window, which needs to know the properties. + gSystemMessenger.broadcastMessage(aName, { + type: aDomMessage.type, + id: aDomMessage.id, + threadId: aDomMessage.threadId, + delivery: aDomMessage.delivery, + deliveryStatus: aDomMessage.deliveryStatus, + sender: aDomMessage.sender, + receiver: aDomMessage.receiver, + body: aDomMessage.body, + messageClass: aDomMessage.messageClass, + timestamp: aDomMessage.timestamp, + read: aDomMessage.read + }); + }, + + portAddressedSmsApps: null, + handleSmsReceived: function handleSmsReceived(message) { + if (DEBUG) this.debug("handleSmsReceived: " + JSON.stringify(message)); + + // FIXME: Bug 737202 - Typed arrays become normal arrays when sent to/from workers + if (message.encoding == RIL.PDU_DCS_MSG_CODING_8BITS_ALPHABET) { + message.fullData = new Uint8Array(message.fullData); + } + + // Dispatch to registered handler if application port addressing is + // available. Note that the destination port can possibly be zero when + // representing a UDP/TCP port. + if (message.header && message.header.destinationPort != null) { + let handler = this.portAddressedSmsApps[message.header.destinationPort]; + if (handler) { + handler(message); + } + return true; + } + + if (message.encoding == RIL.PDU_DCS_MSG_CODING_8BITS_ALPHABET) { + // Don't know how to handle binary data yet. + return true; + } + + message.type = "sms"; + message.sender = message.sender || null; + message.receiver = this.getMsisdn(); + message.body = message.fullBody = message.fullBody || null; + message.timestamp = Date.now(); + + if (gSmsService.isSilentNumber(message.sender)) { + message.id = -1; + message.threadId = 0; + message.delivery = DOM_MOBILE_MESSAGE_DELIVERY_RECEIVED; + message.deliveryStatus = RIL.GECKO_SMS_DELIVERY_STATUS_SUCCESS; + message.read = false; + + let domMessage = + gMobileMessageService.createSmsMessage(message.id, + message.threadId, + message.delivery, + message.deliveryStatus, + message.sender, + message.receiver, + message.body, + message.messageClass, + message.timestamp, + message.read); + + Services.obs.notifyObservers(domMessage, + kSilentSmsReceivedObserverTopic, + null); + return true; + } + + // TODO: Bug #768441 + // For now we don't store indicators persistently. When the mwi.discard + // flag is false, we'll need to persist the indicator to EFmwis. + // See TS 23.040 9.2.3.24.2 + + let mwi = message.mwi; + if (mwi) { + mwi.returnNumber = message.sender; + mwi.returnMessage = message.fullBody; + gMessageManager.sendVoicemailMessage("RIL:VoicemailNotification", + this.clientId, mwi); + return true; + } + + let notifyReceived = function notifyReceived(rv, domMessage) { + let success = Components.isSuccessCode(rv); + + // Acknowledge the reception of the SMS. + this.workerMessenger.send("ackSMS", { + result: (success ? RIL.PDU_FCS_OK + : RIL.PDU_FCS_MEMORY_CAPACITY_EXCEEDED) + }); + + if (!success) { + // At this point we could send a message to content to notify the user + // that storing an incoming SMS failed, most likely due to a full disk. + if (DEBUG) { + this.debug("Could not store SMS " + message.id + ", error code " + rv); + } + return; + } + + this.broadcastSmsSystemMessage("sms-received", domMessage); + Services.obs.notifyObservers(domMessage, kSmsReceivedObserverTopic, null); + }.bind(this); + + if (message.messageClass != RIL.GECKO_SMS_MESSAGE_CLASSES[RIL.PDU_DCS_MSG_CLASS_0]) { + message.id = gMobileMessageDatabaseService.saveReceivedMessage(message, + notifyReceived); + } else { + message.id = -1; + message.threadId = 0; + message.delivery = DOM_MOBILE_MESSAGE_DELIVERY_RECEIVED; + message.deliveryStatus = RIL.GECKO_SMS_DELIVERY_STATUS_SUCCESS; + message.read = false; + + let domMessage = + gMobileMessageService.createSmsMessage(message.id, + message.threadId, + message.delivery, + message.deliveryStatus, + message.sender, + message.receiver, + message.body, + message.messageClass, + message.timestamp, + message.read); + + notifyReceived(Cr.NS_OK, domMessage); + } + + // SMS ACK will be sent in notifyReceived. Return false here. + return false; + }, + /** * Handle data call state changes. */ @@ -1706,6 +1923,622 @@ RadioInterface.prototype = { }).bind(this)); }, + /** + * List of tuples of national language identifier pairs. + * + * TODO: Support static/runtime settings, see bug 733331. + */ + enabledGsmTableTuples: [ + [RIL.PDU_NL_IDENTIFIER_DEFAULT, RIL.PDU_NL_IDENTIFIER_DEFAULT], + ], + + /** + * Use 16-bit reference number for concatenated outgoint messages. + * + * TODO: Support static/runtime settings, see bug 733331. + */ + segmentRef16Bit: false, + + /** + * Get valid SMS concatenation reference number. + */ + _segmentRef: 0, + get nextSegmentRef() { + let ref = this._segmentRef++; + + this._segmentRef %= (this.segmentRef16Bit ? 65535 : 255); + + // 0 is not a valid SMS concatenation reference number. + return ref + 1; + }, + + /** + * Calculate encoded length using specified locking/single shift table + * + * @param message + * message string to be encoded. + * @param langTable + * locking shift table string. + * @param langShiftTable + * single shift table string. + * @param strict7BitEncoding + * Optional. Enable Latin characters replacement with corresponding + * ones in GSM SMS 7-bit default alphabet. + * + * @return encoded length in septets. + * + * @note that the algorithm used in this function must match exactly with + * GsmPDUHelper#writeStringAsSeptets. + */ + _countGsm7BitSeptets: function _countGsm7BitSeptets(message, langTable, langShiftTable, strict7BitEncoding) { + let length = 0; + for (let msgIndex = 0; msgIndex < message.length; msgIndex++) { + let c = message.charAt(msgIndex); + if (strict7BitEncoding) { + c = RIL.GSM_SMS_STRICT_7BIT_CHARMAP[c] || c; + } + + let septet = langTable.indexOf(c); + + // According to 3GPP TS 23.038, section 6.1.1 General notes, "The + // characters marked '1)' are not used but are displayed as a space." + if (septet == RIL.PDU_NL_EXTENDED_ESCAPE) { + continue; + } + + if (septet >= 0) { + length++; + continue; + } + + septet = langShiftTable.indexOf(c); + if (septet < 0) { + if (!strict7BitEncoding) { + return -1; + } + + // Bug 816082, when strict7BitEncoding is enabled, we should replace + // characters that can't be encoded with GSM 7-Bit alphabets with '*'. + c = '*'; + if (langTable.indexOf(c) >= 0) { + length++; + } else if (langShiftTable.indexOf(c) >= 0) { + length += 2; + } else { + // We can't even encode a '*' character with current configuration. + return -1; + } + + continue; + } + + // According to 3GPP TS 23.038 B.2, "This code represents a control + // character and therefore must not be used for language specific + // characters." + if (septet == RIL.PDU_NL_RESERVED_CONTROL) { + continue; + } + + // The character is not found in locking shfit table, but could be + // encoded as with single shift table. Note that it's + // still possible for septet to has the value of PDU_NL_EXTENDED_ESCAPE, + // but we can display it as a space in this case as said in previous + // comment. + length += 2; + } + + return length; + }, + + /** + * Calculate user data length of specified message string encoded in GSM 7Bit + * alphabets. + * + * @param message + * a message string to be encoded. + * @param strict7BitEncoding + * Optional. Enable Latin characters replacement with corresponding + * ones in GSM SMS 7-bit default alphabet. + * + * @return null or an options object with attributes `dcs`, + * `userDataHeaderLength`, `encodedFullBodyLength`, `langIndex`, + * `langShiftIndex`, `segmentMaxSeq` set. + * + * @see #_calculateUserDataLength(). + */ + _calculateUserDataLength7Bit: function _calculateUserDataLength7Bit(message, strict7BitEncoding) { + let options = null; + let minUserDataSeptets = Number.MAX_VALUE; + for (let i = 0; i < this.enabledGsmTableTuples.length; i++) { + let [langIndex, langShiftIndex] = this.enabledGsmTableTuples[i]; + + const langTable = RIL.PDU_NL_LOCKING_SHIFT_TABLES[langIndex]; + const langShiftTable = RIL.PDU_NL_SINGLE_SHIFT_TABLES[langShiftIndex]; + + let bodySeptets = this._countGsm7BitSeptets(message, + langTable, + langShiftTable, + strict7BitEncoding); + if (bodySeptets < 0) { + continue; + } + + let headerLen = 0; + if (langIndex != RIL.PDU_NL_IDENTIFIER_DEFAULT) { + headerLen += 3; // IEI + len + langIndex + } + if (langShiftIndex != RIL.PDU_NL_IDENTIFIER_DEFAULT) { + headerLen += 3; // IEI + len + langShiftIndex + } + + // Calculate full user data length, note the extra byte is for header len + let headerSeptets = Math.ceil((headerLen ? headerLen + 1 : 0) * 8 / 7); + let segmentSeptets = RIL.PDU_MAX_USER_DATA_7BIT; + if ((bodySeptets + headerSeptets) > segmentSeptets) { + headerLen += this.segmentRef16Bit ? 6 : 5; + headerSeptets = Math.ceil((headerLen + 1) * 8 / 7); + segmentSeptets -= headerSeptets; + } + + let segments = Math.ceil(bodySeptets / segmentSeptets); + let userDataSeptets = bodySeptets + headerSeptets * segments; + if (userDataSeptets >= minUserDataSeptets) { + continue; + } + + minUserDataSeptets = userDataSeptets; + + options = { + dcs: RIL.PDU_DCS_MSG_CODING_7BITS_ALPHABET, + encodedFullBodyLength: bodySeptets, + userDataHeaderLength: headerLen, + langIndex: langIndex, + langShiftIndex: langShiftIndex, + segmentMaxSeq: segments, + segmentChars: segmentSeptets, + }; + } + + return options; + }, + + /** + * Calculate user data length of specified message string encoded in UCS2. + * + * @param message + * a message string to be encoded. + * + * @return an options object with attributes `dcs`, `userDataHeaderLength`, + * `encodedFullBodyLength`, `segmentMaxSeq` set. + * + * @see #_calculateUserDataLength(). + */ + _calculateUserDataLengthUCS2: function _calculateUserDataLengthUCS2(message) { + let bodyChars = message.length; + let headerLen = 0; + let headerChars = Math.ceil((headerLen ? headerLen + 1 : 0) / 2); + let segmentChars = RIL.PDU_MAX_USER_DATA_UCS2; + if ((bodyChars + headerChars) > segmentChars) { + headerLen += this.segmentRef16Bit ? 6 : 5; + headerChars = Math.ceil((headerLen + 1) / 2); + segmentChars -= headerChars; + } + + let segments = Math.ceil(bodyChars / segmentChars); + + return { + dcs: RIL.PDU_DCS_MSG_CODING_16BITS_ALPHABET, + encodedFullBodyLength: bodyChars * 2, + userDataHeaderLength: headerLen, + segmentMaxSeq: segments, + segmentChars: segmentChars, + }; + }, + + /** + * Calculate user data length and its encoding. + * + * @param message + * a message string to be encoded. + * @param strict7BitEncoding + * Optional. Enable Latin characters replacement with corresponding + * ones in GSM SMS 7-bit default alphabet. + * + * @return an options object with some or all of following attributes set: + * + * @param dcs + * Data coding scheme. One of the PDU_DCS_MSG_CODING_*BITS_ALPHABET + * constants. + * @param userDataHeaderLength + * Length of embedded user data header, in bytes. The whole header + * size will be userDataHeaderLength + 1; 0 for no header. + * @param encodedFullBodyLength + * Length of the message body when encoded with the given DCS. For + * UCS2, in bytes; for 7-bit, in septets. + * @param langIndex + * Table index used for normal 7-bit encoded character lookup. + * @param langShiftIndex + * Table index used for escaped 7-bit encoded character lookup. + * @param segmentMaxSeq + * Max sequence number of a multi-part messages, or 1 for single one. + * This number might not be accurate for a multi-part message until + * it's processed by #_fragmentText() again. + */ + _calculateUserDataLength: function _calculateUserDataLength(message, strict7BitEncoding) { + let options = this._calculateUserDataLength7Bit(message, strict7BitEncoding); + if (!options) { + options = this._calculateUserDataLengthUCS2(message); + } + + if (DEBUG) this.debug("_calculateUserDataLength: " + JSON.stringify(options)); + return options; + }, + + /** + * Fragment GSM 7-Bit encodable string for transmission. + * + * @param text + * text string to be fragmented. + * @param langTable + * locking shift table string. + * @param langShiftTable + * single shift table string. + * @param segmentSeptets + * Number of available spetets per segment. + * @param strict7BitEncoding + * Optional. Enable Latin characters replacement with corresponding + * ones in GSM SMS 7-bit default alphabet. + * + * @return an array of objects. See #_fragmentText() for detailed definition. + */ + _fragmentText7Bit: function _fragmentText7Bit(text, langTable, langShiftTable, segmentSeptets, strict7BitEncoding) { + let ret = []; + let body = "", len = 0; + for (let i = 0, inc = 0; i < text.length; i++) { + let c = text.charAt(i); + if (strict7BitEncoding) { + c = RIL.GSM_SMS_STRICT_7BIT_CHARMAP[c] || c; + } + + let septet = langTable.indexOf(c); + if (septet == RIL.PDU_NL_EXTENDED_ESCAPE) { + continue; + } + + if (septet >= 0) { + inc = 1; + } else { + septet = langShiftTable.indexOf(c); + if (septet == RIL.PDU_NL_RESERVED_CONTROL) { + continue; + } + + inc = 2; + if (septet < 0) { + if (!strict7BitEncoding) { + throw new Error("Given text cannot be encoded with GSM 7-bit Alphabet!"); + } + + // Bug 816082, when strict7BitEncoding is enabled, we should replace + // characters that can't be encoded with GSM 7-Bit alphabets with '*'. + c = '*'; + if (langTable.indexOf(c) >= 0) { + inc = 1; + } + } + } + + if ((len + inc) > segmentSeptets) { + ret.push({ + body: body, + encodedBodyLength: len, + }); + body = c; + len = inc; + } else { + body += c; + len += inc; + } + } + + if (len) { + ret.push({ + body: body, + encodedBodyLength: len, + }); + } + + return ret; + }, + + /** + * Fragment UCS2 encodable string for transmission. + * + * @param text + * text string to be fragmented. + * @param segmentChars + * Number of available characters per segment. + * + * @return an array of objects. See #_fragmentText() for detailed definition. + */ + _fragmentTextUCS2: function _fragmentTextUCS2(text, segmentChars) { + let ret = []; + for (let offset = 0; offset < text.length; offset += segmentChars) { + let str = text.substr(offset, segmentChars); + ret.push({ + body: str, + encodedBodyLength: str.length * 2, + }); + } + + return ret; + }, + + /** + * Fragment string for transmission. + * + * Fragment input text string into an array of objects that contains + * attributes `body`, substring for this segment, `encodedBodyLength`, + * length of the encoded segment body in septets. + * + * @param text + * Text string to be fragmented. + * @param options + * Optional pre-calculated option object. The output array will be + * stored at options.segments if there are multiple segments. + * @param strict7BitEncoding + * Optional. Enable Latin characters replacement with corresponding + * ones in GSM SMS 7-bit default alphabet. + * + * @return Populated options object. + */ + _fragmentText: function _fragmentText(text, options, strict7BitEncoding) { + if (!options) { + options = this._calculateUserDataLength(text, strict7BitEncoding); + } + + if (options.dcs == RIL.PDU_DCS_MSG_CODING_7BITS_ALPHABET) { + const langTable = RIL.PDU_NL_LOCKING_SHIFT_TABLES[options.langIndex]; + const langShiftTable = RIL.PDU_NL_SINGLE_SHIFT_TABLES[options.langShiftIndex]; + options.segments = this._fragmentText7Bit(text, + langTable, langShiftTable, + options.segmentChars, + strict7BitEncoding); + } else { + options.segments = this._fragmentTextUCS2(text, + options.segmentChars); + } + + // Re-sync options.segmentMaxSeq with actual length of returning array. + options.segmentMaxSeq = options.segments.length; + + return options; + }, + + getSegmentInfoForText: function getSegmentInfoForText(text) { + let strict7BitEncoding; + try { + strict7BitEncoding = Services.prefs.getBoolPref("dom.sms.strict7BitEncoding"); + } catch (e) { + strict7BitEncoding = false; + } + + let options = this._fragmentText(text, null, strict7BitEncoding); + let charsInLastSegment; + if (options.segmentMaxSeq) { + let lastSegment = options.segments[options.segmentMaxSeq - 1]; + charsInLastSegment = lastSegment.encodedBodyLength; + if (options.dcs == RIL.PDU_DCS_MSG_CODING_16BITS_ALPHABET) { + // In UCS2 encoding, encodedBodyLength is in octets. + charsInLastSegment /= 2; + } + } else { + charsInLastSegment = 0; + } + + let result = gMobileMessageService.createSmsSegmentInfo(options.segmentMaxSeq, + options.segmentChars, + options.segmentChars - charsInLastSegment); + return result; + }, + + sendSMS: function sendSMS(number, message, silent, request) { + let strict7BitEncoding; + try { + strict7BitEncoding = Services.prefs.getBoolPref("dom.sms.strict7BitEncoding"); + } catch (e) { + strict7BitEncoding = false; + } + + let options = this._fragmentText(message, null, strict7BitEncoding); + options.number = PhoneNumberUtils.normalize(number); + let requestStatusReport; + try { + requestStatusReport = + Services.prefs.getBoolPref("dom.sms.requestStatusReport"); + } catch (e) { + requestStatusReport = true; + } + options.requestStatusReport = requestStatusReport && !silent; + if (options.segmentMaxSeq > 1) { + options.segmentRef16Bit = this.segmentRef16Bit; + options.segmentRef = this.nextSegmentRef; + } + + let notifyResult = (function notifyResult(rv, domMessage) { + // TODO bug 832140 handle !Components.isSuccessCode(rv) + if (!silent) { + Services.obs.notifyObservers(domMessage, kSmsSendingObserverTopic, null); + } + + // If the radio is disabled or the SIM card is not ready, just directly + // return with the corresponding error code. + let errorCode; + if (!PhoneNumberUtils.isPlainPhoneNumber(options.number)) { + if (DEBUG) this.debug("Error! Address is invalid when sending SMS: " + + options.number); + errorCode = Ci.nsIMobileMessageCallback.INVALID_ADDRESS_ERROR; + } else if (!this._radioEnabled) { + if (DEBUG) this.debug("Error! Radio is disabled when sending SMS."); + errorCode = Ci.nsIMobileMessageCallback.RADIO_DISABLED_ERROR; + } else if (this.rilContext.cardState != "ready") { + if (DEBUG) this.debug("Error! SIM card is not ready when sending SMS."); + errorCode = Ci.nsIMobileMessageCallback.NO_SIM_CARD_ERROR; + } + if (errorCode) { + if (silent) { + request.notifySendMessageFailed(errorCode); + return; + } + + gMobileMessageDatabaseService + .setMessageDeliveryByMessageId(domMessage.id, + null, + DOM_MOBILE_MESSAGE_DELIVERY_ERROR, + RIL.GECKO_SMS_DELIVERY_STATUS_ERROR, + null, + function notifyResult(rv, domMessage) { + // TODO bug 832140 handle !Components.isSuccessCode(rv) + request.notifySendMessageFailed(errorCode); + Services.obs.notifyObservers(domMessage, kSmsFailedObserverTopic, null); + }); + return; + } + + // Keep current SMS message info for sent/delivered notifications + let context = { + request: request, + sms: domMessage, + requestStatusReport: options.requestStatusReport, + silent: silent + }; + + // This is the entry point starting to send SMS. + this.workerMessenger.send("sendSMS", options, + (function(context, response) { + if (response.errorMsg) { + // Failed to send SMS out. + let error = Ci.nsIMobileMessageCallback.UNKNOWN_ERROR; + switch (message.errorMsg) { + case RIL.ERROR_RADIO_NOT_AVAILABLE: + error = Ci.nsIMobileMessageCallback.NO_SIGNAL_ERROR; + break; + } + + if (context.silent) { + context.request.notifySendMessageFailed(error); + return false; + } + + gMobileMessageDatabaseService + .setMessageDeliveryByMessageId(context.sms.id, + null, + DOM_MOBILE_MESSAGE_DELIVERY_ERROR, + RIL.GECKO_SMS_DELIVERY_STATUS_ERROR, + null, + function notifyResult(rv, domMessage) { + // TODO bug 832140 handle !Components.isSuccessCode(rv) + context.request.notifySendMessageFailed(error); + Services.obs.notifyObservers(domMessage, kSmsFailedObserverTopic, null); + }); + return false; + } // End of send failure. + + if (response.deliveryStatus) { + // Message delivery. + gMobileMessageDatabaseService + .setMessageDeliveryByMessageId(context.sms.id, + null, + context.sms.delivery, + response.deliveryStatus, + null, + function notifyResult(rv, domMessage) { + // TODO bug 832140 handle !Components.isSuccessCode(rv) + let topic = (response.deliveryStatus == RIL.GECKO_SMS_DELIVERY_STATUS_SUCCESS) + ? kSmsDeliverySuccessObserverTopic + : kSmsDeliveryErrorObserverTopic; + Services.obs.notifyObservers(domMessage, topic, null); + }); + + // Send transaction has ended completely. + return false; + } // End of message delivery. + + // Message sent. + if (context.silent) { + // There is no way to modify nsIDOMMozSmsMessage attributes as they are + // read only so we just create a new sms instance to send along with + // the notification. + let sms = context.sms; + context.request.notifyMessageSent( + gMobileMessageService.createSmsMessage(sms.id, + sms.threadId, + DOM_MOBILE_MESSAGE_DELIVERY_SENT, + sms.deliveryStatus, + sms.sender, + sms.receiver, + sms.body, + sms.messageClass, + sms.timestamp, + sms.read)); + // We don't wait for SMS-DELIVER-REPORT for silent one. + return false; + } + + gMobileMessageDatabaseService + .setMessageDeliveryByMessageId(context.sms.id, + null, + DOM_MOBILE_MESSAGE_DELIVERY_SENT, + context.sms.deliveryStatus, + null, + (function notifyResult(rv, domMessage) { + // TODO bug 832140 handle !Components.isSuccessCode(rv) + this.broadcastSmsSystemMessage("sms-sent", domMessage); + + if (context.requestStatusReport) { + context.sms = domMessage; + } + + context.request.notifyMessageSent(domMessage); + Services.obs.notifyObservers(domMessage, kSmsSentObserverTopic, null); + }).bind(this)); + + // Only keep current context if we have requested for delivery report. + return context.requestStatusReport; + }).bind(this, context)); // End of |workerMessenger.send| callback. + }).bind(this); // End of DB saveSendingMessage callback. + + let sendingMessage = { + type: "sms", + sender: this.getMsisdn(), + receiver: number, + body: message, + deliveryStatusRequested: options.requestStatusReport, + timestamp: Date.now() + }; + + if (silent) { + let deliveryStatus = RIL.GECKO_SMS_DELIVERY_STATUS_PENDING; + let delivery = DOM_MOBILE_MESSAGE_DELIVERY_SENDING; + let domMessage = + gMobileMessageService.createSmsMessage(-1, // id + 0, // threadId + delivery, + deliveryStatus, + sendingMessage.sender, + sendingMessage.receiver, + sendingMessage.body, + "normal", // message class + sendingMessage.timestamp, + false); + notifyResult(Cr.NS_OK, domMessage); + return; + } + + let id = gMobileMessageDatabaseService.saveSendingMessage( + sendingMessage, notifyResult); + }, + registerDataCallCallback: function registerDataCallCallback(callback) { if (this._datacall_callbacks) { if (this._datacall_callbacks.indexOf(callback) != -1) { diff --git a/dom/system/gonk/nsIRadioInterfaceLayer.idl b/dom/system/gonk/nsIRadioInterfaceLayer.idl index 770c1e1acf7..c9c7eeb51ae 100644 --- a/dom/system/gonk/nsIRadioInterfaceLayer.idl +++ b/dom/system/gonk/nsIRadioInterfaceLayer.idl @@ -6,6 +6,8 @@ interface nsIDOMMozIccInfo; interface nsIDOMMozMobileConnectionInfo; +interface nsIDOMMozSmsSegmentInfo; +interface nsIMobileMessageCallback; [scriptable, uuid(1e602d20-d066-4399-8997-daf36b3158ef)] interface nsIRILDataCallInfo : nsISupports @@ -83,7 +85,7 @@ interface nsIRilSendWorkerMessageCallback : nsISupports boolean handleResponse(in jsval response); }; -[scriptable, uuid(b1af7aad-6547-427c-a878-e2ebf98a14d6)] +[scriptable, uuid(61a8ca67-6113-4cd0-b443-e045f09863ed)] interface nsIRadioInterface : nsISupports { readonly attribute nsIRilContext rilContext; @@ -100,6 +102,16 @@ interface nsIRadioInterface : nsISupports void updateRILNetworkInterface(); + /** + * SMS-related functionality. + */ + nsIDOMMozSmsSegmentInfo getSegmentInfoForText(in DOMString text); + + void sendSMS(in DOMString number, + in DOMString message, + in boolean silent, + in nsIMobileMessageCallback request); + void sendWorkerMessage(in DOMString type, [optional] in jsval message, [optional] in nsIRilSendWorkerMessageCallback callback); From 90809565fde4c9ec2258f861b4b11159243f4a9e Mon Sep 17 00:00:00 2001 From: Ed Morley Date: Wed, 4 Sep 2013 11:50:49 +0100 Subject: [PATCH 020/171] Backed out changeset 21b97e0e5a10 (bug 907585) --- dom/system/gonk/RilMessageManager.jsm | 65 ++++++--------------------- 1 file changed, 14 insertions(+), 51 deletions(-) diff --git a/dom/system/gonk/RilMessageManager.jsm b/dom/system/gonk/RilMessageManager.jsm index fece7a68fc3..d0bb414d595 100644 --- a/dom/system/gonk/RilMessageManager.jsm +++ b/dom/system/gonk/RilMessageManager.jsm @@ -16,15 +16,7 @@ XPCOMUtils.defineLazyServiceGetter(this, "ppmm", "nsIMessageBroadcaster"); // Observer topics. -const kPrefenceChangedObserverTopic = "nsPref:changed"; const kSysMsgListenerReadyObserverTopic = "system-message-listener-ready"; -const kXpcomShutdownObserverTopic = "xpcom-shutdown"; - -// Preference keys. -const kPrefKeyRilDebuggingEnabled = "ril.debugging.enabled"; - -// Frame message names. -const kMsgNameChildProcessShutdown = "child-process-shutdown"; let DEBUG; function debug(s) { @@ -59,13 +51,10 @@ this.RilMessageManager = { ready: false, _init: function _init() { - this._updateDebugFlag(); - - Services.obs.addObserver(this, kPrefenceChangedObserverTopic, false); + Services.obs.addObserver(this, "xpcom-shutdown", false); Services.obs.addObserver(this, kSysMsgListenerReadyObserverTopic, false); - Services.obs.addObserver(this, kXpcomShutdownObserverTopic, false); - ppmm.addMessageListener(kMsgNameChildProcessShutdown, this); + ppmm.addMessageListener("child-process-shutdown", this); let callback = this._registerMessageTarget.bind(this); for (let topic in this.topicRegistrationNames) { @@ -75,22 +64,15 @@ this.RilMessageManager = { }, _shutdown: function _shutdown() { - if (!this.ready) { - Services.obs.removeObserver(this, kSysMsgListenerReadyObserverTopic); - } - Services.obs.removeObserver(this, kPrefenceChangedObserverTopic); - Services.obs.removeObserver(this, kXpcomShutdownObserverTopic); + Services.obs.removeObserver(this, "xpcom-shutdown"); for (let name in this.callbacksByName) { ppmm.removeMessageListener(name, this); } this.callbacksByName = null; - ppmm.removeMessageListener(kMsgNameChildProcessShutdown, this); + ppmm.removeMessageListener("child-process-shutdown", this); ppmm = null; - - this.targetsByTopic = null; - this.targetMessageQueue = null; }, _registerMessageTarget: function _registerMessageTarget(topic, msg) { @@ -169,9 +151,12 @@ this.RilMessageManager = { }, _resendQueuedTargetMessage: function _resendQueuedTargetMessage() { + 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. + // 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 (let msg of this.targetMessageQueue) { @@ -180,23 +165,13 @@ this.RilMessageManager = { this.targetMessageQueue = null; }, - _updateDebugFlag: function _updateDebugFlag() { - try { - DEBUG = RIL.DEBUG_RIL || - Services.prefs.getBoolPref(kPrefKeyRilDebuggingEnabled); - } catch(e) {} - }, - /** * nsIMessageListener interface methods. */ receiveMessage: function receiveMessage(msg) { - if (DEBUG) { - debug("Received '" + msg.name + "' message from content process"); - } - - if (msg.name == kMsgNameChildProcessShutdown) { + 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. @@ -228,19 +203,10 @@ this.RilMessageManager = { observe: function observe(subject, topic, data) { switch (topic) { case kSysMsgListenerReadyObserverTopic: - this.ready = true; Services.obs.removeObserver(this, kSysMsgListenerReadyObserverTopic); - this._resendQueuedTargetMessage(); break; - - case kPrefenceChangedObserverTopic: - if (data === kPrefKeyRilDebuggingEnabled) { - this._updateDebugFlag(); - } - break; - - case kXpcomShutdownObserverTopic: + case "xpcom-shutdown": this._shutdown(); break; } @@ -293,9 +259,7 @@ this.RilMessageManager = { this.callbacksByName = remains; }, - sendMobileConnectionMessage: function sendMobileConnectionMessage(name, - clientId, - data) { + sendMobileConnectionMessage: function sendMobileConnectionMessage(name, clientId, data) { this._sendTargetMessage("mobileconnection", name, { clientId: clientId, data: data @@ -309,8 +273,7 @@ this.RilMessageManager = { }); }, - sendCellBroadcastMessage: function sendCellBroadcastMessage(name, clientId, - data) { + sendCellBroadcastMessage: function sendCellBroadcastMessage(name, clientId, data) { this._sendTargetMessage("cellbroadcast", name, { clientId: clientId, data: data From 3f9e9d1f0039d8453e38ee380e44eaa6b5f92e6e Mon Sep 17 00:00:00 2001 From: Ed Morley Date: Wed, 4 Sep 2013 11:50:52 +0100 Subject: [PATCH 021/171] Backed out changeset 0a1f354d13a0 (bug 907585) --- dom/system/gonk/RadioInterfaceLayer.js | 31 ++--- dom/system/gonk/RilMessageManager.jsm | 171 +++++++++++++------------ 2 files changed, 99 insertions(+), 103 deletions(-) diff --git a/dom/system/gonk/RadioInterfaceLayer.js b/dom/system/gonk/RadioInterfaceLayer.js index ee6547120ac..153e86db50f 100644 --- a/dom/system/gonk/RadioInterfaceLayer.js +++ b/dom/system/gonk/RadioInterfaceLayer.js @@ -79,6 +79,7 @@ const RIL_IPC_MOBILECONNECTION_MSG_NAMES = [ "RIL:SelectNetworkAuto", "RIL:SendMMI", "RIL:CancelMMI", + "RIL:RegisterMobileConnectionMsg", "RIL:SetCallForwardingOption", "RIL:GetCallForwardingOption", "RIL:SetCallBarringOption", @@ -108,13 +109,19 @@ const RIL_IPC_ICCMANAGER_MSG_NAMES = [ "RIL:IccExchangeAPDU", "RIL:IccCloseChannel", "RIL:ReadIccContacts", - "RIL:UpdateIccContact" + "RIL:UpdateIccContact", + "RIL:RegisterIccMsg" ]; const RIL_IPC_VOICEMAIL_MSG_NAMES = [ + "RIL:RegisterVoicemailMsg", "RIL:GetVoicemailInfo" ]; +const RIL_IPC_CELLBROADCAST_MSG_NAMES = [ + "RIL:RegisterCellBroadcastMsg" +]; + XPCOMUtils.defineLazyServiceGetter(this, "gPowerManagerService", "@mozilla.org/power/powermanagerservice;1", "nsIPowerManagerService"); @@ -174,16 +181,7 @@ XPCOMUtils.defineLazyGetter(this, "gMessageManager", function () { }); function RadioInterfaceLayer() { - let callback = this._receiveMessage.bind(this); - gMessageManager.registerMessageListeners("icc", - RIL_IPC_ICCMANAGER_MSG_NAMES, - callback); - gMessageManager.registerMessageListeners("mobileconnection", - RIL_IPC_MOBILECONNECTION_MSG_NAMES, - callback); - gMessageManager.registerMessageListeners("voicemail", - RIL_IPC_VOICEMAIL_MSG_NAMES, - callback); + gMessageManager.init(this); let options = { debug: debugPref, @@ -218,17 +216,6 @@ RadioInterfaceLayer.prototype = { QueryInterface: XPCOMUtils.generateQI([Ci.nsIRadioInterfaceLayer, Ci.nsIObserver]), - _receiveMessage: function _receiveMessage(topic, msg) { - let clientId = msg.json.clientId || 0; - let radioInterface = this.getRadioInterface(clientId); - if (!radioInterface) { - if (DEBUG) debug("No such radio interface: " + clientId); - return null; - } - - return radioInterface.receiveMessage(msg); - }, - /** * nsIObserver interface methods. */ diff --git a/dom/system/gonk/RilMessageManager.jsm b/dom/system/gonk/RilMessageManager.jsm index d0bb414d595..3f8c0f418bd 100644 --- a/dom/system/gonk/RilMessageManager.jsm +++ b/dom/system/gonk/RilMessageManager.jsm @@ -27,20 +27,7 @@ this.RilMessageManager = { QueryInterface: XPCOMUtils.generateQI([Ci.nsIMessageListener, Ci.nsIObserver]), - topicRegistrationNames: { - cellbroadcast: "RIL:RegisterCellBroadcastMsg", - icc: "RIL:RegisterIccMsg", - mobileconnection: "RIL:RegisterMobileConnectionMsg", - voicemail: "RIL:RegisterVoicemailMsg", - }, - - /** - * this.callbacksByName[< A string message name>] = { - * topic: , - * callback: , - * } - */ - callbacksByName: {}, + ril: null, // Manage message targets in terms of topic. Only the authorized and // registered contents can receive related messages. @@ -50,32 +37,55 @@ this.RilMessageManager = { targetMessageQueue: [], ready: false, - _init: function _init() { + init: function init(ril) { + this.ril = ril; + Services.obs.addObserver(this, "xpcom-shutdown", false); Services.obs.addObserver(this, kSysMsgListenerReadyObserverTopic, false); - - ppmm.addMessageListener("child-process-shutdown", this); - - let callback = this._registerMessageTarget.bind(this); - for (let topic in this.topicRegistrationNames) { - let name = this.topicRegistrationNames[topic]; - this.registerMessageListeners(topic, [name], callback); - } + this._registerMessageListeners(); }, _shutdown: function _shutdown() { + this.ril = null; + Services.obs.removeObserver(this, "xpcom-shutdown"); + this._unregisterMessageListeners(); + }, - for (let name in this.callbacksByName) { - ppmm.removeMessageListener(name, this); + _registerMessageListeners: function _registerMessageListeners() { + ppmm.addMessageListener("child-process-shutdown", this); + for (let msgname of RIL_IPC_MOBILECONNECTION_MSG_NAMES) { + ppmm.addMessageListener(msgname, this); } - this.callbacksByName = null; + for (let msgName of RIL_IPC_ICCMANAGER_MSG_NAMES) { + ppmm.addMessageListener(msgName, this); + } + for (let msgname of RIL_IPC_VOICEMAIL_MSG_NAMES) { + ppmm.addMessageListener(msgname, this); + } + for (let msgname of RIL_IPC_CELLBROADCAST_MSG_NAMES) { + ppmm.addMessageListener(msgname, this); + } + }, + _unregisterMessageListeners: function _unregisterMessageListeners() { ppmm.removeMessageListener("child-process-shutdown", this); + for (let msgname of RIL_IPC_MOBILECONNECTION_MSG_NAMES) { + ppmm.removeMessageListener(msgname, this); + } + for (let msgName of RIL_IPC_ICCMANAGER_MSG_NAMES) { + ppmm.removeMessageListener(msgName, this); + } + for (let msgname of RIL_IPC_VOICEMAIL_MSG_NAMES) { + ppmm.removeMessageListener(msgname, this); + } + for (let msgname of RIL_IPC_CELLBROADCAST_MSG_NAMES) { + ppmm.removeMessageListener(msgname, this); + } ppmm = null; }, - _registerMessageTarget: function _registerMessageTarget(topic, msg) { + _registerMessageTarget: function _registerMessageTarget(topic, target) { let targets = this.targetsByTopic[topic]; if (!targets) { targets = this.targetsByTopic[topic] = []; @@ -85,7 +95,6 @@ this.RilMessageManager = { } } - let target = msg.target; if (targets.indexOf(target) != -1) { if (DEBUG) debug("Already registered this target!"); return; @@ -179,21 +188,66 @@ this.RilMessageManager = { return; } - let entry = this.callbacksByName[msg.name]; - if (!entry) { + if (RIL_IPC_MOBILECONNECTION_MSG_NAMES.indexOf(msg.name) != -1) { + if (!msg.target.assertPermission("mobileconnection")) { + if (DEBUG) { + debug("MobileConnection message " + msg.name + + " from a content process with no 'mobileconnection' privileges."); + } + return null; + } + } else 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 (RIL_IPC_VOICEMAIL_MSG_NAMES.indexOf(msg.name) != -1) { + if (!msg.target.assertPermission("voicemail")) { + if (DEBUG) { + debug("Voicemail message " + msg.name + + " from a content process with no 'voicemail' privileges."); + } + return null; + } + } else if (RIL_IPC_CELLBROADCAST_MSG_NAMES.indexOf(msg.name) != -1) { + if (!msg.target.assertPermission("cellbroadcast")) { + if (DEBUG) { + debug("Cell Broadcast message " + msg.name + + " from a content process with no 'cellbroadcast' privileges."); + } + return null; + } + } else { if (DEBUG) debug("Ignoring unknown message type: " + msg.name); return null; } - if (entry.topic && !msg.target.assertPermission(entry.topic)) { - if (DEBUG) { - debug("Message " + msg.name + " from a content process with no '" + - entry.topic + "' privileges."); - } + switch (msg.name) { + case "RIL:RegisterMobileConnectionMsg": + this._registerMessageTarget("mobileconnection", msg.target); + return; + case "RIL:RegisterIccMsg": + this._registerMessageTarget("icc", msg.target); + return; + case "RIL:RegisterVoicemailMsg": + this._registerMessageTarget("voicemail", msg.target); + return; + case "RIL:RegisterCellBroadcastMsg": + this._registerMessageTarget("cellbroadcast", msg.target); + return; + } + + 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 entry.callback(entry.topic, msg); + return radioInterface.receiveMessage(msg); }, /** @@ -216,49 +270,6 @@ this.RilMessageManager = { * Public methods. */ - /** - * @param topic - * A string for the topic of the registrating names. Also the - * permission to listen messages of these names. - * @param names - * An array of string message names to listen. - * @param callback - * A callback that accepts two parameters -- topic and msg. - */ - registerMessageListeners: function registerMessageListeners(topic, names, - callback) { - for (let name of names) { - if (this.callbacksByName[name]) { - if (DEBUG) { - debug("Message name '" + name + "' was already registered. Ignored."); - } - continue; - } - - this.callbacksByName[name] = { topic: topic, callback: callback }; - ppmm.addMessageListener(name, this); - } - }, - - /** - * Remove all listening names with specified callback. - * - * @param callback - * The callback previously registered for messages. - */ - unregisterMessageListeners: function unregisterMessageListeners(callback) { - let remains = {}; - for (let name in this.callbacksByName) { - let entry = this.callbacksByName[name]; - if (entry.callback != callback) { - remains[name] = entry; - } else { - ppmm.removeMessageListener(name, this); - } - } - this.callbacksByName = remains; - }, - sendMobileConnectionMessage: function sendMobileConnectionMessage(name, clientId, data) { this._sendTargetMessage("mobileconnection", name, { clientId: clientId, @@ -288,6 +299,4 @@ this.RilMessageManager = { } }; -RilMessageManager._init(); - this.EXPORTED_SYMBOLS = ["RilMessageManager"]; From 4cc16102ced31736801c83d341e9172f5ba31f85 Mon Sep 17 00:00:00 2001 From: Ed Morley Date: Wed, 4 Sep 2013 11:50:55 +0100 Subject: [PATCH 022/171] Backed out changeset 0b45d07ccdee (bug 907585) --- dom/system/gonk/RadioInterfaceLayer.js | 278 ++++++++++++++++++++++- dom/system/gonk/RilMessageManager.jsm | 302 ------------------------- dom/system/gonk/moz.build | 1 - 3 files changed, 275 insertions(+), 306 deletions(-) delete mode 100644 dom/system/gonk/RilMessageManager.jsm diff --git a/dom/system/gonk/RadioInterfaceLayer.js b/dom/system/gonk/RadioInterfaceLayer.js index 153e86db50f..937a033c4b9 100644 --- a/dom/system/gonk/RadioInterfaceLayer.js +++ b/dom/system/gonk/RadioInterfaceLayer.js @@ -138,6 +138,10 @@ XPCOMUtils.defineLazyServiceGetter(this, "gMobileMessageDatabaseService", "@mozilla.org/mobilemessage/rilmobilemessagedatabaseservice;1", "nsIRilMobileMessageDatabaseService"); +XPCOMUtils.defineLazyServiceGetter(this, "ppmm", + "@mozilla.org/parentprocessmessagemanager;1", + "nsIMessageBroadcaster"); + XPCOMUtils.defineLazyServiceGetter(this, "gSettingsService", "@mozilla.org/settingsService;1", "nsISettingsService"); @@ -175,9 +179,277 @@ XPCOMUtils.defineLazyGetter(this, "PhoneNumberUtils", function () { }); XPCOMUtils.defineLazyGetter(this, "gMessageManager", function () { - let ns = {}; - Cu.import("resource://gre/modules/RilMessageManager.jsm", ns); - return ns.RilMessageManager; + 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 init(ril) { + this.ril = ril; + + Services.obs.addObserver(this, "xpcom-shutdown", false); + Services.obs.addObserver(this, kSysMsgListenerReadyObserverTopic, false); + this._registerMessageListeners(); + }, + + _shutdown: function _shutdown() { + this.ril = null; + + Services.obs.removeObserver(this, "xpcom-shutdown"); + this._unregisterMessageListeners(); + }, + + _registerMessageListeners: function _registerMessageListeners() { + ppmm.addMessageListener("child-process-shutdown", this); + for (let msgname of RIL_IPC_MOBILECONNECTION_MSG_NAMES) { + ppmm.addMessageListener(msgname, this); + } + for (let msgName of RIL_IPC_ICCMANAGER_MSG_NAMES) { + ppmm.addMessageListener(msgName, this); + } + for (let msgname of RIL_IPC_VOICEMAIL_MSG_NAMES) { + ppmm.addMessageListener(msgname, this); + } + for (let msgname of RIL_IPC_CELLBROADCAST_MSG_NAMES) { + ppmm.addMessageListener(msgname, this); + } + }, + + _unregisterMessageListeners: function _unregisterMessageListeners() { + ppmm.removeMessageListener("child-process-shutdown", this); + for (let msgname of RIL_IPC_MOBILECONNECTION_MSG_NAMES) { + ppmm.removeMessageListener(msgname, this); + } + for (let msgName of RIL_IPC_ICCMANAGER_MSG_NAMES) { + ppmm.removeMessageListener(msgName, this); + } + for (let msgname of RIL_IPC_VOICEMAIL_MSG_NAMES) { + ppmm.removeMessageListener(msgname, this); + } + for (let msgname of RIL_IPC_CELLBROADCAST_MSG_NAMES) { + ppmm.removeMessageListener(msgname, this); + } + ppmm = null; + }, + + _registerMessageTarget: function _registerMessageTarget(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 _unregisterMessageTarget(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 _enqueueTargetMessage(topic, message, options) { + let msg = { topic : topic, + message : message, + options : options }; + // Remove previous queued message of same message type, only one message + // per message type is allowed in queue. + let messageQueue = this.targetMessageQueue; + for(let i = 0; i < messageQueue.length; i++) { + if (messageQueue[i].message === message) { + messageQueue.splice(i, 1); + break; + } + } + + messageQueue.push(msg); + }, + + _sendTargetMessage: function _sendTargetMessage(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 _resendQueuedTargetMessage() { + 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 receiveMessage(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; + } + + if (RIL_IPC_MOBILECONNECTION_MSG_NAMES.indexOf(msg.name) != -1) { + if (!msg.target.assertPermission("mobileconnection")) { + if (DEBUG) { + debug("MobileConnection message " + msg.name + + " from a content process with no 'mobileconnection' privileges."); + } + return null; + } + } else 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 (RIL_IPC_VOICEMAIL_MSG_NAMES.indexOf(msg.name) != -1) { + if (!msg.target.assertPermission("voicemail")) { + if (DEBUG) { + debug("Voicemail message " + msg.name + + " from a content process with no 'voicemail' privileges."); + } + return null; + } + } else if (RIL_IPC_CELLBROADCAST_MSG_NAMES.indexOf(msg.name) != -1) { + if (!msg.target.assertPermission("cellbroadcast")) { + if (DEBUG) { + debug("Cell Broadcast message " + msg.name + + " from a content process with no 'cellbroadcast' privileges."); + } + return null; + } + } else { + if (DEBUG) debug("Ignoring unknown message type: " + msg.name); + return null; + } + + switch (msg.name) { + case "RIL:RegisterMobileConnectionMsg": + this._registerMessageTarget("mobileconnection", msg.target); + return; + case "RIL:RegisterIccMsg": + this._registerMessageTarget("icc", msg.target); + return; + case "RIL:RegisterVoicemailMsg": + this._registerMessageTarget("voicemail", msg.target); + return; + case "RIL:RegisterCellBroadcastMsg": + this._registerMessageTarget("cellbroadcast", msg.target); + return; + } + + 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 observe(subject, topic, data) { + switch (topic) { + case kSysMsgListenerReadyObserverTopic: + Services.obs.removeObserver(this, kSysMsgListenerReadyObserverTopic); + this._resendQueuedTargetMessage(); + break; + case "xpcom-shutdown": + this._shutdown(); + break; + } + }, + + sendMobileConnectionMessage: function sendMobileConnectionMessage(message, clientId, data) { + this._sendTargetMessage("mobileconnection", message, { + clientId: clientId, + data: data + }); + }, + + sendVoicemailMessage: function sendVoicemailMessage(message, clientId, data) { + this._sendTargetMessage("voicemail", message, { + clientId: clientId, + data: data + }); + }, + + sendCellBroadcastMessage: function sendCellBroadcastMessage(message, clientId, data) { + this._sendTargetMessage("cellbroadcast", message, { + clientId: clientId, + data: data + }); + }, + + sendIccMessage: function sendIccMessage(message, clientId, data) { + this._sendTargetMessage("icc", message, { + clientId: clientId, + data: data + }); + } + }; }); function RadioInterfaceLayer() { diff --git a/dom/system/gonk/RilMessageManager.jsm b/dom/system/gonk/RilMessageManager.jsm deleted file mode 100644 index 3f8c0f418bd..00000000000 --- a/dom/system/gonk/RilMessageManager.jsm +++ /dev/null @@ -1,302 +0,0 @@ -/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ -/* 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/. */ - -"use strict"; - -const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); - -XPCOMUtils.defineLazyServiceGetter(this, "ppmm", - "@mozilla.org/parentprocessmessagemanager;1", - "nsIMessageBroadcaster"); - -// Observer topics. -const kSysMsgListenerReadyObserverTopic = "system-message-listener-ready"; - -let DEBUG; -function debug(s) { - dump("RilMessageManager: " + s + "\n"); -} - -this.RilMessageManager = { - 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 init(ril) { - this.ril = ril; - - Services.obs.addObserver(this, "xpcom-shutdown", false); - Services.obs.addObserver(this, kSysMsgListenerReadyObserverTopic, false); - this._registerMessageListeners(); - }, - - _shutdown: function _shutdown() { - this.ril = null; - - Services.obs.removeObserver(this, "xpcom-shutdown"); - this._unregisterMessageListeners(); - }, - - _registerMessageListeners: function _registerMessageListeners() { - ppmm.addMessageListener("child-process-shutdown", this); - for (let msgname of RIL_IPC_MOBILECONNECTION_MSG_NAMES) { - ppmm.addMessageListener(msgname, this); - } - for (let msgName of RIL_IPC_ICCMANAGER_MSG_NAMES) { - ppmm.addMessageListener(msgName, this); - } - for (let msgname of RIL_IPC_VOICEMAIL_MSG_NAMES) { - ppmm.addMessageListener(msgname, this); - } - for (let msgname of RIL_IPC_CELLBROADCAST_MSG_NAMES) { - ppmm.addMessageListener(msgname, this); - } - }, - - _unregisterMessageListeners: function _unregisterMessageListeners() { - ppmm.removeMessageListener("child-process-shutdown", this); - for (let msgname of RIL_IPC_MOBILECONNECTION_MSG_NAMES) { - ppmm.removeMessageListener(msgname, this); - } - for (let msgName of RIL_IPC_ICCMANAGER_MSG_NAMES) { - ppmm.removeMessageListener(msgName, this); - } - for (let msgname of RIL_IPC_VOICEMAIL_MSG_NAMES) { - ppmm.removeMessageListener(msgname, this); - } - for (let msgname of RIL_IPC_CELLBROADCAST_MSG_NAMES) { - ppmm.removeMessageListener(msgname, this); - } - ppmm = null; - }, - - _registerMessageTarget: function _registerMessageTarget(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 _unregisterMessageTarget(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 _enqueueTargetMessage(topic, name, options) { - let msg = { topic : topic, - name : name, - options : options }; - // Remove previous queued message of same message name, only one message - // per message name is allowed in queue. - let messageQueue = this.targetMessageQueue; - for (let i = 0; i < messageQueue.length; i++) { - if (messageQueue[i].name === name) { - messageQueue.splice(i, 1); - break; - } - } - - messageQueue.push(msg); - }, - - _sendTargetMessage: function _sendTargetMessage(topic, name, options) { - if (!this.ready) { - this._enqueueTargetMessage(topic, name, options); - return; - } - - let targets = this.targetsByTopic[topic]; - if (!targets) { - return; - } - - for (let target of targets) { - target.sendAsyncMessage(name, options); - } - }, - - _resendQueuedTargetMessage: function _resendQueuedTargetMessage() { - 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 (let msg of this.targetMessageQueue) { - this._sendTargetMessage(msg.topic, msg.name, msg.options); - } - this.targetMessageQueue = null; - }, - - /** - * nsIMessageListener interface methods. - */ - - receiveMessage: function receiveMessage(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; - } - - if (RIL_IPC_MOBILECONNECTION_MSG_NAMES.indexOf(msg.name) != -1) { - if (!msg.target.assertPermission("mobileconnection")) { - if (DEBUG) { - debug("MobileConnection message " + msg.name + - " from a content process with no 'mobileconnection' privileges."); - } - return null; - } - } else 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 (RIL_IPC_VOICEMAIL_MSG_NAMES.indexOf(msg.name) != -1) { - if (!msg.target.assertPermission("voicemail")) { - if (DEBUG) { - debug("Voicemail message " + msg.name + - " from a content process with no 'voicemail' privileges."); - } - return null; - } - } else if (RIL_IPC_CELLBROADCAST_MSG_NAMES.indexOf(msg.name) != -1) { - if (!msg.target.assertPermission("cellbroadcast")) { - if (DEBUG) { - debug("Cell Broadcast message " + msg.name + - " from a content process with no 'cellbroadcast' privileges."); - } - return null; - } - } else { - if (DEBUG) debug("Ignoring unknown message type: " + msg.name); - return null; - } - - switch (msg.name) { - case "RIL:RegisterMobileConnectionMsg": - this._registerMessageTarget("mobileconnection", msg.target); - return; - case "RIL:RegisterIccMsg": - this._registerMessageTarget("icc", msg.target); - return; - case "RIL:RegisterVoicemailMsg": - this._registerMessageTarget("voicemail", msg.target); - return; - case "RIL:RegisterCellBroadcastMsg": - this._registerMessageTarget("cellbroadcast", msg.target); - return; - } - - 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 observe(subject, topic, data) { - switch (topic) { - case kSysMsgListenerReadyObserverTopic: - Services.obs.removeObserver(this, kSysMsgListenerReadyObserverTopic); - this._resendQueuedTargetMessage(); - break; - case "xpcom-shutdown": - this._shutdown(); - break; - } - }, - - /** - * Public methods. - */ - - sendMobileConnectionMessage: function sendMobileConnectionMessage(name, clientId, data) { - this._sendTargetMessage("mobileconnection", name, { - clientId: clientId, - data: data - }); - }, - - sendVoicemailMessage: function sendVoicemailMessage(name, clientId, data) { - this._sendTargetMessage("voicemail", name, { - clientId: clientId, - data: data - }); - }, - - sendCellBroadcastMessage: function sendCellBroadcastMessage(name, clientId, data) { - this._sendTargetMessage("cellbroadcast", name, { - clientId: clientId, - data: data - }); - }, - - sendIccMessage: function sendIccMessage(name, clientId, data) { - this._sendTargetMessage("icc", name, { - clientId: clientId, - data: data - }); - } -}; - -this.EXPORTED_SYMBOLS = ["RilMessageManager"]; diff --git a/dom/system/gonk/moz.build b/dom/system/gonk/moz.build index e4d53da7f57..694b01a0217 100644 --- a/dom/system/gonk/moz.build +++ b/dom/system/gonk/moz.build @@ -74,7 +74,6 @@ EXTRA_COMPONENTS += [ ] EXTRA_JS_MODULES += [ - 'RilMessageManager.jsm', 'net_worker.js', 'ril_consts.js', 'ril_worker.js', From 7182289847c8611fc33e01b6a045c4ce5819c6c5 Mon Sep 17 00:00:00 2001 From: Ed Morley Date: Wed, 4 Sep 2013 11:50:59 +0100 Subject: [PATCH 023/171] Backed out changeset 89113a5b091e (bug 864485) --- b2g/installer/package-manifest.in | 2 - dom/system/gonk/RILContentHelper.js | 231 ++++++++ dom/system/gonk/RadioInterfaceLayer.js | 455 ++++++++++++++- dom/system/gonk/nsIRadioInterfaceLayer.idl | 12 +- dom/telephony/TelephonyFactory.cpp | 7 - dom/telephony/gonk/TelephonyProvider.js | 525 ------------------ dom/telephony/gonk/TelephonyProvider.manifest | 2 - dom/telephony/moz.build | 9 - dom/telephony/nsIGonkTelephonyProvider.idl | 31 -- 9 files changed, 666 insertions(+), 608 deletions(-) delete mode 100644 dom/telephony/gonk/TelephonyProvider.js delete mode 100644 dom/telephony/gonk/TelephonyProvider.manifest delete mode 100644 dom/telephony/nsIGonkTelephonyProvider.idl diff --git a/b2g/installer/package-manifest.in b/b2g/installer/package-manifest.in index f358d9f1007..adf1200a495 100644 --- a/b2g/installer/package-manifest.in +++ b/b2g/installer/package-manifest.in @@ -471,8 +471,6 @@ @BINPATH@/components/NetworkStatsManager.manifest @BINPATH@/components/NetworkInterfaceListService.manifest @BINPATH@/components/NetworkInterfaceListService.js -@BINPATH@/components/TelephonyProvider.manifest -@BINPATH@/components/TelephonyProvider.js #endif #ifdef MOZ_ENABLE_DBUS @BINPATH@/components/@DLL_PREFIX@dbusservice@DLL_SUFFIX@ diff --git a/dom/system/gonk/RILContentHelper.js b/dom/system/gonk/RILContentHelper.js index 9edac38f150..c0c8356895e 100644 --- a/dom/system/gonk/RILContentHelper.js +++ b/dom/system/gonk/RILContentHelper.js @@ -69,13 +69,17 @@ const RIL_IPC_MSG_NAMES = [ "RIL:IccInfoChanged", "RIL:VoiceInfoChanged", "RIL:DataInfoChanged", + "RIL:EnumerateCalls", "RIL:GetAvailableNetworks", "RIL:NetworkSelectionModeChanged", "RIL:SelectNetwork", "RIL:SelectNetworkAuto", + "RIL:CallStateChanged", "RIL:EmergencyCbModeChanged", "RIL:VoicemailNotification", "RIL:VoicemailInfoChanged", + "RIL:CallError", + "RIL:SuppSvcNotification", "RIL:CardLockResult", "RIL:CardLockRetryCount", "RIL:USSDReceived", @@ -102,9 +106,11 @@ const RIL_IPC_MSG_NAMES = [ "RIL:UpdateIccContact", "RIL:SetRoamingPreference", "RIL:GetRoamingPreference", + "RIL:CdmaCallWaiting", "RIL:ExitEmergencyCbMode", "RIL:SetVoicePrivacyMode", "RIL:GetVoicePrivacyMode", + "RIL:ConferenceCallStateChanged", "RIL:OtaStatusChanged" ]; @@ -112,6 +118,10 @@ XPCOMUtils.defineLazyServiceGetter(this, "cpmm", "@mozilla.org/childprocessmessagemanager;1", "nsISyncMessageSender"); +XPCOMUtils.defineLazyServiceGetter(this, "gUUIDGenerator", + "@mozilla.org/uuid-generator;1", + "nsIUUIDGenerator"); + function MobileIccCardLockResult(options) { this.lockType = options.lockType; this.enabled = options.enabled; @@ -411,6 +421,7 @@ RILContentHelper.prototype = { QueryInterface: XPCOMUtils.generateQI([Ci.nsIMobileConnectionProvider, Ci.nsICellBroadcastProvider, Ci.nsIVoicemailProvider, + Ci.nsITelephonyProvider, Ci.nsIIccProvider, Ci.nsIObserver, Ci.nsISupportsWeakReference]), @@ -420,6 +431,7 @@ RILContentHelper.prototype = { interfaces: [Ci.nsIMobileConnectionProvider, Ci.nsICellBroadcastProvider, Ci.nsIVoicemailProvider, + Ci.nsITelephonyProvider, Ci.nsIIccProvider]}), // An utility function to copy objects. @@ -1212,9 +1224,11 @@ RILContentHelper.prototype = { }, _mobileConnectionListeners: null, + _telephonyListeners: null, _cellBroadcastListeners: null, _voicemailListeners: null, _iccListeners: null, + _enumerateTelephonyCallbacks: null, voicemailStatus: null, @@ -1276,6 +1290,24 @@ RILContentHelper.prototype = { this.unregisterListener("_mobileConnectionListeners", listener); }, + registerTelephonyMsg: function registerTelephonyMsg(listener) { + debug("Registering for telephony-related messages"); + this.registerListener("_telephonyListeners", listener); + cpmm.sendAsyncMessage("RIL:RegisterTelephonyMsg"); + }, + + unregisterTelephonyMsg: function unregisteTelephonyMsg(listener) { + this.unregisterListener("_telephonyListeners", listener); + + // We also need to make sure the listener is removed from + // _enumerateTelephonyCallbacks. + let index = this._enumerateTelephonyCallbacks.indexOf(listener); + if (index != -1) { + this._enumerateTelephonyCallbacks.splice(index, 1); + if (DEBUG) debug("Unregistered enumerateTelephony callback: " + listener); + } + }, + registerVoicemailMsg: function registerVoicemailMsg(listener) { debug("Registering for voicemail-related messages"); this.registerListener("_voicemailListeners", listener); @@ -1306,6 +1338,135 @@ RILContentHelper.prototype = { this.unregisterListener("_iccListeners", listener); }, + enumerateCalls: function enumerateCalls(callback) { + debug("Requesting enumeration of calls for callback: " + callback); + // We need 'requestId' to meet the 'RILContentHelper <--> RadioInterfaceLayer' + // protocol. + let requestId = this._getRandomId(); + cpmm.sendAsyncMessage("RIL:EnumerateCalls", { + clientId: 0, + data: { + requestId: requestId + } + }); + if (!this._enumerateTelephonyCallbacks) { + this._enumerateTelephonyCallbacks = []; + } + this._enumerateTelephonyCallbacks.push(callback); + }, + + startTone: function startTone(dtmfChar) { + debug("Sending Tone for " + dtmfChar); + cpmm.sendAsyncMessage("RIL:StartTone", { + clientId: 0, + data: dtmfChar + }); + }, + + stopTone: function stopTone() { + debug("Stopping Tone"); + cpmm.sendAsyncMessage("RIL:StopTone", {clientId: 0}); + }, + + dial: function dial(number) { + debug("Dialing " + number); + cpmm.sendAsyncMessage("RIL:Dial", { + clientId: 0, + data: number + }); + }, + + dialEmergency: function dialEmergency(number) { + debug("Dialing emergency " + number); + cpmm.sendAsyncMessage("RIL:DialEmergency", { + clientId: 0, + data: number + }); + }, + + hangUp: function hangUp(callIndex) { + debug("Hanging up call no. " + callIndex); + cpmm.sendAsyncMessage("RIL:HangUp", { + clientId: 0, + data: callIndex + }); + }, + + answerCall: function answerCall(callIndex) { + cpmm.sendAsyncMessage("RIL:AnswerCall", { + clientId: 0, + data: callIndex + }); + }, + + rejectCall: function rejectCall(callIndex) { + cpmm.sendAsyncMessage("RIL:RejectCall", { + clientId: 0, + data: callIndex + }); + }, + + holdCall: function holdCall(callIndex) { + cpmm.sendAsyncMessage("RIL:HoldCall", { + clientId: 0, + data: callIndex + }); + }, + + resumeCall: function resumeCall(callIndex) { + cpmm.sendAsyncMessage("RIL:ResumeCall", { + clientId: 0, + data: callIndex + }); + }, + + conferenceCall: function conferenceCall() { + cpmm.sendAsyncMessage("RIL:ConferenceCall", { + clientId: 0 + }); + }, + + separateCall: function separateCall(callIndex) { + cpmm.sendAsyncMessage("RIL:SeparateCall", { + clientId: 0, + data: callIndex + }); + }, + + holdConference: function holdConference() { + cpmm.sendAsyncMessage("RIL:HoldConference", { + clientId: 0 + }); + }, + + resumeConference: function resumeConference() { + cpmm.sendAsyncMessage("RIL:ResumeConference", { + clientId: 0 + }); + }, + + get microphoneMuted() { + return cpmm.sendSyncMessage("RIL:GetMicrophoneMuted", {clientId: 0})[0]; + }, + + set microphoneMuted(value) { + cpmm.sendAsyncMessage("RIL:SetMicrophoneMuted", { + clientId: 0, + data: value + }); + }, + + get speakerEnabled() { + return cpmm.sendSyncMessage("RIL:GetSpeakerEnabled", {clientId: 0})[0]; + }, + + set speakerEnabled(value) { + cpmm.sendAsyncMessage("RIL:SetSpeakerEnabled", { + clientId: 0, + data: value + }); + }, + // nsIObserver observe: function observe(subject, topic, data) { @@ -1402,6 +1563,9 @@ RILContentHelper.prototype = { "notifyOtaStatusChanged", [msg.json.data]); break; + case "RIL:EnumerateCalls": + this.handleEnumerateCalls(msg.json.calls); + break; case "RIL:GetAvailableNetworks": this.handleGetAvailableNetworks(msg.json); break; @@ -1416,6 +1580,35 @@ RILContentHelper.prototype = { this.handleSelectNetwork(msg.json, RIL.GECKO_NETWORK_SELECTION_AUTOMATIC); break; + case "RIL:CallStateChanged": { + let data = msg.json.data; + this._deliverEvent("_telephonyListeners", + "callStateChanged", + [data.callIndex, data.state, + data.number, data.isActive, + data.isOutgoing, data.isEmergency, + data.isConference]); + break; + } + case "RIL:ConferenceCallStateChanged": { + let data = msg.json.data; + this._deliverEvent("_telephonyListeners", + "conferenceCallStateChanged", + [data]); + break; + } + case "RIL:CallError": { + let data = msg.json.data; + this._deliverEvent("_telephonyListeners", + "notifyError", + [data.callIndex, data.errorMsg]); + break; + } + case "RIL:SuppSvcNotification": + this._deliverEvent("_telephonyListeners", + "supplementaryServiceNotification", + [msg.json.callIndex, msg.json.notification]); + break; case "RIL:VoicemailNotification": this.handleVoicemailNotification(msg.json.data); break; @@ -1536,6 +1729,11 @@ RILContentHelper.prototype = { this.handleSimpleRequest(msg.json.requestId, msg.json.errorMsg, msg.json.mode); break; + case "RIL:CdmaCallWaiting": + this._deliverEvent("_telephonyListeners", + "notifyCdmaCallWaiting", + [msg.json.data]); + break; case "RIL:ExitEmergencyCbMode": this.handleExitEmergencyCbMode(msg.json); break; @@ -1555,6 +1753,35 @@ RILContentHelper.prototype = { } }, + handleEnumerateCalls: function handleEnumerateCalls(calls) { + debug("handleEnumerateCalls: " + JSON.stringify(calls)); + let callback = this._enumerateTelephonyCallbacks.shift(); + if (!calls.length) { + callback.enumerateCallStateComplete(); + return; + } + + for (let i in calls) { + let call = calls[i]; + let keepGoing; + try { + keepGoing = + callback.enumerateCallState(call.callIndex, call.state, call.number, + call.isActive, call.isOutgoing, + call.isEmergency, call.isConference); + } catch (e) { + debug("callback handler for 'enumerateCallState' threw an " + + " exception: " + e); + keepGoing = true; + } + if (!keepGoing) { + break; + } + } + + callback.enumerateCallStateComplete(); + }, + handleSimpleRequest: function handleSimpleRequest(requestId, errorMsg, result) { if (errorMsg) { this.fireRequestError(requestId, errorMsg); @@ -1767,6 +1994,10 @@ RILContentHelper.prototype = { } }, + _getRandomId: function _getRandomId() { + return gUUIDGenerator.generateUUID().toString(); + }, + _deliverEvent: function _deliverEvent(listenerType, name, args) { let thisListeners = this[listenerType]; if (!thisListeners) { diff --git a/dom/system/gonk/RadioInterfaceLayer.js b/dom/system/gonk/RadioInterfaceLayer.js index 937a033c4b9..fb5c06529fc 100644 --- a/dom/system/gonk/RadioInterfaceLayer.js +++ b/dom/system/gonk/RadioInterfaceLayer.js @@ -46,6 +46,9 @@ const RADIOINTERFACE_CID = const RILNETWORKINTERFACE_CID = Components.ID("{3bdd52a9-3965-4130-b569-0ac5afed045e}"); +const nsIAudioManager = Ci.nsIAudioManager; +const nsITelephonyProvider = Ci.nsITelephonyProvider; + const kNetworkInterfaceStateChangedTopic = "network-interface-state-changed"; const kSmsReceivedObserverTopic = "sms-received"; const kSilentSmsReceivedObserverTopic = "silent-sms-received"; @@ -70,7 +73,30 @@ const DOM_MOBILE_MESSAGE_DELIVERY_SENDING = "sending"; const DOM_MOBILE_MESSAGE_DELIVERY_SENT = "sent"; const DOM_MOBILE_MESSAGE_DELIVERY_ERROR = "error"; -const RADIO_POWER_OFF_TIMEOUT = 30000; +const CALL_WAKELOCK_TIMEOUT = 5000; +const RADIO_POWER_OFF_TIMEOUT = 30000; + +const RIL_IPC_TELEPHONY_MSG_NAMES = [ + "RIL:EnumerateCalls", + "RIL:GetMicrophoneMuted", + "RIL:SetMicrophoneMuted", + "RIL:GetSpeakerEnabled", + "RIL:SetSpeakerEnabled", + "RIL:StartTone", + "RIL:StopTone", + "RIL:Dial", + "RIL:DialEmergency", + "RIL:HangUp", + "RIL:AnswerCall", + "RIL:RejectCall", + "RIL:HoldCall", + "RIL:ResumeCall", + "RIL:RegisterTelephonyMsg", + "RIL:ConferenceCall", + "RIL:SeparateCall", + "RIL:HoldConference", + "RIL:ResumeConference" +]; const RIL_IPC_MOBILECONNECTION_MSG_NAMES = [ "RIL:GetRilContext", @@ -162,10 +188,6 @@ XPCOMUtils.defineLazyServiceGetter(this, "gSystemWorkerManager", "@mozilla.org/telephony/system-worker-manager;1", "nsISystemWorkerManager"); -XPCOMUtils.defineLazyServiceGetter(this, "gTelephonyProvider", - "@mozilla.org/telephony/telephonyprovider;1", - "nsIGonkTelephonyProvider"); - XPCOMUtils.defineLazyGetter(this, "WAP", function () { let wap = {}; Cu.import("resource://gre/modules/WapPushManager.js", wap); @@ -178,6 +200,64 @@ XPCOMUtils.defineLazyGetter(this, "PhoneNumberUtils", function () { return ns.PhoneNumberUtils; }); +function convertRILCallState(state) { + switch (state) { + case RIL.CALL_STATE_ACTIVE: + return nsITelephonyProvider.CALL_STATE_CONNECTED; + case RIL.CALL_STATE_HOLDING: + return nsITelephonyProvider.CALL_STATE_HELD; + case RIL.CALL_STATE_DIALING: + return nsITelephonyProvider.CALL_STATE_DIALING; + case RIL.CALL_STATE_ALERTING: + return nsITelephonyProvider.CALL_STATE_ALERTING; + case RIL.CALL_STATE_INCOMING: + case RIL.CALL_STATE_WAITING: + return nsITelephonyProvider.CALL_STATE_INCOMING; + default: + throw new Error("Unknown rilCallState: " + state); + } +} + +function convertRILSuppSvcNotification(notification) { + switch (notification) { + case RIL.GECKO_SUPP_SVC_NOTIFICATION_REMOTE_HELD: + return nsITelephonyProvider.NOTIFICATION_REMOTE_HELD; + case RIL.GECKO_SUPP_SVC_NOTIFICATION_REMOTE_RESUMED: + return nsITelephonyProvider.NOTIFICATION_REMOTE_RESUMED; + default: + throw new Error("Unknown rilSuppSvcNotification: " + notification); + } +} + +/** + * Fake nsIAudioManager implementation so that we can run the telephony + * code in a non-Gonk build. + */ +let FakeAudioManager = { + microphoneMuted: false, + masterVolume: 1.0, + masterMuted: false, + phoneState: nsIAudioManager.PHONE_STATE_CURRENT, + _forceForUse: {}, + setForceForUse: function setForceForUse(usage, force) { + this._forceForUse[usage] = force; + }, + getForceForUse: function setForceForUse(usage) { + return this._forceForUse[usage] || nsIAudioManager.FORCE_NONE; + } +}; + +XPCOMUtils.defineLazyGetter(this, "gAudioManager", function getAudioManager() { + try { + return Cc["@mozilla.org/telephony/audiomanager;1"] + .getService(nsIAudioManager); + } catch (ex) { + //TODO on the phone this should not fall back as silently. + if (DEBUG) debug("Using fake audio manager."); + return FakeAudioManager; + } +}); + XPCOMUtils.defineLazyGetter(this, "gMessageManager", function () { return { QueryInterface: XPCOMUtils.generateQI([Ci.nsIMessageListener, @@ -210,6 +290,9 @@ XPCOMUtils.defineLazyGetter(this, "gMessageManager", function () { _registerMessageListeners: function _registerMessageListeners() { ppmm.addMessageListener("child-process-shutdown", this); + for (let msgname of RIL_IPC_TELEPHONY_MSG_NAMES) { + ppmm.addMessageListener(msgname, this); + } for (let msgname of RIL_IPC_MOBILECONNECTION_MSG_NAMES) { ppmm.addMessageListener(msgname, this); } @@ -226,6 +309,9 @@ XPCOMUtils.defineLazyGetter(this, "gMessageManager", function () { _unregisterMessageListeners: function _unregisterMessageListeners() { ppmm.removeMessageListener("child-process-shutdown", this); + for (let msgname of RIL_IPC_TELEPHONY_MSG_NAMES) { + ppmm.removeMessageListener(msgname, this); + } for (let msgname of RIL_IPC_MOBILECONNECTION_MSG_NAMES) { ppmm.removeMessageListener(msgname, this); } @@ -344,7 +430,15 @@ XPCOMUtils.defineLazyGetter(this, "gMessageManager", function () { return; } - if (RIL_IPC_MOBILECONNECTION_MSG_NAMES.indexOf(msg.name) != -1) { + if (RIL_IPC_TELEPHONY_MSG_NAMES.indexOf(msg.name) != -1) { + if (!msg.target.assertPermission("telephony")) { + if (DEBUG) { + debug("Telephony message " + msg.name + + " from a content process with no 'telephony' privileges."); + } + return null; + } + } else if (RIL_IPC_MOBILECONNECTION_MSG_NAMES.indexOf(msg.name) != -1) { if (!msg.target.assertPermission("mobileconnection")) { if (DEBUG) { debug("MobileConnection message " + msg.name + @@ -382,6 +476,9 @@ XPCOMUtils.defineLazyGetter(this, "gMessageManager", function () { } switch (msg.name) { + case "RIL:RegisterTelephonyMsg": + this._registerMessageTarget("telephony", msg.target); + return; case "RIL:RegisterMobileConnectionMsg": this._registerMessageTarget("mobileconnection", msg.target); return; @@ -422,6 +519,13 @@ XPCOMUtils.defineLazyGetter(this, "gMessageManager", function () { } }, + sendTelephonyMessage: function sendTelephonyMessage(message, clientId, data) { + this._sendTargetMessage("telephony", message, { + clientId: clientId, + data: data + }); + }, + sendMobileConnectionMessage: function sendMobileConnectionMessage(message, clientId, data) { this._sendTargetMessage("mobileconnection", message, { clientId: clientId, @@ -790,6 +894,61 @@ RadioInterface.prototype = { case "RIL:GetRilContext": // This message is sync. return this.rilContext; + case "RIL:EnumerateCalls": + this.enumerateCalls(msg.target, msg.json.data); + break; + case "RIL:GetMicrophoneMuted": + // This message is sync. + return this.microphoneMuted; + case "RIL:SetMicrophoneMuted": + this.microphoneMuted = msg.json.data; + break; + case "RIL:GetSpeakerEnabled": + // This message is sync. + return this.speakerEnabled; + case "RIL:SetSpeakerEnabled": + this.speakerEnabled = msg.json.data; + break; + case "RIL:StartTone": + this.workerMessenger.send("startTone", { dtmfChar: msg.json.data }); + break; + case "RIL:StopTone": + this.workerMessenger.send("stopTone"); + break; + case "RIL:Dial": + this.dial(msg.json.data); + break; + case "RIL:DialEmergency": + this.dialEmergency(msg.json.data); + break; + case "RIL:HangUp": + this.workerMessenger.send("hangUp", { callIndex: msg.json.data }); + break; + case "RIL:AnswerCall": + this.workerMessenger.send("answerCall", { callIndex: msg.json.data }); + break; + case "RIL:RejectCall": + this.workerMessenger.send("rejectCall", { callIndex: msg.json.data }); + break; + case "RIL:HoldCall": + this.workerMessenger.send("holdCall", { callIndex: msg.json.data }); + break; + case "RIL:ResumeCall": + this.workerMessenger.send("resumeCall", { callIndex: msg.json.data }); + break; + case "RIL:ConferenceCall": + this.workerMessenger.send("conferenceCall"); + break; + case "RIL:SeparateCall": + this.workerMessenger.send("separateCall", + { callIndex: msg.json.data }); + break; + case "RIL:HoldConference": + this.workerMessenger.send("holdConference"); + break; + case "RIL:ResumeConference": + this.workerMessenger.send("resumeConference"); + break; case "RIL:GetAvailableNetworks": this.workerMessenger.sendWithIPCMessage(msg, "getAvailableNetworks"); break; @@ -899,26 +1058,28 @@ RadioInterface.prototype = { handleUnsolicitedWorkerMessage: function handleUnsolicitedWorkerMessage(message) { switch (message.rilMessageType) { case "callRing": - gTelephonyProvider.notifyCallRing(); + this.handleCallRing(); break; case "callStateChange": - gTelephonyProvider.notifyCallStateChanged(message.call); + // This one will handle its own notifications. + this.handleCallStateChange(message.call); break; case "callDisconnected": - gTelephonyProvider.notifyCallDisconnected(message.call); + // This one will handle its own notifications. + this.handleCallDisconnected(message.call); break; case "conferenceCallStateChanged": - gTelephonyProvider.notifyConferenceCallStateChanged(message.state); + this.handleConferenceCallStateChanged(message.state); break; case "cdmaCallWaiting": - gTelephonyProvider.notifyCdmaCallWaiting(message.number); + gMessageManager.sendTelephonyMessage("RIL:CdmaCallWaiting", + this.clientId, message.number); break; case "callError": - gTelephonyProvider.notifyCallError(message.callIndex, message.errorMsg); + this.handleCallError(message); break; case "suppSvcNotification": - gTelephonyProvider.notifySupplementaryService(message.callIndex, - message.notification); + this.handleSuppSvcNotification(message); break; case "emergencyCbModeChange": this.handleEmergencyCbModeChange(message); @@ -1566,6 +1727,165 @@ RadioInterface.prototype = { this.setupDataCallByType("default"); }, + /** + * Track the active call and update the audio system as its state changes. + */ + _activeCall: null, + updateCallAudioState: function updateCallAudioState(options) { + if (options.conferenceState === nsITelephonyProvider.CALL_STATE_CONNECTED) { + gAudioManager.phoneState = nsIAudioManager.PHONE_STATE_IN_CALL; + if (this.speakerEnabled) { + gAudioManager.setForceForUse(nsIAudioManager.USE_COMMUNICATION, + nsIAudioManager.FORCE_SPEAKER); + } + return; + } + if (options.conferenceState === nsITelephonyProvider.CALL_STATE_UNKNOWN || + options.conferenceState === nsITelephonyProvider.CALL_STATE_HELD) { + if (!this._activeCall) { + gAudioManager.phoneState = nsIAudioManager.PHONE_STATE_NORMAL; + } + return; + } + + if (!options.call) { + return; + } + + if (options.call.isConference) { + if (this._activeCall && this._activeCall.callIndex == options.call.callIndex) { + this._activeCall = null; + } + return; + } + + let call = options.call; + switch (call.state) { + case nsITelephonyProvider.CALL_STATE_DIALING: // Fall through... + case nsITelephonyProvider.CALL_STATE_ALERTING: + case nsITelephonyProvider.CALL_STATE_CONNECTED: + call.isActive = true; + this._activeCall = call; + gAudioManager.phoneState = nsIAudioManager.PHONE_STATE_IN_CALL; + if (this.speakerEnabled) { + gAudioManager.setForceForUse(nsIAudioManager.USE_COMMUNICATION, + nsIAudioManager.FORCE_SPEAKER); + } + if (DEBUG) { + this.debug("Active call, put audio system into PHONE_STATE_IN_CALL: " + + gAudioManager.phoneState); + } + break; + case nsITelephonyProvider.CALL_STATE_INCOMING: + call.isActive = false; + if (!this._activeCall) { + // We can change the phone state into RINGTONE only when there's + // no active call. + gAudioManager.phoneState = nsIAudioManager.PHONE_STATE_RINGTONE; + if (DEBUG) { + this.debug("Incoming call, put audio system into " + + "PHONE_STATE_RINGTONE: " + gAudioManager.phoneState); + } + } + break; + case nsITelephonyProvider.CALL_STATE_HELD: // Fall through... + case nsITelephonyProvider.CALL_STATE_DISCONNECTED: + call.isActive = false; + if (this._activeCall && + this._activeCall.callIndex == call.callIndex) { + // Previously active call is not active now. + this._activeCall = null; + } + + if (!this._activeCall) { + // No active call. Disable the audio. + gAudioManager.phoneState = nsIAudioManager.PHONE_STATE_NORMAL; + if (DEBUG) { + this.debug("No active call, put audio system into " + + "PHONE_STATE_NORMAL: " + gAudioManager.phoneState); + } + } + break; + } + }, + + _callRingWakeLock: null, + _callRingWakeLockTimer: null, + _cancelCallRingWakeLockTimer: function _cancelCallRingWakeLockTimer() { + if (this._callRingWakeLockTimer) { + this._callRingWakeLockTimer.cancel(); + } + if (this._callRingWakeLock) { + this._callRingWakeLock.unlock(); + this._callRingWakeLock = null; + } + }, + + /** + * Handle an incoming call. + * + * Not much is known about this call at this point, but it's enough + * to start bringing up the Phone app already. + */ + handleCallRing: function handleCallRing() { + if (!this._callRingWakeLock) { + this._callRingWakeLock = gPowerManagerService.newWakeLock("cpu"); + } + if (!this._callRingWakeLockTimer) { + this._callRingWakeLockTimer = + Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); + } + this._callRingWakeLockTimer + .initWithCallback(this._cancelCallRingWakeLockTimer.bind(this), + CALL_WAKELOCK_TIMEOUT, Ci.nsITimer.TYPE_ONE_SHOT); + + gSystemMessenger.broadcastMessage("telephony-new-call", {}); + }, + + /** + * Handle call state changes by updating our current state and the audio + * system. + */ + handleCallStateChange: function handleCallStateChange(call) { + if (DEBUG) this.debug("handleCallStateChange: " + JSON.stringify(call)); + call.state = convertRILCallState(call.state); + + if (call.state == nsITelephonyProvider.CALL_STATE_DIALING) { + gSystemMessenger.broadcastMessage("telephony-new-call", {}); + } + this.updateCallAudioState({call: call}); + gMessageManager.sendTelephonyMessage("RIL:CallStateChanged", + this.clientId, call); + }, + + /** + * Handle call disconnects by updating our current state and the audio system. + */ + handleCallDisconnected: function handleCallDisconnected(call) { + if (DEBUG) this.debug("handleCallDisconnected: " + JSON.stringify(call)); + call.state = nsITelephonyProvider.CALL_STATE_DISCONNECTED; + let duration = ("started" in call && typeof call.started == "number") ? + new Date().getTime() - call.started : 0; + let data = { + number: call.number, + duration: duration, + direction: call.isOutgoing ? "outgoing" : "incoming" + }; + gSystemMessenger.broadcastMessage("telephony-call-ended", data); + this.updateCallAudioState({call: call}); + gMessageManager.sendTelephonyMessage("RIL:CallStateChanged", + this.clientId, call); + }, + + handleConferenceCallStateChanged: function handleConferenceCallStateChanged(state) { + debug("handleConferenceCallStateChanged: " + state); + state = state != null ? convertRILCallState(state) : + nsITelephonyProvider.CALL_STATE_UNKNOWN; + this.updateCallAudioState({conferenceState: state}); + gMessageManager.sendTelephonyMessage("RIL:ConferenceCallStateChanged", + this.clientId, state); + }, + /** * Update network selection mode */ @@ -1585,6 +1905,23 @@ RadioInterface.prototype = { this.clientId, message); }, + /** + * Handle call error. + */ + handleCallError: function handleCallError(message) { + gMessageManager.sendTelephonyMessage("RIL:CallError", + this.clientId, message); + }, + + /** + * Handle supplementary service notification. + */ + handleSuppSvcNotification: function handleSuppSvcNotification(message) { + message.notification = convertRILSuppSvcNotification(message.notification); + gMessageManager.sendTelephonyMessage("RIL:SuppSvcNotification", + this.clientId, message); + }, + /** * Handle WDP port push PDU. Constructor WDP bearer information and deliver * to WapPushManager. @@ -1979,6 +2316,8 @@ RadioInterface.prototype = { } break; case "xpcom-shutdown": + // Cancel the timer for the call-ring wake lock. + this._cancelCallRingWakeLockTimer(); // Shutdown all RIL network interfaces for each (let apnSetting in this.apnSettings.byAPN) { if (apnSetting.iface) { @@ -2128,6 +2467,56 @@ RadioInterface.prototype = { // Handle phone functions of nsIRILContentHelper + enumerateCalls: function enumerateCalls(target, message) { + if (DEBUG) this.debug("Requesting enumeration of calls for callback"); + this.workerMessenger.send("enumerateCalls", message, (function(response) { + for (let call of response.calls) { + call.state = convertRILCallState(call.state); + call.isActive = this._activeCall ? + call.callIndex == this._activeCall.callIndex : false; + } + target.sendAsyncMessage("RIL:EnumerateCalls", response); + return false; + }).bind(this)); + }, + + _validateNumber: function _validateNumber(number) { + // note: isPlainPhoneNumber also accepts USSD and SS numbers + if (PhoneNumberUtils.isPlainPhoneNumber(number)) { + return true; + } + + this.handleCallError({ + callIndex: -1, + errorMsg: RIL.RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[RIL.CALL_FAIL_UNOBTAINABLE_NUMBER] + }); + if (DEBUG) { + this.debug("Number '" + number + "' doesn't seem to be a viable number." + + " Drop."); + } + + return false; + }, + + dial: function dial(number) { + if (DEBUG) this.debug("Dialing " + number); + number = PhoneNumberUtils.normalize(number); + if (this._validateNumber(number)) { + this.workerMessenger.send("dial", { number: number, + isDialEmergency: false }); + } + }, + + dialEmergency: function dialEmergency(number) { + if (DEBUG) this.debug("Dialing emergency " + number); + // we don't try to be too clever here, as the phone is probably in the + // locked state. Let's just check if it's a number without normalizing + if (this._validateNumber(number)) { + this.workerMessenger.send("dial", { number: number, + isDialEmergency: true }); + } + }, + _sendCfStateChanged: function _sendCfStateChanged(message) { gMessageManager.sendMobileConnectionMessage("RIL:CfStateChanged", this.clientId, message); @@ -2182,6 +2571,37 @@ RadioInterface.prototype = { }).bind(this)); }, + get microphoneMuted() { + return gAudioManager.microphoneMuted; + }, + set microphoneMuted(value) { + if (value == this.microphoneMuted) { + return; + } + gAudioManager.microphoneMuted = value; + + if (!this._activeCall) { + gAudioManager.phoneState = nsIAudioManager.PHONE_STATE_NORMAL; + } + }, + + get speakerEnabled() { + return (gAudioManager.getForceForUse(nsIAudioManager.USE_COMMUNICATION) == + nsIAudioManager.FORCE_SPEAKER); + }, + set speakerEnabled(value) { + if (value == this.speakerEnabled) { + return; + } + let force = value ? nsIAudioManager.FORCE_SPEAKER : + nsIAudioManager.FORCE_NONE; + gAudioManager.setForceForUse(nsIAudioManager.USE_COMMUNICATION, force); + + if (!this._activeCall) { + gAudioManager.phoneState = nsIAudioManager.PHONE_STATE_NORMAL; + } + }, + /** * List of tuples of national language identifier pairs. * @@ -2948,13 +3368,6 @@ RadioInterface.prototype = { this.workerMessenger.send("deactivateDataCall", { cid: cid, reason: reason }); }, - - sendWorkerMessage: function sendWorkerMessage(rilMessageType, message, - callback) { - this.workerMessenger.send(rilMessageType, message, function (response) { - return callback.handleResponse(response); - }); - } }; function RILNetworkInterface(radioInterface, apnSetting) { diff --git a/dom/system/gonk/nsIRadioInterfaceLayer.idl b/dom/system/gonk/nsIRadioInterfaceLayer.idl index c9c7eeb51ae..3b226a1eee4 100644 --- a/dom/system/gonk/nsIRadioInterfaceLayer.idl +++ b/dom/system/gonk/nsIRadioInterfaceLayer.idl @@ -79,13 +79,7 @@ interface nsIRilContext : nsISupports readonly attribute nsIDOMMozMobileConnectionInfo data; }; -[scriptable, function, uuid(3bc96351-53b0-47a1-a888-c74c64b60f25)] -interface nsIRilSendWorkerMessageCallback : nsISupports -{ - boolean handleResponse(in jsval response); -}; - -[scriptable, uuid(61a8ca67-6113-4cd0-b443-e045f09863ed)] +[scriptable, uuid(5efcd358-080e-46d6-a7f7-4f36c204eec3)] interface nsIRadioInterface : nsISupports { readonly attribute nsIRilContext rilContext; @@ -111,10 +105,6 @@ interface nsIRadioInterface : nsISupports in DOMString message, in boolean silent, in nsIMobileMessageCallback request); - - void sendWorkerMessage(in DOMString type, - [optional] in jsval message, - [optional] in nsIRilSendWorkerMessageCallback callback); }; [scriptable, uuid(44b03951-1444-4c03-bd37-0bcb3a01b56f)] diff --git a/dom/telephony/TelephonyFactory.cpp b/dom/telephony/TelephonyFactory.cpp index dacfb001836..cdb2b88dd86 100644 --- a/dom/telephony/TelephonyFactory.cpp +++ b/dom/telephony/TelephonyFactory.cpp @@ -4,9 +4,6 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "mozilla/dom/telephony/TelephonyFactory.h" -#ifdef MOZ_WIDGET_GONK -#include "nsIGonkTelephonyProvider.h" -#endif #include "nsServiceManagerUtils.h" #include "nsXULAppAPI.h" #include "TelephonyIPCProvider.h" @@ -20,10 +17,6 @@ TelephonyFactory::CreateTelephonyProvider() if (XRE_GetProcessType() == GeckoProcessType_Content) { provider = new TelephonyIPCProvider(); -#ifdef MOZ_WIDGET_GONK - } else { - provider = do_CreateInstance(GONK_TELEPHONY_PROVIDER_CONTRACTID); -#endif } return provider.forget(); diff --git a/dom/telephony/gonk/TelephonyProvider.js b/dom/telephony/gonk/TelephonyProvider.js deleted file mode 100644 index 0629f5cdea5..00000000000 --- a/dom/telephony/gonk/TelephonyProvider.js +++ /dev/null @@ -1,525 +0,0 @@ -/* -*- Mode: js; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* 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/. */ - -"use strict"; - -const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); - -var RIL = {}; -Cu.import("resource://gre/modules/ril_consts.js", RIL); - -const GONK_TELEPHONYPROVIDER_CONTRACTID = - "@mozilla.org/telephony/gonktelephonyprovider;1"; -const GONK_TELEPHONYPROVIDER_CID = - Components.ID("{67d26434-d063-4d28-9f48-5b3189788155}"); - -const kPrefenceChangedObserverTopic = "nsPref:changed"; -const kXpcomShutdownObserverTopic = "xpcom-shutdown"; - -const nsIAudioManager = Ci.nsIAudioManager; -const nsITelephonyProvider = Ci.nsITelephonyProvider; - -const CALL_WAKELOCK_TIMEOUT = 5000; - -let DEBUG; -function debug(s) { - dump("TelephonyProvider: " + s + "\n"); -} - -XPCOMUtils.defineLazyGetter(this, "gAudioManager", function getAudioManager() { - try { - return Cc["@mozilla.org/telephony/audiomanager;1"] - .getService(nsIAudioManager); - } catch (ex) { - //TODO on the phone this should not fall back as silently. - - // Fake nsIAudioManager implementation so that we can run the telephony - // code in a non-Gonk build. - if (DEBUG) debug("Using fake audio manager."); - return { - microphoneMuted: false, - masterVolume: 1.0, - masterMuted: false, - phoneState: nsIAudioManager.PHONE_STATE_CURRENT, - _forceForUse: {}, - - setForceForUse: function setForceForUse(usage, force) { - this._forceForUse[usage] = force; - }, - - getForceForUse: function setForceForUse(usage) { - return this._forceForUse[usage] || nsIAudioManager.FORCE_NONE; - } - }; - } -}); - -XPCOMUtils.defineLazyServiceGetter(this, "gPowerManagerService", - "@mozilla.org/power/powermanagerservice;1", - "nsIPowerManagerService"); - -XPCOMUtils.defineLazyServiceGetter(this, "gSystemMessenger", - "@mozilla.org/system-message-internal;1", - "nsISystemMessagesInternal"); - -XPCOMUtils.defineLazyGetter(this, "gRadioInterface", function () { - let ril = Cc["@mozilla.org/ril;1"].getService(Ci["nsIRadioInterfaceLayer"]); - // TODO: Bug 854326 - B2G Multi-SIM: support multiple SIM cards for SMS/MMS - return ril.getRadioInterface(0); -}); - -XPCOMUtils.defineLazyGetter(this, "gPhoneNumberUtils", function () { - let ns = {}; - Cu.import("resource://gre/modules/PhoneNumberUtils.jsm", ns); - return ns.PhoneNumberUtils; -}); - -function TelephonyProvider() { - this._listeners = []; - - this._updateDebugFlag(); - - Services.obs.addObserver(this, kPrefenceChangedObserverTopic, false); - Services.obs.addObserver(this, kXpcomShutdownObserverTopic, false); -} -TelephonyProvider.prototype = { - classID: GONK_TELEPHONYPROVIDER_CID, - classInfo: XPCOMUtils.generateCI({classID: GONK_TELEPHONYPROVIDER_CID, - contractID: GONK_TELEPHONYPROVIDER_CONTRACTID, - classDescription: "TelephonyProvider", - interfaces: [Ci.nsITelephonyProvider, - Ci.nsIGonkTelephonyProvider], - flags: Ci.nsIClassInfo.SINGLETON}), - QueryInterface: XPCOMUtils.generateQI([Ci.nsITelephonyProvider, - Ci.nsIGonkTelephonyProvider, - Ci.nsIObserver]), - - _callRingWakeLock: null, - _callRingWakeLockTimer: null, - _cancelCallRingWakeLockTimer: function _cancelCallRingWakeLockTimer() { - if (this._callRingWakeLockTimer) { - this._callRingWakeLockTimer.cancel(); - } - if (this._callRingWakeLock) { - this._callRingWakeLock.unlock(); - this._callRingWakeLock = null; - } - }, - - // An array of nsITelephonyListener instances. - _listeners: null, - _notifyAllListeners: function _notifyAllListeners(aMethodName, aArgs) { - let listeners = this._listeners.slice(); - for (let listener of listeners) { - if (this._listeners.indexOf(listener) == -1) { - // Listener has been unregistered in previous run. - continue; - } - - let handler = listener[aMethodName]; - try { - handler.apply(listener, aArgs); - } catch (e) { - debug("listener for " + aMethodName + " threw an exception: " + e); - } - } - }, - - /** - * Track the active call and update the audio system as its state changes. - */ - _activeCall: null, - _updateCallAudioState: function _updateCallAudioState(aCall, - aConferenceState) { - if (aConferenceState === nsITelephonyProvider.CALL_STATE_CONNECTED) { - gAudioManager.phoneState = nsIAudioManager.PHONE_STATE_IN_CALL; - if (this.speakerEnabled) { - gAudioManager.setForceForUse(nsIAudioManager.USE_COMMUNICATION, - nsIAudioManager.FORCE_SPEAKER); - } - return; - } - if (aConferenceState === nsITelephonyProvider.CALL_STATE_UNKNOWN || - aConferenceState === nsITelephonyProvider.CALL_STATE_HELD) { - if (!this._activeCall) { - gAudioManager.phoneState = nsIAudioManager.PHONE_STATE_NORMAL; - } - return; - } - - if (!aCall) { - return; - } - - if (aCall.isConference) { - if (this._activeCall && this._activeCall.callIndex == aCall.callIndex) { - this._activeCall = null; - } - return; - } - - switch (aCall.state) { - case nsITelephonyProvider.CALL_STATE_DIALING: // Fall through... - case nsITelephonyProvider.CALL_STATE_ALERTING: - case nsITelephonyProvider.CALL_STATE_CONNECTED: - aCall.isActive = true; - this._activeCall = aCall; - gAudioManager.phoneState = nsIAudioManager.PHONE_STATE_IN_CALL; - if (this.speakerEnabled) { - gAudioManager.setForceForUse(nsIAudioManager.USE_COMMUNICATION, - nsIAudioManager.FORCE_SPEAKER); - } - if (DEBUG) { - debug("Active call, put audio system into PHONE_STATE_IN_CALL: " + - gAudioManager.phoneState); - } - break; - - case nsITelephonyProvider.CALL_STATE_INCOMING: - aCall.isActive = false; - if (!this._activeCall) { - // We can change the phone state into RINGTONE only when there's - // no active call. - gAudioManager.phoneState = nsIAudioManager.PHONE_STATE_RINGTONE; - if (DEBUG) { - debug("Incoming call, put audio system into PHONE_STATE_RINGTONE: " + - gAudioManager.phoneState); - } - } - break; - - case nsITelephonyProvider.CALL_STATE_HELD: // Fall through... - case nsITelephonyProvider.CALL_STATE_DISCONNECTED: - aCall.isActive = false; - if (this._activeCall && - this._activeCall.callIndex == aCall.callIndex) { - // Previously active call is not active now. - this._activeCall = null; - } - - if (!this._activeCall) { - // No active call. Disable the audio. - gAudioManager.phoneState = nsIAudioManager.PHONE_STATE_NORMAL; - if (DEBUG) { - debug("No active call, put audio system into PHONE_STATE_NORMAL: " + - gAudioManager.phoneState); - } - } - break; - } - }, - - _convertRILCallState: function _convertRILCallState(aState) { - switch (aState) { - case RIL.CALL_STATE_ACTIVE: - return nsITelephonyProvider.CALL_STATE_CONNECTED; - case RIL.CALL_STATE_HOLDING: - return nsITelephonyProvider.CALL_STATE_HELD; - case RIL.CALL_STATE_DIALING: - return nsITelephonyProvider.CALL_STATE_DIALING; - case RIL.CALL_STATE_ALERTING: - return nsITelephonyProvider.CALL_STATE_ALERTING; - case RIL.CALL_STATE_INCOMING: - case RIL.CALL_STATE_WAITING: - return nsITelephonyProvider.CALL_STATE_INCOMING; - default: - throw new Error("Unknown rilCallState: " + aState); - } - }, - - _convertRILSuppSvcNotification: function _convertRILSuppSvcNotification(aNotification) { - switch (aNotification) { - case RIL.GECKO_SUPP_SVC_NOTIFICATION_REMOTE_HELD: - return nsITelephonyProvider.NOTIFICATION_REMOTE_HELD; - case RIL.GECKO_SUPP_SVC_NOTIFICATION_REMOTE_RESUMED: - return nsITelephonyProvider.NOTIFICATION_REMOTE_RESUMED; - default: - throw new Error("Unknown rilSuppSvcNotification: " + aNotification); - } - }, - - _validateNumber: function _validateNumber(aNumber) { - // note: isPlainPhoneNumber also accepts USSD and SS numbers - if (gPhoneNumberUtils.isPlainPhoneNumber(aNumber)) { - return true; - } - - let errorMsg = RIL.RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[RIL.CALL_FAIL_UNOBTAINABLE_NUMBER]; - let currentThread = Services.tm.currentThread; - currentThread.dispatch(this.notifyCallError.bind(this, -1, errorMsg), - Ci.nsIThread.DISPATCH_NORMAL); - if (DEBUG) { - debug("Number '" + aNumber + "' doesn't seem to be a viable number. Drop."); - } - - return false; - }, - - _updateDebugFlag: function _updateDebugFlag() { - try { - DEBUG = RIL.DEBUG_RIL || - Services.prefs.getBoolPref("ril.debugging.enabled"); - } catch (e) {} - }, - - /** - * nsITelephonyProvider interface. - */ - - registerListener: function(aListener) { - if (this._listeners.indexOf(aListener) >= 0) { - throw Cr.NS_ERROR_UNEXPECTED; - } - - this._listeners.push(aListener); - }, - - unregisterListener: function(aListener) { - let index = this._listeners.indexOf(aListener); - if (index < 0) { - throw Cr.NS_ERROR_UNEXPECTED; - } - - this._listeners.splice(index, 1); - }, - - enumerateCalls: function(aListener) { - if (DEBUG) debug("Requesting enumeration of calls for callback"); - gRadioInterface.sendWorkerMessage("enumerateCalls", null, - (function(response) { - for (let call of response.calls) { - call.state = this._convertRILCallState(call.state); - call.isActive = this._activeCall ? - (call.callIndex == this._activeCall.callIndex) : false; - - aListener.enumerateCallState(call.callIndex, call.state, call.number, - call.isActive, call.isOutgoing, - call.isEmergency, call.isConference); - } - aListener.enumerateCallStateComplete(); - - return false; - }).bind(this)); - }, - - dial: function(aNumber, aIsEmergency) { - if (DEBUG) debug("Dialing " + (aIsEmergency ? "emergency " : "") + aNumber); - // we don't try to be too clever here, as the phone is probably in the - // locked state. Let's just check if it's a number without normalizing - if (!aIsEmergency) { - aNumber = gPhoneNumberUtils.normalize(aNumber); - } - if (this._validateNumber(aNumber)) { - gRadioInterface.sendWorkerMessage("dial", { number: aNumber, - isDialEmergency: aIsEmergency }); - } - }, - - hangUp: function(aCallIndex) { - gRadioInterface.sendWorkerMessage("hangUp", { callIndex: aCallIndex }); - }, - - startTone: function(aDtmfChar) { - gRadioInterface.sendWorkerMessage("startTone", { dtmfChar: aDtmfChar }); - }, - - stopTone: function() { - gRadioInterface.sendWorkerMessage("stopTone"); - }, - - answerCall: function(aCallIndex) { - gRadioInterface.sendWorkerMessage("answerCall", { callIndex: aCallIndex }); - }, - - rejectCall: function(aCallIndex) { - gRadioInterface.sendWorkerMessage("rejectCall", { callIndex: aCallIndex }); - }, - - holdCall: function(aCallIndex) { - gRadioInterface.sendWorkerMessage("holdCall", { callIndex: aCallIndex }); - }, - - resumeCall: function(aCallIndex) { - gRadioInterface.sendWorkerMessage("resumeCall", { callIndex: aCallIndex }); - }, - - conferenceCall: function conferenceCall() { - gRadioInterface.sendWorkerMessage("conferenceCall"); - }, - - separateCall: function separateCall(aCallIndex) { - gRadioInterface.sendWorkerMessage("separateCall", { callIndex: aCallIndex }); - }, - - holdConference: function holdConference() { - gRadioInterface.sendWorkerMessage("holdConference"); - }, - - resumeConference: function resumeConference() { - gRadioInterface.sendWorkerMessage("resumeConference"); - }, - - get microphoneMuted() { - return gAudioManager.microphoneMuted; - }, - - set microphoneMuted(aMuted) { - if (aMuted == this.microphoneMuted) { - return; - } - gAudioManager.microphoneMuted = aMuted; - - if (!this._activeCall) { - gAudioManager.phoneState = nsIAudioManager.PHONE_STATE_NORMAL; - } - }, - - get speakerEnabled() { - let force = gAudioManager.getForceForUse(nsIAudioManager.USE_COMMUNICATION); - return (force == nsIAudioManager.FORCE_SPEAKER); - }, - - set speakerEnabled(aEnabled) { - if (aEnabled == this.speakerEnabled) { - return; - } - let force = aEnabled ? nsIAudioManager.FORCE_SPEAKER : - nsIAudioManager.FORCE_NONE; - gAudioManager.setForceForUse(nsIAudioManager.USE_COMMUNICATION, force); - - if (!this._activeCall) { - gAudioManager.phoneState = nsIAudioManager.PHONE_STATE_NORMAL; - } - }, - - /** - * nsIGonkTelephonyProvider interface. - */ - - /** - * Handle call disconnects by updating our current state and the audio system. - */ - notifyCallDisconnected: function notifyCallDisconnected(aCall) { - if (DEBUG) debug("handleCallDisconnected: " + JSON.stringify(aCall)); - - aCall.state = nsITelephonyProvider.CALL_STATE_DISCONNECTED; - let duration = ("started" in aCall && typeof aCall.started == "number") ? - new Date().getTime() - aCall.started : 0; - let data = { - number: aCall.number, - duration: duration, - direction: aCall.isOutgoing ? "outgoing" : "incoming" - }; - gSystemMessenger.broadcastMessage("telephony-call-ended", data); - - this._updateCallAudioState(aCall, null); - - this._notifyAllListeners("callStateChanged", [aCall.callIndex, - aCall.state, - aCall.number, - aCall.isActive, - aCall.isOutgoing, - aCall.isEmergency, - aCall.isConference]); - }, - - /** - * Handle call error. - */ - notifyCallError: function notifyCallError(aCallIndex, aErrorMsg) { - this._notifyAllListeners("notifyError", [aCallIndex, aErrorMsg]); - }, - - /** - * Handle an incoming call. - * - * Not much is known about this call at this point, but it's enough - * to start bringing up the Phone app already. - */ - notifyCallRing: function notifyCallRing() { - if (!this._callRingWakeLock) { - this._callRingWakeLock = gPowerManagerService.newWakeLock("cpu"); - } - if (!this._callRingWakeLockTimer) { - this._callRingWakeLockTimer = - Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - } - this._callRingWakeLockTimer - .initWithCallback(this._cancelCallRingWakeLockTimer.bind(this), - CALL_WAKELOCK_TIMEOUT, Ci.nsITimer.TYPE_ONE_SHOT); - - gSystemMessenger.broadcastMessage("telephony-new-call", {}); - }, - - /** - * Handle call state changes by updating our current state and the audio - * system. - */ - notifyCallStateChanged: function notifyCallStateChanged(aCall) { - if (DEBUG) debug("handleCallStateChange: " + JSON.stringify(aCall)); - - aCall.state = this._convertRILCallState(aCall.state); - if (aCall.state == nsITelephonyProvider.CALL_STATE_DIALING) { - gSystemMessenger.broadcastMessage("telephony-new-call", {}); - } - - this._updateCallAudioState(aCall, null); - - this._notifyAllListeners("callStateChanged", [aCall.callIndex, - aCall.state, - aCall.number, - aCall.isActive, - aCall.isOutgoing, - aCall.isEmergency, - aCall.isConference]); - }, - - notifyCdmaCallWaiting: function notifyCdmaCallWaiting(aNumber) { - this._notifyAllListeners("notifyCdmaCallWaiting", [aNumber]); - }, - - notifySupplementaryService: function notifySupplementaryService(aCallIndex, - aNotification) { - let notification = this._convertRILSuppSvcNotification(aNotification); - this._notifyAllListeners("supplementaryServiceNotification", - [aCallIndex, notification]); - }, - - notifyConferenceCallStateChanged: function notifyConferenceCallStateChanged(aState) { - if (DEBUG) debug("handleConferenceCallStateChanged: " + aState); - aState = aState != null ? convertRILCallState(aState) : - nsITelephonyProvider.CALL_STATE_UNKNOWN; - this._updateCallAudioState(null, aState); - - this._notifyAllListeners("conferenceCallStateChanged", [aState]); - }, - - /** - * nsIObserver interface. - */ - - observe: function observe(aSubject, aTopic, aData) { - switch (aTopic) { - case kPrefenceChangedObserverTopic: - if (aData === "ril.debugging.enabled") { - this._updateDebugFlag(); - } - break; - - case kXpcomShutdownObserverTopic: - // Cancel the timer for the call-ring wake lock. - this._cancelCallRingWakeLockTimer(); - - Services.obs.removeObserver(this, kPrefenceChangedObserverTopic); - Services.obs.removeObserver(this, kXpcomShutdownObserverTopic); - break; - } - } -}; - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([TelephonyProvider]); diff --git a/dom/telephony/gonk/TelephonyProvider.manifest b/dom/telephony/gonk/TelephonyProvider.manifest deleted file mode 100644 index 06cfba0c798..00000000000 --- a/dom/telephony/gonk/TelephonyProvider.manifest +++ /dev/null @@ -1,2 +0,0 @@ -component {67d26434-d063-4d28-9f48-5b3189788155} TelephonyProvider.js -contract @mozilla.org/telephony/gonktelephonyprovider;1 {67d26434-d063-4d28-9f48-5b3189788155} diff --git a/dom/telephony/moz.build b/dom/telephony/moz.build index d2a457fa92f..e15bf63810e 100644 --- a/dom/telephony/moz.build +++ b/dom/telephony/moz.build @@ -42,15 +42,6 @@ IPDL_SOURCES += [ 'ipc/TelephonyTypes.ipdlh' ] -if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk': - XPIDL_SOURCES += [ - 'nsIGonkTelephonyProvider.idl', - ] - EXTRA_COMPONENTS += [ - 'gonk/TelephonyProvider.js', - 'gonk/TelephonyProvider.manifest', - ] - FAIL_ON_WARNINGS = True LIBXUL_LIBRARY = True diff --git a/dom/telephony/nsIGonkTelephonyProvider.idl b/dom/telephony/nsIGonkTelephonyProvider.idl deleted file mode 100644 index 934f57d25c2..00000000000 --- a/dom/telephony/nsIGonkTelephonyProvider.idl +++ /dev/null @@ -1,31 +0,0 @@ -/* -*- Mode: idl; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* 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 "nsITelephonyProvider.idl" - -%{C++ -#define GONK_TELEPHONY_PROVIDER_CONTRACTID \ - "@mozilla.org/telephony/gonktelephonyprovider;1" -%} - -[scriptable, uuid(0d106c7e-ba47-48ee-ba48-c92002d401b6)] -interface nsIGonkTelephonyProvider : nsITelephonyProvider -{ - void notifyCallDisconnected(in jsval call); - - void notifyCallError(in long callIndex, - in AString error); - - void notifyCallRing(); - - void notifyCallStateChanged(in jsval call); - - void notifyCdmaCallWaiting(in AString number); - - void notifySupplementaryService(in long callIndex, - in AString notification); - - void notifyConferenceCallStateChanged(in unsigned short state); -}; From 29ff7437c42a705e9a325b8eaa848c6d49910aa0 Mon Sep 17 00:00:00 2001 From: Ed Morley Date: Wed, 4 Sep 2013 11:51:02 +0100 Subject: [PATCH 024/171] Backed out changeset 9bd4fcd6d084 (bug 864485) --- b2g/installer/package-manifest.in | 2 +- browser/installer/package-manifest.in | 2 +- dom/base/Navigator.cpp | 2 +- dom/bindings/Bindings.conf | 10 +- dom/bluetooth/BluetoothHfpManager.cpp | 2 +- dom/bluetooth/BluetoothTelephonyListener.cpp | 12 +- dom/dom-config.mk | 1 + dom/ipc/ContentChild.cpp | 15 - dom/ipc/ContentChild.h | 3 - dom/ipc/ContentParent.cpp | 21 - dom/ipc/ContentParent.h | 3 - dom/mobilemessage/src/Makefile.in | 1 + dom/moz.build | 4 +- dom/system/gonk/Makefile.in | 1 + dom/telephony/CallEvent.cpp | 1 - dom/telephony/Makefile.in | 11 +- dom/telephony/Telephony.cpp | 23 +- dom/telephony/TelephonyCall.cpp | 1 - dom/telephony/TelephonyCallGroup.cpp | 1 - dom/telephony/TelephonyFactory.cpp | 23 - dom/telephony/TelephonyFactory.h | 24 - dom/telephony/ipc/TelephonyChild.cpp | 130 ------ dom/telephony/ipc/TelephonyChild.h | 77 ---- dom/telephony/ipc/TelephonyIPCProvider.cpp | 258 ----------- dom/telephony/ipc/TelephonyIPCProvider.h | 37 -- dom/telephony/ipc/TelephonyParent.cpp | 448 ------------------- dom/telephony/ipc/TelephonyParent.h | 128 ------ dom/telephony/moz.build | 23 +- dom/webidl/WebIDL.mk | 10 +- layout/build/Makefile.in | 2 +- layout/build/nsLayoutModule.cpp | 9 - 31 files changed, 45 insertions(+), 1240 deletions(-) delete mode 100644 dom/telephony/TelephonyFactory.cpp delete mode 100644 dom/telephony/TelephonyFactory.h delete mode 100644 dom/telephony/ipc/TelephonyChild.cpp delete mode 100644 dom/telephony/ipc/TelephonyChild.h delete mode 100644 dom/telephony/ipc/TelephonyIPCProvider.cpp delete mode 100644 dom/telephony/ipc/TelephonyIPCProvider.h delete mode 100644 dom/telephony/ipc/TelephonyParent.cpp delete mode 100644 dom/telephony/ipc/TelephonyParent.h diff --git a/b2g/installer/package-manifest.in b/b2g/installer/package-manifest.in index adf1200a495..2553cf7659a 100644 --- a/b2g/installer/package-manifest.in +++ b/b2g/installer/package-manifest.in @@ -164,6 +164,7 @@ @BINPATH@/components/dom_base.xpt @BINPATH@/components/dom_system.xpt #ifdef MOZ_B2G_RIL +@BINPATH@/components/dom_telephony.xpt @BINPATH@/components/dom_voicemail.xpt @BINPATH@/components/dom_wifi.xpt @BINPATH@/components/dom_system_gonk.xpt @@ -202,7 +203,6 @@ @BINPATH@/components/dom_mobilemessage.xpt @BINPATH@/components/dom_storage.xpt @BINPATH@/components/dom_stylesheets.xpt -@BINPATH@/components/dom_telephony.xpt @BINPATH@/components/dom_threads.xpt @BINPATH@/components/dom_traversal.xpt @BINPATH@/components/dom_views.xpt diff --git a/browser/installer/package-manifest.in b/browser/installer/package-manifest.in index 387a7915c87..7842047d3bc 100644 --- a/browser/installer/package-manifest.in +++ b/browser/installer/package-manifest.in @@ -176,6 +176,7 @@ @BINPATH@/components/dom_base.xpt @BINPATH@/components/dom_system.xpt #ifdef MOZ_B2G_RIL +@BINPATH@/components/dom_telephony.xpt @BINPATH@/components/dom_voicemail.xpt @BINPATH@/components/dom_wifi.xpt @BINPATH@/components/dom_system_gonk.xpt @@ -211,7 +212,6 @@ @BINPATH@/components/dom_mobilemessage.xpt @BINPATH@/components/dom_storage.xpt @BINPATH@/components/dom_stylesheets.xpt -@BINPATH@/components/dom_telephony.xpt @BINPATH@/components/dom_traversal.xpt #ifdef MOZ_WEBSPEECH @BINPATH@/components/dom_webspeechrecognition.xpt diff --git a/dom/base/Navigator.cpp b/dom/base/Navigator.cpp index afca9c5111e..45ba553271b 100644 --- a/dom/base/Navigator.cpp +++ b/dom/base/Navigator.cpp @@ -54,7 +54,7 @@ #include "MediaManager.h" #endif #ifdef MOZ_B2G_RIL -#include "mozilla/dom/telephony/Telephony.h" +#include "Telephony.h" #endif #ifdef MOZ_B2G_BT #include "BluetoothManager.h" diff --git a/dom/bindings/Bindings.conf b/dom/bindings/Bindings.conf index 28f4b4d783d..280dec64d94 100644 --- a/dom/bindings/Bindings.conf +++ b/dom/bindings/Bindings.conf @@ -168,12 +168,12 @@ DOMInterfaces = { 'CallEvent': { 'nativeType': 'mozilla::dom::telephony::CallEvent', - 'headerFile': 'mozilla/dom/telephony/CallEvent.h', + 'headerFile': 'CallEvent.h', }, 'CallsList': { 'nativeType': 'mozilla::dom::telephony::CallsList', - 'headerFile': 'mozilla/dom/telephony/CallsList.h', + 'headerFile': 'CallsList.h', }, 'CameraControl': { @@ -1162,17 +1162,17 @@ DOMInterfaces = { 'Telephony' : { 'nativeType': 'mozilla::dom::telephony::Telephony', - 'headerFile': 'mozilla/dom/telephony/Telephony.h', + 'headerFile': 'Telephony.h', }, 'TelephonyCall' : { 'nativeType': 'mozilla::dom::telephony::TelephonyCall', - 'headerFile': 'mozilla/dom/telephony/TelephonyCall.h', + 'headerFile': 'TelephonyCall.h', }, 'TelephonyCallGroup' : { 'nativeType': 'mozilla::dom::telephony::TelephonyCallGroup', - 'headerFile': 'mozilla/dom/telephony/TelephonyCallGroup.h', + 'headerFile': 'TelephonyCallGroup.h', }, 'Text': { diff --git a/dom/bluetooth/BluetoothHfpManager.cpp b/dom/bluetooth/BluetoothHfpManager.cpp index 2df32818d00..99a7d68d741 100644 --- a/dom/bluetooth/BluetoothHfpManager.cpp +++ b/dom/bluetooth/BluetoothHfpManager.cpp @@ -1479,7 +1479,7 @@ BluetoothHfpManager::OnConnectSuccess(BluetoothSocket* aSocket) } nsCOMPtr provider = - do_GetService(TELEPHONY_PROVIDER_CONTRACTID); + do_GetService(NS_RILCONTENTHELPER_CONTRACTID); NS_ENSURE_TRUE_VOID(provider); provider->EnumerateCalls(mListener->GetListener()); diff --git a/dom/bluetooth/BluetoothTelephonyListener.cpp b/dom/bluetooth/BluetoothTelephonyListener.cpp index 93bfc84e676..eac3a431ba0 100644 --- a/dom/bluetooth/BluetoothTelephonyListener.cpp +++ b/dom/bluetooth/BluetoothTelephonyListener.cpp @@ -61,11 +61,13 @@ TelephonyListener::EnumerateCallState(uint32_t aCallIndex, bool aIsActive, bool aIsOutgoing, bool aIsEmergency, - bool aIsConference) + bool aIsConference, + bool* aResult) { BluetoothHfpManager* hfp = BluetoothHfpManager::Get(); hfp->HandleCallStateChanged(aCallIndex, aCallState, EmptyString(), aNumber, aIsOutgoing, false); + *aResult = true; return NS_OK; } @@ -115,10 +117,10 @@ bool BluetoothTelephonyListener::StartListening() { nsCOMPtr provider = - do_GetService(TELEPHONY_PROVIDER_CONTRACTID); + do_GetService(NS_RILCONTENTHELPER_CONTRACTID); NS_ENSURE_TRUE(provider, false); - nsresult rv = provider->RegisterListener(mTelephonyListener); + nsresult rv = provider->RegisterTelephonyMsg(mTelephonyListener); NS_ENSURE_SUCCESS(rv, false); return true; @@ -128,10 +130,10 @@ bool BluetoothTelephonyListener::StopListening() { nsCOMPtr provider = - do_GetService(TELEPHONY_PROVIDER_CONTRACTID); + do_GetService(NS_RILCONTENTHELPER_CONTRACTID); NS_ENSURE_TRUE(provider, false); - nsresult rv = provider->UnregisterListener(mTelephonyListener); + nsresult rv = provider->UnregisterTelephonyMsg(mTelephonyListener); return NS_FAILED(rv) ? false : true; } diff --git a/dom/dom-config.mk b/dom/dom-config.mk index 6450d3c92a0..b001fc9d378 100644 --- a/dom/dom-config.mk +++ b/dom/dom-config.mk @@ -40,6 +40,7 @@ DOM_SRCDIRS = \ ifdef MOZ_B2G_RIL DOM_SRCDIRS += \ dom/system/gonk \ + dom/telephony \ dom/wifi \ dom/icc/src \ $(NULL) diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp index ceb98dd23f1..f1afd28ea2d 100644 --- a/dom/ipc/ContentChild.cpp +++ b/dom/ipc/ContentChild.cpp @@ -96,7 +96,6 @@ #include "mozilla/dom/indexedDB/PIndexedDBChild.h" #include "mozilla/dom/mobilemessage/SmsChild.h" -#include "mozilla/dom/telephony/TelephonyChild.h" #include "mozilla/dom/devicestorage/DeviceStorageRequestChild.h" #include "mozilla/dom/bluetooth/PBluetoothChild.h" #include "mozilla/dom/PFMRadioChild.h" @@ -127,7 +126,6 @@ using namespace mozilla::dom::devicestorage; using namespace mozilla::dom::ipc; using namespace mozilla::dom::mobilemessage; using namespace mozilla::dom::indexedDB; -using namespace mozilla::dom::telephony; using namespace mozilla::hal_sandbox; using namespace mozilla::ipc; using namespace mozilla::layers; @@ -921,19 +919,6 @@ ContentChild::DeallocPSmsChild(PSmsChild* aSms) return true; } -PTelephonyChild* -ContentChild::AllocPTelephonyChild() -{ - MOZ_CRASH("No one should be allocating PTelephonyChild actors"); -} - -bool -ContentChild::DeallocPTelephonyChild(PTelephonyChild* aActor) -{ - delete aActor; - return true; -} - PStorageChild* ContentChild::AllocPStorageChild() { diff --git a/dom/ipc/ContentChild.h b/dom/ipc/ContentChild.h index 4dd4d77e20b..279af64fb61 100644 --- a/dom/ipc/ContentChild.h +++ b/dom/ipc/ContentChild.h @@ -152,9 +152,6 @@ public: virtual PSmsChild* AllocPSmsChild(); virtual bool DeallocPSmsChild(PSmsChild*); - virtual PTelephonyChild* AllocPTelephonyChild(); - virtual bool DeallocPTelephonyChild(PTelephonyChild*); - virtual PStorageChild* AllocPStorageChild(); virtual bool DeallocPStorageChild(PStorageChild* aActor); diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index 7c2552b3cbb..320e465a627 100644 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -34,7 +34,6 @@ #include "mozilla/dom/bluetooth/PBluetoothParent.h" #include "mozilla/dom/PFMRadioParent.h" #include "mozilla/dom/devicestorage/DeviceStorageRequestParent.h" -#include "mozilla/dom/telephony/TelephonyParent.h" #include "SmsParent.h" #include "mozilla/Hal.h" #include "mozilla/hal_sandbox/PHalParent.h" @@ -148,7 +147,6 @@ using namespace mozilla::dom::devicestorage; using namespace mozilla::dom::indexedDB; using namespace mozilla::dom::power; using namespace mozilla::dom::mobilemessage; -using namespace mozilla::dom::telephony; using namespace mozilla::hal; using namespace mozilla::idl; using namespace mozilla::ipc; @@ -2248,25 +2246,6 @@ ContentParent::DeallocPSmsParent(PSmsParent* aSms) return true; } -PTelephonyParent* -ContentParent::AllocPTelephonyParent() -{ - if (!AssertAppProcessPermission(this, "telephony")) { - return nullptr; - } - - TelephonyParent* actor = new TelephonyParent(); - NS_ADDREF(actor); - return actor; -} - -bool -ContentParent::DeallocPTelephonyParent(PTelephonyParent* aActor) -{ - static_cast(aActor)->Release(); - return true; -} - PStorageParent* ContentParent::AllocPStorageParent() { diff --git a/dom/ipc/ContentParent.h b/dom/ipc/ContentParent.h index 252e0235c90..5bfa77b18d1 100644 --- a/dom/ipc/ContentParent.h +++ b/dom/ipc/ContentParent.h @@ -321,9 +321,6 @@ private: virtual PSmsParent* AllocPSmsParent(); virtual bool DeallocPSmsParent(PSmsParent*); - virtual PTelephonyParent* AllocPTelephonyParent(); - virtual bool DeallocPTelephonyParent(PTelephonyParent*); - virtual PStorageParent* AllocPStorageParent(); virtual bool DeallocPStorageParent(PStorageParent* aActor); diff --git a/dom/mobilemessage/src/Makefile.in b/dom/mobilemessage/src/Makefile.in index e45e9b971de..4dfe608bd89 100644 --- a/dom/mobilemessage/src/Makefile.in +++ b/dom/mobilemessage/src/Makefile.in @@ -33,6 +33,7 @@ LOCAL_INCLUDES += $(VPATH:%=-I%) ifdef MOZ_B2G_RIL LOCAL_INCLUDES += \ + -I$(topsrcdir)/dom/telephony \ -I$(topsrcdir)/dom/system/gonk \ $(NULL) endif diff --git a/dom/moz.build b/dom/moz.build index 4c87f43ef34..5aeb1ba6a7a 100644 --- a/dom/moz.build +++ b/dom/moz.build @@ -72,8 +72,7 @@ PARALLEL_DIRS += [ 'camera', 'audiochannel', 'promise', - 'wappush', - 'telephony', + 'wappush' ] if CONFIG['OS_ARCH'] == 'WINNT': @@ -81,6 +80,7 @@ if CONFIG['OS_ARCH'] == 'WINNT': if CONFIG['MOZ_B2G_RIL']: PARALLEL_DIRS += [ + 'telephony', 'wifi', 'icc', 'cellbroadcast', diff --git a/dom/system/gonk/Makefile.in b/dom/system/gonk/Makefile.in index d19b0731f1f..d648d2d7407 100644 --- a/dom/system/gonk/Makefile.in +++ b/dom/system/gonk/Makefile.in @@ -26,6 +26,7 @@ include $(topsrcdir)/dom/dom-config.mk LOCAL_INCLUDES = \ -I$(topsrcdir)/dom/base \ -I$(topsrcdir)/dom/src/geolocation \ + -I$(topsrcdir)/dom/telephony \ -I$(topsrcdir)/dom/wifi \ -I$(topsrcdir)/dom/bluetooth \ -I$(topsrcdir)/content/events/src \ diff --git a/dom/telephony/CallEvent.cpp b/dom/telephony/CallEvent.cpp index 580750f0608..30ab81aee46 100644 --- a/dom/telephony/CallEvent.cpp +++ b/dom/telephony/CallEvent.cpp @@ -11,7 +11,6 @@ USING_TELEPHONY_NAMESPACE using namespace mozilla::dom; -using mozilla::ErrorResult; /* static */ already_AddRefed diff --git a/dom/telephony/Makefile.in b/dom/telephony/Makefile.in index cf24906409e..143590c476a 100644 --- a/dom/telephony/Makefile.in +++ b/dom/telephony/Makefile.in @@ -5,18 +5,11 @@ DEPTH = @DEPTH@ topsrcdir = @top_srcdir@ srcdir = @srcdir@ -VPATH = \ - $(srcdir) \ - $(srcdir)/ipc \ - $(NULL) +VPATH = @srcdir@ include $(DEPTH)/config/autoconf.mk include $(topsrcdir)/dom/dom-config.mk -# Add VPATH to LOCAL_INCLUDES so we are going to include the correct backend -# subdirectory (and the ipc one). -LOCAL_INCLUDES = $(VPATH:%=-I%) - include $(topsrcdir)/config/rules.mk -include $(topsrcdir)/ipc/chromium/chromium-config.mk + diff --git a/dom/telephony/Telephony.cpp b/dom/telephony/Telephony.cpp index 95749b0fb6f..430242e65c6 100644 --- a/dom/telephony/Telephony.cpp +++ b/dom/telephony/Telephony.cpp @@ -24,9 +24,10 @@ #include "TelephonyCall.h" #include "TelephonyCallGroup.h" +#define NS_RILCONTENTHELPER_CONTRACTID "@mozilla.org/ril/content-helper;1" + USING_TELEPHONY_NAMESPACE using namespace mozilla::dom; -using mozilla::ErrorResult; namespace { @@ -50,8 +51,6 @@ public: MOZ_ASSERT(mTelephony); } - virtual ~Listener() {} - void Disconnect() { @@ -112,7 +111,7 @@ Telephony::Shutdown() mListener->Disconnect(); if (mProvider) { - mProvider->UnregisterListener(mListener); + mProvider->UnregisterTelephonyMsg(mListener); mProvider = nullptr; } @@ -133,7 +132,7 @@ Telephony::Create(nsPIDOMWindow* aOwner, ErrorResult& aRv) NS_ASSERTION(aOwner, "Null owner!"); nsCOMPtr ril = - do_GetService(TELEPHONY_PROVIDER_CONTRACTID); + do_GetService(NS_RILCONTENTHELPER_CONTRACTID); if (!ril) { aRv.Throw(NS_ERROR_UNEXPECTED); return nullptr; @@ -166,7 +165,7 @@ Telephony::Create(nsPIDOMWindow* aOwner, ErrorResult& aRv) return nullptr; } - rv = ril->RegisterListener(telephony->mListener); + rv = ril->RegisterTelephonyMsg(telephony->mListener); if (NS_FAILED(rv)) { aRv.Throw(rv); return nullptr; @@ -223,7 +222,12 @@ Telephony::DialInternal(bool isEmergency, } } - nsresult rv = mProvider->Dial(aNumber, isEmergency); + nsresult rv; + if (isEmergency) { + rv = mProvider->DialEmergency(aNumber); + } else { + rv = mProvider->Dial(aNumber); + } if (NS_FAILED(rv)) { aRv.Throw(rv); return nullptr; @@ -587,7 +591,7 @@ NS_IMETHODIMP Telephony::EnumerateCallState(uint32_t aCallIndex, uint16_t aCallState, const nsAString& aNumber, bool aIsActive, bool aIsOutgoing, bool aIsEmergency, - bool aIsConference) + bool aIsConference, bool* aContinue) { nsRefPtr call; @@ -599,10 +603,12 @@ Telephony::EnumerateCallState(uint32_t aCallIndex, uint16_t aCallState, call = aIsConference ? mGroup->GetCall(aCallIndex) : GetCall(aCallIndex); if (call) { // We have the call either in mCalls or in mGroup. Skip it. + *aContinue = true; return NS_OK; } if (MoveCall(aCallIndex, aIsConference)) { + *aContinue = true; return NS_OK; } @@ -616,6 +622,7 @@ Telephony::EnumerateCallState(uint32_t aCallIndex, uint16_t aCallState, mCalls.Contains(call), "Should have auto-added new call!"); + *aContinue = true; return NS_OK; } diff --git a/dom/telephony/TelephonyCall.cpp b/dom/telephony/TelephonyCall.cpp index 23868f82964..f90389da17a 100644 --- a/dom/telephony/TelephonyCall.cpp +++ b/dom/telephony/TelephonyCall.cpp @@ -15,7 +15,6 @@ USING_TELEPHONY_NAMESPACE using namespace mozilla::dom; -using mozilla::ErrorResult; // static already_AddRefed diff --git a/dom/telephony/TelephonyCallGroup.cpp b/dom/telephony/TelephonyCallGroup.cpp index d5571a657ac..0e71643afba 100644 --- a/dom/telephony/TelephonyCallGroup.cpp +++ b/dom/telephony/TelephonyCallGroup.cpp @@ -13,7 +13,6 @@ USING_TELEPHONY_NAMESPACE using namespace mozilla::dom; -using mozilla::ErrorResult; TelephonyCallGroup::TelephonyCallGroup() : mCallState(nsITelephonyProvider::CALL_STATE_UNKNOWN) diff --git a/dom/telephony/TelephonyFactory.cpp b/dom/telephony/TelephonyFactory.cpp deleted file mode 100644 index cdb2b88dd86..00000000000 --- a/dom/telephony/TelephonyFactory.cpp +++ /dev/null @@ -1,23 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* 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/telephony/TelephonyFactory.h" -#include "nsServiceManagerUtils.h" -#include "nsXULAppAPI.h" -#include "TelephonyIPCProvider.h" - -USING_TELEPHONY_NAMESPACE - -/* static */ already_AddRefed -TelephonyFactory::CreateTelephonyProvider() -{ - nsCOMPtr provider; - - if (XRE_GetProcessType() == GeckoProcessType_Content) { - provider = new TelephonyIPCProvider(); - } - - return provider.forget(); -} diff --git a/dom/telephony/TelephonyFactory.h b/dom/telephony/TelephonyFactory.h deleted file mode 100644 index 07e3f779304..00000000000 --- a/dom/telephony/TelephonyFactory.h +++ /dev/null @@ -1,24 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* 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_telephony_TelephonyFactory_h -#define mozilla_dom_telephony_TelephonyFactory_h - -#include "nsCOMPtr.h" -#include "mozilla/dom/telephony/TelephonyCommon.h" - -class nsITelephonyProvider; - -BEGIN_TELEPHONY_NAMESPACE - -class TelephonyFactory -{ -public: - static already_AddRefed CreateTelephonyProvider(); -}; - -END_TELEPHONY_NAMESPACE - -#endif // mozilla_dom_telephony_TelephonyFactory_h diff --git a/dom/telephony/ipc/TelephonyChild.cpp b/dom/telephony/ipc/TelephonyChild.cpp deleted file mode 100644 index a4c85f241ca..00000000000 --- a/dom/telephony/ipc/TelephonyChild.cpp +++ /dev/null @@ -1,130 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* 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 "TelephonyChild.h" - -USING_TELEPHONY_NAMESPACE - -/******************************************************************************* - * TelephonyChild - ******************************************************************************/ - -TelephonyChild::TelephonyChild(nsITelephonyListener* aListener) - : mListener(aListener) -{ - MOZ_ASSERT(aListener); -} - -void -TelephonyChild::ActorDestroy(ActorDestroyReason aWhy) -{ - mListener = nullptr; -} - -PTelephonyRequestChild* -TelephonyChild::AllocPTelephonyRequestChild() -{ - MOZ_CRASH("Caller is supposed to manually construct a request!"); -} - -bool -TelephonyChild::DeallocPTelephonyRequestChild(PTelephonyRequestChild* aActor) -{ - delete aActor; - return true; -} - -bool -TelephonyChild::RecvNotifyCallError(const int32_t& aCallIndex, - const nsString& aError) -{ - MOZ_ASSERT(mListener); - - mListener->NotifyError(aCallIndex, aError); - return true; -} - -bool -TelephonyChild::RecvNotifyCallStateChanged(const IPCCallStateData& aData) -{ - MOZ_ASSERT(mListener); - - mListener->CallStateChanged(aData.callIndex(), - aData.callState(), - aData.number(), - aData.isActive(), - aData.isOutGoing(), - aData.isEmergency(), - aData.isConference()); - return true; -} - -bool -TelephonyChild::RecvNotifyCdmaCallWaiting(const nsString& aNumber) -{ - MOZ_ASSERT(mListener); - - mListener->NotifyCdmaCallWaiting(aNumber); - return true; -} - -bool -TelephonyChild::RecvNotifyConferenceCallStateChanged(const uint16_t& aCallState) -{ - MOZ_ASSERT(mListener); - - mListener->ConferenceCallStateChanged(aCallState); - return true; -} - -bool -TelephonyChild::RecvNotifySupplementaryService(const int32_t& aCallIndex, - const uint16_t& aNotification) -{ - MOZ_ASSERT(mListener); - - mListener->SupplementaryServiceNotification(aCallIndex, aNotification); - return true; -} - -/******************************************************************************* - * TelephonyRequestChild - ******************************************************************************/ - -TelephonyRequestChild::TelephonyRequestChild(nsITelephonyListener* aListener) - : mListener(aListener) -{ - MOZ_ASSERT(aListener); -} - -void -TelephonyRequestChild::ActorDestroy(ActorDestroyReason aWhy) -{ - mListener = nullptr; -} - -bool -TelephonyRequestChild::Recv__delete__() -{ - MOZ_ASSERT(mListener); - - mListener->EnumerateCallStateComplete(); - return true; -} - -bool -TelephonyRequestChild::RecvNotifyEnumerateCallState(const IPCCallStateData& aData) -{ - MOZ_ASSERT(mListener); - - mListener->EnumerateCallState(aData.callIndex(), - aData.callState(), - aData.number(), - aData.isActive(), - aData.isOutGoing(), - aData.isEmergency(), - aData.isConference()); - return true; -} diff --git a/dom/telephony/ipc/TelephonyChild.h b/dom/telephony/ipc/TelephonyChild.h deleted file mode 100644 index 91eb1f8d2a5..00000000000 --- a/dom/telephony/ipc/TelephonyChild.h +++ /dev/null @@ -1,77 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* 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_telephony_TelephonyChild_h -#define mozilla_dom_telephony_TelephonyChild_h - -#include "mozilla/dom/telephony/TelephonyCommon.h" -#include "mozilla/dom/telephony/PTelephonyChild.h" -#include "mozilla/dom/telephony/PTelephonyRequestChild.h" -#include "nsITelephonyProvider.h" - -BEGIN_TELEPHONY_NAMESPACE - -class TelephonyChild : public PTelephonyChild -{ -public: - TelephonyChild(nsITelephonyListener* aListener); - -protected: - virtual ~TelephonyChild() {} - - virtual void - ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE; - - virtual PTelephonyRequestChild* - AllocPTelephonyRequestChild() MOZ_OVERRIDE; - - virtual bool - DeallocPTelephonyRequestChild(PTelephonyRequestChild* aActor) MOZ_OVERRIDE; - - virtual bool - RecvNotifyCallError(const int32_t& aCallIndex, - const nsString& aError) MOZ_OVERRIDE; - - virtual bool - RecvNotifyCallStateChanged(const IPCCallStateData& aData) MOZ_OVERRIDE; - - virtual bool - RecvNotifyCdmaCallWaiting(const nsString& aNumber) MOZ_OVERRIDE; - - virtual bool - RecvNotifyConferenceCallStateChanged(const uint16_t& aCallState) MOZ_OVERRIDE; - - virtual bool - RecvNotifySupplementaryService(const int32_t& aCallIndex, - const uint16_t& aNotification) MOZ_OVERRIDE; - -private: - nsCOMPtr mListener; -}; - -class TelephonyRequestChild : public PTelephonyRequestChild -{ -public: - TelephonyRequestChild(nsITelephonyListener* aListener); - -protected: - virtual ~TelephonyRequestChild() {} - - virtual void - ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE; - - virtual bool - Recv__delete__() MOZ_OVERRIDE; - - virtual bool - RecvNotifyEnumerateCallState(const IPCCallStateData& aData) MOZ_OVERRIDE; - -private: - nsCOMPtr mListener; -}; - -END_TELEPHONY_NAMESPACE - -#endif // mozilla_dom_telephony_TelephonyChild_h diff --git a/dom/telephony/ipc/TelephonyIPCProvider.cpp b/dom/telephony/ipc/TelephonyIPCProvider.cpp deleted file mode 100644 index 93843d5e956..00000000000 --- a/dom/telephony/ipc/TelephonyIPCProvider.cpp +++ /dev/null @@ -1,258 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* 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/ContentChild.h" -#include "TelephonyChild.h" -#include "TelephonyIPCProvider.h" - -USING_TELEPHONY_NAMESPACE -using namespace mozilla::dom; - -NS_IMPL_ISUPPORTS2(TelephonyIPCProvider, - nsITelephonyProvider, - nsITelephonyListener) - -TelephonyIPCProvider::TelephonyIPCProvider() -{ - // Deallocated in ContentChild::DeallocPTelephonyChild(). - mPTelephonyChild = new TelephonyChild(this); - ContentChild::GetSingleton()->SendPTelephonyConstructor(mPTelephonyChild); -} - -TelephonyIPCProvider::~TelephonyIPCProvider() -{ - mPTelephonyChild->Send__delete__(mPTelephonyChild); - mPTelephonyChild = nullptr; -} - -/* - * Implementation of nsITelephonyProvider. - */ - -NS_IMETHODIMP -TelephonyIPCProvider::RegisterListener(nsITelephonyListener *aListener) -{ - MOZ_ASSERT(!mListeners.Contains(aListener)); - - // nsTArray doesn't fail. - mListeners.AppendElement(aListener); - - if (mListeners.Length() == 1) { - mPTelephonyChild->SendRegisterListener(); - } - return NS_OK; -} - -NS_IMETHODIMP -TelephonyIPCProvider::UnregisterListener(nsITelephonyListener *aListener) -{ - MOZ_ASSERT(mListeners.Contains(aListener)); - - // We always have the element here, so it can't fail. - mListeners.RemoveElement(aListener); - - if (!mListeners.Length()) { - mPTelephonyChild->SendUnregisterListener(); - } - return NS_OK; -} - -NS_IMETHODIMP -TelephonyIPCProvider::EnumerateCalls(nsITelephonyListener *aListener) -{ - // Life time of newly allocated TelephonyRequestChild instance is managed by - // IPDL itself. - TelephonyRequestChild* actor = new TelephonyRequestChild(aListener); - mPTelephonyChild->SendPTelephonyRequestConstructor(actor); - return NS_OK; -} - -NS_IMETHODIMP -TelephonyIPCProvider::Dial(const nsAString& aNumber, - bool aIsEmergency) -{ - mPTelephonyChild->SendDialCall(nsString(aNumber), aIsEmergency); - return NS_OK; -} - -NS_IMETHODIMP -TelephonyIPCProvider::HangUp(uint32_t aCallIndex) -{ - mPTelephonyChild->SendHangUpCall(aCallIndex); - return NS_OK; -} - -NS_IMETHODIMP -TelephonyIPCProvider::AnswerCall(uint32_t aCallIndex) -{ - mPTelephonyChild->SendAnswerCall(aCallIndex); - return NS_OK; -} - -NS_IMETHODIMP -TelephonyIPCProvider::RejectCall(uint32_t aCallIndex) -{ - mPTelephonyChild->SendRejectCall(aCallIndex); - return NS_OK; -} - -NS_IMETHODIMP -TelephonyIPCProvider::HoldCall(uint32_t aCallIndex) -{ - mPTelephonyChild->SendHoldCall(aCallIndex); - return NS_OK; -} - -NS_IMETHODIMP -TelephonyIPCProvider::ResumeCall(uint32_t aCallIndex) -{ - mPTelephonyChild->SendResumeCall(aCallIndex); - return NS_OK; -} - -NS_IMETHODIMP -TelephonyIPCProvider::ConferenceCall() -{ - mPTelephonyChild->SendConferenceCall(); - return NS_OK; -} - -NS_IMETHODIMP -TelephonyIPCProvider::SeparateCall(uint32_t aCallIndex) -{ - mPTelephonyChild->SendSeparateCall(aCallIndex); - return NS_OK; -} - -NS_IMETHODIMP -TelephonyIPCProvider::HoldConference() -{ - mPTelephonyChild->SendHoldConference(); - return NS_OK; -} - -NS_IMETHODIMP -TelephonyIPCProvider::ResumeConference() -{ - mPTelephonyChild->SendResumeConference(); - return NS_OK; -} - -NS_IMETHODIMP -TelephonyIPCProvider::StartTone(const nsAString& aDtmfChar) -{ - mPTelephonyChild->SendStartTone(nsString(aDtmfChar)); - return NS_OK; -} - -NS_IMETHODIMP -TelephonyIPCProvider::StopTone() -{ - mPTelephonyChild->SendStopTone(); - return NS_OK; -} - -NS_IMETHODIMP -TelephonyIPCProvider::GetMicrophoneMuted(bool* aMuted) -{ - mPTelephonyChild->SendGetMicrophoneMuted(aMuted); - return NS_OK; -} - -NS_IMETHODIMP -TelephonyIPCProvider::SetMicrophoneMuted(bool aMuted) -{ - mPTelephonyChild->SendSetMicrophoneMuted(aMuted); - return NS_OK; -} - -NS_IMETHODIMP -TelephonyIPCProvider::GetSpeakerEnabled(bool* aEnabled) -{ - mPTelephonyChild->SendGetSpeakerEnabled(aEnabled); - return NS_OK; -} - -NS_IMETHODIMP -TelephonyIPCProvider::SetSpeakerEnabled(bool aEnabled) -{ - mPTelephonyChild->SendSetSpeakerEnabled(aEnabled); - return NS_OK; -} - -// nsITelephonyListener - -NS_IMETHODIMP -TelephonyIPCProvider::CallStateChanged(uint32_t aCallIndex, - uint16_t aCallState, - const nsAString& aNumber, - bool aIsActive, - bool aIsOutgoing, - bool aIsEmergency, - bool aIsConference) -{ - for (uint32_t i = 0; i < mListeners.Length(); i++) { - mListeners[i]->CallStateChanged(aCallIndex, aCallState, aNumber, - aIsActive, aIsOutgoing, aIsEmergency, - aIsConference); - } - return NS_OK; -} - -NS_IMETHODIMP -TelephonyIPCProvider::ConferenceCallStateChanged(uint16_t aCallState) -{ - for (uint32_t i = 0; i < mListeners.Length(); i++) { - mListeners[i]->ConferenceCallStateChanged(aCallState); - } - return NS_OK; -} - -NS_IMETHODIMP -TelephonyIPCProvider::EnumerateCallStateComplete() -{ - MOZ_CRASH("Not a EnumerateCalls request!"); -} - -NS_IMETHODIMP -TelephonyIPCProvider::EnumerateCallState(uint32_t aCallIndex, - uint16_t aCallState, - const nsAString& aNumber, - bool aIsActive, - bool aIsOutgoing, - bool aIsEmergency, - bool aIsConference) -{ - MOZ_CRASH("Not a EnumerateCalls request!"); -} - -NS_IMETHODIMP -TelephonyIPCProvider::NotifyCdmaCallWaiting(const nsAString& aNumber) -{ - for (uint32_t i = 0; i < mListeners.Length(); i++) { - mListeners[i]->NotifyCdmaCallWaiting(aNumber); - } - return NS_OK; -} - -NS_IMETHODIMP -TelephonyIPCProvider::NotifyError(int32_t aCallIndex, - const nsAString& aError) -{ - for (uint32_t i = 0; i < mListeners.Length(); i++) { - mListeners[i]->NotifyError(aCallIndex, aError); - } - return NS_OK; -} - -NS_IMETHODIMP -TelephonyIPCProvider::SupplementaryServiceNotification(int32_t aCallIndex, - uint16_t aNotification) -{ - for (uint32_t i = 0; i < mListeners.Length(); i++) { - mListeners[i]->SupplementaryServiceNotification(aCallIndex, aNotification); - } - return NS_OK; -} diff --git a/dom/telephony/ipc/TelephonyIPCProvider.h b/dom/telephony/ipc/TelephonyIPCProvider.h deleted file mode 100644 index 928fd1d6567..00000000000 --- a/dom/telephony/ipc/TelephonyIPCProvider.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* 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_telephony_TelephonyIPCProvider_h -#define mozilla_dom_telephony_TelephonyIPCProvider_h - -#include "mozilla/dom/telephony/TelephonyCommon.h" -#include "mozilla/Attributes.h" -#include "nsITelephonyProvider.h" - -BEGIN_TELEPHONY_NAMESPACE - -class PTelephonyChild; - -class TelephonyIPCProvider MOZ_FINAL : public nsITelephonyProvider - , public nsITelephonyListener -{ -public: - NS_DECL_ISUPPORTS - NS_DECL_NSITELEPHONYPROVIDER - NS_DECL_NSITELEPHONYLISTENER - - TelephonyIPCProvider(); - -protected: - virtual ~TelephonyIPCProvider(); - -private: - nsTArray > mListeners; - PTelephonyChild* mPTelephonyChild; -}; - -END_TELEPHONY_NAMESPACE - -#endif // mozilla_dom_telephony_TelephonyIPCProvider_h diff --git a/dom/telephony/ipc/TelephonyParent.cpp b/dom/telephony/ipc/TelephonyParent.cpp deleted file mode 100644 index 3e82f86836e..00000000000 --- a/dom/telephony/ipc/TelephonyParent.cpp +++ /dev/null @@ -1,448 +0,0 @@ -/* -*- Mode: C++ tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* 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 "TelephonyParent.h" - -USING_TELEPHONY_NAMESPACE - -/******************************************************************************* - * TelephonyParent - ******************************************************************************/ - -NS_IMPL_ISUPPORTS1(TelephonyParent, nsITelephonyListener) - -TelephonyParent::TelephonyParent() - : mActorDestroyed(false) - , mRegistered(false) -{ -} - -void -TelephonyParent::ActorDestroy(ActorDestroyReason why) -{ - // The child process could die before this asynchronous notification, in which - // case ActorDestroy() was called and mActorDestroyed is set to true. Return - // an error here to avoid sending a message to the dead process. - mActorDestroyed = true; - - // Try to unregister listener if we're still registered. - RecvUnregisterListener(); -} - -bool -TelephonyParent::RecvPTelephonyRequestConstructor(PTelephonyRequestParent* aActor) -{ - TelephonyRequestParent* actor = static_cast(aActor); - - return actor->DoRequest(); -} - -PTelephonyRequestParent* -TelephonyParent::AllocPTelephonyRequestParent() -{ - TelephonyRequestParent* actor = new TelephonyRequestParent(); - // Add an extra ref for IPDL. Will be released in - // TelephonyParent::DeallocPTelephonyRequestParent(). - NS_ADDREF(actor); - - return actor; -} - -bool -TelephonyParent::DeallocPTelephonyRequestParent(PTelephonyRequestParent* aActor) -{ - // TelephonyRequestParent is refcounted, must not be freed manually. - static_cast(aActor)->Release(); - return true; -} - -bool -TelephonyParent::Recv__delete__() -{ - return true; // Unregister listener in TelephonyParent::ActorDestroy(). -} - -bool -TelephonyParent::RecvRegisterListener() -{ - NS_ENSURE_TRUE(!mRegistered, true); - - nsCOMPtr provider = - do_GetService(TELEPHONY_PROVIDER_CONTRACTID); - NS_ENSURE_TRUE(provider, true); - - mRegistered = NS_SUCCEEDED(provider->RegisterListener(this)); - return true; -} - -bool -TelephonyParent::RecvUnregisterListener() -{ - NS_ENSURE_TRUE(mRegistered, true); - - nsCOMPtr provider = - do_GetService(TELEPHONY_PROVIDER_CONTRACTID); - NS_ENSURE_TRUE(provider, true); - - mRegistered = !NS_SUCCEEDED(provider->UnregisterListener(this)); - return true; -} - -bool -TelephonyParent::RecvDialCall(const nsString& aNumber, - const bool& aIsEmergency) -{ - nsCOMPtr provider = - do_GetService(TELEPHONY_PROVIDER_CONTRACTID); - NS_ENSURE_TRUE(provider, true); - - provider->Dial(aNumber, aIsEmergency); - return true; -} - -bool -TelephonyParent::RecvHangUpCall(const uint32_t& aCallIndex) -{ - nsCOMPtr provider = - do_GetService(TELEPHONY_PROVIDER_CONTRACTID); - NS_ENSURE_TRUE(provider, true); - - provider->HangUp(aCallIndex); - return true; -} - -bool -TelephonyParent::RecvAnswerCall(const uint32_t& aCallIndex) -{ - nsCOMPtr provider = - do_GetService(TELEPHONY_PROVIDER_CONTRACTID); - NS_ENSURE_TRUE(provider, true); - - provider->AnswerCall(aCallIndex); - return true; -} - -bool -TelephonyParent::RecvRejectCall(const uint32_t& aCallIndex) -{ - nsCOMPtr provider = - do_GetService(TELEPHONY_PROVIDER_CONTRACTID); - NS_ENSURE_TRUE(provider, true); - - provider->RejectCall(aCallIndex); - return true; -} - -bool -TelephonyParent::RecvHoldCall(const uint32_t& aCallIndex) -{ - nsCOMPtr provider = - do_GetService(TELEPHONY_PROVIDER_CONTRACTID); - NS_ENSURE_TRUE(provider, true); - - provider->HoldCall(aCallIndex); - return true; -} - -bool -TelephonyParent::RecvResumeCall(const uint32_t& aCallIndex) -{ - nsCOMPtr provider = - do_GetService(TELEPHONY_PROVIDER_CONTRACTID); - NS_ENSURE_TRUE(provider, true); - - provider->ResumeCall(aCallIndex); - return true; -} - -bool -TelephonyParent::RecvConferenceCall() -{ - nsCOMPtr provider = - do_GetService(TELEPHONY_PROVIDER_CONTRACTID); - NS_ENSURE_TRUE(provider, true); - - provider->ConferenceCall(); - return true; -} - -bool -TelephonyParent::RecvSeparateCall(const uint32_t& aCallState) -{ - nsCOMPtr provider = - do_GetService(TELEPHONY_PROVIDER_CONTRACTID); - NS_ENSURE_TRUE(provider, true); - - provider->SeparateCall(aCallState); - return true; -} - -bool -TelephonyParent::RecvHoldConference() -{ - nsCOMPtr provider = - do_GetService(TELEPHONY_PROVIDER_CONTRACTID); - NS_ENSURE_TRUE(provider, true); - - provider->HoldConference(); - return true; -} - -bool -TelephonyParent::RecvResumeConference() -{ - nsCOMPtr provider = - do_GetService(TELEPHONY_PROVIDER_CONTRACTID); - NS_ENSURE_TRUE(provider, true); - - provider->ResumeConference(); - return true; -} - -bool -TelephonyParent::RecvStartTone(const nsString& aTone) -{ - nsCOMPtr provider = - do_GetService(TELEPHONY_PROVIDER_CONTRACTID); - NS_ENSURE_TRUE(provider, true); - - provider->StartTone(aTone); - return true; -} - -bool -TelephonyParent::RecvStopTone() -{ - nsCOMPtr provider = - do_GetService(TELEPHONY_PROVIDER_CONTRACTID); - NS_ENSURE_TRUE(provider, true); - - provider->StopTone(); - return true; -} - -bool -TelephonyParent::RecvGetMicrophoneMuted(bool* aMuted) -{ - *aMuted = false; - - nsCOMPtr provider = - do_GetService(TELEPHONY_PROVIDER_CONTRACTID); - NS_ENSURE_TRUE(provider, true); - - provider->GetMicrophoneMuted(aMuted); - return true; -} - -bool -TelephonyParent::RecvSetMicrophoneMuted(const bool& aMuted) -{ - nsCOMPtr provider = - do_GetService(TELEPHONY_PROVIDER_CONTRACTID); - NS_ENSURE_TRUE(provider, true); - - provider->SetMicrophoneMuted(aMuted); - return true; -} - -bool -TelephonyParent::RecvGetSpeakerEnabled(bool* aEnabled) -{ - *aEnabled = false; - - nsCOMPtr provider = - do_GetService(TELEPHONY_PROVIDER_CONTRACTID); - NS_ENSURE_TRUE(provider, true); - - provider->GetSpeakerEnabled(aEnabled); - return true; -} - -bool -TelephonyParent::RecvSetSpeakerEnabled(const bool& aEnabled) -{ - nsCOMPtr provider = - do_GetService(TELEPHONY_PROVIDER_CONTRACTID); - NS_ENSURE_TRUE(provider, true); - - provider->SetSpeakerEnabled(aEnabled); - return true; -} - -// nsITelephonyListener - -NS_IMETHODIMP -TelephonyParent::CallStateChanged(uint32_t aCallIndex, - uint16_t aCallState, - const nsAString& aNumber, - bool aIsActive, - bool aIsOutgoing, - bool aIsEmergency, - bool aIsConference) -{ - NS_ENSURE_TRUE(!mActorDestroyed, NS_ERROR_FAILURE); - - IPCCallStateData data(aCallIndex, aCallState, nsString(aNumber), aIsActive, - aIsOutgoing, aIsEmergency, aIsConference); - return SendNotifyCallStateChanged(data) ? NS_OK : NS_ERROR_FAILURE; -} - -NS_IMETHODIMP -TelephonyParent::ConferenceCallStateChanged(uint16_t aCallState) -{ - NS_ENSURE_TRUE(!mActorDestroyed, NS_ERROR_FAILURE); - - return SendNotifyConferenceCallStateChanged(aCallState) ? NS_OK - : NS_ERROR_FAILURE; -} - -NS_IMETHODIMP -TelephonyParent::EnumerateCallStateComplete() -{ - MOZ_CRASH("Not a EnumerateCalls request!"); -} - -NS_IMETHODIMP -TelephonyParent::EnumerateCallState(uint32_t aCallIndex, - uint16_t aCallState, - const nsAString& aNumber, - bool aIsActive, - bool aIsOutgoing, - bool aIsEmergency, - bool aIsConference) -{ - MOZ_CRASH("Not a EnumerateCalls request!"); -} - -NS_IMETHODIMP -TelephonyParent::NotifyCdmaCallWaiting(const nsAString& aNumber) -{ - NS_ENSURE_TRUE(!mActorDestroyed, NS_ERROR_FAILURE); - - return SendNotifyCdmaCallWaiting(nsString(aNumber)) ? NS_OK - : NS_ERROR_FAILURE; -} - -NS_IMETHODIMP -TelephonyParent::NotifyError(int32_t aCallIndex, - const nsAString& aError) -{ - NS_ENSURE_TRUE(!mActorDestroyed, NS_ERROR_FAILURE); - - return SendNotifyCallError(aCallIndex, nsString(aError)) ? NS_OK - : NS_ERROR_FAILURE; -} - -NS_IMETHODIMP -TelephonyParent::SupplementaryServiceNotification(int32_t aCallIndex, - uint16_t aNotification) -{ - NS_ENSURE_TRUE(!mActorDestroyed, NS_ERROR_FAILURE); - - return SendNotifySupplementaryService(aCallIndex, aNotification) - ? NS_OK : NS_ERROR_FAILURE; -} - -/******************************************************************************* - * TelephonyRequestParent - ******************************************************************************/ - -NS_IMPL_ISUPPORTS1(TelephonyRequestParent, nsITelephonyListener) - -TelephonyRequestParent::TelephonyRequestParent() - : mActorDestroyed(false) -{ -} - -void -TelephonyRequestParent::ActorDestroy(ActorDestroyReason why) -{ - // The child process could die before this asynchronous notification, in which - // case ActorDestroy() was called and mActorDestroyed is set to true. Return - // an error here to avoid sending a message to the dead process. - mActorDestroyed = true; -} - -bool -TelephonyRequestParent::DoRequest() -{ - nsresult rv = NS_ERROR_FAILURE; - - nsCOMPtr provider = - do_GetService(TELEPHONY_PROVIDER_CONTRACTID); - if (provider) { - rv = provider->EnumerateCalls(this); - } - - if (NS_FAILED(rv)) { - return NS_SUCCEEDED(EnumerateCallStateComplete()); - } - - return true; -} - -// nsITelephonyListener - -NS_IMETHODIMP -TelephonyRequestParent::CallStateChanged(uint32_t aCallIndex, - uint16_t aCallState, - const nsAString& aNumber, - bool aIsActive, - bool aIsOutgoing, - bool aIsEmergency, - bool aIsConference) -{ - MOZ_CRASH("Not a TelephonyParent!"); -} - -NS_IMETHODIMP -TelephonyRequestParent::ConferenceCallStateChanged(uint16_t aCallState) -{ - MOZ_CRASH("Not a TelephonyParent!"); -} - -NS_IMETHODIMP -TelephonyRequestParent::EnumerateCallStateComplete() -{ - NS_ENSURE_TRUE(!mActorDestroyed, NS_ERROR_FAILURE); - - return Send__delete__(this) ? NS_OK : NS_ERROR_FAILURE; -} - -NS_IMETHODIMP -TelephonyRequestParent::EnumerateCallState(uint32_t aCallIndex, - uint16_t aCallState, - const nsAString& aNumber, - bool aIsActive, - bool aIsOutgoing, - bool aIsEmergency, - bool aIsConference) -{ - NS_ENSURE_TRUE(!mActorDestroyed, NS_ERROR_FAILURE); - - IPCCallStateData data(aCallIndex, aCallState, nsString(aNumber), aIsActive, - aIsOutgoing, aIsEmergency, aIsConference); - return SendNotifyEnumerateCallState(data) ? NS_OK : NS_ERROR_FAILURE; -} - -NS_IMETHODIMP -TelephonyRequestParent::NotifyCdmaCallWaiting(const nsAString& aNumber) -{ - MOZ_CRASH("Not a TelephonyParent!"); -} - -NS_IMETHODIMP -TelephonyRequestParent::NotifyError(int32_t aCallIndex, - const nsAString& aError) -{ - MOZ_CRASH("Not a TelephonyParent!"); -} - -NS_IMETHODIMP -TelephonyRequestParent::SupplementaryServiceNotification(int32_t aCallIndex, - uint16_t aNotification) -{ - MOZ_CRASH("Not a TelephonyParent!"); -} diff --git a/dom/telephony/ipc/TelephonyParent.h b/dom/telephony/ipc/TelephonyParent.h deleted file mode 100644 index ac508c264be..00000000000 --- a/dom/telephony/ipc/TelephonyParent.h +++ /dev/null @@ -1,128 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* 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_telephony_TelephonyParent_h -#define mozilla_dom_telephony_TelephonyParent_h - -#include "mozilla/dom/telephony/TelephonyCommon.h" -#include "mozilla/dom/telephony/PTelephonyParent.h" -#include "mozilla/dom/telephony/PTelephonyRequestParent.h" -#include "nsITelephonyProvider.h" - -BEGIN_TELEPHONY_NAMESPACE - -class TelephonyParent : public PTelephonyParent - , public nsITelephonyListener -{ -public: - NS_DECL_ISUPPORTS - NS_DECL_NSITELEPHONYLISTENER - - TelephonyParent(); - -protected: - virtual ~TelephonyParent() {} - - virtual void - ActorDestroy(ActorDestroyReason why); - - virtual bool - RecvPTelephonyRequestConstructor(PTelephonyRequestParent* aActor) MOZ_OVERRIDE; - - virtual PTelephonyRequestParent* - AllocPTelephonyRequestParent() MOZ_OVERRIDE; - - virtual bool - DeallocPTelephonyRequestParent(PTelephonyRequestParent* aActor) MOZ_OVERRIDE; - - virtual bool - Recv__delete__() MOZ_OVERRIDE; - - virtual bool - RecvRegisterListener() MOZ_OVERRIDE; - - virtual bool - RecvUnregisterListener() MOZ_OVERRIDE; - - virtual bool - RecvDialCall(const nsString& aNumber, - const bool& aIsEmergency) MOZ_OVERRIDE; - - virtual bool - RecvHangUpCall(const uint32_t& aCallIndex) MOZ_OVERRIDE; - - virtual bool - RecvAnswerCall(const uint32_t& aCallIndex) MOZ_OVERRIDE; - - virtual bool - RecvRejectCall(const uint32_t& aCallIndex) MOZ_OVERRIDE; - - virtual bool - RecvHoldCall(const uint32_t& aCallIndex) MOZ_OVERRIDE; - - virtual bool - RecvResumeCall(const uint32_t& aCallIndex) MOZ_OVERRIDE; - - virtual bool - RecvConferenceCall() MOZ_OVERRIDE; - - virtual bool - RecvSeparateCall(const uint32_t& callIndex) MOZ_OVERRIDE; - - virtual bool - RecvHoldConference() MOZ_OVERRIDE; - - virtual bool - RecvResumeConference() MOZ_OVERRIDE; - - virtual bool - RecvStartTone(const nsString& aTone) MOZ_OVERRIDE; - - virtual bool - RecvStopTone() MOZ_OVERRIDE; - - virtual bool - RecvGetMicrophoneMuted(bool* aMuted) MOZ_OVERRIDE; - - virtual bool - RecvSetMicrophoneMuted(const bool& aMuted) MOZ_OVERRIDE; - - virtual bool - RecvGetSpeakerEnabled(bool* aEnabled) MOZ_OVERRIDE; - - virtual bool - RecvSetSpeakerEnabled(const bool& aEnabled) MOZ_OVERRIDE; - -private: - bool mActorDestroyed; - bool mRegistered; -}; - -class TelephonyRequestParent : public PTelephonyRequestParent - , public nsITelephonyListener -{ - friend class TelephonyParent; - -public: - NS_DECL_ISUPPORTS - NS_DECL_NSITELEPHONYLISTENER - -protected: - TelephonyRequestParent(); - virtual ~TelephonyRequestParent() {} - - virtual void - ActorDestroy(ActorDestroyReason why); - -private: - bool mActorDestroyed; - - bool - DoRequest(); -}; - -END_TELEPHONY_NAMESPACE - -#endif /* mozilla_dom_telephony_TelephonyParent_h */ diff --git a/dom/telephony/moz.build b/dom/telephony/moz.build index e15bf63810e..8910a24c887 100644 --- a/dom/telephony/moz.build +++ b/dom/telephony/moz.build @@ -12,34 +12,12 @@ XPIDL_MODULE = 'dom_telephony' MODULE = 'dom' -EXPORTS.mozilla.dom.telephony += [ - 'CallEvent.h', - 'CallsList.h', - 'Telephony.h', - 'TelephonyCall.h', - 'TelephonyCallGroup.h', - 'TelephonyCommon.h', - 'TelephonyFactory.h', - 'ipc/TelephonyChild.h', - 'ipc/TelephonyParent.h', -] - CPP_SOURCES += [ 'CallEvent.cpp', 'CallsList.cpp', 'Telephony.cpp', 'TelephonyCall.cpp', 'TelephonyCallGroup.cpp', - 'TelephonyChild.cpp', - 'TelephonyFactory.cpp', - 'TelephonyIPCProvider.cpp', - 'TelephonyParent.cpp', -] - -IPDL_SOURCES += [ - 'ipc/PTelephony.ipdl', - 'ipc/PTelephonyRequest.ipdl', - 'ipc/TelephonyTypes.ipdlh' ] FAIL_ON_WARNINGS = True @@ -47,3 +25,4 @@ FAIL_ON_WARNINGS = True LIBXUL_LIBRARY = True LIBRARY_NAME = 'domtelephony_s' + diff --git a/dom/webidl/WebIDL.mk b/dom/webidl/WebIDL.mk index b5d7dafa936..f18ce2bddd4 100644 --- a/dom/webidl/WebIDL.mk +++ b/dom/webidl/WebIDL.mk @@ -34,8 +34,6 @@ webidl_files = \ BiquadFilterNode.webidl \ Blob.webidl \ BrowserElementDictionaries.webidl \ - CallEvent.webidl \ - CallsList.webidl \ CameraControl.webidl \ CameraManager.webidl \ CanvasRenderingContext2D.webidl \ @@ -361,9 +359,6 @@ webidl_files = \ SVGViewElement.webidl \ SVGZoomAndPan.webidl \ SVGZoomEvent.webidl \ - Telephony.webidl \ - TelephonyCall.webidl \ - TelephonyCallGroup.webidl \ Text.webidl \ TextDecoder.webidl \ TextEncoder.webidl \ @@ -450,8 +445,12 @@ endif ifdef MOZ_B2G_RIL webidl_files += \ + CallsList.webidl \ MozStkCommandEvent.webidl \ MozVoicemail.webidl \ + Telephony.webidl \ + TelephonyCall.webidl \ + TelephonyCallGroup.webidl \ $(NULL) endif @@ -496,6 +495,7 @@ endif ifdef MOZ_B2G_RIL webidl_files += \ + CallEvent.webidl \ CFStateChangeEvent.webidl \ DataErrorEvent.webidl \ IccCardLockErrorEvent.webidl \ diff --git a/layout/build/Makefile.in b/layout/build/Makefile.in index baf892dab18..0db2d8428cf 100644 --- a/layout/build/Makefile.in +++ b/layout/build/Makefile.in @@ -66,7 +66,6 @@ SHARED_LIBRARY_LIBS = \ $(DEPTH)/dom/promise/$(LIB_PREFIX)dompromise_s.$(LIB_SUFFIX) \ $(DEPTH)/dom/src/notification/$(LIB_PREFIX)jsdomnotification_s.$(LIB_SUFFIX) \ $(DEPTH)/dom/system/$(LIB_PREFIX)domsystem_s.$(LIB_SUFFIX) \ - $(DEPTH)/dom/telephony/$(LIB_PREFIX)domtelephony_s.$(LIB_SUFFIX) \ $(DEPTH)/dom/workers/$(LIB_PREFIX)domworkers_s.$(LIB_SUFFIX) \ $(DEPTH)/dom/indexedDB/$(LIB_PREFIX)dom_indexeddb_s.$(LIB_SUFFIX) \ $(DEPTH)/dom/indexedDB/ipc/$(LIB_PREFIX)dom_indexeddb_ipc_s.$(LIB_SUFFIX) \ @@ -137,6 +136,7 @@ SHARED_LIBRARY_LIBS += $(DEPTH)/dom/camera/$(LIB_PREFIX)domcamera_s.$(LIB_SUFFIX ifdef MOZ_B2G_RIL #{ SHARED_LIBRARY_LIBS += \ $(DEPTH)/dom/system/gonk/$(LIB_PREFIX)domsystemgonk_s.$(LIB_SUFFIX) \ + $(DEPTH)/dom/telephony/$(LIB_PREFIX)domtelephony_s.$(LIB_SUFFIX) \ $(DEPTH)/dom/icc/src/$(LIB_PREFIX)dom_icc_s.$(LIB_SUFFIX) \ $(DEPTH)/dom/cellbroadcast/src/$(LIB_PREFIX)dom_cellbroadcast_s.$(LIB_SUFFIX) \ $(DEPTH)/dom/voicemail/$(LIB_PREFIX)domvoicemail_s.$(LIB_SUFFIX) \ diff --git a/layout/build/nsLayoutModule.cpp b/layout/build/nsLayoutModule.cpp index 6278d4b8352..1d55dd37446 100644 --- a/layout/build/nsLayoutModule.cpp +++ b/layout/build/nsLayoutModule.cpp @@ -230,9 +230,6 @@ static void Shutdown(); #include "mozilla/dom/alarm/AlarmHalService.h" #include "mozilla/dom/time/TimeService.h" -#include "mozilla/dom/telephony/TelephonyFactory.h" -#include "nsITelephonyProvider.h" - #ifdef MOZ_WIDGET_GONK #include "GonkGPSGeolocationProvider.h" #endif @@ -241,7 +238,6 @@ static void Shutdown(); using namespace mozilla; using namespace mozilla::dom; using namespace mozilla::dom::mobilemessage; -using namespace mozilla::dom::telephony; using mozilla::dom::alarm::AlarmHalService; using mozilla::dom::indexedDB::IndexedDatabaseManager; using mozilla::dom::power::PowerManagerService; @@ -342,8 +338,6 @@ NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsVolumeService, #endif NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsIMediaManagerService, MediaManager::GetInstance) -NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsITelephonyProvider, - TelephonyFactory::CreateTelephonyProvider) //----------------------------------------------------------------------------- @@ -817,7 +811,6 @@ NS_DEFINE_NAMED_CID(NS_SYNTHVOICEREGISTRY_CID); #ifdef ACCESSIBILITY NS_DEFINE_NAMED_CID(NS_ACCESSIBILITY_SERVICE_CID); #endif -NS_DEFINE_NAMED_CID(TELEPHONY_PROVIDER_CID); static nsresult CreateWindowCommandTableConstructor(nsISupports *aOuter, @@ -1100,7 +1093,6 @@ static const mozilla::Module::CIDEntry kLayoutCIDs[] = { #ifdef ACCESSIBILITY { &kNS_ACCESSIBILITY_SERVICE_CID, false, NULL, CreateA11yService }, #endif - { &kTELEPHONY_PROVIDER_CID, false, NULL, nsITelephonyProviderConstructor }, { NULL } }; @@ -1256,7 +1248,6 @@ static const mozilla::Module::ContractIDEntry kLayoutContracts[] = { { "@mozilla.org/accessibilityService;1", &kNS_ACCESSIBILITY_SERVICE_CID }, { "@mozilla.org/accessibleRetrieval;1", &kNS_ACCESSIBILITY_SERVICE_CID }, #endif - { TELEPHONY_PROVIDER_CONTRACTID, &kTELEPHONY_PROVIDER_CID }, { NULL } }; From a0c2c59d2c8ac2e4e473e2efd49ffc227afcabb3 Mon Sep 17 00:00:00 2001 From: Ed Morley Date: Wed, 4 Sep 2013 11:51:30 +0100 Subject: [PATCH 025/171] Backed out changeset 9a72765987b8 (bug 864485) for mochitest-3 failures on a CLOSED TREE --- dom/ipc/PContent.ipdl | 4 -- dom/telephony/ipc/PTelephony.ipdl | 83 ------------------------ dom/telephony/ipc/PTelephonyRequest.ipdl | 30 --------- dom/telephony/ipc/TelephonyTypes.ipdlh | 24 ------- dom/telephony/nsITelephonyProvider.idl | 34 ++++------ 5 files changed, 14 insertions(+), 161 deletions(-) delete mode 100644 dom/telephony/ipc/PTelephony.ipdl delete mode 100644 dom/telephony/ipc/PTelephonyRequest.ipdl delete mode 100644 dom/telephony/ipc/TelephonyTypes.ipdlh diff --git a/dom/ipc/PContent.ipdl b/dom/ipc/PContent.ipdl index a4f5e80d1e1..eb706f624d4 100644 --- a/dom/ipc/PContent.ipdl +++ b/dom/ipc/PContent.ipdl @@ -20,7 +20,6 @@ include protocol PNecko; include protocol PSms; include protocol PSpeechSynthesis; include protocol PStorage; -include protocol PTelephony; include protocol PTestShell; include protocol PJavaScript; include DOMTypes; @@ -198,7 +197,6 @@ rpc protocol PContent manages PSms; manages PSpeechSynthesis; manages PStorage; - manages PTelephony; manages PTestShell; manages PJavaScript; @@ -355,8 +353,6 @@ parent: PStorage(); - PTelephony(); - PBluetooth(); PFMRadio(); diff --git a/dom/telephony/ipc/PTelephony.ipdl b/dom/telephony/ipc/PTelephony.ipdl deleted file mode 100644 index d82044401ef..00000000000 --- a/dom/telephony/ipc/PTelephony.ipdl +++ /dev/null @@ -1,83 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set sw=2 ts=8 et ft=cpp : */ -/* 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 protocol PContent; -include protocol PTelephonyRequest; -include TelephonyTypes; - -namespace mozilla { -namespace dom { -namespace telephony { - -sync protocol PTelephony { - manager PContent; - manages PTelephonyRequest; - -child: - NotifyCallError(int32_t aCallIndex, nsString aError); - - NotifyCallStateChanged(IPCCallStateData aData); - - NotifyCdmaCallWaiting(nsString aNumber); - - NotifyConferenceCallStateChanged(uint16_t aCallState); - - NotifySupplementaryService(int32_t aCallIndex, uint16_t aNotification); - -parent: - /** - * Sent when the child no longer needs to use PTelephony. - */ - __delete__(); - - /** - * Sent when the child makes an asynchronous request to the parent. It's - * currently only for request call enumeration. - */ - PTelephonyRequest(); - - RegisterListener(); - - UnregisterListener(); - - DialCall(nsString aNumber, bool aIsEmergency); - - HangUpCall(uint32_t aCallIndex); - - AnswerCall(uint32_t aCallIndex); - - RejectCall(uint32_t aCallIndex); - - HoldCall(uint32_t aCallIndex); - - ResumeCall(uint32_t aCallIndex); - - ConferenceCall(); - - SeparateCall(uint32_t aCallIndex); - - HoldConference(); - - ResumeConference(); - - StartTone(nsString aTone); - - StopTone(); - - sync GetMicrophoneMuted() - returns (bool aMuted); - - SetMicrophoneMuted(bool aMuted); - - sync GetSpeakerEnabled() - returns (bool aEnabled); - - SetSpeakerEnabled(bool aEnabled); -}; - -} /* namespace telephony */ -} /* namespace dom */ -} /* namespace mozilla */ diff --git a/dom/telephony/ipc/PTelephonyRequest.ipdl b/dom/telephony/ipc/PTelephonyRequest.ipdl deleted file mode 100644 index 05f708ffc6a..00000000000 --- a/dom/telephony/ipc/PTelephonyRequest.ipdl +++ /dev/null @@ -1,30 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* vim: set ts=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 protocol PTelephony; -include TelephonyTypes; - -namespace mozilla { -namespace dom { -namespace telephony { - -protocol PTelephonyRequest -{ - manager PTelephony; - -child: - NotifyEnumerateCallState(IPCCallStateData aData); - - /** - * Sent when the asynchronous request has completed. It's currently only for - * request call enumeration. - */ - __delete__(); -}; - -} /* namespace telephony */ -} /* namespace dom */ -} /* namespace mozilla */ diff --git a/dom/telephony/ipc/TelephonyTypes.ipdlh b/dom/telephony/ipc/TelephonyTypes.ipdlh deleted file mode 100644 index 5a46e4ace56..00000000000 --- a/dom/telephony/ipc/TelephonyTypes.ipdlh +++ /dev/null @@ -1,24 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* vim: set ts=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/. */ - -namespace mozilla { -namespace dom { -namespace telephony { - -struct IPCCallStateData -{ - uint32_t callIndex; - uint16_t callState; - nsString number; - bool isActive; - bool isOutGoing; - bool isEmergency; - bool isConference; -}; - -} /* namespace telephony */ -} /* namespace dom */ -} /* namespace mozilla */ diff --git a/dom/telephony/nsITelephonyProvider.idl b/dom/telephony/nsITelephonyProvider.idl index d8cb28adc70..8076ac3c5a4 100644 --- a/dom/telephony/nsITelephonyProvider.idl +++ b/dom/telephony/nsITelephonyProvider.idl @@ -4,7 +4,7 @@ #include "nsISupports.idl" -[scriptable, uuid(3aa42e77-7c2b-43a1-b105-7be094b0817a)] +[scriptable, uuid(a5818719-e1b6-4fdc-8551-006055fa9996)] interface nsITelephonyListener : nsISupports { /** @@ -67,14 +67,15 @@ interface nsITelephonyListener : nsISupports * Indicates whether this call is outgoing or incoming. * @param isConference * Indicates whether this call is a conference call. + * @return true to continue enumeration or false to cancel. */ - void enumerateCallState(in unsigned long callIndex, - in unsigned short callState, - in AString number, - in boolean isActive, - in boolean isOutgoing, - in boolean isEmergency, - in boolean isConference); + boolean enumerateCallState(in unsigned long callIndex, + in unsigned short callState, + in AString number, + in boolean isActive, + in boolean isOutgoing, + in boolean isEmergency, + in boolean isConference); /** * Notify when RIL receives supplementary service notification. @@ -107,18 +108,11 @@ interface nsITelephonyListener : nsISupports void notifyCdmaCallWaiting(in AString number); }; -%{C++ -#define TELEPHONY_PROVIDER_CID \ - { 0x9cf8aa52, 0x7c1c, 0x4cde, { 0x97, 0x4e, 0xed, 0x2a, 0xa0, 0xe7, 0x35, 0xfa } } -#define TELEPHONY_PROVIDER_CONTRACTID \ - "@mozilla.org/telephony/telephonyprovider;1" -%} - /** * XPCOM component (in the content process) that provides the telephony * information. */ -[scriptable, uuid(effca006-1ca8-47f7-9bab-1323f90a14ec)] +[scriptable, uuid(45a2f856-4e07-499a-94c6-624f90c3345b)] interface nsITelephonyProvider : nsISupports { const unsigned short CALL_STATE_UNKNOWN = 0; @@ -141,8 +135,8 @@ interface nsITelephonyProvider : nsISupports * RadioInterfaceLayer in the chrome process. Only a content process that has * the 'telephony' permission is allowed to register. */ - void registerListener(in nsITelephonyListener listener); - void unregisterListener(in nsITelephonyListener listener); + void registerTelephonyMsg(in nsITelephonyListener listener); + void unregisterTelephonyMsg(in nsITelephonyListener listener); /** * Will continue calling listener.enumerateCallState until the listener @@ -153,8 +147,8 @@ interface nsITelephonyProvider : nsISupports /** * Functionality for making and managing phone calls. */ - void dial(in DOMString number, - in boolean isEmergency); + void dial(in DOMString number); + void dialEmergency(in DOMString number); void hangUp(in unsigned long callIndex); void startTone(in DOMString dtmfChar); From 6fdd48f7e63ff4b52543aa6489a3fcba721d0ea9 Mon Sep 17 00:00:00 2001 From: Gaia Pushbot Date: Wed, 4 Sep 2013 03:55:24 -0700 Subject: [PATCH 026/171] Bumping gaia.json for 2 gaia-central revision(s) ======== https://hg.mozilla.org/integration/gaia-central/rev/6e4866e3453f Author: Cristian Rodriguez Desc: Merge pull request #11866 from mcjimenez/bug893800_2 Bug 893800 - Add a way to insert an app on a given position ======== https://hg.mozilla.org/integration/gaia-central/rev/4c23771ec053 Author: Carmen Jimenez Cabezas Desc: Bug 893800 - Add a way to insert an app on a given position --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index f4d999f9b49..32755bd481e 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,4 +1,4 @@ { - "revision": "ddbce8d8bd5a2f49c29531e7af636fce5266b0d5", + "revision": "6e4866e3453f231d1089b95d7010101b99b2c18b", "repo_path": "/integration/gaia-central" } From bb908f496f5f1bc1afabda7e7ad9f6810264a7e3 Mon Sep 17 00:00:00 2001 From: Vicamo Yang Date: Wed, 4 Sep 2013 18:58:23 +0800 Subject: [PATCH 027/171] Bug 911341 - 1/2: B2G RIL - refactor worker_buf. r=yoshi --- dom/system/gonk/ril_worker.js | 13 +- dom/system/gonk/worker_buf.js | 1230 ++++++++++++++++----------------- 2 files changed, 624 insertions(+), 619 deletions(-) diff --git a/dom/system/gonk/ril_worker.js b/dom/system/gonk/ril_worker.js index 7dc7447a814..6138a05e217 100644 --- a/dom/system/gonk/ril_worker.js +++ b/dom/system/gonk/ril_worker.js @@ -96,7 +96,15 @@ let RILQUIRKS_HAVE_QUERY_ICC_LOCK_RETRY_COUNT = libcutils.property_get("ro.moz.r // Marker object. let PENDING_NETWORK_TYPE = {}; -let Buf = require("resource://gre/modules/workers/worker_buf.js"); +let Buf = { + __proto__: (function(){ + return require("resource://gre/modules/workers/worker_buf.js").Buf; + })(), + + onSendParcel: function onSendParcel(parcel) { + postRILMessage(CLIENT_ID, parcel); + } +}; /** * The RIL state machine. @@ -12792,9 +12800,6 @@ let RuimRecordHelper = { // Initialize buffers. This is a separate function so that unit tests can // re-initialize the buffers at will. Buf.init(); -Buf.setOutputStream(function (parcel) { - postRILMessage(CLIENT_ID, parcel); -}); function onRILMessage(data) { Buf.processIncoming(data); diff --git a/dom/system/gonk/worker_buf.js b/dom/system/gonk/worker_buf.js index 4c0748eca74..d9bfb0fc627 100644 --- a/dom/system/gonk/worker_buf.js +++ b/dom/system/gonk/worker_buf.js @@ -21,656 +21,656 @@ const PARCEL_SIZE_SIZE = UINT32_SIZE; * every time a parcel is sent. */ -let mIncomingBufferLength = 1024; -let mOutgoingBufferLength = 1024; -let mIncomingBuffer, mOutgoingBuffer, mIncomingBytes, mOutgoingBytes, - mIncomingWriteIndex, mIncomingReadIndex, mOutgoingIndex, mReadIncoming, - mReadAvailable, mCurrentParcelSize, mToken, mTokenRequestMap, - mLasSolicitedToken, mOutgoingBufferCalSizeQueue, mOutputStream; +let Buf = { + mIncomingBufferLength: 1024, + mIncomingBuffer: null, + mIncomingBytes: null, + mIncomingWriteIndex: 0, + mIncomingReadIndex: 0, + mReadIncoming: 0, + mReadAvailable: 0, + mCurrentParcelSize: 0, -function init() { - mIncomingBuffer = new ArrayBuffer(mIncomingBufferLength); - mOutgoingBuffer = new ArrayBuffer(mOutgoingBufferLength); + mOutgoingBufferLength: 1024, + mOutgoingBuffer: null, + mOutgoingBytes: null, + mOutgoingIndex: 0, + mOutgoingBufferCalSizeQueue: null, - mIncomingBytes = new Uint8Array(mIncomingBuffer); - mOutgoingBytes = new Uint8Array(mOutgoingBuffer); + mToken: 0, + mTokenRequestMap: null, - // Track where incoming data is read from and written to. - mIncomingWriteIndex = 0; - mIncomingReadIndex = 0; + init: function init() { + this.mIncomingBuffer = new ArrayBuffer(this.mIncomingBufferLength); + this.mOutgoingBuffer = new ArrayBuffer(this.mOutgoingBufferLength); - // Leave room for the parcel size for outgoing parcels. - mOutgoingIndex = PARCEL_SIZE_SIZE; + this.mIncomingBytes = new Uint8Array(this.mIncomingBuffer); + this.mOutgoingBytes = new Uint8Array(this.mOutgoingBuffer); - // How many bytes we've read for this parcel so far. - mReadIncoming = 0; + // Track where incoming data is read from and written to. + this.mIncomingWriteIndex = 0; + this.mIncomingReadIndex = 0; - // How many bytes available as parcel data. - mReadAvailable = 0; + // Leave room for the parcel size for outgoing parcels. + this.mOutgoingIndex = PARCEL_SIZE_SIZE; - // Size of the incoming parcel. If this is zero, we're expecting a new - // parcel. - mCurrentParcelSize = 0; + // How many bytes we've read for this parcel so far. + this.mReadIncoming = 0; - // This gets incremented each time we send out a parcel. - mToken = 1; + // How many bytes available as parcel data. + this.mReadAvailable = 0; - // Maps tokens we send out with requests to the request type, so that - // when we get a response parcel back, we know what request it was for. - mTokenRequestMap = {}; + // Size of the incoming parcel. If this is zero, we're expecting a new + // parcel. + this.mCurrentParcelSize = 0; - // This is the token of last solicited response. - mLasSolicitedToken = 0; + // This gets incremented each time we send out a parcel. + this.mToken = 1; - // Queue for storing outgoing override points - mOutgoingBufferCalSizeQueue = []; -} + // Maps tokens we send out with requests to the request type, so that + // when we get a response parcel back, we know what request it was for. + this.mTokenRequestMap = {}; -/** - * Mark current mOutgoingIndex as start point for calculation length of data - * written to mOutgoingBuffer. - * Mark can be nested for here uses queue to remember marks. - * - * @param writeFunction - * Function to write data length into mOutgoingBuffer, this function is - * also used to allocate buffer for data length. - * Raw data size(in Uint8) is provided as parameter calling writeFunction. - * If raw data size is not in proper unit for writing, user can adjust - * the length value in writeFunction before writing. - **/ -function startCalOutgoingSize(writeFunction) { - let sizeInfo = {index: mOutgoingIndex, - write: writeFunction}; + // Queue for storing outgoing override points + this.mOutgoingBufferCalSizeQueue = []; + }, - // Allocate buffer for data lemgtj. - writeFunction.call(0); - - // Get size of data length buffer for it is not counted into data size. - sizeInfo.size = mOutgoingIndex - sizeInfo.index; - - // Enqueue size calculation information. - mOutgoingBufferCalSizeQueue.push(sizeInfo); -} - -/** - * Calculate data length since last mark, and write it into mark position. - **/ -function stopCalOutgoingSize() { - let sizeInfo = mOutgoingBufferCalSizeQueue.pop(); - - // Remember current mOutgoingIndex. - let currentOutgoingIndex = mOutgoingIndex; - // Calculate data length, in uint8. - let writeSize = mOutgoingIndex - sizeInfo.index - sizeInfo.size; - - // Write data length to mark, use same function for allocating buffer to make - // sure there is no buffer overloading. - mOutgoingIndex = sizeInfo.index; - sizeInfo.write(writeSize); - - // Restore mOutgoingIndex. - mOutgoingIndex = currentOutgoingIndex; -} - -/** - * Grow the incoming buffer. - * - * @param min_size - * Minimum new size. The actual new size will be the the smallest - * power of 2 that's larger than this number. - */ -function growIncomingBuffer(min_size) { - if (DEBUG) { - debug("Current buffer of " + mIncomingBufferLength + - " can't handle incoming " + min_size + " bytes."); - } - let oldBytes = mIncomingBytes; - mIncomingBufferLength = - 2 << Math.floor(Math.log(min_size)/Math.log(2)); - if (DEBUG) debug("New incoming buffer size: " + mIncomingBufferLength); - mIncomingBuffer = new ArrayBuffer(mIncomingBufferLength); - mIncomingBytes = new Uint8Array(mIncomingBuffer); - if (mIncomingReadIndex <= mIncomingWriteIndex) { - // Read and write index are in natural order, so we can just copy - // the old buffer over to the bigger one without having to worry - // about the indexes. - mIncomingBytes.set(oldBytes, 0); - } else { - // The write index has wrapped around but the read index hasn't yet. - // Write whatever the read index has left to read until it would - // circle around to the beginning of the new buffer, and the rest - // behind that. - let head = oldBytes.subarray(mIncomingReadIndex); - let tail = oldBytes.subarray(0, mIncomingReadIndex); - mIncomingBytes.set(head, 0); - mIncomingBytes.set(tail, head.length); - mIncomingReadIndex = 0; - mIncomingWriteIndex += head.length; - } - if (DEBUG) { - debug("New incoming buffer size is " + mIncomingBufferLength); - } -} - -/** - * Grow the outgoing buffer. - * - * @param min_size - * Minimum new size. The actual new size will be the the smallest - * power of 2 that's larger than this number. - */ -function growOutgoingBuffer(min_size) { - if (DEBUG) { - debug("Current buffer of " + mOutgoingBufferLength + - " is too small."); - } - let oldBytes = mOutgoingBytes; - mOutgoingBufferLength = - 2 << Math.floor(Math.log(min_size)/Math.log(2)); - mOutgoingBuffer = new ArrayBuffer(mOutgoingBufferLength); - mOutgoingBytes = new Uint8Array(mOutgoingBuffer); - mOutgoingBytes.set(oldBytes, 0); - if (DEBUG) { - debug("New outgoing buffer size is " + mOutgoingBufferLength); - } -} - -/** - * Functions for reading data from the incoming buffer. - * - * These are all little endian, apart from readParcelSize(); - */ - -/** - * Ensure position specified is readable. - * - * @param index - * Data position in incoming parcel, valid from 0 to - * mCurrentParcelSize. - */ -function ensureIncomingAvailable(index) { - if (index >= mCurrentParcelSize) { - throw new Error("Trying to read data beyond the parcel end!"); - } else if (index < 0) { - throw new Error("Trying to read data before the parcel begin!"); - } -} - -/** - * Seek in current incoming parcel. - * - * @param offset - * Seek offset in relative to current position. - */ -function seekIncoming(offset) { - // Translate to 0..mCurrentParcelSize - let cur = mCurrentParcelSize - mReadAvailable; - - let newIndex = cur + offset; - ensureIncomingAvailable(newIndex); - - // ... mIncomingReadIndex -->| - // 0 new cur mCurrentParcelSize - // |================|=======|===================| - // |<-- cur -->|<- mReadAvailable ->| - // |<-- newIndex -->|<-- new mReadAvailable -->| - mReadAvailable = mCurrentParcelSize - newIndex; - - // Translate back: - if (mIncomingReadIndex < cur) { - // The mIncomingReadIndex is wrapped. - newIndex += mIncomingBufferLength; - } - newIndex += (mIncomingReadIndex - cur); - newIndex %= mIncomingBufferLength; - mIncomingReadIndex = newIndex; -} - -function readUint8Unchecked() { - let value = mIncomingBytes[mIncomingReadIndex]; - mIncomingReadIndex = (mIncomingReadIndex + 1) % - mIncomingBufferLength; - return value; -} - -function readUint8() { - // Translate to 0..mCurrentParcelSize - let cur = mCurrentParcelSize - mReadAvailable; - ensureIncomingAvailable(cur); - - mReadAvailable--; - return readUint8Unchecked(); -} - -function readUint8Array(length) { - // Translate to 0..mCurrentParcelSize - let last = mCurrentParcelSize - mReadAvailable; - last += (length - 1); - ensureIncomingAvailable(last); - - let array = new Uint8Array(length); - for (let i = 0; i < length; i++) { - array[i] = readUint8Unchecked(); - } - - mReadAvailable -= length; - return array; -} - -function readUint16() { - return readUint8() | readUint8() << 8; -} - -function readUint32() { - return readUint8() | readUint8() << 8 | - readUint8() << 16 | readUint8() << 24; -} - -function readUint32List() { - let length = readUint32(); - let ints = []; - for (let i = 0; i < length; i++) { - ints.push(readUint32()); - } - return ints; -} - -function readString() { - let string_len = readUint32(); - if (string_len < 0 || string_len >= INT32_MAX) { - return null; - } - let s = ""; - for (let i = 0; i < string_len; i++) { - s += String.fromCharCode(readUint16()); - } - // Strings are \0\0 delimited, but that isn't part of the length. And - // if the string length is even, the delimiter is two characters wide. - // It's insane, I know. - readStringDelimiter(string_len); - return s; -} - -function readStringList() { - let num_strings = readUint32(); - let strings = []; - for (let i = 0; i < num_strings; i++) { - strings.push(readString()); - } - return strings; -} - -function readStringDelimiter(length) { - let delimiter = readUint16(); - if (!(length & 1)) { - delimiter |= readUint16(); - } - if (DEBUG) { - if (delimiter !== 0) { - debug("Something's wrong, found string delimiter: " + delimiter); - } - } -} - -function readParcelSize() { - return readUint8Unchecked() << 24 | - readUint8Unchecked() << 16 | - readUint8Unchecked() << 8 | - readUint8Unchecked(); -} - -/** - * Functions for writing data to the outgoing buffer. - */ - -/** - * Ensure position specified is writable. - * - * @param index - * Data position in outgoing parcel, valid from 0 to - * mOutgoingBufferLength. - */ -function ensureOutgoingAvailable(index) { - if (index >= mOutgoingBufferLength) { - growOutgoingBuffer(index + 1); - } -} - -function writeUint8(value) { - ensureOutgoingAvailable(mOutgoingIndex); - - mOutgoingBytes[mOutgoingIndex] = value; - mOutgoingIndex++; -} - -function writeUint16(value) { - writeUint8(value & 0xff); - writeUint8((value >> 8) & 0xff); -} - -function writeUint32(value) { - writeUint8(value & 0xff); - writeUint8((value >> 8) & 0xff); - writeUint8((value >> 16) & 0xff); - writeUint8((value >> 24) & 0xff); -} - -function writeString(value) { - if (value == null) { - writeUint32(-1); - return; - } - writeUint32(value.length); - for (let i = 0; i < value.length; i++) { - writeUint16(value.charCodeAt(i)); - } - // Strings are \0\0 delimited, but that isn't part of the length. And - // if the string length is even, the delimiter is two characters wide. - // It's insane, I know. - writeStringDelimiter(value.length); -} - -function writeStringList(strings) { - writeUint32(strings.length); - for (let i = 0; i < strings.length; i++) { - writeString(strings[i]); - } -} - -function writeStringDelimiter(length) { - writeUint16(0); - if (!(length & 1)) { - writeUint16(0); - } -} - -function writeParcelSize(value) { /** - * Parcel size will always be the first thing in the parcel byte - * array, but the last thing written. Store the current index off - * to a temporary to be reset after we write the size. + * Mark current mOutgoingIndex as start point for calculation length of data + * written to mOutgoingBuffer. + * Mark can be nested for here uses queue to remember marks. + * + * @param writeFunction + * Function to write data length into mOutgoingBuffer, this function is + * also used to allocate buffer for data length. + * Raw data size(in Uint8) is provided as parameter calling writeFunction. + * If raw data size is not in proper unit for writing, user can adjust + * the length value in writeFunction before writing. + **/ + startCalOutgoingSize: function startCalOutgoingSize(writeFunction) { + let sizeInfo = {index: this.mOutgoingIndex, + write: writeFunction}; + + // Allocate buffer for data lemgtj. + writeFunction.call(0); + + // Get size of data length buffer for it is not counted into data size. + sizeInfo.size = this.mOutgoingIndex - sizeInfo.index; + + // Enqueue size calculation information. + this.mOutgoingBufferCalSizeQueue.push(sizeInfo); + }, + + /** + * Calculate data length since last mark, and write it into mark position. + **/ + stopCalOutgoingSize: function stopCalOutgoingSize() { + let sizeInfo = this.mOutgoingBufferCalSizeQueue.pop(); + + // Remember current mOutgoingIndex. + let currentOutgoingIndex = this.mOutgoingIndex; + // Calculate data length, in uint8. + let writeSize = this.mOutgoingIndex - sizeInfo.index - sizeInfo.size; + + // Write data length to mark, use same function for allocating buffer to make + // sure there is no buffer overloading. + this.mOutgoingIndex = sizeInfo.index; + sizeInfo.write(writeSize); + + // Restore mOutgoingIndex. + this.mOutgoingIndex = currentOutgoingIndex; + }, + + /** + * Grow the incoming buffer. + * + * @param min_size + * Minimum new size. The actual new size will be the the smallest + * power of 2 that's larger than this number. */ - let currentIndex = mOutgoingIndex; - mOutgoingIndex = 0; - writeUint8((value >> 24) & 0xff); - writeUint8((value >> 16) & 0xff); - writeUint8((value >> 8) & 0xff); - writeUint8(value & 0xff); - mOutgoingIndex = currentIndex; -} - -function copyIncomingToOutgoing(length) { - if (!length || (length < 0)) { - return; - } - - let translatedReadIndexEnd = mCurrentParcelSize - mReadAvailable + length - 1; - ensureIncomingAvailable(translatedReadIndexEnd); - - let translatedWriteIndexEnd = mOutgoingIndex + length - 1; - ensureOutgoingAvailable(translatedWriteIndexEnd); - - let newIncomingReadIndex = mIncomingReadIndex + length; - if (newIncomingReadIndex < mIncomingBufferLength) { - // Reading won't cause wrapping, go ahead with builtin copy. - mOutgoingBytes.set(mIncomingBytes.subarray(mIncomingReadIndex, newIncomingReadIndex), - mOutgoingIndex); - } else { - // Not so lucky. - newIncomingReadIndex %= mIncomingBufferLength; - mOutgoingBytes.set(mIncomingBytes.subarray(mIncomingReadIndex, mIncomingBufferLength), - mOutgoingIndex); - if (newIncomingReadIndex) { - let firstPartLength = mIncomingBufferLength - mIncomingReadIndex; - mOutgoingBytes.set(mIncomingBytes.subarray(0, newIncomingReadIndex), - mOutgoingIndex + firstPartLength); + growIncomingBuffer: function growIncomingBuffer(min_size) { + if (DEBUG) { + debug("Current buffer of " + this.mIncomingBufferLength + + " can't handle incoming " + min_size + " bytes."); } - } + let oldBytes = this.mIncomingBytes; + this.mIncomingBufferLength = + 2 << Math.floor(Math.log(min_size)/Math.log(2)); + if (DEBUG) debug("New incoming buffer size: " + this.mIncomingBufferLength); + this.mIncomingBuffer = new ArrayBuffer(this.mIncomingBufferLength); + this.mIncomingBytes = new Uint8Array(this.mIncomingBuffer); + if (this.mIncomingReadIndex <= this.mIncomingWriteIndex) { + // Read and write index are in natural order, so we can just copy + // the old buffer over to the bigger one without having to worry + // about the indexes. + this.mIncomingBytes.set(oldBytes, 0); + } else { + // The write index has wrapped around but the read index hasn't yet. + // Write whatever the read index has left to read until it would + // circle around to the beginning of the new buffer, and the rest + // behind that. + let head = oldBytes.subarray(this.mIncomingReadIndex); + let tail = oldBytes.subarray(0, this.mIncomingReadIndex); + this.mIncomingBytes.set(head, 0); + this.mIncomingBytes.set(tail, head.length); + this.mIncomingReadIndex = 0; + this.mIncomingWriteIndex += head.length; + } + if (DEBUG) { + debug("New incoming buffer size is " + this.mIncomingBufferLength); + } + }, - mIncomingReadIndex = newIncomingReadIndex; - mReadAvailable -= length; - mOutgoingIndex += length; -} + /** + * Grow the outgoing buffer. + * + * @param min_size + * Minimum new size. The actual new size will be the the smallest + * power of 2 that's larger than this number. + */ + growOutgoingBuffer: function growOutgoingBuffer(min_size) { + if (DEBUG) { + debug("Current buffer of " + this.mOutgoingBufferLength + + " is too small."); + } + let oldBytes = this.mOutgoingBytes; + this.mOutgoingBufferLength = + 2 << Math.floor(Math.log(min_size)/Math.log(2)); + this.mOutgoingBuffer = new ArrayBuffer(this.mOutgoingBufferLength); + this.mOutgoingBytes = new Uint8Array(this.mOutgoingBuffer); + this.mOutgoingBytes.set(oldBytes, 0); + if (DEBUG) { + debug("New outgoing buffer size is " + this.mOutgoingBufferLength); + } + }, -/** - * Parcel management - */ + /** + * Functions for reading data from the incoming buffer. + * + * These are all little endian, apart from readParcelSize(); + */ -/** - * Write incoming data to the circular buffer. - * - * @param incoming - * Uint8Array containing the incoming data. - */ -function writeToIncoming(incoming) { - // We don't have to worry about the head catching the tail since - // we process any backlog in parcels immediately, before writing - // new data to the buffer. So the only edge case we need to handle - // is when the incoming data is larger than the buffer size. - let minMustAvailableSize = incoming.length + mReadIncoming; - if (minMustAvailableSize > mIncomingBufferLength) { - growIncomingBuffer(minMustAvailableSize); - } + /** + * Ensure position specified is readable. + * + * @param index + * Data position in incoming parcel, valid from 0 to + * mCurrentParcelSize. + */ + ensureIncomingAvailable: function ensureIncomingAvailable(index) { + if (index >= this.mCurrentParcelSize) { + throw new Error("Trying to read data beyond the parcel end!"); + } else if (index < 0) { + throw new Error("Trying to read data before the parcel begin!"); + } + }, - // We can let the typed arrays do the copying if the incoming data won't - // wrap around the edges of the circular buffer. - let remaining = mIncomingBufferLength - mIncomingWriteIndex; - if (remaining >= incoming.length) { - mIncomingBytes.set(incoming, mIncomingWriteIndex); - } else { - // The incoming data would wrap around it. - let head = incoming.subarray(0, remaining); - let tail = incoming.subarray(remaining); - mIncomingBytes.set(head, mIncomingWriteIndex); - mIncomingBytes.set(tail, 0); - } - mIncomingWriteIndex = (mIncomingWriteIndex + incoming.length) % - mIncomingBufferLength; -} + /** + * Seek in current incoming parcel. + * + * @param offset + * Seek offset in relative to current position. + */ + seekIncoming: function seekIncoming(offset) { + // Translate to 0..mCurrentParcelSize + let cur = this.mCurrentParcelSize - this.mReadAvailable; -/** - * Process incoming data. - * - * @param incoming - * Uint8Array containing the incoming data. - */ -function processIncoming(incoming) { - if (DEBUG) { - debug("Received " + incoming.length + " bytes."); - debug("Already read " + mReadIncoming); - } + let newIndex = cur + offset; + this.ensureIncomingAvailable(newIndex); - writeToIncoming(incoming); - mReadIncoming += incoming.length; - while (true) { - if (!mCurrentParcelSize) { - // We're expecting a new parcel. - if (mReadIncoming < PARCEL_SIZE_SIZE) { - // We don't know how big the next parcel is going to be, need more - // data. - if (DEBUG) debug("Next parcel size unknown, going to sleep."); + // ... mIncomingReadIndex -->| + // 0 new cur mCurrentParcelSize + // |================|=======|====================| + // |<-- cur -->|<- mReadAvailable ->| + // |<-- newIndex -->|<-- new mReadAvailable -->| + this.mReadAvailable = this.mCurrentParcelSize - newIndex; + + // Translate back: + if (this.mIncomingReadIndex < cur) { + // The mIncomingReadIndex is wrapped. + newIndex += this.mIncomingBufferLength; + } + newIndex += (this.mIncomingReadIndex - cur); + newIndex %= this.mIncomingBufferLength; + this.mIncomingReadIndex = newIndex; + }, + + readUint8Unchecked: function readUint8Unchecked() { + let value = this.mIncomingBytes[this.mIncomingReadIndex]; + this.mIncomingReadIndex = (this.mIncomingReadIndex + 1) % + this.mIncomingBufferLength; + return value; + }, + + readUint8: function readUint8() { + // Translate to 0..mCurrentParcelSize + let cur = this.mCurrentParcelSize - this.mReadAvailable; + this.ensureIncomingAvailable(cur); + + this.mReadAvailable--; + return this.readUint8Unchecked(); + }, + + readUint8Array: function readUint8Array(length) { + // Translate to 0..mCurrentParcelSize + let last = this.mCurrentParcelSize - this.mReadAvailable; + last += (length - 1); + this.ensureIncomingAvailable(last); + + let array = new Uint8Array(length); + for (let i = 0; i < length; i++) { + array[i] = this.readUint8Unchecked(); + } + + this.mReadAvailable -= length; + return array; + }, + + readUint16: function readUint16() { + return this.readUint8() | this.readUint8() << 8; + }, + + readUint32: function readUint32() { + return this.readUint8() | this.readUint8() << 8 | + this.readUint8() << 16 | this.readUint8() << 24; + }, + + readUint32List: function readUint32List() { + let length = this.readUint32(); + let ints = []; + for (let i = 0; i < length; i++) { + ints.push(this.readUint32()); + } + return ints; + }, + + readString: function readString() { + let string_len = this.readUint32(); + if (string_len < 0 || string_len >= INT32_MAX) { + return null; + } + let s = ""; + for (let i = 0; i < string_len; i++) { + s += String.fromCharCode(this.readUint16()); + } + // Strings are \0\0 delimited, but that isn't part of the length. And + // if the string length is even, the delimiter is two characters wide. + // It's insane, I know. + this.readStringDelimiter(string_len); + return s; + }, + + readStringList: function readStringList() { + let num_strings = this.readUint32(); + let strings = []; + for (let i = 0; i < num_strings; i++) { + strings.push(this.readString()); + } + return strings; + }, + + readStringDelimiter: function readStringDelimiter(length) { + let delimiter = this.readUint16(); + if (!(length & 1)) { + delimiter |= this.readUint16(); + } + if (DEBUG) { + if (delimiter !== 0) { + debug("Something's wrong, found string delimiter: " + delimiter); + } + } + }, + + readParcelSize: function readParcelSize() { + return this.readUint8Unchecked() << 24 | + this.readUint8Unchecked() << 16 | + this.readUint8Unchecked() << 8 | + this.readUint8Unchecked(); + }, + + /** + * Functions for writing data to the outgoing buffer. + */ + + /** + * Ensure position specified is writable. + * + * @param index + * Data position in outgoing parcel, valid from 0 to + * mOutgoingBufferLength. + */ + ensureOutgoingAvailable: function ensureOutgoingAvailable(index) { + if (index >= this.mOutgoingBufferLength) { + this.growOutgoingBuffer(index + 1); + } + }, + + writeUint8: function writeUint8(value) { + this.ensureOutgoingAvailable(this.mOutgoingIndex); + + this.mOutgoingBytes[this.mOutgoingIndex] = value; + this.mOutgoingIndex++; + }, + + writeUint16: function writeUint16(value) { + this.writeUint8(value & 0xff); + this.writeUint8((value >> 8) & 0xff); + }, + + writeUint32: function writeUint32(value) { + this.writeUint8(value & 0xff); + this.writeUint8((value >> 8) & 0xff); + this.writeUint8((value >> 16) & 0xff); + this.writeUint8((value >> 24) & 0xff); + }, + + writeString: function writeString(value) { + if (value == null) { + this.writeUint32(-1); + return; + } + this.writeUint32(value.length); + for (let i = 0; i < value.length; i++) { + this.writeUint16(value.charCodeAt(i)); + } + // Strings are \0\0 delimited, but that isn't part of the length. And + // if the string length is even, the delimiter is two characters wide. + // It's insane, I know. + this.writeStringDelimiter(value.length); + }, + + writeStringList: function writeStringList(strings) { + this.writeUint32(strings.length); + for (let i = 0; i < strings.length; i++) { + this.writeString(strings[i]); + } + }, + + writeStringDelimiter: function writeStringDelimiter(length) { + this.writeUint16(0); + if (!(length & 1)) { + this.writeUint16(0); + } + }, + + writeParcelSize: function writeParcelSize(value) { + /** + * Parcel size will always be the first thing in the parcel byte + * array, but the last thing written. Store the current index off + * to a temporary to be reset after we write the size. + */ + let currentIndex = this.mOutgoingIndex; + this.mOutgoingIndex = 0; + this.writeUint8((value >> 24) & 0xff); + this.writeUint8((value >> 16) & 0xff); + this.writeUint8((value >> 8) & 0xff); + this.writeUint8(value & 0xff); + this.mOutgoingIndex = currentIndex; + }, + + copyIncomingToOutgoing: function copyIncomingToOutgoing(length) { + if (!length || (length < 0)) { + return; + } + + let translatedReadIndexEnd = + this.mCurrentParcelSize - this.mReadAvailable + length - 1; + this.ensureIncomingAvailable(translatedReadIndexEnd); + + let translatedWriteIndexEnd = this.mOutgoingIndex + length - 1; + this.ensureOutgoingAvailable(translatedWriteIndexEnd); + + let newIncomingReadIndex = this.mIncomingReadIndex + length; + if (newIncomingReadIndex < this.mIncomingBufferLength) { + // Reading won't cause wrapping, go ahead with builtin copy. + this.mOutgoingBytes + .set(this.mIncomingBytes.subarray(this.mIncomingReadIndex, + newIncomingReadIndex), + this.mOutgoingIndex); + } else { + // Not so lucky. + newIncomingReadIndex %= this.mIncomingBufferLength; + this.mOutgoingBytes + .set(this.mIncomingBytes.subarray(this.mIncomingReadIndex, + this.mIncomingBufferLength), + this.mOutgoingIndex); + if (newIncomingReadIndex) { + let firstPartLength = this.mIncomingBufferLength - this.mIncomingReadIndex; + this.mOutgoingBytes.set(this.mIncomingBytes.subarray(0, newIncomingReadIndex), + this.mOutgoingIndex + firstPartLength); + } + } + + this.mIncomingReadIndex = newIncomingReadIndex; + this.mReadAvailable -= length; + this.mOutgoingIndex += length; + }, + + /** + * Parcel management + */ + + /** + * Write incoming data to the circular buffer. + * + * @param incoming + * Uint8Array containing the incoming data. + */ + writeToIncoming: function writeToIncoming(incoming) { + // We don't have to worry about the head catching the tail since + // we process any backlog in parcels immediately, before writing + // new data to the buffer. So the only edge case we need to handle + // is when the incoming data is larger than the buffer size. + let minMustAvailableSize = incoming.length + this.mReadIncoming; + if (minMustAvailableSize > this.mIncomingBufferLength) { + this.growIncomingBuffer(minMustAvailableSize); + } + + // We can let the typed arrays do the copying if the incoming data won't + // wrap around the edges of the circular buffer. + let remaining = this.mIncomingBufferLength - this.mIncomingWriteIndex; + if (remaining >= incoming.length) { + this.mIncomingBytes.set(incoming, this.mIncomingWriteIndex); + } else { + // The incoming data would wrap around it. + let head = incoming.subarray(0, remaining); + let tail = incoming.subarray(remaining); + this.mIncomingBytes.set(head, this.mIncomingWriteIndex); + this.mIncomingBytes.set(tail, 0); + } + this.mIncomingWriteIndex = (this.mIncomingWriteIndex + incoming.length) % + this.mIncomingBufferLength; + }, + + /** + * Process incoming data. + * + * @param incoming + * Uint8Array containing the incoming data. + */ + processIncoming: function processIncoming(incoming) { + if (DEBUG) { + debug("Received " + incoming.length + " bytes."); + debug("Already read " + this.mReadIncoming); + } + + this.writeToIncoming(incoming); + this.mReadIncoming += incoming.length; + while (true) { + if (!this.mCurrentParcelSize) { + // We're expecting a new parcel. + if (this.mReadIncoming < PARCEL_SIZE_SIZE) { + // We don't know how big the next parcel is going to be, need more + // data. + if (DEBUG) debug("Next parcel size unknown, going to sleep."); + return; + } + this.mCurrentParcelSize = this.readParcelSize(); + if (DEBUG) { + debug("New incoming parcel of size " + this.mCurrentParcelSize); + } + // The size itself is not included in the size. + this.mReadIncoming -= PARCEL_SIZE_SIZE; + } + + if (this.mReadIncoming < this.mCurrentParcelSize) { + // We haven't read enough yet in order to be able to process a parcel. + if (DEBUG) debug("Read " + this.mReadIncoming + ", but parcel size is " + + this.mCurrentParcelSize + ". Going to sleep."); return; } - mCurrentParcelSize = readParcelSize(); - if (DEBUG) debug("New incoming parcel of size " + - mCurrentParcelSize); - // The size itself is not included in the size. - mReadIncoming -= PARCEL_SIZE_SIZE; - } - if (mReadIncoming < mCurrentParcelSize) { - // We haven't read enough yet in order to be able to process a parcel. - if (DEBUG) debug("Read " + mReadIncoming + ", but parcel size is " - + mCurrentParcelSize + ". Going to sleep."); + // Alright, we have enough data to process at least one whole parcel. + // Let's do that. + let expectedAfterIndex = (this.mIncomingReadIndex + this.mCurrentParcelSize) + % this.mIncomingBufferLength; + + if (DEBUG) { + let parcel; + if (expectedAfterIndex < this.mIncomingReadIndex) { + let head = this.mIncomingBytes.subarray(this.mIncomingReadIndex); + let tail = this.mIncomingBytes.subarray(0, expectedAfterIndex); + parcel = Array.slice(head).concat(Array.slice(tail)); + } else { + parcel = Array.slice(this.mIncomingBytes.subarray( + this.mIncomingReadIndex, expectedAfterIndex)); + } + debug("Parcel (size " + this.mCurrentParcelSize + "): " + parcel); + } + + if (DEBUG) debug("We have at least one complete parcel."); + try { + this.mReadAvailable = this.mCurrentParcelSize; + this.processParcel(); + } catch (ex) { + if (DEBUG) debug("Parcel handling threw " + ex + "\n" + ex.stack); + } + + // Ensure that the whole parcel was consumed. + if (this.mIncomingReadIndex != expectedAfterIndex) { + if (DEBUG) { + debug("Parcel handler didn't consume whole parcel, " + + Math.abs(expectedAfterIndex - this.mIncomingReadIndex) + + " bytes left over"); + } + this.mIncomingReadIndex = expectedAfterIndex; + } + this.mReadIncoming -= this.mCurrentParcelSize; + this.mReadAvailable = 0; + this.mCurrentParcelSize = 0; + } + }, + + /** + * Process one parcel. + */ + processParcel: function processParcel() { + let response_type = this.readUint32(); + + let request_type, options; + if (response_type == RESPONSE_TYPE_SOLICITED) { + let token = this.readUint32(); + let error = this.readUint32(); + + options = this.mTokenRequestMap[token]; + if (!options) { + if (DEBUG) { + debug("Suspicious uninvited request found: " + token + ". Ignored!"); + } + return; + } + + delete this.mTokenRequestMap[token]; + request_type = options.rilRequestType; + + options.rilRequestError = error; + if (DEBUG) { + debug("Solicited response for request type " + request_type + + ", token " + token + ", error " + error); + } + } else if (response_type == RESPONSE_TYPE_UNSOLICITED) { + request_type = this.readUint32(); + if (DEBUG) debug("Unsolicited response for request type " + request_type); + } else { + if (DEBUG) debug("Unknown response type: " + response_type); return; } - // Alright, we have enough data to process at least one whole parcel. - // Let's do that. - let expectedAfterIndex = (mIncomingReadIndex + mCurrentParcelSize) - % mIncomingBufferLength; + RIL.handleParcel(request_type, this.mReadAvailable, options); + }, - if (DEBUG) { - let parcel; - if (expectedAfterIndex < mIncomingReadIndex) { - let head = mIncomingBytes.subarray(mIncomingReadIndex); - let tail = mIncomingBytes.subarray(0, expectedAfterIndex); - parcel = Array.slice(head).concat(Array.slice(tail)); - } else { - parcel = Array.slice(mIncomingBytes.subarray( - mIncomingReadIndex, expectedAfterIndex)); - } - debug("Parcel (size " + mCurrentParcelSize + "): " + parcel); - } + /** + * Start a new outgoing parcel. + * + * @param type + * Integer specifying the request type. + * @param options [optional] + * Object containing information about the request, e.g. the + * original main thread message object that led to the RIL request. + */ + newParcel: function newParcel(type, options) { + if (DEBUG) debug("New outgoing parcel of type " + type); - if (DEBUG) debug("We have at least one complete parcel."); - try { - mReadAvailable = mCurrentParcelSize; - processParcel(); - } catch (ex) { - if (DEBUG) debug("Parcel handling threw " + ex + "\n" + ex.stack); - } + // We're going to leave room for the parcel size at the beginning. + this.mOutgoingIndex = PARCEL_SIZE_SIZE; + this.writeUint32(type); + this.writeUint32(this.mToken); - // Ensure that the whole parcel was consumed. - if (mIncomingReadIndex != expectedAfterIndex) { - if (DEBUG) { - debug("Parcel handler didn't consume whole parcel, " + - Math.abs(expectedAfterIndex - mIncomingReadIndex) + - " bytes left over"); - } - mIncomingReadIndex = expectedAfterIndex; - } - mReadIncoming -= mCurrentParcelSize; - mReadAvailable = 0; - mCurrentParcelSize = 0; - } -} - -/** - * Process one parcel. - */ -function processParcel() { - let response_type = readUint32(); - - let request_type, options; - if (response_type == RESPONSE_TYPE_SOLICITED) { - let token = readUint32(); - let error = readUint32(); - - options = mTokenRequestMap[token]; if (!options) { - if (DEBUG) { - debug("Suspicious uninvited request found: " + token + ". Ignored!"); - } - return; + options = {}; } + options.rilRequestType = type; + options.rilRequestError = null; + this.mTokenRequestMap[this.mToken] = options; + this.mToken++; + return this.mToken; + }, - delete mTokenRequestMap[token]; - request_type = options.rilRequestType; + /** + * Communicate with the RIL IPC thread. + */ + sendParcel: function sendParcel() { + // Compute the size of the parcel and write it to the front of the parcel + // where we left room for it. Note that he parcel size does not include + // the size itself. + let parcelSize = this.mOutgoingIndex - PARCEL_SIZE_SIZE; + this.writeParcelSize(parcelSize); - options.rilRequestError = error; - if (DEBUG) { - debug("Solicited response for request type " + request_type + - ", token " + token + ", error " + error); - } - } else if (response_type == RESPONSE_TYPE_UNSOLICITED) { - request_type = readUint32(); - if (DEBUG) debug("Unsolicited response for request type " + request_type); - } else { - if (DEBUG) debug("Unknown response type: " + response_type); - return; + // This assumes that postRILMessage will make a copy of the ArrayBufferView + // right away! + let parcel = this.mOutgoingBytes.subarray(0, this.mOutgoingIndex); + if (DEBUG) debug("Outgoing parcel: " + Array.slice(parcel)); + this.onSendParcel(parcel); + this.mOutgoingIndex = PARCEL_SIZE_SIZE; + }, + + simpleRequest: function simpleRequest(type, options) { + this.newParcel(type, options); + this.sendParcel(); + }, + + getCurrentParcelSize: function getCurrentParcelSize() { + return this.mCurrentParcelSize; + }, + + getReadAvailable: function getReadAvailable() { + return this.mReadAvailable; } - RIL.handleParcel(request_type, mReadAvailable, options); -} - -/** - * Start a new outgoing parcel. - * - * @param type - * Integer specifying the request type. - * @param options [optional] - * Object containing information about the request, e.g. the - * original main thread message object that led to the RIL request. - */ -function newParcel(type, options) { - if (DEBUG) debug("New outgoing parcel of type " + type); - - // We're going to leave room for the parcel size at the beginning. - mOutgoingIndex = PARCEL_SIZE_SIZE; - writeUint32(type); - writeUint32(mToken); - - if (!options) { - options = {}; - } - options.rilRequestType = type; - options.rilRequestError = null; - mTokenRequestMap[mToken] = options; - mToken++; - return mToken; -} - -/** - * Communicate with the RIL IPC thread. - */ -function sendParcel() { - // Compute the size of the parcel and write it to the front of the parcel - // where we left room for it. Note that he parcel size does not include - // the size itself. - let parcelSize = mOutgoingIndex - PARCEL_SIZE_SIZE; - writeParcelSize(parcelSize); - - // This assumes that postRILMessage will make a copy of the ArrayBufferView - // right away! - let parcel = mOutgoingBytes.subarray(0, mOutgoingIndex); - if (DEBUG) debug("Outgoing parcel: " + Array.slice(parcel)); - mOutputStream(parcel); - mOutgoingIndex = PARCEL_SIZE_SIZE; -} - -function setOutputStream(func) { - mOutputStream = func; -} - -function simpleRequest(type, options) { - newParcel(type, options); - sendParcel(); -} - -function getCurrentParcelSize() { - return mCurrentParcelSize; -} - -function getReadAvailable() { - return mReadAvailable; -} - -module.exports = { - init: init, - startCalOutgoingSize: startCalOutgoingSize, - stopCalOutgoingSize: stopCalOutgoingSize, - seekIncoming: seekIncoming, - readUint8: readUint8, - readUint8Array: readUint8Array, - readUint16: readUint16, - readUint32: readUint32, - readUint32List: readUint32List, - readString: readString, - readStringList: readStringList, - readStringDelimiter: readStringDelimiter, - writeUint8: writeUint8, - writeUint16: writeUint16, - writeUint32: writeUint32, - writeString: writeString, - writeStringList: writeStringList, - writeStringDelimiter: writeStringDelimiter, - copyIncomingToOutgoing: copyIncomingToOutgoing, - processIncoming: processIncoming, - newParcel: newParcel, - sendParcel: sendParcel, - simpleRequest: simpleRequest, - setOutputStream: setOutputStream, - getCurrentParcelSize: getCurrentParcelSize, - getReadAvailable: getReadAvailable, + /** + * Write raw data out to underlying channel. + * + * |onSendParcel| is an implementation provided stream output function + * invoked when we're really going to write something out. We assume the + * data are completely copied to some output buffer in this call and may + * be destroyed when it's done. + * + * @param parcel + * An array of numeric octet data. + */ + //onSendParcel: function onSendParcel(parcel) { + // ... + //} }; + +module.exports = { Buf: Buf }; From cf990e3acce11c9ab7781b02052e8c84eb8a6b8c Mon Sep 17 00:00:00 2001 From: Vicamo Yang Date: Wed, 4 Sep 2013 18:58:26 +0800 Subject: [PATCH 028/171] Bug 911341 - 2/2: Seperate the parcel header handling. r=yoshi --- dom/system/gonk/ril_worker.js | 84 ++++++++++++++++++++++++++ dom/system/gonk/worker_buf.js | 109 +++++++--------------------------- 2 files changed, 105 insertions(+), 88 deletions(-) diff --git a/dom/system/gonk/ril_worker.js b/dom/system/gonk/ril_worker.js index 6138a05e217..e0844ec1996 100644 --- a/dom/system/gonk/ril_worker.js +++ b/dom/system/gonk/ril_worker.js @@ -101,6 +101,90 @@ let Buf = { return require("resource://gre/modules/workers/worker_buf.js").Buf; })(), + mToken: 0, + mTokenRequestMap: null, + + init: function init() { + this._init(); + + // This gets incremented each time we send out a parcel. + this.mToken = 1; + + // Maps tokens we send out with requests to the request type, so that + // when we get a response parcel back, we know what request it was for. + this.mTokenRequestMap = {}; + }, + + /** + * Process one parcel. + */ + processParcel: function processParcel() { + let response_type = this.readUint32(); + + let request_type, options; + if (response_type == RESPONSE_TYPE_SOLICITED) { + let token = this.readUint32(); + let error = this.readUint32(); + + options = this.mTokenRequestMap[token]; + if (!options) { + if (DEBUG) { + debug("Suspicious uninvited request found: " + token + ". Ignored!"); + } + return; + } + + delete this.mTokenRequestMap[token]; + request_type = options.rilRequestType; + + options.rilRequestError = error; + if (DEBUG) { + debug("Solicited response for request type " + request_type + + ", token " + token + ", error " + error); + } + } else if (response_type == RESPONSE_TYPE_UNSOLICITED) { + request_type = this.readUint32(); + if (DEBUG) debug("Unsolicited response for request type " + request_type); + } else { + if (DEBUG) debug("Unknown response type: " + response_type); + return; + } + + RIL.handleParcel(request_type, this.mReadAvailable, options); + }, + + /** + * Start a new outgoing parcel. + * + * @param type + * Integer specifying the request type. + * @param options [optional] + * Object containing information about the request, e.g. the + * original main thread message object that led to the RIL request. + */ + newParcel: function newParcel(type, options) { + if (DEBUG) debug("New outgoing parcel of type " + type); + + // We're going to leave room for the parcel size at the beginning. + this.mOutgoingIndex = this.PARCEL_SIZE_SIZE; + this.writeUint32(type); + this.writeUint32(this.mToken); + + if (!options) { + options = {}; + } + options.rilRequestType = type; + options.rilRequestError = null; + this.mTokenRequestMap[this.mToken] = options; + this.mToken++; + return this.mToken; + }, + + simpleRequest: function simpleRequest(type, options) { + this.newParcel(type, options); + this.sendParcel(); + }, + onSendParcel: function onSendParcel(parcel) { postRILMessage(CLIENT_ID, parcel); } diff --git a/dom/system/gonk/worker_buf.js b/dom/system/gonk/worker_buf.js index d9bfb0fc627..49616db8700 100644 --- a/dom/system/gonk/worker_buf.js +++ b/dom/system/gonk/worker_buf.js @@ -6,7 +6,6 @@ const INT32_MAX = 2147483647; const UINT8_SIZE = 1; const UINT16_SIZE = 2; const UINT32_SIZE = 4; -const PARCEL_SIZE_SIZE = UINT32_SIZE; /** * This object contains helpers buffering incoming data & deconstructing it @@ -22,6 +21,8 @@ const PARCEL_SIZE_SIZE = UINT32_SIZE; */ let Buf = { + PARCEL_SIZE_SIZE: UINT32_SIZE, + mIncomingBufferLength: 1024, mIncomingBuffer: null, mIncomingBytes: null, @@ -37,10 +38,7 @@ let Buf = { mOutgoingIndex: 0, mOutgoingBufferCalSizeQueue: null, - mToken: 0, - mTokenRequestMap: null, - - init: function init() { + _init: function _init() { this.mIncomingBuffer = new ArrayBuffer(this.mIncomingBufferLength); this.mOutgoingBuffer = new ArrayBuffer(this.mOutgoingBufferLength); @@ -52,7 +50,7 @@ let Buf = { this.mIncomingReadIndex = 0; // Leave room for the parcel size for outgoing parcels. - this.mOutgoingIndex = PARCEL_SIZE_SIZE; + this.mOutgoingIndex = this.PARCEL_SIZE_SIZE; // How many bytes we've read for this parcel so far. this.mReadIncoming = 0; @@ -64,13 +62,6 @@ let Buf = { // parcel. this.mCurrentParcelSize = 0; - // This gets incremented each time we send out a parcel. - this.mToken = 1; - - // Maps tokens we send out with requests to the request type, so that - // when we get a response parcel back, we know what request it was for. - this.mTokenRequestMap = {}; - // Queue for storing outgoing override points this.mOutgoingBufferCalSizeQueue = []; }, @@ -499,7 +490,7 @@ let Buf = { while (true) { if (!this.mCurrentParcelSize) { // We're expecting a new parcel. - if (this.mReadIncoming < PARCEL_SIZE_SIZE) { + if (this.mReadIncoming < this.PARCEL_SIZE_SIZE) { // We don't know how big the next parcel is going to be, need more // data. if (DEBUG) debug("Next parcel size unknown, going to sleep."); @@ -510,7 +501,7 @@ let Buf = { debug("New incoming parcel of size " + this.mCurrentParcelSize); } // The size itself is not included in the size. - this.mReadIncoming -= PARCEL_SIZE_SIZE; + this.mReadIncoming -= this.PARCEL_SIZE_SIZE; } if (this.mReadIncoming < this.mCurrentParcelSize) { @@ -562,78 +553,13 @@ let Buf = { }, /** - * Process one parcel. - */ - processParcel: function processParcel() { - let response_type = this.readUint32(); - - let request_type, options; - if (response_type == RESPONSE_TYPE_SOLICITED) { - let token = this.readUint32(); - let error = this.readUint32(); - - options = this.mTokenRequestMap[token]; - if (!options) { - if (DEBUG) { - debug("Suspicious uninvited request found: " + token + ". Ignored!"); - } - return; - } - - delete this.mTokenRequestMap[token]; - request_type = options.rilRequestType; - - options.rilRequestError = error; - if (DEBUG) { - debug("Solicited response for request type " + request_type + - ", token " + token + ", error " + error); - } - } else if (response_type == RESPONSE_TYPE_UNSOLICITED) { - request_type = this.readUint32(); - if (DEBUG) debug("Unsolicited response for request type " + request_type); - } else { - if (DEBUG) debug("Unknown response type: " + response_type); - return; - } - - RIL.handleParcel(request_type, this.mReadAvailable, options); - }, - - /** - * Start a new outgoing parcel. - * - * @param type - * Integer specifying the request type. - * @param options [optional] - * Object containing information about the request, e.g. the - * original main thread message object that led to the RIL request. - */ - newParcel: function newParcel(type, options) { - if (DEBUG) debug("New outgoing parcel of type " + type); - - // We're going to leave room for the parcel size at the beginning. - this.mOutgoingIndex = PARCEL_SIZE_SIZE; - this.writeUint32(type); - this.writeUint32(this.mToken); - - if (!options) { - options = {}; - } - options.rilRequestType = type; - options.rilRequestError = null; - this.mTokenRequestMap[this.mToken] = options; - this.mToken++; - return this.mToken; - }, - - /** - * Communicate with the RIL IPC thread. + * Communicate with the IPC thread. */ sendParcel: function sendParcel() { // Compute the size of the parcel and write it to the front of the parcel // where we left room for it. Note that he parcel size does not include // the size itself. - let parcelSize = this.mOutgoingIndex - PARCEL_SIZE_SIZE; + let parcelSize = this.mOutgoingIndex - this.PARCEL_SIZE_SIZE; this.writeParcelSize(parcelSize); // This assumes that postRILMessage will make a copy of the ArrayBufferView @@ -641,12 +567,7 @@ let Buf = { let parcel = this.mOutgoingBytes.subarray(0, this.mOutgoingIndex); if (DEBUG) debug("Outgoing parcel: " + Array.slice(parcel)); this.onSendParcel(parcel); - this.mOutgoingIndex = PARCEL_SIZE_SIZE; - }, - - simpleRequest: function simpleRequest(type, options) { - this.newParcel(type, options); - this.sendParcel(); + this.mOutgoingIndex = this.PARCEL_SIZE_SIZE; }, getCurrentParcelSize: function getCurrentParcelSize() { @@ -657,6 +578,18 @@ let Buf = { return this.mReadAvailable; } + /** + * Process one parcel. + * + * |processParcel| is an implementation provided incoming parcel processing + * function invoked when we have received a complete parcel. Implementation + * may call multiple read functions to extract data from the incoming buffer. + */ + //processParcel: function processParcel() { + // let something = this.readUint32(); + // ... + //}, + /** * Write raw data out to underlying channel. * From da895651afb3e01dad288618ae4eac938a3260fb Mon Sep 17 00:00:00 2001 From: Gaia Pushbot Date: Wed, 4 Sep 2013 04:55:22 -0700 Subject: [PATCH 029/171] Bumping gaia.json for 1 gaia-central revision(s) ======== https://hg.mozilla.org/integration/gaia-central/rev/e7bd49ad100b Author: b2gautomation Desc: Bug 907941 - gaia-ui-tests-pushbot (see bug) --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 32755bd481e..9c7d312c6c8 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,4 +1,4 @@ { - "revision": "6e4866e3453f231d1089b95d7010101b99b2c18b", + "revision": "e7bd49ad100bbe19677aa6d5ca91439a71519c4b", "repo_path": "/integration/gaia-central" } From e19ec03eb6ef802dc1d4f12bcfacd7b63a945216 Mon Sep 17 00:00:00 2001 From: Gaia Pushbot Date: Wed, 4 Sep 2013 05:25:21 -0700 Subject: [PATCH 030/171] Bumping gaia.json for 1 gaia-central revision(s) ======== https://hg.mozilla.org/integration/gaia-central/rev/e596cc6a1c09 Author: b2gautomation Desc: Bug 907941 - gaia-ui-tests-pushbot (see bug) --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 9c7d312c6c8..7f18a25bb88 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,4 +1,4 @@ { - "revision": "e7bd49ad100bbe19677aa6d5ca91439a71519c4b", + "revision": "e596cc6a1c092b728c02ba2be9a62e974661ce6a", "repo_path": "/integration/gaia-central" } From 246d5a9bc729de2d0d9790e70f8382bfddcdc775 Mon Sep 17 00:00:00 2001 From: Tim Chien Date: Wed, 4 Sep 2013 08:28:28 -0400 Subject: [PATCH 031/171] Bug 798353 - Make SettingsListener reuse the lock. r=fabrice --- b2g/chrome/content/settings.js | 68 +++++++++++++++++++++------------- 1 file changed, 43 insertions(+), 25 deletions(-) diff --git a/b2g/chrome/content/settings.js b/b2g/chrome/content/settings.js index 248e286fe18..c1d0aafdc14 100644 --- a/b2g/chrome/content/settings.js +++ b/b2g/chrome/content/settings.js @@ -4,7 +4,7 @@ * 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/. */ -"use strict;" +"use strict"; const Cc = Components.classes; const Ci = Components.interfaces; @@ -21,47 +21,65 @@ XPCOMUtils.defineLazyGetter(this, "libcutils", function () { }); #endif -// Once Bug 731746 - Allow chrome JS object to implement nsIDOMEventTarget -// is resolved this helper could be removed. var SettingsListener = { - _callbacks: {}, + // Timer to remove the lock. + _timer: null, - init: function sl_init() { - if ('mozSettings' in navigator && navigator.mozSettings) { - navigator.mozSettings.onsettingchange = this.onchange.bind(this); - } - }, + // lock stores here + _lock: null, - onchange: function sl_onchange(evt) { - var callback = this._callbacks[evt.settingName]; - if (callback) { - callback(evt.settingValue); + /** + * getSettingsLock: create a lock or retrieve one that we saved. + * mozSettings.createLock() is expensive and lock should be reused + * whenever possible. + */ + getSettingsLock: function sl_getSettingsLock() { + // Each time there is a getSettingsLock call, we postpone the removal. + clearTimeout(this._timer); + this._timer = setTimeout((function() { + this._lock = null; + }).bind(this), 0); + + // If there is a lock present we return that. + if (this._lock) { + return this._lock; } + + // If there isn't we create a new one. + let settings = window.navigator.mozSettings; + + return (this._lock = settings.createLock()); }, observe: function sl_observe(name, defaultValue, callback) { - var settings = window.navigator.mozSettings; - if (!settings) { - window.setTimeout(function() { callback(defaultValue); }); - return; + let settings = window.navigator.mozSettings; + + let req; + try { + req = this.getSettingsLock().get(name); + } catch (e) { + // It is possible (but rare) for getSettingsLock() to return + // a SettingsLock object that is no longer valid. + // Until https://bugzilla.mozilla.org/show_bug.cgi?id=793239 + // is fixed, we just catch the resulting exception and try + // again with a fresh lock + console.warn('Stale lock in settings.js.', + 'See https://bugzilla.mozilla.org/show_bug.cgi?id=793239'); + this._lock = null; + req = this.getSettingsLock().get(name); } - if (!callback || typeof callback !== 'function') { - throw new Error('Callback is not a function'); - } - - var req = settings.createLock().get(name); req.addEventListener('success', (function onsuccess() { callback(typeof(req.result[name]) != 'undefined' ? req.result[name] : defaultValue); })); - this._callbacks[name] = callback; + settings.addObserver(name, function settingChanged(evt) { + callback(evt.settingValue); + }); } }; -SettingsListener.init(); - // =================== Console ====================== SettingsListener.observe('debug.console.enabled', true, function(value) { From 871a8a3d7ead39a89b4ee6f2ac4c047a43bf2b38 Mon Sep 17 00:00:00 2001 From: Jan Jongboom Date: Wed, 4 Sep 2013 08:29:22 -0400 Subject: [PATCH 032/171] Bug 906096 - Move InputMethod API behind a pref instead of build option. r=kanru, r=sicking --HG-- rename : b2g/components/Keyboard.jsm => dom/inputmethod/Keyboard.jsm rename : b2g/components/MozKeyboard.js => dom/inputmethod/MozKeyboard.js --- b2g/app/b2g.js | 3 + b2g/components/B2GComponents.manifest | 8 --- b2g/components/b2g.idl | 68 ------------------ b2g/components/moz.build | 2 - b2g/installer/package-manifest.in | 1 + dom/inputmethod/InputMethod.manifest | 6 ++ .../inputmethod}/Keyboard.jsm | 0 .../inputmethod}/MozKeyboard.js | 0 dom/inputmethod/moz.build | 26 +++++++ dom/inputmethod/nsIB2GKeyboard.idl | 71 +++++++++++++++++++ dom/moz.build | 3 +- dom/webidl/InputMethod.webidl | 13 +++- dom/webidl/WebIDL.mk | 7 +- modules/libpref/src/init/all.js | 3 + 14 files changed, 123 insertions(+), 88 deletions(-) create mode 100644 dom/inputmethod/InputMethod.manifest rename {b2g/components => dom/inputmethod}/Keyboard.jsm (100%) rename {b2g/components => dom/inputmethod}/MozKeyboard.js (100%) create mode 100644 dom/inputmethod/moz.build create mode 100644 dom/inputmethod/nsIB2GKeyboard.idl diff --git a/b2g/app/b2g.js b/b2g/app/b2g.js index 0fe4804e343..be954a9e5c4 100644 --- a/b2g/app/b2g.js +++ b/b2g/app/b2g.js @@ -750,3 +750,6 @@ pref("dom.promise.enabled", false); // (only applies when marionette is disabled) // 0 disables the timer. pref("b2g.adb.timeout-hours", 12); + +// InputMethod so we can do soft keyboards +pref("dom.mozInputMethod.enabled", true); diff --git a/b2g/components/B2GComponents.manifest b/b2g/components/B2GComponents.manifest index 07bf3fe11ad..5198a35cfca 100644 --- a/b2g/components/B2GComponents.manifest +++ b/b2g/components/B2GComponents.manifest @@ -15,14 +15,6 @@ component {88b3eb21-d072-4e3b-886d-f89d8c49fe59} UpdatePrompt.js contract @mozilla.org/updates/update-prompt;1 {88b3eb21-d072-4e3b-886d-f89d8c49fe59} #endif -# MozKeyboard.js -component {397a7fdf-2254-47be-b74e-76625a1a66d5} MozKeyboard.js -contract @mozilla.org/b2g-keyboard;1 {397a7fdf-2254-47be-b74e-76625a1a66d5} -category JavaScript-navigator-property mozKeyboard @mozilla.org/b2g-keyboard;1 - -component {4607330d-e7d2-40a4-9eb8-43967eae0142} MozKeyboard.js -contract @mozilla.org/b2g-inputmethod;1 {4607330d-e7d2-40a4-9eb8-43967eae0142} - # DirectoryProvider.js component {9181eb7c-6f87-11e1-90b1-4f59d80dd2e5} DirectoryProvider.js contract @mozilla.org/browser/directory-provider;1 {9181eb7c-6f87-11e1-90b1-4f59d80dd2e5} diff --git a/b2g/components/b2g.idl b/b2g/components/b2g.idl index a6f48924112..6f24657b6a9 100644 --- a/b2g/components/b2g.idl +++ b/b2g/components/b2g.idl @@ -4,77 +4,9 @@ #include "domstubs.idl" -interface nsIDOMDOMRequest; - [scriptable, uuid(3615a616-571d-4194-bf54-ccf546067b14)] interface nsIB2GCameraContent : nsISupports { /* temporary solution, waiting for getUserMedia */ DOMString getCameraURI([optional] in jsval options); }; - -[scriptable, uuid(40ad96b2-9efa-41fb-84c7-fbcec9b153f0)] -interface nsIB2GKeyboard : nsISupports -{ - void sendKey(in long keyCode, in long charCode); - - // Select the that support multiple - // selection, then the option specified by index will be added to - // the selection. - // If this method is called for a select that does not support multiple - // selection the previous element will be unselected. - void setSelectedOption(in jsval index); - - // Select the that does not support multiple - // selection, then the last index specified in indexes will be selected. - void setSelectedOptions(in jsval indexes); - - // Set the value on the currently focused element. This has to be used - // for special situations where the value had to be chosen amongst a - // list (type=month) or a widget (type=date, time, etc.). - // If the value passed in parameter isn't valid (in the term of HTML5 - // Forms Validation), the value will simply be ignored by the element. - void setValue(in jsval value); - - void removeFocus(); - - attribute nsIDOMEventListener onfocuschange; - - // Fires when user moves the cursor, changes the selection, or alters the - // composing text length - attribute nsIDOMEventListener onselectionchange; - - // The start position of the selection. - readonly attribute long selectionStart; - - // The stop position of the selection. - readonly attribute long selectionEnd; - - /* - * Set the selection range of the the editable text. - * - * @param start The beginning of the selected text. - * @param end The end of the selected text. - * - * Note that the start position should be less or equal to the end position. - * To move the cursor, set the start and end position to the same value. - */ - void setSelectionRange(in long start, in long end); - - /* - * Replace text around the beginning of the current selection range of the - * editable text. - * - * @param text The string to be replaced with. - * @param beforeLength The number of characters to be deleted before the - * beginning of the current selection range. Defaults to 0. - * @param afterLength The number of characters to be deleted after the - * beginning of the current selection range. Defaults to 0. - */ - void replaceSurroundingText(in DOMString text, - [optional] in long beforeLength, - [optional] in long afterLength); -}; diff --git a/b2g/components/moz.build b/b2g/components/moz.build index 915bac5a93e..78d7b30739a 100644 --- a/b2g/components/moz.build +++ b/b2g/components/moz.build @@ -20,7 +20,6 @@ EXTRA_COMPONENTS += [ 'ContentPermissionPrompt.js', 'FilePicker.js', 'MailtoProtocolHandler.js', - 'MozKeyboard.js', 'PaymentGlue.js', 'ProcessGlobal.js', 'SmsProtocolHandler.js', @@ -41,7 +40,6 @@ if CONFIG['MOZ_UPDATER']: EXTRA_JS_MODULES += [ 'ErrorPage.jsm', - 'Keyboard.jsm', 'SignInToWebsite.jsm', 'TelURIParser.jsm', ] diff --git a/b2g/installer/package-manifest.in b/b2g/installer/package-manifest.in index 2553cf7659a..d52988cb8b9 100644 --- a/b2g/installer/package-manifest.in +++ b/b2g/installer/package-manifest.in @@ -213,6 +213,7 @@ @BINPATH@/components/dom_xpath.xpt @BINPATH@/components/dom_xul.xpt @BINPATH@/components/dom_time.xpt +@BINPATH@/components/dom_inputmethod.xpt @BINPATH@/components/downloads.xpt @BINPATH@/components/editor.xpt @BINPATH@/components/embed_base.xpt diff --git a/dom/inputmethod/InputMethod.manifest b/dom/inputmethod/InputMethod.manifest new file mode 100644 index 00000000000..77fd07313b3 --- /dev/null +++ b/dom/inputmethod/InputMethod.manifest @@ -0,0 +1,6 @@ +component {397a7fdf-2254-47be-b74e-76625a1a66d5} MozKeyboard.js +contract @mozilla.org/b2g-keyboard;1 {397a7fdf-2254-47be-b74e-76625a1a66d5} +category JavaScript-navigator-property mozKeyboard @mozilla.org/b2g-keyboard;1 + +component {4607330d-e7d2-40a4-9eb8-43967eae0142} MozKeyboard.js +contract @mozilla.org/b2g-inputmethod;1 {4607330d-e7d2-40a4-9eb8-43967eae0142} diff --git a/b2g/components/Keyboard.jsm b/dom/inputmethod/Keyboard.jsm similarity index 100% rename from b2g/components/Keyboard.jsm rename to dom/inputmethod/Keyboard.jsm diff --git a/b2g/components/MozKeyboard.js b/dom/inputmethod/MozKeyboard.js similarity index 100% rename from b2g/components/MozKeyboard.js rename to dom/inputmethod/MozKeyboard.js diff --git a/dom/inputmethod/moz.build b/dom/inputmethod/moz.build new file mode 100644 index 00000000000..965397cfe0c --- /dev/null +++ b/dom/inputmethod/moz.build @@ -0,0 +1,26 @@ +# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +XPIDL_SOURCES += [ + 'nsIB2GKeyboard.idl', +] + +XPIDL_MODULE = 'dom_inputmethod' + +MODULE = 'dom' + +EXTRA_COMPONENTS += [ + 'InputMethod.manifest', + 'MozKeyboard.js', +] + +EXTRA_JS_MODULES += [ + 'Keyboard.jsm', +] + +FAIL_ON_WARNINGS = True + +LIBXUL_LIBRARY = True diff --git a/dom/inputmethod/nsIB2GKeyboard.idl b/dom/inputmethod/nsIB2GKeyboard.idl new file mode 100644 index 00000000000..be205282384 --- /dev/null +++ b/dom/inputmethod/nsIB2GKeyboard.idl @@ -0,0 +1,71 @@ +/* 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 "domstubs.idl" + +[scriptable, uuid(40ad96b2-9efa-41fb-84c7-fbcec9b153f0)] +interface nsIB2GKeyboard : nsISupports +{ + void sendKey(in long keyCode, in long charCode); + + // Select the that support multiple + // selection, then the option specified by index will be added to + // the selection. + // If this method is called for a select that does not support multiple + // selection the previous element will be unselected. + void setSelectedOption(in jsval index); + + // Select the that does not support multiple + // selection, then the last index specified in indexes will be selected. + void setSelectedOptions(in jsval indexes); + + // Set the value on the currently focused element. This has to be used + // for special situations where the value had to be chosen amongst a + // list (type=month) or a widget (type=date, time, etc.). + // If the value passed in parameter isn't valid (in the term of HTML5 + // Forms Validation), the value will simply be ignored by the element. + void setValue(in jsval value); + + void removeFocus(); + + attribute nsIDOMEventListener onfocuschange; + + // Fires when user moves the cursor, changes the selection, or alters the + // composing text length + attribute nsIDOMEventListener onselectionchange; + + // The start position of the selection. + readonly attribute long selectionStart; + + // The stop position of the selection. + readonly attribute long selectionEnd; + + /* + * Set the selection range of the the editable text. + * + * @param start The beginning of the selected text. + * @param end The end of the selected text. + * + * Note that the start position should be less or equal to the end position. + * To move the cursor, set the start and end position to the same value. + */ + void setSelectionRange(in long start, in long end); + + /* + * Replace text around the beginning of the current selection range of the + * editable text. + * + * @param text The string to be replaced with. + * @param beforeLength The number of characters to be deleted before the + * beginning of the current selection range. Defaults to 0. + * @param afterLength The number of characters to be deleted after the + * beginning of the current selection range. Defaults to 0. + */ + void replaceSurroundingText(in DOMString text, + [optional] in long beforeLength, + [optional] in long afterLength); +}; diff --git a/dom/moz.build b/dom/moz.build index 5aeb1ba6a7a..77aa7032d97 100644 --- a/dom/moz.build +++ b/dom/moz.build @@ -72,7 +72,8 @@ PARALLEL_DIRS += [ 'camera', 'audiochannel', 'promise', - 'wappush' + 'wappush', + 'inputmethod' ] if CONFIG['OS_ARCH'] == 'WINNT': diff --git a/dom/webidl/InputMethod.webidl b/dom/webidl/InputMethod.webidl index 5c0812c12ef..ae48dd0044b 100644 --- a/dom/webidl/InputMethod.webidl +++ b/dom/webidl/InputMethod.webidl @@ -5,7 +5,8 @@ */ [JSImplementation="@mozilla.org/b2g-inputmethod;1", - NavigatorProperty="mozInputMethod"] + NavigatorProperty="mozInputMethod", + Pref="dom.mozInputMethod.enabled"] interface MozInputMethod : EventTarget { // Input Method Manager contain a few global methods expose to apps readonly attribute MozInputMethodManager mgmt; @@ -27,7 +28,8 @@ interface MozInputMethod : EventTarget { // Manages the list of IMEs, enables/disables IME and switches to an // IME. -[JSImplementation="@mozilla.org/b2g-imm;1"] +[JSImplementation="@mozilla.org/b2g-imm;1", + Pref="dom.mozInputMethod.enabled"] interface MozInputMethodManager { // Ask the OS to show a list of available IMEs for users to switch from. // OS should ignore this request if the app is currently not the active one. @@ -55,7 +57,8 @@ interface MozInputMethodManager { // It also hosts the methods available to the keyboard app to mutate the input field represented. // An "input context" gets void when the app is no longer allowed to interact with the text field, // e.g., the text field does no longer exist, the app is being switched to background, and etc. -[JSImplementation="@mozilla.org/b2g-inputcontext;1"] +[JSImplementation="@mozilla.org/b2g-inputcontext;1", + Pref="dom.mozInputMethod.enabled"] interface MozInputContext: EventTarget { // The tag name of input field, which is enum of "input", "textarea", or "contenteditable" readonly attribute DOMString? type; @@ -82,6 +85,10 @@ interface MozInputContext: EventTarget { readonly attribute long selectionStart; readonly attribute long selectionEnd; + // The start and stop position of the selection. + readonly attribute DOMString? textBeforeCursor; + readonly attribute DOMString? textAfterCursor; + /* * Set the selection range of the the editable text. * Note: This method cannot be used to move the cursor during composition. Calling this diff --git a/dom/webidl/WebIDL.mk b/dom/webidl/WebIDL.mk index f18ce2bddd4..c0856a026e6 100644 --- a/dom/webidl/WebIDL.mk +++ b/dom/webidl/WebIDL.mk @@ -180,6 +180,7 @@ webidl_files = \ IDBVersionChangeEvent.webidl \ ImageData.webidl \ ImageDocument.webidl \ + InputMethod.webidl \ InspectorUtils.webidl \ KeyboardEvent.webidl \ KeyEvent.webidl \ @@ -541,9 +542,3 @@ test_webidl_files := \ else test_webidl_files := $(NULL) endif - -ifdef MOZ_B2G -webidl_files += \ - InputMethod.webidl \ - $(NULL) -endif diff --git a/modules/libpref/src/init/all.js b/modules/libpref/src/init/all.js index 33257ad2883..1b83cf99569 100644 --- a/modules/libpref/src/init/all.js +++ b/modules/libpref/src/init/all.js @@ -4380,3 +4380,6 @@ pref("dom.forms.inputmode", false); #else pref("dom.forms.inputmode", true); #endif + +// InputMethods for soft keyboards in B2G +pref("dom.mozInputMethod.enabled", false); From 93eb04a526f3a52944d6da52e6d700d14b91abd1 Mon Sep 17 00:00:00 2001 From: Anthony Ricaud Date: Wed, 4 Sep 2013 08:29:46 -0400 Subject: [PATCH 033/171] Bug 889717 - Do not send focus when the user taps to stop scrolling. r=vingtetun --- dom/browser-element/BrowserElementPanning.js | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/dom/browser-element/BrowserElementPanning.js b/dom/browser-element/BrowserElementPanning.js index 4068e158fab..437818dcd41 100644 --- a/dom/browser-element/BrowserElementPanning.js +++ b/dom/browser-element/BrowserElementPanning.js @@ -183,6 +183,12 @@ const ContentPanning = { this.position.set(screenX, screenY); KineticPanning.record(new Point(0, 0), evt.timeStamp); + + // We prevent start events to avoid sending a focus event at the end of this + // touch series. See bug 889717. + if (this.panning || this.preventNextClick) { + evt.preventDefault(); + } }, onTouchEnd: function cp_onTouchEnd(evt) { @@ -214,10 +220,15 @@ const ContentPanning = { } if (this.target && click && (this.panning || this.preventNextClick)) { - let target = this.target; - let view = target.ownerDocument ? target.ownerDocument.defaultView - : target; - view.addEventListener('click', this, true, true); + if (this.hybridEvents) { + let target = this.target; + let view = target.ownerDocument ? target.ownerDocument.defaultView + : target; + view.addEventListener('click', this, true, true); + } else { + // We prevent end events to avoid sending a focus event. See bug 889717. + evt.preventDefault(); + } } this._finishPanning(); From 1a6639563f754e2e99ae3ec7e18b85b47b74c28e Mon Sep 17 00:00:00 2001 From: Gene Lian Date: Fri, 9 Aug 2013 21:25:53 +0800 Subject: [PATCH 034/171] Bug 903403 - [sms][mms] Make getSegmentInfoForText() Asynchronous to Improve Typing Performance. r=vicamo, sr=mounir --- .../interfaces/nsIDOMMobileMessageManager.idl | 4 +- .../interfaces/nsIMobileMessageCallback.idl | 6 +- .../interfaces/nsISmsService.idl | 5 +- .../src/MobileMessageCallback.cpp | 53 ++++-- dom/mobilemessage/src/MobileMessageCallback.h | 6 +- .../src/MobileMessageManager.cpp | 11 +- dom/mobilemessage/src/SmsSegmentInfo.cpp | 6 + dom/mobilemessage/src/SmsSegmentInfo.h | 3 + dom/mobilemessage/src/android/SmsService.cpp | 9 +- dom/mobilemessage/src/fallback/SmsService.cpp | 4 +- dom/mobilemessage/src/gonk/SmsService.cpp | 6 +- dom/mobilemessage/src/ipc/PSms.ipdl | 9 +- dom/mobilemessage/src/ipc/PSmsRequest.ipdl | 12 ++ dom/mobilemessage/src/ipc/SmsChild.cpp | 14 +- dom/mobilemessage/src/ipc/SmsIPCService.cpp | 16 +- dom/mobilemessage/src/ipc/SmsParent.cpp | 62 ++++--- dom/mobilemessage/src/ipc/SmsParent.h | 6 +- .../marionette/test_getsegmentinfofortext.js | 34 +++- .../tests/marionette/test_segment_info.js | 175 ++++++++++++------ dom/system/gonk/RadioInterfaceLayer.js | 11 +- dom/system/gonk/nsIRadioInterfaceLayer.idl | 6 +- widget/android/AndroidBridge.cpp | 22 ++- widget/android/AndroidBridge.h | 2 +- 23 files changed, 319 insertions(+), 163 deletions(-) diff --git a/dom/mobilemessage/interfaces/nsIDOMMobileMessageManager.idl b/dom/mobilemessage/interfaces/nsIDOMMobileMessageManager.idl index a60cd58f577..634ca505936 100644 --- a/dom/mobilemessage/interfaces/nsIDOMMobileMessageManager.idl +++ b/dom/mobilemessage/interfaces/nsIDOMMobileMessageManager.idl @@ -11,10 +11,10 @@ interface nsIDOMDOMCursor; interface nsIDOMDOMRequest; interface nsIDOMBlob; -[scriptable, builtinclass, uuid(efff5276-0f3f-4137-9b16-66e894400e01)] +[scriptable, builtinclass, uuid(3f81dcbc-00cf-11e3-ae66-538115636543)] interface nsIDOMMozMobileMessageManager : nsIDOMEventTarget { - nsIDOMMozSmsSegmentInfo getSegmentInfoForText(in DOMString text); + nsIDOMDOMRequest getSegmentInfoForText(in DOMString text); // The first parameter can be either a DOMString (only one number) or an array // of DOMStrings. diff --git a/dom/mobilemessage/interfaces/nsIMobileMessageCallback.idl b/dom/mobilemessage/interfaces/nsIMobileMessageCallback.idl index 478c5cedc8f..85cd690aadc 100644 --- a/dom/mobilemessage/interfaces/nsIMobileMessageCallback.idl +++ b/dom/mobilemessage/interfaces/nsIMobileMessageCallback.idl @@ -3,6 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsISupports.idl" +#include "nsIDOMSmsSegmentInfo.idl" dictionary SmsThreadListItem { @@ -13,7 +14,7 @@ dictionary SmsThreadListItem unsigned long long unreadCount; }; -[scriptable, uuid(ea5fb581-bee7-40a6-b2dc-c98b99a2dc49)] +[scriptable, uuid(399125a8-00d2-11e3-8d12-3fba4465c097)] interface nsIMobileMessageCallback : nsISupports { /** @@ -48,4 +49,7 @@ interface nsIMobileMessageCallback : nsISupports void notifyMessageMarkedRead(in boolean read); void notifyMarkMessageReadFailed(in long error); + + void notifySegmentInfoForTextGot(in nsIDOMMozSmsSegmentInfo info); + void notifyGetSegmentInfoForTextFailed(in long error); }; diff --git a/dom/mobilemessage/interfaces/nsISmsService.idl b/dom/mobilemessage/interfaces/nsISmsService.idl index 0623d62ef78..e3cde07aeb3 100644 --- a/dom/mobilemessage/interfaces/nsISmsService.idl +++ b/dom/mobilemessage/interfaces/nsISmsService.idl @@ -13,12 +13,13 @@ interface nsIMobileMessageCallback; #define SMS_SERVICE_CONTRACTID "@mozilla.org/sms/smsservice;1" %} -[scriptable, builtinclass, uuid(f0d5d11b-0326-4cb1-bb76-a3f912212287)] +[scriptable, builtinclass, uuid(0f3f75ec-00dd-11e3-87ac-0b1d5c79afdf)] interface nsISmsService : nsISupports { boolean hasSupport(); - nsIDOMMozSmsSegmentInfo getSegmentInfoForText(in DOMString text); + void getSegmentInfoForText(in DOMString text, + in nsIMobileMessageCallback request); void send(in DOMString number, in DOMString message, diff --git a/dom/mobilemessage/src/MobileMessageCallback.cpp b/dom/mobilemessage/src/MobileMessageCallback.cpp index f81dd543284..20d5612132b 100644 --- a/dom/mobilemessage/src/MobileMessageCallback.cpp +++ b/dom/mobilemessage/src/MobileMessageCallback.cpp @@ -8,6 +8,7 @@ #include "nsCxPusher.h" #include "nsIDOMMozSmsMessage.h" #include "nsIDOMMozMmsMessage.h" +#include "nsIDOMSmsSegmentInfo.h" #include "nsIScriptGlobalObject.h" #include "nsPIDOMWindow.h" #include "MmsMessage.h" @@ -39,14 +40,22 @@ MobileMessageCallback::~MobileMessageCallback() nsresult -MobileMessageCallback::NotifySuccess(JS::Handle aResult) +MobileMessageCallback::NotifySuccess(JS::Handle aResult, bool aAsync) { + if (aAsync) { + nsCOMPtr rs = + do_GetService(DOMREQUEST_SERVICE_CONTRACTID); + NS_ENSURE_TRUE(rs, NS_ERROR_FAILURE); + + return rs->FireSuccessAsync(mDOMRequest, aResult); + } + mDOMRequest->FireSuccess(aResult); return NS_OK; } nsresult -MobileMessageCallback::NotifySuccess(nsISupports *aMessage) +MobileMessageCallback::NotifySuccess(nsISupports *aMessage, bool aAsync) { nsresult rv; nsIScriptContext* scriptContext = mDOMRequest->GetContextForEventHandlers(&rv); @@ -66,38 +75,48 @@ MobileMessageCallback::NotifySuccess(nsISupports *aMessage) wrappedMessage.address()); NS_ENSURE_SUCCESS(rv, rv); - return NotifySuccess(wrappedMessage); + return NotifySuccess(wrappedMessage, aAsync); } nsresult -MobileMessageCallback::NotifyError(int32_t aError) +MobileMessageCallback::NotifyError(int32_t aError, bool aAsync) { + nsAutoString errorStr; switch (aError) { case nsIMobileMessageCallback::NO_SIGNAL_ERROR: - mDOMRequest->FireError(NS_LITERAL_STRING("NoSignalError")); + errorStr = NS_LITERAL_STRING("NoSignalError"); break; case nsIMobileMessageCallback::NOT_FOUND_ERROR: - mDOMRequest->FireError(NS_LITERAL_STRING("NotFoundError")); + errorStr = NS_LITERAL_STRING("NotFoundError"); break; case nsIMobileMessageCallback::UNKNOWN_ERROR: - mDOMRequest->FireError(NS_LITERAL_STRING("UnknownError")); + errorStr = NS_LITERAL_STRING("UnknownError"); break; case nsIMobileMessageCallback::INTERNAL_ERROR: - mDOMRequest->FireError(NS_LITERAL_STRING("InternalError")); + errorStr = NS_LITERAL_STRING("InternalError"); break; case nsIMobileMessageCallback::NO_SIM_CARD_ERROR: - mDOMRequest->FireError(NS_LITERAL_STRING("NoSimCardError")); + errorStr = NS_LITERAL_STRING("NoSimCardError"); break; case nsIMobileMessageCallback::RADIO_DISABLED_ERROR: - mDOMRequest->FireError(NS_LITERAL_STRING("RadioDisabledError")); + errorStr = NS_LITERAL_STRING("RadioDisabledError"); break; case nsIMobileMessageCallback::INVALID_ADDRESS_ERROR: - mDOMRequest->FireError(NS_LITERAL_STRING("InvalidAddressError")); + errorStr = NS_LITERAL_STRING("InvalidAddressError"); break; default: // SUCCESS_NO_ERROR is handled above. MOZ_CRASH("Should never get here!"); } + if (aAsync) { + nsCOMPtr rs = + do_GetService(DOMREQUEST_SERVICE_CONTRACTID); + NS_ENSURE_TRUE(rs, NS_ERROR_FAILURE); + + return rs->FireErrorAsync(mDOMRequest, errorStr); + } + + mDOMRequest->FireError(errorStr); return NS_OK; } @@ -173,6 +192,18 @@ MobileMessageCallback::NotifyMarkMessageReadFailed(int32_t aError) return NotifyError(aError); } +NS_IMETHODIMP +MobileMessageCallback::NotifySegmentInfoForTextGot(nsIDOMMozSmsSegmentInfo *aInfo) +{ + return NotifySuccess(aInfo, true); +} + +NS_IMETHODIMP +MobileMessageCallback::NotifyGetSegmentInfoForTextFailed(int32_t aError) +{ + return NotifyError(aError, true); +} + } // namesapce mobilemessage } // namespace dom } // namespace mozilla diff --git a/dom/mobilemessage/src/MobileMessageCallback.h b/dom/mobilemessage/src/MobileMessageCallback.h index bce94af5a26..b793df70edf 100644 --- a/dom/mobilemessage/src/MobileMessageCallback.h +++ b/dom/mobilemessage/src/MobileMessageCallback.h @@ -29,9 +29,9 @@ private: nsRefPtr mDOMRequest; - nsresult NotifySuccess(JS::Handle aResult); - nsresult NotifySuccess(nsISupports *aMessage); - nsresult NotifyError(int32_t aError); + nsresult NotifySuccess(JS::Handle aResult, bool aAsync = false); + nsresult NotifySuccess(nsISupports *aMessage, bool aAsync = false); + nsresult NotifyError(int32_t aError, bool aAsync = false); }; } // namespace mobilemessage diff --git a/dom/mobilemessage/src/MobileMessageManager.cpp b/dom/mobilemessage/src/MobileMessageManager.cpp index 57724428403..0094b7c8b2f 100644 --- a/dom/mobilemessage/src/MobileMessageManager.cpp +++ b/dom/mobilemessage/src/MobileMessageManager.cpp @@ -101,12 +101,19 @@ MobileMessageManager::Shutdown() NS_IMETHODIMP MobileMessageManager::GetSegmentInfoForText(const nsAString& aText, - nsIDOMMozSmsSegmentInfo** aResult) + nsIDOMDOMRequest** aRequest) { nsCOMPtr smsService = do_GetService(SMS_SERVICE_CONTRACTID); NS_ENSURE_TRUE(smsService, NS_ERROR_FAILURE); - return smsService->GetSegmentInfoForText(aText, aResult); + nsRefPtr request = new DOMRequest(GetOwner()); + nsCOMPtr msgCallback = + new MobileMessageCallback(request); + nsresult rv = smsService->GetSegmentInfoForText(aText, msgCallback); + NS_ENSURE_SUCCESS(rv, rv); + + request.forget(aRequest); + return NS_OK; } nsresult diff --git a/dom/mobilemessage/src/SmsSegmentInfo.cpp b/dom/mobilemessage/src/SmsSegmentInfo.cpp index 426ee87e778..2bb031ec8cc 100644 --- a/dom/mobilemessage/src/SmsSegmentInfo.cpp +++ b/dom/mobilemessage/src/SmsSegmentInfo.cpp @@ -55,5 +55,11 @@ SmsSegmentInfo::GetCharsAvailableInLastSegment(int32_t* aCharsAvailableInLastSeg return NS_OK; } +const SmsSegmentInfoData& +SmsSegmentInfo::GetData() const +{ + return mData; +} + } // namespace dom } // namespace mozilla diff --git a/dom/mobilemessage/src/SmsSegmentInfo.h b/dom/mobilemessage/src/SmsSegmentInfo.h index eb3e52472db..a4b40cddde4 100644 --- a/dom/mobilemessage/src/SmsSegmentInfo.h +++ b/dom/mobilemessage/src/SmsSegmentInfo.h @@ -22,8 +22,11 @@ public: SmsSegmentInfo(int32_t aSegments, int32_t aCharsPerSegment, int32_t aCharsAvailableInLastSegment); + SmsSegmentInfo(const mobilemessage::SmsSegmentInfoData& aData); + const mobilemessage::SmsSegmentInfoData& GetData() const; + private: mobilemessage::SmsSegmentInfoData mData; }; diff --git a/dom/mobilemessage/src/android/SmsService.cpp b/dom/mobilemessage/src/android/SmsService.cpp index 146190766fa..1da4b0a7ead 100644 --- a/dom/mobilemessage/src/android/SmsService.cpp +++ b/dom/mobilemessage/src/android/SmsService.cpp @@ -23,19 +23,16 @@ SmsService::HasSupport(bool* aHasSupport) } NS_IMETHODIMP -SmsService::GetSegmentInfoForText(const nsAString & aText, - nsIDOMMozSmsSegmentInfo** aResult) +SmsService::GetSegmentInfoForText(const nsAString& aText, + nsIMobileMessageCallback* aRequest) { if (!AndroidBridge::Bridge()) { return NS_ERROR_FAILURE; } - SmsSegmentInfoData data; - nsresult rv = AndroidBridge::Bridge()->GetSegmentInfoForText(aText, &data); + nsresult rv = AndroidBridge::Bridge()->GetSegmentInfoForText(aText, aRequest); NS_ENSURE_SUCCESS(rv, rv); - nsCOMPtr info = new SmsSegmentInfo(data); - info.forget(aResult); return NS_OK; } diff --git a/dom/mobilemessage/src/fallback/SmsService.cpp b/dom/mobilemessage/src/fallback/SmsService.cpp index 5df3504226b..a04a4676549 100644 --- a/dom/mobilemessage/src/fallback/SmsService.cpp +++ b/dom/mobilemessage/src/fallback/SmsService.cpp @@ -22,8 +22,8 @@ SmsService::HasSupport(bool* aHasSupport) } NS_IMETHODIMP -SmsService::GetSegmentInfoForText(const nsAString & aText, - nsIDOMMozSmsSegmentInfo** aResult) +SmsService::GetSegmentInfoForText(const nsAString& aText, + nsIMobileMessageCallback* aRequest) { NS_ERROR("We should not be here!"); return NS_ERROR_FAILURE; diff --git a/dom/mobilemessage/src/gonk/SmsService.cpp b/dom/mobilemessage/src/gonk/SmsService.cpp index 484dd94091a..335334786fb 100644 --- a/dom/mobilemessage/src/gonk/SmsService.cpp +++ b/dom/mobilemessage/src/gonk/SmsService.cpp @@ -31,12 +31,12 @@ SmsService::HasSupport(bool* aHasSupport) } NS_IMETHODIMP -SmsService::GetSegmentInfoForText(const nsAString & aText, - nsIDOMMozSmsSegmentInfo** aResult) +SmsService::GetSegmentInfoForText(const nsAString& aText, + nsIMobileMessageCallback* aRequest) { NS_ENSURE_TRUE(mRadioInterface, NS_ERROR_FAILURE); - return mRadioInterface->GetSegmentInfoForText(aText, aResult); + return mRadioInterface->GetSegmentInfoForText(aText, aRequest); } NS_IMETHODIMP diff --git a/dom/mobilemessage/src/ipc/PSms.ipdl b/dom/mobilemessage/src/ipc/PSms.ipdl index 57bb49e70ad..e27b35e8993 100644 --- a/dom/mobilemessage/src/ipc/PSms.ipdl +++ b/dom/mobilemessage/src/ipc/PSms.ipdl @@ -62,6 +62,11 @@ struct MarkMessageReadRequest bool value; }; +struct GetSegmentInfoForTextRequest +{ + nsString text; +}; + struct CreateThreadCursorRequest { }; @@ -73,6 +78,7 @@ union IPCSmsRequest GetMessageRequest; DeleteMessageRequest; MarkMessageReadRequest; + GetSegmentInfoForTextRequest; }; union IPCMobileMessageCursor @@ -122,9 +128,6 @@ parent: sync HasSupport() returns (bool aHasSupport); - sync GetSegmentInfoForText(nsString aText) - returns (SmsSegmentInfoData aResult); - AddSilentNumber(nsString aNumber); RemoveSilentNumber(nsString aNumber); }; diff --git a/dom/mobilemessage/src/ipc/PSmsRequest.ipdl b/dom/mobilemessage/src/ipc/PSmsRequest.ipdl index 98d1573d22d..abd7ea79e9b 100644 --- a/dom/mobilemessage/src/ipc/PSmsRequest.ipdl +++ b/dom/mobilemessage/src/ipc/PSmsRequest.ipdl @@ -66,6 +66,16 @@ struct ReplyMarkeMessageReadFail int32_t error; }; +struct ReplyGetSegmentInfoForText +{ + SmsSegmentInfoData infoData; +}; + +struct ReplyGetSegmentInfoForTextFail +{ + int32_t error; +}; + union MessageReply { ReplyMessageSend; @@ -76,6 +86,8 @@ union MessageReply ReplyMessageDeleteFail; ReplyMarkeMessageRead; ReplyMarkeMessageReadFail; + ReplyGetSegmentInfoForText; + ReplyGetSegmentInfoForTextFail; }; } // namespace mobilemessage diff --git a/dom/mobilemessage/src/ipc/SmsChild.cpp b/dom/mobilemessage/src/ipc/SmsChild.cpp index 3b90b5092aa..8e58b6af1af 100644 --- a/dom/mobilemessage/src/ipc/SmsChild.cpp +++ b/dom/mobilemessage/src/ipc/SmsChild.cpp @@ -5,6 +5,7 @@ #include "SmsChild.h" #include "SmsMessage.h" #include "MmsMessage.h" +#include "SmsSegmentInfo.h" #include "Constants.h" #include "nsIObserverService.h" #include "mozilla/Services.h" @@ -22,7 +23,7 @@ CreateMessageFromMessageData(const MobileMessageData& aData) { nsCOMPtr message; - switch(aData. type()) { + switch(aData.type()) { case MobileMessageData::TMmsMessageData: message = new MmsMessage(aData.get_MmsMessageData()); break; @@ -203,6 +204,17 @@ SmsRequestChild::Recv__delete__(const MessageReply& aReply) case MessageReply::TReplyMarkeMessageReadFail: mReplyRequest->NotifyMarkMessageReadFailed(aReply.get_ReplyMarkeMessageReadFail().error()); break; + case MessageReply::TReplyGetSegmentInfoForText: { + const SmsSegmentInfoData& data = + aReply.get_ReplyGetSegmentInfoForText().infoData(); + nsCOMPtr info = new SmsSegmentInfo(data); + mReplyRequest->NotifySegmentInfoForTextGot(info); + } + break; + case MessageReply::TReplyGetSegmentInfoForTextFail: + mReplyRequest->NotifyGetSegmentInfoForTextFailed( + aReply.get_ReplyGetSegmentInfoForTextFail().error()); + break; default: MOZ_CRASH("Received invalid response parameters!"); } diff --git a/dom/mobilemessage/src/ipc/SmsIPCService.cpp b/dom/mobilemessage/src/ipc/SmsIPCService.cpp index eebcbdc9a4e..876bb2a2f4f 100644 --- a/dom/mobilemessage/src/ipc/SmsIPCService.cpp +++ b/dom/mobilemessage/src/ipc/SmsIPCService.cpp @@ -96,19 +96,11 @@ SmsIPCService::HasSupport(bool* aHasSupport) } NS_IMETHODIMP -SmsIPCService::GetSegmentInfoForText(const nsAString & aText, - nsIDOMMozSmsSegmentInfo** aResult) +SmsIPCService::GetSegmentInfoForText(const nsAString& aText, + nsIMobileMessageCallback* aRequest) { - PSmsChild* smsChild = GetSmsChild(); - NS_ENSURE_TRUE(smsChild, NS_ERROR_FAILURE); - - SmsSegmentInfoData data; - bool ok = smsChild->SendGetSegmentInfoForText(nsString(aText), &data); - NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE); - - nsCOMPtr info = new SmsSegmentInfo(data); - info.forget(aResult); - return NS_OK; + return SendRequest(GetSegmentInfoForTextRequest(nsString(aText)), + aRequest); } NS_IMETHODIMP diff --git a/dom/mobilemessage/src/ipc/SmsParent.cpp b/dom/mobilemessage/src/ipc/SmsParent.cpp index ba4789e3f0d..da674b81449 100644 --- a/dom/mobilemessage/src/ipc/SmsParent.cpp +++ b/dom/mobilemessage/src/ipc/SmsParent.cpp @@ -311,35 +311,6 @@ SmsParent::RecvHasSupport(bool* aHasSupport) return true; } -bool -SmsParent::RecvGetSegmentInfoForText(const nsString& aText, - SmsSegmentInfoData* aResult) -{ - aResult->segments() = 0; - aResult->charsPerSegment() = 0; - aResult->charsAvailableInLastSegment() = 0; - - nsCOMPtr smsService = do_GetService(SMS_SERVICE_CONTRACTID); - NS_ENSURE_TRUE(smsService, true); - - nsCOMPtr info; - nsresult rv = smsService->GetSegmentInfoForText(aText, getter_AddRefs(info)); - NS_ENSURE_SUCCESS(rv, true); - - int segments, charsPerSegment, charsAvailableInLastSegment; - if (NS_FAILED(info->GetSegments(&segments)) || - NS_FAILED(info->GetCharsPerSegment(&charsPerSegment)) || - NS_FAILED(info->GetCharsAvailableInLastSegment(&charsAvailableInLastSegment))) { - NS_ERROR("Can't get attribute values from nsIDOMMozSmsSegmentInfo"); - return true; - } - - aResult->segments() = segments; - aResult->charsPerSegment() = charsPerSegment; - aResult->charsAvailableInLastSegment() = charsAvailableInLastSegment; - return true; -} - bool SmsParent::RecvAddSilentNumber(const nsString& aNumber) { @@ -393,6 +364,8 @@ SmsParent::RecvPSmsRequestConstructor(PSmsRequestParent* aActor, return actor->DoRequest(aRequest.get_DeleteMessageRequest()); case IPCSmsRequest::TMarkMessageReadRequest: return actor->DoRequest(aRequest.get_MarkMessageReadRequest()); + case IPCSmsRequest::TGetSegmentInfoForTextRequest: + return actor->DoRequest(aRequest.get_GetSegmentInfoForTextRequest()); default: MOZ_CRASH("Unknown type!"); } @@ -577,6 +550,24 @@ SmsRequestParent::DoRequest(const MarkMessageReadRequest& aRequest) return true; } +bool +SmsRequestParent::DoRequest(const GetSegmentInfoForTextRequest& aRequest) +{ + nsresult rv = NS_ERROR_FAILURE; + + nsCOMPtr smsService = do_GetService(SMS_SERVICE_CONTRACTID); + if (smsService) { + rv = smsService->GetSegmentInfoForText(aRequest.text(), this); + } + + if (NS_FAILED(rv)) { + return NS_SUCCEEDED(NotifyGetSegmentInfoForTextFailed( + nsIMobileMessageCallback::INTERNAL_ERROR)); + } + + return true; +} + nsresult SmsRequestParent::SendReply(const MessageReply& aReply) { @@ -674,6 +665,19 @@ SmsRequestParent::NotifyMarkMessageReadFailed(int32_t aError) return SendReply(ReplyMarkeMessageReadFail(aError)); } +NS_IMETHODIMP +SmsRequestParent::NotifySegmentInfoForTextGot(nsIDOMMozSmsSegmentInfo *aInfo) +{ + SmsSegmentInfo* info = static_cast(aInfo); + return SendReply(ReplyGetSegmentInfoForText(info->GetData())); +} + +NS_IMETHODIMP +SmsRequestParent::NotifyGetSegmentInfoForTextFailed(int32_t aError) +{ + return SendReply(ReplyGetSegmentInfoForTextFail(aError)); +} + /******************************************************************************* * MobileMessageCursorParent ******************************************************************************/ diff --git a/dom/mobilemessage/src/ipc/SmsParent.h b/dom/mobilemessage/src/ipc/SmsParent.h index c5757e6fc00..22908f1d776 100644 --- a/dom/mobilemessage/src/ipc/SmsParent.h +++ b/dom/mobilemessage/src/ipc/SmsParent.h @@ -34,9 +34,6 @@ protected: virtual bool RecvHasSupport(bool* aHasSupport) MOZ_OVERRIDE; - virtual bool - RecvGetSegmentInfoForText(const nsString& aText, SmsSegmentInfoData* aResult) MOZ_OVERRIDE; - virtual bool RecvAddSilentNumber(const nsString& aNumber) MOZ_OVERRIDE; @@ -120,6 +117,9 @@ protected: bool DoRequest(const MarkMessageReadRequest& aRequest); + bool + DoRequest(const GetSegmentInfoForTextRequest& aRequest); + nsresult SendReply(const MessageReply& aReply); }; diff --git a/dom/mobilemessage/tests/marionette/test_getsegmentinfofortext.js b/dom/mobilemessage/tests/marionette/test_getsegmentinfofortext.js index 9c7169a8a2a..0c4848aabf5 100644 --- a/dom/mobilemessage/tests/marionette/test_getsegmentinfofortext.js +++ b/dom/mobilemessage/tests/marionette/test_getsegmentinfofortext.js @@ -49,13 +49,31 @@ let tasks = { function addTest(text, segments, charsPerSegment, charsAvailableInLastSegment) { tasks.push(function () { log("Testing '" + text + "' ..."); - let info = manager.getSegmentInfoForText(text); - is(info.segments, segments, "info.segments"); - is(info.charsPerSegment, charsPerSegment, "info.charsPerSegment"); - is(info.charsAvailableInLastSegment, charsAvailableInLastSegment, - "info.charsAvailableInLastSegment"); + let domRequest = manager.getSegmentInfoForText(text); + ok(domRequest, "DOMRequest object returned."); - tasks.next(); + domRequest.onsuccess = function(e) { + log("Received 'onsuccess' DOMRequest event."); + + let result = e.target.result; + if (!result) { + ok(false, "getSegmentInfoForText() result is not valid."); + tasks.finish(); + return; + } + + is(result.segments, segments, "info.segments"); + is(result.charsPerSegment, charsPerSegment, "info.charsPerSegment"); + is(result.charsAvailableInLastSegment, charsAvailableInLastSegment, + "info.charsAvailableInLastSegment"); + + tasks.next(); + }; + + domRequest.onerror = function(e) { + ok(false, "Failed to call getSegmentInfoForText()."); + tasks.finish(); + }; }); } @@ -63,9 +81,9 @@ function addTestThrows(text) { tasks.push(function () { log("Testing '" + text + "' ..."); try { - let info = manager.getSegmentInfoForText(text); + let domRequest = manager.getSegmentInfoForText(text); - ok(false, "Not thrown"); + ok(false, "Not thrown."); tasks.finish(); } catch (e) { tasks.next(); diff --git a/dom/mobilemessage/tests/marionette/test_segment_info.js b/dom/mobilemessage/tests/marionette/test_segment_info.js index 9ebeb512fd7..15b6ba1a63a 100644 --- a/dom/mobilemessage/tests/marionette/test_segment_info.js +++ b/dom/mobilemessage/tests/marionette/test_segment_info.js @@ -12,7 +12,8 @@ const LEN_UCS2_WITH_16BIT_REF = 66; SpecialPowers.setBoolPref("dom.sms.enabled", true); let currentStrict7BitEncoding = false; -SpecialPowers.setBoolPref("dom.sms.strict7BitEncoding", currentStrict7BitEncoding); +SpecialPowers.setBoolPref("dom.sms.strict7BitEncoding", + currentStrict7BitEncoding); SpecialPowers.addPermission("sms", true, document); let manager = window.navigator.mozMobileMessage; @@ -23,107 +24,165 @@ function times(str, n) { return (new Array(n + 1)).join(str); } -function doTest(text, strict7BitEncoding, expected) { - if (strict7BitEncoding != currentStrict7BitEncoding) { - currentStrict7BitEncoding = strict7BitEncoding; - SpecialPowers.setBoolPref("dom.sms.strict7BitEncoding", currentStrict7BitEncoding); +let tasks = { + // List of test fuctions. Each of them should call |tasks.next()| when + // completed or |tasks.finish()| to jump to the last one. + _tasks: [], + _nextTaskIndex: 0, + + push: function push(func) { + this._tasks.push(func); + }, + + next: function next() { + let index = this._nextTaskIndex++; + let task = this._tasks[index]; + try { + task(); + } catch (ex) { + ok(false, "test task[" + index + "] throws: " + ex); + // Run last task as clean up if possible. + if (index != this._tasks.length - 1) { + this.finish(); + } + } + }, + + finish: function finish() { + this._tasks[this._tasks.length - 1](); + }, + + run: function run() { + this.next(); } +}; - let result = manager.getSegmentInfoForText(text); - ok(result, "result of GetSegmentInfoForText is valid"); - is(result.segments, expected[0], "segments"); - is(result.charsPerSegment, expected[1], "charsPerSegment"); - is(result.charsAvailableInLastSegment, expected[2], "charsAvailableInLastSegment"); -} +function addTest(text, strict7BitEncoding, expected) { + tasks.push(function () { + if (strict7BitEncoding != currentStrict7BitEncoding) { + currentStrict7BitEncoding = strict7BitEncoding; + SpecialPowers.setBoolPref("dom.sms.strict7BitEncoding", + currentStrict7BitEncoding); + } -function cleanUp() { - SpecialPowers.removePermission("sms", document); - SpecialPowers.clearUserPref("dom.sms.enabled"); - SpecialPowers.clearUserPref("dom.sms.strict7BitEncoding"); - finish(); + let domRequest = manager.getSegmentInfoForText(text); + ok(domRequest, "DOMRequest object returned."); + + domRequest.onsuccess = function(e) { + log("Received 'onsuccess' DOMRequest event."); + + let result = e.target.result; + if (!result) { + ok(false, "getSegmentInfoForText() result is not valid."); + tasks.finish(); + return; + } + + is(result.segments, expected[0], "segments"); + is(result.charsPerSegment, expected[1], "charsPerSegment"); + is(result.charsAvailableInLastSegment, expected[2], + "charsAvailableInLastSegment"); + + tasks.next(); + }; + + domRequest.onerror = function(e) { + ok(false, "Failed to call getSegmentInfoForText()."); + tasks.finish(); + }; + }); } // GSM 7Bit Alphabets: // // 'a' is in GSM default locking shift table, so it takes 1 septet. -doTest("a", false, [1, LEN_7BIT, LEN_7BIT - 1]); +addTest("a", false, [1, LEN_7BIT, LEN_7BIT - 1]); // '\u20ac' is in GSM default single shift table, so it takes 2 septets. -doTest("\u20ac", false, [1, LEN_7BIT, LEN_7BIT - 2]); +addTest("\u20ac", false, [1, LEN_7BIT, LEN_7BIT - 2]); // SP is defined in both locking shift and single shift tables. -doTest(" ", false, [1, LEN_7BIT, LEN_7BIT - 1]); +addTest(" ", false, [1, LEN_7BIT, LEN_7BIT - 1]); // Some combinations. -doTest("a\u20ac", false, [1, LEN_7BIT, LEN_7BIT - 3]); -doTest("a ", false, [1, LEN_7BIT, LEN_7BIT - 2]); -doTest("\u20aca", false, [1, LEN_7BIT, LEN_7BIT - 3]); -doTest("\u20ac ", false, [1, LEN_7BIT, LEN_7BIT - 3]); -doTest(" \u20ac", false, [1, LEN_7BIT, LEN_7BIT - 3]); -doTest(" a", false, [1, LEN_7BIT, LEN_7BIT - 2]); +addTest("a\u20ac", false, [1, LEN_7BIT, LEN_7BIT - 3]); +addTest("a ", false, [1, LEN_7BIT, LEN_7BIT - 2]); +addTest("\u20aca", false, [1, LEN_7BIT, LEN_7BIT - 3]); +addTest("\u20ac ", false, [1, LEN_7BIT, LEN_7BIT - 3]); +addTest(" \u20ac", false, [1, LEN_7BIT, LEN_7BIT - 3]); +addTest(" a", false, [1, LEN_7BIT, LEN_7BIT - 2]); // GSM 7Bit Alphabets (multipart): // // Exactly 160 locking shift table chararacters. -doTest(times("a", LEN_7BIT), false, [1, LEN_7BIT, 0]); +addTest(times("a", LEN_7BIT), false, [1, LEN_7BIT, 0]); // 161 locking shift table chararacters. We'll have |161 - 153 = 8| septets in // the 2nd segment. -doTest(times("a", LEN_7BIT + 1), false, - [2, LEN_7BIT_WITH_8BIT_REF, LEN_7BIT_WITH_8BIT_REF - 8]); +addTest(times("a", LEN_7BIT + 1), false, + [2, LEN_7BIT_WITH_8BIT_REF, LEN_7BIT_WITH_8BIT_REF - 8]); // |LEN_7BIT_WITH_8BIT_REF * 2| locking shift table chararacters. -doTest(times("a", LEN_7BIT_WITH_8BIT_REF * 2), false, - [2, LEN_7BIT_WITH_8BIT_REF, 0]); +addTest(times("a", LEN_7BIT_WITH_8BIT_REF * 2), false, + [2, LEN_7BIT_WITH_8BIT_REF, 0]); // |LEN_7BIT_WITH_8BIT_REF * 2 + 1| locking shift table chararacters. -doTest(times("a", LEN_7BIT_WITH_8BIT_REF * 2 + 1), false, - [3, LEN_7BIT_WITH_8BIT_REF, LEN_7BIT_WITH_8BIT_REF - 1]); +addTest(times("a", LEN_7BIT_WITH_8BIT_REF * 2 + 1), false, + [3, LEN_7BIT_WITH_8BIT_REF, LEN_7BIT_WITH_8BIT_REF - 1]); // Exactly 80 single shift table chararacters. -doTest(times("\u20ac", LEN_7BIT / 2), false, [1, LEN_7BIT, 0]); +addTest(times("\u20ac", LEN_7BIT / 2), false, [1, LEN_7BIT, 0]); // 81 single shift table chararacters. Because |Math.floor(153 / 2) = 76|, it // should left 5 septets in the 2nd segment. -doTest(times("\u20ac", LEN_7BIT / 2 + 1), false, - [2, LEN_7BIT_WITH_8BIT_REF, LEN_7BIT_WITH_8BIT_REF - 10]); +addTest(times("\u20ac", LEN_7BIT / 2 + 1), false, + [2, LEN_7BIT_WITH_8BIT_REF, LEN_7BIT_WITH_8BIT_REF - 10]); // |1 + 2 * 76| single shift table chararacters. We have only |153 - 76 * 2 = 1| // space left, but each single shift table character takes 2, so it will be // filled in the 3rd segment. -doTest(times("\u20ac", 1 + 2 * Math.floor(LEN_7BIT_WITH_8BIT_REF / 2)), false, - [3, LEN_7BIT_WITH_8BIT_REF, LEN_7BIT_WITH_8BIT_REF - 2]); +addTest(times("\u20ac", 1 + 2 * Math.floor(LEN_7BIT_WITH_8BIT_REF / 2)), false, + [3, LEN_7BIT_WITH_8BIT_REF, LEN_7BIT_WITH_8BIT_REF - 2]); // |2 * 76| single shift table chararacters + 1 locking shift table chararacter. -doTest("a" + times("\u20ac", 2 * Math.floor(LEN_7BIT_WITH_8BIT_REF / 2)), false, - [2, LEN_7BIT_WITH_8BIT_REF, 1]); -doTest(times("\u20ac", 2 * Math.floor(LEN_7BIT_WITH_8BIT_REF / 2)) + "a", false, - [2, LEN_7BIT_WITH_8BIT_REF, 0]); +addTest("a" + times("\u20ac", 2 * Math.floor(LEN_7BIT_WITH_8BIT_REF / 2)), false, + [2, LEN_7BIT_WITH_8BIT_REF, 1]); +addTest(times("\u20ac", 2 * Math.floor(LEN_7BIT_WITH_8BIT_REF / 2)) + "a", false, + [2, LEN_7BIT_WITH_8BIT_REF, 0]); // UCS2: // // '\u6afb' should be encoded as UCS2. -doTest("\u6afb", false, [1, LEN_UCS2, LEN_UCS2 - 1]); +addTest("\u6afb", false, [1, LEN_UCS2, LEN_UCS2 - 1]); // Combination of GSM 7bit alphabets. -doTest("\u6afba", false, [1, LEN_UCS2, LEN_UCS2 - 2]); -doTest("\u6afb\u20ac", false, [1, LEN_UCS2, LEN_UCS2 - 2]); -doTest("\u6afb ", false, [1, LEN_UCS2, LEN_UCS2 - 2]); +addTest("\u6afba", false, [1, LEN_UCS2, LEN_UCS2 - 2]); +addTest("\u6afb\u20ac", false, [1, LEN_UCS2, LEN_UCS2 - 2]); +addTest("\u6afb ", false, [1, LEN_UCS2, LEN_UCS2 - 2]); // UCS2 (multipart): // // Exactly 70 UCS2 chararacters. -doTest(times("\u6afb", LEN_UCS2), false, [1, LEN_UCS2, 0]); +addTest(times("\u6afb", LEN_UCS2), false, [1, LEN_UCS2, 0]); // 71 UCS2 chararacters. We'll have |71 - 67 = 4| chararacters in the 2nd // segment. -doTest(times("\u6afb", LEN_UCS2 + 1), false, - [2, LEN_UCS2_WITH_8BIT_REF, LEN_UCS2_WITH_8BIT_REF - 4]); +addTest(times("\u6afb", LEN_UCS2 + 1), false, + [2, LEN_UCS2_WITH_8BIT_REF, LEN_UCS2_WITH_8BIT_REF - 4]); // |LEN_UCS2_WITH_8BIT_REF * 2| ucs2 chararacters. -doTest(times("\u6afb", LEN_UCS2_WITH_8BIT_REF * 2), false, - [2, LEN_UCS2_WITH_8BIT_REF, 0]); +addTest(times("\u6afb", LEN_UCS2_WITH_8BIT_REF * 2), false, + [2, LEN_UCS2_WITH_8BIT_REF, 0]); // |LEN_7BIT_WITH_8BIT_REF * 2 + 1| ucs2 chararacters. -doTest(times("\u6afb", LEN_UCS2_WITH_8BIT_REF * 2 + 1), false, - [3, LEN_UCS2_WITH_8BIT_REF, LEN_UCS2_WITH_8BIT_REF - 1]); +addTest(times("\u6afb", LEN_UCS2_WITH_8BIT_REF * 2 + 1), false, + [3, LEN_UCS2_WITH_8BIT_REF, LEN_UCS2_WITH_8BIT_REF - 1]); // Strict 7-Bit Encoding: // // Should have no effect on GSM default alphabet characters. -doTest("\u0041", true, [1, LEN_7BIT, LEN_7BIT - 1]); +addTest("\u0041", true, [1, LEN_7BIT, LEN_7BIT - 1]); // "\u00c0"(À) should be mapped to "\u0041"(A). -doTest("\u00c0", true, [1, LEN_7BIT, LEN_7BIT - 1]); +addTest("\u00c0", true, [1, LEN_7BIT, LEN_7BIT - 1]); // Mixing mapped characters with unmapped ones. -doTest("\u00c0\u0041", true, [1, LEN_7BIT, LEN_7BIT - 2]); -doTest("\u0041\u00c0", true, [1, LEN_7BIT, LEN_7BIT - 2]); +addTest("\u00c0\u0041", true, [1, LEN_7BIT, LEN_7BIT - 2]); +addTest("\u0041\u00c0", true, [1, LEN_7BIT, LEN_7BIT - 2]); // UCS2 characters should be mapped to '*'. -doTest("\u1234", true, [1, LEN_7BIT, LEN_7BIT - 1]); +addTest("\u1234", true, [1, LEN_7BIT, LEN_7BIT - 1]); -cleanUp(); + +// WARNING: All tasks should be pushed before this!!! +tasks.push(function cleanUp() { + SpecialPowers.removePermission("sms", document); + SpecialPowers.clearUserPref("dom.sms.enabled"); + SpecialPowers.clearUserPref("dom.sms.strict7BitEncoding"); + finish(); +}); + +tasks.run(); diff --git a/dom/system/gonk/RadioInterfaceLayer.js b/dom/system/gonk/RadioInterfaceLayer.js index fb5c06529fc..ed9dea360c1 100644 --- a/dom/system/gonk/RadioInterfaceLayer.js +++ b/dom/system/gonk/RadioInterfaceLayer.js @@ -2994,7 +2994,7 @@ RadioInterface.prototype = { return options; }, - getSegmentInfoForText: function getSegmentInfoForText(text) { + getSegmentInfoForText: function getSegmentInfoForText(text, request) { let strict7BitEncoding; try { strict7BitEncoding = Services.prefs.getBoolPref("dom.sms.strict7BitEncoding"); @@ -3015,10 +3015,11 @@ RadioInterface.prototype = { charsInLastSegment = 0; } - let result = gMobileMessageService.createSmsSegmentInfo(options.segmentMaxSeq, - options.segmentChars, - options.segmentChars - charsInLastSegment); - return result; + let result = gMobileMessageService + .createSmsSegmentInfo(options.segmentMaxSeq, + options.segmentChars, + options.segmentChars - charsInLastSegment); + request.notifySegmentInfoForTextGot(result); }, sendSMS: function sendSMS(number, message, silent, request) { diff --git a/dom/system/gonk/nsIRadioInterfaceLayer.idl b/dom/system/gonk/nsIRadioInterfaceLayer.idl index 3b226a1eee4..71afdbcf8f5 100644 --- a/dom/system/gonk/nsIRadioInterfaceLayer.idl +++ b/dom/system/gonk/nsIRadioInterfaceLayer.idl @@ -6,7 +6,6 @@ interface nsIDOMMozIccInfo; interface nsIDOMMozMobileConnectionInfo; -interface nsIDOMMozSmsSegmentInfo; interface nsIMobileMessageCallback; [scriptable, uuid(1e602d20-d066-4399-8997-daf36b3158ef)] @@ -79,7 +78,7 @@ interface nsIRilContext : nsISupports readonly attribute nsIDOMMozMobileConnectionInfo data; }; -[scriptable, uuid(5efcd358-080e-46d6-a7f7-4f36c204eec3)] +[scriptable, uuid(a50d65aa-00da-11e3-b954-7bfb233d98fc)] interface nsIRadioInterface : nsISupports { readonly attribute nsIRilContext rilContext; @@ -99,7 +98,8 @@ interface nsIRadioInterface : nsISupports /** * SMS-related functionality. */ - nsIDOMMozSmsSegmentInfo getSegmentInfoForText(in DOMString text); + void getSegmentInfoForText(in DOMString text, + in nsIMobileMessageCallback request); void sendSMS(in DOMString number, in DOMString message, diff --git a/widget/android/AndroidBridge.cpp b/widget/android/AndroidBridge.cpp index e6bde9831d4..3d9bb375cb5 100644 --- a/widget/android/AndroidBridge.cpp +++ b/widget/android/AndroidBridge.cpp @@ -1658,16 +1658,18 @@ AndroidBridge::SetURITitle(const nsAString& aURI, const nsAString& aTitle) nsresult AndroidBridge::GetSegmentInfoForText(const nsAString& aText, - dom::mobilemessage::SmsSegmentInfoData* aData) + nsIMobileMessageCallback* aRequest) { #ifndef MOZ_WEBSMS_BACKEND return NS_ERROR_FAILURE; #else ALOG_BRIDGE("AndroidBridge::GetSegmentInfoForText"); - aData->segments() = 0; - aData->charsPerSegment() = 0; - aData->charsAvailableInLastSegment() = 0; + dom::mobilemessage::SmsSegmentInfoData data; + + data.segments() = 0; + data.charsPerSegment() = 0; + data.charsAvailableInLastSegment() = 0; JNIEnv *env = GetJNIEnv(); if (!env) @@ -1686,13 +1688,17 @@ AndroidBridge::GetSegmentInfoForText(const nsAString& aText, jint* info = env->GetIntArrayElements(arr, JNI_FALSE); - aData->segments() = info[0]; // msgCount - aData->charsPerSegment() = info[2]; // codeUnitsRemaining + data.segments() = info[0]; // msgCount + data.charsPerSegment() = info[2]; // codeUnitsRemaining // segmentChars = (codeUnitCount + codeUnitsRemaining) / msgCount - aData->charsAvailableInLastSegment() = (info[1] + info[2]) / info[0]; + data.charsAvailableInLastSegment() = (info[1] + info[2]) / info[0]; env->ReleaseIntArrayElements(arr, info, JNI_ABORT); - return NS_OK; + + // TODO Bug 908598 - Should properly use |QueueSmsRequest(...)| to queue up + // the nsIMobileMessageCallback just like other functions. + nsCOMPtr info = new SmsSegmentInfo(data); + return aRequest->NotifySegmentInfoForTextGot(info); #endif } diff --git a/widget/android/AndroidBridge.h b/widget/android/AndroidBridge.h index 311ecf8ce61..01e3d8bebc4 100644 --- a/widget/android/AndroidBridge.h +++ b/widget/android/AndroidBridge.h @@ -356,7 +356,7 @@ public: void GetCurrentBatteryInformation(hal::BatteryInformation* aBatteryInfo); nsresult GetSegmentInfoForText(const nsAString& aText, - dom::mobilemessage::SmsSegmentInfoData* aData); + nsIMobileMessageCallback* aRequest); void SendMessage(const nsAString& aNumber, const nsAString& aText, nsIMobileMessageCallback* aRequest); void GetMessage(int32_t aMessageId, nsIMobileMessageCallback* aRequest); From 7795aacd934038f0f28e07d80660f05dd601430b Mon Sep 17 00:00:00 2001 From: "Szu-Yu Chen [:aknow]" Date: Wed, 4 Sep 2013 08:30:31 -0400 Subject: [PATCH 035/171] Bug 909669 - Part 1: Change error code to InvalidParameter (idl). r=hsinyi --- dom/network/interfaces/nsIDOMMobileConnection.idl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dom/network/interfaces/nsIDOMMobileConnection.idl b/dom/network/interfaces/nsIDOMMobileConnection.idl index f4567571f9f..894715201f1 100644 --- a/dom/network/interfaces/nsIDOMMobileConnection.idl +++ b/dom/network/interfaces/nsIDOMMobileConnection.idl @@ -209,7 +209,7 @@ interface nsIDOMMozMobileConnection : nsIDOMEventTarget * * Otherwise, the request's onerror will be called, and the request's error * will be either 'RadioNotAvailable', 'RequestNotSupported', - * 'IllegalSIMorME', or 'GenericFailure' + * 'IllegalSIMorME', 'InvalidParameter', or 'GenericFailure' */ nsIDOMDOMRequest setCallForwardingOption(in nsIDOMMozMobileCFInfo CFInfo); @@ -226,7 +226,7 @@ interface nsIDOMMozMobileConnection : nsIDOMEventTarget * * Otherwise, the request's onerror will be called, and the request's error * will be either 'RadioNotAvailable', 'RequestNotSupported', - * or 'GenericFailure'. + * 'InvalidParameter', or 'GenericFailure'. */ nsIDOMDOMRequest getCallForwardingOption(in unsigned short reason); @@ -241,7 +241,7 @@ interface nsIDOMMozMobileConnection : nsIDOMEventTarget * * Otherwise, the request's onerror will be called, and the request's error * will be either 'RadioNotAvailable', 'RequestNotSupported', - * 'IllegalSIMorME', 'InvalidCallBarringOption' or 'GenericFailure' + * 'IllegalSIMorME', 'InvalidParameter', or 'GenericFailure' */ nsIDOMDOMRequest setCallBarringOption(in jsval option); @@ -259,7 +259,7 @@ interface nsIDOMMozMobileConnection : nsIDOMEventTarget * * Otherwise, the request's onerror will be called, and the request's error * will be either 'RadioNotAvailable', 'RequestNotSupported', - * 'InvalidCallBarringOption' or 'GenericFailure'. + * 'InvalidParameter', or 'GenericFailure'. */ nsIDOMDOMRequest getCallBarringOption(in jsval option); From 7855688d8b0199dd5f5f3533d6febcbbe6779513 Mon Sep 17 00:00:00 2001 From: "Szu-Yu Chen [:aknow]" Date: Wed, 4 Sep 2013 08:30:44 -0400 Subject: [PATCH 036/171] Bug 909669 - Part 2: Change error code to InvalidParameter (ril, test). r=hsinyi --- .../marionette/test_call_barring_set_error.js | 2 +- dom/system/gonk/RILContentHelper.js | 15 ++++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/dom/network/tests/marionette/test_call_barring_set_error.js b/dom/network/tests/marionette/test_call_barring_set_error.js index 0bc0c77a92a..437f4517587 100644 --- a/dom/network/tests/marionette/test_call_barring_set_error.js +++ b/dom/network/tests/marionette/test_call_barring_set_error.js @@ -53,7 +53,7 @@ function testSetCallBarringOptionError(option) { + JSON.stringify(option)); }; request.onerror = function(event) { - is(event.target.error.name, 'InvalidCallBarringOption', JSON.stringify(option)); + is(event.target.error.name, 'InvalidParameter', JSON.stringify(option)); nextTest(); }; } diff --git a/dom/system/gonk/RILContentHelper.js b/dom/system/gonk/RILContentHelper.js index c0c8356895e..16477d38d2f 100644 --- a/dom/system/gonk/RILContentHelper.js +++ b/dom/system/gonk/RILContentHelper.js @@ -643,7 +643,8 @@ RILContentHelper.prototype = { let requestId = this.getRequestId(request); if (!mode) { - this.dispatchFireRequestError(requestId, "InvalidParameter"); + this.dispatchFireRequestError(requestId, + RIL.GECKO_ERROR_INVALID_PARAMETER); return request; } @@ -1006,7 +1007,8 @@ RILContentHelper.prototype = { let requestId = this.getRequestId(request); if (!this._isValidCFReason(reason)){ - this.dispatchFireRequestError(requestId, "Invalid call forwarding reason."); + this.dispatchFireRequestError(requestId, + RIL.GECKO_ERROR_INVALID_PARAMETER); return request; } @@ -1032,7 +1034,8 @@ RILContentHelper.prototype = { if (!cfInfo || !this._isValidCFReason(cfInfo.reason) || !this._isValidCFAction(cfInfo.action)){ - this.dispatchFireRequestError(requestId, "Invalid call forwarding rule definition."); + this.dispatchFireRequestError(requestId, + RIL.GECKO_ERROR_INVALID_PARAMETER); return request; } @@ -1061,7 +1064,8 @@ RILContentHelper.prototype = { if (DEBUG) debug("getCallBarringOption: " + JSON.stringify(option)); if (!this._isValidCallBarringOption(option)) { - this.dispatchFireRequestError(requestId, "InvalidCallBarringOption"); + this.dispatchFireRequestError(requestId, + RIL.GECKO_ERROR_INVALID_PARAMETER); return request; } @@ -1087,7 +1091,8 @@ RILContentHelper.prototype = { if (DEBUG) debug("setCallBarringOption: " + JSON.stringify(option)); if (!this._isValidCallBarringOption(option, true)) { - this.dispatchFireRequestError(requestId, "InvalidCallBarringOption"); + this.dispatchFireRequestError(requestId, + RIL.GECKO_ERROR_INVALID_PARAMETER); return request; } From 8a8c486dcd8553689ae8bcebe94174707f151083 Mon Sep 17 00:00:00 2001 From: Gaia Pushbot Date: Wed, 4 Sep 2013 06:50:22 -0700 Subject: [PATCH 037/171] Bumping gaia.json for 1 gaia-central revision(s) ======== https://hg.mozilla.org/integration/gaia-central/rev/5fb9d168ff84 Author: b2gautomation Desc: Bug 907941 - gaia-ui-tests-pushbot (see bug) --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 7f18a25bb88..b9608ed3dd6 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,4 +1,4 @@ { - "revision": "e596cc6a1c092b728c02ba2be9a62e974661ce6a", + "revision": "5fb9d168ff842ba7442c61bb59daa70478bb9eb9", "repo_path": "/integration/gaia-central" } From fcb53583ebb8d3913e9be375762abfbdcc5ae802 Mon Sep 17 00:00:00 2001 From: Gaia Pushbot Date: Wed, 4 Sep 2013 07:45:21 -0700 Subject: [PATCH 038/171] Bumping gaia.json for 2 gaia-central revision(s) ======== https://hg.mozilla.org/integration/gaia-central/rev/d62883622e43 Author: Jose Antonio Olivera Ortega Desc: Merge pull request #11924 from jaoo/901227 Bug 901227 - APN Settings authType field typo error leads to data call error. r=arthurcc ======== https://hg.mozilla.org/integration/gaia-central/rev/8d4deebe3be4 Author: Jose Antonio Olivera Ortega Desc: Bug 901227 - APN Settings authType field typo error leads to data call error. r=arthurcc --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index b9608ed3dd6..635e6f6a8e1 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,4 +1,4 @@ { - "revision": "5fb9d168ff842ba7442c61bb59daa70478bb9eb9", + "revision": "d62883622e43ea6fa31cbfe40181f3835c55396e", "repo_path": "/integration/gaia-central" } From b22f25c5a0dff51969d1918eb9e1c7782fc21908 Mon Sep 17 00:00:00 2001 From: Gaia Pushbot Date: Wed, 4 Sep 2013 07:55:22 -0700 Subject: [PATCH 039/171] Bumping gaia.json for 2 gaia-central revision(s) ======== https://hg.mozilla.org/integration/gaia-central/rev/37a295e9b0c6 Author: Etienne Segonzac Desc: Merge pull request #11909 from etiennesegonzac/bug-912060-call-screen-exit-cleanup-and-fix Bug 912060 - Better and more tested call screen toggling ======== https://hg.mozilla.org/integration/gaia-central/rev/0485c79cd8d5 Author: Etienne Segonzac Desc: Bug 912060 - Better and more tested call screen toggling --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 635e6f6a8e1..1121eeeda3c 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,4 +1,4 @@ { - "revision": "d62883622e43ea6fa31cbfe40181f3835c55396e", + "revision": "37a295e9b0c6840f846e631b64cdd3963740a73c", "repo_path": "/integration/gaia-central" } From 5a7f0067444476b0c4674ae4e643d5fe099fca71 Mon Sep 17 00:00:00 2001 From: Edgar Chen Date: Mon, 12 Aug 2013 14:50:54 +0800 Subject: [PATCH 040/171] Bug 869778 - Part 1: Expose CDMA MIN to MozIccInfo. r=allstars.chh. sr=sicking --- dom/icc/interfaces/nsIDOMIccInfo.idl | 31 ++++++++++++++++++++++--- dom/icc/interfaces/nsIDOMIccManager.idl | 2 ++ 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/dom/icc/interfaces/nsIDOMIccInfo.idl b/dom/icc/interfaces/nsIDOMIccInfo.idl index ce82100f2e1..3a04fc95043 100644 --- a/dom/icc/interfaces/nsIDOMIccInfo.idl +++ b/dom/icc/interfaces/nsIDOMIccInfo.idl @@ -4,10 +4,17 @@ #include "nsISupports.idl" -[scriptable, uuid(a45c0fe0-c911-11e2-8b8b-0800200c9a66)] +[scriptable, uuid(dd9f229c-e5a6-453a-8388-950af0ff9918)] interface nsIDOMMozIccInfo : nsISupports { - /** + /** + * Integrated Circuit Card Type. + * + * Possible values: "sim", "usim", "ruim". + */ + readonly attribute DOMString iccType; + + /** * Integrated Circuit Card Identifier. */ readonly attribute DOMString iccid; @@ -36,10 +43,28 @@ interface nsIDOMMozIccInfo : nsISupports * Service provider name must be a part of displayed carrier name. */ readonly attribute boolean isDisplaySpnRequired; +}; +[scriptable, uuid(3c237e39-7af3-4748-baf4-4a3b6c3e0e66)] +interface nsIDOMMozGsmIccInfo : nsIDOMMozIccInfo +{ /** - * Mobile Station ISDN Number (MSISDN) of the subscriber's, aka + * Mobile Station ISDN Number (MSISDN) of the subscriber, aka * his phone number. */ readonly attribute DOMString msisdn; }; + +[scriptable, uuid(013e973e-8b56-4525-b634-d23166b86edb)] +interface nsIDOMMozCdmaIccInfo : nsIDOMMozIccInfo +{ + /** + * Mobile Directory Number (MDN) of the subscriber, aka his phone number. + */ + readonly attribute DOMString mdn; + + /** + * Mobile Identification Number (MIN) of the subscriber. + */ + readonly attribute DOMString min; +}; diff --git a/dom/icc/interfaces/nsIDOMIccManager.idl b/dom/icc/interfaces/nsIDOMIccManager.idl index fd4df4954a2..1fb00465612 100644 --- a/dom/icc/interfaces/nsIDOMIccManager.idl +++ b/dom/icc/interfaces/nsIDOMIccManager.idl @@ -280,6 +280,8 @@ interface nsIDOMMozIccManager : nsIDOMEventTarget /** * Information stored in the device's ICC card. + * + * Null if the card is not detected. */ readonly attribute nsIDOMMozIccInfo iccInfo; From 64455efdc72710f0e3840feea969a02b9248dc9e Mon Sep 17 00:00:00 2001 From: Edgar Chen Date: Wed, 21 Aug 2013 00:48:11 +0800 Subject: [PATCH 041/171] Bug 869778 - Part 2: Move mbdn to iccInfoPrivate. r=allstars.chh --- dom/system/gonk/ril_worker.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dom/system/gonk/ril_worker.js b/dom/system/gonk/ril_worker.js index e0844ec1996..cb761c0c90c 100644 --- a/dom/system/gonk/ril_worker.js +++ b/dom/system/gonk/ril_worker.js @@ -11077,11 +11077,11 @@ let ICCRecordHelper = { function callback(options) { let contact = GsmPDUHelper.readAlphaIdDiallingNumber(options.recordSize); if (!contact || - (RIL.iccInfo.mbdn !== undefined && - RIL.iccInfo.mbdn === contact.number)) { + (RIL.iccInfoPrivate.mbdn !== undefined && + RIL.iccInfoPrivate.mbdn === contact.number)) { return; } - RIL.iccInfo.mbdn = contact.number; + RIL.iccInfoPrivate.mbdn = contact.number; if (DEBUG) { debug("MBDN, alphaId="+contact.alphaId+" number="+contact.number); } From 042970044d8bf9962867fce957c21946b41bc72f Mon Sep 17 00:00:00 2001 From: Edgar Chen Date: Mon, 12 Aug 2013 14:59:17 +0800 Subject: [PATCH 042/171] Bug 869778 - Part 3: RIL implementation for CDMA MIN. r=allstars.chh --- dom/system/gonk/RILContentHelper.js | 86 +++++++++++++++++++++----- dom/system/gonk/RadioInterfaceLayer.js | 15 ++--- dom/system/gonk/ril_consts.js | 9 +++ dom/system/gonk/ril_worker.js | 26 +++++++- 4 files changed, 107 insertions(+), 29 deletions(-) diff --git a/dom/system/gonk/RILContentHelper.js b/dom/system/gonk/RILContentHelper.js index 16477d38d2f..b7bc9ce4aa9 100644 --- a/dom/system/gonk/RILContentHelper.js +++ b/dom/system/gonk/RILContentHelper.js @@ -45,8 +45,10 @@ if (DEBUG) { const RILCONTENTHELPER_CID = Components.ID("{472816e1-1fd6-4405-996c-806f9ea68174}"); -const ICCINFO_CID = - Components.ID("{fab2c0f0-d73a-11e2-8b8b-0800200c9a66}"); +const GSMICCINFO_CID = + Components.ID("{e0fa785b-ad3f-46ed-bc56-fcb0d6fe4fa8}"); +const CDMAICCINFO_CID = + Components.ID("{3d1f844f-9ec5-48fb-8907-aed2e5421709}"); const MOBILECONNECTIONINFO_CID = Components.ID("{a35cfd39-2d93-4489-ac7d-396475dacb27}"); const MOBILENETWORKINFO_CID = @@ -148,24 +150,50 @@ MobileIccCardLockRetryCount.prototype = { function IccInfo() {} IccInfo.prototype = { - QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMMozIccInfo]), - classID: ICCINFO_CID, - classInfo: XPCOMUtils.generateCI({ - classID: ICCINFO_CID, - classDescription: "IccInfo", - flags: Ci.nsIClassInfo.DOM_OBJECT, - interfaces: [Ci.nsIDOMMozIccInfo] - }), - - // nsIDOMMozIccInfo - + iccType: null, iccid: null, mcc: null, mnc: null, spn: null, + isDisplayNetworkNameRequired: null, + isDisplaySpnRequired: null +}; + +function GsmIccInfo() {} +GsmIccInfo.prototype = { + __proto__: IccInfo.prototype, + QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMMozGsmIccInfo]), + classID: GSMICCINFO_CID, + classInfo: XPCOMUtils.generateCI({ + classID: GSMICCINFO_CID, + classDescription: "MozGsmIccInfo", + flags: Ci.nsIClassInfo.DOM_OBJECT, + interfaces: [Ci.nsIDOMMozGsmIccInfo] + }), + + // nsIDOMMozGsmIccInfo + msisdn: null }; +function CdmaIccInfo() {} +CdmaIccInfo.prototype = { + __proto__: IccInfo.prototype, + QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMMozCdmaIccInfo]), + classID: CDMAICCINFO_CID, + classInfo: XPCOMUtils.generateCI({ + classID: CDMAICCINFO_CID, + classDescription: "MozCdmaIccInfo", + flags: Ci.nsIClassInfo.DOM_OBJECT, + interfaces: [Ci.nsIDOMMozCdmaIccInfo] + }), + + // nsIDOMMozCdmaIccInfo + + mdn: null, + min: null +}; + function VoicemailInfo() {} VoicemailInfo.prototype = { number: null, @@ -404,7 +432,7 @@ function RILContentHelper() { this.rilContext = { cardState: RIL.GECKO_CARDSTATE_UNKNOWN, networkSelectionMode: RIL.GECKO_NETWORK_SELECTION_UNKNOWN, - iccInfo: new IccInfo(), + iccInfo: null, voiceConnectionInfo: new MobileConnectionInfo(), dataConnectionInfo: new MobileConnectionInfo() }; @@ -472,7 +500,31 @@ RILContentHelper.prototype = { } this.updateInfo(srcNetwork, network); - }, + }, + + /** + * We need to consider below cases when update iccInfo: + * 1. Should clear iccInfo to null if there is no card detected. + * 2. Need to create corresponding object based on iccType. + */ + updateIccInfo: function updateIccInfo(newInfo) { + // Card is not detected, clear iccInfo to null. + if (!newInfo || !newInfo.iccType) { + this.rilContext.iccInfo = null; + return; + } + + // If iccInfo is null, new corresponding object based on iccType. + if (!this.rilContext.iccInfo) { + if (newInfo.iccType === "ruim" || newInfo.iccType === "csim") { + this.rilContext.iccInfo = new CdmaIccInfo(); + } else { + this.rilContext.iccInfo = new GsmIccInfo(); + } + } + + this.updateInfo(newInfo, this.rilContext.iccInfo); + }, _windowsMap: null, @@ -494,7 +546,7 @@ RILContentHelper.prototype = { } this.rilContext.cardState = rilContext.cardState; this.rilContext.networkSelectionMode = rilContext.networkSelectionMode; - this.updateInfo(rilContext.iccInfo, this.rilContext.iccInfo); + this.updateIccInfo(rilContext.iccInfo); this.updateConnectionInfo(rilContext.voice, this.rilContext.voiceConnectionInfo); this.updateConnectionInfo(rilContext.data, this.rilContext.dataConnectionInfo); @@ -1546,7 +1598,7 @@ RILContentHelper.prototype = { break; } case "RIL:IccInfoChanged": - this.updateInfo(msg.json.data, this.rilContext.iccInfo); + this.updateIccInfo(msg.json.data); this._deliverEvent("_iccListeners", "notifyIccInfoChanged", null); break; case "RIL:VoiceInfoChanged": diff --git a/dom/system/gonk/RadioInterfaceLayer.js b/dom/system/gonk/RadioInterfaceLayer.js index ed9dea360c1..bec339608bc 100644 --- a/dom/system/gonk/RadioInterfaceLayer.js +++ b/dom/system/gonk/RadioInterfaceLayer.js @@ -2222,21 +2222,14 @@ RadioInterface.prototype = { let oldIccInfo = this.rilContext.iccInfo; this.rilContext.iccInfo = message; - let iccInfoChanged = !oldIccInfo || - oldIccInfo.iccid != message.iccid || - oldIccInfo.mcc != message.mcc || - oldIccInfo.mnc != message.mnc || - oldIccInfo.spn != message.spn || - oldIccInfo.isDisplayNetworkNameRequired != message.isDisplayNetworkNameRequired || - oldIccInfo.isDisplaySpnRequired != message.isDisplaySpnRequired || - oldIccInfo.msisdn != message.msisdn; - if (!iccInfoChanged) { + if (!this.isInfoChanged(message, oldIccInfo)) { return; } // RIL:IccInfoChanged corresponds to a DOM event that gets fired only - // when the MCC or MNC codes have changed. + // when iccInfo has changed. gMessageManager.sendIccMessage("RIL:IccInfoChanged", - this.clientId, message); + this.clientId, + message.iccType ? message : null); // Update lastKnownSimMcc. if (message.mcc) { diff --git a/dom/system/gonk/ril_consts.js b/dom/system/gonk/ril_consts.js index c1bb002902e..0e4982d7dc1 100644 --- a/dom/system/gonk/ril_consts.js +++ b/dom/system/gonk/ril_consts.js @@ -370,6 +370,15 @@ this.CARD_APPTYPE_ISIM = 5; this.CARD_MAX_APPS = 8; +this.GECKO_CARD_TYPE = [ + null, + "sim", + "usim", + "ruim", + "csim", + "isim" +]; + this.NETWORK_STATE_UNKNOWN = "unknown"; this.NETWORK_STATE_AVAILABLE = "available"; this.NETWORK_STATE_CONNECTED = "connected"; diff --git a/dom/system/gonk/ril_worker.js b/dom/system/gonk/ril_worker.js index cb761c0c90c..8ffafbcf112 100644 --- a/dom/system/gonk/ril_worker.js +++ b/dom/system/gonk/ril_worker.js @@ -1314,6 +1314,10 @@ let RIL = { Buf.simpleRequest(REQUEST_EXIT_EMERGENCY_CALLBACK_MODE, options); }, + getCdmaSubscription: function getCdmaSubscription() { + Buf.simpleRequest(REQUEST_CDMA_SUBSCRIPTION); + }, + exitEmergencyCbMode: function exitEmergencyCbMode(options) { // The function could be called by an API from RadioInterfaceLayer or by // ril_worker itself. From ril_worker, we won't pass the parameter @@ -2929,6 +2933,9 @@ let RIL = { if (newCardState == this.cardState) { return; } + this.iccInfo = {iccType: null}; + ICCUtilsHelper.handleICCInfoChange(); + this.cardState = newCardState; this.sendChromeMessage({rilMessageType: "cardstatechange", cardState: this.cardState}); @@ -2980,6 +2987,8 @@ let RIL = { // This was moved down from CARD_APPSTATE_READY this.requestNetworkInfo(); if (newCardState == GECKO_CARDSTATE_READY) { + this.iccInfo.iccType = GECKO_CARD_TYPE[this.appType]; + // For type SIM, we need to check EF_phase first. // Other types of ICC we can send Terminal_Profile immediately. if (this.appType == CARD_APPTYPE_SIM) { @@ -5763,7 +5772,21 @@ RIL[REQUEST_GSM_SMS_BROADCAST_ACTIVATION] = null; RIL[REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG] = null; RIL[REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG] = null; RIL[REQUEST_CDMA_SMS_BROADCAST_ACTIVATION] = null; -RIL[REQUEST_CDMA_SUBSCRIPTION] = null; +RIL[REQUEST_CDMA_SUBSCRIPTION] = function REQUEST_CDMA_SUBSCRIPTION(length, options) { + if (options.rilRequestError) { + return; + } + + let result = Buf.readStringList(); + + this.iccInfo.mdn = result[0]; + // The result[1] is Home SID. (Already be handled in readCDMAHome()) + // The result[2] is Home NID. (Already be handled in readCDMAHome()) + this.iccInfo.min = result[3]; + // The result[4] is PRL version. + + ICCUtilsHelper.handleICCInfoChange(); +}; RIL[REQUEST_CDMA_WRITE_SMS_TO_RUIM] = null; RIL[REQUEST_CDMA_DELETE_SMS_ON_RUIM] = null; RIL[REQUEST_DEVICE_IDENTITY] = function REQUEST_DEVICE_IDENTITY(length, options) { @@ -12760,6 +12783,7 @@ let RuimRecordHelper = { RIL.getIMSI(); this.readCST(); this.readCDMAHome(); + RIL.getCdmaSubscription(); }, /** From 4672bbb630461735775cf431f7198c88fa0320cf Mon Sep 17 00:00:00 2001 From: Gregory Szorc Date: Tue, 3 Sep 2013 20:28:05 -0700 Subject: [PATCH 043/171] Bug 896797 - Part 2: Don't list autogenerated files in EXPORTS; r=glandium --- accessible/public/ia2/Makefile.in | 5 +++ accessible/public/ia2/moz.build | 44 ------------------- accessible/public/msaa/Makefile.in | 14 ++++++ accessible/public/msaa/moz.build | 9 ---- accessible/src/xpcom/Makefile.in | 5 +++ accessible/src/xpcom/moz.build | 4 -- dom/bindings/Makefile.in | 1 + dom/bindings/moz.build | 1 - gfx/cairo/cairo/src/Makefile.in | 5 +++ gfx/cairo/cairo/src/moz.build | 1 - gfx/layers/moz.build | 8 ++-- js/src/Makefile.in | 10 +++++ js/src/moz.build | 6 --- js/xpconnect/src/Makefile.in | 17 +++---- js/xpconnect/src/moz.build | 1 - layout/style/Makefile.in | 5 +++ layout/style/moz.build | 1 - netwerk/Makefile.in | 15 +++++++ netwerk/moz.build | 5 --- .../mozbuild/backend/recursivemake.py | 12 +++-- .../mozbuild/test/backend/data/exports/dom1.h | 0 .../mozbuild/test/backend/data/exports/dom2.h | 0 .../mozbuild/test/backend/data/exports/foo.h | 0 .../mozbuild/test/backend/data/exports/gfx.h | 0 .../test/backend/data/exports/mozilla1.h | 0 .../test/backend/data/exports/mozilla2.h | 0 .../test/backend/data/exports/pprio.h | 0 toolkit/components/telemetry/Makefile.in | 5 +++ toolkit/components/telemetry/moz.build | 1 - uriloader/exthandler/moz.build | 8 ++-- xpcom/Makefile.in | 15 +++++++ xpcom/base/Makefile.in | 8 ++++ xpcom/base/moz.build | 2 - xpcom/moz.build | 5 --- 34 files changed, 114 insertions(+), 99 deletions(-) create mode 100644 netwerk/Makefile.in create mode 100644 python/mozbuild/mozbuild/test/backend/data/exports/dom1.h create mode 100644 python/mozbuild/mozbuild/test/backend/data/exports/dom2.h create mode 100644 python/mozbuild/mozbuild/test/backend/data/exports/foo.h create mode 100644 python/mozbuild/mozbuild/test/backend/data/exports/gfx.h create mode 100644 python/mozbuild/mozbuild/test/backend/data/exports/mozilla1.h create mode 100644 python/mozbuild/mozbuild/test/backend/data/exports/mozilla2.h create mode 100644 python/mozbuild/mozbuild/test/backend/data/exports/pprio.h create mode 100644 xpcom/Makefile.in diff --git a/accessible/public/ia2/Makefile.in b/accessible/public/ia2/Makefile.in index ba08b512606..35fd596d697 100644 --- a/accessible/public/ia2/Makefile.in +++ b/accessible/public/ia2/Makefile.in @@ -67,6 +67,11 @@ MIDL_GENERATED_FILES = \ EMBED_MANIFEST_AT = 2 +INSTALL_TARGETS += midl +midl_FILES := $(filter %.h %_i.c,$(MIDL_GENERATED_FILES)) +midl_DEST = $(DIST)/include +midl_TARGET := export + include $(topsrcdir)/config/rules.mk OS_LIBS = $(call EXPAND_LIBNAME,uuid kernel32 rpcns4 rpcrt4 ole32 oleaut32) diff --git a/accessible/public/ia2/moz.build b/accessible/public/ia2/moz.build index 308e3aaeb26..ba9c2b6207f 100644 --- a/accessible/public/ia2/moz.build +++ b/accessible/public/ia2/moz.build @@ -5,49 +5,5 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. MODULE = 'accessibility' - -# Please keep this list in sync with the Makefile.in until the rest of that file -# is ported over. -midl_interfaces = [ - 'Accessible2', - 'Accessible2_2', - 'AccessibleAction', - 'AccessibleApplication', - 'AccessibleComponent', - 'AccessibleDocument', - 'AccessibleEditableText', - 'AccessibleHyperlink', - 'AccessibleHypertext', - 'AccessibleHypertext2', - 'AccessibleImage', - 'AccessibleRelation', - 'AccessibleTable', - 'AccessibleTable2', - 'AccessibleTableCell', - 'AccessibleText', - 'AccessibleText2', - 'AccessibleValue', -] - -# Please keep this list in sync with the Makefile.in until the rest of that file -# is ported over. -midl_enums = [ - 'AccessibleEventId', - 'AccessibleRole', - 'AccessibleStates', - 'IA2CommonTypes', -] - -headers = ['%s.h' % x for x in midl_enums] -interfaces_h = ['%s.h' % x for x in midl_interfaces] -interfaces_c = ['%s_i.c' % x for x in midl_interfaces] - -# The underscore throws off sorting and EXPORTS expects sorted lists. -interfaces_c.sort() - -EXPORTS += headers -EXPORTS += interfaces_h -EXPORTS += interfaces_c - LIBRARY_NAME = 'IA2Marshal' diff --git a/accessible/public/msaa/Makefile.in b/accessible/public/msaa/Makefile.in index 452959f73fb..a72b5c89d80 100644 --- a/accessible/public/msaa/Makefile.in +++ b/accessible/public/msaa/Makefile.in @@ -60,5 +60,19 @@ register:: EMBED_MANIFEST_AT = 2 +midl_exports := \ + ISimpleDOMDocument.h \ + ISimpleDOMDocument_i.c \ + ISimpleDOMNode.h \ + ISimpleDOMNode_i.c \ + ISimpleDOMText.h \ + ISimpleDOMText_i.c \ + $(NULL) + +INSTALL_TARGETS += midl_exports +midl_exports_FILES := $(midl_exports) +midl_exports_DEST = $(DIST)/include +midl_exports_TARGET := export + include $(topsrcdir)/config/rules.mk diff --git a/accessible/public/msaa/moz.build b/accessible/public/msaa/moz.build index d4cace7276a..0b8d28869db 100644 --- a/accessible/public/msaa/moz.build +++ b/accessible/public/msaa/moz.build @@ -6,14 +6,5 @@ MODULE = 'accessibility' -EXPORTS += [ - 'ISimpleDOMDocument.h', - 'ISimpleDOMDocument_i.c', - 'ISimpleDOMNode.h', - 'ISimpleDOMNode_i.c', - 'ISimpleDOMText.h', - 'ISimpleDOMText_i.c', -] - LIBRARY_NAME = 'AccessibleMarshal' diff --git a/accessible/src/xpcom/Makefile.in b/accessible/src/xpcom/Makefile.in index a87748938cc..d8e5659645c 100644 --- a/accessible/src/xpcom/Makefile.in +++ b/accessible/src/xpcom/Makefile.in @@ -11,6 +11,11 @@ include $(DEPTH)/config/autoconf.mk EXTRA_MDDEPEND_FILES = xpcAccEvents.pp +INSTALL_TARGETS += xpcaccevents +xpcaccevents_FILES := xpcAccEvents.h +xpcaccevents_DEST = $(DIST)/include +xpcaccevents_TARGET := export + include $(topsrcdir)/config/rules.mk LOCAL_INCLUDES = \ diff --git a/accessible/src/xpcom/moz.build b/accessible/src/xpcom/moz.build index 9bbe8560717..da9fcd374cb 100644 --- a/accessible/src/xpcom/moz.build +++ b/accessible/src/xpcom/moz.build @@ -6,10 +6,6 @@ MODULE = 'accessibility' -EXPORTS += [ - 'xpcAccEvents.h', -] - CPP_SOURCES += [ 'nsAccessibleRelation.cpp', 'xpcAccEvents.cpp', diff --git a/dom/bindings/Makefile.in b/dom/bindings/Makefile.in index b4fc965b457..78b39789502 100644 --- a/dom/bindings/Makefile.in +++ b/dom/bindings/Makefile.in @@ -110,6 +110,7 @@ INSTALL_TARGETS += EXPORTS_GENERATED # be in the same target/subtier as GlobalGen.py, otherwise the files will not # get installed into the appropriate location as they are generated. globalgen_headers_FILES := \ + GeneratedAtomList.h \ PrototypeList.h \ RegisterBindings.h \ UnionConversions.h \ diff --git a/dom/bindings/moz.build b/dom/bindings/moz.build index 69b28606ed6..3368a276e81 100644 --- a/dom/bindings/moz.build +++ b/dom/bindings/moz.build @@ -21,7 +21,6 @@ EXPORTS.mozilla.dom += [ 'DOMJSProxyHandler.h', 'Date.h', 'Errors.msg', - 'GeneratedAtomList.h', 'JSSlots.h', 'NonRefcountedDOMObject.h', 'Nullable.h', diff --git a/gfx/cairo/cairo/src/Makefile.in b/gfx/cairo/cairo/src/Makefile.in index 21e1506502e..993d7d2d6c7 100644 --- a/gfx/cairo/cairo/src/Makefile.in +++ b/gfx/cairo/cairo/src/Makefile.in @@ -93,6 +93,11 @@ endif LOCAL_INCLUDES += -I$(srcdir) +INSTALL_TARGETS += cairo_features +cairo_features_FILES := cairo-features.h +cairo_features_DEST = $(DIST)/include/cairo +cairo_features_TARGET := export + include $(topsrcdir)/config/rules.mk ifdef GNU_CC diff --git a/gfx/cairo/cairo/src/moz.build b/gfx/cairo/cairo/src/moz.build index 53535922c5a..afe9dcf114c 100644 --- a/gfx/cairo/cairo/src/moz.build +++ b/gfx/cairo/cairo/src/moz.build @@ -10,7 +10,6 @@ MODULE = 'cairo' EXPORTS.cairo += [ 'cairo-deprecated.h', - 'cairo-features.h', 'cairo-platform.h', 'cairo-rename.h', 'cairo-tee.h', diff --git a/gfx/layers/moz.build b/gfx/layers/moz.build index 529846e1853..1c49fb3efae 100644 --- a/gfx/layers/moz.build +++ b/gfx/layers/moz.build @@ -53,8 +53,8 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows': 'd3d9/LayerManagerD3D9.h', ] EXPORTS.mozilla.layers += [ - 'CompositorD3D9.h', - 'TextureD3D9.h', + 'd3d9/CompositorD3D9.h', + 'd3d9/TextureD3D9.h', ] CPP_SOURCES += [ 'CompositorD3D9.cpp', @@ -100,8 +100,6 @@ EXPORTS.mozilla.layers += [ 'CompositorTypes.h', 'D3D9SurfaceImage.h', 'Effects.h', - 'GrallocTextureClient.h', - 'GrallocTextureHost.h', 'ImageDataSerializer.h', 'LayersTypes.h', 'RenderTrace.h', @@ -145,6 +143,8 @@ EXPORTS.mozilla.layers += [ 'ipc/TaskThrottler.h', 'opengl/CompositingRenderTargetOGL.h', 'opengl/CompositorOGL.h', + 'opengl/GrallocTextureClient.h', + 'opengl/GrallocTextureHost.h', 'opengl/TextureClientOGL.h', 'opengl/TextureHostOGL.h', ] diff --git a/js/src/Makefile.in b/js/src/Makefile.in index 0f860609431..2439e81e72b 100644 --- a/js/src/Makefile.in +++ b/js/src/Makefile.in @@ -201,6 +201,16 @@ symverscript: symverscript.in EXTRA_DEPS += symverscript endif +export_files = js-config.h +ifdef HAVE_DTRACE +export_files += $(CURDIR)/javascript-trace.h +endif + +INSTALL_TARGETS += jsconfig +jsconfig_FILES = $(export_files) +jsconfig_DEST = $(DIST)/include +jsconfig_TARGETS := export + include $(topsrcdir)/config/rules.mk ifdef JS_HAS_CTYPES diff --git a/js/src/moz.build b/js/src/moz.build index 850f778eb49..e9348ff0953 100644 --- a/js/src/moz.build +++ b/js/src/moz.build @@ -31,7 +31,6 @@ CONFIGURE_SUBST_FILES += ['devtools/rootAnalysis/Makefile'] # browser builds. Don't add new files here unless you know what you're # doing! EXPORTS += [ - 'js-config.h', 'js.msg', 'jsalloc.h', 'jsapi.h', @@ -49,11 +48,6 @@ EXPORTS += [ 'perf/jsperf.h', ] -if CONFIG['HAVE_DTRACE']: - EXPORTS += [ - '$(CURDIR)/javascript-trace.h', - ] - # If you add a header here, add it to js/src/jsapi-tests/testIntTypesABI.cpp so # that we ensure we don't over-expose our internal integer typedefs. Note that # LegacyIntTypes.h below is deliberately exempted from this requirement. diff --git a/js/xpconnect/src/Makefile.in b/js/xpconnect/src/Makefile.in index 74105ae9933..2911973d5fd 100644 --- a/js/xpconnect/src/Makefile.in +++ b/js/xpconnect/src/Makefile.in @@ -40,6 +40,15 @@ SHARED_LIBRARY_LIBS = \ EXTRA_MDDEPEND_FILES = dom_qsgen.pp dictionary_helper_gen.pp event_impl_gen.pp +INSTALL_TARGETS += extra_export_files +extra_export_files_FILES := \ + DictionaryHelpers.h \ + GeneratedEventClasses.h \ + GeneratedEvents.h \ + $(NULL) +extra_export_files_DEST = $(DIST)/include +extra_export_files_TARGET := export + include $(topsrcdir)/config/rules.mk include $(topsrcdir)/ipc/chromium/chromium-config.mk @@ -147,14 +156,6 @@ GeneratedEvents-webidl: event_impl_gen.conf --webidltarget=$(top_srcdir)/dom/webidl \ event_impl_gen.conf -_EXTRA_EXPORT_FILES = \ - DictionaryHelpers.h \ - GeneratedEventClasses.h \ - $(NULL) - -libs:: $(_EXTRA_EXPORT_FILES) - $(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/dist/include - GARBAGE += \ dom_quickstubs.h \ dom_quickstubs.cpp \ diff --git a/js/xpconnect/src/moz.build b/js/xpconnect/src/moz.build index b47d77abd48..5d6ff8bd59c 100644 --- a/js/xpconnect/src/moz.build +++ b/js/xpconnect/src/moz.build @@ -8,7 +8,6 @@ MODULE = 'xpconnect' EXPORTS += [ 'BackstagePass.h', - 'GeneratedEvents.h', 'XPCJSMemoryReporter.h', 'nsCxPusher.h', 'qsObjectHelper.h', diff --git a/layout/style/Makefile.in b/layout/style/Makefile.in index e526b903499..776f3bea45f 100644 --- a/layout/style/Makefile.in +++ b/layout/style/Makefile.in @@ -14,6 +14,11 @@ OS_CFLAGS := $(OS_CFLAGS) -Wshadow OS_CXXFLAGS := $(OS_CXXFLAGS) -Wshadow endif +INSTALL_TARGETS += structlist +structlist_FILES := nsStyleStructList.h +structlist_DEST = $(DIST)/include +structlist_TARGET := export + include $(topsrcdir)/config/rules.mk include $(topsrcdir)/ipc/chromium/chromium-config.mk diff --git a/layout/style/moz.build b/layout/style/moz.build index 0d4ed279a21..5bf1ae4184c 100644 --- a/layout/style/moz.build +++ b/layout/style/moz.build @@ -54,7 +54,6 @@ EXPORTS += [ 'nsStyleStruct.h', 'nsStyleStructFwd.h', 'nsStyleStructInlines.h', - 'nsStyleStructList.h', 'nsStyleTransformMatrix.h', 'nsStyleUtil.h', ] diff --git a/netwerk/Makefile.in b/netwerk/Makefile.in new file mode 100644 index 00000000000..900f0ea07a1 --- /dev/null +++ b/netwerk/Makefile.in @@ -0,0 +1,15 @@ +# 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/. + +DEPTH := @DEPTH@ +topsrcdir := @top_srcdir@ +srcdir := @srcdir@ +VPATH := @srcdir@ + +INSTALL_TARGETS += neckoconfig +neckoconfig_FILES := necko-config.h +neckoconfig_DEST = $(DIST)/include +neckoconfig_TARGET := export + +include $(topsrcdir)/config/rules.mk diff --git a/netwerk/moz.build b/netwerk/moz.build index ad37d15c7cc..9a2dfa6d13b 100644 --- a/netwerk/moz.build +++ b/netwerk/moz.build @@ -35,8 +35,3 @@ DIRS += ['build'] TEST_TOOL_DIRS += ['test'] MODULE = 'necko' - -EXPORTS += [ - 'necko-config.h', -] - diff --git a/python/mozbuild/mozbuild/backend/recursivemake.py b/python/mozbuild/mozbuild/backend/recursivemake.py index 05b08ef56ed..4527e3cf477 100644 --- a/python/mozbuild/mozbuild/backend/recursivemake.py +++ b/python/mozbuild/mozbuild/backend/recursivemake.py @@ -208,7 +208,7 @@ class RecursiveMakeBackend(CommonBackend): else: backend_file.write('%s := %s\n' % (k, v)) elif isinstance(obj, Exports): - self._process_exports(obj.exports, backend_file) + self._process_exports(obj, obj.exports, backend_file) elif isinstance(obj, IPDLFile): self._ipdl_sources.add(mozpath.join(obj.srcdir, obj.basename)) @@ -367,7 +367,7 @@ class RecursiveMakeBackend(CommonBackend): fh.write('PARALLEL_DIRS += %s\n' % ' '.join(obj.parallel_external_make_dirs)) - def _process_exports(self, exports, backend_file, namespace=""): + def _process_exports(self, obj, exports, backend_file, namespace=""): strings = exports.get_strings() if namespace: if strings: @@ -383,13 +383,17 @@ class RecursiveMakeBackend(CommonBackend): backend_file.write('%s += %s\n' % (export_name, ' '.join(strings))) for s in strings: + source = os.path.normpath(os.path.join(obj.srcdir, s)) + if not os.path.isfile(source): + raise Exception('File listed in EXPORTS does not exist: %s' % source) + p = '%s%s' % (namespace, s) self._purge_manifests['dist_include'].add(p) children = exports.get_children() for subdir in sorted(children): - self._process_exports(children[subdir], backend_file, - namespace=namespace + subdir) + self._process_exports(obj, children[subdir], backend_file, + namespace=namespace + subdir) def _handle_idl_manager(self, manager): build_files = self._purge_manifests['xpidl'] diff --git a/python/mozbuild/mozbuild/test/backend/data/exports/dom1.h b/python/mozbuild/mozbuild/test/backend/data/exports/dom1.h new file mode 100644 index 00000000000..e69de29bb2d diff --git a/python/mozbuild/mozbuild/test/backend/data/exports/dom2.h b/python/mozbuild/mozbuild/test/backend/data/exports/dom2.h new file mode 100644 index 00000000000..e69de29bb2d diff --git a/python/mozbuild/mozbuild/test/backend/data/exports/foo.h b/python/mozbuild/mozbuild/test/backend/data/exports/foo.h new file mode 100644 index 00000000000..e69de29bb2d diff --git a/python/mozbuild/mozbuild/test/backend/data/exports/gfx.h b/python/mozbuild/mozbuild/test/backend/data/exports/gfx.h new file mode 100644 index 00000000000..e69de29bb2d diff --git a/python/mozbuild/mozbuild/test/backend/data/exports/mozilla1.h b/python/mozbuild/mozbuild/test/backend/data/exports/mozilla1.h new file mode 100644 index 00000000000..e69de29bb2d diff --git a/python/mozbuild/mozbuild/test/backend/data/exports/mozilla2.h b/python/mozbuild/mozbuild/test/backend/data/exports/mozilla2.h new file mode 100644 index 00000000000..e69de29bb2d diff --git a/python/mozbuild/mozbuild/test/backend/data/exports/pprio.h b/python/mozbuild/mozbuild/test/backend/data/exports/pprio.h new file mode 100644 index 00000000000..e69de29bb2d diff --git a/toolkit/components/telemetry/Makefile.in b/toolkit/components/telemetry/Makefile.in index 96de16c4932..c91cbad5609 100644 --- a/toolkit/components/telemetry/Makefile.in +++ b/toolkit/components/telemetry/Makefile.in @@ -30,6 +30,11 @@ ifdef MOZ_HISTOGRAMS_VERSION DEFINES += -DHISTOGRAMS_FILE_VERSION="$(MOZ_HISTOGRAMS_VERSION)" endif +INSTALL_TARGETS += histoenums +histoenums_FILES := TelemetryHistogramEnums.h +histoenums_DEST = $(DIST)/include/mozilla +histoenums_TARGET := export + include $(topsrcdir)/config/rules.mk include $(topsrcdir)/ipc/chromium/chromium-config.mk diff --git a/toolkit/components/telemetry/moz.build b/toolkit/components/telemetry/moz.build index 363cff19012..bb4f01a543b 100644 --- a/toolkit/components/telemetry/moz.build +++ b/toolkit/components/telemetry/moz.build @@ -16,7 +16,6 @@ MODULE = 'telemetry' EXPORTS.mozilla += [ 'ProcessedStack.h', 'Telemetry.h', - 'TelemetryHistogramEnums.h', ] CPP_SOURCES += [ diff --git a/uriloader/exthandler/moz.build b/uriloader/exthandler/moz.build index ed9a37031d6..78f69f77031 100644 --- a/uriloader/exthandler/moz.build +++ b/uriloader/exthandler/moz.build @@ -42,12 +42,14 @@ EXPORTS += [ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android': EXPORTS += [ - 'nsExternalSharingAppService.h', - 'nsExternalURLHandlerService.h', + osdir + '/nsExternalSharingAppService.h', + osdir + '/nsExternalURLHandlerService.h', ] if CONFIG['MOZ_ENABLE_MEEGOTOUCHSHARE']: - EXPORTS += ['nsExternalSharingAppService.h'] + EXPORTS += [ + osdir + '/nsExternalSharingAppService.h', + ] EXPORTS.mozilla.dom += [ 'ExternalHelperAppChild.h', diff --git a/xpcom/Makefile.in b/xpcom/Makefile.in new file mode 100644 index 00000000000..e7f6c35a192 --- /dev/null +++ b/xpcom/Makefile.in @@ -0,0 +1,15 @@ +# 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/. + +DEPTH := @DEPTH@ +topsrcdir := @top_srcdir@ +srcdir := @srcdir@ +VPATH := @srcdir@ + +INSTALL_TARGETS += xpcom +xpcom_FILES := xpcom-config.h +xpcom_DEST = $(DIST)/include +xpcom_TARGET := export + +include $(topsrcdir)/config/rules.mk diff --git a/xpcom/base/Makefile.in b/xpcom/base/Makefile.in index cdb4b4ae698..5e34139d291 100644 --- a/xpcom/base/Makefile.in +++ b/xpcom/base/Makefile.in @@ -19,6 +19,14 @@ endif endif #if OS_ARCH == WINNT +INSTALL_TARGETS += errorlist +errorlist_FILES := \ + ErrorListCDefines.h \ + ErrorListCxxDefines.h \ + $(NULL) +errorlist_DEST = $(DIST)/include +errorlist_TARGET := export + include $(topsrcdir)/config/rules.mk include $(topsrcdir)/ipc/chromium/chromium-config.mk diff --git a/xpcom/base/moz.build b/xpcom/base/moz.build index b46a78f0cec..8a6c76f29be 100644 --- a/xpcom/base/moz.build +++ b/xpcom/base/moz.build @@ -43,8 +43,6 @@ MODULE = 'xpcom' EXPORTS += [ 'ErrorList.h', - 'ErrorListCDefines.h', - 'ErrorListCxxDefines.h', 'nsAgg.h', 'nsAutoPtr.h', 'nsAutoRef.h', diff --git a/xpcom/moz.build b/xpcom/moz.build index 133e68d21ed..3ff09e57340 100644 --- a/xpcom/moz.build +++ b/xpcom/moz.build @@ -39,8 +39,3 @@ if CONFIG['DEHYDRA_PATH']: DIRS += ['analysis'] MODULE = 'xpcom' - -# xpcom-config.h is generated by configure -EXPORTS += [ - 'xpcom-config.h', -] From fe08b9fbf78a1267a85823eb3cf5eaf93c78a40f Mon Sep 17 00:00:00 2001 From: Gregory Szorc Date: Tue, 3 Sep 2013 22:51:58 -0700 Subject: [PATCH 044/171] Bug 896797 - Part 3: Use install manifests for managing dist/include; r=glandium --- Makefile.in | 1 + js/src/Makefile.in | 1 + .../action/process_install_manifest.py | 9 +++-- .../mozbuild/backend/recursivemake.py | 34 +++++++---------- python/mozbuild/mozbuild/frontend/data.py | 6 ++- python/mozbuild/mozbuild/frontend/emitter.py | 3 +- .../test/backend/test_recursivemake.py | 38 +++++-------------- 7 files changed, 38 insertions(+), 54 deletions(-) diff --git a/Makefile.in b/Makefile.in index 3d3bc0f5bce..6bfc1eff78b 100644 --- a/Makefile.in +++ b/Makefile.in @@ -62,6 +62,7 @@ ifndef MOZ_PROFILE_USE default alldep all:: CLOBBER $(topsrcdir)/configure config.status backend.RecursiveMakeBackend.built $(call SUBMAKE,backend.RecursiveMakeBackend.built,js/src,1) $(call py_action,purge_manifests,-d _build_manifests/purge .) + $(call py_action,process_install_manifest,$(DIST)/include _build_manifests/install/dist_include js/src/_build_manifests/install/dist_include) endif CLOBBER: $(topsrcdir)/CLOBBER diff --git a/js/src/Makefile.in b/js/src/Makefile.in index 2439e81e72b..8e6996e1e48 100644 --- a/js/src/Makefile.in +++ b/js/src/Makefile.in @@ -177,6 +177,7 @@ MOZILLA_DTRACE_SRC = $(srcdir)/devtools/javascript-trace.d endif default:: + $(call py_action,process_install_manifest,--no-remove $(DIST)/include _build_manifests/install/dist_include) ifneq (,$(CROSS_COMPILE)$(filter-out WINNT OS2,$(OS_ARCH))) # nsinstall doesn't get built until we enter config/ in the exports phase, diff --git a/python/mozbuild/mozbuild/action/process_install_manifest.py b/python/mozbuild/mozbuild/action/process_install_manifest.py index 33468703145..9c5aec14196 100644 --- a/python/mozbuild/mozbuild/action/process_install_manifest.py +++ b/python/mozbuild/mozbuild/action/process_install_manifest.py @@ -13,14 +13,14 @@ COMPLETE = 'From {dest}: Kept {existing} existing; Added/updated {updated}; ' \ 'Removed {rm_files} files and {rm_dirs} directories.' -def process_manifest(destdir, *paths): +def process_manifest(destdir, paths, remove_unaccounted=True): manifest = InstallManifest() for path in paths: manifest |= InstallManifest(path=path) copier = FileCopier() manifest.populate_registry(copier) - return copier.copy(destdir) + return copier.copy(destdir, remove_unaccounted=remove_unaccounted) if __name__ == '__main__': @@ -29,10 +29,13 @@ if __name__ == '__main__': parser.add_argument('destdir', help='Destination directory.') parser.add_argument('manifests', nargs='+', help='Path to manifest file(s).') + parser.add_argument('--no-remove', action='store_true', + help='Do not remove unaccounted files from destination.') args = parser.parse_args() - result = process_manifest(args.destdir, *args.manifests) + result = process_manifest(args.destdir, args.manifests, + remove_unaccounted=not args.no_remove) print(COMPLETE.format(dest=args.destdir, existing=result.existing_files_count, diff --git a/python/mozbuild/mozbuild/backend/recursivemake.py b/python/mozbuild/mozbuild/backend/recursivemake.py index 4527e3cf477..765f329d004 100644 --- a/python/mozbuild/mozbuild/backend/recursivemake.py +++ b/python/mozbuild/mozbuild/backend/recursivemake.py @@ -149,11 +149,8 @@ class RecursiveMakeBackend(CommonBackend): self.backend_input_files.add(os.path.join(self.environment.topobjdir, 'config', 'autoconf.mk')) - self._install_manifests = dict() - self._purge_manifests = dict( dist_bin=PurgeManifest(relpath='dist/bin'), - dist_include=PurgeManifest(relpath='dist/include'), dist_private=PurgeManifest(relpath='dist/private'), dist_public=PurgeManifest(relpath='dist/public'), dist_sdk=PurgeManifest(relpath='dist/sdk'), @@ -163,6 +160,7 @@ class RecursiveMakeBackend(CommonBackend): self._install_manifests = dict( dist_idl=InstallManifest(), + dist_include=InstallManifest(), ) def _update_from_avoid_write(self, result): @@ -368,27 +366,22 @@ class RecursiveMakeBackend(CommonBackend): ' '.join(obj.parallel_external_make_dirs)) def _process_exports(self, obj, exports, backend_file, namespace=""): + # This may not be needed, but is present for backwards compatibility + # with the old make rules, just in case. + if not obj.dist_install: + return + strings = exports.get_strings() if namespace: - if strings: - backend_file.write('EXPORTS_NAMESPACES += %s\n' % namespace) - export_name = 'EXPORTS_%s' % namespace namespace += '/' - else: - export_name = 'EXPORTS' - # Iterate over the list of export filenames, printing out an EXPORTS - # declaration for each. - if strings: - backend_file.write('%s += %s\n' % (export_name, ' '.join(strings))) + for s in strings: + source = os.path.normpath(os.path.join(obj.srcdir, s)) + dest = '%s%s' % (namespace, os.path.basename(s)) + self._install_manifests['dist_include'].add_symlink(source, dest) - for s in strings: - source = os.path.normpath(os.path.join(obj.srcdir, s)) - if not os.path.isfile(source): - raise Exception('File listed in EXPORTS does not exist: %s' % source) - - p = '%s%s' % (namespace, s) - self._purge_manifests['dist_include'].add(p) + if not os.path.exists(source): + raise Exception('File listed in EXPORTS does not exist: %s' % source) children = exports.get_children() for subdir in sorted(children): @@ -405,7 +398,8 @@ class RecursiveMakeBackend(CommonBackend): for idl in manager.idls.values(): self._install_manifests['dist_idl'].add_symlink(idl['source'], idl['basename']) - self._purge_manifests['dist_include'].add('%s.h' % idl['root']) + self._install_manifests['dist_include'].add_optional_exists('%s.h' + % idl['root']) build_files.add(mozpath.join('headers', '%s.h' % idl['root'])) for module in manager.modules: diff --git a/python/mozbuild/mozbuild/frontend/data.py b/python/mozbuild/mozbuild/frontend/data.py index 0ca88f36cdf..9db3d89079c 100644 --- a/python/mozbuild/mozbuild/frontend/data.py +++ b/python/mozbuild/mozbuild/frontend/data.py @@ -161,11 +161,13 @@ class Exports(SandboxDerived): this object fills that role. It just has a reference to the underlying HierarchicalStringList, which is created when parsing EXPORTS. """ - __slots__ = ('exports') + __slots__ = ('exports', 'dist_install') - def __init__(self, sandbox, exports): + def __init__(self, sandbox, exports, dist_install=True): SandboxDerived.__init__(self, sandbox) self.exports = exports + self.dist_install = dist_install + class IPDLFile(SandboxDerived): """Describes an individual .ipdl source file.""" diff --git a/python/mozbuild/mozbuild/frontend/emitter.py b/python/mozbuild/mozbuild/frontend/emitter.py index 4979e8b02c5..3e8bd677582 100644 --- a/python/mozbuild/mozbuild/frontend/emitter.py +++ b/python/mozbuild/mozbuild/frontend/emitter.py @@ -154,7 +154,8 @@ class TreeMetadataEmitter(LoggingMixin): exports = sandbox.get('EXPORTS') if exports: - yield Exports(sandbox, exports) + yield Exports(sandbox, exports, + dist_install=not sandbox.get('NO_DIST_INSTALL', False)) program = sandbox.get('PROGRAM') if program: diff --git a/python/mozbuild/mozbuild/test/backend/test_recursivemake.py b/python/mozbuild/mozbuild/test/backend/test_recursivemake.py index ff411d2701c..a2d64e8b31c 100644 --- a/python/mozbuild/mozbuild/test/backend/test_recursivemake.py +++ b/python/mozbuild/mozbuild/test/backend/test_recursivemake.py @@ -234,33 +234,16 @@ class TestRecursiveMakeBackend(BackendTester): self.assertEqual(found, val) def test_exports(self): - """Ensure EXPORTS is written out correctly.""" + """Ensure EXPORTS is handled properly.""" env = self._consume('exports', RecursiveMakeBackend) - backend_path = os.path.join(env.topobjdir, 'backend.mk') - lines = [l.strip() for l in open(backend_path, 'rt').readlines()[2:]] - - self.assertEqual(lines, [ - 'MOZBUILD_DERIVED := 1', - 'NO_MAKEFILE_RULE := 1', - 'NO_SUBMAKEFILES_RULE := 1', - 'EXPORTS += foo.h', - 'EXPORTS_NAMESPACES += mozilla', - 'EXPORTS_mozilla += mozilla1.h mozilla2.h', - 'EXPORTS_NAMESPACES += mozilla/dom', - 'EXPORTS_mozilla/dom += dom1.h dom2.h', - 'EXPORTS_NAMESPACES += mozilla/gfx', - 'EXPORTS_mozilla/gfx += gfx.h', - 'EXPORTS_NAMESPACES += nspr/private', - 'EXPORTS_nspr/private += pprio.h', - ]) - - # EXPORTS files should appear in the dist_include purge manifest. - m = PurgeManifest(path=os.path.join(env.topobjdir, - '_build_manifests', 'purge', 'dist_include')) - self.assertIn('foo.h', m.entries) - self.assertIn('mozilla/mozilla1.h', m.entries) - self.assertIn('mozilla/dom/dom2.h', m.entries) + # EXPORTS files should appear in the dist_include install manifest. + m = InstallManifest(path=os.path.join(env.topobjdir, + '_build_manifests', 'install', 'dist_include')) + self.assertEqual(len(m), 7) + self.assertIn('foo.h', m) + self.assertIn('mozilla/mozilla1.h', m) + self.assertIn('mozilla/dom/dom2.h', m) def test_xpcshell_manifests(self): """Ensure XPCSHELL_TESTS_MANIFESTS is written out correctly.""" @@ -297,8 +280,8 @@ class TestRecursiveMakeBackend(BackendTester): self.assertIn('bar.idl', m) self.assertIn('foo.idl', m) - m = PurgeManifest(path=os.path.join(purge_dir, 'dist_include')) - self.assertIn('foo.h', m.entries) + m = InstallManifest(path=os.path.join(install_dir, 'dist_include')) + self.assertIn('foo.h', m) p = os.path.join(env.topobjdir, 'config/makefiles/xpidl') self.assertTrue(os.path.isdir(p)) @@ -325,7 +308,6 @@ class TestRecursiveMakeBackend(BackendTester): expected = [ 'dist_bin', - 'dist_include', 'dist_private', 'dist_public', 'dist_sdk', From e8fc16b78cd9b666973ce603d5690417df361e2d Mon Sep 17 00:00:00 2001 From: Makoto Kato Date: Wed, 4 Sep 2013 16:42:24 +0900 Subject: [PATCH 045/171] Bug 911741 - ICU doesn't use optimize flag. r=gps --- js/src/configure.in | 3 +++ 1 file changed, 3 insertions(+) diff --git a/js/src/configure.in b/js/src/configure.in index 91e419e567e..bb80456d826 100644 --- a/js/src/configure.in +++ b/js/src/configure.in @@ -4305,6 +4305,9 @@ if test -n "$ENABLE_INTL_API" -a -z "$MOZ_NATIVE_ICU"; then fi if test -z "$MOZ_OPTIMIZE"; then ICU_BUILD_OPTS="$ICU_BUILD_OPTS --disable-release" + else + ICU_CFLAGS="$ICU_CFLAGS $MOZ_OPTIMIZE_FLAGS" + ICU_CXXFLAGS="$ICU_CXXFLAGS $MOZ_OPTIMIZE_FLAGS" fi abs_srcdir=`(cd $srcdir; pwd)` From 645a124f6af6c4937d0a144e95b7859e31ef1436 Mon Sep 17 00:00:00 2001 From: David Burns Date: Wed, 4 Sep 2013 09:05:43 +0100 Subject: [PATCH 046/171] Bug 912244: Correct screenshot with element highlighting in Marionette; r=jgriffin --- .../client/marionette/marionette.py | 5 ++++- .../marionette/tests/unit/test_screenshot.py | 7 +++++++ testing/marionette/marionette-listener.js | 20 ++++--------------- 3 files changed, 15 insertions(+), 17 deletions(-) diff --git a/testing/marionette/client/marionette/marionette.py b/testing/marionette/client/marionette/marionette.py index 035dafed569..5ce6ca8ab27 100644 --- a/testing/marionette/client/marionette/marionette.py +++ b/testing/marionette/client/marionette/marionette.py @@ -1255,4 +1255,7 @@ class Marionette(object): ''' if element is not None: element = element.id - return self._send_message("screenShot", 'value', element=element, highlights=highlights) + lights = None + if highlights is not None: + lights = [highlight.id for highlight in highlights if highlights] + return self._send_message("screenShot", 'value', element=element, highlights=lights) diff --git a/testing/marionette/client/marionette/tests/unit/test_screenshot.py b/testing/marionette/client/marionette/tests/unit/test_screenshot.py index 5fcd49fa9fc..8994c41c01f 100644 --- a/testing/marionette/client/marionette/tests/unit/test_screenshot.py +++ b/testing/marionette/client/marionette/tests/unit/test_screenshot.py @@ -10,6 +10,13 @@ class ScreenshotTests(MarionetteTestCase): self.assertEqual('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAVUlEQVRoge3PsQ0AIAzAsI78fzBwBhHykD2ePev80LweAAGJB1ILpBZILZBaILVAaoHUAqkFUgukFkgtkFogtUBqgdQCqQVSC6QWSC2QWiC1QGp9A7ma+7nyXgOpzQAAAABJRU5ErkJggg==', self.marionette.screenshot(element=el)) + def testWeCanTakeAScreenShotWithHighlightOfAnElement(self): + test_url = self.marionette.absolute_url('html5Page.html') + self.marionette.navigate(test_url) + el = self.marionette.find_element('id', 'green') + self.assertEqual('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABDUAAAI7CAYAAAD8qqCrAAAgAElEQVR4nOzdT6szW7zg9XLmm+iB4Ljegl1ORfIG0oKT4DBwB5KZBEECF9uASOhJumkiLXESUIKDtBChDVeCTZomXgkSLuQ2REhDHNSgoH8O8q8qe+9n7+ecnHP2Ov35wIKz905SlapnUt+zalUWAAAAAAnK/ugdAAAAAPglRA0AAAAgSaIGAAAAkCRRAwAAAEiSqAEAAAAkSdQAAAAAkiRqAAAAAEkSNQAAAIAk/YKoUcZ+u47lYhGLxSJWm12cyioiIqrDJlbb40t38Hw8xvE+TlG+9NN/rTK2y3nMFus4Vb/PFqvzqXY8jnE8HZs/N8b599kpAAAA+AP8VNTYL8fRyrLIsiyyrIhOp3397yzavX60syyyweqFu3eOcSu7byPLilj9YdfpVey3uzjX4sV+3r3vWzFc/y57sR4WtePxyciHcXrBNqvTPrZ7gQQAAIDv5YtRo4rl8BEwit4sHpe4ZazGj4v71qsv7st1LaS0Yv0HXVvv573IsrwRVdbD1uOYvDTmfGwzupyH7ngZp6ga+5C1RnGKKvbLcRTXn3/94dpH7+WxCgAAAH69L0WNw7xX+7///Ti885rNuPObRY32Hxw1qt008ne2Xx2X0ckvv5+sX3vbzUc2oyKy3qL28yM2ZcUjYhwW/cv+/qr7dcqYdfPf5rwCAADAr/R51Kh20a3d0tAabT544TEGH/wf/fNhF+vVKlab7btrT5SnfaxXy1guV7HdP8WBH0aNMvabdSyXy1iuNnH84AK+Oh3un7/ZHeJ5F6rzIbbrVaxWq1hvdnGqfU65nzdmiiz2pzify4jqHKfTOc7nU5xO5yir5qf+6DudT6c43cflC53228v2t2/3r/59x0UWg9pB+ChqRLmKIuvEroqI6hy7zTpWq1VsD883pJTXv61jdzjF+biL7f4UEWUsBvWZKIs4nc+N228AAADgj/Rp1DhvRo11GkY/mCpx3i1jvqrP4zjFtH+7MM7v62JMNrcL66p260oerfyyjbwziv3t4vmDqFEdV9G9vb712MZouW/s02b6mGVS5LfbNAaxKyMiylgMO9cZKMXllo3r6E03EXGO4bvrVQzib5+OS36POZ99p+d1QrIoWk/rZHSnH942Up7PjejxYdSIKqoq4rSZ3qNMftuX7uSy1sZ5fT+GWZ43vst5PXh3nY7+6hWrdAAAAMCv92nUOK2GjYva4frrF7Wr+6KW3dhGxHl5u1DuxKaM2E46988db6uIqM0KaU8uF+jvRY1yG53a66qI2E+7tc+6XNrvZo+4MDtExPYRIgarU5S1MDHaVhFximFR21YZUZ13Maj9br473mdX1Pf/dnvGl75THGKQ10NPO6azUWMR1q8uiPpx1IiI0/IeajqTXUScrtvNoj3exnZ8eW/em19fv45Odlv0tIr94hE2iv4ijqeTmRoAAAB8G59GjcZClFkrll9tGtXmESNa48vsgsPsujZFFsO/Wj/CRD6I2w0ay/5j1sJkV74bNXbTRzgYLK/vPC4eMy3akyjrMeG6YGa1n9bizDnO60ewaY+3ERGxqX3f8eYczZkVzTUqys24GTWq3de+U+Mzi5gfIiKqxgyOH82IqftR1LhFi0dgiZhf18jIilH876PHDJf+dB1lXMJT+xpo6tHHmhoAAAB8N59GjeOyeRtCfabG8TqLI8/zKPI88ryI/Hobw3/3P/2Te8C4396RP37+u//F33/8vfaUjvpFenuyfSdqVPfFK29xIiKeXteJ/+NfThoX+5e9ruKwXcdqs79EluoQ00E/ev1hLDabWEyG0c6fv+tT1KhVg/PTRX+1n33tO737mc3bUr46I+ZHt5/Uj9Pb21yKmPw3rcbfs6yI4Xz74fcDAACA7+Sn19QYrB6LXlblOc6nbQwaa0R0Y7k/xb+uzYLIil4srgtxrlarWC2X8b/N/qt3L8brF+nFcP1O1DjFqHjn4v/pdf90WdvvHzzatDysY9ht38NLPcT8bNQ4N77zD77T7xI1msepN1lcFmu9juVyHadyF71axLnv43V9EFEDAACA7+wLTz/ZNp5+UvSXb17SuLBuT6KMiOowrwWCbuyeP7b+9w9mNXSmu3dnasx7jxkIo3dnanTjn/+Lce1Cvf3uo01Pq1r4aI/jHFVM2j+OGqsfzdT46nf6nWZqzHtFbbv7p3dWsd9s4nA6xnLSf5pVc3lsr6gBAADAd/Z51IiI/bxXCwSXRT7r6hfW90e+VttaZMiiPX48CnY1akd7/L9E734R/f76E9N99e6aGvvZY3/6762p0ZlFVdUWE82yaA0eMaY6rGK2OsSiFkd688tjTIe12Q2j7fP6F63YVBHb2TiWh7K55sRoHRH7r32nL0WNr62pUV83I2uNo/zob1nnMcvkuIpO/p/Gf55l0brFjuoY88Ht9d3YVk9RY7SNqLYxnqzigyfnAgAAwO/qS1EjooplLVzk3Ukc7le2ZcxqMwIejzZ9XmQ0i05/EL3rTIjZrozDvP+4iF+dI6rNI0T05lFFRHWoxYqsiPm+jIh99G+3TRTDOEfEdnxbPDSP2fV5sPUnkWRZFq3eKCbj/n3GxKLfXHMirwWNy8/dWOz/VeM2jlb78p3mhzKWg8f3K/qLqCK+9J3iXFskNStitisj4lB7ykoW/UX90bgfnJVyH6N2fZ/bsdjXp5Ksak9UySIrOjEcXINQ95/EP2hdospsc8kv9/VT2tOoIpq30+Sty2f1Fl/7JwMAAAC/sS9GjYvjehadpwv/RjToDmK5q88wKGM56j69rhXTzePWit18eL/14RYv2oPZdWHPc4xaT9sphpe/lbsYtm9P8ng8GnW2rd+2UcV60nuzn/3pZdbIeTNp3HaRtwcxHtRmN+TdWJ8iNpPmdxguD2/WGqnfMvLZdxo/f6esHcNBJ56P048e6/re9puzRq5nYL+I7tO6Ga3+NE5xjuE762lkeTdWx+q2kcatR1l7GHuPdAUAAOCb+KmocXM67GKzXsd6vYnNdhv7wzHKH1zsVudT7Pf72B+O8e7LqlPsD8c4HvZxOP3czQ2nwyGOp2Ps94cPb4uozsfY73ax2x/i/LwD5WXfjrXtng772B9OjX0tT8fY7/fx5d37Fd/p9arLd9rv41g7AMf9/rIGR3mKw34fu3ePYRnH6/EAAACA7+QXRQ0AAACAP5qoAQAAACRJ1AAAAACSJGoAAAAASRI1AAAAgCSJGgAAAECSRA0AAAAgSaIGAAAAkCRRAwAAAEiSqAEAAAAkSdQAAAAAkiRqAAAAAEkSNQAAAIAkiRoAAABAkkQNAAAAIEmiBgAAAJAkUQMAAABIkqgBAAAAJEnUAAAAAJIkagAAAABJEjUAAACAJIkaAAAAQJJEDQAAACBJogYAAACQpESjxjl2212cqz96Pz5Wng5x/M47CAAAAIn7cdSo9jFs55Fl2X20erMof6ed+8h23Iosy6K/Ov3Be/JWdVhEJ78cs8E33D8AAAD4s/jSTI3V8BIRerP9b70/7zptZjHfnu8/n3fz6HX6sTx8z5kQh+UgsiyL4VrUAAAAgN/Kl6LGZtSOLMtitDl//uIXqw6LKLIshps/en7I1503I1EDAAAAfmM/FTU+u0g/rKfRzrPI8iyyrIj+ZNW4VeW4nkQre/x9MN1EFRFRHWLSa0WWF1FkWWStfmxOVVT72ePWlzyLvD2Oc3mM9XwS3VYRo9r+fLjt8hCLySg6RRGD+TJGncutIXlrELt3Okm5m0UrzyPPixhvy4jDPNp5HkWex2Cx/9LnPaLGOSL2Mey0olUUURTtmP3Lv/7S/nz8fbbRzfMoiiKK9iDW23m0s+vPRSfmh4hqP4tWnkXemcTf7lcxHvaiyNsxXUyifT2eneEyvuc8FwAAAPial0WN42p4WedifrlFZT3uXC7W+4uoIuK0vvx9sjlFxDlGrcvF+uocsR237/8d1TY6WRb5YBVRlbFbDK6fu43T6RzlfhmDTtHYnx9v+xjTXnGPI73JImajy99bo8273+V0/bzb55e7aWRZFsVwHfGFz7tFjdGmvESILIvWcBGnKr70/s+O5WHeu/x9cby8/nq7S/d+e9A5RnkW/eUxjptZdIvbmiitmC0X0W9lkWV5XN8OAAAASXpR1DjGIM8iK4bxeMUtXOQxP/xtDPJrqLg6rcdRFP3YlRH7WS+yrBu7iIhqH4P8FhAiysash4tqO67tz2fbriLOqyiyx2dGtYlW/ecnb24fKTfRrr/+k8+7vb8/nUY3y6I32z1t4Efv/8L3uYafrD2Oc23/stbo8vNxHlnWjVviuEWj5fUDz+vhJ+cTAAAAvr/XRI3z+nJbSet6kf38vn/6v/4wIlw+Y3e5BeX2lJWnQFDfduN3n217dYooL6+5febt569HjafXf/J5t/dfRi/eLK/6o/d/5ftExGpQXGZbnCLKa6TIsjzmp4jdqIhiuKm9txVZ1opbF7LmBwAAAH8GL4ga5zj838vrhfiocSG+nVxumxj+1Tq6WRbFcPXO+y+zNi4hYxkRZUxaWeQ/HTU+2Pb69GGU+LVR46Ofb+/Pi8ttJnlv3ly/4kfv/8r3iYhqf7klpjOex6idR288jCLLoj0YRScrYl67tUTUAAAA4M/o555+sn779JPDrBNZ97+PXpZFlnViW7t6v9z2kMXsr//qcqGedWJVu45ejzoxWP1NjIossmJ0XVT0HMP8bdSoP3ml+bv9j7e9r97ePvI8U+JJY02M+utva3B88nm394+3h5h38+vjcGu3oPzw/V/4PhERcbrekpJFlg3iHFVM2tef29PGAq2iBgAAAH9GX4oaq2HremG+jbI8x7k8x+m4j9XsctvDYHWK3bR7nW1xm41xiEHxuMBe9m+LY7ZiNJ3FqJtHlvXjEKdL1MiKGC/WsbguipkV3Zitdvf1HzrjZawmg5huz/d1Nm4LY3627dushnuU+GxNjes28+44trtV9PJLLMjbw9gczp9+XrkdXY9LGRH7+/uHq8v0ic/e/9n3ubkvGDo/RMRjwdDhqhkrtqPWu2tqjBJ6TC4AAAA8+3HUqPYxaOe19SHeG+3rDIAqVuPudaZA5/I40vYo7hML4hjT2poZWdGLzfUiezvt3X/fHkxieH3MadFfRJzXl0Uxrwtjbpajy2Nfr2tIDBb7H2+72t2jQpYVMZzOGt9pMH+z4kVEHGNUe01/NIgiy6LTG8T8//yrH37ef/mP/tFl+7e/z+YxaD2OV/vv/+Mv7M9nx/KqXEcr68R9Dki1jXb954g4LIaR34/5IDbb+XXWTBZZ3o75XtgAAAAgTV+aqfEzqvMp9vt97A/v39pQnc9xOr+9jaUqz1Her6+rKMuq/sfmz79w2z+rLMu4bbb6fPMv95XvUz0dl+efAQAA4M/q5VEDAAAA4PcgagAAAABJEjUAAACAJIkaAAAAQJJEDQAAACBJogYAAACQJFEDAAAASJKoAQAAACRJ1AAAAACSJGoAAAAASRI1AAAAgCSJGgAAAECSRA0AAAAgSaIGAAAAkCRRAwAAAEiSqAEAAAAkSdQAAAAAkiRqAAAAAEkSNQAAAIAkiRoAAABAkkQNAAAAIEmiBgAAAJAkUQMAAABIkqgBAAAAJOkXRo0yNotlHKrX7syPnI/HON7HKcravmyX85gt1nH63fbnj9jm23047DaxXCxisVjEarON4/myM+VhHavt8WVb+vjYv0IZp8bnN8fz386v3TgAAAAJ+0VRo9rPIsuy6M72r96fD5xj3Moiy26jiNX58pf9vHv/fTFc/wbbrmK/3cW5Fi9++23+2H45jtb9WLSi223f96fd7UU7yyIfrF60tY+P/Ws+fhVFVv/8H4/B6vSCjb49pwAAAKTnF0WN1aC4XGTmg3jdfIBPlOvGhfz6emG9HrYegeFlF/IP+3kvsixvXMj/1tv8WBmLQW3bvVljxspq/IgtrZfGlmMMirfH/iXKdbSzLLK8F8vdKeK8qp3nLAarY8R5F5Pu5d/caPPrN/7eOQUAACA9Px81yk10ahedr7jI/Np2rxe/TxfW1XEZnfzyu8n6tYml2k0jf+dC/rfc5o9cLsavxyDvx+Gd12zGnd8gatRna7ReGwPKdbSyPBbHx8/t2r+v4fo2M+MQ/SyL1mjzqzb30TkFAAAgPT8dNQ71C+ssi6wzi/dm8ZenU5yu41xFVKd9rFfLWK7WcTj//OvejRrVOU6nc5zPpzidzlFWzT2pTofLZy1Xsdkd3uxndT7Edr2K1WoV680uTrX1Gsr9vDEzZLE/xflcfrrN8rb/y1Vs983gca5919Pp8uVO++1l+9u3+9fc2W10a8f944v7YwyyLLLGDJIqDrvLdlbrdewOH93CUcVhu47lchmr9SYO9/sz6lGjHZsq4ny4fN5m+15aiTgfdrFerWK12f5w3ZFyO4osG8b9VH8YNSLWgyLak11EdY7dZh2r1Sq273yX8njZ9nqzi9P5FLvrPnx4TgEAAEjST0aNU4wa6ytc1lhYPE1WuK258fHIY7I+ffl1EfFu1Cg3o8br6+tIbKaP+FLk19e0BrErIyLKWAw71xkPRWNNh950ExHnGL67P4P42w+3WdVu/8ijdd1m3hnFvop4uzZFFkWraH5+dxofTR44P213+INpBufdMuarS2wo94v7cWtsr+hFY5LNaR292y0mRf64/WO+f7PvrXareQy6s9p+n2Lab92Pw+3fyGTzQUipyjiXterxg6gRVRWnzfQeJvLbMe5O4vaqzeRxC05e+ze6On98Tl+xSgcAAAC/v5+KGtVucrn9YLdqXHi+d6vDeT1sXDx2p+vYLga133ViW379dR/dfrKddN7sx272iAuzQ0RsH0FgsDo1YshoW0XEKYb1NSPKiOq8a6wjMd8d77Mr3ttm/XfjbRURu8fMivbketF/iEFev9hvx3Q2qs0e+HgRztOqeZwaF/sfqsWIYhxVRJxWj2Nb3GZ7VI99zXvziKge78uHcXoTZD7e79XwFk66sY2I8/K2vU5svjIp4kdR47S8B6jOZBcRp+vxzKI93kaUm+t785hfQ9t63IksK2J9/vE5BQAAID0/FTWWvSyyziwiIha9vHaR24nt0y0G9ZkFlwvliIhzjIr6Bev5y6/7KGqUm/FTYKjFhNYozhFR7afNbdZCSnu8jYiITW3xz/HmHM/rSKzrt6Y8b7PaPdYZqS2euuw/ZkZMduXTZxYxP0Q0AkKWxeiDGRj1xUmzLIvJ9iuF4FyLNe3YRjQXXG2P4xwR++ljdsNljZQqZp1bDBnF+Wm/LzNzmvs9XJ8jqs3jHLUuESUOs/uMiS+FmB9Eje348ZSX8fUf3LybP/bzXPturX6sDmVEnGLQ6lz/vXx8TgEAAEjP16PG9WL4dpFZbieNi+zevLm2Qj1WtEa3mRxlTDuPGNKd7b/8uo+iRuP9w3WUu9p+FaPrrQWXtSJWm/3lQrs6xHTQj15/GIvNJhaTYbTz5wvppwvg8wffbbiOav+4cL+FlIiIzaj2qNXJ9oPPPD/Fgfcv/I/LQeN4f22mRsRhNY1+rxfDySK260UMa49/vRyfMqadt59bnQ+xXq1if6q+vN+N45Bll1t7asf1S4+//TBqVDHr5o1j0Lx9p4jVcd14ckqWZVF0hrG9n7uPzykAAADp+XLU2M+eFgh9HsWwsTbB84X/Tf3/treG6y+/7qtR47yurT1RCwzPysP6cYGfF42L8Z+NGo1baIr3o8blgv6XR43nNTW+/tSZMtazR7QpiuxpX8+NdVLenynytf1uHodeLK6LsK5Wq1gtl7He/ZqZGqfG7J3eZHFZiPQ6lst1nKqI3bv/TotYnj76HgAAAKTqi1HjGIM8i6I/i91uG9vtNra7XSzHncbF47h2S8T7MzCqmNduWxmuTl9+3ZdnamzHtX1qv3uLwWlVCwTtcZyjikn7x1Fj9aOZGof5pzM1OtPdm8/8majx/Cjdor/8+HSd97HdnyPi2AwWm3PEm5ks58Z3f5yDxgd+baZG/Thk3dh9vIcf+8FMjXmvqB3P/Zu3VqddbHbHOO6W0W83Z3X0F4c33+Olj6YFAADgd/elqHELBfOnp5xEtW1caNcf79pcK2Nx/e0h+vfbEfKY7asvv+7jNTWeosjTPrUGj4v/6rCK2erQWA+kNz9FRFlbeyKL0fZ5/YtWbKqI7Wwcy0P5dpuxj95tmx+sqTHdf/U2jo+vtPezx9oXWZbH/L2nqZ7WlzVFinGUx3pk6McxIsr6bIrWOMqI2E3qcaoVy/t5rmI9m8e++ny/R+tzRLVtBIn2+PHY2dWo3fj5Q/V1OZ5mpNRn72RZ5zHT4riKTt6J1T8bRJa145Y7TtvZ/bM679z+Uz+nAAAApOfzqFHenhjRjc3paTXQqh4frheh10eJPt8u0ZuuYjmuXZR3ZlH+xOuqw6L26NUi5vsyIqpYDh4LaBb9RVTRfBJJlmXR6o1iMu7fZ0ws+s3/i58X2dPP3Vjs/1XjdofbY0znh/LdbR7m/UeYWF0WzbzHld78EnvO61pwKWK2KyPiUHsix21GwYcnIxaD+oKh7Ziud3E6n+N0OsRyel13I+9fHl17XDTXuMjyNz93h4soy6c4lbViNJlEv32JB7t//YX9nl9SwvOCpp3+IHrXmSCX9/1IFftl899De7iI872UrZprZhSdGA6ut5t0Z/H/Xv8ttfqzOFYREcf7Pl4Waj19cE6rj3cJAACAb+uTqPH8KM8sxrdVF8u3izLeZyXsyqdYUdSCRBZ5ZxS368ivva657sPlgnYYf/MURC4zHU4RUcV68nZthf50c93mpHFxn7cHMR7UZgHk3VifIjaTbvOzl4c3EeaxzYjdfHj/3Nv3aA9m17VG3h7LLGvHcNB5+t3nt0Uc1tPoFM+fdY0Iw3ltbZNTTBqLa+bRH48aMyG6k8vtJtVxHb3nzyz6sTn97H6XsRx13/xtuvlsPY33tvN4/31mzn4R3aeQ1upP4xSPxwPnT+/vjlf3GUTvnVMAAADS9FOPdP0Z9Yv/y2NTyzjs97E/nH7R636J6nyM/W4Xu/3h8X/7b8pT7Pf7OJ4eswdOh8t2q8bLjrHf7+P01TsUqlPsD8c4HvZx+PKbfpnTYReb9TrW63VstrsP9/HyvY5R3r7Y9buf3hyUKo6Hfex2uzgcf92CE9X5so394RivnwdRXb7Tfh/H+ncoj7E/Xh5JezoeYr/bvXsOfvqcAgAA8C39ZlGj3DwW7HyslfHLXwcAAABQ9xtFjTLWjWn+nVge3vs//199HQAAAEDTbxI1yt00iiyPVqt1HUU0nlbxk68DAAAAePab3X4CAAAA8FsSNQAAAIAkiRoAAABAkkQNAAAAIEmiBgAAAJAkUQMAAABIkqgBAAAAJEnUAAAAAJIkagAAAABJEjUAAACAJIkaAAAAQJJEDQAAACBJogYAAACQJFEDAAAASJKoAQAAACRJ1AAAAACSJGoAAAAASRI1AAAAgCSJGgAAAECSRA0AAAAgSaIGAAAAkKSfjhpVeY7T8Rin0zmq6+/Kc/ni3eKN6hyH/fF+zAEAAODfdl+OGtVxE8NuEVmWNUa7044s68X+t9zLf5tV+xh2rsc9H8bpj94fAAAA+Ca+FDVO6/E1YhQxWe/vswVOu0V0siyyrBWr82+4lz+titV4HNvfaJ9Om1nMf6sPf0d13kQ3yyJrjeLXb/Xnjs3v/V0BAADgqz6PGud1tLIssiyP2f6dmx/Oy8izPJbf6Lp3N+tFlhWx/g3uiqkOiyiyLIab3/OWm3OMW1lkxehXz9T4mWPzx3xXAAAA+JpPo8Zm3I4syyLvzj5cz2Ezm8Vf/1+zaOV55HkR420ZcZhHO8+jyPMYLPYR5THWi2l0iyIG01n0W1lk2d+L/2H+/LtObMqI8rCMbnG9zSVvx3h5ucHlvF/FeNiLIm/HdDGJ9vU2mM5wGVVE7Gfdxu0x3cmmubPlIRaTUXSKIgbzZYw6+eX7tQaxq1277+bDyK+fUbQHsT5WUe1nj8/Os8jb4/h/lsPIszyKLIvudBu7eT+yLI+iyKPVm0YZEbtp77Iv021ERBzW02jnl8/IsiL6k1WUER8co05sykfUKCNiOexGq1VEURTRHS7ibXKoYjXuRp4X0SryyPJubM4fHJvqEJNeK7K8iCLLImv1Y3N6/7v+81k/8jyPoj2MY0TsZ/3I8yLy6+dHRBzXkyiyLIpWEXmeR3d8Of6HxSCyLIvB8vDZPzkAAAD4kk+jxnJwWc+hNdp89tI4rYaRZVkM15f5BOVueokCw3XEaX29SL9GiE4RWfYfxH/2Hz3/rhXrv1lGkWUxWh0j4hDD6/sm2zKOm9kjdmStmC0X18/NY3GMiOoci0ErsqyI+fYY5ZsSc4xp77E2SG+yiNmo0/iO+3k3sqwb2zKi3M2vM1X6cajK2F0vzvvzbZxO54goY9K5fNbsGBFRxqybR5YVsbxNqzgvI89asSkjjtdj1J9fIs16fNl23l9E9e4xasX6fIsa46giYtEvIsv7sTm+P4Oi3F5uF5oeIyL20ctbl5k07xyb7bgdWVZcbh+qttHJssgHq4gPvuu41bzdaD1s1X4+RC/Lonf94uthEXl/FRER28kljrUn20//HQEAAMBXfBI1TjG8BoTh6vMbH86bUSNqRLmJ9i1qRER1vdjuTneXP5fVu79bDYrIsiJGs1lMZ7MYtrNHHInHhfgtGpzXzZiyGbUiywZx/HBHV5fZBNfPi2oTrdvP1T56WRZZaxCz2Sxms9E9Msz2VZT37/i43+YWc3rXUHGcdRrfaTdpR9ZfRsQxBnkWWVFf8PMco2uUmR/ePx7320/yTgy6eWSdyQ9vQ7kdj+54HVVEnFazuJ2S52Ozn/Uiy7qxi4io9jHIH8flve96OfatuP3q8nnXn6/nO2sPL2t2VJuYzHfXd5Zx2B/emVUCAMia8a0AABIYSURBVAAAv8ynMzVWg9Z1FsP60w97GzXWj1hQ+/toc37znsfvrhfwrX5MZ7OYTqcxm81jPpvFand5TeNC+p3tbkZFZPkPFtW87lfrFjXq+3ldQ6TojWM2m963P5vNYnMo337HiIi4hpDr7SGL3nW2RTGMc5yin2Ux2VeP9Ula48a+bUbtezh67xhFnGPcfszgGH22xsUtLmRZZFk7ppvHvr57bM67yy0o1/e0ns5X/bs+H/vmz9V1lsr19pbx0iNoAQAA+M18GjW21zU1svb40ydvfDVq1C+S3/6ujGnnEQgaqssl8quiRvGDqNGbv137oaqqD6LGLUzkMVlOo5W1YzTsRJblMRz3Iyuu+3KPGs1920469898//OvoeceKi7rjvzQaROD9iMw3NayeD42tyfbtIbLiChj0soi/8VR47Kvi2Hnsa8/WIsFAAAAfo0vPP1kdV1TIovh6v0bOnaLaawOVW2WwfWK+zYj4rpWxf3v63dmatx/V8bkOithXJ+tcFxEkV9u2/g8arQua2B89J2ebotpzNwoN5fH1Oa92NWuxnfTTrSGmw9mUlz37zbTYbyLKB/Hrbe47cl1RkfWiW3ts2/haLav3j1G96jRnsRmOfw0Mp1XoxheH0ezW4wuC552LouWNo/NOUZFPSCdY5i/jRr173o79rdTfLsdZVNejmOvN4+IiOqwil7RXH+jPLv5BAAAgNf5PGrE48kVWZbFYLa5z6AoT7uY9ovIsnasT4+1HPLuOLa7VfTyy3vy9jA2h/N9jYb6LIj3fndboyLL8hhM5rGYXS7M+8tLVNmOWu+uqXGLKZfFK/OYrFYxGU7frD9R7aeNhUEba2pEFbPu7faRbkym0xgPHhfut211xstYTQYx3T7HmNtF/O1zmrMqdtPudWbE6nZ0Y1BkkbUv0eG94xFxuq7FMY6IiOX1lqCiP393jYrzehhZflu3o4pRnl3X9Hg+Nv8w/uvi8gSW8WIdi+uipVnRjdlq9+53vbw/i/5sHdvVuHarySrO53UU17VBIiL2k/ZlvY7qtnZHFh0LhQIAAPAiX4oaERGn7bz21JHHaPUmcbhfWR9jVLvloT8aRJFl0ekNYvY//+P7zIXLRfE2yt3sze8uqliPm48fvf3tsHg8ajUrBrHZzh+fkbdjvi/vTxjJsix6s6eL6Gp3jy1ZVsRwOmvepjHfR5S7+xNXbutSLPbXL3leX2ZyXGdL1OeunJa9yHuL+8/n1SDy7iKaLo9bvby/c3m0a3sU+yrePx7VLgatx/51hovYzPuPfSv6jUfRRjxmWGRFO9pFFlnejeX1JD0fm+31cbNZlkV7MInh9RG3RX/x7nct97XjnXVjMu5FlrWiP5zF4f+7reWRX89RHoPrQqG3x8mKGgAAALzKl6PGzel4iN1uH/vDIT66m6Asy/ujVKtfsaBCdT7F8XiM8y/4jPJ8+nD/vup0PMbxeHq7JkRVXp9K8stV51Ps9/vYHz5/qswv3kZZxvl8frP/z8emKs9R3n+umt/t3e9axul0+9zq3eNzOp3ePE7X7ScAAAC80k9HDQAAAIDvQNQAAAAAkiRqAAAAAEkSNQAAAIAkiRoAAABAkkQNAAAAIEmiBgAAAJAkUQMAAABIkqgBAAAAJEnUAAAAAJIkagAAAABJEjUAAACAJIkaAAAAQJJEDQAAACBJogYAAACQJFEDAAAASJKoAQAAACRJ1AAAAACSJGoAAAAASRI1/kz+8i//XAMAAAB+QNT4M8myP9cAAACAH/j0yvHfZP/un2I8+/ey//ZPMZpn8xID/vI//jtJj/eixr/5Z9mfYgAAAPA6okbio3k2LzHg3/kf/8Okh6gBAADAV4gaiY/m2RQ1vvsAAADgdUSNxEfzbIoa330AAADwOqJG4qN5NkWN7z4AAAB4HVEj8dE8m6LGdx8AAAC8jqiR+GieTVHjuw8AAABeR9RIfDTPpqjx3QcAAACvI2okPppnU9T47gMAAIDXETUSH82zKWp89wEAAMDriBqJj+bZFDW++wAAAOB1RI3ER/NsihrffQAAAPA6okbio3k2RY3vPgAAAHgdUSPx0TybosZ3HwAAALyOqJH4aJ5NUeO7DwAAAF5H1Eh8NM+mqPHdBwAAAK8jaiQ+mmdT1PjuAwAAgNcRNRIfzbMpanz3AQAAwOuIGomP5tkUNb77AAAA4HVEjcRH82yKGt99AAAA8DqiRuKjeTZFje8+AAAAeB1RI/HRPJuixncfAAAAvI6okfhonk1R47sPAAAAXkfUSHw0z6ao8d0HAAAAryNqJD6aZ1PU+O4DAACA1xE1Eh/NsylqfPcBAADA64gaiY/m2RQ1vvsAAADgdUSNxEfzbIoa330AAADwOqJG4qN5NkWN7z4AAAB4HVEj8dE8m6LGdx8AAAC8jqiR+GieTVHjuw8AAABeR9RIfDTPpqjx3QcAAACvI2okPppnU9T47gMAAIDXETUSH82zKWp89wEAAMDriBqJj+bZFDW++wAAAOB1RI3ER/NsihrffQAAAPA6okbio3k2RY3vPgAAAHgdUSPx0TybosZ3HwAAALyOqJH4aJ5NUeO7DwAAAF5H1Eh8NM+mqPHdBwAAAK8jaiQ+mmdT1PjuAwAAgNcRNRIfzbMpanz3AQAAwOuIGomP5tkUNb77AAAA4HVEjcRH82yKGt99AAAA8DqiRuKjeTZFje8+AAAAeB1RI/HRPJuixncfAAAAvI6okfhonk1R47sPAAAAXkfUSHw0z6ao8d0HAAAAryNqJD6aZ/MSA/7iP/n3kx6iBgAAAF8haiQ+mmcz+3ON+r/DbxAkRA0AAIDvxVXWn8lf/MWfawAAAMAPiBoAAABAkkQNAAAAIEmiBgAAAJAkUQMAAABIkqgBAAAAJEnUAAAAAJIkagAAAABJEjUAAACAJIkaAAAAQJJEDQAAACBJogYAAACQJFEDAAAASJKoAQAAACRJ1AAAAACSJGoAAAAASRI1AAAAgCSJGgAAAECSRA0AAAAgSaIGAAAAkCRRAwAAAEiSqAEAAAAkSdQAAAAAkiRqAAAAAEkSNQAAAIAkiRoAAABAkkQNAAAAIEmiBgAAAJAkUQMAAABIkqgBAAAAJEnUAAAAAJIkagAAAABJEjUAAACAJIkaAAAAQJJEDQAAACBJogYAAACQJFEDAAAASJKoAQAAACRJ1AAAAACSJGoAAAAASRI1AAAAgCSJGgAAAECSRA0AAAAgSaIGAAAAkCRRAwAAAEiSqAEAAAAkSdQAAAAAkiRqAAAAAEkSNQAAAIAkiRoAAABAkkQNAAAAIEmiBgAAAJAkUQMAAABIkqgBAAAAJEnUAAAAAJIkagAAAABJEjUAAACAJIkaAAAAQJJEDQAAACBJogYAAACQJFEDAAAASJKoAQAAACRJ1AAAAACSJGoAAAAASRI1AAAAgCSJGgAAAECSRA0AAAAgSaIGAAAAkCRRAwAAAEiSqAEAAAAkSdQAAAAAkiRqAAAAAEkSNQAAAIAkiRoAAABAkkQNAAAAIEmiBgAAAJAkUQMAAABIkqgBAAAAJEnUAAAAAJIkagAAAABJEjUAAACAJIkaAAAAQJJEDQAAACBJogYAAACQJFEDAAAASJKoAQAAACRJ1AAAAACSJGoAAAAASRI1AAAAgCSJGgAAAECSRA0AAAAgSaIGAAAAkCRRAwAAAEiSqAEAAAAkSdQAAAAAkiRqAAAAAEkSNQAAAIAkiRoAAABAkkQNAAAAIEmiBgAAAJAkUQMAAABIkqgBAAAAJEnUAAAAAJIkagAAAABJEjUAAACAJIkaAAAAQJJEDQAAACBJogYAAACQJFEDAAAASJKoAQAAACRJ1AAAAACSJGoAAAAASRI1AAAAgCSJGgAAAECSRA0AAAAgSaIGAAAAkCRRAwAAAEiSqAEAAAAkSdQAAAAAkiRqAAAAAEkSNQAAAIAkiRoAAABAkkQNAAAAIEmiBgAAAJAkUQMAAABIkqgBAAAAJEnUAAAAAJIkagAAAABJEjUAAACAJIkaAAAAQJJEDQAAACBJogYAAACQJFEDAAAASJKoAQAAACRJ1AAAAACSJGoAAAAASRI1AAAAgCSJGgAAAECSRA0AAAAgSaIGAAAAkCRRAwAAAEiSqAEAAAAkSdQAAAAAkiRqAAAAAEkSNQAAAIAkiRoAAABAkkQNAAAAIEmiBgAAAJAkUQMAAABIkqgBAAAAJEnUAAAAAJIkagAAAABJEjUAAACAJIkaAAAAQJJEDQAAACBJogYAAACQJFEDAAAASJKoAQAAACRJ1AAAAACSJGoAAAAASRI1AAAAgCSJGgAAAECSRA0AAAAgSaIGAAAAkCRRAwAAAEiSqAEAAAAkSdQAAAAAkiRqAAAAAEkSNQAAAIAkiRoAAABAkkQNAAAAIEmiBgAAAJAkUQMAAABIkqgBAAAAJEnUAAAAAJIkagAAAABJEjUAAACAJIkaAAAAQJJEDQAAACBJogYAAACQJFEDAAAASJKoAQAAACRJ1AAAAACSJGoAAAAASRI1AAAAgCSJGgAAAECSRA0AAAAgSaIGAAAAkCRRAwAAAEiSqAEAAAAkSdQAAAAAkiRqAAAAAEkSNQAAAIAkiRoAAABAkkQNAAAAIEmiBgAAAJAkUQMAAABIkqgBAAAAJEnUAAAAAJIkagAAAABJEjUAAACAJIkaAAAAQJJEDQAAACBJogYAAACQJFEDAAAASJKoAQAAACRJ1AAAAACSJGoAAAAASRI1AAAAgCSJGgAAAECSRA0AAAAgSaIGAAAAkCRRAwAAAEiSqAEAAAAkSdQAAAAAkiRqAAAAAEkSNQAAAIAkiRoAAABAkkQNAAAAIEmiBgAAAJAkUQMAAABIkqgBAAAAJEnUAAAAAJIkagAAAABJEjUAAACAJIkaAAAAQJJEDQAAACBJogYAAACQJFEDAAAASJKoAQAAACRJ1AAAAACSJGoAAAAASRI1AAAAgCSJGgAAAECSRA0AAAAgSaIGAAAAkCRRAwAAAEiSqAEAAAAkSdQAAAAAkiRqAAAAAEkSNQAAAIAkiRoAAABAkkQNAAAAIEmiBgAAAJAkUQMAAABIkqgBAAAAJEnUAAAAAJIkagAAAABJEjUAAACAJIkaAAAAQJJEDQAAACBJogYAAACQJFEDAAAASJKoAQAAACRJ1AAAAACSJGoAAAAASRI1AAAAgCSJGgAAAECSRA0AAAAgSaIGAAAAkCRRAwAAAEiSqAEAAAAkSdQAAAAAkiRqAAAAAEkSNQAAAIAkiRoAAABAkkQNAAAAIEmiBgAAAJAkUQMAAABIkqgBAAAAJEnUAAAAAJIkagAAAABJEjUAAACAJIkaAAAAQJJEDQAAACBJogYAAACQJFEDAAAASJKoAQAAACRJ1AAAAACSJGoAAAAASRI1AAAAgCSJGgAAAECSRA0AAAAgSaIGAAAAkCRRAwAAAEiSqAEAAAAkSdQAAAAAkiRqAAAAAEkSNQAAAIAkiRoAAABAkkQNAAAAIEmiBgAAAJAkUQMAAABIkqgBAAAAJEnUAAAAAJIkagAAAABJEjUAAACAJIkaAAAAQJJEDQAAACBJogYAAACQJFEDAAAASJKoAQAAACRJ1AAAAACSJGoAAAAASRI1AAAAgCSJGgAAAECSRA0AAAAgSaIGAAAAkCRRAwAAAEiSqAEAAAAkSdQAAAAAkiRqAAAAAEkSNQAAAIAkiRoAAABAkkQNAAAAIEmiBgAAAJAkUQMAAABIkqgBAAAAJEnUAAAAAJIkagAAAABJEjUAAACAJIkaAAAAQJJEDQAAACBJogYAAACQJFEDAAAASJKoAQAAACRJ1AAAAACSJGoAAAAASRI1AAAAgCSJGgAAAECSRA0AAAAgSaIGAAAAkCRRAwAAAEiSqAEAAAAkSdQAAAAAkiRqAAAAAEkSNQAAAIAkiRoAAABAkkQNAAAAIEmiBgAAAJAkUQMAAABIkqgBwP/fjh2QAAAAAAj6/7odgc4QAACWpAYAAACwJDUAAACAJakBAAAALEkNAAAAYElqAAAAAEtSAwAAAFiSGgAAAMCS1AAAAACWpAYAAACwJDUAAACAJakBAAAALEkNAAAAYElqAAAAAEtSAwAAAFiSGgAAAMCS1AAAAACWpAYAAACwJDUAAACAJakBAAAALEkNAAAAYElqAAAAAEsBt+vReTPIffgAAAAASUVORK5CYII=', + self.marionette.screenshot(highlights=[el])) + def testWeCanTakeAScreenShotEntireCanvas(self): test_url = self.marionette.absolute_url('html5Page.html') self.marionette.navigate(test_url) diff --git a/testing/marionette/marionette-listener.js b/testing/marionette/marionette-listener.js index 58505052c3c..0e2d8365408 100644 --- a/testing/marionette/marionette-listener.js +++ b/testing/marionette/marionette-listener.js @@ -1789,7 +1789,7 @@ function screenShot(msg) { let highlights = msg.json.highlights; var document = curWindow.document; - var rect, win, width, height, left, top, needsOffset; + var rect, win, width, height, left, top; // node can be either a window or an arbitrary DOM node if (node == curWindow) { // node is a window @@ -1798,8 +1798,6 @@ function screenShot(msg) { height = win.innerHeight; top = 0; left = 0; - // offset needed for highlights to take 'outerHeight' of window into account - needsOffset = true; } else { // node is an arbitrary DOM node @@ -1809,8 +1807,6 @@ function screenShot(msg) { height = rect.height; top = rect.top; left = rect.left; - // offset for highlights not needed as they will be relative to this node - needsOffset = false; } var canvas = document.createElementNS("http://www.w3.org/1999/xhtml", "canvas"); @@ -1827,19 +1823,11 @@ function screenShot(msg) { ctx.save(); for (var i = 0; i < highlights.length; ++i) { - var elem = highlights[i]; + var elem = elementManager.getKnownElement(highlights[i], curWindow) rect = elem.getBoundingClientRect(); - var offsetY = 0, offsetX = 0; - if (needsOffset) { - var offset = getChromeOffset(elem); - offsetX = offset.x; - offsetY = offset.y; - } else { - // Don't need to offset the window chrome, just make relative to containing node - offsetY = -top; - offsetX = -left; - } + var offsetY = -top; + var offsetX = -left; // Draw the rectangle ctx.strokeRect(rect.left + offsetX, rect.top + offsetY, rect.width, rect.height); From e9d8d271dd862db99185253f0984d3570c174bdc Mon Sep 17 00:00:00 2001 From: Jonathan Kew Date: Wed, 4 Sep 2013 10:01:57 +0100 Subject: [PATCH 047/171] bug 910376 - don't risk leaving mSharedBlobData uninitialized. r=karlt --- gfx/thebes/gfxFont.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/gfx/thebes/gfxFont.h b/gfx/thebes/gfxFont.h index 167022c122d..2f5e8bb5c19 100644 --- a/gfx/thebes/gfxFont.h +++ b/gfx/thebes/gfxFont.h @@ -604,12 +604,20 @@ private: typedef KeyClass::KeyTypePointer KeyTypePointer; FontTableHashEntry(KeyTypePointer aTag) - : KeyClass(aTag), mBlob() { } + : KeyClass(aTag) + , mSharedBlobData(nullptr) + , mBlob(nullptr) + { } + // NOTE: This assumes the new entry belongs to the same hashtable as + // the old, because the mHashtable pointer in mSharedBlobData (if + // present) will not be updated. FontTableHashEntry(FontTableHashEntry&& toMove) : KeyClass(mozilla::Move(toMove)) + , mSharedBlobData(mozilla::Move(toMove.mSharedBlobData)) , mBlob(mozilla::Move(toMove.mBlob)) { + toMove.mSharedBlobData = nullptr; toMove.mBlob = nullptr; } From 27f311b7c87245652c1fb2af877e17fc23e13a1f Mon Sep 17 00:00:00 2001 From: Jonathan Watt Date: Tue, 27 Aug 2013 09:30:28 +0100 Subject: [PATCH 048/171] Bug 912385 - Include a trailing slash in File.path. r=sicking --- content/base/src/nsDOMFile.cpp | 3 +++ content/html/content/src/HTMLInputElement.cpp | 5 +++-- content/html/content/src/nsFormSubmission.cpp | 3 ++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/content/base/src/nsDOMFile.cpp b/content/base/src/nsDOMFile.cpp index f98400ec196..b8a5507db5f 100644 --- a/content/base/src/nsDOMFile.cpp +++ b/content/base/src/nsDOMFile.cpp @@ -602,6 +602,9 @@ nsDOMFileFile::GetInternalStream(nsIInputStream **aStream) void nsDOMFileFile::SetPath(const nsAString& aPath) { + MOZ_ASSERT(aPath.IsEmpty() || + aPath[aPath.Length() - 1] == PRUnichar('/'), + "Path must end with a path separator"); mPath = aPath; } diff --git a/content/html/content/src/HTMLInputElement.cpp b/content/html/content/src/HTMLInputElement.cpp index 9503c379d37..98cc4431bc2 100644 --- a/content/html/content/src/HTMLInputElement.cpp +++ b/content/html/content/src/HTMLInputElement.cpp @@ -375,9 +375,10 @@ public: nsAutoString leafName; mNextFile->GetLeafName(leafName); MOZ_ASSERT(leafName.Length() <= path.Length()); - int32_t length = path.Length() - leafName.Length() - 1; // -1 for "/" - MOZ_ASSERT(length >= -1); + int32_t length = path.Length() - leafName.Length(); + MOZ_ASSERT(length >= 0); if (length > 0) { + // Note that we leave the trailing "/" on the path. domFile->SetPath(Substring(path, 0, uint32_t(length))); } *aResult = static_cast(domFile.forget().get()); diff --git a/content/html/content/src/nsFormSubmission.cpp b/content/html/content/src/nsFormSubmission.cpp index 372105da25e..a0909b277f2 100644 --- a/content/html/content/src/nsFormSubmission.cpp +++ b/content/html/content/src/nsFormSubmission.cpp @@ -475,7 +475,8 @@ nsFSMultipartFormData::AddNameFilePair(const nsAString& aName, rv = file->GetPath(filepath16); NS_ENSURE_SUCCESS(rv, rv); if (!filepath16.IsEmpty()) { - filename16 = filepath16 + NS_LITERAL_STRING("/") + filename16; + // File.path includes trailing "/" + filename16 = filepath16 + filename16; } } From 2e0932d7e927e9a520e10b648db5f2d4176dae69 Mon Sep 17 00:00:00 2001 From: Christian Holler Date: Wed, 4 Sep 2013 01:49:13 +0200 Subject: [PATCH 049/171] Bug 910486 - Disable a slow jit-test under ASan+debug. r=h4writer --HG-- extra : rebase_source : 24cb356e45a5f9cd57c1b3711afcd6aba52c1a93 --- js/src/jit-test/tests/basic/testOOMInAutoEnterCompartment.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/js/src/jit-test/tests/basic/testOOMInAutoEnterCompartment.js b/js/src/jit-test/tests/basic/testOOMInAutoEnterCompartment.js index e81aeab2e0d..328117e2f0e 100644 --- a/js/src/jit-test/tests/basic/testOOMInAutoEnterCompartment.js +++ b/js/src/jit-test/tests/basic/testOOMInAutoEnterCompartment.js @@ -1,3 +1,5 @@ +// This test is too slow to run with ASan in a debug configuration +if (getBuildConfiguration()['asan'] && getBuildConfiguration()['debug']) quit(0); function fatty() { try { From abff0fd6d56ee0e33f26df0a552e5fd0cdb958f4 Mon Sep 17 00:00:00 2001 From: Jonathan Kew Date: Wed, 4 Sep 2013 10:49:47 +0100 Subject: [PATCH 050/171] bug 909264 - control characters in the location bar should be %-encoded for visibility. r=gavin --- browser/base/content/browser.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index 9f89513a6a2..71e92ffc340 100644 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -2214,9 +2214,10 @@ function losslessDecodeURI(aURI) { encodeURIComponent); } catch (e) {} - // Encode invisible characters (line and paragraph separator, - // object replacement character) (bug 452979) - value = value.replace(/[\v\x0c\x1c\x1d\x1e\x1f\u2028\u2029\ufffc]/g, + // Encode invisible characters (C0/C1 control characters, U+007F [DEL], + // U+00A0 [no-break space], line and paragraph separator, + // object replacement character) (bug 452979, bug 909264) + value = value.replace(/[\u0000-\u001f\u007f-\u00a0\u2028\u2029\ufffc]/g, encodeURIComponent); // Encode default ignorable characters (bug 546013) From ad96cc4b8bd57f2f985461392debdf5f5e1d61c1 Mon Sep 17 00:00:00 2001 From: Ed Morley Date: Wed, 4 Sep 2013 11:30:06 +0100 Subject: [PATCH 051/171] Backed out changeset 69be1a2ffd39 (bug 912244) for Marionette failures on a CLOSED TREE --- .../client/marionette/marionette.py | 5 +---- .../marionette/tests/unit/test_screenshot.py | 7 ------- testing/marionette/marionette-listener.js | 20 +++++++++++++++---- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/testing/marionette/client/marionette/marionette.py b/testing/marionette/client/marionette/marionette.py index 5ce6ca8ab27..035dafed569 100644 --- a/testing/marionette/client/marionette/marionette.py +++ b/testing/marionette/client/marionette/marionette.py @@ -1255,7 +1255,4 @@ class Marionette(object): ''' if element is not None: element = element.id - lights = None - if highlights is not None: - lights = [highlight.id for highlight in highlights if highlights] - return self._send_message("screenShot", 'value', element=element, highlights=lights) + return self._send_message("screenShot", 'value', element=element, highlights=highlights) diff --git a/testing/marionette/client/marionette/tests/unit/test_screenshot.py b/testing/marionette/client/marionette/tests/unit/test_screenshot.py index 8994c41c01f..5fcd49fa9fc 100644 --- a/testing/marionette/client/marionette/tests/unit/test_screenshot.py +++ b/testing/marionette/client/marionette/tests/unit/test_screenshot.py @@ -10,13 +10,6 @@ class ScreenshotTests(MarionetteTestCase): self.assertEqual('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAVUlEQVRoge3PsQ0AIAzAsI78fzBwBhHykD2ePev80LweAAGJB1ILpBZILZBaILVAaoHUAqkFUgukFkgtkFogtUBqgdQCqQVSC6QWSC2QWiC1QGp9A7ma+7nyXgOpzQAAAABJRU5ErkJggg==', self.marionette.screenshot(element=el)) - def testWeCanTakeAScreenShotWithHighlightOfAnElement(self): - test_url = self.marionette.absolute_url('html5Page.html') - self.marionette.navigate(test_url) - el = self.marionette.find_element('id', 'green') - self.assertEqual('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABDUAAAI7CAYAAAD8qqCrAAAgAElEQVR4nOzdT6szW7zg9XLmm+iB4Ljegl1ORfIG0oKT4DBwB5KZBEECF9uASOhJumkiLXESUIKDtBChDVeCTZomXgkSLuQ2REhDHNSgoH8O8q8qe+9n7+ecnHP2Ov35wIKz905SlapnUt+zalUWAAAAAAnK/ugdAAAAAPglRA0AAAAgSaIGAAAAkCRRAwAAAEiSqAEAAAAkSdQAAAAAkiRqAAAAAEkSNQAAAIAk/YKoUcZ+u47lYhGLxSJWm12cyioiIqrDJlbb40t38Hw8xvE+TlG+9NN/rTK2y3nMFus4Vb/PFqvzqXY8jnE8HZs/N8b599kpAAAA+AP8VNTYL8fRyrLIsiyyrIhOp3397yzavX60syyyweqFu3eOcSu7byPLilj9YdfpVey3uzjX4sV+3r3vWzFc/y57sR4WtePxyciHcXrBNqvTPrZ7gQQAAIDv5YtRo4rl8BEwit4sHpe4ZazGj4v71qsv7st1LaS0Yv0HXVvv573IsrwRVdbD1uOYvDTmfGwzupyH7ngZp6ga+5C1RnGKKvbLcRTXn3/94dpH7+WxCgAAAH69L0WNw7xX+7///Ti885rNuPObRY32Hxw1qt008ne2Xx2X0ckvv5+sX3vbzUc2oyKy3qL28yM2ZcUjYhwW/cv+/qr7dcqYdfPf5rwCAADAr/R51Kh20a3d0tAabT544TEGH/wf/fNhF+vVKlab7btrT5SnfaxXy1guV7HdP8WBH0aNMvabdSyXy1iuNnH84AK+Oh3un7/ZHeJ5F6rzIbbrVaxWq1hvdnGqfU65nzdmiiz2pzify4jqHKfTOc7nU5xO5yir5qf+6DudT6c43cflC53228v2t2/3r/59x0UWg9pB+ChqRLmKIuvEroqI6hy7zTpWq1VsD883pJTXv61jdzjF+biL7f4UEWUsBvWZKIs4nc+N228AAADgj/Rp1DhvRo11GkY/mCpx3i1jvqrP4zjFtH+7MM7v62JMNrcL66p260oerfyyjbwziv3t4vmDqFEdV9G9vb712MZouW/s02b6mGVS5LfbNAaxKyMiylgMO9cZKMXllo3r6E03EXGO4bvrVQzib5+OS36POZ99p+d1QrIoWk/rZHSnH942Up7PjejxYdSIKqoq4rSZ3qNMftuX7uSy1sZ5fT+GWZ43vst5PXh3nY7+6hWrdAAAAMCv92nUOK2GjYva4frrF7Wr+6KW3dhGxHl5u1DuxKaM2E46988db6uIqM0KaU8uF+jvRY1yG53a66qI2E+7tc+6XNrvZo+4MDtExPYRIgarU5S1MDHaVhFximFR21YZUZ13Maj9br473mdX1Pf/dnvGl75THGKQ10NPO6azUWMR1q8uiPpx1IiI0/IeajqTXUScrtvNoj3exnZ8eW/em19fv45Odlv0tIr94hE2iv4ijqeTmRoAAAB8G59GjcZClFkrll9tGtXmESNa48vsgsPsujZFFsO/Wj/CRD6I2w0ay/5j1sJkV74bNXbTRzgYLK/vPC4eMy3akyjrMeG6YGa1n9bizDnO60ewaY+3ERGxqX3f8eYczZkVzTUqys24GTWq3de+U+Mzi5gfIiKqxgyOH82IqftR1LhFi0dgiZhf18jIilH876PHDJf+dB1lXMJT+xpo6tHHmhoAAAB8N59GjeOyeRtCfabG8TqLI8/zKPI88ryI/Hobw3/3P/2Te8C4396RP37+u//F33/8vfaUjvpFenuyfSdqVPfFK29xIiKeXteJ/+NfThoX+5e9ruKwXcdqs79EluoQ00E/ev1hLDabWEyG0c6fv+tT1KhVg/PTRX+1n33tO737mc3bUr46I+ZHt5/Uj9Pb21yKmPw3rcbfs6yI4Xz74fcDAACA7+Sn19QYrB6LXlblOc6nbQwaa0R0Y7k/xb+uzYLIil4srgtxrlarWC2X8b/N/qt3L8brF+nFcP1O1DjFqHjn4v/pdf90WdvvHzzatDysY9ht38NLPcT8bNQ4N77zD77T7xI1msepN1lcFmu9juVyHadyF71axLnv43V9EFEDAACA7+wLTz/ZNp5+UvSXb17SuLBuT6KMiOowrwWCbuyeP7b+9w9mNXSmu3dnasx7jxkIo3dnanTjn/+Lce1Cvf3uo01Pq1r4aI/jHFVM2j+OGqsfzdT46nf6nWZqzHtFbbv7p3dWsd9s4nA6xnLSf5pVc3lsr6gBAADAd/Z51IiI/bxXCwSXRT7r6hfW90e+VttaZMiiPX48CnY1akd7/L9E734R/f76E9N99e6aGvvZY3/6762p0ZlFVdUWE82yaA0eMaY6rGK2OsSiFkd688tjTIe12Q2j7fP6F63YVBHb2TiWh7K55sRoHRH7r32nL0WNr62pUV83I2uNo/zob1nnMcvkuIpO/p/Gf55l0brFjuoY88Ht9d3YVk9RY7SNqLYxnqzigyfnAgAAwO/qS1EjooplLVzk3Ukc7le2ZcxqMwIejzZ9XmQ0i05/EL3rTIjZrozDvP+4iF+dI6rNI0T05lFFRHWoxYqsiPm+jIh99G+3TRTDOEfEdnxbPDSP2fV5sPUnkWRZFq3eKCbj/n3GxKLfXHMirwWNy8/dWOz/VeM2jlb78p3mhzKWg8f3K/qLqCK+9J3iXFskNStitisj4lB7ykoW/UX90bgfnJVyH6N2fZ/bsdjXp5Ksak9UySIrOjEcXINQ95/EP2hdospsc8kv9/VT2tOoIpq30+Sty2f1Fl/7JwMAAAC/sS9GjYvjehadpwv/RjToDmK5q88wKGM56j69rhXTzePWit18eL/14RYv2oPZdWHPc4xaT9sphpe/lbsYtm9P8ng8GnW2rd+2UcV60nuzn/3pZdbIeTNp3HaRtwcxHtRmN+TdWJ8iNpPmdxguD2/WGqnfMvLZdxo/f6esHcNBJ56P048e6/re9puzRq5nYL+I7tO6Ga3+NE5xjuE762lkeTdWx+q2kcatR1l7GHuPdAUAAOCb+KmocXM67GKzXsd6vYnNdhv7wzHKH1zsVudT7Pf72B+O8e7LqlPsD8c4HvZxOP3czQ2nwyGOp2Ps94cPb4uozsfY73ax2x/i/LwD5WXfjrXtng772B9OjX0tT8fY7/fx5d37Fd/p9arLd9rv41g7AMf9/rIGR3mKw34fu3ePYRnH6/EAAACA7+QXRQ0AAACAP5qoAQAAACRJ1AAAAACSJGoAAAAASRI1AAAAgCSJGgAAAECSRA0AAAAgSaIGAAAAkCRRAwAAAEiSqAEAAAAkSdQAAAAAkiRqAAAAAEkSNQAAAIAkiRoAAABAkkQNAAAAIEmiBgAAAJAkUQMAAABIkqgBAAAAJEnUAAAAAJIkagAAAABJEjUAAACAJIkaAAAAQJJEDQAAACBJogYAAACQpESjxjl2212cqz96Pz5Wng5x/M47CAAAAIn7cdSo9jFs55Fl2X20erMof6ed+8h23Iosy6K/Ov3Be/JWdVhEJ78cs8E33D8AAAD4s/jSTI3V8BIRerP9b70/7zptZjHfnu8/n3fz6HX6sTx8z5kQh+UgsiyL4VrUAAAAgN/Kl6LGZtSOLMtitDl//uIXqw6LKLIshps/en7I1503I1EDAAAAfmM/FTU+u0g/rKfRzrPI8iyyrIj+ZNW4VeW4nkQre/x9MN1EFRFRHWLSa0WWF1FkWWStfmxOVVT72ePWlzyLvD2Oc3mM9XwS3VYRo9r+fLjt8hCLySg6RRGD+TJGncutIXlrELt3Okm5m0UrzyPPixhvy4jDPNp5HkWex2Cx/9LnPaLGOSL2Mey0olUUURTtmP3Lv/7S/nz8fbbRzfMoiiKK9iDW23m0s+vPRSfmh4hqP4tWnkXemcTf7lcxHvaiyNsxXUyifT2eneEyvuc8FwAAAPial0WN42p4WedifrlFZT3uXC7W+4uoIuK0vvx9sjlFxDlGrcvF+uocsR237/8d1TY6WRb5YBVRlbFbDK6fu43T6RzlfhmDTtHYnx9v+xjTXnGPI73JImajy99bo8273+V0/bzb55e7aWRZFsVwHfGFz7tFjdGmvESILIvWcBGnKr70/s+O5WHeu/x9cby8/nq7S/d+e9A5RnkW/eUxjptZdIvbmiitmC0X0W9lkWV5XN8OAAAASXpR1DjGIM8iK4bxeMUtXOQxP/xtDPJrqLg6rcdRFP3YlRH7WS+yrBu7iIhqH4P8FhAiysash4tqO67tz2fbriLOqyiyx2dGtYlW/ecnb24fKTfRrr/+k8+7vb8/nUY3y6I32z1t4Efv/8L3uYafrD2Oc23/stbo8vNxHlnWjVviuEWj5fUDz+vhJ+cTAAAAvr/XRI3z+nJbSet6kf38vn/6v/4wIlw+Y3e5BeX2lJWnQFDfduN3n217dYooL6+5febt569HjafXf/J5t/dfRi/eLK/6o/d/5ftExGpQXGZbnCLKa6TIsjzmp4jdqIhiuKm9txVZ1opbF7LmBwAAAH8GL4ga5zj838vrhfiocSG+nVxumxj+1Tq6WRbFcPXO+y+zNi4hYxkRZUxaWeQ/HTU+2Pb69GGU+LVR46Ofb+/Pi8ttJnlv3ly/4kfv/8r3iYhqf7klpjOex6idR288jCLLoj0YRScrYl67tUTUAAAA4M/o555+sn779JPDrBNZ97+PXpZFlnViW7t6v9z2kMXsr//qcqGedWJVu45ejzoxWP1NjIossmJ0XVT0HMP8bdSoP3ml+bv9j7e9r97ePvI8U+JJY02M+utva3B88nm394+3h5h38+vjcGu3oPzw/V/4PhERcbrekpJFlg3iHFVM2tef29PGAq2iBgAAAH9GX4oaq2HremG+jbI8x7k8x+m4j9XsctvDYHWK3bR7nW1xm41xiEHxuMBe9m+LY7ZiNJ3FqJtHlvXjEKdL1MiKGC/WsbguipkV3Zitdvf1HzrjZawmg5huz/d1Nm4LY3627dushnuU+GxNjes28+44trtV9PJLLMjbw9gczp9+XrkdXY9LGRH7+/uHq8v0ic/e/9n3ubkvGDo/RMRjwdDhqhkrtqPWu2tqjBJ6TC4AAAA8+3HUqPYxaOe19SHeG+3rDIAqVuPudaZA5/I40vYo7hML4hjT2poZWdGLzfUiezvt3X/fHkxieH3MadFfRJzXl0Uxrwtjbpajy2Nfr2tIDBb7H2+72t2jQpYVMZzOGt9pMH+z4kVEHGNUe01/NIgiy6LTG8T8//yrH37ef/mP/tFl+7e/z+YxaD2OV/vv/+Mv7M9nx/KqXEcr68R9Dki1jXb954g4LIaR34/5IDbb+XXWTBZZ3o75XtgAAAAgTV+aqfEzqvMp9vt97A/v39pQnc9xOr+9jaUqz1Her6+rKMuq/sfmz79w2z+rLMu4bbb6fPMv95XvUz0dl+efAQAA4M/q5VEDAAAA4PcgagAAAABJEjUAAACAJIkaAAAAQJJEDQAAACBJogYAAACQJFEDAAAASJKoAQAAACRJ1AAAAACSJGoAAAAASRI1AAAAgCSJGgAAAECSRA0AAAAgSaIGAAAAkCRRAwAAAEiSqAEAAAAkSdQAAAAAkiRqAAAAAEkSNQAAAIAkiRoAAABAkkQNAAAAIEmiBgAAAJAkUQMAAABIkqgBAAAAJOkXRo0yNotlHKrX7syPnI/HON7HKcravmyX85gt1nH63fbnj9jm23047DaxXCxisVjEarON4/myM+VhHavt8WVb+vjYv0IZp8bnN8fz386v3TgAAAAJ+0VRo9rPIsuy6M72r96fD5xj3Moiy26jiNX58pf9vHv/fTFc/wbbrmK/3cW5Fi9++23+2H45jtb9WLSi223f96fd7UU7yyIfrF60tY+P/Ws+fhVFVv/8H4/B6vSCjb49pwAAAKTnF0WN1aC4XGTmg3jdfIBPlOvGhfz6emG9HrYegeFlF/IP+3kvsixvXMj/1tv8WBmLQW3bvVljxspq/IgtrZfGlmMMirfH/iXKdbSzLLK8F8vdKeK8qp3nLAarY8R5F5Pu5d/caPPrN/7eOQUAACA9Px81yk10ahedr7jI/Np2rxe/TxfW1XEZnfzyu8n6tYml2k0jf+dC/rfc5o9cLsavxyDvx+Gd12zGnd8gatRna7ReGwPKdbSyPBbHx8/t2r+v4fo2M+MQ/SyL1mjzqzb30TkFAAAgPT8dNQ71C+ssi6wzi/dm8ZenU5yu41xFVKd9rFfLWK7WcTj//OvejRrVOU6nc5zPpzidzlFWzT2pTofLZy1Xsdkd3uxndT7Edr2K1WoV680uTrX1Gsr9vDEzZLE/xflcfrrN8rb/y1Vs983gca5919Pp8uVO++1l+9u3+9fc2W10a8f944v7YwyyLLLGDJIqDrvLdlbrdewOH93CUcVhu47lchmr9SYO9/sz6lGjHZsq4ny4fN5m+15aiTgfdrFerWK12f5w3ZFyO4osG8b9VH8YNSLWgyLak11EdY7dZh2r1Sq273yX8njZ9nqzi9P5FLvrPnx4TgEAAEjST0aNU4wa6ytc1lhYPE1WuK258fHIY7I+ffl1EfFu1Cg3o8br6+tIbKaP+FLk19e0BrErIyLKWAw71xkPRWNNh950ExHnGL67P4P42w+3WdVu/8ijdd1m3hnFvop4uzZFFkWraH5+dxofTR44P213+INpBufdMuarS2wo94v7cWtsr+hFY5LNaR292y0mRf64/WO+f7PvrXareQy6s9p+n2Lab92Pw+3fyGTzQUipyjiXterxg6gRVRWnzfQeJvLbMe5O4vaqzeRxC05e+ze6On98Tl+xSgcAAAC/v5+KGtVucrn9YLdqXHi+d6vDeT1sXDx2p+vYLga133ViW379dR/dfrKddN7sx272iAuzQ0RsH0FgsDo1YshoW0XEKYb1NSPKiOq8a6wjMd8d77Mr3ttm/XfjbRURu8fMivbketF/iEFev9hvx3Q2qs0e+HgRztOqeZwaF/sfqsWIYhxVRJxWj2Nb3GZ7VI99zXvziKge78uHcXoTZD7e79XwFk66sY2I8/K2vU5svjIp4kdR47S8B6jOZBcRp+vxzKI93kaUm+t785hfQ9t63IksK2J9/vE5BQAAID0/FTWWvSyyziwiIha9vHaR24nt0y0G9ZkFlwvliIhzjIr6Bev5y6/7KGqUm/FTYKjFhNYozhFR7afNbdZCSnu8jYiITW3xz/HmHM/rSKzrt6Y8b7PaPdYZqS2euuw/ZkZMduXTZxYxP0Q0AkKWxeiDGRj1xUmzLIvJ9iuF4FyLNe3YRjQXXG2P4xwR++ljdsNljZQqZp1bDBnF+Wm/LzNzmvs9XJ8jqs3jHLUuESUOs/uMiS+FmB9Eje348ZSX8fUf3LybP/bzXPturX6sDmVEnGLQ6lz/vXx8TgEAAEjP16PG9WL4dpFZbieNi+zevLm2Qj1WtEa3mRxlTDuPGNKd7b/8uo+iRuP9w3WUu9p+FaPrrQWXtSJWm/3lQrs6xHTQj15/GIvNJhaTYbTz5wvppwvg8wffbbiOav+4cL+FlIiIzaj2qNXJ9oPPPD/Fgfcv/I/LQeN4f22mRsRhNY1+rxfDySK260UMa49/vRyfMqadt59bnQ+xXq1if6q+vN+N45Bll1t7asf1S4+//TBqVDHr5o1j0Lx9p4jVcd14ckqWZVF0hrG9n7uPzykAAADp+XLU2M+eFgh9HsWwsTbB84X/Tf3/treG6y+/7qtR47yurT1RCwzPysP6cYGfF42L8Z+NGo1baIr3o8blgv6XR43nNTW+/tSZMtazR7QpiuxpX8+NdVLenynytf1uHodeLK6LsK5Wq1gtl7He/ZqZGqfG7J3eZHFZiPQ6lst1nKqI3bv/TotYnj76HgAAAKTqi1HjGIM8i6I/i91uG9vtNra7XSzHncbF47h2S8T7MzCqmNduWxmuTl9+3ZdnamzHtX1qv3uLwWlVCwTtcZyjikn7x1Fj9aOZGof5pzM1OtPdm8/8majx/Cjdor/8+HSd97HdnyPi2AwWm3PEm5ks58Z3f5yDxgd+baZG/Thk3dh9vIcf+8FMjXmvqB3P/Zu3VqddbHbHOO6W0W83Z3X0F4c33+Olj6YFAADgd/elqHELBfOnp5xEtW1caNcf79pcK2Nx/e0h+vfbEfKY7asvv+7jNTWeosjTPrUGj4v/6rCK2erQWA+kNz9FRFlbeyKL0fZ5/YtWbKqI7Wwcy0P5dpuxj95tmx+sqTHdf/U2jo+vtPezx9oXWZbH/L2nqZ7WlzVFinGUx3pk6McxIsr6bIrWOMqI2E3qcaoVy/t5rmI9m8e++ny/R+tzRLVtBIn2+PHY2dWo3fj5Q/V1OZ5mpNRn72RZ5zHT4riKTt6J1T8bRJa145Y7TtvZ/bM679z+Uz+nAAAApOfzqFHenhjRjc3paTXQqh4frheh10eJPt8u0ZuuYjmuXZR3ZlH+xOuqw6L26NUi5vsyIqpYDh4LaBb9RVTRfBJJlmXR6o1iMu7fZ0ws+s3/i58X2dPP3Vjs/1XjdofbY0znh/LdbR7m/UeYWF0WzbzHld78EnvO61pwKWK2KyPiUHsix21GwYcnIxaD+oKh7Ziud3E6n+N0OsRyel13I+9fHl17XDTXuMjyNz93h4soy6c4lbViNJlEv32JB7t//YX9nl9SwvOCpp3+IHrXmSCX9/1IFftl899De7iI872UrZprZhSdGA6ut5t0Z/H/Xv8ttfqzOFYREcf7Pl4Waj19cE6rj3cJAACAb+uTqPH8KM8sxrdVF8u3izLeZyXsyqdYUdSCRBZ5ZxS368ivva657sPlgnYYf/MURC4zHU4RUcV68nZthf50c93mpHFxn7cHMR7UZgHk3VifIjaTbvOzl4c3EeaxzYjdfHj/3Nv3aA9m17VG3h7LLGvHcNB5+t3nt0Uc1tPoFM+fdY0Iw3ltbZNTTBqLa+bRH48aMyG6k8vtJtVxHb3nzyz6sTn97H6XsRx13/xtuvlsPY33tvN4/31mzn4R3aeQ1upP4xSPxwPnT+/vjlf3GUTvnVMAAADS9FOPdP0Z9Yv/y2NTyzjs97E/nH7R636J6nyM/W4Xu/3h8X/7b8pT7Pf7OJ4eswdOh8t2q8bLjrHf7+P01TsUqlPsD8c4HvZx+PKbfpnTYReb9TrW63VstrsP9/HyvY5R3r7Y9buf3hyUKo6Hfex2uzgcf92CE9X5so394RivnwdRXb7Tfh/H+ncoj7E/Xh5JezoeYr/bvXsOfvqcAgAA8C39ZlGj3DwW7HyslfHLXwcAAABQ9xtFjTLWjWn+nVge3vs//199HQAAAEDTbxI1yt00iiyPVqt1HUU0nlbxk68DAAAAePab3X4CAAAA8FsSNQAAAIAkiRoAAABAkkQNAAAAIEmiBgAAAJAkUQMAAABIkqgBAAAAJEnUAAAAAJIkagAAAABJEjUAAACAJIkaAAAAQJJEDQAAACBJogYAAACQJFEDAAAASJKoAQAAACRJ1AAAAACSJGoAAAAASRI1AAAAgCSJGgAAAECSRA0AAAAgSaIGAAAAkKSfjhpVeY7T8Rin0zmq6+/Kc/ni3eKN6hyH/fF+zAEAAODfdl+OGtVxE8NuEVmWNUa7044s68X+t9zLf5tV+xh2rsc9H8bpj94fAAAA+Ca+FDVO6/E1YhQxWe/vswVOu0V0siyyrBWr82+4lz+titV4HNvfaJ9Om1nMf6sPf0d13kQ3yyJrjeLXb/Xnjs3v/V0BAADgqz6PGud1tLIssiyP2f6dmx/Oy8izPJbf6Lp3N+tFlhWx/g3uiqkOiyiyLIab3/OWm3OMW1lkxehXz9T4mWPzx3xXAAAA+JpPo8Zm3I4syyLvzj5cz2Ezm8Vf/1+zaOV55HkR420ZcZhHO8+jyPMYLPYR5THWi2l0iyIG01n0W1lk2d+L/2H+/LtObMqI8rCMbnG9zSVvx3h5ucHlvF/FeNiLIm/HdDGJ9vU2mM5wGVVE7Gfdxu0x3cmmubPlIRaTUXSKIgbzZYw6+eX7tQaxq1277+bDyK+fUbQHsT5WUe1nj8/Os8jb4/h/lsPIszyKLIvudBu7eT+yLI+iyKPVm0YZEbtp77Iv021ERBzW02jnl8/IsiL6k1WUER8co05sykfUKCNiOexGq1VEURTRHS7ibXKoYjXuRp4X0SryyPJubM4fHJvqEJNeK7K8iCLLImv1Y3N6/7v+81k/8jyPoj2MY0TsZ/3I8yLy6+dHRBzXkyiyLIpWEXmeR3d8Of6HxSCyLIvB8vDZPzkAAAD4kk+jxnJwWc+hNdp89tI4rYaRZVkM15f5BOVueokCw3XEaX29SL9GiE4RWfYfxH/2Hz3/rhXrv1lGkWUxWh0j4hDD6/sm2zKOm9kjdmStmC0X18/NY3GMiOoci0ErsqyI+fYY5ZsSc4xp77E2SG+yiNmo0/iO+3k3sqwb2zKi3M2vM1X6cajK2F0vzvvzbZxO54goY9K5fNbsGBFRxqybR5YVsbxNqzgvI89asSkjjtdj1J9fIs16fNl23l9E9e4xasX6fIsa46giYtEvIsv7sTm+P4Oi3F5uF5oeIyL20ctbl5k07xyb7bgdWVZcbh+qttHJssgHq4gPvuu41bzdaD1s1X4+RC/Lonf94uthEXl/FRER28kljrUn20//HQEAAMBXfBI1TjG8BoTh6vMbH86bUSNqRLmJ9i1qRER1vdjuTneXP5fVu79bDYrIsiJGs1lMZ7MYtrNHHInHhfgtGpzXzZiyGbUiywZx/HBHV5fZBNfPi2oTrdvP1T56WRZZaxCz2Sxms9E9Msz2VZT37/i43+YWc3rXUHGcdRrfaTdpR9ZfRsQxBnkWWVFf8PMco2uUmR/ePx7320/yTgy6eWSdyQ9vQ7kdj+54HVVEnFazuJ2S52Ozn/Uiy7qxi4io9jHIH8flve96OfatuP3q8nnXn6/nO2sPL2t2VJuYzHfXd5Zx2B/emVUCAMia8a0AABIYSURBVAAAv8ynMzVWg9Z1FsP60w97GzXWj1hQ+/toc37znsfvrhfwrX5MZ7OYTqcxm81jPpvFand5TeNC+p3tbkZFZPkPFtW87lfrFjXq+3ldQ6TojWM2m963P5vNYnMo337HiIi4hpDr7SGL3nW2RTGMc5yin2Ux2VeP9Ula48a+bUbtezh67xhFnGPcfszgGH22xsUtLmRZZFk7ppvHvr57bM67yy0o1/e0ns5X/bs+H/vmz9V1lsr19pbx0iNoAQAA+M18GjW21zU1svb40ydvfDVq1C+S3/6ujGnnEQgaqssl8quiRvGDqNGbv137oaqqD6LGLUzkMVlOo5W1YzTsRJblMRz3Iyuu+3KPGs1920469898//OvoeceKi7rjvzQaROD9iMw3NayeD42tyfbtIbLiChj0soi/8VR47Kvi2Hnsa8/WIsFAAAAfo0vPP1kdV1TIovh6v0bOnaLaawOVW2WwfWK+zYj4rpWxf3v63dmatx/V8bkOithXJ+tcFxEkV9u2/g8arQua2B89J2ebotpzNwoN5fH1Oa92NWuxnfTTrSGmw9mUlz37zbTYbyLKB/Hrbe47cl1RkfWiW3ts2/haLav3j1G96jRnsRmOfw0Mp1XoxheH0ezW4wuC552LouWNo/NOUZFPSCdY5i/jRr173o79rdTfLsdZVNejmOvN4+IiOqwil7RXH+jPLv5BAAAgNf5PGrE48kVWZbFYLa5z6AoT7uY9ovIsnasT4+1HPLuOLa7VfTyy3vy9jA2h/N9jYb6LIj3fndboyLL8hhM5rGYXS7M+8tLVNmOWu+uqXGLKZfFK/OYrFYxGU7frD9R7aeNhUEba2pEFbPu7faRbkym0xgPHhfut211xstYTQYx3T7HmNtF/O1zmrMqdtPudWbE6nZ0Y1BkkbUv0eG94xFxuq7FMY6IiOX1lqCiP393jYrzehhZflu3o4pRnl3X9Hg+Nv8w/uvi8gSW8WIdi+uipVnRjdlq9+53vbw/i/5sHdvVuHarySrO53UU17VBIiL2k/ZlvY7qtnZHFh0LhQIAAPAiX4oaERGn7bz21JHHaPUmcbhfWR9jVLvloT8aRJFl0ekNYvY//+P7zIXLRfE2yt3sze8uqliPm48fvf3tsHg8ajUrBrHZzh+fkbdjvi/vTxjJsix6s6eL6Gp3jy1ZVsRwOmvepjHfR5S7+xNXbutSLPbXL3leX2ZyXGdL1OeunJa9yHuL+8/n1SDy7iKaLo9bvby/c3m0a3sU+yrePx7VLgatx/51hovYzPuPfSv6jUfRRjxmWGRFO9pFFlnejeX1JD0fm+31cbNZlkV7MInh9RG3RX/x7nct97XjnXVjMu5FlrWiP5zF4f+7reWRX89RHoPrQqG3x8mKGgAAALzKl6PGzel4iN1uH/vDIT66m6Asy/ujVKtfsaBCdT7F8XiM8y/4jPJ8+nD/vup0PMbxeHq7JkRVXp9K8stV51Ps9/vYHz5/qswv3kZZxvl8frP/z8emKs9R3n+umt/t3e9axul0+9zq3eNzOp3ePE7X7ScAAAC80k9HDQAAAIDvQNQAAAAAkiRqAAAAAEkSNQAAAIAkiRoAAABAkkQNAAAAIEmiBgAAAJAkUQMAAABIkqgBAAAAJEnUAAAAAJIkagAAAABJEjUAAACAJIkaAAAAQJJEDQAAACBJogYAAACQJFEDAAAASJKoAQAAACRJ1AAAAACSJGoAAAAASRI1/kz+8i//XAMAAAB+QNT4M8myP9cAAACAH/j0yvHfZP/un2I8+/ey//ZPMZpn8xID/vI//jtJj/eixr/5Z9mfYgAAAPA6okbio3k2LzHg3/kf/8Okh6gBAADAV4gaiY/m2RQ1vvsAAADgdUSNxEfzbIoa330AAADwOqJG4qN5NkWN7z4AAAB4HVEj8dE8m6LGdx8AAAC8jqiR+GieTVHjuw8AAABeR9RIfDTPpqjx3QcAAACvI2okPppnU9T47gMAAIDXETUSH82zKWp89wEAAMDriBqJj+bZFDW++wAAAOB1RI3ER/NsihrffQAAAPA6okbio3k2RY3vPgAAAHgdUSPx0TybosZ3HwAAALyOqJH4aJ5NUeO7DwAAAF5H1Eh8NM+mqPHdBwAAAK8jaiQ+mmdT1PjuAwAAgNcRNRIfzbMpanz3AQAAwOuIGomP5tkUNb77AAAA4HVEjcRH82yKGt99AAAA8DqiRuKjeTZFje8+AAAAeB1RI/HRPJuixncfAAAAvI6okfhonk1R47sPAAAAXkfUSHw0z6ao8d0HAAAAryNqJD6aZ1PU+O4DAACA1xE1Eh/NsylqfPcBAADA64gaiY/m2RQ1vvsAAADgdUSNxEfzbIoa330AAADwOqJG4qN5NkWN7z4AAAB4HVEj8dE8m6LGdx8AAAC8jqiR+GieTVHjuw8AAABeR9RIfDTPpqjx3QcAAACvI2okPppnU9T47gMAAIDXETUSH82zKWp89wEAAMDriBqJj+bZFDW++wAAAOB1RI3ER/NsihrffQAAAPA6okbio3k2RY3vPgAAAHgdUSPx0TybosZ3HwAAALyOqJH4aJ5NUeO7DwAAAF5H1Eh8NM+mqPHdBwAAAK8jaiQ+mmdT1PjuAwAAgNcRNRIfzbMpanz3AQAAwOuIGomP5tkUNb77AAAA4HVEjcRH82yKGt99AAAA8DqiRuKjeTZFje8+AAAAeB1RI/HRPJuixncfAAAAvI6okfhonk1R47sPAAAAXkfUSHw0z6ao8d0HAAAAryNqJD6aZ/MSA/7iP/n3kx6iBgAAAF8haiQ+mmcz+3ON+r/DbxAkRA0AAIDvxVXWn8lf/MWfawAAAMAPiBoAAABAkkQNAAAAIEmiBgAAAJAkUQMAAABIkqgBAAAAJEnUAAAAAJIkagAAAABJEjUAAACAJIkaAAAAQJJEDQAAACBJogYAAACQJFEDAAAASJKoAQAAACRJ1AAAAACSJGoAAAAASRI1AAAAgCSJGgAAAECSRA0AAAAgSaIGAAAAkCRRAwAAAEiSqAEAAAAkSdQAAAAAkiRqAAAAAEkSNQAAAIAkiRoAAABAkkQNAAAAIEmiBgAAAJAkUQMAAABIkqgBAAAAJEnUAAAAAJIkagAAAABJEjUAAACAJIkaAAAAQJJEDQAAACBJogYAAACQJFEDAAAASJKoAQAAACRJ1AAAAACSJGoAAAAASRI1AAAAgCSJGgAAAECSRA0AAAAgSaIGAAAAkCRRAwAAAEiSqAEAAAAkSdQAAAAAkiRqAAAAAEkSNQAAAIAkiRoAAABAkkQNAAAAIEmiBgAAAJAkUQMAAABIkqgBAAAAJEnUAAAAAJIkagAAAABJEjUAAACAJIkaAAAAQJJEDQAAACBJogYAAACQJFEDAAAASJKoAQAAACRJ1AAAAACSJGoAAAAASRI1AAAAgCSJGgAAAECSRA0AAAAgSaIGAAAAkCRRAwAAAEiSqAEAAAAkSdQAAAAAkiRqAAAAAEkSNQAAAIAkiRoAAABAkkQNAAAAIEmiBgAAAJAkUQMAAABIkqgBAAAAJEnUAAAAAJIkagAAAABJEjUAAACAJIkaAAAAQJJEDQAAACBJogYAAACQJFEDAAAASJKoAQAAACRJ1AAAAACSJGoAAAAASRI1AAAAgCSJGgAAAECSRA0AAAAgSaIGAAAAkCRRAwAAAEiSqAEAAAAkSdQAAAAAkiRqAAAAAEkSNQAAAIAkiRoAAABAkkQNAAAAIEmiBgAAAJAkUQMAAABIkqgBAAAAJEnUAAAAAJIkagAAAABJEjUAAACAJIkaAAAAQJJEDQAAACBJogYAAACQJFEDAAAASJKoAQAAACRJ1AAAAACSJGoAAAAASRI1AAAAgCSJGgAAAECSRA0AAAAgSaIGAAAAkCRRAwAAAEiSqAEAAAAkSdQAAAAAkiRqAAAAAEkSNQAAAIAkiRoAAABAkkQNAAAAIEmiBgAAAJAkUQMAAABIkqgBAAAAJEnUAAAAAJIkagAAAABJEjUAAACAJIkaAAAAQJJEDQAAACBJogYAAACQJFEDAAAASJKoAQAAACRJ1AAAAACSJGoAAAAASRI1AAAAgCSJGgAAAECSRA0AAAAgSaIGAAAAkCRRAwAAAEiSqAEAAAAkSdQAAAAAkiRqAAAAAEkSNQAAAIAkiRoAAABAkkQNAAAAIEmiBgAAAJAkUQMAAABIkqgBAAAAJEnUAAAAAJIkagAAAABJEjUAAACAJIkaAAAAQJJEDQAAACBJogYAAACQJFEDAAAASJKoAQAAACRJ1AAAAACSJGoAAAAASRI1AAAAgCSJGgAAAECSRA0AAAAgSaIGAAAAkCRRAwAAAEiSqAEAAAAkSdQAAAAAkiRqAAAAAEkSNQAAAIAkiRoAAABAkkQNAAAAIEmiBgAAAJAkUQMAAABIkqgBAAAAJEnUAAAAAJIkagAAAABJEjUAAACAJIkaAAAAQJJEDQAAACBJogYAAACQJFEDAAAASJKoAQAAACRJ1AAAAACSJGoAAAAASRI1AAAAgCSJGgAAAECSRA0AAAAgSaIGAAAAkCRRAwAAAEiSqAEAAAAkSdQAAAAAkiRqAAAAAEkSNQAAAIAkiRoAAABAkkQNAAAAIEmiBgAAAJAkUQMAAABIkqgBAAAAJEnUAAAAAJIkagAAAABJEjUAAACAJIkaAAAAQJJEDQAAACBJogYAAACQJFEDAAAASJKoAQAAACRJ1AAAAACSJGoAAAAASRI1AAAAgCSJGgAAAECSRA0AAAAgSaIGAAAAkCRRAwAAAEiSqAEAAAAkSdQAAAAAkiRqAAAAAEkSNQAAAIAkiRoAAABAkkQNAAAAIEmiBgAAAJAkUQMAAABIkqgBAAAAJEnUAAAAAJIkagAAAABJEjUAAACAJIkaAAAAQJJEDQAAACBJogYAAACQJFEDAAAASJKoAQAAACRJ1AAAAACSJGoAAAAASRI1AAAAgCSJGgAAAECSRA0AAAAgSaIGAAAAkCRRAwAAAEiSqAEAAAAkSdQAAAAAkiRqAAAAAEkSNQAAAIAkiRoAAABAkkQNAAAAIEmiBgAAAJAkUQMAAABIkqgBAAAAJEnUAAAAAJIkagAAAABJEjUAAACAJIkaAAAAQJJEDQAAACBJogYAAACQJFEDAAAASJKoAQAAACRJ1AAAAACSJGoAAAAASRI1AAAAgCSJGgAAAECSRA0AAAAgSaIGAAAAkCRRAwAAAEiSqAEAAAAkSdQAAAAAkiRqAAAAAEkSNQAAAIAkiRoAAABAkkQNAAAAIEmiBgAAAJAkUQMAAABIkqgBAAAAJEnUAAAAAJIkagAAAABJEjUAAACAJIkaAAAAQJJEDQAAACBJogYAAACQJFEDAAAASJKoAQAAACRJ1AAAAACSJGoAAAAASRI1AAAAgCSJGgAAAECSRA0AAAAgSaIGAAAAkCRRAwAAAEiSqAEAAAAkSdQAAAAAkiRqAAAAAEkSNQAAAIAkiRoAAABAkkQNAAAAIEmiBgAAAJAkUQMAAABIkqgBAAAAJEnUAAAAAJIkagAAAABJEjUAAACAJIkaAAAAQJJEDQAAACBJogYAAACQJFEDAAAASJKoAQAAACRJ1AAAAACSJGoAAAAASRI1AAAAgCSJGgAAAECSRA0AAAAgSaIGAAAAkCRRAwAAAEiSqAEAAAAkSdQAAAAAkiRqAAAAAEkSNQAAAIAkiRoAAABAkkQNAAAAIEmiBgAAAJAkUQMAAABIkqgBAAAAJEnUAAAAAJIkagAAAABJEjUAAACAJIkaAAAAQJJEDQAAACBJogYAAACQJFEDAAAASJKoAQAAACRJ1AAAAACSJGoAAAAASRI1AAAAgCSJGgAAAECSRA0AAAAgSaIGAAAAkCRRAwAAAEiSqAEAAAAkSdQAAAAAkiRqAAAAAEkSNQAAAIAkiRoAAABAkkQNAAAAIEmiBgAAAJAkUQMAAABIkqgBwP/fjh2QAAAAAAj6/7odgc4QAACWpAYAAACwJDUAAACAJakBAAAALEkNAAAAYElqAAAAAEtSAwAAAFiSGgAAAMCS1AAAAACWpAYAAACwJDUAAACAJakBAAAALEkNAAAAYElqAAAAAEtSAwAAAFiSGgAAAMCS1AAAAACWpAYAAACwJDUAAACAJakBAAAALEkNAAAAYElqAAAAAEsBt+vReTPIffgAAAAASUVORK5CYII=', - self.marionette.screenshot(highlights=[el])) - def testWeCanTakeAScreenShotEntireCanvas(self): test_url = self.marionette.absolute_url('html5Page.html') self.marionette.navigate(test_url) diff --git a/testing/marionette/marionette-listener.js b/testing/marionette/marionette-listener.js index 0e2d8365408..58505052c3c 100644 --- a/testing/marionette/marionette-listener.js +++ b/testing/marionette/marionette-listener.js @@ -1789,7 +1789,7 @@ function screenShot(msg) { let highlights = msg.json.highlights; var document = curWindow.document; - var rect, win, width, height, left, top; + var rect, win, width, height, left, top, needsOffset; // node can be either a window or an arbitrary DOM node if (node == curWindow) { // node is a window @@ -1798,6 +1798,8 @@ function screenShot(msg) { height = win.innerHeight; top = 0; left = 0; + // offset needed for highlights to take 'outerHeight' of window into account + needsOffset = true; } else { // node is an arbitrary DOM node @@ -1807,6 +1809,8 @@ function screenShot(msg) { height = rect.height; top = rect.top; left = rect.left; + // offset for highlights not needed as they will be relative to this node + needsOffset = false; } var canvas = document.createElementNS("http://www.w3.org/1999/xhtml", "canvas"); @@ -1823,11 +1827,19 @@ function screenShot(msg) { ctx.save(); for (var i = 0; i < highlights.length; ++i) { - var elem = elementManager.getKnownElement(highlights[i], curWindow) + var elem = highlights[i]; rect = elem.getBoundingClientRect(); - var offsetY = -top; - var offsetX = -left; + var offsetY = 0, offsetX = 0; + if (needsOffset) { + var offset = getChromeOffset(elem); + offsetX = offset.x; + offsetY = offset.y; + } else { + // Don't need to offset the window chrome, just make relative to containing node + offsetY = -top; + offsetX = -left; + } // Draw the rectangle ctx.strokeRect(rect.left + offsetX, rect.top + offsetY, rect.width, rect.height); From 05acb4b4038c05f7b9b0a1afa934e15dbd4c5223 Mon Sep 17 00:00:00 2001 From: Jonathan Watt Date: Wed, 4 Sep 2013 11:39:30 +0100 Subject: [PATCH 052/171] Bug 911862 - Make VectorImage use the refresh driver to send out frame change notifications. r=dholbert --- image/src/VectorImage.cpp | 24 +++++++++++++++++------- image/src/VectorImage.h | 13 +++++++++++-- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/image/src/VectorImage.cpp b/image/src/VectorImage.cpp index f87babcfe9f..7655505f259 100644 --- a/image/src/VectorImage.cpp +++ b/image/src/VectorImage.cpp @@ -90,7 +90,7 @@ protected: // Ignore further invalidations until we draw. mHonoringInvalidations = false; - mVectorImage->InvalidateObserver(); + mVectorImage->InvalidateObserversOnNextRefreshDriverTick(); } // Our caller might've removed us from rendering-observer list. @@ -314,7 +314,8 @@ VectorImage::VectorImage(imgStatusTracker* aStatusTracker, mIsInitialized(false), mIsFullyLoaded(false), mIsDrawing(false), - mHaveAnimations(false) + mHaveAnimations(false), + mHasPendingInvalidation(false) { } @@ -485,6 +486,18 @@ VectorImage::RequestRefresh(const mozilla::TimeStamp& aTime) { // TODO: Implement for b666446. EvaluateAnimation(); + + if (mHasPendingInvalidation && mStatusTracker) { + // This method is called under the Tick() of an observing document's + // refresh driver. We send out the following notifications here rather than + // under WillRefresh() (which would be called by our own refresh driver) so + // that we only send these notifications if we actually have a document + // that is observing us. + mStatusTracker->FrameChanged(&nsIntRect::GetMaxSizedIntRect()); + mStatusTracker->OnStopFrame(); + } + + mHasPendingInvalidation = false; } //****************************************************************************** @@ -1006,12 +1019,9 @@ VectorImage::OnDataAvailable(nsIRequest* aRequest, nsISupports* aCtxt, // Invalidation helper method void -VectorImage::InvalidateObserver() +VectorImage::InvalidateObserversOnNextRefreshDriverTick() { - if (mStatusTracker) { - mStatusTracker->FrameChanged(&nsIntRect::GetMaxSizedIntRect()); - mStatusTracker->OnStopFrame(); - } + mHasPendingInvalidation = true; } } // namespace image diff --git a/image/src/VectorImage.h b/image/src/VectorImage.h index fdfa2868712..5ffd018dac6 100644 --- a/image/src/VectorImage.h +++ b/image/src/VectorImage.h @@ -59,8 +59,15 @@ public: bool aLastPart) MOZ_OVERRIDE; virtual nsresult OnNewSourceData() MOZ_OVERRIDE; - // Callback for SVGRootRenderingObserver. - void InvalidateObserver(); + /** + * Callback for SVGRootRenderingObserver. + * + * This just sets a dirty flag that we check in VectorImage::RequestRefresh, + * which is called under the ticks of the refresh driver of any observing + * documents that we may have. Only then (after all animations in this image + * have been updated) do we send out "frame changed" notifications, + */ + void InvalidateObserversOnNextRefreshDriverTick(); // Callback for SVGParseCompleteListener. void OnSVGDocumentParsed(); @@ -89,6 +96,8 @@ private: bool mIsDrawing; // Are we currently drawing? bool mHaveAnimations; // Is our SVG content SMIL-animated? // (Only set after mIsFullyLoaded.) + bool mHasPendingInvalidation; // Invalidate observers next refresh + // driver tick. friend class ImageFactory; }; From 01b166fceffbf6616889f0c8c5bdea02b431ea53 Mon Sep 17 00:00:00 2001 From: Jonathan Watt Date: Wed, 4 Sep 2013 11:39:31 +0100 Subject: [PATCH 053/171] Bug 907503 - Fix invalidation for SMIL animation in SVG-as-an-image. r=roc --- layout/base/nsDisplayList.cpp | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index b12509ec0d4..520df5f3d7f 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -1141,7 +1141,16 @@ void nsDisplayList::PaintForFrame(nsDisplayListBuilder* aBuilder, BuildContainerLayerFor(aBuilder, layerManager, aForFrame, nullptr, *this, containerParameters, nullptr); - if (widgetTransaction) { + nsIDocument* document = nullptr; + if (presShell) { + document = presShell->GetDocument(); + } + + if (widgetTransaction || + // SVG-as-an-image docs don't paint as part of the retained layer tree, + // but they still need the invalidation state bits cleared in order for + // invalidation for CSS/SMIL animation to work properly. + (document && document->IsBeingUsedAsImage())) { aForFrame->ClearInvalidationStateBits(); } @@ -1177,13 +1186,10 @@ void nsDisplayList::PaintForFrame(nsDisplayListBuilder* aBuilder, } bool mayHaveTouchListeners = false; - if (presShell) { - nsIDocument* document = presShell->GetDocument(); - if (document) { - nsCOMPtr innerWin(document->GetInnerWindow()); - if (innerWin) { - mayHaveTouchListeners = innerWin->HasTouchEventListeners(); - } + if (document) { + nsCOMPtr innerWin(document->GetInnerWindow()); + if (innerWin) { + mayHaveTouchListeners = innerWin->HasTouchEventListeners(); } } From 9c1142dce4170e6bfff449828e0235fb3a9fd5c3 Mon Sep 17 00:00:00 2001 From: Jonathan Watt Date: Wed, 4 Sep 2013 11:39:32 +0100 Subject: [PATCH 054/171] Bug 907503 - Test that invalidation works for SMIL animation in SVG-as-an-image. r=longsonr --- image/test/mochitest/Makefile.in | 2 + image/test/mochitest/lime-anim-100x100-2.svg | 6 + image/test/mochitest/test_animSVGImage2.html | 118 +++++++++++++++++++ 3 files changed, 126 insertions(+) create mode 100644 image/test/mochitest/lime-anim-100x100-2.svg create mode 100644 image/test/mochitest/test_animSVGImage2.html diff --git a/image/test/mochitest/Makefile.in b/image/test/mochitest/Makefile.in index ed43a84879a..3935249e510 100644 --- a/image/test/mochitest/Makefile.in +++ b/image/test/mochitest/Makefile.in @@ -81,8 +81,10 @@ MOCHITEST_FILES = imgutils.js \ MOCHITEST_CHROME_FILES = imgutils.js \ animationPolling.js \ lime-anim-100x100.svg \ + lime-anim-100x100-2.svg \ animation.svg \ test_animSVGImage.html \ + test_animSVGImage2.html \ test_animation.html \ test_animation2.html \ animated-gif-finalframe.gif \ diff --git a/image/test/mochitest/lime-anim-100x100-2.svg b/image/test/mochitest/lime-anim-100x100-2.svg new file mode 100644 index 00000000000..d19d3b0e7e6 --- /dev/null +++ b/image/test/mochitest/lime-anim-100x100-2.svg @@ -0,0 +1,6 @@ + + + + + diff --git a/image/test/mochitest/test_animSVGImage2.html b/image/test/mochitest/test_animSVGImage2.html new file mode 100644 index 00000000000..de0fabf216e --- /dev/null +++ b/image/test/mochitest/test_animSVGImage2.html @@ -0,0 +1,118 @@ + + + + + Test for Bug 907503 + + + + + + +Mozilla Bug 907503 +

+
+
+ +
+
+
+
+ + From 65548f9f1d43b26294f17ed2766cd5b81d6ee466 Mon Sep 17 00:00:00 2001 From: Till Schneidereit Date: Wed, 4 Sep 2013 12:35:50 +0200 Subject: [PATCH 055/171] Bug 912302 - Slim down TraceLogging output by shortening entry keys and timestamps. r=h4writer --HG-- extra : rebase_source : c6eb53e295f648267c0dfbcf7f34709a3eccf15a --- js/src/TraceLogging.cpp | 45 +++++++++++++++++++++-------------------- js/src/TraceLogging.h | 1 + 2 files changed, 24 insertions(+), 22 deletions(-) diff --git a/js/src/TraceLogging.cpp b/js/src/TraceLogging.cpp index c6b0793516d..898044b4653 100644 --- a/js/src/TraceLogging.cpp +++ b/js/src/TraceLogging.cpp @@ -66,30 +66,31 @@ rdtsc(void) #endif const char* const TraceLogging::type_name[] = { - "start,script", - "stop,script", - "start,ion_compile", - "stop,ion_compile", - "start,yarr_jit_execute", - "stop,yarr_jit_execute", - "start,gc", - "stop,gc", - "start,minor_gc", - "stop,minor_gc", - "start,parser_script", - "stop,parser_script", - "start,parser_lazy", - "stop,parser_lazy", - "start,parser_function", - "stop,parser_function", - "info,engine,interpreter", - "info,engine,baseline", - "info,engine,ionmonkey" + "1,s", // start script + "0,s", // stop script + "1,c", // start ion compilation + "0,c", // stop ion compilation + "1,r", // start regexp JIT execution + "0,r", // stop regexp JIT execution + "1,G", // start major GC + "0,G", // stop major GC + "1,g", // start minor GC + "0,g", // stop minor GC + "1,ps", // start script parsing + "0,ps", // stop script parsing + "1,pl", // start lazy parsing + "0,pl", // stop lazy parsing + "1,pf", // start Function parsing + "0,pf", // stop Function parsing + "e,i", // engine interpreter + "e,b", // engine baseline + "e,o" // engine ionmonkey }; TraceLogging* TraceLogging::_defaultLogger = NULL; TraceLogging::TraceLogging() : loggingTime(0), + startupTime(rdtsc()), entries(NULL), curEntry(0), numEntries(1000000), @@ -131,7 +132,7 @@ TraceLogging::grow() void TraceLogging::log(Type type, const char* file, unsigned int lineno) { - uint64_t now = rdtsc(); + uint64_t now = rdtsc() - startupTime; // Create array containing the entries if not existing. if (entries == NULL) { @@ -155,7 +156,7 @@ TraceLogging::log(Type type, const char* file, unsigned int lineno) // Save the time spend logging the information in order to discard this // time from the logged time. Especially needed when increasing the array // or flushing the information. - loggingTime += rdtsc()-now; + loggingTime += rdtsc() - startupTime - now; } void @@ -193,7 +194,7 @@ TraceLogging::flush() for (unsigned int i = 0; i < curEntry; i++) { int written; if (entries[i].type() == INFO) { - written = fprintf(out, "INFO,%s\n", entries[i].file()); + written = fprintf(out, "I,%s\n", entries[i].file()); } else { if (entries[i].file() == NULL) { written = fprintf(out, "%llu,%s\n", diff --git a/js/src/TraceLogging.h b/js/src/TraceLogging.h index 64ae5a8df23..59c7c9a9c35 100644 --- a/js/src/TraceLogging.h +++ b/js/src/TraceLogging.h @@ -58,6 +58,7 @@ class TraceLogging Type type() const { return (Type) type_; } }; + uint64_t startupTime; uint64_t loggingTime; Entry *entries; unsigned int curEntry; From 77cc54733ec080432d9dc3267c7b15d60f2a94f8 Mon Sep 17 00:00:00 2001 From: Gabor Krizsanits Date: Wed, 4 Sep 2013 12:15:50 +0200 Subject: [PATCH 056/171] Bug 892203 - Minor cleanups in sandbox.cpp. r=bholley --- js/xpconnect/src/Sandbox.cpp | 59 +++++++++++----------- js/xpconnect/src/XPCWrappedNativeScope.cpp | 1 - 2 files changed, 29 insertions(+), 31 deletions(-) diff --git a/js/xpconnect/src/Sandbox.cpp b/js/xpconnect/src/Sandbox.cpp index 0700d723f6d..8f88f8159ed 100644 --- a/js/xpconnect/src/Sandbox.cpp +++ b/js/xpconnect/src/Sandbox.cpp @@ -960,14 +960,14 @@ xpc::CreateSandboxObject(JSContext *cx, jsval *vp, nsISupports *prinOrSop, Sandb // Pass on ownership of sbp to |sandbox|. JS_SetPrivate(sandbox, sbp.forget().get()); - bool allowComponents = nsContentUtils::IsSystemPrincipal(principal) || - nsContentUtils::IsExpandedPrincipal(principal); - if (options.wantComponents && allowComponents && - !nsXPCComponents::AttachComponentsObject(cx, GetObjectScope(sandbox))) - return NS_ERROR_XPC_UNEXPECTED; + bool allowComponents = nsContentUtils::IsSystemPrincipal(principal) || + nsContentUtils::IsExpandedPrincipal(principal); + if (options.wantComponents && allowComponents && + !nsXPCComponents::AttachComponentsObject(cx, GetObjectScope(sandbox))) + return NS_ERROR_XPC_UNEXPECTED; - if (!XPCNativeWrapper::AttachNewConstructorObject(cx, sandbox)) - return NS_ERROR_XPC_UNEXPECTED; + if (!XPCNativeWrapper::AttachNewConstructorObject(cx, sandbox)) + return NS_ERROR_XPC_UNEXPECTED; if (!JS_DefineFunctions(cx, sandbox, SandboxFunctions)) return NS_ERROR_XPC_UNEXPECTED; @@ -1037,7 +1037,7 @@ nsXPCComponents_utils_Sandbox::Construct(nsIXPConnectWrappedNative *wrapper, JSC * For sandbox constructor the first argument can be a URI string in which case * we use the related Codebase Principal for the sandbox. */ -nsresult +static nsresult GetPrincipalFromString(JSContext *cx, HandleString codebase, nsIPrincipal **principal) { MOZ_ASSERT(principal); @@ -1063,10 +1063,10 @@ GetPrincipalFromString(JSContext *cx, HandleString codebase, nsIPrincipal **prin } /* - * For sandbox constructor the first argument can be a principal object or + * For sandbox constructor the first argument can be a principal object or * a script object principal (Document, Window). */ -nsresult +static nsresult GetPrincipalOrSOP(JSContext *cx, HandleObject from, nsISupports **out) { MOZ_ASSERT(out); @@ -1095,7 +1095,7 @@ GetPrincipalOrSOP(JSContext *cx, HandleObject from, nsISupports **out) * The first parameter of the sandbox constructor might be an array of principals, either in string * format or actual objects (see GetPrincipalOrSOP) */ -nsresult +static nsresult GetExpandedPrincipal(JSContext *cx, HandleObject arrayObj, nsIExpandedPrincipal **out) { MOZ_ASSERT(out); @@ -1159,38 +1159,39 @@ GetExpandedPrincipal(JSContext *cx, HandleObject arrayObj, nsIExpandedPrincipal /* * Helper that tries to get a property form the options object. */ -nsresult +static nsresult GetPropFromOptions(JSContext *cx, HandleObject from, const char *name, MutableHandleValue prop, bool *found) { - if (!JS_HasProperty(cx, from, name, found)) - return NS_ERROR_INVALID_ARG; + MOZ_ASSERT(found); + bool ok = JS_HasProperty(cx, from, name, found); + NS_ENSURE_TRUE(ok, NS_ERROR_INVALID_ARG); - if (*found && !JS_GetProperty(cx, from, name, prop)) - return NS_ERROR_INVALID_ARG; + if (!*found) + return NS_OK; + ok = JS_GetProperty(cx, from, name, prop); + NS_ENSURE_TRUE(ok, NS_ERROR_INVALID_ARG); return NS_OK; } /* * Helper that tries to get a boolean property form the options object. */ -nsresult +static nsresult GetBoolPropFromOptions(JSContext *cx, HandleObject from, const char *name, bool *prop) { MOZ_ASSERT(prop); - RootedValue value(cx); bool found; - if (NS_FAILED(GetPropFromOptions(cx, from, name, &value, &found))) - return NS_ERROR_INVALID_ARG; + nsresult rv = GetPropFromOptions(cx, from, name, &value, &found); + NS_ENSURE_SUCCESS(rv, rv); if (!found) return NS_OK; - if (!value.isBoolean()) - return NS_ERROR_INVALID_ARG; + NS_ENSURE_TRUE(value.isBoolean(), NS_ERROR_INVALID_ARG); *prop = value.toBoolean(); return NS_OK; @@ -1199,24 +1200,22 @@ GetBoolPropFromOptions(JSContext *cx, HandleObject from, const char *name, bool /* * Helper that tries to get an object property form the options object. */ -nsresult +static nsresult GetObjPropFromOptions(JSContext *cx, HandleObject from, const char *name, JSObject **prop) { MOZ_ASSERT(prop); RootedValue value(cx); bool found; - if (NS_FAILED(GetPropFromOptions(cx, from, name, &value, &found))) - return NS_ERROR_INVALID_ARG; + nsresult rv = GetPropFromOptions(cx, from, name, &value, &found); + NS_ENSURE_SUCCESS(rv, rv); if (!found) { *prop = NULL; return NS_OK; } - if (!value.isObject()) - return NS_ERROR_INVALID_ARG; - + NS_ENSURE_TRUE(value.isObject(), NS_ERROR_INVALID_ARG); *prop = &value.toObject(); return NS_OK; } @@ -1224,7 +1223,7 @@ GetObjPropFromOptions(JSContext *cx, HandleObject from, const char *name, JSObje /* * Helper that tries to get a string property form the options object. */ -nsresult +static nsresult GetStringPropFromOptions(JSContext *cx, HandleObject from, const char *name, nsCString &prop) { RootedValue value(cx); @@ -1246,7 +1245,7 @@ GetStringPropFromOptions(JSContext *cx, HandleObject from, const char *name, nsC /* * Helper that parsing the sandbox options object (from) and sets the fields of the incoming options struct (options). */ -nsresult +static nsresult ParseOptionsObject(JSContext *cx, jsval from, SandboxOptions &options) { NS_ENSURE_TRUE(from.isObject(), NS_ERROR_INVALID_ARG); diff --git a/js/xpconnect/src/XPCWrappedNativeScope.cpp b/js/xpconnect/src/XPCWrappedNativeScope.cpp index 198274f7580..1cf3055a6b6 100644 --- a/js/xpconnect/src/XPCWrappedNativeScope.cpp +++ b/js/xpconnect/src/XPCWrappedNativeScope.cpp @@ -242,7 +242,6 @@ XPCWrappedNativeScope::EnsureXBLScope(JSContext *cx) SandboxOptions options(cx); options.wantXrays = true; options.wantComponents = true; - options.wantXHRConstructor = false; options.proto = global; options.sameZoneAs = global; From 1cb4e55c927b20d0833ce90c7b631a12acfab372 Mon Sep 17 00:00:00 2001 From: Gabor Krizsanits Date: Wed, 4 Sep 2013 12:16:04 +0200 Subject: [PATCH 057/171] Bug 892203 - DOMConstructors for SandboxOptions. r=bholley --- .../chrome/test_sandbox_eventhandler.xul | 2 +- js/xpconnect/src/Sandbox.cpp | 68 ++++++++++++++++--- js/xpconnect/src/xpcprivate.h | 10 ++- .../tests/unit/test_allowedDomainsXHR.js | 2 +- js/xpconnect/tests/unit/test_bug868675.js | 2 +- js/xpconnect/tests/unit/test_bug872772.js | 2 +- .../tests/unit/test_exportFunction.js | 4 +- 7 files changed, 74 insertions(+), 16 deletions(-) diff --git a/dom/tests/mochitest/chrome/test_sandbox_eventhandler.xul b/dom/tests/mochitest/chrome/test_sandbox_eventhandler.xul index 9218094bf0d..24d0c6a343a 100644 --- a/dom/tests/mochitest/chrome/test_sandbox_eventhandler.xul +++ b/dom/tests/mochitest/chrome/test_sandbox_eventhandler.xul @@ -20,7 +20,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=817284 /** Test for Bug 817284 **/ var cu = Components.utils; - var sb = cu.Sandbox("http://example.com", {wantXHRConstructor: true}); + var sb = cu.Sandbox("http://example.com", { wantDOMConstructors: ["XMLHttpRequest"] }); // Test event handler calls var xhr = cu.evalInSandbox( diff --git a/js/xpconnect/src/Sandbox.cpp b/js/xpconnect/src/Sandbox.cpp index 8f88f8159ed..534d5dcd9b8 100644 --- a/js/xpconnect/src/Sandbox.cpp +++ b/js/xpconnect/src/Sandbox.cpp @@ -870,6 +870,41 @@ xpc::SandboxProxyHandler::iterate(JSContext *cx, JS::Handle proxy, return BaseProxyHandler::iterate(cx, proxy, flags, vp); } +bool +xpc::SandboxOptions::DOMConstructors::Parse(JSContext* cx, JS::HandleObject obj) +{ + NS_ENSURE_TRUE(JS_IsArrayObject(cx, obj), false); + + uint32_t length; + bool ok = JS_GetArrayLength(cx, obj, &length); + NS_ENSURE_TRUE(ok, false); + for (uint32_t i = 0; i < length; i++) { + RootedValue nameValue(cx); + ok = JS_GetElement(cx, obj, i, &nameValue); + NS_ENSURE_TRUE(ok, false); + NS_ENSURE_TRUE(nameValue.isString(), false); + char *name = JS_EncodeString(cx, nameValue.toString()); + NS_ENSURE_TRUE(name, false); + if (!strcmp(name, "XMLHttpRequest")) { + XMLHttpRequest = true; + } else { + // Reporting error, if one of the DOM constructor names is unknown. + return false; + } + } + return true; +} + +bool +xpc::SandboxOptions::DOMConstructors::Define(JSContext* cx, JS::HandleObject obj) +{ + if (XMLHttpRequest && + !JS_DefineFunction(cx, obj, "XMLHttpRequest", CreateXMLHttpRequest, 0, JSFUN_CONSTRUCTOR)) + return false; + + return true; +} + nsresult xpc::CreateSandboxObject(JSContext *cx, jsval *vp, nsISupports *prinOrSop, SandboxOptions& options) { @@ -972,15 +1007,13 @@ xpc::CreateSandboxObject(JSContext *cx, jsval *vp, nsISupports *prinOrSop, Sandb if (!JS_DefineFunctions(cx, sandbox, SandboxFunctions)) return NS_ERROR_XPC_UNEXPECTED; - if (options.wantXHRConstructor && - !JS_DefineFunction(cx, sandbox, "XMLHttpRequest", CreateXMLHttpRequest, 0, JSFUN_CONSTRUCTOR)) - return NS_ERROR_XPC_UNEXPECTED; - if (options.wantExportHelpers && (!JS_DefineFunction(cx, sandbox, "exportFunction", ExportFunction, 3, 0) || !JS_DefineFunction(cx, sandbox, "evalInWindow", EvalInWindow, 2, 0))) return NS_ERROR_XPC_UNEXPECTED; + if (!options.DOMConstructors.Define(cx, sandbox)) + return NS_ERROR_XPC_UNEXPECTED; } if (vp) { @@ -1242,6 +1275,26 @@ GetStringPropFromOptions(JSContext *cx, HandleObject from, const char *name, nsC return NS_OK; } +/* + * Helper that tries to get a list of DOM constructors from the options object. + */ +static nsresult +GetDOMConstructorsFromOptions(JSContext *cx, HandleObject from, SandboxOptions& options) +{ + RootedValue value(cx); + bool found; + nsresult rv = GetPropFromOptions(cx, from, "wantDOMConstructors", &value, &found); + NS_ENSURE_SUCCESS(rv, rv); + if (!found) + return NS_OK; + + NS_ENSURE_TRUE(value.isObject(), NS_ERROR_INVALID_ARG); + RootedObject ctors(cx, &value.toObject()); + bool ok = options.DOMConstructors.Parse(cx, ctors); + NS_ENSURE_TRUE(ok, NS_ERROR_INVALID_ARG); + return NS_OK; +} + /* * Helper that parsing the sandbox options object (from) and sets the fields of the incoming options struct (options). */ @@ -1262,10 +1315,6 @@ ParseOptionsObject(JSContext *cx, jsval from, SandboxOptions &options) "wantComponents", &options.wantComponents); NS_ENSURE_SUCCESS(rv, rv); - rv = GetBoolPropFromOptions(cx, optionsObject, - "wantXHRConstructor", &options.wantXHRConstructor); - NS_ENSURE_SUCCESS(rv, rv); - rv = GetBoolPropFromOptions(cx, optionsObject, "wantExportHelpers", &options.wantExportHelpers); NS_ENSURE_SUCCESS(rv, rv); @@ -1278,6 +1327,9 @@ ParseOptionsObject(JSContext *cx, jsval from, SandboxOptions &options) "sameZoneAs", options.sameZoneAs.address()); NS_ENSURE_SUCCESS(rv, rv); + rv = GetDOMConstructorsFromOptions(cx, optionsObject, options); + NS_ENSURE_SUCCESS(rv, rv); + return NS_OK; } diff --git a/js/xpconnect/src/xpcprivate.h b/js/xpconnect/src/xpcprivate.h index 082ed215da4..b51698a9635 100644 --- a/js/xpconnect/src/xpcprivate.h +++ b/js/xpconnect/src/xpcprivate.h @@ -3699,10 +3699,16 @@ bool IsSandbox(JSObject *obj); struct SandboxOptions { + struct DOMConstructors { + DOMConstructors() { mozilla::PodZero(this); } + bool Parse(JSContext* cx, JS::HandleObject obj); + bool Define(JSContext* cx, JS::HandleObject obj); + bool XMLHttpRequest; + }; + SandboxOptions(JSContext *cx) : wantXrays(true) , wantComponents(true) - , wantXHRConstructor(false) , wantExportHelpers(false) , proto(xpc_GetSafeJSContext()) , sameZoneAs(xpc_GetSafeJSContext()) @@ -3710,11 +3716,11 @@ struct SandboxOptions { bool wantXrays; bool wantComponents; - bool wantXHRConstructor; bool wantExportHelpers; JS::RootedObject proto; nsCString sandboxName; JS::RootedObject sameZoneAs; + DOMConstructors DOMConstructors; }; JSObject * diff --git a/js/xpconnect/tests/unit/test_allowedDomainsXHR.js b/js/xpconnect/tests/unit/test_allowedDomainsXHR.js index 183484737ab..00788f2e1ce 100644 --- a/js/xpconnect/tests/unit/test_allowedDomainsXHR.js +++ b/js/xpconnect/tests/unit/test_allowedDomainsXHR.js @@ -10,7 +10,7 @@ var httpbody = "0123456789"; var sb = cu.Sandbox(["http://www.example.com", "http://localhost:4444/simple"], - {wantXHRConstructor: true}); + { wantDOMConstructors: ["XMLHttpRequest"] }); function createXHR(loc, async) { diff --git a/js/xpconnect/tests/unit/test_bug868675.js b/js/xpconnect/tests/unit/test_bug868675.js index 951356efb04..266cd037995 100644 --- a/js/xpconnect/tests/unit/test_bug868675.js +++ b/js/xpconnect/tests/unit/test_bug868675.js @@ -11,7 +11,7 @@ function run_test() { // Make sure that we can waive on a non-Xrayable object, and that we preserve // transitive waiving behavior. - var sb = new Cu.Sandbox('http://www.example.com', {wantXHRConstructor: true}); + var sb = new Cu.Sandbox('http://www.example.com', { wantDOMConstructors: ["XMLHttpRequest"] }); Cu.evalInSandbox('this.xhr = new XMLHttpRequest();', sb); Cu.evalInSandbox('this.jsobj = {mynative: xhr};', sb); do_check_true(!Cu.isXrayWrapper(XPCNativeWrapper.unwrap(sb.xhr))); diff --git a/js/xpconnect/tests/unit/test_bug872772.js b/js/xpconnect/tests/unit/test_bug872772.js index c471ae367ec..1435c4a04b4 100644 --- a/js/xpconnect/tests/unit/test_bug872772.js +++ b/js/xpconnect/tests/unit/test_bug872772.js @@ -5,7 +5,7 @@ function run_test() { // NB: We use an nsEP here so that we can have access to Components, but still // have Xray behavior from this scope. var contentSB = new Cu.Sandbox(['http://www.google.com'], - {wantXHRConstructor: true, wantComponents: true}); + { wantDOMConstructors: ["XMLHttpRequest"], wantComponents: true }); // Make an XHR in the content sandbox. Cu.evalInSandbox('xhr = new XMLHttpRequest();', contentSB); diff --git a/js/xpconnect/tests/unit/test_exportFunction.js b/js/xpconnect/tests/unit/test_exportFunction.js index 4828245c8b1..2aa508f26a7 100644 --- a/js/xpconnect/tests/unit/test_exportFunction.js +++ b/js/xpconnect/tests/unit/test_exportFunction.js @@ -1,8 +1,8 @@ function run_test() { var Cu = Components.utils; var epsb = new Cu.Sandbox(["http://example.com", "http://example.org"], { wantExportHelpers: true }); - subsb = new Cu.Sandbox("http://example.com", { wantXHRConstructor: true }); - subsb2 = new Cu.Sandbox("http://example.com", { wantXHRConstructor: true }); + subsb = new Cu.Sandbox("http://example.com", { wantDOMConstructors: ["XMLHttpRequest"] }); + subsb2 = new Cu.Sandbox("http://example.com", { wantDOMConstructors: ["XMLHttpRequest"] }); xorigsb = new Cu.Sandbox("http://test.com"); epsb.subsb = subsb; From b0a8de003d5f118acb2874210e32a580cc5d01f4 Mon Sep 17 00:00:00 2001 From: Gabor Krizsanits Date: Wed, 4 Sep 2013 12:18:28 +0200 Subject: [PATCH 058/171] Bug 892203 - TextEncoder and TextDecoder for sandbox. r=bholley --- js/xpconnect/src/Sandbox.cpp | 14 ++++++++++++++ js/xpconnect/src/xpcprivate.h | 2 ++ js/xpconnect/tests/unit/test_textDecoder.js | 9 +++++++++ js/xpconnect/tests/unit/xpcshell.ini | 1 + 4 files changed, 26 insertions(+) create mode 100644 js/xpconnect/tests/unit/test_textDecoder.js diff --git a/js/xpconnect/src/Sandbox.cpp b/js/xpconnect/src/Sandbox.cpp index 534d5dcd9b8..9f820c331e4 100644 --- a/js/xpconnect/src/Sandbox.cpp +++ b/js/xpconnect/src/Sandbox.cpp @@ -34,6 +34,8 @@ #include "XPCWrapper.h" #include "XrayWrapper.h" #include "mozilla/dom/BindingUtils.h" +#include "mozilla/dom/TextDecoderBinding.h" +#include "mozilla/dom/TextEncoderBinding.h" using namespace mozilla; using namespace JS; @@ -887,6 +889,10 @@ xpc::SandboxOptions::DOMConstructors::Parse(JSContext* cx, JS::HandleObject obj) NS_ENSURE_TRUE(name, false); if (!strcmp(name, "XMLHttpRequest")) { XMLHttpRequest = true; + } else if (!strcmp(name, "TextEncoder")) { + TextEncoder = true; + } else if (!strcmp(name, "TextDecoder")) { + TextDecoder = true; } else { // Reporting error, if one of the DOM constructor names is unknown. return false; @@ -902,6 +908,14 @@ xpc::SandboxOptions::DOMConstructors::Define(JSContext* cx, JS::HandleObject obj !JS_DefineFunction(cx, obj, "XMLHttpRequest", CreateXMLHttpRequest, 0, JSFUN_CONSTRUCTOR)) return false; + if (TextEncoder && + !dom::TextEncoderBinding::GetConstructorObject(cx, obj)) + return false; + + if (TextDecoder && + !dom::TextDecoderBinding::GetConstructorObject(cx, obj)) + return false; + return true; } diff --git a/js/xpconnect/src/xpcprivate.h b/js/xpconnect/src/xpcprivate.h index b51698a9635..7aa790c63d5 100644 --- a/js/xpconnect/src/xpcprivate.h +++ b/js/xpconnect/src/xpcprivate.h @@ -3704,6 +3704,8 @@ struct SandboxOptions { bool Parse(JSContext* cx, JS::HandleObject obj); bool Define(JSContext* cx, JS::HandleObject obj); bool XMLHttpRequest; + bool TextDecoder; + bool TextEncoder; }; SandboxOptions(JSContext *cx) diff --git a/js/xpconnect/tests/unit/test_textDecoder.js b/js/xpconnect/tests/unit/test_textDecoder.js new file mode 100644 index 00000000000..3607b9cbcf2 --- /dev/null +++ b/js/xpconnect/tests/unit/test_textDecoder.js @@ -0,0 +1,9 @@ +function run_test() { + var Cu = Components.utils; + sb = new Cu.Sandbox('http://www.example.com', + { wantDOMConstructors: ["TextDecoder", "TextEncoder"] }); + sb.do_check_eq = do_check_eq; + Cu.evalInSandbox('do_check_eq(new TextDecoder().encoding, "utf-8");' + + 'do_check_eq(new TextEncoder().encoding, "utf-8");', + sb); +} diff --git a/js/xpconnect/tests/unit/xpcshell.ini b/js/xpconnect/tests/unit/xpcshell.ini index bc8b45637af..285cf3c1ea7 100644 --- a/js/xpconnect/tests/unit/xpcshell.ini +++ b/js/xpconnect/tests/unit/xpcshell.ini @@ -52,6 +52,7 @@ fail-if = os == "android" [test_allowedDomainsXHR.js] [test_nuke_sandbox.js] [test_exportFunction.js] +[test_textDecoder.js] [test_watchdog_enable.js] head = head_watchdog.js [test_watchdog_disable.js] From 3dffe95932ffb4d062728ce9885da55a4b396086 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Wed, 4 Sep 2013 23:13:06 +1200 Subject: [PATCH 059/171] Bug 904926. Remove unnecessary lock. r=cpearce --HG-- extra : rebase_source : 0088907b65ff3ce2e1f15b2bb1b5e0cdb7126f24 --- content/media/MediaDecoder.cpp | 6 ++---- content/media/MediaDecoder.h | 18 ++++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/content/media/MediaDecoder.cpp b/content/media/MediaDecoder.cpp index 11457dcd96e..c1ff95aa917 100644 --- a/content/media/MediaDecoder.cpp +++ b/content/media/MediaDecoder.cpp @@ -362,7 +362,6 @@ MediaDecoder::MediaDecoder() : mInitialVolume(0.0), mInitialPlaybackRate(1.0), mInitialPreservesPitch(true), - mRequestedSeekTime(-1.0), mDuration(-1), mTransportSeekable(true), mMediaSeekable(true), @@ -372,6 +371,7 @@ MediaDecoder::MediaDecoder() : mIsExitingDormant(false), mPlayState(PLAY_STATE_PAUSED), mNextState(PLAY_STATE_PAUSED), + mRequestedSeekTime(-1.0), mCalledResourceLoaded(false), mIgnoreProgressData(false), mInfiniteStream(false), @@ -708,8 +708,7 @@ bool MediaDecoder::IsDataCachedToEndOfResource() { NS_ASSERTION(!mShuttingDown, "Don't call during shutdown!"); - GetReentrantMonitor().AssertCurrentThreadIn(); - + ReentrantMonitorAutoEnter mon(GetReentrantMonitor()); return (mResource && mResource->IsDataCachedToEndOfResource(mDecoderPosition)); } @@ -755,7 +754,6 @@ void MediaDecoder::MetadataLoaded(int aChannels, int aRate, bool aHasAudio, bool // Only inform the element of FirstFrameLoaded if not doing a load() in order // to fulfill a seek, otherwise we'll get multiple loadedfirstframe events. - ReentrantMonitorAutoEnter mon(GetReentrantMonitor()); bool notifyResourceIsLoaded = !mCalledResourceLoaded && IsDataCachedToEndOfResource(); if (mOwner) { diff --git a/content/media/MediaDecoder.h b/content/media/MediaDecoder.h index 78ea87dcfb3..65d62454c4a 100644 --- a/content/media/MediaDecoder.h +++ b/content/media/MediaDecoder.h @@ -692,7 +692,7 @@ public: // Call on the main thread only. void FirstFrameLoaded(); - // Returns true if the resource has been loaded. Must be in monitor. + // Returns true if the resource has been loaded. Acquires the monitor. // Call from any thread. virtual bool IsDataCachedToEndOfResource(); @@ -946,13 +946,6 @@ public: double mInitialPlaybackRate; bool mInitialPreservesPitch; - // Position to seek to when the seek notification is received by the - // decode thread. Written by the main thread and read via the - // decode thread. Synchronised using mReentrantMonitor. If the - // value is negative then no seek has been requested. When a seek is - // started this is reset to negative. - double mRequestedSeekTime; - // Duration of the media resource. Set to -1 if unknown. // Set when the metadata is loaded. Accessed on the main thread // only. @@ -1055,6 +1048,15 @@ public: // This can only be PLAY_STATE_PAUSED or PLAY_STATE_PLAYING. PlayState mNextState; + // Position to seek to when the seek notification is received by the + // decode thread. + // This can only be changed on the main thread while holding the decoder + // monitor. Thus, it can be safely read while holding the decoder monitor + // OR on the main thread. + // If the value is negative then no seek has been requested. When a seek is + // started this is reset to negative. + double mRequestedSeekTime; + // True when we have fully loaded the resource and reported that // to the element (i.e. reached NETWORK_LOADED state). // Accessed on the main thread only. From 0991ab95c28b56418ca8f38821cce7e683199b3b Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Wed, 4 Sep 2013 23:13:11 +1200 Subject: [PATCH 060/171] Bug 909157. Invalidate rendering observers when an image changes. r=mattwoodrow --HG-- extra : rebase_source : 04b127fde9a9e07e50c6196f53a1eea3c8f04db6 --- .../image-element/invalidate-1-ref.html | 7 +++++++ layout/reftests/image-element/invalidate-1.html | 7 +++++++ layout/reftests/image-element/reftest.list | 1 + .../repeatable-diagonal-gradient.png | Bin 0 -> 14520 bytes layout/style/ImageLoader.cpp | 8 ++++++++ 5 files changed, 23 insertions(+) create mode 100644 layout/reftests/image-element/invalidate-1-ref.html create mode 100644 layout/reftests/image-element/invalidate-1.html create mode 100644 layout/reftests/image-element/repeatable-diagonal-gradient.png diff --git a/layout/reftests/image-element/invalidate-1-ref.html b/layout/reftests/image-element/invalidate-1-ref.html new file mode 100644 index 00000000000..833c8461707 --- /dev/null +++ b/layout/reftests/image-element/invalidate-1-ref.html @@ -0,0 +1,7 @@ + + + +
+
+ + diff --git a/layout/reftests/image-element/invalidate-1.html b/layout/reftests/image-element/invalidate-1.html new file mode 100644 index 00000000000..bbd2c07851e --- /dev/null +++ b/layout/reftests/image-element/invalidate-1.html @@ -0,0 +1,7 @@ + + + +
+
+ + diff --git a/layout/reftests/image-element/reftest.list b/layout/reftests/image-element/reftest.list index 1f95df0c90e..0b2ae3bc2a1 100644 --- a/layout/reftests/image-element/reftest.list +++ b/layout/reftests/image-element/reftest.list @@ -41,6 +41,7 @@ fuzzy(1,9674) random-if(!cocoaWidget) == gradient-html-06b.html gradient-html-06 == gradient-html-06d.html gradient-html-06e.html random-if(!cocoaWidget) fuzzy-if(azureQuartz,1,11367) == gradient-html-07a.html gradient-html-07b.html fuzzy(1,16900) == gradient-html-07c.html gradient-html-07d.html +HTTP == invalidate-1.html invalidate-1-ref.html == pattern-html-01.html pattern-html-01-ref.svg == pattern-html-02.html pattern-html-02-ref.svg == referenced-from-binding-01.html referenced-from-binding-01-ref.html diff --git a/layout/reftests/image-element/repeatable-diagonal-gradient.png b/layout/reftests/image-element/repeatable-diagonal-gradient.png new file mode 100644 index 0000000000000000000000000000000000000000..d114e100d322161c443aabffd7bd428e5c88d3ad GIT binary patch literal 14520 zcmWlgXE+;P8^$S$zuBtN8qq~tyIM1-YOAVfYg2m{v4a?~N3FJ6d$hI1sFm2URqYX* zSZ%BbjfjXOulLhAAJ28JbDncQ_x(Ewul2Mz{=5Dk9UUEq_KT-)>FDUsr}T6z7tV(% zZgtu7LCEi!sh_5&hleA`k51Fa(bmt=K_tM{&qc)0#Zg2{TlY22;SPw7PJ~YTsfJ~m zo*E)eDX}1R*6pe~AONa;sDnOiu|iS@(XL17>=q8lrLnf=!PKe@Rv;hifjB>UK z4LiYOQ1vII;J?cN5*hGsttPdAMnakpS)tTX0+qHdjzh{)=qqZ>X_MG7q?H*>i*^P? zphJj!(YaP z-3;=5wH2(z8`ZAV9j>5wrm}51=Z!Jz`xP`i1MN(8cRvjswuZp;*3bfa$kmG~YsX)_ zMyZw743vF@=LF#~VPHA92Jn0FO$3ZKR^L?h&!PAx6_dJCGfF5ch&&d)WBB*SHhZFUY>wB8=KsMLF(WTVBR7i z8-@IU0}aA#LV=$O5Vn(}S_Sm=f%VR_fh6sLysvav8f)tNaQ9wy~C*e$%$0U zrx$iTSl6!sfJa@4-*G(kIGVft6ZuG^h@U%rBC{2(g^d1(hi^ke{%N>94!_AjzwUua ztHW!X$z9-A=?MX;W7}XK&Cpy>nqKH`vAZ8Eh*qKBIrJRJ`URV+B7lPW=vaB6X?S(- zvq*7~yFYZc_8*=YP*~Nnny#Km22Sj7Is5bYV|aAgrr{3@)U6+NF2j>r1EFLkz%ux7 zr9CgxxA4?@p}TsUzWx-Z>-4*3*_vVYHPz)9AbC(zD%`fq8&{|%NR8Qv+x<3{?-{Vz=;a(t zwk*v~Rx4exLBIFse;WD%=yxop*}-^W@`wVs``Z6lpU(a4jKcy|g9t+WseP}=VxuiDo8bN9;mf8=82yFXHw#s|oZ6>(;-$iRi0b!bY8MDN(eJ{69>b{FiCIaiZFM?+U z{-vS!=pSC@XWDnJTapTzv?OQ;j1zgXjh8Hgyk{Argt{Bq7MAk;ekgPVn_}l{aCKYq z)cTD`=(fianA&W()-9RGPGJL--5?>9$l@uI z%Z1hZD<4{dVi&95vu7`31->tJtI<LNkpw|3e+@?1YoW((&)sH_aSw9u^UEQS|oJ zZtI#F+V$*G>dK6toeSv_*6fBV@ULbzXO zUFq8Xqn1nBdytI=9N((e%;(2xm?UT-fc*VHNo~JNGCk)xkm+xIZX+6mF+lRa<=MlN zc>s|`8b09mE|Hbw*3 z>d{qU9t8Z|74&~|D)s_Ss*{PN8}fSx6aU`6=>Ue@)KJ$)q(#O_*EdBBzD zQib4yyN|kBe?MR5uQ6ZqQ|p0XV)y*2N-;#0p)T-_STGhY5IdQsxydelyV z53_{7YM~{Ah45&|Vcv@EiHfeQVs0XF+J`7s(Ubx0Jas4#$4g(*onx&4mfOYj{6Qp~m;# znXjBvU5^f%+|v7N#AJzPAU>TM(p4w#fD9*= z)=yb$ElNG{tuoEW1&2T0NgpZ=EvlEii1PgOu=v@d?;SX$jAlsqx|iQ2eg0Rd4>ao8 z8LW0|Epv>?id}1-W%^!nUhTh&jupq?Go2aU90^1+w!q?ZT# z-Hjgl`~D~OdaRj^~^wBPm`{T<>s_nx$LE_+GDoi;tq-8 zoe@E^xBB0p(N@O^Y+ZQ2CR??vC!Mz5z#H38CAPW^kJ*Pw*Mm{xkE=Mjs_UN&DVJ#a zZH&%Y`sNnTSWcqlRPa<-z=NdhKP4lo%F!V#DWxwYxIaJBAU6T^;|^NGx1zDjmp+AI zrk;=!pF=dndfw<5iQWnnHlZ<9?p3LJ|ENcv-ZmzrT1b7|-pES22p-(hbKbc_Z8r*z z%HufZA3e>l`S$%!@l4~4AXb68RgG{|#Do#>o=}USb;3Id9h;enjW1f__s&3^A4C{O)iaBstQ`H?k#AvMq5jo1kgM$U4*Hdxld?r z^S-O&3uiMZUh3^A;LG+N^H-qMD4eUuEH?h^C?=I#viKOC_!-8w@;JLvXHj(3c0 z+~UwR0qt)TdDsXAy>tpdA$Z%jeE_R#JPN#7M*QTpY^^xzN$iiFI%#J-E2}(O!VBn@T4J zyr?2Ike9tgW7IgjHkwP{73*4u&Ti9uMpmYA4U?Q7=g z`)v;=Jv>YZ;!HgL^y)A$iO9n`6u7r1RxQ6&_mGH(Xy%j|g^J*3YCjMou$ z&hLZx8|FqCOYeAj3l~_s5N>~~DvS#3pJ`B6;SLO#Wedt%$0?Ojw^lwRXoQcUNsKGB z`cqamVP^!3QLvwURRjxz-J(j93v0!Kdg7YJh)+~ib%i7#t$VNBlqo|l^(^Gwl4$Oi zYQ;Z+qB2;$5>ktN7H9OvwHj5e0t9Vbqvc&4zMT3?3#{YrueO1%pw9eax^AhqhUPLs z^WeLMw0IQyF9f&k$qGF@iEA#Xf_t0ZGpgnr4%nD@dO*GBuh$x??k&Z$7XTK>H$;9N zGkRl{ssdo+T&SRKAB6aM>8|a3J4~E-d1jMAo9D~SN;dN43YCGIf(#vJG3vNCx5l5Mnp% z+_slGvhQ_7HdL5cp9E&30HPP&tCaRf!qMyk7BWqb016F&m|>ixq89?#&#-MDbT8N`~zcPpR}=+Dh&Gbr^3rt9yZW4{0xYInW0Ux&S|SkD+@ogWAIr#DwcWz6SXnzdJGy+dcM z)0x-%*I#G;7XrO1zXX{}&iVV|rtj)t8j5XX`j+0?&qHsx#Y zx1`zC3wr+oN$-8=;3t%Id#$`t;2pKsGD7mh@%VJMhTKX7?t!b@w6P_yeLWnraY}R+ znudHGpR*w7Gmm)Ot0@w%_HR$0!FTspg+XHSA59GvQidNDIcKHi*{HYF}94-~8N* z9=V6raGiJ2Ltmho72qF#R&R(N4o|}@&f*>j4F0J5jlC?=d2mWa^gvL(`__gm8l+Z; z<1Ir1_Y#{4(oq%tGVpr^atJgLCP)Qgmimm3h(kxDm31OwT0wU|@i_`KkrN#l`tCEM z_xF0_kA0tw-xEWv$3UUp-%u2hHo!9xrZzs&+t@_6P`y`Hv9xoz(`X5LzDDQ5hwr+x zDAjE?@|(9?TWaAK_AiJlBM#JX%LHOAqRQ*CEn}ogdnxs6U^B+1Z~t7e#OYxH*WXw75}^}@pLm_ z1{2XZ>oN$u`DZ_AEw}$6Q9muXkk#oGb7ohmN77i`fJWiq&8q7dnXo$S5RNW zY(SP)2$Z($#iVqbH}Yx&X@S>PgunOLD(8xHM)b)}$mBjMC?(Vfb$0=aj8!%RmSZzB zUoi{M+g)#o?ZLBllBb$X&o7!pN^Ib@)D6p;#0!ic+z_Uqdn#RDEFvZK;}UAER_9L* zt#Ehdt2WOR`^i1-lxtHOsjj!Dbt+jd;&EJfG$DAhHhdvXYS(X}?-g4;(Jy{^2RY)t zdF4&PpY+RoW`FbNh(1#Z#r0C@t!U3bMrkr!syCACjao+`S;JRE^~lu98b9IL1p*~{ zRp!vXCG@d%d`@^(xqCWeXUK)%W)`iqs?oSiVo6b3h+0a-r7@eLS`W70A)440FbKQ*L1;E2#+RxfCQta+oMLR<@7)y#Rx|_ zKw(Sh+`+EZ+=M1jjOQ?Vydb5{7Fe*?<`J)}WZU!G5?2{VnQ!c@AN5h5Bbd*Cbz;fv z>GLeEZ0QAuwQ=<+Vx}sg>LG65Q2>O3k6-)HG+Fc}g$sapt?9lOQNP@QzDah%M5^vr zKqEOCWw2TBro%4xzecSKf@G3Qwx-PMJzu>86+ncI)bk|YX-UX{+yT{dXn+TjeFy8S z{;+Gn3RI93d+8Ix~O+a+MpMJDeQ ztMUQ`8k_wYkPF>iA)ufexYNM*_tTl4-pMrMLUclas@lVI$O^#VRK;hRHGIV;B- z9rx8`@jq#bBQ=r2R`ytZ>|?e*BD{%P^krF$N^KVC`1u;%T52wv<9D&$!b(eVswZuGct zNRTOAF@ss0tOe$xKuV2bFI!zu*V5M~K2%*iqlN@A+08FQiyC29e~lC=gCE=$*Gb%- z+lDZ;s3PnvO9sxZB4OD|%g(MN#To^#`$Ww}DNs;hUr0%{>O~t02OL`gQ}4=S=GDpG zbcZyzD|zzBw~B@d78&7tQjQ`6P=Ly@Kk(El@qRPNvz)ob64OheiEJNC>jJ>X)}!LM zt;Z{H%PIx&E9%~NiV9Hq(vIZZJ{aF9F;H!jsYuiVXME|j+8!lu)4IpH1`^3qr*=n*7)>OlPfXWfLK@ML0q zsW=eyLK^V_J@l`I?ebdWGJW{cFJrvu>=O`6&nSmhrq&i%yEPB~v{Ws>S-6nx;o4e37$wL|Meu)#@jZYZ zQ)u%?e%u`e-R*6=WKH;?LU1_e)JFZN+}TERDRZZ%f}krJt6Z z$YV~+qu2v*G|~#bNLY<4WGb*Lpsw3$C3)MXL%B2(4(zN}u)0EY(}w;8a@H*nVBLoi zaw(;pV!YN=dZfDBeRTvp7N-25>lt7!=7!lDllrQW^g*ay+XO1mE9hy+lDB%b_)TW9E{gAaG56d*eEE|W zdl;4!5U9r2AD)Vmqz78%))&Am;+JgomoKnetf-IC0e}5Smw&hv-pDCXk>+9IHbZhD zh*39Z1iIh3>knfckHwsu@2nilmbs}^Q962r{L#`JD@()u4;uw1|6<4cj5QesPz8;T zViE%{w5cDgg9}fu^(f_e%o^DM8dG?Up?*)Q$*%mOK&93dm>co4?bFVIsb}p(QSq`cFWcS?lC&0u){8|>(}MQ;g*9} z?pFn2vnnjTzBXHq^a`3lcXVA(nJh=SfVm8cv$porX?y8z0g7rp0Zs{ce7y_9#J~cx8@oIXEBSJG7P_1H(N3?+N7JG1%oa1-%~PnVjUhm2d1+$iyWqmm71qyvNV>-N7 z@sKdvf7Ool7OP8aVEyOugnjIWNZdwuxv|svqyH(nP05lVb}oBTN}cmL8Cv0R6!e>W z!`sRN8%2DrC>>fsExGn*lv491Q_n3U7m_U+kTlu8i?JsWOAW(;74Fl3e61F;88!sV z#593UK1<1E<|%7kfsU4}3@QF1bLFj6D<}uukJA|Gphfr2ez=hu3M`GHAL{w`447bP z`=E8|Jkk@mL|nLgHRJwCDN`M|eeguxY?z_5>zx3vM%}GcrCusU0KPwe<7TVyXf|Qt z0rafg1T$s+n}&E}oA{?hHmqmDd5(DY0|UWDCJE_2aer_&-Lk)@e=NH|I5-aoeXpn& zIeYIJLSg9UVf&5njrqTCwj~2dU*a;%ODQ2u9XN^R7X}cn3aFcpQFB|6IVE>nCW2=s zz1pN`!kmn?Pqzp^I)!V6paYVrzW8b7fo(>o#>Bm=nQIXN?b$!G@+Rkra%$TlvFvgv zv#OZ7iR-pgWVk-u@&>c&4VMHbgVWgzy5rBuJvxyR1#Viiu(-UtD<8H(@hn%8P z^n(m2w+qA{GXSwWp88vrxJPV9x(xV;-K4Qmk<--BxD&4FKRZHOvd99@){8G-$Ja*Z zS&i$(qZ~E>;D^`h+Fi%O61af-PK4&`LzGeHb&g+t?zS&W#$=8K*#`WJBLeq>6l5fs z*8<<~RD(RzH;#$KH@5z2o{Xu3XKwv+i&DRK-siE8RY2`l0GA+ba%WoT@zNS!JwwXj zgCy+zXnW=U*Vf4w#CcWgP5i=RIxixv%VwXZDqccb$LT$JJFv6gi-B7{Jq8@?(Q^EB z8Z6szHU6Ddsm@+H*8Pd}D5Rjj&P(~lh|(xg(8%c2_m|3<{na~KpGTdQ4a3X+SaJ?YYMd!A5x_!>4vNkDqPHh`OHH=ZO|) z)U8)Qph?_>wGB6^EOga|fLP4;qWcNj@vqN~_ryDj3ur#b<+`;4uxoZz-~Ek0e7uMn zC4~7^{pPun6x+Kk-&k*-82DbETsFV=nj23zmDVdnhNvwO9%JO-66*P7)FW1F(Ckrk z3)9OB;7N;%x)L$iaZM@(%h@CbAsXN+YV*L~6J-yRaV_g%FK!GSR|hC9O1-5J=8=~S z_&Mj9T9waQa&B}_hyt_X#i*A*ZGYPMlm2}7-!AkY-$h^GdH3e!H@rs{cl+QN$iI{u zQIdn&+f0mJec#gj2P6J@bhvC27GAr(Iab?R;n$l~=sRy#8=F*Fhn1kQto{&tBnNVpb5B9Nr_o)z@ zSsiYv!@SXv9Z!wWCs35Z8vU3vcs$_etxW}n3o6`6)P>#4|9Q#+?6lpA-|9PUt&&Oc zgI>0=X<4TKwF_B_Nfd1V{7zDy0{6`r*_>)9?j}w6&ejWn9jv5dD<*!)VUIpA{&fV_ z{E?_Xw`oWIKK0GwWGu0))Vun*!3d>Jj5hzgtepBT7Yfas&?h(Xv^gq!=|bqfh0JyV zb;%_$wKR0hmDU_xMI7LW^6t3L`n0he9@z%>=QnsV2{hc}ts`h<8N$sbr zO4TXkp7~wtqYJTk#hv%rD)hJVv6m2=MaZwSt!vxdRF5rZK1w~y)FsOV7eLXev&kP| z^RGed0$9Gig-E5tiCura!U{MEg!fmCqb9b=kDTRp%I>p5tT-*V2bxrVKZA2tx9(Zu z?pB1Xg3;R{OTc~(vjZL!;6bjMJW7&pT>27H@2)@eCIYt35PwnjV_eY765Qp7tWIF~ z2>z1xQWev;G*d{eTiZGqum>sR!F}*BnZEMvXZuq88-Ia)BABaMSD*RDU$$#xd19$m zx#zXyq}{;9;tefJ&x|=Vc>A)o;@X<&qT@E?PqJ(ILXaNsJXfv}jjq2+;^bEawN2Jf z;K*xf5^Uy*ir!NUIG`GjHQc^$il7R7Ob;W7oqXT00bNsRURy@z-;vY^Ty>A1vIw_v z-FpfLFIIotZjemQiqG{n4i4^YEa`J~MtqzV8NX(o{B&uI`Sb|?C@=#Bit*i={3v;l z5Vs+H>-0{!elwcrIi>b|mU4PVJ)*R4Zp_&y1+NsoALbS*ls^{h6CooadNA0Xr|)K35WaT1)avuAl@2i;JpHvHT`i;kQp5~H zvKOVWKC+nvie?b%1KUwqnl0To7%DOg)`_bUTK( zWwEa$N{MT;#j6hgOeuc}cG$TLVpyBfY;U38*$Lp);W<0o?x0=p?v>d|RLb;?(_FK) z^i_WWVakFKm&QW#$Gp<7^J)!yKdhB0Fbe+mXZdE5TyD=MsTcW{!YUOFH|ys7o4#KA z`;epWMx!B?@1Pi(!x}JEQ6>G(P4$8kf}b68XM}qF4%&BK@*HLWE)&@ZkeTbVd)G!& z@S7<;6A_6XG1y8F(VPCYL*mB0aG{lZLaP+E*Lgd!o_l$eh>_$#@S=%*cN+V&_44z( z1-6Pj8Hvqil&XjJwqxsi| z*X>lYcA^{`5!X{u#j~Gv&4e8hTP(ZuTO+2ZeNcdTK!(1?a6;Xi%Jx4szf&f?6gFBcdolcw)tLJF`C1U=~5DswNX$aD8> znsSp*(HB6Wof=1l{B?5rKKsA4@b9Y9Re;G4l|OR7rT?Fw+R!YyL4c+(?0Z7>@Emy8 zdI$u|)U2~sOSRk=cpeXPzr7#hi^QF~i#l0h0MT^LGavnHu7HtA=q<3)VYfl}#q*Tx zYQKn;lgEn<4ZC}_fi1WBT+SVJyi!z*@R$%Y{^?cp2l~UB^IZCG=*AVCzUY)k&e9h_ z47iBP9dE83p4&Ug(ax}`LZy=O?Y}=i6IEfLTi2G!Wf~TGC8nv6`fCA_8>IZP9SLr% zKDO*pCo@D94P@#Euau@ahn4Td5!D^qQ*^~Nw=iioXiqz}cZb|_BRe-dOm+=6#u-+! z)Ov2KCR{Gau>$qZC-6Ul7k!g!vzECohK*mH9tu#AX)`dUJuF>uwQKL}3F@him;Uu| z_B*9_X=y8bBa1W5NJd22Uf|s0W3P*!!#c~C*!v87+YKK^Yj_;KBJem`DI)>-6i>O% zlXy3gOT0X(zfv+RW*kLAfF=dznCEa00c7~7bJRxjhf&Ohrg(?uX4yWwolus;=;yfI zxj~-atyMg}-^w$JCR*D{m$ap>Q@h<04l%L(+w_42Q;cxu=LQ^bH9Q}3XPzn`z0@Q!)5ilnbWG<+<{ z+RtH9sbYTZW`IbWOHb3A){DieG>#IAK|Y`0Wq-ftbCF05`5t4gtu|#CRFL8WN1U|~ z-Izmmj2Q{ra{^iYdFzI#C0cs;MP&&T%+4~^1#IQBmzBh8wybQ;0H=&w^W0nCwy0ic zDOhvnotxNnUu>)bxfXMO-WcpVlT>W}L$G1DN!19CDjrIvhwj;l-)$fABdzqECu2~LC2jY7iWfV?*Sq|>*!Ef*#z%JdK9NlA6(047 zFyvTI&sZDxu=EqBRiA!`ltYAvj3Fm?pQRa|HDp-$2P5E|o7V}lfOcX45xTmk-%rnN zQLr#2bUN2B$#>UuH`UU8ak$Y45c##<9z)tt&UT5_S*NIGA)2&6?s zk?yDp@-2tEJMn#DCzj^1H-2j0kAHhlpa+Rz&<8T_q*s<&+$Do7=*%c-Ob_*4XMxA< zOA-n&j#lY(}(QGv7A1Y@1ctvz5&u7-x*$;mErdHqFV^Er-Xj87aO@{=#3}T_D<@XS9=ZUamxp~{G>VNpa$26#9sWQ*C%LwH zqxU-VxRuivpZk2G9@MH6%)NUPEID#VwU({B|J)aT4kT6}*{YX&LYnkxwHY~`byd1s zl2`vNC;hBaF**TI6%jf)M^Df-_R>8;Y*9}*HY1{%(*tq>*5HYfwq3wYCsf#Xu4c2t zJ*WIx72!a0;+e$mw!sk8Xba>l}v;vpqn3Q>8R$)nGlXV9E8&!X{a z%cZY-TzRhWp@+_iDJgd2n$H)z8S}w1(pe(p>-U=+!%&8nwls+BR&p{Ma|K zfG(Hpd2PY7%^!?zt1x3kC8m8T_BMVvn_QbnGzoge#wbTJz%jUTw1SKixLV(%k#lf1 z{r0Mo`o^O)WoYOzk49k!PT2oJ?yKn@P`l=^v-XS|xi)nytd`1;=y=R!tCk^0hz#Ko z&r2^-cojuj+JTrLX03;PiwB)AVWK zaj!$GR|ez+F`s8BM7$XP=tPjBiIEis0xD}#m`sxG z$!dk~JYOr23RGxy?CF{Rk2b7Z(o=b(N`Bc#0j8SuDfA_?XE+fNZ?wC>YWrg@7vgVM zZlv|?v~(DKOW>P;20M)U``d#oeT%CBD-mfoh zi@+qSAMSo7cPEK#qds08yWir)M4aB126#EPELIP8+NOKi>b578)2bdz=m)fScc)A} zOUdG-f-&Etrw4bYmzHlkp?>F@Bzx^uELfIkUYWvP zTc6*VQbt^lCpC?>0}+H0a8aFXE6V6p*pqpi*Q+6B=yO!>WbgBgkjn?lm9h1sUeXLh1lj!j6vI zm1muk4_w8ipD@+~bN>uDTsxKBIx^xm4bwJXoDOjOE$T0IS?V>a+~({BA) zTaab?yU?|NzZzkHaQL)(E049Ejz2c=qMS<%6<)Bovc@>&HD%}Fj*r6F`%4?t&HwU$ zvkOtkWtT4B)X&-esW4+IoT3NT0S8>LRlB1DyV$KOY>9>-&vJv~Hf#g3_JvbRjPyzC z2(l%5;x=W+TF9EE$;@m{4`%ZaCCM6{Gk*Nyy+}i~f|?V!<1~MDgrr2|{AOkCB%&}L zXquJ0`N}~jU(@jx;$((@P=Uj4#&X0V@5y(NcTCRE;o(dF+QdL(9!mu z0!Te6Bo1U8vRI7Vog*Graz>#nW8C64wB?2B!OB_Wa{rkp1)lh^K(*HxCg`G=(n&H# zo_|(#{_Q4&AAbX+XOYkOI$^PH=`Hnh&tU^ZquU?-4`(eMbpdBUL&yTKt9RpP&CtnNb^%JGqa)f-e`%Wb|0?e$1^#RvOb9W(Bso zoV1CJ?C&b(uN_eqI&RPb_7j$*k^?_5nH|SFpVzs8^)E2Gf)Sx~9gMG%?9+Mgg#zFD%N*9fIK~=+)C6KfpALPY z%mXHyGsZ;nEC?#vkT$>)j9H4oj^(7I^kj z|Bo5kkO)uDm9t#B znd}3h?jFY$H%)^jL%upMjBw|^nqtw90(OUpg2B0=kiJG#`)w8%r7bdp;QKc!S6Lg_ z$fTkyyHNj>u$Y!&UB~RrIDo&DJF<1V@*@M2;P5gx z(xIx0euXRG>;NZ=hY-(p0vatR?r_EQ?DT^`sr&Q?z9y{oqA<5<>`D5m&=;u%Tx`cEqP03u~V zDNN{A{-6z&@vqfDi`C7ja4?+{8oJ^9NSV*#;Hjmg6&(iLCcJWt^PCd@hAg$F801sv zL8|JFdNzVZxEcoGm6DaYbA@f}+u)|Zw;6<77e?ObFdjX8!@I9)y?xSKpOp-y$@c^) z<&691NHsQFwy}AifD0J$1jwT|GZzl-779MeTpIUseP?cs`6fIDAHP|ZVX<){N zHoOf#Xz962cwFKD-Kp|xuU`RcjIwD04Z?~&?3eyA()VO-f`=DoOHjSj&d?cYqN=FO zPr>1?5Oasa7Iy%8j*0c4{C{N2 zjTr%rSI(H7k|}tLm0l!pmuw=r`trH2*J#*{KlNL-sdY<}2`9_{d~(7*^0-9M-y z2%SADX;ovAWv)0b+x{I=Y67@-bx88uvkGp<{Uv<<<1}tdtH(#Uq9m))PE9H(z+92E zGL&s-g0TtCYBx*1>3$;?FGCI+LT_~`OTIcjN>cR?T+` zX)Ts+JX7Ei)r2A%V2N9_eh#sot&&aKTlv8Wf1>$K)~uVONG~k#EJ`hS9Lx9@pDTo_Q2a^EsxC z=)E0?bazOQA}kNqhz@(u>el7ZT+9x->X#tMB`&}$?sqRtISZ2U>LDa@htL%)K2b*gJUY_n8pUjsa3mO(Z&f5Zio3sUQi?U}^8 zoo}sz&~7F0w#;v#;ZhO-&i7)kfHD{Y!O<4h9OW1k`qMhHWY@tef6!V-=Co=_UoO%HMVN)Cfj`q+iXI%6|aU5?0hrE7=< zMd(grt}4O2sE5qM(lq*bG98V(oNpVxE7hY!FA!_jN#j~EVGm6l3UWCAib$vZOz&y+ I6Pw8Y0alBYZ2$lO literal 0 HcmV?d00001 diff --git a/layout/style/ImageLoader.cpp b/layout/style/ImageLoader.cpp index edd47ba0993..7ccd49db6fe 100644 --- a/layout/style/ImageLoader.cpp +++ b/layout/style/ImageLoader.cpp @@ -12,6 +12,7 @@ #include "nsError.h" #include "nsDisplayList.h" #include "FrameLayerBuilder.h" +#include "nsSVGEffects.h" namespace mozilla { namespace css { @@ -329,6 +330,13 @@ void InvalidateImagesCallback(nsIFrame* aFrame, aItem->Invalidate(); aFrame->SchedulePaint(); + + // Update ancestor rendering observers (-moz-element etc) + nsIFrame *f = aFrame; + while (f && !f->HasAnyStateBits(NS_FRAME_DESCENDANT_NEEDS_PAINT)) { + nsSVGEffects::InvalidateDirectRenderingObservers(f); + f = nsLayoutUtils::GetCrossDocParentFrame(f); + } } void From 92b2b26b2a8b6fefda23e4459b234ceab34cf57a Mon Sep 17 00:00:00 2001 From: Jonathan Kew Date: Wed, 4 Sep 2013 12:16:36 +0100 Subject: [PATCH 061/171] bug 906646 - glyphs with an SVG representation should never be considered "contained". r=roc --- gfx/thebes/gfxFont.cpp | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/gfx/thebes/gfxFont.cpp b/gfx/thebes/gfxFont.cpp index d50ee17ae32..77dcae2b74e 100644 --- a/gfx/thebes/gfxFont.cpp +++ b/gfx/thebes/gfxFont.cpp @@ -3386,6 +3386,19 @@ gfxFont::SetupGlyphExtents(gfxContext *aContext, uint32_t aGlyphID, bool aNeedTi { gfxContextMatrixAutoSaveRestore matrixRestore(aContext); aContext->IdentityMatrix(); + + gfxRect svgBounds; + if (mFontEntry->TryGetSVGData() && mFontEntry->HasSVGGlyph(aGlyphID) && + mFontEntry->GetSVGGlyphExtents(aContext, aGlyphID, &svgBounds)) { + gfxFloat d2a = aExtents->GetAppUnitsPerDevUnit(); + aExtents->SetTightGlyphExtents(aGlyphID, + gfxRect(svgBounds.x * d2a, + svgBounds.y * d2a, + svgBounds.width * d2a, + svgBounds.height * d2a)); + return; + } + cairo_glyph_t glyph; glyph.index = aGlyphID; glyph.x = 0; @@ -3414,16 +3427,6 @@ gfxFont::SetupGlyphExtents(gfxContext *aContext, uint32_t aGlyphID, bool aNeedTi gfxFloat d2a = appUnitsPerDevUnit; gfxRect bounds(extents.x_bearing*d2a, extents.y_bearing*d2a, extents.width*d2a, extents.height*d2a); - - gfxRect svgBounds; - if (mFontEntry->TryGetSVGData() && - mFontEntry->HasSVGGlyph(aGlyphID) && - mFontEntry->GetSVGGlyphExtents(aContext, aGlyphID, &svgBounds)) { - - bounds = bounds.Union(gfxRect(svgBounds.x * d2a, svgBounds.y * d2a, - svgBounds.width * d2a, svgBounds.height * d2a)); - } - aExtents->SetTightGlyphExtents(aGlyphID, bounds); } From 578269fa2d307120c1eeb4cef6535753d506e2b1 Mon Sep 17 00:00:00 2001 From: Yaron Tausky Date: Wed, 4 Sep 2013 13:14:44 +0200 Subject: [PATCH 062/171] Bug 911954 - Add forward declaration of JSScript to TraceLogging.h, r=h4writer --- js/src/TraceLogging.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/js/src/TraceLogging.h b/js/src/TraceLogging.h index 59c7c9a9c35..0de77f176ba 100644 --- a/js/src/TraceLogging.h +++ b/js/src/TraceLogging.h @@ -10,6 +10,8 @@ #include #include +#include "js/TypeDecls.h" + namespace JS { class CompileOptions; } From 018c827b7912131819e527b5a5934011812efb72 Mon Sep 17 00:00:00 2001 From: Ed Morley Date: Wed, 4 Sep 2013 12:44:59 +0100 Subject: [PATCH 063/171] Backed out changeset 8090e534656a (bug 896797) on suspicion of causing bug 912451 on a CLOSED TREE --- Makefile.in | 1 - js/src/Makefile.in | 1 - .../action/process_install_manifest.py | 9 ++--- .../mozbuild/backend/recursivemake.py | 34 ++++++++++------- python/mozbuild/mozbuild/frontend/data.py | 6 +-- python/mozbuild/mozbuild/frontend/emitter.py | 3 +- .../test/backend/test_recursivemake.py | 38 ++++++++++++++----- 7 files changed, 54 insertions(+), 38 deletions(-) diff --git a/Makefile.in b/Makefile.in index 6bfc1eff78b..3d3bc0f5bce 100644 --- a/Makefile.in +++ b/Makefile.in @@ -62,7 +62,6 @@ ifndef MOZ_PROFILE_USE default alldep all:: CLOBBER $(topsrcdir)/configure config.status backend.RecursiveMakeBackend.built $(call SUBMAKE,backend.RecursiveMakeBackend.built,js/src,1) $(call py_action,purge_manifests,-d _build_manifests/purge .) - $(call py_action,process_install_manifest,$(DIST)/include _build_manifests/install/dist_include js/src/_build_manifests/install/dist_include) endif CLOBBER: $(topsrcdir)/CLOBBER diff --git a/js/src/Makefile.in b/js/src/Makefile.in index 8e6996e1e48..2439e81e72b 100644 --- a/js/src/Makefile.in +++ b/js/src/Makefile.in @@ -177,7 +177,6 @@ MOZILLA_DTRACE_SRC = $(srcdir)/devtools/javascript-trace.d endif default:: - $(call py_action,process_install_manifest,--no-remove $(DIST)/include _build_manifests/install/dist_include) ifneq (,$(CROSS_COMPILE)$(filter-out WINNT OS2,$(OS_ARCH))) # nsinstall doesn't get built until we enter config/ in the exports phase, diff --git a/python/mozbuild/mozbuild/action/process_install_manifest.py b/python/mozbuild/mozbuild/action/process_install_manifest.py index 9c5aec14196..33468703145 100644 --- a/python/mozbuild/mozbuild/action/process_install_manifest.py +++ b/python/mozbuild/mozbuild/action/process_install_manifest.py @@ -13,14 +13,14 @@ COMPLETE = 'From {dest}: Kept {existing} existing; Added/updated {updated}; ' \ 'Removed {rm_files} files and {rm_dirs} directories.' -def process_manifest(destdir, paths, remove_unaccounted=True): +def process_manifest(destdir, *paths): manifest = InstallManifest() for path in paths: manifest |= InstallManifest(path=path) copier = FileCopier() manifest.populate_registry(copier) - return copier.copy(destdir, remove_unaccounted=remove_unaccounted) + return copier.copy(destdir) if __name__ == '__main__': @@ -29,13 +29,10 @@ if __name__ == '__main__': parser.add_argument('destdir', help='Destination directory.') parser.add_argument('manifests', nargs='+', help='Path to manifest file(s).') - parser.add_argument('--no-remove', action='store_true', - help='Do not remove unaccounted files from destination.') args = parser.parse_args() - result = process_manifest(args.destdir, args.manifests, - remove_unaccounted=not args.no_remove) + result = process_manifest(args.destdir, *args.manifests) print(COMPLETE.format(dest=args.destdir, existing=result.existing_files_count, diff --git a/python/mozbuild/mozbuild/backend/recursivemake.py b/python/mozbuild/mozbuild/backend/recursivemake.py index 765f329d004..4527e3cf477 100644 --- a/python/mozbuild/mozbuild/backend/recursivemake.py +++ b/python/mozbuild/mozbuild/backend/recursivemake.py @@ -149,8 +149,11 @@ class RecursiveMakeBackend(CommonBackend): self.backend_input_files.add(os.path.join(self.environment.topobjdir, 'config', 'autoconf.mk')) + self._install_manifests = dict() + self._purge_manifests = dict( dist_bin=PurgeManifest(relpath='dist/bin'), + dist_include=PurgeManifest(relpath='dist/include'), dist_private=PurgeManifest(relpath='dist/private'), dist_public=PurgeManifest(relpath='dist/public'), dist_sdk=PurgeManifest(relpath='dist/sdk'), @@ -160,7 +163,6 @@ class RecursiveMakeBackend(CommonBackend): self._install_manifests = dict( dist_idl=InstallManifest(), - dist_include=InstallManifest(), ) def _update_from_avoid_write(self, result): @@ -366,22 +368,27 @@ class RecursiveMakeBackend(CommonBackend): ' '.join(obj.parallel_external_make_dirs)) def _process_exports(self, obj, exports, backend_file, namespace=""): - # This may not be needed, but is present for backwards compatibility - # with the old make rules, just in case. - if not obj.dist_install: - return - strings = exports.get_strings() if namespace: + if strings: + backend_file.write('EXPORTS_NAMESPACES += %s\n' % namespace) + export_name = 'EXPORTS_%s' % namespace namespace += '/' + else: + export_name = 'EXPORTS' - for s in strings: - source = os.path.normpath(os.path.join(obj.srcdir, s)) - dest = '%s%s' % (namespace, os.path.basename(s)) - self._install_manifests['dist_include'].add_symlink(source, dest) + # Iterate over the list of export filenames, printing out an EXPORTS + # declaration for each. + if strings: + backend_file.write('%s += %s\n' % (export_name, ' '.join(strings))) - if not os.path.exists(source): - raise Exception('File listed in EXPORTS does not exist: %s' % source) + for s in strings: + source = os.path.normpath(os.path.join(obj.srcdir, s)) + if not os.path.isfile(source): + raise Exception('File listed in EXPORTS does not exist: %s' % source) + + p = '%s%s' % (namespace, s) + self._purge_manifests['dist_include'].add(p) children = exports.get_children() for subdir in sorted(children): @@ -398,8 +405,7 @@ class RecursiveMakeBackend(CommonBackend): for idl in manager.idls.values(): self._install_manifests['dist_idl'].add_symlink(idl['source'], idl['basename']) - self._install_manifests['dist_include'].add_optional_exists('%s.h' - % idl['root']) + self._purge_manifests['dist_include'].add('%s.h' % idl['root']) build_files.add(mozpath.join('headers', '%s.h' % idl['root'])) for module in manager.modules: diff --git a/python/mozbuild/mozbuild/frontend/data.py b/python/mozbuild/mozbuild/frontend/data.py index 9db3d89079c..0ca88f36cdf 100644 --- a/python/mozbuild/mozbuild/frontend/data.py +++ b/python/mozbuild/mozbuild/frontend/data.py @@ -161,13 +161,11 @@ class Exports(SandboxDerived): this object fills that role. It just has a reference to the underlying HierarchicalStringList, which is created when parsing EXPORTS. """ - __slots__ = ('exports', 'dist_install') + __slots__ = ('exports') - def __init__(self, sandbox, exports, dist_install=True): + def __init__(self, sandbox, exports): SandboxDerived.__init__(self, sandbox) self.exports = exports - self.dist_install = dist_install - class IPDLFile(SandboxDerived): """Describes an individual .ipdl source file.""" diff --git a/python/mozbuild/mozbuild/frontend/emitter.py b/python/mozbuild/mozbuild/frontend/emitter.py index 3e8bd677582..4979e8b02c5 100644 --- a/python/mozbuild/mozbuild/frontend/emitter.py +++ b/python/mozbuild/mozbuild/frontend/emitter.py @@ -154,8 +154,7 @@ class TreeMetadataEmitter(LoggingMixin): exports = sandbox.get('EXPORTS') if exports: - yield Exports(sandbox, exports, - dist_install=not sandbox.get('NO_DIST_INSTALL', False)) + yield Exports(sandbox, exports) program = sandbox.get('PROGRAM') if program: diff --git a/python/mozbuild/mozbuild/test/backend/test_recursivemake.py b/python/mozbuild/mozbuild/test/backend/test_recursivemake.py index a2d64e8b31c..ff411d2701c 100644 --- a/python/mozbuild/mozbuild/test/backend/test_recursivemake.py +++ b/python/mozbuild/mozbuild/test/backend/test_recursivemake.py @@ -234,16 +234,33 @@ class TestRecursiveMakeBackend(BackendTester): self.assertEqual(found, val) def test_exports(self): - """Ensure EXPORTS is handled properly.""" + """Ensure EXPORTS is written out correctly.""" env = self._consume('exports', RecursiveMakeBackend) - # EXPORTS files should appear in the dist_include install manifest. - m = InstallManifest(path=os.path.join(env.topobjdir, - '_build_manifests', 'install', 'dist_include')) - self.assertEqual(len(m), 7) - self.assertIn('foo.h', m) - self.assertIn('mozilla/mozilla1.h', m) - self.assertIn('mozilla/dom/dom2.h', m) + backend_path = os.path.join(env.topobjdir, 'backend.mk') + lines = [l.strip() for l in open(backend_path, 'rt').readlines()[2:]] + + self.assertEqual(lines, [ + 'MOZBUILD_DERIVED := 1', + 'NO_MAKEFILE_RULE := 1', + 'NO_SUBMAKEFILES_RULE := 1', + 'EXPORTS += foo.h', + 'EXPORTS_NAMESPACES += mozilla', + 'EXPORTS_mozilla += mozilla1.h mozilla2.h', + 'EXPORTS_NAMESPACES += mozilla/dom', + 'EXPORTS_mozilla/dom += dom1.h dom2.h', + 'EXPORTS_NAMESPACES += mozilla/gfx', + 'EXPORTS_mozilla/gfx += gfx.h', + 'EXPORTS_NAMESPACES += nspr/private', + 'EXPORTS_nspr/private += pprio.h', + ]) + + # EXPORTS files should appear in the dist_include purge manifest. + m = PurgeManifest(path=os.path.join(env.topobjdir, + '_build_manifests', 'purge', 'dist_include')) + self.assertIn('foo.h', m.entries) + self.assertIn('mozilla/mozilla1.h', m.entries) + self.assertIn('mozilla/dom/dom2.h', m.entries) def test_xpcshell_manifests(self): """Ensure XPCSHELL_TESTS_MANIFESTS is written out correctly.""" @@ -280,8 +297,8 @@ class TestRecursiveMakeBackend(BackendTester): self.assertIn('bar.idl', m) self.assertIn('foo.idl', m) - m = InstallManifest(path=os.path.join(install_dir, 'dist_include')) - self.assertIn('foo.h', m) + m = PurgeManifest(path=os.path.join(purge_dir, 'dist_include')) + self.assertIn('foo.h', m.entries) p = os.path.join(env.topobjdir, 'config/makefiles/xpidl') self.assertTrue(os.path.isdir(p)) @@ -308,6 +325,7 @@ class TestRecursiveMakeBackend(BackendTester): expected = [ 'dist_bin', + 'dist_include', 'dist_private', 'dist_public', 'dist_sdk', From 99e1fb0e191bc13f45967a3950cf91fb168a95dd Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Wed, 4 Sep 2013 11:26:20 -0400 Subject: [PATCH 064/171] Bug 912195 - Minimize the #includes in docshell/shistory; r=bzbarsky --- docshell/shistory/src/nsSHEntry.cpp | 6 ++---- docshell/shistory/src/nsSHEntry.h | 4 ++-- docshell/shistory/src/nsSHEntryShared.cpp | 2 +- docshell/shistory/src/nsSHEntryShared.h | 2 +- docshell/shistory/src/nsSHTransaction.cpp | 1 + docshell/shistory/src/nsSHTransaction.h | 3 ++- docshell/shistory/src/nsSHistory.cpp | 10 +++++----- docshell/shistory/src/nsSHistory.h | 8 ++++---- 8 files changed, 18 insertions(+), 18 deletions(-) diff --git a/docshell/shistory/src/nsSHEntry.cpp b/docshell/shistory/src/nsSHEntry.cpp index 8d849abe0c3..cd10c23394e 100644 --- a/docshell/shistory/src/nsSHEntry.cpp +++ b/docshell/shistory/src/nsSHEntry.cpp @@ -5,18 +5,16 @@ // Local Includes #include "nsSHEntry.h" -#include "nsXPIDLString.h" -#include "nsReadableUtils.h" #include "nsIDocShellLoadInfo.h" #include "nsIDocShellTreeItem.h" -#include "nsISHistory.h" -#include "nsISHistoryInternal.h" #include "nsDocShellEditorData.h" #include "nsSHEntryShared.h" #include "nsILayoutHistoryState.h" #include "nsIContentViewer.h" #include "nsISupportsArray.h" #include "nsIStructuredCloneContainer.h" +#include "nsIInputStream.h" +#include "nsIURI.h" #include namespace dom = mozilla::dom; diff --git a/docshell/shistory/src/nsSHEntry.h b/docshell/shistory/src/nsSHEntry.h index 7c9489ea37c..66d5934326d 100644 --- a/docshell/shistory/src/nsSHEntry.h +++ b/docshell/shistory/src/nsSHEntry.h @@ -15,12 +15,12 @@ #include "mozilla/Attributes.h" // Interfaces needed -#include "nsIInputStream.h" #include "nsISHEntry.h" #include "nsISHContainer.h" -#include "nsIURI.h" class nsSHEntryShared; +class nsIInputStream; +class nsIURI; class nsSHEntry MOZ_FINAL : public nsISHEntry, public nsISHContainer, diff --git a/docshell/shistory/src/nsSHEntryShared.cpp b/docshell/shistory/src/nsSHEntryShared.cpp index 8c81854faba..5d44492fc8a 100644 --- a/docshell/shistory/src/nsSHEntryShared.cpp +++ b/docshell/shistory/src/nsSHEntryShared.cpp @@ -14,8 +14,8 @@ #include "nsDocShellEditorData.h" #include "nsThreadUtils.h" #include "nsILayoutHistoryState.h" -#include "prprf.h" #include "mozilla/Attributes.h" +#include "nsISupportsArray.h" namespace dom = mozilla::dom; diff --git a/docshell/shistory/src/nsSHEntryShared.h b/docshell/shistory/src/nsSHEntryShared.h index 31b0afb82c0..5bd757ee427 100644 --- a/docshell/shistory/src/nsSHEntryShared.h +++ b/docshell/shistory/src/nsSHEntryShared.h @@ -8,7 +8,6 @@ #include "nsCOMPtr.h" #include "nsAutoPtr.h" #include "nsCOMArray.h" -#include "nsISupportsArray.h" #include "nsIBFCacheEntry.h" #include "nsIMutationObserver.h" #include "nsExpirationTracker.h" @@ -23,6 +22,7 @@ class nsIContentViewer; class nsIDocShellTreeItem; class nsILayoutHistoryState; class nsDocShellEditorData; +class nsISupportsArray; // A document may have multiple SHEntries, either due to hash navigations or // calls to history.pushState. SHEntries corresponding to the same document diff --git a/docshell/shistory/src/nsSHTransaction.cpp b/docshell/shistory/src/nsSHTransaction.cpp index 463300564fc..1768a44efdd 100644 --- a/docshell/shistory/src/nsSHTransaction.cpp +++ b/docshell/shistory/src/nsSHTransaction.cpp @@ -6,6 +6,7 @@ // Local Includes #include "nsSHTransaction.h" +#include "nsISHEntry.h" //***************************************************************************** //*** nsSHTransaction: Object Management diff --git a/docshell/shistory/src/nsSHTransaction.h b/docshell/shistory/src/nsSHTransaction.h index fafd43bac1a..8c7ba2afd5c 100644 --- a/docshell/shistory/src/nsSHTransaction.h +++ b/docshell/shistory/src/nsSHTransaction.h @@ -12,7 +12,8 @@ // Needed interfaces #include "nsISHTransaction.h" -#include "nsISHEntry.h" + +class nsISHEntry; class nsSHTransaction: public nsISHTransaction { diff --git a/docshell/shistory/src/nsSHistory.cpp b/docshell/shistory/src/nsSHistory.cpp index 5d385383f1e..eae5642fd9e 100644 --- a/docshell/shistory/src/nsSHistory.cpp +++ b/docshell/shistory/src/nsSHistory.cpp @@ -9,8 +9,6 @@ #include // Helper Classes -#include "nsXPIDLString.h" -#include "nsReadableUtils.h" #include "mozilla/Preferences.h" // Interfaces Needed @@ -20,8 +18,6 @@ #include "nsISHContainer.h" #include "nsIDocShellTreeItem.h" #include "nsIDocShellTreeNode.h" -#include "nsIDocShellLoadInfo.h" -#include "nsIServiceManager.h" #include "nsIURI.h" #include "nsIContentViewer.h" #include "nsICacheService.h" @@ -32,9 +28,13 @@ #include "nsCOMArray.h" #include "nsDocShell.h" #include "mozilla/Attributes.h" +#include "nsISHEntry.h" +#include "nsISHTransaction.h" +#include "nsISHistoryListener.h" +#include "nsComponentManagerUtils.h" // For calculating max history entries and max cachable contentviewers -#include "nspr.h" +#include "prsystem.h" #include "mozilla/MathAlgorithms.h" using namespace mozilla; diff --git a/docshell/shistory/src/nsSHistory.h b/docshell/shistory/src/nsSHistory.h index c88ab270a1e..546b2f7cf66 100644 --- a/docshell/shistory/src/nsSHistory.h +++ b/docshell/shistory/src/nsSHistory.h @@ -13,13 +13,10 @@ //Interfaces Needed #include "nsISHistory.h" #include "nsISHistoryInternal.h" -#include "nsISHTransaction.h" #include "nsIWebNavigation.h" -#include "nsIWeakReference.h" #include "nsISimpleEnumerator.h" -#include "nsISHistoryListener.h" -#include "nsISHEntry.h" #include "nsTObserverArray.h" +#include "nsWeakPtr.h" // Needed to maintain global list of all SHistory objects #include "prclist.h" @@ -27,6 +24,9 @@ class nsIDocShell; class nsSHEnumerator; class nsSHistoryObserver; +class nsISHEntry; +class nsISHTransaction; + class nsSHistory: public PRCList, public nsISHistory, public nsISHistoryInternal, From d42c57edaeff03bbffe2e401a1d3018749c955b3 Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Wed, 4 Sep 2013 08:14:35 -0400 Subject: [PATCH 065/171] Bug 911848 - WebGLBuffer's mByteLength should be a WebGLsizeiptr - r=jgilbert --- content/canvas/src/WebGLBuffer.h | 6 +++--- content/canvas/src/WebGLContextBuffers.cpp | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/content/canvas/src/WebGLBuffer.h b/content/canvas/src/WebGLBuffer.h index 5b5833f8a73..dd4434a414b 100644 --- a/content/canvas/src/WebGLBuffer.h +++ b/content/canvas/src/WebGLBuffer.h @@ -40,10 +40,10 @@ public: bool HasEverBeenBound() { return mHasEverBeenBound; } void SetHasEverBeenBound(bool x) { mHasEverBeenBound = x; } GLuint GLName() const { return mGLName; } - GLuint ByteLength() const { return mByteLength; } + WebGLsizeiptr ByteLength() const { return mByteLength; } GLenum Target() const { return mTarget; } - void SetByteLength(GLuint byteLength) { mByteLength = byteLength; } + void SetByteLength(WebGLsizeiptr byteLength) { mByteLength = byteLength; } void SetTarget(GLenum target); @@ -69,7 +69,7 @@ protected: WebGLuint mGLName; bool mHasEverBeenBound; - GLuint mByteLength; + WebGLsizeiptr mByteLength; GLenum mTarget; nsAutoPtr mCache; diff --git a/content/canvas/src/WebGLContextBuffers.cpp b/content/canvas/src/WebGLContextBuffers.cpp index 83e777b1bcf..ffbaed492fc 100644 --- a/content/canvas/src/WebGLContextBuffers.cpp +++ b/content/canvas/src/WebGLContextBuffers.cpp @@ -281,7 +281,7 @@ WebGLContext::BufferSubData(GLenum target, WebGLsizeiptr byteOffset, if (!boundBuffer) return ErrorInvalidOperation("bufferData: no buffer bound!"); - CheckedUint32 checked_neededByteLength = CheckedUint32(byteOffset) + data.Length(); + CheckedInt checked_neededByteLength = CheckedInt(byteOffset) + data.Length(); if (!checked_neededByteLength.isValid()) return ErrorInvalidValue("bufferSubData: integer overflow computing the needed byte length"); @@ -317,7 +317,7 @@ WebGLContext::BufferSubData(WebGLenum target, WebGLsizeiptr byteOffset, if (!boundBuffer) return ErrorInvalidOperation("bufferSubData: no buffer bound!"); - CheckedUint32 checked_neededByteLength = CheckedUint32(byteOffset) + data.Length(); + CheckedInt checked_neededByteLength = CheckedInt(byteOffset) + data.Length(); if (!checked_neededByteLength.isValid()) return ErrorInvalidValue("bufferSubData: integer overflow computing the needed byte length"); From aa0bf1b2aea05b4e4fd9ccd0584ab021da2ef58d Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Wed, 4 Sep 2013 08:14:37 -0400 Subject: [PATCH 066/171] Bug 911850 - BindBufferRange should check for out-of-bounds range - r=jgilbert --- content/canvas/src/WebGLContextBuffers.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/content/canvas/src/WebGLContextBuffers.cpp b/content/canvas/src/WebGLContextBuffers.cpp index ffbaed492fc..29143b44d00 100644 --- a/content/canvas/src/WebGLContextBuffers.cpp +++ b/content/canvas/src/WebGLContextBuffers.cpp @@ -113,6 +113,12 @@ WebGLContext::BindBufferRange(WebGLenum target, WebGLuint index, WebGLBuffer* bu } else if (target != buffer->Target()) { return ErrorInvalidOperation("bindBuffer: buffer already bound to a different target"); } + CheckedInt checked_neededByteLength = CheckedInt(offset) + size; + if (!checked_neededByteLength.isValid() || + checked_neededByteLength.value() > buffer->ByteLength()) + { + return ErrorInvalidValue("bindBufferRange: invalid range"); + } } WebGLRefPtr* bufferSlot = GetBufferSlotByTarget(target, "bindBuffer"); From 70cb68de38204fa0c51610a26bad3f16c76a495e Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Wed, 4 Sep 2013 08:14:39 -0400 Subject: [PATCH 067/171] Bug 911851 - Check WebGL sizeiptr arguments - r=jgilbert --- content/canvas/src/WebGLContextBuffers.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/content/canvas/src/WebGLContextBuffers.cpp b/content/canvas/src/WebGLContextBuffers.cpp index 29143b44d00..6909e332b5a 100644 --- a/content/canvas/src/WebGLContextBuffers.cpp +++ b/content/canvas/src/WebGLContextBuffers.cpp @@ -152,6 +152,10 @@ WebGLContext::BufferData(WebGLenum target, WebGLsizeiptr size, if (!ValidateBufferUsageEnum(usage, "bufferData: usage")) return; + // careful: WebGLsizeiptr is always 64-bit, but GLsizeiptr is like intptr_t. + if (!CheckedInt(size).isValid()) + return ErrorOutOfMemory("bufferData: bad size"); + WebGLBuffer* boundBuffer = bufferSlot->get(); if (!boundBuffer) @@ -199,6 +203,10 @@ WebGLContext::BufferData(WebGLenum target, const ArrayBuffer& data = maybeData.Value(); + // careful: data.Length() could conceivably be any size_t, but GLsizeiptr is like intptr_t. + if (!CheckedInt(data.Length()).isValid()) + return ErrorOutOfMemory("bufferData: bad size"); + if (!ValidateBufferUsageEnum(usage, "bufferData: usage")) return; @@ -244,6 +252,10 @@ WebGLContext::BufferData(WebGLenum target, const ArrayBufferView& data, if (!boundBuffer) return ErrorInvalidOperation("bufferData: no buffer bound!"); + // careful: data.Length() could conceivably be any size_t, but GLsizeiptr is like intptr_t. + if (!CheckedInt(data.Length()).isValid()) + return ErrorOutOfMemory("bufferData: bad size"); + InvalidateBufferFetching(); MakeContextCurrent(); From 20d3a7a3bc3183714280e70ef868151d9942fa59 Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Wed, 4 Sep 2013 08:14:41 -0400 Subject: [PATCH 068/171] Bug 911853 - OpenGL types should be explicit-size integer types - r=jgilbert --- gfx/gl/GLContext.h | 2 -- gfx/gl/GLTypes.h | 20 ++++++++++---------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/gfx/gl/GLContext.h b/gfx/gl/GLContext.h index 0de58e125e1..6ec2fec93f4 100644 --- a/gfx/gl/GLContext.h +++ b/gfx/gl/GLContext.h @@ -48,8 +48,6 @@ #include "SurfaceTypes.h" #include "GLScreenBuffer.h" -typedef char realGLboolean; - #include "GLContextSymbols.h" #include "mozilla/mozalloc.h" diff --git a/gfx/gl/GLTypes.h b/gfx/gl/GLTypes.h index 866f041626d..8044370ea4d 100644 --- a/gfx/gl/GLTypes.h +++ b/gfx/gl/GLTypes.h @@ -12,16 +12,16 @@ #include #include -typedef unsigned int GLenum; -typedef unsigned int GLbitfield; -typedef unsigned int GLuint; -typedef int GLint; -typedef int GLsizei; -typedef char realGLboolean; -typedef signed char GLbyte; -typedef short GLshort; -typedef unsigned char GLubyte; -typedef unsigned short GLushort; +typedef uint32_t GLenum; +typedef uint32_t GLbitfield; +typedef uint32_t GLuint; +typedef int32_t GLint; +typedef int32_t GLsizei; +typedef int8_t realGLboolean; +typedef int8_t GLbyte; +typedef int16_t GLshort; +typedef uint8_t GLubyte; +typedef uint16_t GLushort; typedef float GLfloat; typedef float GLclampf; #ifndef GLdouble_defined From a53a6563d13e11589d33991f876624f4d6f5be37 Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Wed, 4 Sep 2013 08:14:43 -0400 Subject: [PATCH 069/171] Bug 911855 - Remove redundant WebGL integer typedefs - r=jgilbert --- content/canvas/src/WebGLActiveInfo.h | 10 +- content/canvas/src/WebGLBuffer.h | 4 +- content/canvas/src/WebGLContext.cpp | 4 +- content/canvas/src/WebGLContext.h | 478 +++++++++--------- .../canvas/src/WebGLContextAsyncQueries.cpp | 12 +- content/canvas/src/WebGLContextBuffers.cpp | 22 +- .../src/WebGLContextFramebufferOperations.cpp | 18 +- content/canvas/src/WebGLContextGL.cpp | 330 ++++++------ content/canvas/src/WebGLContextState.cpp | 16 +- content/canvas/src/WebGLContextUtils.cpp | 8 +- content/canvas/src/WebGLContextValidate.cpp | 42 +- content/canvas/src/WebGLContextVertices.cpp | 74 +-- .../src/WebGLExtensionInstancedArrays.cpp | 12 +- content/canvas/src/WebGLExtensions.h | 12 +- content/canvas/src/WebGLFramebuffer.cpp | 50 +- content/canvas/src/WebGLFramebuffer.h | 36 +- content/canvas/src/WebGLObjectModel.h | 16 +- content/canvas/src/WebGLProgram.h | 4 +- content/canvas/src/WebGLQuery.h | 4 +- content/canvas/src/WebGLRenderbuffer.h | 16 +- content/canvas/src/WebGLShader.cpp | 2 +- content/canvas/src/WebGLShader.h | 10 +- .../canvas/src/WebGLShaderPrecisionFormat.h | 14 +- content/canvas/src/WebGLTexture.cpp | 12 +- content/canvas/src/WebGLTexture.h | 40 +- content/canvas/src/WebGLTypes.h | 10 +- content/canvas/src/WebGLVertexArray.cpp | 6 +- content/canvas/src/WebGLVertexArray.h | 6 +- content/canvas/src/WebGLVertexAttribData.h | 6 +- 29 files changed, 634 insertions(+), 640 deletions(-) diff --git a/content/canvas/src/WebGLActiveInfo.h b/content/canvas/src/WebGLActiveInfo.h index 54625c26e84..ab7dd0f270a 100644 --- a/content/canvas/src/WebGLActiveInfo.h +++ b/content/canvas/src/WebGLActiveInfo.h @@ -16,7 +16,7 @@ namespace mozilla { class WebGLActiveInfo MOZ_FINAL { public: - WebGLActiveInfo(WebGLint size, WebGLenum type, const nsACString& name) : + WebGLActiveInfo(GLint size, GLenum type, const nsACString& name) : mSize(size), mType(type), mName(NS_ConvertASCIItoUTF16(name)) @@ -24,11 +24,11 @@ public: // WebIDL attributes - WebGLint Size() const { + GLint Size() const { return mSize; } - WebGLenum Type() const { + GLenum Type() const { return mType; } @@ -41,8 +41,8 @@ public: NS_INLINE_DECL_REFCOUNTING(WebGLActiveInfo) protected: - WebGLint mSize; - WebGLenum mType; + GLint mSize; + GLenum mType; nsString mName; }; diff --git a/content/canvas/src/WebGLBuffer.h b/content/canvas/src/WebGLBuffer.h index dd4434a414b..a653bd74839 100644 --- a/content/canvas/src/WebGLBuffer.h +++ b/content/canvas/src/WebGLBuffer.h @@ -51,7 +51,7 @@ public: void ElementArrayCacheBufferSubData(size_t pos, const void* ptr, size_t update_size_in_bytes); - bool Validate(WebGLenum type, uint32_t max_allowed, size_t first, size_t count) { + bool Validate(GLenum type, uint32_t max_allowed, size_t first, size_t count) { return mCache->Validate(type, max_allowed, first, count); } @@ -67,7 +67,7 @@ public: protected: - WebGLuint mGLName; + GLuint mGLName; bool mHasEverBeenBound; WebGLsizeiptr mByteLength; GLenum mTarget; diff --git a/content/canvas/src/WebGLContext.cpp b/content/canvas/src/WebGLContext.cpp index 5b208afa993..34b3c574d3d 100644 --- a/content/canvas/src/WebGLContext.cpp +++ b/content/canvas/src/WebGLContext.cpp @@ -914,7 +914,7 @@ WebGLContext::GetContextAttributes(Nullable > &retval); JSObject* GetExtension(JSContext* cx, const nsAString& aName, ErrorResult& rv); - void ActiveTexture(WebGLenum texture); + void ActiveTexture(GLenum texture); void AttachShader(WebGLProgram* program, WebGLShader* shader); - void BindAttribLocation(WebGLProgram* program, WebGLuint location, + void BindAttribLocation(WebGLProgram* program, GLuint location, const nsAString& name); - void BindFramebuffer(WebGLenum target, WebGLFramebuffer* wfb); - void BindRenderbuffer(WebGLenum target, WebGLRenderbuffer* wrb); - void BindTexture(WebGLenum target, WebGLTexture *tex); + void BindFramebuffer(GLenum target, WebGLFramebuffer* wfb); + void BindRenderbuffer(GLenum target, WebGLRenderbuffer* wrb); + void BindTexture(GLenum target, WebGLTexture *tex); void BindVertexArray(WebGLVertexArray *vao); - void BlendColor(WebGLclampf r, WebGLclampf g, WebGLclampf b, WebGLclampf a) { + void BlendColor(GLclampf r, GLclampf g, GLclampf b, GLclampf a) { if (!IsContextStable()) return; MakeContextCurrent(); gl->fBlendColor(r, g, b, a); } - void BlendEquation(WebGLenum mode); - void BlendEquationSeparate(WebGLenum modeRGB, WebGLenum modeAlpha); - void BlendFunc(WebGLenum sfactor, WebGLenum dfactor); - void BlendFuncSeparate(WebGLenum srcRGB, WebGLenum dstRGB, - WebGLenum srcAlpha, WebGLenum dstAlpha); - WebGLenum CheckFramebufferStatus(WebGLenum target); - void Clear(WebGLbitfield mask); - void ClearColor(WebGLclampf r, WebGLclampf g, WebGLclampf b, WebGLclampf a); - void ClearDepth(WebGLclampf v); - void ClearStencil(WebGLint v); + void BlendEquation(GLenum mode); + void BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha); + void BlendFunc(GLenum sfactor, GLenum dfactor); + void BlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, + GLenum srcAlpha, GLenum dstAlpha); + GLenum CheckFramebufferStatus(GLenum target); + void Clear(GLbitfield mask); + void ClearColor(GLclampf r, GLclampf g, GLclampf b, GLclampf a); + void ClearDepth(GLclampf v); + void ClearStencil(GLint v); void ColorMask(WebGLboolean r, WebGLboolean g, WebGLboolean b, WebGLboolean a); void CompileShader(WebGLShader *shader); - void CompressedTexImage2D(WebGLenum target, WebGLint level, - WebGLenum internalformat, WebGLsizei width, - WebGLsizei height, WebGLint border, + void CompressedTexImage2D(GLenum target, GLint level, + GLenum internalformat, GLsizei width, + GLsizei height, GLint border, const dom::ArrayBufferView& view); - void CompressedTexSubImage2D(WebGLenum target, WebGLint level, - WebGLint xoffset, WebGLint yoffset, - WebGLsizei width, WebGLsizei height, - WebGLenum format, + void CompressedTexSubImage2D(GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, const dom::ArrayBufferView& view); - void CopyTexImage2D(WebGLenum target, WebGLint level, - WebGLenum internalformat, WebGLint x, WebGLint y, - WebGLsizei width, WebGLsizei height, WebGLint border); - void CopyTexSubImage2D(WebGLenum target, WebGLint level, WebGLint xoffset, - WebGLint yoffset, WebGLint x, WebGLint y, - WebGLsizei width, WebGLsizei height); + void CopyTexImage2D(GLenum target, GLint level, + GLenum internalformat, GLint x, GLint y, + GLsizei width, GLsizei height, GLint border); + void CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, + GLint yoffset, GLint x, GLint y, + GLsizei width, GLsizei height); already_AddRefed CreateFramebuffer(); already_AddRefed CreateProgram(); already_AddRefed CreateRenderbuffer(); already_AddRefed CreateTexture(); - already_AddRefed CreateShader(WebGLenum type); + already_AddRefed CreateShader(GLenum type); already_AddRefed CreateVertexArray(); - void CullFace(WebGLenum face); + void CullFace(GLenum face); void DeleteFramebuffer(WebGLFramebuffer *fbuf); void DeleteProgram(WebGLProgram *prog); void DeleteRenderbuffer(WebGLRenderbuffer *rbuf); void DeleteShader(WebGLShader *shader); void DeleteVertexArray(WebGLVertexArray *vao); void DeleteTexture(WebGLTexture *tex); - void DepthFunc(WebGLenum func); + void DepthFunc(GLenum func); void DepthMask(WebGLboolean b); - void DepthRange(WebGLclampf zNear, WebGLclampf zFar); + void DepthRange(GLclampf zNear, GLclampf zFar); void DetachShader(WebGLProgram *program, WebGLShader *shader); void DrawBuffers(const dom::Sequence& buffers); void Flush() { @@ -382,119 +382,119 @@ public: MakeContextCurrent(); gl->fFinish(); } - void FramebufferRenderbuffer(WebGLenum target, WebGLenum attachment, - WebGLenum rbtarget, WebGLRenderbuffer *wrb); - void FramebufferTexture2D(WebGLenum target, WebGLenum attachment, - WebGLenum textarget, WebGLTexture *tobj, - WebGLint level); - void FrontFace(WebGLenum mode); - void GenerateMipmap(WebGLenum target); + void FramebufferRenderbuffer(GLenum target, GLenum attachment, + GLenum rbtarget, WebGLRenderbuffer *wrb); + void FramebufferTexture2D(GLenum target, GLenum attachment, + GLenum textarget, WebGLTexture *tobj, + GLint level); + void FrontFace(GLenum mode); + void GenerateMipmap(GLenum target); already_AddRefed GetActiveAttrib(WebGLProgram *prog, - WebGLuint index); + GLuint index); already_AddRefed GetActiveUniform(WebGLProgram *prog, - WebGLuint index); + GLuint index); void GetAttachedShaders(WebGLProgram* prog, dom::Nullable< nsTArray > &retval); - WebGLint GetAttribLocation(WebGLProgram* prog, const nsAString& name); - JS::Value GetBufferParameter(WebGLenum target, WebGLenum pname); - JS::Value GetBufferParameter(JSContext* /* unused */, WebGLenum target, - WebGLenum pname) { + GLint GetAttribLocation(WebGLProgram* prog, const nsAString& name); + JS::Value GetBufferParameter(GLenum target, GLenum pname); + JS::Value GetBufferParameter(JSContext* /* unused */, GLenum target, + GLenum pname) { return GetBufferParameter(target, pname); } - WebGLenum GetError(); + GLenum GetError(); JS::Value GetFramebufferAttachmentParameter(JSContext* cx, - WebGLenum target, - WebGLenum attachment, - WebGLenum pname, + GLenum target, + GLenum attachment, + GLenum pname, ErrorResult& rv); - JS::Value GetProgramParameter(WebGLProgram *prog, WebGLenum pname); + JS::Value GetProgramParameter(WebGLProgram *prog, GLenum pname); JS::Value GetProgramParameter(JSContext* /* unused */, WebGLProgram *prog, - WebGLenum pname) { + GLenum pname) { return GetProgramParameter(prog, pname); } void GetProgramInfoLog(WebGLProgram *prog, nsACString& retval); void GetProgramInfoLog(WebGLProgram *prog, nsAString& retval); - JS::Value GetRenderbufferParameter(WebGLenum target, WebGLenum pname); + JS::Value GetRenderbufferParameter(GLenum target, GLenum pname); JS::Value GetRenderbufferParameter(JSContext* /* unused */, - WebGLenum target, WebGLenum pname) { + GLenum target, GLenum pname) { return GetRenderbufferParameter(target, pname); } - JS::Value GetShaderParameter(WebGLShader *shader, WebGLenum pname); + JS::Value GetShaderParameter(WebGLShader *shader, GLenum pname); JS::Value GetShaderParameter(JSContext* /* unused */, WebGLShader *shader, - WebGLenum pname) { + GLenum pname) { return GetShaderParameter(shader, pname); } already_AddRefed - GetShaderPrecisionFormat(WebGLenum shadertype, WebGLenum precisiontype); + GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype); void GetShaderInfoLog(WebGLShader *shader, nsACString& retval); void GetShaderInfoLog(WebGLShader *shader, nsAString& retval); void GetShaderSource(WebGLShader *shader, nsAString& retval); - JS::Value GetTexParameter(WebGLenum target, WebGLenum pname); - JS::Value GetTexParameter(JSContext * /* unused */, WebGLenum target, - WebGLenum pname) { + JS::Value GetTexParameter(GLenum target, GLenum pname); + JS::Value GetTexParameter(JSContext * /* unused */, GLenum target, + GLenum pname) { return GetTexParameter(target, pname); } JS::Value GetUniform(JSContext* cx, WebGLProgram *prog, WebGLUniformLocation *location, ErrorResult& rv); already_AddRefed GetUniformLocation(WebGLProgram *prog, const nsAString& name); - void Hint(WebGLenum target, WebGLenum mode); + void Hint(GLenum target, GLenum mode); bool IsFramebuffer(WebGLFramebuffer *fb); bool IsProgram(WebGLProgram *prog); bool IsRenderbuffer(WebGLRenderbuffer *rb); bool IsShader(WebGLShader *shader); bool IsTexture(WebGLTexture *tex); bool IsVertexArray(WebGLVertexArray *vao); - void LineWidth(WebGLfloat width) { + void LineWidth(GLfloat width) { if (!IsContextStable()) return; MakeContextCurrent(); gl->fLineWidth(width); } void LinkProgram(WebGLProgram *program); - void PixelStorei(WebGLenum pname, WebGLint param); - void PolygonOffset(WebGLfloat factor, WebGLfloat units) { + void PixelStorei(GLenum pname, GLint param); + void PolygonOffset(GLfloat factor, GLfloat units) { if (!IsContextStable()) return; MakeContextCurrent(); gl->fPolygonOffset(factor, units); } - void ReadPixels(WebGLint x, WebGLint y, WebGLsizei width, WebGLsizei height, - WebGLenum format, WebGLenum type, + void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, const Nullable &pixels, ErrorResult& rv); - void RenderbufferStorage(WebGLenum target, WebGLenum internalformat, - WebGLsizei width, WebGLsizei height); - void SampleCoverage(WebGLclampf value, WebGLboolean invert) { + void RenderbufferStorage(GLenum target, GLenum internalformat, + GLsizei width, GLsizei height); + void SampleCoverage(GLclampf value, WebGLboolean invert) { if (!IsContextStable()) return; MakeContextCurrent(); gl->fSampleCoverage(value, invert); } - void Scissor(WebGLint x, WebGLint y, WebGLsizei width, WebGLsizei height); + void Scissor(GLint x, GLint y, GLsizei width, GLsizei height); void ShaderSource(WebGLShader *shader, const nsAString& source); - void StencilFunc(WebGLenum func, WebGLint ref, WebGLuint mask); - void StencilFuncSeparate(WebGLenum face, WebGLenum func, WebGLint ref, - WebGLuint mask); - void StencilMask(WebGLuint mask); - void StencilMaskSeparate(WebGLenum face, WebGLuint mask); - void StencilOp(WebGLenum sfail, WebGLenum dpfail, WebGLenum dppass); - void StencilOpSeparate(WebGLenum face, WebGLenum sfail, WebGLenum dpfail, - WebGLenum dppass); - void TexImage2D(WebGLenum target, WebGLint level, - WebGLenum internalformat, WebGLsizei width, - WebGLsizei height, WebGLint border, WebGLenum format, - WebGLenum type, + void StencilFunc(GLenum func, GLint ref, GLuint mask); + void StencilFuncSeparate(GLenum face, GLenum func, GLint ref, + GLuint mask); + void StencilMask(GLuint mask); + void StencilMaskSeparate(GLenum face, GLuint mask); + void StencilOp(GLenum sfail, GLenum dpfail, GLenum dppass); + void StencilOpSeparate(GLenum face, GLenum sfail, GLenum dpfail, + GLenum dppass); + void TexImage2D(GLenum target, GLint level, + GLenum internalformat, GLsizei width, + GLsizei height, GLint border, GLenum format, + GLenum type, const Nullable &pixels, ErrorResult& rv); - void TexImage2D(WebGLenum target, WebGLint level, - WebGLenum internalformat, WebGLenum format, WebGLenum type, + void TexImage2D(GLenum target, GLint level, + GLenum internalformat, GLenum format, GLenum type, dom::ImageData* pixels, ErrorResult& rv); // Allow whatever element types the bindings are willing to pass // us in TexImage2D template - void TexImage2D(WebGLenum target, WebGLint level, - WebGLenum internalformat, WebGLenum format, WebGLenum type, + void TexImage2D(GLenum target, GLint level, + GLenum internalformat, GLenum format, GLenum type, ElementType& elt, ErrorResult& rv) { if (!IsContextStable()) @@ -513,28 +513,28 @@ public: 0, format, type, isurf->Data(), byteLength, -1, srcFormat, mPixelStorePremultiplyAlpha); } - void TexParameterf(WebGLenum target, WebGLenum pname, WebGLfloat param) { + void TexParameterf(GLenum target, GLenum pname, GLfloat param) { TexParameter_base(target, pname, nullptr, ¶m); } - void TexParameteri(WebGLenum target, WebGLenum pname, WebGLint param) { + void TexParameteri(GLenum target, GLenum pname, GLint param) { TexParameter_base(target, pname, ¶m, nullptr); } - void TexSubImage2D(WebGLenum target, WebGLint level, - WebGLint xoffset, WebGLint yoffset, - WebGLsizei width, WebGLsizei height, WebGLenum format, - WebGLenum type, + void TexSubImage2D(GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, GLenum format, + GLenum type, const Nullable &pixels, ErrorResult& rv); - void TexSubImage2D(WebGLenum target, WebGLint level, - WebGLint xoffset, WebGLint yoffset, WebGLenum format, - WebGLenum type, dom::ImageData* pixels, ErrorResult& rv); + void TexSubImage2D(GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLenum format, + GLenum type, dom::ImageData* pixels, ErrorResult& rv); // Allow whatever element types the bindings are willing to pass // us in TexSubImage2D template - void TexSubImage2D(WebGLenum target, WebGLint level, - WebGLint xoffset, WebGLint yoffset, WebGLenum format, - WebGLenum type, ElementType& elt, ErrorResult& rv) + void TexSubImage2D(GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLenum format, + GLenum type, ElementType& elt, ErrorResult& rv) { if (!IsContextStable()) return; @@ -555,107 +555,107 @@ public: } - void Uniform1i(WebGLUniformLocation* location, WebGLint x); - void Uniform2i(WebGLUniformLocation* location, WebGLint x, WebGLint y); - void Uniform3i(WebGLUniformLocation* location, WebGLint x, WebGLint y, - WebGLint z); - void Uniform4i(WebGLUniformLocation* location, WebGLint x, WebGLint y, - WebGLint z, WebGLint w); + void Uniform1i(WebGLUniformLocation* location, GLint x); + void Uniform2i(WebGLUniformLocation* location, GLint x, GLint y); + void Uniform3i(WebGLUniformLocation* location, GLint x, GLint y, + GLint z); + void Uniform4i(WebGLUniformLocation* location, GLint x, GLint y, + GLint z, GLint w); - void Uniform1f(WebGLUniformLocation* location, WebGLfloat x); - void Uniform2f(WebGLUniformLocation* location, WebGLfloat x, WebGLfloat y); - void Uniform3f(WebGLUniformLocation* location, WebGLfloat x, WebGLfloat y, - WebGLfloat z); - void Uniform4f(WebGLUniformLocation* location, WebGLfloat x, WebGLfloat y, - WebGLfloat z, WebGLfloat w); + void Uniform1f(WebGLUniformLocation* location, GLfloat x); + void Uniform2f(WebGLUniformLocation* location, GLfloat x, GLfloat y); + void Uniform3f(WebGLUniformLocation* location, GLfloat x, GLfloat y, + GLfloat z); + void Uniform4f(WebGLUniformLocation* location, GLfloat x, GLfloat y, + GLfloat z, GLfloat w); void Uniform1iv(WebGLUniformLocation* location, const dom::Int32Array& arr) { Uniform1iv_base(location, arr.Length(), arr.Data()); } void Uniform1iv(WebGLUniformLocation* location, - const dom::Sequence& arr) { + const dom::Sequence& arr) { Uniform1iv_base(location, arr.Length(), arr.Elements()); } void Uniform1iv_base(WebGLUniformLocation* location, uint32_t arrayLength, - const WebGLint* data); + const GLint* data); void Uniform2iv(WebGLUniformLocation* location, const dom::Int32Array& arr) { Uniform2iv_base(location, arr.Length(), arr.Data()); } void Uniform2iv(WebGLUniformLocation* location, - const dom::Sequence& arr) { + const dom::Sequence& arr) { Uniform2iv_base(location, arr.Length(), arr.Elements()); } void Uniform2iv_base(WebGLUniformLocation* location, uint32_t arrayLength, - const WebGLint* data); + const GLint* data); void Uniform3iv(WebGLUniformLocation* location, const dom::Int32Array& arr) { Uniform3iv_base(location, arr.Length(), arr.Data()); } void Uniform3iv(WebGLUniformLocation* location, - const dom::Sequence& arr) { + const dom::Sequence& arr) { Uniform3iv_base(location, arr.Length(), arr.Elements()); } void Uniform3iv_base(WebGLUniformLocation* location, uint32_t arrayLength, - const WebGLint* data); + const GLint* data); void Uniform4iv(WebGLUniformLocation* location, const dom::Int32Array& arr) { Uniform4iv_base(location, arr.Length(), arr.Data()); } void Uniform4iv(WebGLUniformLocation* location, - const dom::Sequence& arr) { + const dom::Sequence& arr) { Uniform4iv_base(location, arr.Length(), arr.Elements()); } void Uniform4iv_base(WebGLUniformLocation* location, uint32_t arrayLength, - const WebGLint* data); + const GLint* data); void Uniform1fv(WebGLUniformLocation* location, const dom::Float32Array& arr) { Uniform1fv_base(location, arr.Length(), arr.Data()); } void Uniform1fv(WebGLUniformLocation* location, - const dom::Sequence& arr) { + const dom::Sequence& arr) { Uniform1fv_base(location, arr.Length(), arr.Elements()); } void Uniform1fv_base(WebGLUniformLocation* location, uint32_t arrayLength, - const WebGLfloat* data); + const GLfloat* data); void Uniform2fv(WebGLUniformLocation* location, const dom::Float32Array& arr) { Uniform2fv_base(location, arr.Length(), arr.Data()); } void Uniform2fv(WebGLUniformLocation* location, - const dom::Sequence& arr) { + const dom::Sequence& arr) { Uniform2fv_base(location, arr.Length(), arr.Elements()); } void Uniform2fv_base(WebGLUniformLocation* location, uint32_t arrayLength, - const WebGLfloat* data); + const GLfloat* data); void Uniform3fv(WebGLUniformLocation* location, const dom::Float32Array& arr) { Uniform3fv_base(location, arr.Length(), arr.Data()); } void Uniform3fv(WebGLUniformLocation* location, - const dom::Sequence& arr) { + const dom::Sequence& arr) { Uniform3fv_base(location, arr.Length(), arr.Elements()); } void Uniform3fv_base(WebGLUniformLocation* location, uint32_t arrayLength, - const WebGLfloat* data); + const GLfloat* data); void Uniform4fv(WebGLUniformLocation* location, const dom::Float32Array& arr) { Uniform4fv_base(location, arr.Length(), arr.Data()); } void Uniform4fv(WebGLUniformLocation* location, - const dom::Sequence& arr) { + const dom::Sequence& arr) { Uniform4fv_base(location, arr.Length(), arr.Elements()); } void Uniform4fv_base(WebGLUniformLocation* location, uint32_t arrayLength, - const WebGLfloat* data); + const GLfloat* data); void UniformMatrix2fv(WebGLUniformLocation* location, WebGLboolean transpose, @@ -714,20 +714,20 @@ public: bool ValidateUniformLocation(const char* info, WebGLUniformLocation *location_object); bool ValidateSamplerUniformSetter(const char* info, WebGLUniformLocation *location, - WebGLint value); + GLint value); - void Viewport(WebGLint x, WebGLint y, WebGLsizei width, WebGLsizei height); + void Viewport(GLint x, GLint y, GLsizei width, GLsizei height); // ----------------------------------------------------------------------------- // Asynchronous Queries (WebGLContextAsyncQueries.cpp) public: already_AddRefed CreateQuery(); void DeleteQuery(WebGLQuery *query); - void BeginQuery(WebGLenum target, WebGLQuery *query); - void EndQuery(WebGLenum target); + void BeginQuery(GLenum target, WebGLQuery *query); + void EndQuery(GLenum target); bool IsQuery(WebGLQuery *query); - already_AddRefed GetQuery(WebGLenum target, WebGLenum pname); - JS::Value GetQueryObject(JSContext* cx, WebGLQuery *query, WebGLenum pname); + already_AddRefed GetQuery(GLenum target, GLenum pname); + JS::Value GetQueryObject(JSContext* cx, WebGLQuery *query, GLenum pname); private: // ANY_SAMPLES_PASSED(_CONSERVATIVE) slot @@ -736,24 +736,24 @@ private: // LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN slot WebGLRefPtr mActiveTransformFeedbackQuery; - WebGLRefPtr* GetQueryTargetSlot(WebGLenum target, const char* infos); + WebGLRefPtr* GetQueryTargetSlot(GLenum target, const char* infos); // ----------------------------------------------------------------------------- // Buffer Objects (WebGLContextBuffers.cpp) public: - void BindBuffer(WebGLenum target, WebGLBuffer* buf); - void BindBufferBase(WebGLenum target, WebGLuint index, WebGLBuffer* buffer); - void BindBufferRange(WebGLenum target, WebGLuint index, WebGLBuffer* buffer, + void BindBuffer(GLenum target, WebGLBuffer* buf); + void BindBufferBase(GLenum target, GLuint index, WebGLBuffer* buffer); + void BindBufferRange(GLenum target, GLuint index, WebGLBuffer* buffer, WebGLintptr offset, WebGLsizeiptr size); - void BufferData(WebGLenum target, WebGLsizeiptr size, WebGLenum usage); - void BufferData(WebGLenum target, const dom::ArrayBufferView &data, - WebGLenum usage); - void BufferData(WebGLenum target, + void BufferData(GLenum target, WebGLsizeiptr size, GLenum usage); + void BufferData(GLenum target, const dom::ArrayBufferView &data, + GLenum usage); + void BufferData(GLenum target, const Nullable &maybeData, - WebGLenum usage); - void BufferSubData(WebGLenum target, WebGLsizeiptr byteOffset, + GLenum usage); + void BufferSubData(GLenum target, WebGLsizeiptr byteOffset, const dom::ArrayBufferView &data); - void BufferSubData(WebGLenum target, WebGLsizeiptr byteOffset, + void BufferSubData(GLenum target, WebGLsizeiptr byteOffset, const Nullable &maybeData); already_AddRefed CreateBuffer(); void DeleteBuffer(WebGLBuffer *buf); @@ -769,16 +769,16 @@ private: // these two functions emit INVALID_ENUM for invalid `target`. WebGLRefPtr* GetBufferSlotByTarget(GLenum target, const char* infos); WebGLRefPtr* GetBufferSlotByTargetIndexed(GLenum target, GLuint index, const char* infos); - bool ValidateBufferUsageEnum(WebGLenum target, const char* infos); + bool ValidateBufferUsageEnum(GLenum target, const char* infos); // ----------------------------------------------------------------------------- // State and State Requests (WebGLContextState.cpp) public: - void Disable(WebGLenum cap); - void Enable(WebGLenum cap); - JS::Value GetParameter(JSContext* cx, WebGLenum pname, ErrorResult& rv); - JS::Value GetParameterIndexed(JSContext* cx, WebGLenum pname, WebGLuint index); - bool IsEnabled(WebGLenum cap); + void Disable(GLenum cap); + void Enable(GLenum cap); + JS::Value GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv); + JS::Value GetParameterIndexed(JSContext* cx, GLenum pname, GLuint index); + bool IsEnabled(GLenum cap); private: // State tracking slots @@ -786,64 +786,64 @@ private: realGLboolean mRasterizerDiscardEnabled; realGLboolean mScissorTestEnabled; - bool ValidateCapabilityEnum(WebGLenum cap, const char* info); - realGLboolean* GetStateTrackingSlot(WebGLenum cap); + bool ValidateCapabilityEnum(GLenum cap, const char* info); + realGLboolean* GetStateTrackingSlot(GLenum cap); // ----------------------------------------------------------------------------- // Vertices Feature (WebGLContextVertices.cpp) public: - void DrawArrays(GLenum mode, WebGLint first, WebGLsizei count); - void DrawArraysInstanced(GLenum mode, WebGLint first, WebGLsizei count, WebGLsizei primcount); - void DrawElements(WebGLenum mode, WebGLsizei count, WebGLenum type, WebGLintptr byteOffset); - void DrawElementsInstanced(WebGLenum mode, WebGLsizei count, WebGLenum type, - WebGLintptr byteOffset, WebGLsizei primcount); + void DrawArrays(GLenum mode, GLint first, GLsizei count); + void DrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei primcount); + void DrawElements(GLenum mode, GLsizei count, GLenum type, WebGLintptr byteOffset); + void DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, + WebGLintptr byteOffset, GLsizei primcount); - void EnableVertexAttribArray(WebGLuint index); - void DisableVertexAttribArray(WebGLuint index); + void EnableVertexAttribArray(GLuint index); + void DisableVertexAttribArray(GLuint index); - JS::Value GetVertexAttrib(JSContext* cx, WebGLuint index, WebGLenum pname, + JS::Value GetVertexAttrib(JSContext* cx, GLuint index, GLenum pname, ErrorResult& rv); - WebGLsizeiptr GetVertexAttribOffset(WebGLuint index, WebGLenum pname); + WebGLsizeiptr GetVertexAttribOffset(GLuint index, GLenum pname); - void VertexAttrib1f(WebGLuint index, WebGLfloat x0); - void VertexAttrib2f(WebGLuint index, WebGLfloat x0, WebGLfloat x1); - void VertexAttrib3f(WebGLuint index, WebGLfloat x0, WebGLfloat x1, - WebGLfloat x2); - void VertexAttrib4f(WebGLuint index, WebGLfloat x0, WebGLfloat x1, - WebGLfloat x2, WebGLfloat x3); + void VertexAttrib1f(GLuint index, GLfloat x0); + void VertexAttrib2f(GLuint index, GLfloat x0, GLfloat x1); + void VertexAttrib3f(GLuint index, GLfloat x0, GLfloat x1, + GLfloat x2); + void VertexAttrib4f(GLuint index, GLfloat x0, GLfloat x1, + GLfloat x2, GLfloat x3); - void VertexAttrib1fv(WebGLuint idx, const dom::Float32Array &arr) { + void VertexAttrib1fv(GLuint idx, const dom::Float32Array &arr) { VertexAttrib1fv_base(idx, arr.Length(), arr.Data()); } - void VertexAttrib1fv(WebGLuint idx, const dom::Sequence& arr) { + void VertexAttrib1fv(GLuint idx, const dom::Sequence& arr) { VertexAttrib1fv_base(idx, arr.Length(), arr.Elements()); } - void VertexAttrib2fv(WebGLuint idx, const dom::Float32Array &arr) { + void VertexAttrib2fv(GLuint idx, const dom::Float32Array &arr) { VertexAttrib2fv_base(idx, arr.Length(), arr.Data()); } - void VertexAttrib2fv(WebGLuint idx, const dom::Sequence& arr) { + void VertexAttrib2fv(GLuint idx, const dom::Sequence& arr) { VertexAttrib2fv_base(idx, arr.Length(), arr.Elements()); } - void VertexAttrib3fv(WebGLuint idx, const dom::Float32Array &arr) { + void VertexAttrib3fv(GLuint idx, const dom::Float32Array &arr) { VertexAttrib3fv_base(idx, arr.Length(), arr.Data()); } - void VertexAttrib3fv(WebGLuint idx, const dom::Sequence& arr) { + void VertexAttrib3fv(GLuint idx, const dom::Sequence& arr) { VertexAttrib3fv_base(idx, arr.Length(), arr.Elements()); } - void VertexAttrib4fv(WebGLuint idx, const dom::Float32Array &arr) { + void VertexAttrib4fv(GLuint idx, const dom::Float32Array &arr) { VertexAttrib4fv_base(idx, arr.Length(), arr.Data()); } - void VertexAttrib4fv(WebGLuint idx, const dom::Sequence& arr) { + void VertexAttrib4fv(GLuint idx, const dom::Sequence& arr) { VertexAttrib4fv_base(idx, arr.Length(), arr.Elements()); } - void VertexAttribPointer(WebGLuint index, WebGLint size, WebGLenum type, - WebGLboolean normalized, WebGLsizei stride, + void VertexAttribPointer(GLuint index, GLint size, GLenum type, + WebGLboolean normalized, GLsizei stride, WebGLintptr byteOffset); - void VertexAttribDivisor(WebGLuint index, WebGLuint divisor); + void VertexAttribDivisor(GLuint index, GLuint divisor); private: // Cache the max number of vertices and instances that can be read from @@ -861,15 +861,15 @@ private: mMaxFetchedInstances = 0; } - bool DrawArrays_check(WebGLint first, WebGLsizei count, WebGLsizei primcount, const char* info); - bool DrawElements_check(WebGLsizei count, WebGLenum type, WebGLintptr byteOffset, - WebGLsizei primcount, const char* info); + bool DrawArrays_check(GLint first, GLsizei count, GLsizei primcount, const char* info); + bool DrawElements_check(GLsizei count, GLenum type, WebGLintptr byteOffset, + GLsizei primcount, const char* info); void Draw_cleanup(); - void VertexAttrib1fv_base(WebGLuint idx, uint32_t arrayLength, const WebGLfloat* ptr); - void VertexAttrib2fv_base(WebGLuint idx, uint32_t arrayLength, const WebGLfloat* ptr); - void VertexAttrib3fv_base(WebGLuint idx, uint32_t arrayLength, const WebGLfloat* ptr); - void VertexAttrib4fv_base(WebGLuint idx, uint32_t arrayLength, const WebGLfloat* ptr); + void VertexAttrib1fv_base(GLuint idx, uint32_t arrayLength, const GLfloat* ptr); + void VertexAttrib2fv_base(GLuint idx, uint32_t arrayLength, const GLfloat* ptr); + void VertexAttrib3fv_base(GLuint idx, uint32_t arrayLength, const GLfloat* ptr); + void VertexAttrib4fv_base(GLuint idx, uint32_t arrayLength, const GLfloat* ptr); bool ValidateBufferFetching(const char *info); bool BindArrayAttribToLocation0(WebGLProgram *program); @@ -886,12 +886,12 @@ protected: void UnbindFakeBlackTextures(); int WhatDoesVertexAttrib0Need(); - bool DoFakeVertexAttrib0(WebGLuint vertexCount); + bool DoFakeVertexAttrib0(GLuint vertexCount); void UndoFakeVertexAttrib0(); void InvalidateFakeVertexAttrib0(); - static CheckedUint32 GetImageSize(WebGLsizei height, - WebGLsizei width, + static CheckedUint32 GetImageSize(GLsizei height, + GLsizei width, uint32_t pixelSize, uint32_t alignment); @@ -922,8 +922,8 @@ protected: template void DeleteWebGLObjectsArray(nsTArray& array); - WebGLuint mActiveTexture; - WebGLenum mWebGLError; + GLuint mActiveTexture; + GLenum mWebGLError; // whether shader validation is supported bool mShaderValidation; @@ -996,7 +996,7 @@ protected: static const char* GetExtensionString(WebGLExtensionID ext); - nsTArray mCompressedTextureFormats; + nsTArray mCompressedTextureFormats; // ------------------------------------------------------------------------- @@ -1010,29 +1010,29 @@ protected: // ------------------------------------------------------------------------- // Validation functions (implemented in WebGLContextValidate.cpp) bool InitAndValidateGL(); - bool ValidateBlendEquationEnum(WebGLenum cap, const char *info); - bool ValidateBlendFuncDstEnum(WebGLenum mode, const char *info); - bool ValidateBlendFuncSrcEnum(WebGLenum mode, const char *info); - bool ValidateBlendFuncEnumsCompatibility(WebGLenum sfactor, WebGLenum dfactor, const char *info); - bool ValidateTextureTargetEnum(WebGLenum target, const char *info); - bool ValidateComparisonEnum(WebGLenum target, const char *info); - bool ValidateStencilOpEnum(WebGLenum action, const char *info); - bool ValidateFaceEnum(WebGLenum face, const char *info); - bool ValidateTexFormatAndType(WebGLenum format, WebGLenum type, int jsArrayType, + bool ValidateBlendEquationEnum(GLenum cap, const char *info); + bool ValidateBlendFuncDstEnum(GLenum mode, const char *info); + bool ValidateBlendFuncSrcEnum(GLenum mode, const char *info); + bool ValidateBlendFuncEnumsCompatibility(GLenum sfactor, GLenum dfactor, const char *info); + bool ValidateTextureTargetEnum(GLenum target, const char *info); + bool ValidateComparisonEnum(GLenum target, const char *info); + bool ValidateStencilOpEnum(GLenum action, const char *info); + bool ValidateFaceEnum(GLenum face, const char *info); + bool ValidateTexFormatAndType(GLenum format, GLenum type, int jsArrayType, uint32_t *texelSize, const char *info); - bool ValidateDrawModeEnum(WebGLenum mode, const char *info); - bool ValidateAttribIndex(WebGLuint index, const char *info); + bool ValidateDrawModeEnum(GLenum mode, const char *info); + bool ValidateAttribIndex(GLuint index, const char *info); bool ValidateStencilParamsForDrawCall(); bool ValidateGLSLVariableName(const nsAString& name, const char *info); bool ValidateGLSLCharacter(PRUnichar c); bool ValidateGLSLString(const nsAString& string, const char *info); - bool ValidateTexImage2DTarget(WebGLenum target, WebGLsizei width, WebGLsizei height, const char* info); - bool ValidateCompressedTextureSize(WebGLenum target, WebGLint level, WebGLenum format, WebGLsizei width, WebGLsizei height, uint32_t byteLength, const char* info); - bool ValidateLevelWidthHeightForTarget(WebGLenum target, WebGLint level, WebGLsizei width, WebGLsizei height, const char* info); + bool ValidateTexImage2DTarget(GLenum target, GLsizei width, GLsizei height, const char* info); + bool ValidateCompressedTextureSize(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, uint32_t byteLength, const char* info); + bool ValidateLevelWidthHeightForTarget(GLenum target, GLint level, GLsizei width, GLsizei height, const char* info); - static uint32_t GetBitsPerTexel(WebGLenum format, WebGLenum type); + static uint32_t GetBitsPerTexel(GLenum format, GLenum type); void Invalidate(); void DestroyResourcesAndContext(); @@ -1040,21 +1040,21 @@ protected: void MakeContextCurrent() const { gl->MakeCurrent(); } // helpers - void TexImage2D_base(WebGLenum target, WebGLint level, WebGLenum internalformat, - WebGLsizei width, WebGLsizei height, WebGLsizei srcStrideOrZero, WebGLint border, - WebGLenum format, WebGLenum type, + void TexImage2D_base(GLenum target, GLint level, GLenum internalformat, + GLsizei width, GLsizei height, GLsizei srcStrideOrZero, GLint border, + GLenum format, GLenum type, void *data, uint32_t byteLength, int jsArrayType, WebGLTexelFormat srcFormat, bool srcPremultiplied); - void TexSubImage2D_base(WebGLenum target, WebGLint level, - WebGLint xoffset, WebGLint yoffset, - WebGLsizei width, WebGLsizei height, WebGLsizei srcStrideOrZero, - WebGLenum format, WebGLenum type, + void TexSubImage2D_base(GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, GLsizei srcStrideOrZero, + GLenum format, GLenum type, void *pixels, uint32_t byteLength, int jsArrayType, WebGLTexelFormat srcFormat, bool srcPremultiplied); - void TexParameter_base(WebGLenum target, WebGLenum pname, - WebGLint *intParamPtr, WebGLfloat *floatParamPtr); + void TexParameter_base(GLenum target, GLenum pname, + GLint *intParamPtr, GLfloat *floatParamPtr); void ConvertImage(size_t width, size_t height, size_t srcStride, size_t dstStride, const uint8_t* src, uint8_t *dst, @@ -1084,15 +1084,15 @@ protected: gfxImageSurface **imageOut, WebGLTexelFormat *format); - void CopyTexSubImage2D_base(WebGLenum target, - WebGLint level, - WebGLenum internalformat, - WebGLint xoffset, - WebGLint yoffset, - WebGLint x, - WebGLint y, - WebGLsizei width, - WebGLsizei height, + void CopyTexSubImage2D_base(GLenum target, + GLint level, + GLenum internalformat, + GLint xoffset, + GLint yoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height, bool sub); // Returns false if aObject is null or not valid @@ -1116,7 +1116,7 @@ private: bool ValidateObjectAssumeNonNull(const char* info, ObjectType *aObject); protected: - int32_t MaxTextureSizeForTarget(WebGLenum target) const { + int32_t MaxTextureSizeForTarget(GLenum target) const { return target == LOCAL_GL_TEXTURE_2D ? mGLMaxTextureSize : mGLMaxCubeMapTextureSize; } @@ -1173,23 +1173,23 @@ protected: FakeBlackStatus mFakeBlackStatus; - WebGLuint mBlackTexture2D, mBlackTextureCubeMap; + GLuint mBlackTexture2D, mBlackTextureCubeMap; bool mBlackTexturesAreInitialized; - WebGLfloat mVertexAttrib0Vector[4]; - WebGLfloat mFakeVertexAttrib0BufferObjectVector[4]; + GLfloat mVertexAttrib0Vector[4]; + GLfloat mFakeVertexAttrib0BufferObjectVector[4]; size_t mFakeVertexAttrib0BufferObjectSize; GLuint mFakeVertexAttrib0BufferObject; int mFakeVertexAttrib0BufferStatus; - WebGLint mStencilRefFront, mStencilRefBack; - WebGLuint mStencilValueMaskFront, mStencilValueMaskBack, + GLint mStencilRefFront, mStencilRefBack; + GLuint mStencilValueMaskFront, mStencilValueMaskBack, mStencilWriteMaskFront, mStencilWriteMaskBack; realGLboolean mColorWriteMask[4]; realGLboolean mDepthWriteMask; - WebGLfloat mColorClearValue[4]; - WebGLint mStencilClearValue; - WebGLfloat mDepthClearValue; + GLfloat mColorClearValue[4]; + GLint mStencilClearValue; + GLfloat mDepthClearValue; nsCOMPtr mContextRestorer; bool mAllowRestore; @@ -1224,7 +1224,7 @@ protected: template JSObject* WebGLObjectAsJSObject(JSContext *cx, const WebGLObjectType *, ErrorResult& rv) const; - void ReattachTextureToAnyFramebufferToWorkAroundBugs(WebGLTexture *tex, WebGLint level); + void ReattachTextureToAnyFramebufferToWorkAroundBugs(WebGLTexture *tex, GLint level); #ifdef XP_MACOSX // see bug 713305. This RAII helper guarantees that we're on the discrete GPU, during its lifetime diff --git a/content/canvas/src/WebGLContextAsyncQueries.cpp b/content/canvas/src/WebGLContextAsyncQueries.cpp index 447fa0f38f4..ae20a568761 100644 --- a/content/canvas/src/WebGLContextAsyncQueries.cpp +++ b/content/canvas/src/WebGLContextAsyncQueries.cpp @@ -19,7 +19,7 @@ using namespace mozilla; */ static const char* -GetQueryTargetEnumString(WebGLenum target) +GetQueryTargetEnumString(GLenum target) { switch (target) { @@ -108,7 +108,7 @@ WebGLContext::DeleteQuery(WebGLQuery *query) } void -WebGLContext::BeginQuery(WebGLenum target, WebGLQuery *query) +WebGLContext::BeginQuery(GLenum target, WebGLQuery *query) { if (!IsContextStable()) return; @@ -178,7 +178,7 @@ WebGLContext::BeginQuery(WebGLenum target, WebGLQuery *query) } void -WebGLContext::EndQuery(WebGLenum target) +WebGLContext::EndQuery(GLenum target) { if (!IsContextStable()) return; @@ -234,7 +234,7 @@ WebGLContext::IsQuery(WebGLQuery *query) } already_AddRefed -WebGLContext::GetQuery(WebGLenum target, WebGLenum pname) +WebGLContext::GetQuery(GLenum target, GLenum pname) { if (!IsContextStable()) return nullptr; @@ -257,7 +257,7 @@ WebGLContext::GetQuery(WebGLenum target, WebGLenum pname) } JS::Value -WebGLContext::GetQueryObject(JSContext* cx, WebGLQuery *query, WebGLenum pname) +WebGLContext::GetQueryObject(JSContext* cx, WebGLQuery *query, GLenum pname) { if (!IsContextStable()) return JS::NullValue(); @@ -333,7 +333,7 @@ WebGLContext::GetQueryObject(JSContext* cx, WebGLQuery *query, WebGLenum pname) } WebGLRefPtr* -WebGLContext::GetQueryTargetSlot(WebGLenum target, const char* infos) +WebGLContext::GetQueryTargetSlot(GLenum target, const char* infos) { switch (target) { case LOCAL_GL_ANY_SAMPLES_PASSED: diff --git a/content/canvas/src/WebGLContextBuffers.cpp b/content/canvas/src/WebGLContextBuffers.cpp index 6909e332b5a..3174360d587 100644 --- a/content/canvas/src/WebGLContextBuffers.cpp +++ b/content/canvas/src/WebGLContextBuffers.cpp @@ -11,7 +11,7 @@ using namespace mozilla; using namespace mozilla::dom; void -WebGLContext::BindBuffer(WebGLenum target, WebGLBuffer *buffer) +WebGLContext::BindBuffer(GLenum target, WebGLBuffer *buffer) { if (!IsContextStable()) return; @@ -46,7 +46,7 @@ WebGLContext::BindBuffer(WebGLenum target, WebGLBuffer *buffer) } void -WebGLContext::BindBufferBase(WebGLenum target, WebGLuint index, WebGLBuffer* buffer) +WebGLContext::BindBufferBase(GLenum target, GLuint index, WebGLBuffer* buffer) { if (!IsContextStable()) return; @@ -87,7 +87,7 @@ WebGLContext::BindBufferBase(WebGLenum target, WebGLuint index, WebGLBuffer* buf } void -WebGLContext::BindBufferRange(WebGLenum target, WebGLuint index, WebGLBuffer* buffer, +WebGLContext::BindBufferRange(GLenum target, GLuint index, WebGLBuffer* buffer, WebGLintptr offset, WebGLsizeiptr size) { if (!IsContextStable()) @@ -134,8 +134,8 @@ WebGLContext::BindBufferRange(WebGLenum target, WebGLuint index, WebGLBuffer* bu } void -WebGLContext::BufferData(WebGLenum target, WebGLsizeiptr size, - WebGLenum usage) +WebGLContext::BufferData(GLenum target, WebGLsizeiptr size, + GLenum usage) { if (!IsContextStable()) return; @@ -183,9 +183,9 @@ WebGLContext::BufferData(WebGLenum target, WebGLsizeiptr size, } void -WebGLContext::BufferData(WebGLenum target, +WebGLContext::BufferData(GLenum target, const Nullable &maybeData, - WebGLenum usage) + GLenum usage) { if (!IsContextStable()) return; @@ -232,8 +232,8 @@ WebGLContext::BufferData(WebGLenum target, } void -WebGLContext::BufferData(WebGLenum target, const ArrayBufferView& data, - WebGLenum usage) +WebGLContext::BufferData(GLenum target, const ArrayBufferView& data, + GLenum usage) { if (!IsContextStable()) return; @@ -315,7 +315,7 @@ WebGLContext::BufferSubData(GLenum target, WebGLsizeiptr byteOffset, } void -WebGLContext::BufferSubData(WebGLenum target, WebGLsizeiptr byteOffset, +WebGLContext::BufferSubData(GLenum target, WebGLsizeiptr byteOffset, const ArrayBufferView& data) { if (!IsContextStable()) @@ -401,7 +401,7 @@ WebGLContext::IsBuffer(WebGLBuffer *buffer) } bool -WebGLContext::ValidateBufferUsageEnum(WebGLenum target, const char *infos) +WebGLContext::ValidateBufferUsageEnum(GLenum target, const char *infos) { switch (target) { case LOCAL_GL_STREAM_DRAW: diff --git a/content/canvas/src/WebGLContextFramebufferOperations.cpp b/content/canvas/src/WebGLContextFramebufferOperations.cpp index a920c6bfdfb..cadbbb704e4 100644 --- a/content/canvas/src/WebGLContextFramebufferOperations.cpp +++ b/content/canvas/src/WebGLContextFramebufferOperations.cpp @@ -11,7 +11,7 @@ using namespace mozilla; void -WebGLContext::Clear(WebGLbitfield mask) +WebGLContext::Clear(GLbitfield mask) { if (!IsContextStable()) return; @@ -76,8 +76,8 @@ WebGLContext::Clear(WebGLbitfield mask) mShouldPresent = true; } -static WebGLclampf -GLClampFloat(WebGLclampf val) +static GLclampf +GLClampFloat(GLclampf val) { if (val < 0.0) return 0.0; @@ -89,8 +89,8 @@ GLClampFloat(WebGLclampf val) } void -WebGLContext::ClearColor(WebGLclampf r, WebGLclampf g, - WebGLclampf b, WebGLclampf a) +WebGLContext::ClearColor(GLclampf r, GLclampf g, + GLclampf b, GLclampf a) { if (!IsContextStable()) return; @@ -104,7 +104,7 @@ WebGLContext::ClearColor(WebGLclampf r, WebGLclampf g, } void -WebGLContext::ClearDepth(WebGLclampf v) +WebGLContext::ClearDepth(GLclampf v) { if (!IsContextStable()) return; @@ -115,7 +115,7 @@ WebGLContext::ClearDepth(WebGLclampf v) } void -WebGLContext::ClearStencil(WebGLint v) +WebGLContext::ClearStencil(GLint v) { if (!IsContextStable()) return; @@ -227,7 +227,7 @@ WebGLContext::DrawBuffers(const dom::Sequence& buffers) } void -WebGLContext::StencilMask(WebGLuint mask) +WebGLContext::StencilMask(GLuint mask) { if (!IsContextStable()) return; @@ -240,7 +240,7 @@ WebGLContext::StencilMask(WebGLuint mask) } void -WebGLContext::StencilMaskSeparate(WebGLenum face, WebGLuint mask) +WebGLContext::StencilMaskSeparate(GLenum face, GLuint mask) { if (!IsContextStable()) return; diff --git a/content/canvas/src/WebGLContextGL.cpp b/content/canvas/src/WebGLContextGL.cpp index 85093176f8c..6eccaa021e2 100644 --- a/content/canvas/src/WebGLContextGL.cpp +++ b/content/canvas/src/WebGLContextGL.cpp @@ -48,8 +48,8 @@ using namespace mozilla; using namespace mozilla::dom; using namespace mozilla::gl; -static bool BaseTypeAndSizeFromUniformType(WebGLenum uType, WebGLenum *baseType, WebGLint *unitSize); -static WebGLenum InternalFormatForFormatAndType(WebGLenum format, WebGLenum type, bool isGLES2); +static bool BaseTypeAndSizeFromUniformType(GLenum uType, GLenum *baseType, GLint *unitSize); +static GLenum InternalFormatForFormatAndType(GLenum format, GLenum type, bool isGLES2); // // WebGL API @@ -61,7 +61,7 @@ inline const WebGLRectangleObject *WebGLContext::FramebufferRectangleObject() co } void -WebGLContext::ActiveTexture(WebGLenum texture) +WebGLContext::ActiveTexture(GLenum texture) { if (!IsContextStable()) return; @@ -103,7 +103,7 @@ WebGLContext::AttachShader(WebGLProgram *program, WebGLShader *shader) void -WebGLContext::BindAttribLocation(WebGLProgram *prog, WebGLuint location, +WebGLContext::BindAttribLocation(WebGLProgram *prog, GLuint location, const nsAString& name) { if (!IsContextStable()) @@ -112,7 +112,7 @@ WebGLContext::BindAttribLocation(WebGLProgram *prog, WebGLuint location, if (!ValidateObject("bindAttribLocation: program", prog)) return; - WebGLuint progname = prog->GLName(); + GLuint progname = prog->GLName(); if (!ValidateGLSLVariableName(name, "bindAttribLocation")) return; @@ -129,7 +129,7 @@ WebGLContext::BindAttribLocation(WebGLProgram *prog, WebGLuint location, } void -WebGLContext::BindFramebuffer(WebGLenum target, WebGLFramebuffer *wfb) +WebGLContext::BindFramebuffer(GLenum target, WebGLFramebuffer *wfb) { if (!IsContextStable()) return; @@ -149,7 +149,7 @@ WebGLContext::BindFramebuffer(WebGLenum target, WebGLFramebuffer *wfb) if (!wfb) { gl->fBindFramebuffer(target, 0); } else { - WebGLuint framebuffername = wfb->GLName(); + GLuint framebuffername = wfb->GLName(); gl->fBindFramebuffer(target, framebuffername); wfb->SetHasEverBeenBound(true); } @@ -158,7 +158,7 @@ WebGLContext::BindFramebuffer(WebGLenum target, WebGLFramebuffer *wfb) } void -WebGLContext::BindRenderbuffer(WebGLenum target, WebGLRenderbuffer *wrb) +WebGLContext::BindRenderbuffer(GLenum target, WebGLRenderbuffer *wrb) { if (!IsContextStable()) return; @@ -178,14 +178,14 @@ WebGLContext::BindRenderbuffer(WebGLenum target, WebGLRenderbuffer *wrb) MakeContextCurrent(); - WebGLuint renderbuffername = wrb ? wrb->GLName() : 0; + GLuint renderbuffername = wrb ? wrb->GLName() : 0; gl->fBindRenderbuffer(target, renderbuffername); mBoundRenderbuffer = wrb; } void -WebGLContext::BindTexture(WebGLenum target, WebGLTexture *tex) +WebGLContext::BindTexture(GLenum target, WebGLTexture *tex) { if (!IsContextStable()) return; @@ -214,7 +214,7 @@ WebGLContext::BindTexture(WebGLenum target, WebGLTexture *tex) gl->fBindTexture(target, 0 /* == texturename */); } -void WebGLContext::BlendEquation(WebGLenum mode) +void WebGLContext::BlendEquation(GLenum mode) { if (!IsContextStable()) return; @@ -226,7 +226,7 @@ void WebGLContext::BlendEquation(WebGLenum mode) gl->fBlendEquation(mode); } -void WebGLContext::BlendEquationSeparate(WebGLenum modeRGB, WebGLenum modeAlpha) +void WebGLContext::BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) { if (!IsContextStable()) return; @@ -239,7 +239,7 @@ void WebGLContext::BlendEquationSeparate(WebGLenum modeRGB, WebGLenum modeAlpha) gl->fBlendEquationSeparate(modeRGB, modeAlpha); } -void WebGLContext::BlendFunc(WebGLenum sfactor, WebGLenum dfactor) +void WebGLContext::BlendFunc(GLenum sfactor, GLenum dfactor) { if (!IsContextStable()) return; @@ -256,8 +256,8 @@ void WebGLContext::BlendFunc(WebGLenum sfactor, WebGLenum dfactor) } void -WebGLContext::BlendFuncSeparate(WebGLenum srcRGB, WebGLenum dstRGB, - WebGLenum srcAlpha, WebGLenum dstAlpha) +WebGLContext::BlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, + GLenum srcAlpha, GLenum dstAlpha) { if (!IsContextStable()) return; @@ -312,8 +312,8 @@ GLenum WebGLContext::CheckedBufferData(GLenum target, } } -WebGLenum -WebGLContext::CheckFramebufferStatus(WebGLenum target) +GLenum +WebGLContext::CheckFramebufferStatus(GLenum target) { if (!IsContextStable()) { @@ -363,20 +363,20 @@ WebGLContext::CheckFramebufferStatus(WebGLenum target) } void -WebGLContext::CopyTexSubImage2D_base(WebGLenum target, - WebGLint level, - WebGLenum internalformat, - WebGLint xoffset, - WebGLint yoffset, - WebGLint x, - WebGLint y, - WebGLsizei width, - WebGLsizei height, +WebGLContext::CopyTexSubImage2D_base(GLenum target, + GLint level, + GLenum internalformat, + GLint xoffset, + GLint yoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height, bool sub) { const WebGLRectangleObject *framebufferRect = FramebufferRectangleObject(); - WebGLsizei framebufferWidth = framebufferRect ? framebufferRect->Width() : 0; - WebGLsizei framebufferHeight = framebufferRect ? framebufferRect->Height() : 0; + GLsizei framebufferWidth = framebufferRect ? framebufferRect->Width() : 0; + GLsizei framebufferHeight = framebufferRect ? framebufferRect->Height() : 0; const char *info = sub ? "copyTexSubImage2D" : "copyTexImage2D"; @@ -463,14 +463,14 @@ WebGLContext::CopyTexSubImage2D_base(WebGLenum target, } void -WebGLContext::CopyTexImage2D(WebGLenum target, - WebGLint level, - WebGLenum internalformat, - WebGLint x, - WebGLint y, - WebGLsizei width, - WebGLsizei height, - WebGLint border) +WebGLContext::CopyTexImage2D(GLenum target, + GLint level, + GLenum internalformat, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLint border) { if (!IsContextStable()) return; @@ -509,7 +509,7 @@ WebGLContext::CopyTexImage2D(WebGLenum target, if (level < 0) return ErrorInvalidValue("copyTexImage2D: level may not be negative"); - WebGLsizei maxTextureSize = MaxTextureSizeForTarget(target); + GLsizei maxTextureSize = MaxTextureSizeForTarget(target); if (!(maxTextureSize >> level)) return ErrorInvalidValue("copyTexImage2D: 2^level exceeds maximum texture size"); @@ -572,14 +572,14 @@ WebGLContext::CopyTexImage2D(WebGLenum target, } void -WebGLContext::CopyTexSubImage2D(WebGLenum target, - WebGLint level, - WebGLint xoffset, - WebGLint yoffset, - WebGLint x, - WebGLint y, - WebGLsizei width, - WebGLsizei height) +WebGLContext::CopyTexSubImage2D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height) { if (!IsContextStable()) return; @@ -600,7 +600,7 @@ WebGLContext::CopyTexSubImage2D(WebGLenum target, if (level < 0) return ErrorInvalidValue("copyTexSubImage2D: level may not be negative"); - WebGLsizei maxTextureSize = MaxTextureSizeForTarget(target); + GLsizei maxTextureSize = MaxTextureSizeForTarget(target); if (!(maxTextureSize >> level)) return ErrorInvalidValue("copyTexSubImage2D: 2^level exceeds maximum texture size"); @@ -614,13 +614,13 @@ WebGLContext::CopyTexSubImage2D(WebGLenum target, if (!tex) return ErrorInvalidOperation("copyTexSubImage2D: no texture bound to this target"); - WebGLint face = WebGLTexture::FaceForTarget(target); + GLint face = WebGLTexture::FaceForTarget(target); if (!tex->HasImageInfoAt(level, face)) return ErrorInvalidOperation("copyTexSubImage2D: no texture image previously defined for this level and face"); const WebGLTexture::ImageInfo &imageInfo = tex->ImageInfoAt(level, face); - WebGLsizei texWidth = imageInfo.Width(); - WebGLsizei texHeight = imageInfo.Height(); + GLsizei texWidth = imageInfo.Width(); + GLsizei texHeight = imageInfo.Height(); if (xoffset + width > texWidth || xoffset + width < 0) return ErrorInvalidValue("copyTexSubImage2D: xoffset+width is too large"); @@ -628,7 +628,7 @@ WebGLContext::CopyTexSubImage2D(WebGLenum target, if (yoffset + height > texHeight || yoffset + height < 0) return ErrorInvalidValue("copyTexSubImage2D: yoffset+height is too large"); - WebGLenum format = imageInfo.Format(); + GLenum format = imageInfo.Format(); bool texFormatRequiresAlpha = format == LOCAL_GL_RGBA || format == LOCAL_GL_ALPHA || format == LOCAL_GL_LUMINANCE_ALPHA; @@ -661,7 +661,7 @@ WebGLContext::CreateProgram() } already_AddRefed -WebGLContext::CreateShader(WebGLenum type) +WebGLContext::CreateShader(GLenum type) { if (!IsContextStable()) return nullptr; @@ -678,7 +678,7 @@ WebGLContext::CreateShader(WebGLenum type) } void -WebGLContext::CullFace(WebGLenum face) +WebGLContext::CullFace(GLenum face) { if (!IsContextStable()) return; @@ -746,7 +746,7 @@ WebGLContext::DeleteTexture(WebGLTexture *tex) if (mBoundFramebuffer) mBoundFramebuffer->DetachTexture(tex); - WebGLuint activeTexture = mActiveTexture; + GLuint activeTexture = mActiveTexture; for (int32_t i = 0; i < mGLMaxTextureUnits; i++) { if ((tex->Target() == LOCAL_GL_TEXTURE_2D && mBound2DTextures[i] == tex) || (tex->Target() == LOCAL_GL_TEXTURE_CUBE_MAP && mBoundCubeMapTextures[i] == tex)) @@ -807,7 +807,7 @@ WebGLContext::DetachShader(WebGLProgram *program, WebGLShader *shader) } void -WebGLContext::DepthFunc(WebGLenum func) +WebGLContext::DepthFunc(GLenum func) { if (!IsContextStable()) return; @@ -820,7 +820,7 @@ WebGLContext::DepthFunc(WebGLenum func) } void -WebGLContext::DepthRange(WebGLfloat zNear, WebGLfloat zFar) +WebGLContext::DepthRange(GLfloat zNear, GLfloat zFar) { if (!IsContextStable()) return; @@ -853,7 +853,7 @@ WebGLContext::WhatDoesVertexAttrib0Need() } bool -WebGLContext::DoFakeVertexAttrib0(WebGLuint vertexCount) +WebGLContext::DoFakeVertexAttrib0(GLuint vertexCount) { int whatDoesAttrib0Need = WhatDoesVertexAttrib0Need(); @@ -869,7 +869,7 @@ WebGLContext::DoFakeVertexAttrib0(WebGLuint vertexCount) mAlreadyWarnedAboutFakeVertexAttrib0 = true; } - CheckedUint32 checked_dataSize = CheckedUint32(vertexCount) * 4 * sizeof(WebGLfloat); + CheckedUint32 checked_dataSize = CheckedUint32(vertexCount) * 4 * sizeof(GLfloat); if (!checked_dataSize.isValid()) { ErrorOutOfMemory("Integer overflow trying to construct a fake vertex attrib 0 array for a draw-operation " @@ -877,7 +877,7 @@ WebGLContext::DoFakeVertexAttrib0(WebGLuint vertexCount) return false; } - WebGLuint dataSize = checked_dataSize.value(); + GLuint dataSize = checked_dataSize.value(); if (!mFakeVertexAttrib0BufferObject) { gl->fGenBuffers(1, &mFakeVertexAttrib0BufferObject); @@ -910,7 +910,7 @@ WebGLContext::DoFakeVertexAttrib0(WebGLuint vertexCount) UpdateWebGLErrorAndClearGLError(); if (mFakeVertexAttrib0BufferStatus == VertexAttrib0Status::EmulatedInitializedArray) { - nsAutoArrayPtr array(new WebGLfloat[4 * vertexCount]); + nsAutoArrayPtr array(new GLfloat[4 * vertexCount]); for(size_t i = 0; i < vertexCount; ++i) { array[4 * i + 0] = mVertexAttrib0Vector[0]; array[4 * i + 1] = mVertexAttrib0Vector[1]; @@ -1005,7 +1005,7 @@ WebGLContext::BindFakeBlackTextures() gl->fGenTextures(1, &mBlackTextureCubeMap); gl->fBindTexture(LOCAL_GL_TEXTURE_CUBE_MAP, mBlackTextureCubeMap); - for (WebGLuint i = 0; i < 6; ++i) { + for (GLuint i = 0; i < 6; ++i) { gl->fTexImage2D(LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, LOCAL_GL_RGBA, 1, 1, 0, LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE, &black); } @@ -1051,7 +1051,7 @@ WebGLContext::UnbindFakeBlackTextures() } void -WebGLContext::FramebufferRenderbuffer(WebGLenum target, WebGLenum attachment, WebGLenum rbtarget, WebGLRenderbuffer *wrb) +WebGLContext::FramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum rbtarget, WebGLRenderbuffer *wrb) { if (!IsContextStable()) return; @@ -1063,11 +1063,11 @@ WebGLContext::FramebufferRenderbuffer(WebGLenum target, WebGLenum attachment, We } void -WebGLContext::FramebufferTexture2D(WebGLenum target, - WebGLenum attachment, - WebGLenum textarget, +WebGLContext::FramebufferTexture2D(GLenum target, + GLenum attachment, + GLenum textarget, WebGLTexture *tobj, - WebGLint level) + GLint level) { if (!IsContextStable()) return; @@ -1079,7 +1079,7 @@ WebGLContext::FramebufferTexture2D(WebGLenum target, } void -WebGLContext::FrontFace(WebGLenum mode) +WebGLContext::FrontFace(GLenum mode) { if (!IsContextStable()) return; @@ -1108,7 +1108,7 @@ WebGLContext::GetActiveAttrib(WebGLProgram *prog, uint32_t index) MakeContextCurrent(); GLint len = 0; - WebGLuint progname = prog->GLName();; + GLuint progname = prog->GLName();; gl->fGetProgramiv(progname, LOCAL_GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &len); if (len == 0) return nullptr; @@ -1131,7 +1131,7 @@ WebGLContext::GetActiveAttrib(WebGLProgram *prog, uint32_t index) } void -WebGLContext::GenerateMipmap(WebGLenum target) +WebGLContext::GenerateMipmap(GLenum target) { if (!IsContextStable()) return; @@ -1193,7 +1193,7 @@ WebGLContext::GetActiveUniform(WebGLProgram *prog, uint32_t index) MakeContextCurrent(); GLint len = 0; - WebGLuint progname = prog->GLName(); + GLuint progname = prog->GLName(); gl->fGetProgramiv(progname, LOCAL_GL_ACTIVE_UNIFORM_MAX_LENGTH, &len); if (len == 0) return nullptr; @@ -1255,7 +1255,7 @@ WebGLContext::GetAttachedShaders(WebGLProgram *prog, } } -WebGLint +GLint WebGLContext::GetAttribLocation(WebGLProgram *prog, const nsAString& name) { if (!IsContextStable()) @@ -1271,14 +1271,14 @@ WebGLContext::GetAttribLocation(WebGLProgram *prog, const nsAString& name) nsCString mappedName; prog->MapIdentifier(cname, &mappedName); - WebGLuint progname = prog->GLName(); + GLuint progname = prog->GLName(); MakeContextCurrent(); return gl->fGetAttribLocation(progname, mappedName.get()); } JS::Value -WebGLContext::GetBufferParameter(WebGLenum target, WebGLenum pname) +WebGLContext::GetBufferParameter(GLenum target, GLenum pname) { if (!IsContextStable()) return JS::NullValue(); @@ -1314,9 +1314,9 @@ WebGLContext::GetBufferParameter(WebGLenum target, WebGLenum pname) JS::Value WebGLContext::GetFramebufferAttachmentParameter(JSContext* cx, - WebGLenum target, - WebGLenum attachment, - WebGLenum pname, + GLenum target, + GLenum attachment, + GLenum pname, ErrorResult& rv) { if (!IsContextStable()) @@ -1334,7 +1334,7 @@ WebGLContext::GetFramebufferAttachmentParameter(JSContext* cx, if (IsExtensionEnabled(WEBGL_draw_buffers)) { if (attachment < LOCAL_GL_COLOR_ATTACHMENT0 || - attachment >= WebGLenum(LOCAL_GL_COLOR_ATTACHMENT0 + mGLMaxColorAttachments)) + attachment >= GLenum(LOCAL_GL_COLOR_ATTACHMENT0 + mGLMaxColorAttachments)) { ErrorInvalidEnumInfo("getFramebufferAttachmentParameter: attachment", attachment); return JS::NullValue(); @@ -1407,7 +1407,7 @@ WebGLContext::GetFramebufferAttachmentParameter(JSContext* cx, } JS::Value -WebGLContext::GetRenderbufferParameter(WebGLenum target, WebGLenum pname) +WebGLContext::GetRenderbufferParameter(GLenum target, GLenum pname) { if (!IsContextStable()) return JS::NullValue(); @@ -1458,7 +1458,7 @@ WebGLContext::CreateTexture() return globj.forget(); } -WebGLenum +GLenum WebGLContext::GetError() { if (mContextStatus == ContextStable) { @@ -1469,13 +1469,13 @@ WebGLContext::GetError() mContextLostErrorSet = true; } - WebGLenum err = mWebGLError; + GLenum err = mWebGLError; mWebGLError = LOCAL_GL_NO_ERROR; return err; } JS::Value -WebGLContext::GetProgramParameter(WebGLProgram *prog, WebGLenum pname) +WebGLContext::GetProgramParameter(WebGLProgram *prog, GLenum pname) { if (!IsContextStable()) return JS::NullValue(); @@ -1483,7 +1483,7 @@ WebGLContext::GetProgramParameter(WebGLProgram *prog, WebGLenum pname) if (!ValidateObjectAllowDeleted("getProgramParameter: program", prog)) return JS::NullValue(); - WebGLuint progname = prog->GLName(); + GLuint progname = prog->GLName(); MakeContextCurrent(); @@ -1550,7 +1550,7 @@ WebGLContext::GetProgramInfoLog(WebGLProgram *prog, nsACString& retval) return; } - WebGLuint progname = prog->GLName(); + GLuint progname = prog->GLName(); MakeContextCurrent(); @@ -1577,17 +1577,17 @@ WebGLContext::GetProgramInfoLog(WebGLProgram *prog, nsACString& retval) // here we have to support all pnames with both int and float params. // See this discussion: // https://www.khronos.org/webgl/public-mailing-list/archives/1008/msg00014.html -void WebGLContext::TexParameter_base(WebGLenum target, WebGLenum pname, - WebGLint *intParamPtr, - WebGLfloat *floatParamPtr) +void WebGLContext::TexParameter_base(GLenum target, GLenum pname, + GLint *intParamPtr, + GLfloat *floatParamPtr) { MOZ_ASSERT(intParamPtr || floatParamPtr); if (!IsContextStable()) return; - WebGLint intParam = intParamPtr ? *intParamPtr : WebGLint(*floatParamPtr); - WebGLfloat floatParam = floatParamPtr ? *floatParamPtr : WebGLfloat(*intParamPtr); + GLint intParam = intParamPtr ? *intParamPtr : GLint(*floatParamPtr); + GLfloat floatParam = floatParamPtr ? *floatParamPtr : GLfloat(*intParamPtr); if (!ValidateTextureTargetEnum(target, "texParameter: target")) return; @@ -1684,7 +1684,7 @@ void WebGLContext::TexParameter_base(WebGLenum target, WebGLenum pname, } JS::Value -WebGLContext::GetTexParameter(WebGLenum target, WebGLenum pname) +WebGLContext::GetTexParameter(GLenum target, GLenum pname) { if (!IsContextStable()) return JS::NullValue(); @@ -1749,7 +1749,7 @@ WebGLContext::GetUniform(JSContext* cx, WebGLProgram *prog, return JS::NullValue(); } - WebGLuint progname = prog->GLName(); + GLuint progname = prog->GLName(); MakeContextCurrent(); @@ -1875,7 +1875,7 @@ WebGLContext::GetUniformLocation(WebGLProgram *prog, const nsAString& name) nsCString mappedName; prog->MapIdentifier(cname, &mappedName); - WebGLuint progname = prog->GLName(); + GLuint progname = prog->GLName(); MakeContextCurrent(); GLint intlocation = gl->fGetUniformLocation(progname, mappedName.get()); @@ -1891,7 +1891,7 @@ WebGLContext::GetUniformLocation(WebGLProgram *prog, const nsAString& name) } void -WebGLContext::Hint(WebGLenum target, WebGLenum mode) +WebGLContext::Hint(GLenum target, GLenum mode) { if (!IsContextStable()) return; @@ -2127,7 +2127,7 @@ WebGLContext::LinkProgram(WebGLProgram *program) } void -WebGLContext::PixelStorei(WebGLenum pname, WebGLint param) +WebGLContext::PixelStorei(GLenum pname, GLint param) { if (!IsContextStable()) return; @@ -2165,9 +2165,9 @@ WebGLContext::PixelStorei(WebGLenum pname, WebGLint param) } void -WebGLContext::ReadPixels(WebGLint x, WebGLint y, WebGLsizei width, - WebGLsizei height, WebGLenum format, - WebGLenum type, const Nullable &pixels, +WebGLContext::ReadPixels(GLint x, GLint y, GLsizei width, + GLsizei height, GLenum format, + GLenum type, const Nullable &pixels, ErrorResult& rv) { if (!IsContextStable()) { @@ -2186,8 +2186,8 @@ WebGLContext::ReadPixels(WebGLint x, WebGLint y, WebGLsizei width, return ErrorInvalidValue("readPixels: null destination buffer"); const WebGLRectangleObject *framebufferRect = FramebufferRectangleObject(); - WebGLsizei framebufferWidth = framebufferRect ? framebufferRect->Width() : 0; - WebGLsizei framebufferHeight = framebufferRect ? framebufferRect->Height() : 0; + GLsizei framebufferWidth = framebufferRect ? framebufferRect->Width() : 0; + GLsizei framebufferHeight = framebufferRect ? framebufferRect->Height() : 0; uint32_t channels = 0; @@ -2391,7 +2391,7 @@ WebGLContext::ReadPixels(WebGLint x, WebGLint y, WebGLsizei width, } void -WebGLContext::RenderbufferStorage(WebGLenum target, WebGLenum internalformat, WebGLsizei width, WebGLsizei height) +WebGLContext::RenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) { if (!IsContextStable()) return; @@ -2409,7 +2409,7 @@ WebGLContext::RenderbufferStorage(WebGLenum target, WebGLenum internalformat, We return ErrorInvalidValue("renderbufferStorage: width or height exceeds maximum renderbuffer size"); // certain OpenGL ES renderbuffer formats may not exist on desktop OpenGL - WebGLenum internalformatForGL = internalformat; + GLenum internalformatForGL = internalformat; switch (internalformat) { case LOCAL_GL_RGBA4: @@ -2468,7 +2468,7 @@ WebGLContext::RenderbufferStorage(WebGLenum target, WebGLenum internalformat, We } void -WebGLContext::Scissor(WebGLint x, WebGLint y, WebGLsizei width, WebGLsizei height) +WebGLContext::Scissor(GLint x, GLint y, GLsizei width, GLsizei height) { if (!IsContextStable()) return; @@ -2481,7 +2481,7 @@ WebGLContext::Scissor(WebGLint x, WebGLint y, WebGLsizei width, WebGLsizei heigh } void -WebGLContext::StencilFunc(WebGLenum func, WebGLint ref, WebGLuint mask) +WebGLContext::StencilFunc(GLenum func, GLint ref, GLuint mask) { if (!IsContextStable()) return; @@ -2499,7 +2499,7 @@ WebGLContext::StencilFunc(WebGLenum func, WebGLint ref, WebGLuint mask) } void -WebGLContext::StencilFuncSeparate(WebGLenum face, WebGLenum func, WebGLint ref, WebGLuint mask) +WebGLContext::StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask) { if (!IsContextStable()) return; @@ -2530,7 +2530,7 @@ WebGLContext::StencilFuncSeparate(WebGLenum face, WebGLenum func, WebGLint ref, } void -WebGLContext::StencilOp(WebGLenum sfail, WebGLenum dpfail, WebGLenum dppass) +WebGLContext::StencilOp(GLenum sfail, GLenum dpfail, GLenum dppass) { if (!IsContextStable()) return; @@ -2545,7 +2545,7 @@ WebGLContext::StencilOp(WebGLenum sfail, WebGLenum dpfail, WebGLenum dppass) } void -WebGLContext::StencilOpSeparate(WebGLenum face, WebGLenum sfail, WebGLenum dpfail, WebGLenum dppass) +WebGLContext::StencilOpSeparate(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass) { if (!IsContextStable()) return; @@ -2635,7 +2635,7 @@ WebGLContext::SurfaceFromElementResultToImageSurface(nsLayoutUtils::SurfaceFromE void -WebGLContext::Uniform1i(WebGLUniformLocation *location_object, WebGLint a1) +WebGLContext::Uniform1i(WebGLUniformLocation *location_object, GLint a1) { GLint location; if (!ValidateUniformSetter("Uniform1i", location_object, location)) @@ -2649,8 +2649,8 @@ WebGLContext::Uniform1i(WebGLUniformLocation *location_object, WebGLint a1) } void -WebGLContext::Uniform2i(WebGLUniformLocation *location_object, WebGLint a1, - WebGLint a2) +WebGLContext::Uniform2i(WebGLUniformLocation *location_object, GLint a1, + GLint a2) { GLint location; if (!ValidateUniformSetter("Uniform2i", location_object, location)) @@ -2667,8 +2667,8 @@ WebGLContext::Uniform2i(WebGLUniformLocation *location_object, WebGLint a1, } void -WebGLContext::Uniform3i(WebGLUniformLocation *location_object, WebGLint a1, - WebGLint a2, WebGLint a3) +WebGLContext::Uniform3i(WebGLUniformLocation *location_object, GLint a1, + GLint a2, GLint a3) { GLint location; if (!ValidateUniformSetter("Uniform3i", location_object, location)) @@ -2686,8 +2686,8 @@ WebGLContext::Uniform3i(WebGLUniformLocation *location_object, WebGLint a1, } void -WebGLContext::Uniform4i(WebGLUniformLocation *location_object, WebGLint a1, - WebGLint a2, WebGLint a3, WebGLint a4) +WebGLContext::Uniform4i(WebGLUniformLocation *location_object, GLint a1, + GLint a2, GLint a3, GLint a4) { GLint location; if (!ValidateUniformSetter("Uniform4i", location_object, location)) @@ -2706,7 +2706,7 @@ WebGLContext::Uniform4i(WebGLUniformLocation *location_object, WebGLint a1, } void -WebGLContext::Uniform1f(WebGLUniformLocation *location_object, WebGLfloat a1) +WebGLContext::Uniform1f(WebGLUniformLocation *location_object, GLfloat a1) { GLint location; if (!ValidateUniformSetter("Uniform1f", location_object, location)) @@ -2716,8 +2716,8 @@ WebGLContext::Uniform1f(WebGLUniformLocation *location_object, WebGLfloat a1) } void -WebGLContext::Uniform2f(WebGLUniformLocation *location_object, WebGLfloat a1, - WebGLfloat a2) +WebGLContext::Uniform2f(WebGLUniformLocation *location_object, GLfloat a1, + GLfloat a2) { GLint location; if (!ValidateUniformSetter("Uniform2f", location_object, location)) @@ -2727,8 +2727,8 @@ WebGLContext::Uniform2f(WebGLUniformLocation *location_object, WebGLfloat a1, } void -WebGLContext::Uniform3f(WebGLUniformLocation *location_object, WebGLfloat a1, - WebGLfloat a2, WebGLfloat a3) +WebGLContext::Uniform3f(WebGLUniformLocation *location_object, GLfloat a1, + GLfloat a2, GLfloat a3) { GLint location; if (!ValidateUniformSetter("Uniform3f", location_object, location)) @@ -2738,8 +2738,8 @@ WebGLContext::Uniform3f(WebGLUniformLocation *location_object, WebGLfloat a1, } void -WebGLContext::Uniform4f(WebGLUniformLocation *location_object, WebGLfloat a1, - WebGLfloat a2, WebGLfloat a3, WebGLfloat a4) +WebGLContext::Uniform4f(WebGLUniformLocation *location_object, GLfloat a1, + GLfloat a2, GLfloat a3, GLfloat a4) { GLint location; if (!ValidateUniformSetter("Uniform4f", location_object, location)) @@ -2750,7 +2750,7 @@ WebGLContext::Uniform4f(WebGLUniformLocation *location_object, WebGLfloat a1, void WebGLContext::Uniform1iv_base(WebGLUniformLocation *location_object, - uint32_t arrayLength, const WebGLint* data) + uint32_t arrayLength, const GLint* data) { uint32_t numElementsToUpload; GLint location; @@ -2768,7 +2768,7 @@ WebGLContext::Uniform1iv_base(WebGLUniformLocation *location_object, void WebGLContext::Uniform2iv_base(WebGLUniformLocation *location_object, - uint32_t arrayLength, const WebGLint* data) + uint32_t arrayLength, const GLint* data) { uint32_t numElementsToUpload; GLint location; @@ -2789,7 +2789,7 @@ WebGLContext::Uniform2iv_base(WebGLUniformLocation *location_object, void WebGLContext::Uniform3iv_base(WebGLUniformLocation *location_object, - uint32_t arrayLength, const WebGLint* data) + uint32_t arrayLength, const GLint* data) { uint32_t numElementsToUpload; GLint location; @@ -2811,7 +2811,7 @@ WebGLContext::Uniform3iv_base(WebGLUniformLocation *location_object, void WebGLContext::Uniform4iv_base(WebGLUniformLocation *location_object, - uint32_t arrayLength, const WebGLint* data) + uint32_t arrayLength, const GLint* data) { uint32_t numElementsToUpload; GLint location; @@ -2834,7 +2834,7 @@ WebGLContext::Uniform4iv_base(WebGLUniformLocation *location_object, void WebGLContext::Uniform1fv_base(WebGLUniformLocation *location_object, - uint32_t arrayLength, const WebGLfloat* data) + uint32_t arrayLength, const GLfloat* data) { uint32_t numElementsToUpload; GLint location; @@ -2848,7 +2848,7 @@ WebGLContext::Uniform1fv_base(WebGLUniformLocation *location_object, void WebGLContext::Uniform2fv_base(WebGLUniformLocation *location_object, - uint32_t arrayLength, const WebGLfloat* data) + uint32_t arrayLength, const GLfloat* data) { uint32_t numElementsToUpload; GLint location; @@ -2862,7 +2862,7 @@ WebGLContext::Uniform2fv_base(WebGLUniformLocation *location_object, void WebGLContext::Uniform3fv_base(WebGLUniformLocation *location_object, - uint32_t arrayLength, const WebGLfloat* data) + uint32_t arrayLength, const GLfloat* data) { uint32_t numElementsToUpload; GLint location; @@ -2876,7 +2876,7 @@ WebGLContext::Uniform3fv_base(WebGLUniformLocation *location_object, void WebGLContext::Uniform4fv_base(WebGLUniformLocation *location_object, - uint32_t arrayLength, const WebGLfloat* data) + uint32_t arrayLength, const GLfloat* data) { uint32_t numElementsToUpload; GLint location; @@ -2946,7 +2946,7 @@ WebGLContext::UseProgram(WebGLProgram *prog) InvalidateBufferFetching(); - WebGLuint progname = prog ? prog->GLName() : 0; + GLuint progname = prog ? prog->GLName() : 0; if (prog && !prog->LinkStatus()) return ErrorInvalidOperation("useProgram: program was not linked successfully"); @@ -2975,7 +2975,7 @@ WebGLContext::ValidateProgram(WebGLProgram *prog) } #endif - WebGLuint progname = prog->GLName(); + GLuint progname = prog->GLName(); gl->fValidateProgram(progname); } @@ -2998,7 +2998,7 @@ WebGLContext::CreateRenderbuffer() } void -WebGLContext::Viewport(WebGLint x, WebGLint y, WebGLsizei width, WebGLsizei height) +WebGLContext::Viewport(GLint x, GLint y, GLsizei width, GLsizei height) { if (!IsContextStable()) return; @@ -3019,7 +3019,7 @@ WebGLContext::CompileShader(WebGLShader *shader) if (!ValidateObject("compileShader", shader)) return; - WebGLuint shadername = shader->GLName(); + GLuint shadername = shader->GLName(); shader->SetCompileStatus(false); @@ -3279,8 +3279,8 @@ WebGLContext::CompileShader(WebGLShader *shader) } void -WebGLContext::CompressedTexImage2D(WebGLenum target, WebGLint level, WebGLenum internalformat, - WebGLsizei width, WebGLsizei height, WebGLint border, +WebGLContext::CompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, + GLsizei width, GLsizei height, GLint border, const ArrayBufferView& view) { if (!IsContextStable()) { @@ -3319,9 +3319,9 @@ WebGLContext::CompressedTexImage2D(WebGLenum target, WebGLint level, WebGLenum i } void -WebGLContext::CompressedTexSubImage2D(WebGLenum target, WebGLint level, WebGLint xoffset, - WebGLint yoffset, WebGLsizei width, WebGLsizei height, - WebGLenum format, const ArrayBufferView& view) +WebGLContext::CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, + GLint yoffset, GLsizei width, GLsizei height, + GLenum format, const ArrayBufferView& view) { if (!IsContextStable()) { return; @@ -3419,7 +3419,7 @@ WebGLContext::CompressedTexSubImage2D(WebGLenum target, WebGLint level, WebGLint } JS::Value -WebGLContext::GetShaderParameter(WebGLShader *shader, WebGLenum pname) +WebGLContext::GetShaderParameter(WebGLShader *shader, GLenum pname) { if (!IsContextStable()) return JS::NullValue(); @@ -3427,7 +3427,7 @@ WebGLContext::GetShaderParameter(WebGLShader *shader, WebGLenum pname) if (!ValidateObject("getShaderParameter: shader", shader)) return JS::NullValue(); - WebGLuint shadername = shader->GLName(); + GLuint shadername = shader->GLName(); MakeContextCurrent(); @@ -3486,7 +3486,7 @@ WebGLContext::GetShaderInfoLog(WebGLShader *shader, nsACString& retval) MakeContextCurrent(); - WebGLuint shadername = shader->GLName(); + GLuint shadername = shader->GLName(); GLint k = -1; gl->fGetShaderiv(shadername, LOCAL_GL_INFO_LOG_LENGTH, &k); if (k == -1) { @@ -3505,7 +3505,7 @@ WebGLContext::GetShaderInfoLog(WebGLShader *shader, nsACString& retval) } already_AddRefed -WebGLContext::GetShaderPrecisionFormat(WebGLenum shadertype, WebGLenum precisiontype) +WebGLContext::GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype) { if (!IsContextStable()) return nullptr; @@ -3626,10 +3626,10 @@ GLenum WebGLContext::CheckedTexImage2D(GLenum target, } void -WebGLContext::TexImage2D_base(WebGLenum target, WebGLint level, WebGLenum internalformat, - WebGLsizei width, WebGLsizei height, WebGLsizei srcStrideOrZero, - WebGLint border, - WebGLenum format, WebGLenum type, +WebGLContext::TexImage2D_base(GLenum target, GLint level, GLenum internalformat, + GLsizei width, GLsizei height, GLsizei srcStrideOrZero, + GLint border, + GLenum format, GLenum type, void *data, uint32_t byteLength, int jsArrayType, // a TypedArray format enum, or -1 if not relevant WebGLTexelFormat srcFormat, bool srcPremultiplied) @@ -3771,10 +3771,10 @@ WebGLContext::TexImage2D_base(WebGLenum target, WebGLint level, WebGLenum intern } void -WebGLContext::TexImage2D(WebGLenum target, WebGLint level, - WebGLenum internalformat, WebGLsizei width, - WebGLsizei height, WebGLint border, WebGLenum format, - WebGLenum type, const Nullable &pixels, ErrorResult& rv) +WebGLContext::TexImage2D(GLenum target, GLint level, + GLenum internalformat, GLsizei width, + GLsizei height, GLint border, GLenum format, + GLenum type, const Nullable &pixels, ErrorResult& rv) { if (!IsContextStable()) return; @@ -3787,9 +3787,9 @@ WebGLContext::TexImage2D(WebGLenum target, WebGLint level, } void -WebGLContext::TexImage2D(WebGLenum target, WebGLint level, - WebGLenum internalformat, WebGLenum format, - WebGLenum type, ImageData* pixels, ErrorResult& rv) +WebGLContext::TexImage2D(GLenum target, GLint level, + GLenum internalformat, GLenum format, + GLenum type, ImageData* pixels, ErrorResult& rv) { if (!IsContextStable()) return; @@ -3808,10 +3808,10 @@ WebGLContext::TexImage2D(WebGLenum target, WebGLint level, void -WebGLContext::TexSubImage2D_base(WebGLenum target, WebGLint level, - WebGLint xoffset, WebGLint yoffset, - WebGLsizei width, WebGLsizei height, WebGLsizei srcStrideOrZero, - WebGLenum format, WebGLenum type, +WebGLContext::TexSubImage2D_base(GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, GLsizei srcStrideOrZero, + GLenum format, GLenum type, void *pixels, uint32_t byteLength, int jsArrayType, WebGLTexelFormat srcFormat, bool srcPremultiplied) @@ -3920,10 +3920,10 @@ WebGLContext::TexSubImage2D_base(WebGLenum target, WebGLint level, } void -WebGLContext::TexSubImage2D(WebGLenum target, WebGLint level, - WebGLint xoffset, WebGLint yoffset, - WebGLsizei width, WebGLsizei height, - WebGLenum format, WebGLenum type, +WebGLContext::TexSubImage2D(GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, GLenum type, const Nullable &pixels, ErrorResult& rv) { @@ -3941,9 +3941,9 @@ WebGLContext::TexSubImage2D(WebGLenum target, WebGLint level, } void -WebGLContext::TexSubImage2D(WebGLenum target, WebGLint level, - WebGLint xoffset, WebGLint yoffset, - WebGLenum format, WebGLenum type, ImageData* pixels, +WebGLContext::TexSubImage2D(GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLenum format, GLenum type, ImageData* pixels, ErrorResult& rv) { if (!IsContextStable()) @@ -3985,7 +3985,7 @@ WebGLContext::RestoreContext() } bool -BaseTypeAndSizeFromUniformType(WebGLenum uType, WebGLenum *baseType, WebGLint *unitSize) +BaseTypeAndSizeFromUniformType(GLenum uType, GLenum *baseType, GLint *unitSize) { switch (uType) { case LOCAL_GL_INT: @@ -4126,8 +4126,8 @@ WebGLTexelFormat mozilla::GetWebGLTexelFormat(GLenum format, GLenum type) } } -WebGLenum -InternalFormatForFormatAndType(WebGLenum format, WebGLenum type, bool isGLES2) +GLenum +InternalFormatForFormatAndType(GLenum format, GLenum type, bool isGLES2) { // ES2 requires that format == internalformat; floating-point is // indicated purely by the type that's loaded. For desktop GL, we @@ -4179,7 +4179,7 @@ InternalFormatForFormatAndType(WebGLenum format, WebGLenum type, bool isGLES2) void WebGLContext::ReattachTextureToAnyFramebufferToWorkAroundBugs(WebGLTexture *tex, - WebGLint level) + GLint level) { MOZ_ASSERT(tex); diff --git a/content/canvas/src/WebGLContextState.cpp b/content/canvas/src/WebGLContextState.cpp index 8f4c005a6e6..d91005ed608 100644 --- a/content/canvas/src/WebGLContextState.cpp +++ b/content/canvas/src/WebGLContextState.cpp @@ -17,7 +17,7 @@ using namespace mozilla; using namespace dom; void -WebGLContext::Disable(WebGLenum cap) +WebGLContext::Disable(GLenum cap) { if (!IsContextStable()) return; @@ -37,7 +37,7 @@ WebGLContext::Disable(WebGLenum cap) } void -WebGLContext::Enable(WebGLenum cap) +WebGLContext::Enable(GLenum cap) { if (!IsContextStable()) return; @@ -69,7 +69,7 @@ StringValue(JSContext* cx, const char* chars, ErrorResult& rv) } JS::Value -WebGLContext::GetParameter(JSContext* cx, WebGLenum pname, ErrorResult& rv) +WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv) { if (!IsContextStable()) return JS::NullValue(); @@ -127,7 +127,7 @@ WebGLContext::GetParameter(JSContext* cx, WebGLenum pname, ErrorResult& rv) return JS::Int32Value(mGLMaxDrawBuffers); } else if (pname >= LOCAL_GL_DRAW_BUFFER0 && - pname < WebGLenum(LOCAL_GL_DRAW_BUFFER0 + mGLMaxDrawBuffers)) + pname < GLenum(LOCAL_GL_DRAW_BUFFER0 + mGLMaxDrawBuffers)) { if (mBoundFramebuffer) { GLint iv = 0; @@ -484,7 +484,7 @@ WebGLContext::GetParameter(JSContext* cx, WebGLenum pname, ErrorResult& rv) } JS::Value -WebGLContext::GetParameterIndexed(JSContext* cx, WebGLenum pname, WebGLuint index) +WebGLContext::GetParameterIndexed(JSContext* cx, GLenum pname, GLuint index) { if (!IsContextStable()) return JS::NullValue(); @@ -510,7 +510,7 @@ WebGLContext::GetParameterIndexed(JSContext* cx, WebGLenum pname, WebGLuint inde } bool -WebGLContext::IsEnabled(WebGLenum cap) +WebGLContext::IsEnabled(GLenum cap) { if (!IsContextStable()) return false; @@ -523,7 +523,7 @@ WebGLContext::IsEnabled(WebGLenum cap) } bool -WebGLContext::ValidateCapabilityEnum(WebGLenum cap, const char* info) +WebGLContext::ValidateCapabilityEnum(GLenum cap, const char* info) { switch (cap) { case LOCAL_GL_BLEND: @@ -545,7 +545,7 @@ WebGLContext::ValidateCapabilityEnum(WebGLenum cap, const char* info) } realGLboolean* -WebGLContext::GetStateTrackingSlot(WebGLenum cap) +WebGLContext::GetStateTrackingSlot(GLenum cap) { switch (cap) { case LOCAL_GL_SCISSOR_TEST: diff --git a/content/canvas/src/WebGLContextUtils.cpp b/content/canvas/src/WebGLContextUtils.cpp index ab660735b82..e2c183d6213 100644 --- a/content/canvas/src/WebGLContextUtils.cpp +++ b/content/canvas/src/WebGLContextUtils.cpp @@ -56,8 +56,8 @@ WebGLContext::GenerateWarning(const char *fmt, va_list ap) } CheckedUint32 -WebGLContext::GetImageSize(WebGLsizei height, - WebGLsizei width, +WebGLContext::GetImageSize(GLsizei height, + GLsizei width, uint32_t pixelSize, uint32_t packOrUnpackAlignment) { @@ -74,7 +74,7 @@ WebGLContext::GetImageSize(WebGLsizei height, } void -WebGLContext::SynthesizeGLError(WebGLenum err) +WebGLContext::SynthesizeGLError(GLenum err) { // If there is already a pending error, don't overwrite it; // but if there isn't, then we need to check for a gl error @@ -90,7 +90,7 @@ WebGLContext::SynthesizeGLError(WebGLenum err) } void -WebGLContext::SynthesizeGLError(WebGLenum err, const char *fmt, ...) +WebGLContext::SynthesizeGLError(GLenum err, const char *fmt, ...) { va_list va; va_start(va, fmt); diff --git a/content/canvas/src/WebGLContextValidate.cpp b/content/canvas/src/WebGLContextValidate.cpp index 127bd22f8a0..bc0422af0d9 100644 --- a/content/canvas/src/WebGLContextValidate.cpp +++ b/content/canvas/src/WebGLContextValidate.cpp @@ -108,7 +108,7 @@ WebGLProgram::UpdateInfo() return true; } -bool WebGLContext::ValidateBlendEquationEnum(WebGLenum mode, const char *info) +bool WebGLContext::ValidateBlendEquationEnum(GLenum mode, const char *info) { switch (mode) { case LOCAL_GL_FUNC_ADD: @@ -130,7 +130,7 @@ bool WebGLContext::ValidateBlendEquationEnum(WebGLenum mode, const char *info) return false; } -bool WebGLContext::ValidateBlendFuncDstEnum(WebGLenum factor, const char *info) +bool WebGLContext::ValidateBlendFuncDstEnum(GLenum factor, const char *info) { switch (factor) { case LOCAL_GL_ZERO: @@ -154,7 +154,7 @@ bool WebGLContext::ValidateBlendFuncDstEnum(WebGLenum factor, const char *info) } } -bool WebGLContext::ValidateBlendFuncSrcEnum(WebGLenum factor, const char *info) +bool WebGLContext::ValidateBlendFuncSrcEnum(GLenum factor, const char *info) { if (factor == LOCAL_GL_SRC_ALPHA_SATURATE) return true; @@ -162,7 +162,7 @@ bool WebGLContext::ValidateBlendFuncSrcEnum(WebGLenum factor, const char *info) return ValidateBlendFuncDstEnum(factor, info); } -bool WebGLContext::ValidateBlendFuncEnumsCompatibility(WebGLenum sfactor, WebGLenum dfactor, const char *info) +bool WebGLContext::ValidateBlendFuncEnumsCompatibility(GLenum sfactor, GLenum dfactor, const char *info) { bool sfactorIsConstantColor = sfactor == LOCAL_GL_CONSTANT_COLOR || sfactor == LOCAL_GL_ONE_MINUS_CONSTANT_COLOR; @@ -181,7 +181,7 @@ bool WebGLContext::ValidateBlendFuncEnumsCompatibility(WebGLenum sfactor, WebGLe } } -bool WebGLContext::ValidateTextureTargetEnum(WebGLenum target, const char *info) +bool WebGLContext::ValidateTextureTargetEnum(GLenum target, const char *info) { switch (target) { case LOCAL_GL_TEXTURE_2D: @@ -193,7 +193,7 @@ bool WebGLContext::ValidateTextureTargetEnum(WebGLenum target, const char *info) } } -bool WebGLContext::ValidateComparisonEnum(WebGLenum target, const char *info) +bool WebGLContext::ValidateComparisonEnum(GLenum target, const char *info) { switch (target) { case LOCAL_GL_NEVER: @@ -211,7 +211,7 @@ bool WebGLContext::ValidateComparisonEnum(WebGLenum target, const char *info) } } -bool WebGLContext::ValidateStencilOpEnum(WebGLenum action, const char *info) +bool WebGLContext::ValidateStencilOpEnum(GLenum action, const char *info) { switch (action) { case LOCAL_GL_KEEP: @@ -229,7 +229,7 @@ bool WebGLContext::ValidateStencilOpEnum(WebGLenum action, const char *info) } } -bool WebGLContext::ValidateFaceEnum(WebGLenum face, const char *info) +bool WebGLContext::ValidateFaceEnum(GLenum face, const char *info) { switch (face) { case LOCAL_GL_FRONT: @@ -242,7 +242,7 @@ bool WebGLContext::ValidateFaceEnum(WebGLenum face, const char *info) } } -bool WebGLContext::ValidateDrawModeEnum(WebGLenum mode, const char *info) +bool WebGLContext::ValidateDrawModeEnum(GLenum mode, const char *info) { switch (mode) { case LOCAL_GL_TRIANGLES: @@ -300,7 +300,7 @@ bool WebGLContext::ValidateGLSLString(const nsAString& string, const char *info) return true; } -bool WebGLContext::ValidateTexImage2DTarget(WebGLenum target, WebGLsizei width, WebGLsizei height, +bool WebGLContext::ValidateTexImage2DTarget(GLenum target, GLsizei width, GLsizei height, const char* info) { switch (target) { @@ -325,9 +325,9 @@ bool WebGLContext::ValidateTexImage2DTarget(WebGLenum target, WebGLsizei width, return true; } -bool WebGLContext::ValidateCompressedTextureSize(WebGLenum target, WebGLint level, - WebGLenum format, - WebGLsizei width, WebGLsizei height, uint32_t byteLength, const char* info) +bool WebGLContext::ValidateCompressedTextureSize(GLenum target, GLint level, + GLenum format, + GLsizei width, GLsizei height, uint32_t byteLength, const char* info) { if (!ValidateLevelWidthHeightForTarget(target, level, width, height, info)) { return false; @@ -408,17 +408,17 @@ bool WebGLContext::ValidateCompressedTextureSize(WebGLenum target, WebGLint leve return true; } -bool WebGLContext::ValidateLevelWidthHeightForTarget(WebGLenum target, WebGLint level, WebGLsizei width, - WebGLsizei height, const char* info) +bool WebGLContext::ValidateLevelWidthHeightForTarget(GLenum target, GLint level, GLsizei width, + GLsizei height, const char* info) { - WebGLsizei maxTextureSize = MaxTextureSizeForTarget(target); + GLsizei maxTextureSize = MaxTextureSizeForTarget(target); if (level < 0) { ErrorInvalidValue("%s: level must be >= 0", info); return false; } - WebGLsizei maxAllowedSize = maxTextureSize >> level; + GLsizei maxAllowedSize = maxTextureSize >> level; if (!maxAllowedSize) { ErrorInvalidValue("%s: 2^level exceeds maximum texture size", info); @@ -438,7 +438,7 @@ bool WebGLContext::ValidateLevelWidthHeightForTarget(WebGLenum target, WebGLint return true; } -uint32_t WebGLContext::GetBitsPerTexel(WebGLenum format, WebGLenum type) +uint32_t WebGLContext::GetBitsPerTexel(GLenum format, GLenum type) { // If there is no defined format or type, we're not taking up any memory if (!format || !type) { @@ -495,7 +495,7 @@ uint32_t WebGLContext::GetBitsPerTexel(WebGLenum format, WebGLenum type) return 0; } -bool WebGLContext::ValidateTexFormatAndType(WebGLenum format, WebGLenum type, int jsArrayType, +bool WebGLContext::ValidateTexFormatAndType(GLenum format, GLenum type, int jsArrayType, uint32_t *texelSize, const char *info) { if (IsExtensionEnabled(WEBGL_depth_texture)) { @@ -635,7 +635,7 @@ WebGLContext::ValidateUniformLocation(const char* info, WebGLUniformLocation *lo } bool -WebGLContext::ValidateSamplerUniformSetter(const char* info, WebGLUniformLocation *location, WebGLint value) +WebGLContext::ValidateSamplerUniformSetter(const char* info, WebGLUniformLocation *location, GLint value) { if (location->Info().type != SH_SAMPLER_2D && location->Info().type != SH_SAMPLER_CUBE) @@ -764,7 +764,7 @@ WebGLContext::ValidateUniformSetter(const char* name, WebGLUniformLocation *loca return true; } -bool WebGLContext::ValidateAttribIndex(WebGLuint index, const char *info) +bool WebGLContext::ValidateAttribIndex(GLuint index, const char *info) { return mBoundVertexArray->EnsureAttribIndex(index, info); } diff --git a/content/canvas/src/WebGLContextVertices.cpp b/content/canvas/src/WebGLContextVertices.cpp index 691ee358bed..af9052e2f83 100644 --- a/content/canvas/src/WebGLContextVertices.cpp +++ b/content/canvas/src/WebGLContextVertices.cpp @@ -21,7 +21,7 @@ using namespace dom; static const int MAX_DRAW_CALLS_SINCE_FLUSH = 100; void -WebGLContext::VertexAttrib1f(WebGLuint index, WebGLfloat x0) +WebGLContext::VertexAttrib1f(GLuint index, GLfloat x0) { if (!IsContextStable()) return; @@ -41,7 +41,7 @@ WebGLContext::VertexAttrib1f(WebGLuint index, WebGLfloat x0) } void -WebGLContext::VertexAttrib2f(WebGLuint index, WebGLfloat x0, WebGLfloat x1) +WebGLContext::VertexAttrib2f(GLuint index, GLfloat x0, GLfloat x1) { if (!IsContextStable()) return; @@ -61,7 +61,7 @@ WebGLContext::VertexAttrib2f(WebGLuint index, WebGLfloat x0, WebGLfloat x1) } void -WebGLContext::VertexAttrib3f(WebGLuint index, WebGLfloat x0, WebGLfloat x1, WebGLfloat x2) +WebGLContext::VertexAttrib3f(GLuint index, GLfloat x0, GLfloat x1, GLfloat x2) { if (!IsContextStable()) return; @@ -81,8 +81,8 @@ WebGLContext::VertexAttrib3f(WebGLuint index, WebGLfloat x0, WebGLfloat x1, WebG } void -WebGLContext::VertexAttrib4f(WebGLuint index, WebGLfloat x0, WebGLfloat x1, - WebGLfloat x2, WebGLfloat x3) +WebGLContext::VertexAttrib4f(GLuint index, GLfloat x0, GLfloat x1, + GLfloat x2, GLfloat x3) { if (!IsContextStable()) return; @@ -103,8 +103,8 @@ WebGLContext::VertexAttrib4f(WebGLuint index, WebGLfloat x0, WebGLfloat x1, void -WebGLContext::VertexAttrib1fv_base(WebGLuint idx, uint32_t arrayLength, - const WebGLfloat* ptr) +WebGLContext::VertexAttrib1fv_base(GLuint idx, uint32_t arrayLength, + const GLfloat* ptr) { if (!ValidateAttribArraySetter("VertexAttrib1fv", 1, arrayLength)) return; @@ -114,17 +114,17 @@ WebGLContext::VertexAttrib1fv_base(WebGLuint idx, uint32_t arrayLength, gl->fVertexAttrib1fv(idx, ptr); } else { mVertexAttrib0Vector[0] = ptr[0]; - mVertexAttrib0Vector[1] = WebGLfloat(0); - mVertexAttrib0Vector[2] = WebGLfloat(0); - mVertexAttrib0Vector[3] = WebGLfloat(1); + mVertexAttrib0Vector[1] = GLfloat(0); + mVertexAttrib0Vector[2] = GLfloat(0); + mVertexAttrib0Vector[3] = GLfloat(1); if (gl->IsGLES2()) gl->fVertexAttrib1fv(idx, ptr); } } void -WebGLContext::VertexAttrib2fv_base(WebGLuint idx, uint32_t arrayLength, - const WebGLfloat* ptr) +WebGLContext::VertexAttrib2fv_base(GLuint idx, uint32_t arrayLength, + const GLfloat* ptr) { if (!ValidateAttribArraySetter("VertexAttrib2fv", 2, arrayLength)) return; @@ -135,16 +135,16 @@ WebGLContext::VertexAttrib2fv_base(WebGLuint idx, uint32_t arrayLength, } else { mVertexAttrib0Vector[0] = ptr[0]; mVertexAttrib0Vector[1] = ptr[1]; - mVertexAttrib0Vector[2] = WebGLfloat(0); - mVertexAttrib0Vector[3] = WebGLfloat(1); + mVertexAttrib0Vector[2] = GLfloat(0); + mVertexAttrib0Vector[3] = GLfloat(1); if (gl->IsGLES2()) gl->fVertexAttrib2fv(idx, ptr); } } void -WebGLContext::VertexAttrib3fv_base(WebGLuint idx, uint32_t arrayLength, - const WebGLfloat* ptr) +WebGLContext::VertexAttrib3fv_base(GLuint idx, uint32_t arrayLength, + const GLfloat* ptr) { if (!ValidateAttribArraySetter("VertexAttrib3fv", 3, arrayLength)) return; @@ -156,15 +156,15 @@ WebGLContext::VertexAttrib3fv_base(WebGLuint idx, uint32_t arrayLength, mVertexAttrib0Vector[0] = ptr[0]; mVertexAttrib0Vector[1] = ptr[1]; mVertexAttrib0Vector[2] = ptr[2]; - mVertexAttrib0Vector[3] = WebGLfloat(1); + mVertexAttrib0Vector[3] = GLfloat(1); if (gl->IsGLES2()) gl->fVertexAttrib3fv(idx, ptr); } } void -WebGLContext::VertexAttrib4fv_base(WebGLuint idx, uint32_t arrayLength, - const WebGLfloat* ptr) +WebGLContext::VertexAttrib4fv_base(GLuint idx, uint32_t arrayLength, + const GLfloat* ptr) { if (!ValidateAttribArraySetter("VertexAttrib4fv", 4, arrayLength)) return; @@ -183,7 +183,7 @@ WebGLContext::VertexAttrib4fv_base(WebGLuint idx, uint32_t arrayLength, } void -WebGLContext::EnableVertexAttribArray(WebGLuint index) +WebGLContext::EnableVertexAttribArray(GLuint index) { if (!IsContextStable()) return; @@ -199,7 +199,7 @@ WebGLContext::EnableVertexAttribArray(WebGLuint index) } void -WebGLContext::DisableVertexAttribArray(WebGLuint index) +WebGLContext::DisableVertexAttribArray(GLuint index) { if (!IsContextStable()) return; @@ -218,7 +218,7 @@ WebGLContext::DisableVertexAttribArray(WebGLuint index) JS::Value -WebGLContext::GetVertexAttrib(JSContext* cx, WebGLuint index, WebGLenum pname, +WebGLContext::GetVertexAttrib(JSContext* cx, GLuint index, GLenum pname, ErrorResult& rv) { if (!IsContextStable()) @@ -271,7 +271,7 @@ WebGLContext::GetVertexAttrib(JSContext* cx, WebGLuint index, WebGLenum pname, case LOCAL_GL_CURRENT_VERTEX_ATTRIB: { - WebGLfloat vec[4] = {0, 0, 0, 1}; + GLfloat vec[4] = {0, 0, 0, 1}; if (index) { gl->fGetVertexAttribfv(index, LOCAL_GL_CURRENT_VERTEX_ATTRIB, &vec[0]); } else { @@ -307,7 +307,7 @@ WebGLContext::GetVertexAttrib(JSContext* cx, WebGLuint index, WebGLenum pname, } WebGLsizeiptr -WebGLContext::GetVertexAttribOffset(WebGLuint index, WebGLenum pname) +WebGLContext::GetVertexAttribOffset(GLuint index, GLenum pname) { if (!IsContextStable()) return 0; @@ -324,8 +324,8 @@ WebGLContext::GetVertexAttribOffset(WebGLuint index, WebGLenum pname) } void -WebGLContext::VertexAttribPointer(WebGLuint index, WebGLint size, WebGLenum type, - WebGLboolean normalized, WebGLsizei stride, +WebGLContext::VertexAttribPointer(GLuint index, GLint size, GLenum type, + WebGLboolean normalized, GLsizei stride, WebGLintptr byteOffset) { if (!IsContextStable()) @@ -334,7 +334,7 @@ WebGLContext::VertexAttribPointer(WebGLuint index, WebGLint size, WebGLenum type if (mBoundArrayBuffer == nullptr) return ErrorInvalidOperation("vertexAttribPointer: must have valid GL_ARRAY_BUFFER binding"); - WebGLsizei requiredAlignment = 1; + GLsizei requiredAlignment = 1; switch (type) { case LOCAL_GL_BYTE: case LOCAL_GL_UNSIGNED_BYTE: @@ -353,7 +353,7 @@ WebGLContext::VertexAttribPointer(WebGLuint index, WebGLint size, WebGLenum type } // requiredAlignment should always be a power of two. - WebGLsizei requiredAlignmentMask = requiredAlignment - 1; + GLsizei requiredAlignmentMask = requiredAlignment - 1; if ( !mBoundVertexArray->EnsureAttribIndex(index, "vertexAttribPointer") ) { return; @@ -403,7 +403,7 @@ WebGLContext::VertexAttribPointer(WebGLuint index, WebGLint size, WebGLenum type } void -WebGLContext::VertexAttribDivisor(WebGLuint index, WebGLuint divisor) +WebGLContext::VertexAttribDivisor(GLuint index, GLuint divisor) { if (!IsContextStable()) return; @@ -422,7 +422,7 @@ WebGLContext::VertexAttribDivisor(WebGLuint index, WebGLuint divisor) gl->fVertexAttribDivisor(index, divisor); } -bool WebGLContext::DrawArrays_check(WebGLint first, WebGLsizei count, WebGLsizei primcount, const char* info) +bool WebGLContext::DrawArrays_check(GLint first, GLsizei count, GLsizei primcount, const char* info) { if (first < 0 || count < 0) { ErrorInvalidValue("%s: negative first or count", info); @@ -498,7 +498,7 @@ bool WebGLContext::DrawArrays_check(WebGLint first, WebGLsizei count, WebGLsizei } void -WebGLContext::DrawArrays(GLenum mode, WebGLint first, WebGLsizei count) +WebGLContext::DrawArrays(GLenum mode, GLint first, GLsizei count) { if (!IsContextStable()) return; @@ -516,7 +516,7 @@ WebGLContext::DrawArrays(GLenum mode, WebGLint first, WebGLsizei count) } void -WebGLContext::DrawArraysInstanced(GLenum mode, WebGLint first, WebGLsizei count, WebGLsizei primcount) +WebGLContext::DrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei primcount) { if (!IsContextStable()) return; @@ -534,7 +534,7 @@ WebGLContext::DrawArraysInstanced(GLenum mode, WebGLint first, WebGLsizei count, } bool -WebGLContext::DrawElements_check(WebGLsizei count, WebGLenum type, WebGLintptr byteOffset, WebGLsizei primcount, const char* info) +WebGLContext::DrawElements_check(GLsizei count, GLenum type, WebGLintptr byteOffset, GLsizei primcount, const char* info) { if (count < 0 || byteOffset < 0) { ErrorInvalidValue("%s: negative count or offset", info); @@ -557,7 +557,7 @@ WebGLContext::DrawElements_check(WebGLsizei count, WebGLenum type, WebGLintptr b CheckedUint32 checked_byteCount; - WebGLsizei first = 0; + GLsizei first = 0; if (type == LOCAL_GL_UNSIGNED_SHORT) { checked_byteCount = 2 * CheckedUint32(count); @@ -662,7 +662,7 @@ WebGLContext::DrawElements_check(WebGLsizei count, WebGLenum type, WebGLintptr b } void -WebGLContext::DrawElements(WebGLenum mode, WebGLsizei count, WebGLenum type, +WebGLContext::DrawElements(GLenum mode, GLsizei count, GLenum type, WebGLintptr byteOffset) { if (!IsContextStable()) @@ -681,8 +681,8 @@ WebGLContext::DrawElements(WebGLenum mode, WebGLsizei count, WebGLenum type, } void -WebGLContext::DrawElementsInstanced(WebGLenum mode, WebGLsizei count, WebGLenum type, - WebGLintptr byteOffset, WebGLsizei primcount) +WebGLContext::DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, + WebGLintptr byteOffset, GLsizei primcount) { if (!IsContextStable()) return; diff --git a/content/canvas/src/WebGLExtensionInstancedArrays.cpp b/content/canvas/src/WebGLExtensionInstancedArrays.cpp index 4970bed5d31..41c6d7fa05b 100644 --- a/content/canvas/src/WebGLExtensionInstancedArrays.cpp +++ b/content/canvas/src/WebGLExtensionInstancedArrays.cpp @@ -21,22 +21,22 @@ WebGLExtensionInstancedArrays::~WebGLExtensionInstancedArrays() } void -WebGLExtensionInstancedArrays::DrawArraysInstancedANGLE(WebGLenum mode, WebGLint first, - WebGLsizei count, WebGLsizei primcount) +WebGLExtensionInstancedArrays::DrawArraysInstancedANGLE(GLenum mode, GLint first, + GLsizei count, GLsizei primcount) { mContext->DrawArraysInstanced(mode, first, count, primcount); } void -WebGLExtensionInstancedArrays::DrawElementsInstancedANGLE(WebGLenum mode, WebGLsizei count, - WebGLenum type, WebGLintptr offset, - WebGLsizei primcount) +WebGLExtensionInstancedArrays::DrawElementsInstancedANGLE(GLenum mode, GLsizei count, + GLenum type, WebGLintptr offset, + GLsizei primcount) { mContext->DrawElementsInstanced(mode, count, type, offset, primcount); } void -WebGLExtensionInstancedArrays::VertexAttribDivisorANGLE(WebGLuint index, WebGLuint divisor) +WebGLExtensionInstancedArrays::VertexAttribDivisorANGLE(GLuint index, GLuint divisor) { mContext->VertexAttribDivisor(index, divisor); } diff --git a/content/canvas/src/WebGLExtensions.h b/content/canvas/src/WebGLExtensions.h index dcfe0db6cdd..c85ab02c746 100644 --- a/content/canvas/src/WebGLExtensions.h +++ b/content/canvas/src/WebGLExtensions.h @@ -196,12 +196,12 @@ public: WebGLExtensionInstancedArrays(WebGLContext* context); virtual ~WebGLExtensionInstancedArrays(); - void DrawArraysInstancedANGLE(WebGLenum mode, WebGLint first, - WebGLsizei count, WebGLsizei primcount); - void DrawElementsInstancedANGLE(WebGLenum mode, WebGLsizei count, - WebGLenum type, WebGLintptr offset, - WebGLsizei primcount); - void VertexAttribDivisorANGLE(WebGLuint index, WebGLuint divisor); + void DrawArraysInstancedANGLE(GLenum mode, GLint first, + GLsizei count, GLsizei primcount); + void DrawElementsInstancedANGLE(GLenum mode, GLsizei count, + GLenum type, WebGLintptr offset, + GLsizei primcount); + void VertexAttribDivisorANGLE(GLuint index, GLuint divisor); static bool IsSupported(const WebGLContext* context); diff --git a/content/canvas/src/WebGLFramebuffer.cpp b/content/canvas/src/WebGLFramebuffer.cpp index 996854eed3e..655f401a51c 100644 --- a/content/canvas/src/WebGLFramebuffer.cpp +++ b/content/canvas/src/WebGLFramebuffer.cpp @@ -44,7 +44,7 @@ WebGLFramebuffer::Attachment::IsDeleteRequested() const { bool WebGLFramebuffer::Attachment::HasAlpha() const { - WebGLenum format = 0; + GLenum format = 0; if (Texture() && Texture()->HasImageInfoAt(mTextureLevel, mTextureCubeMapFace)) format = Texture()->ImageInfoAt(mTextureLevel, mTextureCubeMapFace).Format(); else if (Renderbuffer()) @@ -57,7 +57,7 @@ WebGLFramebuffer::Attachment::HasAlpha() const { } void -WebGLFramebuffer::Attachment::SetTexture(WebGLTexture *tex, WebGLint level, WebGLenum face) { +WebGLFramebuffer::Attachment::SetTexture(WebGLTexture *tex, GLint level, GLenum face) { mTexturePtr = tex; mRenderbufferPtr = nullptr; mTextureLevel = level; @@ -101,7 +101,7 @@ WebGLFramebuffer::Attachment::IsComplete() const { if (!mTexturePtr->HasImageInfoAt(0, 0)) return false; - WebGLenum format = mTexturePtr->ImageInfoAt(0).Format(); + GLenum format = mTexturePtr->ImageInfoAt(0).Format(); if (mAttachmentPoint == LOCAL_GL_DEPTH_ATTACHMENT) { return format == LOCAL_GL_DEPTH_COMPONENT; @@ -110,7 +110,7 @@ WebGLFramebuffer::Attachment::IsComplete() const { return format == LOCAL_GL_DEPTH_STENCIL; } else if (mAttachmentPoint >= LOCAL_GL_COLOR_ATTACHMENT0 && - mAttachmentPoint < WebGLenum(LOCAL_GL_COLOR_ATTACHMENT0 + WebGLContext::sMaxColorAttachments)) { + mAttachmentPoint < GLenum(LOCAL_GL_COLOR_ATTACHMENT0 + WebGLContext::sMaxColorAttachments)) { return (format == LOCAL_GL_ALPHA || format == LOCAL_GL_LUMINANCE || format == LOCAL_GL_LUMINANCE_ALPHA || @@ -121,7 +121,7 @@ WebGLFramebuffer::Attachment::IsComplete() const { } if (mRenderbufferPtr) { - WebGLenum format = mRenderbufferPtr->InternalFormat(); + GLenum format = mRenderbufferPtr->InternalFormat(); if (mAttachmentPoint == LOCAL_GL_DEPTH_ATTACHMENT) { return format == LOCAL_GL_DEPTH_COMPONENT16; @@ -133,7 +133,7 @@ WebGLFramebuffer::Attachment::IsComplete() const { return format == LOCAL_GL_DEPTH_STENCIL; } else if (mAttachmentPoint >= LOCAL_GL_COLOR_ATTACHMENT0 && - mAttachmentPoint < WebGLenum(LOCAL_GL_COLOR_ATTACHMENT0 + WebGLContext::sMaxColorAttachments)) { + mAttachmentPoint < GLenum(LOCAL_GL_COLOR_ATTACHMENT0 + WebGLContext::sMaxColorAttachments)) { return (format == LOCAL_GL_RGB565 || format == LOCAL_GL_RGB5_A1 || format == LOCAL_GL_RGBA4); @@ -157,9 +157,9 @@ WebGLFramebuffer::Delete() { } void -WebGLFramebuffer::FramebufferRenderbuffer(WebGLenum target, - WebGLenum attachment, - WebGLenum rbtarget, +WebGLFramebuffer::FramebufferRenderbuffer(GLenum target, + GLenum attachment, + GLenum rbtarget, WebGLRenderbuffer *wrb) { MOZ_ASSERT(mContext->mBoundFramebuffer == this); @@ -197,10 +197,10 @@ WebGLFramebuffer::FramebufferRenderbuffer(WebGLenum target, } mContext->MakeContextCurrent(); - WebGLuint parambuffername = wrb ? wrb->GLName() : 0; + GLuint parambuffername = wrb ? wrb->GLName() : 0; if (attachment == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) { - WebGLuint depthbuffername = parambuffername; - WebGLuint stencilbuffername = parambuffername; + GLuint depthbuffername = parambuffername; + GLuint stencilbuffername = parambuffername; if (!parambuffername){ depthbuffername = mDepthAttachment.Renderbuffer() ? mDepthAttachment.Renderbuffer()->GLName() : 0; stencilbuffername = mStencilAttachment.Renderbuffer() ? mStencilAttachment.Renderbuffer()->GLName() : 0; @@ -208,7 +208,7 @@ WebGLFramebuffer::FramebufferRenderbuffer(WebGLenum target, mContext->gl->fFramebufferRenderbuffer(target, LOCAL_GL_DEPTH_ATTACHMENT, rbtarget, depthbuffername); mContext->gl->fFramebufferRenderbuffer(target, LOCAL_GL_STENCIL_ATTACHMENT, rbtarget, stencilbuffername); } else { - WebGLuint renderbuffername = parambuffername; + GLuint renderbuffername = parambuffername; if(!parambuffername && (attachment == LOCAL_GL_DEPTH_ATTACHMENT || attachment == LOCAL_GL_STENCIL_ATTACHMENT)){ renderbuffername = mDepthStencilAttachment.Renderbuffer() ? mDepthStencilAttachment.Renderbuffer()->GLName() : 0; } @@ -217,11 +217,11 @@ WebGLFramebuffer::FramebufferRenderbuffer(WebGLenum target, } void -WebGLFramebuffer::FramebufferTexture2D(WebGLenum target, - WebGLenum attachment, - WebGLenum textarget, +WebGLFramebuffer::FramebufferTexture2D(GLenum target, + GLenum attachment, + GLenum textarget, WebGLTexture *wtex, - WebGLint level) + GLint level) { MOZ_ASSERT(mContext->mBoundFramebuffer == this); if (!mContext->ValidateObjectAllowNull("framebufferTexture2D: texture", @@ -264,10 +264,10 @@ WebGLFramebuffer::FramebufferTexture2D(WebGLenum target, } mContext->MakeContextCurrent(); - WebGLuint paramtexturename = wtex ? wtex->GLName() : 0; + GLuint paramtexturename = wtex ? wtex->GLName() : 0; if (attachment == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) { - WebGLuint depthtexturename = paramtexturename; - WebGLuint stenciltexturename = paramtexturename; + GLuint depthtexturename = paramtexturename; + GLuint stenciltexturename = paramtexturename; if(!paramtexturename){ depthtexturename = mDepthAttachment.Texture() ? mDepthAttachment.Texture()->GLName() : 0; stenciltexturename = mStencilAttachment.Texture() ? mStencilAttachment.Texture()->GLName() : 0; @@ -275,7 +275,7 @@ WebGLFramebuffer::FramebufferTexture2D(WebGLenum target, mContext->gl->fFramebufferTexture2D(target, LOCAL_GL_DEPTH_ATTACHMENT, textarget, depthtexturename, level); mContext->gl->fFramebufferTexture2D(target, LOCAL_GL_STENCIL_ATTACHMENT, textarget, stenciltexturename, level); } else { - WebGLuint texturename = paramtexturename; + GLuint texturename = paramtexturename; if(!paramtexturename && (attachment == LOCAL_GL_DEPTH_ATTACHMENT || attachment == LOCAL_GL_STENCIL_ATTACHMENT)){ texturename = mDepthStencilAttachment.Texture() ? mDepthStencilAttachment.Texture()->GLName() : 0; } @@ -320,7 +320,7 @@ WebGLFramebuffer::HasAttachmentsOfMismatchedDimensions() const { } const WebGLFramebuffer::Attachment& -WebGLFramebuffer::GetAttachment(WebGLenum attachment) const { +WebGLFramebuffer::GetAttachment(GLenum attachment) const { if (attachment == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) return mDepthStencilAttachment; if (attachment == LOCAL_GL_DEPTH_ATTACHMENT) @@ -420,7 +420,7 @@ WebGLFramebuffer::CheckAndInitializeRenderbuffers() mContext->MakeContextCurrent(); - WebGLenum status = mContext->CheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER); + GLenum status = mContext->CheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER); if (status != LOCAL_GL_FRAMEBUFFER_COMPLETE) return false; @@ -471,14 +471,14 @@ WebGLFramebuffer::CheckAndInitializeRenderbuffers() return true; } -bool WebGLFramebuffer::CheckColorAttachementNumber(WebGLenum attachment, const char * functionName) const +bool WebGLFramebuffer::CheckColorAttachementNumber(GLenum attachment, const char * functionName) const { const char* const errorFormating = "%s: attachment: invalid enum value 0x%x"; if (mContext->IsExtensionEnabled(WebGLContext::WEBGL_draw_buffers)) { if (attachment < LOCAL_GL_COLOR_ATTACHMENT0 || - attachment > WebGLenum(LOCAL_GL_COLOR_ATTACHMENT0 + mContext->mGLMaxColorAttachments)) + attachment > GLenum(LOCAL_GL_COLOR_ATTACHMENT0 + mContext->mGLMaxColorAttachments)) { mContext->ErrorInvalidEnum(errorFormating, functionName, attachment); return false; diff --git a/content/canvas/src/WebGLFramebuffer.h b/content/canvas/src/WebGLFramebuffer.h index d627acf6841..86a9a2770b1 100644 --- a/content/canvas/src/WebGLFramebuffer.h +++ b/content/canvas/src/WebGLFramebuffer.h @@ -35,11 +35,11 @@ public: // deleting a texture or renderbuffer immediately detaches it WebGLRefPtr mTexturePtr; WebGLRefPtr mRenderbufferPtr; - WebGLenum mAttachmentPoint; - WebGLint mTextureLevel; - WebGLenum mTextureCubeMapFace; + GLenum mAttachmentPoint; + GLint mTextureLevel; + GLenum mTextureCubeMapFace; - Attachment(WebGLenum aAttachmentPoint = LOCAL_GL_COLOR_ATTACHMENT0) + Attachment(GLenum aAttachmentPoint = LOCAL_GL_COLOR_ATTACHMENT0) : mAttachmentPoint(aAttachmentPoint) {} @@ -51,7 +51,7 @@ public: bool HasAlpha() const; - void SetTexture(WebGLTexture *tex, WebGLint level, WebGLenum face); + void SetTexture(WebGLTexture *tex, GLint level, GLenum face); void SetRenderbuffer(WebGLRenderbuffer *rb) { mTexturePtr = nullptr; mRenderbufferPtr = rb; @@ -68,10 +68,10 @@ public: WebGLRenderbuffer *Renderbuffer() { return mRenderbufferPtr; } - WebGLint TextureLevel() const { + GLint TextureLevel() const { return mTextureLevel; } - WebGLenum TextureCubeMapFace() const { + GLenum TextureCubeMapFace() const { return mTextureCubeMapFace; } @@ -92,18 +92,18 @@ public: bool HasEverBeenBound() { return mHasEverBeenBound; } void SetHasEverBeenBound(bool x) { mHasEverBeenBound = x; } - WebGLuint GLName() { return mGLName; } + GLuint GLName() { return mGLName; } - void FramebufferRenderbuffer(WebGLenum target, - WebGLenum attachment, - WebGLenum rbtarget, + void FramebufferRenderbuffer(GLenum target, + GLenum attachment, + GLenum rbtarget, WebGLRenderbuffer *wrb); - void FramebufferTexture2D(WebGLenum target, - WebGLenum attachment, - WebGLenum textarget, + void FramebufferTexture2D(GLenum target, + GLenum attachment, + GLenum textarget, WebGLTexture *wtex, - WebGLint level); + GLint level); bool HasIncompleteAttachment() const; @@ -131,7 +131,7 @@ public: return mDepthStencilAttachment; } - const Attachment& GetAttachment(WebGLenum attachment) const; + const Attachment& GetAttachment(GLenum attachment) const; void DetachTexture(const WebGLTexture *tex); @@ -153,9 +153,9 @@ public: bool CheckAndInitializeRenderbuffers(); - bool CheckColorAttachementNumber(WebGLenum attachment, const char * functionName) const; + bool CheckColorAttachementNumber(GLenum attachment, const char * functionName) const; - WebGLuint mGLName; + GLuint mGLName; bool mHasEverBeenBound; void EnsureColorAttachments(size_t colorAttachmentId); diff --git a/content/canvas/src/WebGLObjectModel.h b/content/canvas/src/WebGLObjectModel.h index a4cd7c59492..6d595e9fbf0 100644 --- a/content/canvas/src/WebGLObjectModel.h +++ b/content/canvas/src/WebGLObjectModel.h @@ -280,16 +280,16 @@ public: WebGLRectangleObject() : mWidth(0), mHeight(0) { } - WebGLRectangleObject(WebGLsizei width, WebGLsizei height) + WebGLRectangleObject(GLsizei width, GLsizei height) : mWidth(width), mHeight(height) { } - WebGLsizei Width() const { return mWidth; } - void width(WebGLsizei value) { mWidth = value; } + GLsizei Width() const { return mWidth; } + void width(GLsizei value) { mWidth = value; } - WebGLsizei Height() const { return mHeight; } - void height(WebGLsizei value) { mHeight = value; } + GLsizei Height() const { return mHeight; } + void height(GLsizei value) { mHeight = value; } - void setDimensions(WebGLsizei width, WebGLsizei height) { + void setDimensions(GLsizei width, GLsizei height) { mWidth = width; mHeight = height; } @@ -309,8 +309,8 @@ public: } protected: - WebGLsizei mWidth; - WebGLsizei mHeight; + GLsizei mWidth; + GLsizei mHeight; }; }// namespace mozilla diff --git a/content/canvas/src/WebGLProgram.h b/content/canvas/src/WebGLProgram.h index a03f7a7311d..d4b4ad5b46d 100644 --- a/content/canvas/src/WebGLProgram.h +++ b/content/canvas/src/WebGLProgram.h @@ -40,7 +40,7 @@ public: mAttachedShaders.Clear(); } - WebGLuint GLName() { return mGLName; } + GLuint GLName() { return mGLName; } const nsTArray >& AttachedShaders() const { return mAttachedShaders; } bool LinkStatus() { return mLinkStatus; } uint32_t Generation() const { return mGeneration.value(); } @@ -114,7 +114,7 @@ public: protected: - WebGLuint mGLName; + GLuint mGLName; bool mLinkStatus; // attached shaders of the program object nsTArray > mAttachedShaders; diff --git a/content/canvas/src/WebGLQuery.h b/content/canvas/src/WebGLQuery.h index af51e378163..fd12a450fa8 100644 --- a/content/canvas/src/WebGLQuery.h +++ b/content/canvas/src/WebGLQuery.h @@ -80,8 +80,8 @@ private: // ------------------------------------------------------------------------- // MEMBERS - WebGLuint mGLName; - WebGLenum mType; + GLuint mGLName; + GLenum mType; // ------------------------------------------------------------------------- // FRIENDSHIPS diff --git a/content/canvas/src/WebGLRenderbuffer.h b/content/canvas/src/WebGLRenderbuffer.h index f18a8de2fce..687ce027884 100644 --- a/content/canvas/src/WebGLRenderbuffer.h +++ b/content/canvas/src/WebGLRenderbuffer.h @@ -32,16 +32,16 @@ public: bool HasEverBeenBound() { return mHasEverBeenBound; } void SetHasEverBeenBound(bool x) { mHasEverBeenBound = x; } - WebGLuint GLName() const { return mGLName; } + GLuint GLName() const { return mGLName; } bool Initialized() const { return mInitialized; } void SetInitialized(bool aInitialized) { mInitialized = aInitialized; } - WebGLenum InternalFormat() const { return mInternalFormat; } - void SetInternalFormat(WebGLenum aInternalFormat) { mInternalFormat = aInternalFormat; } + GLenum InternalFormat() const { return mInternalFormat; } + void SetInternalFormat(GLenum aInternalFormat) { mInternalFormat = aInternalFormat; } - WebGLenum InternalFormatForGL() const { return mInternalFormatForGL; } - void SetInternalFormatForGL(WebGLenum aInternalFormatForGL) { mInternalFormatForGL = aInternalFormatForGL; } + GLenum InternalFormatForGL() const { return mInternalFormatForGL; } + void SetInternalFormatForGL(GLenum aInternalFormatForGL) { mInternalFormatForGL = aInternalFormatForGL; } int64_t MemoryUsage() const; @@ -57,9 +57,9 @@ public: protected: - WebGLuint mGLName; - WebGLenum mInternalFormat; - WebGLenum mInternalFormatForGL; + GLuint mGLName; + GLenum mInternalFormat; + GLenum mInternalFormatForGL; bool mHasEverBeenBound; bool mInitialized; diff --git a/content/canvas/src/WebGLShader.cpp b/content/canvas/src/WebGLShader.cpp index 2dc4d4c91b2..943357096b6 100644 --- a/content/canvas/src/WebGLShader.cpp +++ b/content/canvas/src/WebGLShader.cpp @@ -16,7 +16,7 @@ WebGLShader::WrapObject(JSContext *cx, JS::Handle scope) { return dom::WebGLShaderBinding::Wrap(cx, scope, this); } -WebGLShader::WebGLShader(WebGLContext *context, WebGLenum stype) +WebGLShader::WebGLShader(WebGLContext *context, GLenum stype) : WebGLContextBoundObject(context) , mType(stype) , mNeedsTranslation(true) diff --git a/content/canvas/src/WebGLShader.h b/content/canvas/src/WebGLShader.h index e8cdec9d8aa..ef4fe6b3d57 100644 --- a/content/canvas/src/WebGLShader.h +++ b/content/canvas/src/WebGLShader.h @@ -33,7 +33,7 @@ class WebGLShader MOZ_FINAL friend class WebGLProgram; public: - WebGLShader(WebGLContext *context, WebGLenum stype); + WebGLShader(WebGLContext *context, GLenum stype); ~WebGLShader() { DeleteOnce(); @@ -41,8 +41,8 @@ public: size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; - WebGLuint GLName() { return mGLName; } - WebGLenum ShaderType() { return mType; } + GLuint GLName() { return mGLName; } + GLenum ShaderType() { return mType; } void SetSource(const nsAString& src) { // XXX do some quick gzip here maybe -- getting this will be very rare @@ -84,8 +84,8 @@ public: protected: - WebGLuint mGLName; - WebGLenum mType; + GLuint mGLName; + GLenum mType; nsString mSource; nsCString mTranslationLog; // The translation log should contain only ASCII characters bool mNeedsTranslation; diff --git a/content/canvas/src/WebGLShaderPrecisionFormat.h b/content/canvas/src/WebGLShaderPrecisionFormat.h index 016c4aa770f..9645552b291 100644 --- a/content/canvas/src/WebGLShaderPrecisionFormat.h +++ b/content/canvas/src/WebGLShaderPrecisionFormat.h @@ -16,7 +16,7 @@ class WebGLShaderPrecisionFormat MOZ_FINAL : public WebGLContextBoundObject { public: - WebGLShaderPrecisionFormat(WebGLContext *context, WebGLint rangeMin, WebGLint rangeMax, WebGLint precision) : + WebGLShaderPrecisionFormat(WebGLContext *context, GLint rangeMin, GLint rangeMax, GLint precision) : WebGLContextBoundObject(context), mRangeMin(rangeMin), mRangeMax(rangeMax), @@ -27,22 +27,22 @@ public: JSObject* WrapObject(JSContext *cx, JS::Handle scope); // WebIDL WebGLShaderPrecisionFormat API - WebGLint RangeMin() const { + GLint RangeMin() const { return mRangeMin; } - WebGLint RangeMax() const { + GLint RangeMax() const { return mRangeMax; } - WebGLint Precision() const { + GLint Precision() const { return mPrecision; } NS_INLINE_DECL_REFCOUNTING(WebGLShaderPrecisionFormat) protected: - WebGLint mRangeMin; - WebGLint mRangeMax; - WebGLint mPrecision; + GLint mRangeMin; + GLint mRangeMax; + GLint mPrecision; }; } // namespace mozilla diff --git a/content/canvas/src/WebGLTexture.cpp b/content/canvas/src/WebGLTexture.cpp index 1f23096eeea..e3a6a42dd04 100644 --- a/content/canvas/src/WebGLTexture.cpp +++ b/content/canvas/src/WebGLTexture.cpp @@ -102,7 +102,7 @@ WebGLTexture::SetDontKnowIfNeedFakeBlack() { } void -WebGLTexture::Bind(WebGLenum aTarget) { +WebGLTexture::Bind(GLenum aTarget) { // this function should only be called by bindTexture(). // it assumes that the GL context is already current. @@ -135,9 +135,9 @@ WebGLTexture::Bind(WebGLenum aTarget) { } void -WebGLTexture::SetImageInfo(WebGLenum aTarget, WebGLint aLevel, - WebGLsizei aWidth, WebGLsizei aHeight, - WebGLenum aFormat, WebGLenum aType) +WebGLTexture::SetImageInfo(GLenum aTarget, GLint aLevel, + GLsizei aWidth, GLsizei aHeight, + GLenum aFormat, GLenum aType) { if ( (aTarget == LOCAL_GL_TEXTURE_2D) != (mTarget == LOCAL_GL_TEXTURE_2D) ) return; @@ -173,11 +173,11 @@ WebGLTexture::SetCustomMipmap() { ImageInfo imageInfo = ImageInfoAt(0, 0); NS_ASSERTION(imageInfo.IsPowerOfTwo(), "this texture is NPOT, so how could GenerateMipmap() ever accept it?"); - WebGLsizei size = std::max(imageInfo.mWidth, imageInfo.mHeight); + GLsizei size = std::max(imageInfo.mWidth, imageInfo.mHeight); // so, the size is a power of two, let's find its log in base 2. size_t maxLevel = 0; - for (WebGLsizei n = size; n > 1; n >>= 1) + for (GLsizei n = size; n > 1; n >>= 1) ++maxLevel; EnsureMaxLevelWithCustomImagesAtLeast(maxLevel); diff --git a/content/canvas/src/WebGLTexture.h b/content/canvas/src/WebGLTexture.h index e4a29d5415e..613a873ad0d 100644 --- a/content/canvas/src/WebGLTexture.h +++ b/content/canvas/src/WebGLTexture.h @@ -16,7 +16,7 @@ namespace mozilla { // Zero is not an integer power of two. -inline bool is_pot_assuming_nonnegative(WebGLsizei x) +inline bool is_pot_assuming_nonnegative(GLsizei x) { return x && (x & (x-1)) == 0; } @@ -40,7 +40,7 @@ public: bool HasEverBeenBound() { return mHasEverBeenBound; } void SetHasEverBeenBound(bool x) { mHasEverBeenBound = x; } - WebGLuint GLName() { return mGLName; } + GLuint GLName() { return mGLName; } GLenum Target() const { return mTarget; } WebGLContext *GetParentObject() const { @@ -59,7 +59,7 @@ protected: friend class WebGLFramebuffer; bool mHasEverBeenBound; - WebGLuint mGLName; + GLuint mGLName; // we store information about the various images that are part of // this texture (cubemap faces, mipmap levels) @@ -74,8 +74,8 @@ public: , mIsDefined(false) {} - ImageInfo(WebGLsizei width, WebGLsizei height, - WebGLenum format, WebGLenum type) + ImageInfo(GLsizei width, GLsizei height, + GLenum format, GLenum type) : WebGLRectangleObject(width, height) , mFormat(format) , mType(type) @@ -103,10 +103,10 @@ public: is_pot_assuming_nonnegative(mHeight); // negative sizes should never happen (caught in texImage2D...) } int64_t MemoryUsage() const; - WebGLenum Format() const { return mFormat; } - WebGLenum Type() const { return mType; } + GLenum Format() const { return mFormat; } + GLenum Type() const { return mType; } protected: - WebGLenum mFormat, mType; + GLenum mFormat, mType; bool mIsDefined; friend class WebGLTexture; @@ -132,7 +132,7 @@ public: ImageInfoAt(level, face).mIsDefined; } - static size_t FaceForTarget(WebGLenum target) { + static size_t FaceForTarget(GLenum target) { return target == LOCAL_GL_TEXTURE_2D ? 0 : target - LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X; } @@ -140,8 +140,8 @@ public: protected: - WebGLenum mTarget; - WebGLenum mMinFilter, mMagFilter, mWrapS, mWrapT; + GLenum mTarget; + GLenum mMinFilter, mMagFilter, mWrapS, mWrapT; size_t mFacesCount, mMaxLevelWithCustomImages; nsTArray mImageInfos; @@ -170,29 +170,29 @@ public: void SetDontKnowIfNeedFakeBlack(); - void Bind(WebGLenum aTarget); + void Bind(GLenum aTarget); - void SetImageInfo(WebGLenum aTarget, WebGLint aLevel, - WebGLsizei aWidth, WebGLsizei aHeight, - WebGLenum aFormat, WebGLenum aType); + void SetImageInfo(GLenum aTarget, GLint aLevel, + GLsizei aWidth, GLsizei aHeight, + GLenum aFormat, GLenum aType); - void SetMinFilter(WebGLenum aMinFilter) { + void SetMinFilter(GLenum aMinFilter) { mMinFilter = aMinFilter; SetDontKnowIfNeedFakeBlack(); } - void SetMagFilter(WebGLenum aMagFilter) { + void SetMagFilter(GLenum aMagFilter) { mMagFilter = aMagFilter; SetDontKnowIfNeedFakeBlack(); } - void SetWrapS(WebGLenum aWrapS) { + void SetWrapS(GLenum aWrapS) { mWrapS = aWrapS; SetDontKnowIfNeedFakeBlack(); } - void SetWrapT(WebGLenum aWrapT) { + void SetWrapT(GLenum aWrapT) { mWrapT = aWrapT; SetDontKnowIfNeedFakeBlack(); } - WebGLenum MinFilter() const { return mMinFilter; } + GLenum MinFilter() const { return mMinFilter; } bool DoesMinFilterRequireMipmap() const { return !(mMinFilter == LOCAL_GL_NEAREST || mMinFilter == LOCAL_GL_LINEAR); diff --git a/content/canvas/src/WebGLTypes.h b/content/canvas/src/WebGLTypes.h index af1ec5ee26b..1e77b3d85c8 100644 --- a/content/canvas/src/WebGLTypes.h +++ b/content/canvas/src/WebGLTypes.h @@ -6,16 +6,10 @@ #ifndef WEBGLTYPES_H_ #define WEBGLTYPES_H_ -// Manual reflection of WebIDL typedefs -typedef uint32_t WebGLenum; -typedef uint32_t WebGLbitfield; -typedef int32_t WebGLint; -typedef int32_t WebGLsizei; +// Manual reflection of WebIDL typedefs that are different from the +// corresponding OpenGL typedefs. typedef int64_t WebGLsizeiptr; typedef int64_t WebGLintptr; -typedef uint32_t WebGLuint; -typedef float WebGLfloat; -typedef float WebGLclampf; typedef bool WebGLboolean; namespace mozilla { diff --git a/content/canvas/src/WebGLVertexArray.cpp b/content/canvas/src/WebGLVertexArray.cpp index b0e77e79021..569ad642f61 100644 --- a/content/canvas/src/WebGLVertexArray.cpp +++ b/content/canvas/src/WebGLVertexArray.cpp @@ -36,10 +36,10 @@ void WebGLVertexArray::Delete() { mAttribBuffers.Clear(); } -bool WebGLVertexArray::EnsureAttribIndex(WebGLuint index, const char *info) +bool WebGLVertexArray::EnsureAttribIndex(GLuint index, const char *info) { - if (index >= WebGLuint(mContext->mGLMaxVertexAttribs)) { - if (index == WebGLuint(-1)) { + if (index >= GLuint(mContext->mGLMaxVertexAttribs)) { + if (index == GLuint(-1)) { mContext->ErrorInvalidValue("%s: index -1 is invalid. That probably comes from a getAttribLocation() call, " "where this return value -1 means that the passed name didn't correspond to an active attribute in " "the specified program.", info); diff --git a/content/canvas/src/WebGLVertexArray.h b/content/canvas/src/WebGLVertexArray.h index 97720029962..2d87bc08dd6 100644 --- a/content/canvas/src/WebGLVertexArray.h +++ b/content/canvas/src/WebGLVertexArray.h @@ -58,9 +58,9 @@ public: bool HasEverBeenBound() { return mHasEverBeenBound; } void SetHasEverBeenBound(bool x) { mHasEverBeenBound = x; } - WebGLuint GLName() const { return mGLName; } + GLuint GLName() const { return mGLName; } - bool EnsureAttribIndex(WebGLuint index, const char *info); + bool EnsureAttribIndex(GLuint index, const char *info); // ----------------------------------------------------------------------------- @@ -70,7 +70,7 @@ private: // ------------------------------------------------------------------------- // MEMBERS - WebGLuint mGLName; + GLuint mGLName; bool mHasEverBeenBound; nsTArray mAttribBuffers; WebGLRefPtr mBoundElementArrayBuffer; diff --git a/content/canvas/src/WebGLVertexAttribData.h b/content/canvas/src/WebGLVertexAttribData.h index 16d175fb2d9..86f4233b358 100644 --- a/content/canvas/src/WebGLVertexAttribData.h +++ b/content/canvas/src/WebGLVertexAttribData.h @@ -24,9 +24,9 @@ struct WebGLVertexAttribData { { } WebGLRefPtr buf; - WebGLuint stride; - WebGLuint size; - WebGLuint divisor; + GLuint stride; + GLuint size; + GLuint divisor; GLuint byteOffset; GLenum type; bool enabled; From e915fc8cb0b53addc18791167613e6fc16bbc1fd Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Wed, 4 Sep 2013 08:14:44 -0400 Subject: [PATCH 070/171] Bug 911856 - Remove the custom concept of "stable context" in favor of the standard concept of "lost context" - r=jgilbert --- content/canvas/src/WebGLContext.cpp | 12 +- content/canvas/src/WebGLContext.h | 34 ++-- .../canvas/src/WebGLContextAsyncQueries.cpp | 14 +- content/canvas/src/WebGLContextBuffers.cpp | 22 +-- content/canvas/src/WebGLContextExtensions.cpp | 4 +- .../src/WebGLContextFramebufferOperations.cpp | 16 +- content/canvas/src/WebGLContextGL.cpp | 154 +++++++++--------- content/canvas/src/WebGLContextState.cpp | 10 +- content/canvas/src/WebGLContextValidate.cpp | 8 +- .../canvas/src/WebGLContextVertexArray.cpp | 8 +- content/canvas/src/WebGLContextVertices.cpp | 28 ++-- content/canvas/src/WebGLTypes.h | 7 +- 12 files changed, 159 insertions(+), 158 deletions(-) diff --git a/content/canvas/src/WebGLContext.cpp b/content/canvas/src/WebGLContext.cpp index 34b3c574d3d..dadddcf9117 100644 --- a/content/canvas/src/WebGLContext.cpp +++ b/content/canvas/src/WebGLContext.cpp @@ -184,7 +184,7 @@ WebGLContext::WebGLContext() mContextLossTimerRunning = false; mDrawSinceContextLossTimerSet = false; mContextRestorer = do_CreateInstance("@mozilla.org/timer;1"); - mContextStatus = ContextStable; + mContextStatus = ContextNotLost; mContextLostErrorSet = false; mLoseContextOnHeapMinimize = false; mCanLoseContextInForeground = true; @@ -844,7 +844,7 @@ WebGLContext::GetCanvasLayer(nsDisplayListBuilder* aBuilder, CanvasLayer *aOldLayer, LayerManager *aManager) { - if (!IsContextStable()) + if (IsContextLost()) return nullptr; if (!mResetLayer && aOldLayer && @@ -899,7 +899,7 @@ void WebGLContext::GetContextAttributes(Nullable &retval) { retval.SetNull(); - if (!IsContextStable()) + if (IsContextLost()) return; dom::WebGLContextAttributes& result = retval.SetValue(); @@ -918,7 +918,7 @@ WebGLContext::GetContextAttributes(NullableOwnerDoc(), static_cast(mCanvasElement), NS_LITERAL_STRING("webglcontextrestored"), @@ -1240,7 +1240,7 @@ void WebGLContext::MaybeRestoreContext() { // Don't try to handle it if we already know it's busted. - if (mContextStatus != ContextStable || gl == nullptr) + if (mContextStatus != ContextNotLost || gl == nullptr) return; bool isEGL = gl->GetContextType() == GLContext::ContextTypeEGL, diff --git a/content/canvas/src/WebGLContext.h b/content/canvas/src/WebGLContext.h index 603d2a69a6c..0025417cf3a 100644 --- a/content/canvas/src/WebGLContext.h +++ b/content/canvas/src/WebGLContext.h @@ -297,18 +297,18 @@ public: return mCanvasElement; } GLsizei DrawingBufferWidth() const { - if (!IsContextStable()) + if (IsContextLost()) return 0; return mWidth; } GLsizei DrawingBufferHeight() const { - if (!IsContextStable()) + if (IsContextLost()) return 0; return mHeight; } - + void GetContextAttributes(dom::Nullable& retval); - bool IsContextLost() const { return !IsContextStable(); } + bool IsContextLost() const { return mContextStatus != ContextNotLost; } void GetSupportedExtensions(JSContext *cx, dom::Nullable< nsTArray > &retval); JSObject* GetExtension(JSContext* cx, const nsAString& aName, ErrorResult& rv); void ActiveTexture(GLenum texture); @@ -320,7 +320,7 @@ public: void BindTexture(GLenum target, WebGLTexture *tex); void BindVertexArray(WebGLVertexArray *vao); void BlendColor(GLclampf r, GLclampf g, GLclampf b, GLclampf a) { - if (!IsContextStable()) + if (IsContextLost()) return; MakeContextCurrent(); gl->fBlendColor(r, g, b, a); @@ -371,13 +371,13 @@ public: void DetachShader(WebGLProgram *program, WebGLShader *shader); void DrawBuffers(const dom::Sequence& buffers); void Flush() { - if (!IsContextStable()) + if (IsContextLost()) return; MakeContextCurrent(); gl->fFlush(); } void Finish() { - if (!IsContextStable()) + if (IsContextLost()) return; MakeContextCurrent(); gl->fFinish(); @@ -446,7 +446,7 @@ public: bool IsTexture(WebGLTexture *tex); bool IsVertexArray(WebGLVertexArray *vao); void LineWidth(GLfloat width) { - if (!IsContextStable()) + if (IsContextLost()) return; MakeContextCurrent(); gl->fLineWidth(width); @@ -454,7 +454,7 @@ public: void LinkProgram(WebGLProgram *program); void PixelStorei(GLenum pname, GLint param); void PolygonOffset(GLfloat factor, GLfloat units) { - if (!IsContextStable()) + if (IsContextLost()) return; MakeContextCurrent(); gl->fPolygonOffset(factor, units); @@ -466,7 +466,7 @@ public: void RenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height); void SampleCoverage(GLclampf value, WebGLboolean invert) { - if (!IsContextStable()) + if (IsContextLost()) return; MakeContextCurrent(); gl->fSampleCoverage(value, invert); @@ -497,7 +497,7 @@ public: GLenum internalformat, GLenum format, GLenum type, ElementType& elt, ErrorResult& rv) { - if (!IsContextStable()) + if (IsContextLost()) return; nsRefPtr isurf; WebGLTexelFormat srcFormat; @@ -536,7 +536,7 @@ public: GLint xoffset, GLint yoffset, GLenum format, GLenum type, ElementType& elt, ErrorResult& rv) { - if (!IsContextStable()) + if (IsContextLost()) return; nsRefPtr isurf; WebGLTexelFormat srcFormat; @@ -943,13 +943,14 @@ protected: int32_t mGLMaxDrawBuffers; uint32_t mGLMaxTransformFeedbackSeparateAttribs; - // Represents current status, or state, of the context. That is, is it lost - // or stable and what part of the context lost process are we currently at. + // Represents current status of the context with respect to context loss. + // That is, whether the context is lost, and what part of the context loss + // process we currently are at. // This is used to support the WebGL spec's asyncronous nature in handling // context loss. enum ContextStatus { // The context is stable; there either are none or we don't know of any. - ContextStable, + ContextNotLost, // The context has been lost, but we have not yet sent an event to the // script informing it of this. ContextLostAwaitingEvent, @@ -1139,9 +1140,6 @@ protected: const GLvoid *data); void MaybeRestoreContext(); - bool IsContextStable() const { - return mContextStatus == ContextStable; - } void ForceLoseContext(); void ForceRestoreContext(); diff --git a/content/canvas/src/WebGLContextAsyncQueries.cpp b/content/canvas/src/WebGLContextAsyncQueries.cpp index ae20a568761..228739bc7c9 100644 --- a/content/canvas/src/WebGLContextAsyncQueries.cpp +++ b/content/canvas/src/WebGLContextAsyncQueries.cpp @@ -56,7 +56,7 @@ SimulateOcclusionQueryTarget(const gl::GLContext* gl, GLenum target) already_AddRefed WebGLContext::CreateQuery() { - if (!IsContextStable()) + if (IsContextLost()) return nullptr; if (mActiveOcclusionQuery && !gl->IsGLES2()) { @@ -81,7 +81,7 @@ WebGLContext::CreateQuery() void WebGLContext::DeleteQuery(WebGLQuery *query) { - if (!IsContextStable()) + if (IsContextLost()) return; if (!query) @@ -110,7 +110,7 @@ WebGLContext::DeleteQuery(WebGLQuery *query) void WebGLContext::BeginQuery(GLenum target, WebGLQuery *query) { - if (!IsContextStable()) + if (IsContextLost()) return; WebGLRefPtr* targetSlot = GetQueryTargetSlot(target, "beginQuery"); @@ -180,7 +180,7 @@ WebGLContext::BeginQuery(GLenum target, WebGLQuery *query) void WebGLContext::EndQuery(GLenum target) { - if (!IsContextStable()) + if (IsContextLost()) return; WebGLRefPtr* targetSlot = GetQueryTargetSlot(target, "endQuery"); @@ -222,7 +222,7 @@ WebGLContext::EndQuery(GLenum target) bool WebGLContext::IsQuery(WebGLQuery *query) { - if (!IsContextStable()) + if (IsContextLost()) return false; if (!query) @@ -236,7 +236,7 @@ WebGLContext::IsQuery(WebGLQuery *query) already_AddRefed WebGLContext::GetQuery(GLenum target, GLenum pname) { - if (!IsContextStable()) + if (IsContextLost()) return nullptr; WebGLRefPtr* targetSlot = GetQueryTargetSlot(target, "getQuery"); @@ -259,7 +259,7 @@ WebGLContext::GetQuery(GLenum target, GLenum pname) JS::Value WebGLContext::GetQueryObject(JSContext* cx, WebGLQuery *query, GLenum pname) { - if (!IsContextStable()) + if (IsContextLost()) return JS::NullValue(); if (!query) { diff --git a/content/canvas/src/WebGLContextBuffers.cpp b/content/canvas/src/WebGLContextBuffers.cpp index 3174360d587..8d7d7548161 100644 --- a/content/canvas/src/WebGLContextBuffers.cpp +++ b/content/canvas/src/WebGLContextBuffers.cpp @@ -13,7 +13,7 @@ using namespace mozilla::dom; void WebGLContext::BindBuffer(GLenum target, WebGLBuffer *buffer) { - if (!IsContextStable()) + if (IsContextLost()) return; if (!ValidateObjectAllowDeletedOrNull("bindBuffer", buffer)) @@ -48,7 +48,7 @@ WebGLContext::BindBuffer(GLenum target, WebGLBuffer *buffer) void WebGLContext::BindBufferBase(GLenum target, GLuint index, WebGLBuffer* buffer) { - if (!IsContextStable()) + if (IsContextLost()) return; if (!ValidateObjectAllowDeletedOrNull("bindBufferBase", buffer)) @@ -90,7 +90,7 @@ void WebGLContext::BindBufferRange(GLenum target, GLuint index, WebGLBuffer* buffer, WebGLintptr offset, WebGLsizeiptr size) { - if (!IsContextStable()) + if (IsContextLost()) return; if (!ValidateObjectAllowDeletedOrNull("bindBufferRange", buffer)) @@ -137,7 +137,7 @@ void WebGLContext::BufferData(GLenum target, WebGLsizeiptr size, GLenum usage) { - if (!IsContextStable()) + if (IsContextLost()) return; WebGLRefPtr* bufferSlot = GetBufferSlotByTarget(target, "bufferData"); @@ -187,7 +187,7 @@ WebGLContext::BufferData(GLenum target, const Nullable &maybeData, GLenum usage) { - if (!IsContextStable()) + if (IsContextLost()) return; if (maybeData.IsNull()) { @@ -235,7 +235,7 @@ void WebGLContext::BufferData(GLenum target, const ArrayBufferView& data, GLenum usage) { - if (!IsContextStable()) + if (IsContextLost()) return; WebGLRefPtr* bufferSlot = GetBufferSlotByTarget(target, "bufferSubData"); @@ -275,7 +275,7 @@ void WebGLContext::BufferSubData(GLenum target, WebGLsizeiptr byteOffset, const Nullable &maybeData) { - if (!IsContextStable()) + if (IsContextLost()) return; if (maybeData.IsNull()) { @@ -318,7 +318,7 @@ void WebGLContext::BufferSubData(GLenum target, WebGLsizeiptr byteOffset, const ArrayBufferView& data) { - if (!IsContextStable()) + if (IsContextLost()) return; WebGLRefPtr* bufferSlot = GetBufferSlotByTarget(target, "bufferSubData"); @@ -352,7 +352,7 @@ WebGLContext::BufferSubData(GLenum target, WebGLsizeiptr byteOffset, already_AddRefed WebGLContext::CreateBuffer() { - if (!IsContextStable()) + if (IsContextLost()) return nullptr; nsRefPtr globj = new WebGLBuffer(this); @@ -362,7 +362,7 @@ WebGLContext::CreateBuffer() void WebGLContext::DeleteBuffer(WebGLBuffer *buffer) { - if (!IsContextStable()) + if (IsContextLost()) return; if (!ValidateObjectAllowDeletedOrNull("deleteBuffer", buffer)) @@ -392,7 +392,7 @@ WebGLContext::DeleteBuffer(WebGLBuffer *buffer) bool WebGLContext::IsBuffer(WebGLBuffer *buffer) { - if (!IsContextStable()) + if (IsContextLost()) return false; return ValidateObjectAllowDeleted("isBuffer", buffer) && diff --git a/content/canvas/src/WebGLContextExtensions.cpp b/content/canvas/src/WebGLContextExtensions.cpp index d2813bf2431..4a19bda07cf 100644 --- a/content/canvas/src/WebGLContextExtensions.cpp +++ b/content/canvas/src/WebGLContextExtensions.cpp @@ -136,7 +136,7 @@ CompareWebGLExtensionName(const nsACString& name, const char *other) JSObject* WebGLContext::GetExtension(JSContext *cx, const nsAString& aName, ErrorResult& rv) { - if (!IsContextStable()) + if (IsContextLost()) return nullptr; NS_LossyConvertUTF16toASCII name(aName); @@ -257,7 +257,7 @@ void WebGLContext::GetSupportedExtensions(JSContext *cx, Nullable< nsTArray > &retval) { retval.SetNull(); - if (!IsContextStable()) + if (IsContextLost()) return; nsTArray& arr = retval.SetValue(); diff --git a/content/canvas/src/WebGLContextFramebufferOperations.cpp b/content/canvas/src/WebGLContextFramebufferOperations.cpp index cadbbb704e4..03ceebdaeb0 100644 --- a/content/canvas/src/WebGLContextFramebufferOperations.cpp +++ b/content/canvas/src/WebGLContextFramebufferOperations.cpp @@ -13,7 +13,7 @@ using namespace mozilla; void WebGLContext::Clear(GLbitfield mask) { - if (!IsContextStable()) + if (IsContextLost()) return; MakeContextCurrent(); @@ -92,7 +92,7 @@ void WebGLContext::ClearColor(GLclampf r, GLclampf g, GLclampf b, GLclampf a) { - if (!IsContextStable()) + if (IsContextLost()) return; MakeContextCurrent(); @@ -106,7 +106,7 @@ WebGLContext::ClearColor(GLclampf r, GLclampf g, void WebGLContext::ClearDepth(GLclampf v) { - if (!IsContextStable()) + if (IsContextLost()) return; MakeContextCurrent(); @@ -117,7 +117,7 @@ WebGLContext::ClearDepth(GLclampf v) void WebGLContext::ClearStencil(GLint v) { - if (!IsContextStable()) + if (IsContextLost()) return; MakeContextCurrent(); @@ -128,7 +128,7 @@ WebGLContext::ClearStencil(GLint v) void WebGLContext::ColorMask(WebGLboolean r, WebGLboolean g, WebGLboolean b, WebGLboolean a) { - if (!IsContextStable()) + if (IsContextLost()) return; MakeContextCurrent(); @@ -142,7 +142,7 @@ WebGLContext::ColorMask(WebGLboolean r, WebGLboolean g, WebGLboolean b, WebGLboo void WebGLContext::DepthMask(WebGLboolean b) { - if (!IsContextStable()) + if (IsContextLost()) return; MakeContextCurrent(); @@ -229,7 +229,7 @@ WebGLContext::DrawBuffers(const dom::Sequence& buffers) void WebGLContext::StencilMask(GLuint mask) { - if (!IsContextStable()) + if (IsContextLost()) return; mStencilWriteMaskFront = mask; @@ -242,7 +242,7 @@ WebGLContext::StencilMask(GLuint mask) void WebGLContext::StencilMaskSeparate(GLenum face, GLuint mask) { - if (!IsContextStable()) + if (IsContextLost()) return; if (!ValidateFaceEnum(face, "stencilMaskSeparate: face")) diff --git a/content/canvas/src/WebGLContextGL.cpp b/content/canvas/src/WebGLContextGL.cpp index 6eccaa021e2..adb0f88d8c1 100644 --- a/content/canvas/src/WebGLContextGL.cpp +++ b/content/canvas/src/WebGLContextGL.cpp @@ -63,7 +63,7 @@ inline const WebGLRectangleObject *WebGLContext::FramebufferRectangleObject() co void WebGLContext::ActiveTexture(GLenum texture) { - if (!IsContextStable()) + if (IsContextLost()) return; if (texture < LOCAL_GL_TEXTURE0 || @@ -84,7 +84,7 @@ WebGLContext::ActiveTexture(GLenum texture) void WebGLContext::AttachShader(WebGLProgram *program, WebGLShader *shader) { - if (!IsContextStable()) + if (IsContextLost()) return; if (!ValidateObject("attachShader: program", program) || @@ -106,7 +106,7 @@ void WebGLContext::BindAttribLocation(WebGLProgram *prog, GLuint location, const nsAString& name) { - if (!IsContextStable()) + if (IsContextLost()) return; if (!ValidateObject("bindAttribLocation: program", prog)) @@ -131,7 +131,7 @@ WebGLContext::BindAttribLocation(WebGLProgram *prog, GLuint location, void WebGLContext::BindFramebuffer(GLenum target, WebGLFramebuffer *wfb) { - if (!IsContextStable()) + if (IsContextLost()) return; if (target != LOCAL_GL_FRAMEBUFFER) @@ -160,7 +160,7 @@ WebGLContext::BindFramebuffer(GLenum target, WebGLFramebuffer *wfb) void WebGLContext::BindRenderbuffer(GLenum target, WebGLRenderbuffer *wrb) { - if (!IsContextStable()) + if (IsContextLost()) return; if (target != LOCAL_GL_RENDERBUFFER) @@ -187,7 +187,7 @@ WebGLContext::BindRenderbuffer(GLenum target, WebGLRenderbuffer *wrb) void WebGLContext::BindTexture(GLenum target, WebGLTexture *tex) { - if (!IsContextStable()) + if (IsContextLost()) return; if (!ValidateObjectAllowDeletedOrNull("bindTexture", tex)) @@ -216,7 +216,7 @@ WebGLContext::BindTexture(GLenum target, WebGLTexture *tex) void WebGLContext::BlendEquation(GLenum mode) { - if (!IsContextStable()) + if (IsContextLost()) return; if (!ValidateBlendEquationEnum(mode, "blendEquation: mode")) @@ -228,7 +228,7 @@ void WebGLContext::BlendEquation(GLenum mode) void WebGLContext::BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) { - if (!IsContextStable()) + if (IsContextLost()) return; if (!ValidateBlendEquationEnum(modeRGB, "blendEquationSeparate: modeRGB") || @@ -241,7 +241,7 @@ void WebGLContext::BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) void WebGLContext::BlendFunc(GLenum sfactor, GLenum dfactor) { - if (!IsContextStable()) + if (IsContextLost()) return; if (!ValidateBlendFuncSrcEnum(sfactor, "blendFunc: sfactor") || @@ -259,7 +259,7 @@ void WebGLContext::BlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) { - if (!IsContextStable()) + if (IsContextLost()) return; if (!ValidateBlendFuncSrcEnum(srcRGB, "blendFuncSeparate: srcRGB") || @@ -315,7 +315,7 @@ GLenum WebGLContext::CheckedBufferData(GLenum target, GLenum WebGLContext::CheckFramebufferStatus(GLenum target) { - if (!IsContextStable()) + if (IsContextLost()) { return LOCAL_GL_FRAMEBUFFER_UNSUPPORTED; } @@ -472,7 +472,7 @@ WebGLContext::CopyTexImage2D(GLenum target, GLsizei height, GLint border) { - if (!IsContextStable()) + if (IsContextLost()) return; switch (target) { @@ -581,7 +581,7 @@ WebGLContext::CopyTexSubImage2D(GLenum target, GLsizei width, GLsizei height) { - if (!IsContextStable()) + if (IsContextLost()) return; switch (target) { @@ -654,7 +654,7 @@ WebGLContext::CopyTexSubImage2D(GLenum target, already_AddRefed WebGLContext::CreateProgram() { - if (!IsContextStable()) + if (IsContextLost()) return nullptr; nsRefPtr globj = new WebGLProgram(this); return globj.forget(); @@ -663,7 +663,7 @@ WebGLContext::CreateProgram() already_AddRefed WebGLContext::CreateShader(GLenum type) { - if (!IsContextStable()) + if (IsContextLost()) return nullptr; if (type != LOCAL_GL_VERTEX_SHADER && @@ -680,7 +680,7 @@ WebGLContext::CreateShader(GLenum type) void WebGLContext::CullFace(GLenum face) { - if (!IsContextStable()) + if (IsContextLost()) return; if (!ValidateFaceEnum(face, "cullFace")) @@ -693,7 +693,7 @@ WebGLContext::CullFace(GLenum face) void WebGLContext::DeleteFramebuffer(WebGLFramebuffer* fbuf) { - if (!IsContextStable()) + if (IsContextLost()) return; if (!ValidateObjectAllowDeletedOrNull("deleteFramebuffer", fbuf)) @@ -712,7 +712,7 @@ WebGLContext::DeleteFramebuffer(WebGLFramebuffer* fbuf) void WebGLContext::DeleteRenderbuffer(WebGLRenderbuffer *rbuf) { - if (!IsContextStable()) + if (IsContextLost()) return; if (!ValidateObjectAllowDeletedOrNull("deleteRenderbuffer", rbuf)) @@ -734,7 +734,7 @@ WebGLContext::DeleteRenderbuffer(WebGLRenderbuffer *rbuf) void WebGLContext::DeleteTexture(WebGLTexture *tex) { - if (!IsContextStable()) + if (IsContextLost()) return; if (!ValidateObjectAllowDeletedOrNull("deleteTexture", tex)) @@ -763,7 +763,7 @@ WebGLContext::DeleteTexture(WebGLTexture *tex) void WebGLContext::DeleteProgram(WebGLProgram *prog) { - if (!IsContextStable()) + if (IsContextLost()) return; if (!ValidateObjectAllowDeletedOrNull("deleteProgram", prog)) @@ -778,7 +778,7 @@ WebGLContext::DeleteProgram(WebGLProgram *prog) void WebGLContext::DeleteShader(WebGLShader *shader) { - if (!IsContextStable()) + if (IsContextLost()) return; if (!ValidateObjectAllowDeletedOrNull("deleteShader", shader)) @@ -793,7 +793,7 @@ WebGLContext::DeleteShader(WebGLShader *shader) void WebGLContext::DetachShader(WebGLProgram *program, WebGLShader *shader) { - if (!IsContextStable()) + if (IsContextLost()) return; if (!ValidateObject("detachShader: program", program) || @@ -809,7 +809,7 @@ WebGLContext::DetachShader(WebGLProgram *program, WebGLShader *shader) void WebGLContext::DepthFunc(GLenum func) { - if (!IsContextStable()) + if (IsContextLost()) return; if (!ValidateComparisonEnum(func, "depthFunc")) @@ -822,7 +822,7 @@ WebGLContext::DepthFunc(GLenum func) void WebGLContext::DepthRange(GLfloat zNear, GLfloat zFar) { - if (!IsContextStable()) + if (IsContextLost()) return; if (zNear > zFar) @@ -1053,7 +1053,7 @@ WebGLContext::UnbindFakeBlackTextures() void WebGLContext::FramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum rbtarget, WebGLRenderbuffer *wrb) { - if (!IsContextStable()) + if (IsContextLost()) return; if (!mBoundFramebuffer) @@ -1069,7 +1069,7 @@ WebGLContext::FramebufferTexture2D(GLenum target, WebGLTexture *tobj, GLint level) { - if (!IsContextStable()) + if (IsContextLost()) return; if (!mBoundFramebuffer) @@ -1081,7 +1081,7 @@ WebGLContext::FramebufferTexture2D(GLenum target, void WebGLContext::FrontFace(GLenum mode) { - if (!IsContextStable()) + if (IsContextLost()) return; switch (mode) { @@ -1099,7 +1099,7 @@ WebGLContext::FrontFace(GLenum mode) already_AddRefed WebGLContext::GetActiveAttrib(WebGLProgram *prog, uint32_t index) { - if (!IsContextStable()) + if (IsContextLost()) return nullptr; if (!ValidateObject("getActiveAttrib: program", prog)) @@ -1133,7 +1133,7 @@ WebGLContext::GetActiveAttrib(WebGLProgram *prog, uint32_t index) void WebGLContext::GenerateMipmap(GLenum target) { - if (!IsContextStable()) + if (IsContextLost()) return; if (!ValidateTextureTargetEnum(target, "generateMipmap")) @@ -1184,7 +1184,7 @@ WebGLContext::GenerateMipmap(GLenum target) already_AddRefed WebGLContext::GetActiveUniform(WebGLProgram *prog, uint32_t index) { - if (!IsContextStable()) + if (IsContextLost()) return nullptr; if (!ValidateObject("getActiveUniform: program", prog)) @@ -1237,7 +1237,7 @@ WebGLContext::GetAttachedShaders(WebGLProgram *prog, Nullable< nsTArray > &retval) { retval.SetNull(); - if (!IsContextStable()) + if (IsContextLost()) return; if (!ValidateObjectAllowNull("getAttachedShaders", prog)) @@ -1258,7 +1258,7 @@ WebGLContext::GetAttachedShaders(WebGLProgram *prog, GLint WebGLContext::GetAttribLocation(WebGLProgram *prog, const nsAString& name) { - if (!IsContextStable()) + if (IsContextLost()) return -1; if (!ValidateObject("getAttribLocation: program", prog)) @@ -1280,7 +1280,7 @@ WebGLContext::GetAttribLocation(WebGLProgram *prog, const nsAString& name) JS::Value WebGLContext::GetBufferParameter(GLenum target, GLenum pname) { - if (!IsContextStable()) + if (IsContextLost()) return JS::NullValue(); if (target != LOCAL_GL_ARRAY_BUFFER && target != LOCAL_GL_ELEMENT_ARRAY_BUFFER) { @@ -1319,7 +1319,7 @@ WebGLContext::GetFramebufferAttachmentParameter(JSContext* cx, GLenum pname, ErrorResult& rv) { - if (!IsContextStable()) + if (IsContextLost()) return JS::NullValue(); if (target != LOCAL_GL_FRAMEBUFFER) { @@ -1409,7 +1409,7 @@ WebGLContext::GetFramebufferAttachmentParameter(JSContext* cx, JS::Value WebGLContext::GetRenderbufferParameter(GLenum target, GLenum pname) { - if (!IsContextStable()) + if (IsContextLost()) return JS::NullValue(); if (target != LOCAL_GL_RENDERBUFFER) { @@ -1452,7 +1452,7 @@ WebGLContext::GetRenderbufferParameter(GLenum target, GLenum pname) already_AddRefed WebGLContext::CreateTexture() { - if (!IsContextStable()) + if (IsContextLost()) return nullptr; nsRefPtr globj = new WebGLTexture(this); return globj.forget(); @@ -1461,7 +1461,7 @@ WebGLContext::CreateTexture() GLenum WebGLContext::GetError() { - if (mContextStatus == ContextStable) { + if (mContextStatus == ContextNotLost) { MakeContextCurrent(); UpdateWebGLErrorAndClearGLError(); } else if (!mContextLostErrorSet) { @@ -1477,7 +1477,7 @@ WebGLContext::GetError() JS::Value WebGLContext::GetProgramParameter(WebGLProgram *prog, GLenum pname) { - if (!IsContextStable()) + if (IsContextLost()) return JS::NullValue(); if (!ValidateObjectAllowDeleted("getProgramParameter: program", prog)) @@ -1539,7 +1539,7 @@ WebGLContext::GetProgramInfoLog(WebGLProgram *prog, nsAString& retval) void WebGLContext::GetProgramInfoLog(WebGLProgram *prog, nsACString& retval) { - if (!IsContextStable()) + if (IsContextLost()) { retval.SetIsVoid(true); return; @@ -1583,7 +1583,7 @@ void WebGLContext::TexParameter_base(GLenum target, GLenum pname, { MOZ_ASSERT(intParamPtr || floatParamPtr); - if (!IsContextStable()) + if (IsContextLost()) return; GLint intParam = intParamPtr ? *intParamPtr : GLint(*floatParamPtr); @@ -1686,7 +1686,7 @@ void WebGLContext::TexParameter_base(GLenum target, GLenum pname, JS::Value WebGLContext::GetTexParameter(GLenum target, GLenum pname) { - if (!IsContextStable()) + if (IsContextLost()) return JS::NullValue(); MakeContextCurrent(); @@ -1730,7 +1730,7 @@ JS::Value WebGLContext::GetUniform(JSContext* cx, WebGLProgram *prog, WebGLUniformLocation *location, ErrorResult& rv) { - if (!IsContextStable()) + if (IsContextLost()) return JS::NullValue(); if (!ValidateObject("getUniform: program", prog)) @@ -1862,7 +1862,7 @@ WebGLContext::GetUniform(JSContext* cx, WebGLProgram *prog, already_AddRefed WebGLContext::GetUniformLocation(WebGLProgram *prog, const nsAString& name) { - if (!IsContextStable()) + if (IsContextLost()) return nullptr; if (!ValidateObject("getUniformLocation: program", prog)) @@ -1893,7 +1893,7 @@ WebGLContext::GetUniformLocation(WebGLProgram *prog, const nsAString& name) void WebGLContext::Hint(GLenum target, GLenum mode) { - if (!IsContextStable()) + if (IsContextLost()) return; bool isValid = false; @@ -1917,7 +1917,7 @@ WebGLContext::Hint(GLenum target, GLenum mode) bool WebGLContext::IsFramebuffer(WebGLFramebuffer *fb) { - if (!IsContextStable()) + if (IsContextLost()) return false; return ValidateObjectAllowDeleted("isFramebuffer", fb) && @@ -1928,7 +1928,7 @@ WebGLContext::IsFramebuffer(WebGLFramebuffer *fb) bool WebGLContext::IsProgram(WebGLProgram *prog) { - if (!IsContextStable()) + if (IsContextLost()) return false; return ValidateObjectAllowDeleted("isProgram", prog) && !prog->IsDeleted(); @@ -1937,7 +1937,7 @@ WebGLContext::IsProgram(WebGLProgram *prog) bool WebGLContext::IsRenderbuffer(WebGLRenderbuffer *rb) { - if (!IsContextStable()) + if (IsContextLost()) return false; return ValidateObjectAllowDeleted("isRenderBuffer", rb) && @@ -1948,7 +1948,7 @@ WebGLContext::IsRenderbuffer(WebGLRenderbuffer *rb) bool WebGLContext::IsShader(WebGLShader *shader) { - if (!IsContextStable()) + if (IsContextLost()) return false; return ValidateObjectAllowDeleted("isShader", shader) && @@ -1958,7 +1958,7 @@ WebGLContext::IsShader(WebGLShader *shader) bool WebGLContext::IsTexture(WebGLTexture *tex) { - if (!IsContextStable()) + if (IsContextLost()) return false; return ValidateObjectAllowDeleted("isTexture", tex) && @@ -1999,7 +1999,7 @@ bool WebGLContext::BindArrayAttribToLocation0(WebGLProgram *program) void WebGLContext::LinkProgram(WebGLProgram *program) { - if (!IsContextStable()) + if (IsContextLost()) return; if (!ValidateObject("linkProgram", program)) @@ -2129,7 +2129,7 @@ WebGLContext::LinkProgram(WebGLProgram *program) void WebGLContext::PixelStorei(GLenum pname, GLint param) { - if (!IsContextStable()) + if (IsContextLost()) return; switch (pname) { @@ -2170,7 +2170,7 @@ WebGLContext::ReadPixels(GLint x, GLint y, GLsizei width, GLenum type, const Nullable &pixels, ErrorResult& rv) { - if (!IsContextStable()) { + if (IsContextLost()) { return; } @@ -2393,7 +2393,7 @@ WebGLContext::ReadPixels(GLint x, GLint y, GLsizei width, void WebGLContext::RenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) { - if (!IsContextStable()) + if (IsContextLost()) return; if (!mBoundRenderbuffer || !mBoundRenderbuffer->GLName()) @@ -2470,7 +2470,7 @@ WebGLContext::RenderbufferStorage(GLenum target, GLenum internalformat, GLsizei void WebGLContext::Scissor(GLint x, GLint y, GLsizei width, GLsizei height) { - if (!IsContextStable()) + if (IsContextLost()) return; if (width < 0 || height < 0) @@ -2483,7 +2483,7 @@ WebGLContext::Scissor(GLint x, GLint y, GLsizei width, GLsizei height) void WebGLContext::StencilFunc(GLenum func, GLint ref, GLuint mask) { - if (!IsContextStable()) + if (IsContextLost()) return; if (!ValidateComparisonEnum(func, "stencilFunc: func")) @@ -2501,7 +2501,7 @@ WebGLContext::StencilFunc(GLenum func, GLint ref, GLuint mask) void WebGLContext::StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask) { - if (!IsContextStable()) + if (IsContextLost()) return; if (!ValidateFaceEnum(face, "stencilFuncSeparate: face") || @@ -2532,7 +2532,7 @@ WebGLContext::StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint ma void WebGLContext::StencilOp(GLenum sfail, GLenum dpfail, GLenum dppass) { - if (!IsContextStable()) + if (IsContextLost()) return; if (!ValidateStencilOpEnum(sfail, "stencilOp: sfail") || @@ -2547,7 +2547,7 @@ WebGLContext::StencilOp(GLenum sfail, GLenum dpfail, GLenum dppass) void WebGLContext::StencilOpSeparate(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass) { - if (!IsContextStable()) + if (IsContextLost()) return; if (!ValidateFaceEnum(face, "stencilOpSeparate: face") || @@ -2936,7 +2936,7 @@ WebGLContext::UniformMatrix4fv_base(WebGLUniformLocation* location_object, void WebGLContext::UseProgram(WebGLProgram *prog) { - if (!IsContextStable()) + if (IsContextLost()) return; if (!ValidateObjectAllowNull("useProgram", prog)) @@ -2959,7 +2959,7 @@ WebGLContext::UseProgram(WebGLProgram *prog) void WebGLContext::ValidateProgram(WebGLProgram *prog) { - if (!IsContextStable()) + if (IsContextLost()) return; if (!ValidateObject("validateProgram", prog)) @@ -2982,7 +2982,7 @@ WebGLContext::ValidateProgram(WebGLProgram *prog) already_AddRefed WebGLContext::CreateFramebuffer() { - if (!IsContextStable()) + if (IsContextLost()) return nullptr; nsRefPtr globj = new WebGLFramebuffer(this); return globj.forget(); @@ -2991,7 +2991,7 @@ WebGLContext::CreateFramebuffer() already_AddRefed WebGLContext::CreateRenderbuffer() { - if (!IsContextStable()) + if (IsContextLost()) return nullptr; nsRefPtr globj = new WebGLRenderbuffer(this); return globj.forget(); @@ -3000,7 +3000,7 @@ WebGLContext::CreateRenderbuffer() void WebGLContext::Viewport(GLint x, GLint y, GLsizei width, GLsizei height) { - if (!IsContextStable()) + if (IsContextLost()) return; if (width < 0 || height < 0) @@ -3013,7 +3013,7 @@ WebGLContext::Viewport(GLint x, GLint y, GLsizei width, GLsizei height) void WebGLContext::CompileShader(WebGLShader *shader) { - if (!IsContextStable()) + if (IsContextLost()) return; if (!ValidateObject("compileShader", shader)) @@ -3283,7 +3283,7 @@ WebGLContext::CompressedTexImage2D(GLenum target, GLint level, GLenum internalfo GLsizei width, GLsizei height, GLint border, const ArrayBufferView& view) { - if (!IsContextStable()) { + if (IsContextLost()) { return; } @@ -3323,7 +3323,7 @@ WebGLContext::CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, const ArrayBufferView& view) { - if (!IsContextStable()) { + if (IsContextLost()) { return; } @@ -3421,7 +3421,7 @@ WebGLContext::CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, JS::Value WebGLContext::GetShaderParameter(WebGLShader *shader, GLenum pname) { - if (!IsContextStable()) + if (IsContextLost()) return JS::NullValue(); if (!ValidateObject("getShaderParameter: shader", shader)) @@ -3470,7 +3470,7 @@ WebGLContext::GetShaderInfoLog(WebGLShader *shader, nsAString& retval) void WebGLContext::GetShaderInfoLog(WebGLShader *shader, nsACString& retval) { - if (!IsContextStable()) + if (IsContextLost()) { retval.SetIsVoid(true); return; @@ -3507,7 +3507,7 @@ WebGLContext::GetShaderInfoLog(WebGLShader *shader, nsACString& retval) already_AddRefed WebGLContext::GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype) { - if (!IsContextStable()) + if (IsContextLost()) return nullptr; switch (shadertype) { @@ -3555,7 +3555,7 @@ WebGLContext::GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype) void WebGLContext::GetShaderSource(WebGLShader *shader, nsAString& retval) { - if (!IsContextStable()) + if (IsContextLost()) { retval.SetIsVoid(true); return; @@ -3570,7 +3570,7 @@ WebGLContext::GetShaderSource(WebGLShader *shader, nsAString& retval) void WebGLContext::ShaderSource(WebGLShader *shader, const nsAString& source) { - if (!IsContextStable()) + if (IsContextLost()) return; if (!ValidateObject("shaderSource: shader", shader)) @@ -3776,7 +3776,7 @@ WebGLContext::TexImage2D(GLenum target, GLint level, GLsizei height, GLint border, GLenum format, GLenum type, const Nullable &pixels, ErrorResult& rv) { - if (!IsContextStable()) + if (IsContextLost()) return; return TexImage2D_base(target, level, internalformat, width, height, 0, border, format, type, @@ -3791,7 +3791,7 @@ WebGLContext::TexImage2D(GLenum target, GLint level, GLenum internalformat, GLenum format, GLenum type, ImageData* pixels, ErrorResult& rv) { - if (!IsContextStable()) + if (IsContextLost()) return; if (!pixels) { @@ -3927,7 +3927,7 @@ WebGLContext::TexSubImage2D(GLenum target, GLint level, const Nullable &pixels, ErrorResult& rv) { - if (!IsContextStable()) + if (IsContextLost()) return; if (pixels.IsNull()) @@ -3946,7 +3946,7 @@ WebGLContext::TexSubImage2D(GLenum target, GLint level, GLenum format, GLenum type, ImageData* pixels, ErrorResult& rv) { - if (!IsContextStable()) + if (IsContextLost()) return; if (!pixels) @@ -3964,7 +3964,7 @@ WebGLContext::TexSubImage2D(GLenum target, GLint level, bool WebGLContext::LoseContext() { - if (!IsContextStable()) + if (IsContextLost()) return false; ForceLoseContext(); @@ -3975,7 +3975,7 @@ WebGLContext::LoseContext() bool WebGLContext::RestoreContext() { - if (IsContextStable() || !mAllowRestore) { + if (!IsContextLost() || !mAllowRestore) { return false; } diff --git a/content/canvas/src/WebGLContextState.cpp b/content/canvas/src/WebGLContextState.cpp index d91005ed608..aab97d6cce7 100644 --- a/content/canvas/src/WebGLContextState.cpp +++ b/content/canvas/src/WebGLContextState.cpp @@ -19,7 +19,7 @@ using namespace dom; void WebGLContext::Disable(GLenum cap) { - if (!IsContextStable()) + if (IsContextLost()) return; if (!ValidateCapabilityEnum(cap, "disable")) @@ -39,7 +39,7 @@ WebGLContext::Disable(GLenum cap) void WebGLContext::Enable(GLenum cap) { - if (!IsContextStable()) + if (IsContextLost()) return; if (!ValidateCapabilityEnum(cap, "enable")) @@ -71,7 +71,7 @@ StringValue(JSContext* cx, const char* chars, ErrorResult& rv) JS::Value WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv) { - if (!IsContextStable()) + if (IsContextLost()) return JS::NullValue(); MakeContextCurrent(); @@ -486,7 +486,7 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv) JS::Value WebGLContext::GetParameterIndexed(JSContext* cx, GLenum pname, GLuint index) { - if (!IsContextStable()) + if (IsContextLost()) return JS::NullValue(); MakeContextCurrent(); @@ -512,7 +512,7 @@ WebGLContext::GetParameterIndexed(JSContext* cx, GLenum pname, GLuint index) bool WebGLContext::IsEnabled(GLenum cap) { - if (!IsContextStable()) + if (IsContextLost()) return false; if (!ValidateCapabilityEnum(cap, "isEnabled")) diff --git a/content/canvas/src/WebGLContextValidate.cpp b/content/canvas/src/WebGLContextValidate.cpp index bc0422af0d9..56630d2e046 100644 --- a/content/canvas/src/WebGLContextValidate.cpp +++ b/content/canvas/src/WebGLContextValidate.cpp @@ -654,7 +654,7 @@ WebGLContext::ValidateSamplerUniformSetter(const char* info, WebGLUniformLocatio bool WebGLContext::ValidateAttribArraySetter(const char* name, uint32_t cnt, uint32_t arrayLength) { - if (!IsContextStable()) { + if (IsContextLost()) { return false; } if (arrayLength < cnt) { @@ -668,7 +668,7 @@ bool WebGLContext::ValidateUniformArraySetter(const char* name, uint32_t expectedElemSize, WebGLUniformLocation *location_object, GLint& location, uint32_t& numElementsToUpload, uint32_t arrayLength) { - if (!IsContextStable()) + if (IsContextLost()) return false; if (!ValidateUniformLocation(name, location_object)) return false; @@ -711,7 +711,7 @@ WebGLContext::ValidateUniformMatrixArraySetter(const char* name, int dim, WebGLU WebGLboolean aTranspose) { uint32_t expectedElemSize = (dim)*(dim); - if (!IsContextStable()) + if (IsContextLost()) return false; if (!ValidateUniformLocation(name, location_object)) return false; @@ -756,7 +756,7 @@ WebGLContext::ValidateUniformMatrixArraySetter(const char* name, int dim, WebGLU bool WebGLContext::ValidateUniformSetter(const char* name, WebGLUniformLocation *location_object, GLint& location) { - if (!IsContextStable()) + if (IsContextLost()) return false; if (!ValidateUniformLocation(name, location_object)) return false; diff --git a/content/canvas/src/WebGLContextVertexArray.cpp b/content/canvas/src/WebGLContextVertexArray.cpp index de01eb53fc7..26d7a36848c 100644 --- a/content/canvas/src/WebGLContextVertexArray.cpp +++ b/content/canvas/src/WebGLContextVertexArray.cpp @@ -13,7 +13,7 @@ using namespace mozilla; void WebGLContext::BindVertexArray(WebGLVertexArray *array) { - if (!IsContextStable()) + if (IsContextLost()) return; if (!ValidateObjectAllowDeletedOrNull("bindVertexArrayObject", array)) @@ -48,7 +48,7 @@ WebGLContext::BindVertexArray(WebGLVertexArray *array) already_AddRefed WebGLContext::CreateVertexArray() { - if (!IsContextStable()) + if (IsContextLost()) return nullptr; nsRefPtr globj = new WebGLVertexArray(this); @@ -64,7 +64,7 @@ WebGLContext::CreateVertexArray() void WebGLContext::DeleteVertexArray(WebGLVertexArray *array) { - if (!IsContextStable()) + if (IsContextLost()) return; if (array == nullptr) @@ -82,7 +82,7 @@ WebGLContext::DeleteVertexArray(WebGLVertexArray *array) bool WebGLContext::IsVertexArray(WebGLVertexArray *array) { - if (!IsContextStable()) + if (IsContextLost()) return false; if (!array) diff --git a/content/canvas/src/WebGLContextVertices.cpp b/content/canvas/src/WebGLContextVertices.cpp index af9052e2f83..768dbdf6255 100644 --- a/content/canvas/src/WebGLContextVertices.cpp +++ b/content/canvas/src/WebGLContextVertices.cpp @@ -23,7 +23,7 @@ static const int MAX_DRAW_CALLS_SINCE_FLUSH = 100; void WebGLContext::VertexAttrib1f(GLuint index, GLfloat x0) { - if (!IsContextStable()) + if (IsContextLost()) return; MakeContextCurrent(); @@ -43,7 +43,7 @@ WebGLContext::VertexAttrib1f(GLuint index, GLfloat x0) void WebGLContext::VertexAttrib2f(GLuint index, GLfloat x0, GLfloat x1) { - if (!IsContextStable()) + if (IsContextLost()) return; MakeContextCurrent(); @@ -63,7 +63,7 @@ WebGLContext::VertexAttrib2f(GLuint index, GLfloat x0, GLfloat x1) void WebGLContext::VertexAttrib3f(GLuint index, GLfloat x0, GLfloat x1, GLfloat x2) { - if (!IsContextStable()) + if (IsContextLost()) return; MakeContextCurrent(); @@ -84,7 +84,7 @@ void WebGLContext::VertexAttrib4f(GLuint index, GLfloat x0, GLfloat x1, GLfloat x2, GLfloat x3) { - if (!IsContextStable()) + if (IsContextLost()) return; MakeContextCurrent(); @@ -185,7 +185,7 @@ WebGLContext::VertexAttrib4fv_base(GLuint idx, uint32_t arrayLength, void WebGLContext::EnableVertexAttribArray(GLuint index) { - if (!IsContextStable()) + if (IsContextLost()) return; if (!ValidateAttribIndex(index, "enableVertexAttribArray")) @@ -201,7 +201,7 @@ WebGLContext::EnableVertexAttribArray(GLuint index) void WebGLContext::DisableVertexAttribArray(GLuint index) { - if (!IsContextStable()) + if (IsContextLost()) return; if (!ValidateAttribIndex(index, "disableVertexAttribArray")) @@ -221,7 +221,7 @@ JS::Value WebGLContext::GetVertexAttrib(JSContext* cx, GLuint index, GLenum pname, ErrorResult& rv) { - if (!IsContextStable()) + if (IsContextLost()) return JS::NullValue(); if (!mBoundVertexArray->EnsureAttribIndex(index, "getVertexAttrib")) @@ -309,7 +309,7 @@ WebGLContext::GetVertexAttrib(JSContext* cx, GLuint index, GLenum pname, WebGLsizeiptr WebGLContext::GetVertexAttribOffset(GLuint index, GLenum pname) { - if (!IsContextStable()) + if (IsContextLost()) return 0; if (!ValidateAttribIndex(index, "getVertexAttribOffset")) @@ -328,7 +328,7 @@ WebGLContext::VertexAttribPointer(GLuint index, GLint size, GLenum type, WebGLboolean normalized, GLsizei stride, WebGLintptr byteOffset) { - if (!IsContextStable()) + if (IsContextLost()) return; if (mBoundArrayBuffer == nullptr) @@ -405,7 +405,7 @@ WebGLContext::VertexAttribPointer(GLuint index, GLint size, GLenum type, void WebGLContext::VertexAttribDivisor(GLuint index, GLuint divisor) { - if (!IsContextStable()) + if (IsContextLost()) return; if ( !mBoundVertexArray->EnsureAttribIndex(index, "vertexAttribDivisor") ) { @@ -500,7 +500,7 @@ bool WebGLContext::DrawArrays_check(GLint first, GLsizei count, GLsizei primcoun void WebGLContext::DrawArrays(GLenum mode, GLint first, GLsizei count) { - if (!IsContextStable()) + if (IsContextLost()) return; if (!ValidateDrawModeEnum(mode, "drawArrays: mode")) @@ -518,7 +518,7 @@ WebGLContext::DrawArrays(GLenum mode, GLint first, GLsizei count) void WebGLContext::DrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei primcount) { - if (!IsContextStable()) + if (IsContextLost()) return; if (!ValidateDrawModeEnum(mode, "drawArraysInstanced: mode")) @@ -665,7 +665,7 @@ void WebGLContext::DrawElements(GLenum mode, GLsizei count, GLenum type, WebGLintptr byteOffset) { - if (!IsContextStable()) + if (IsContextLost()) return; if (!ValidateDrawModeEnum(mode, "drawElements: mode")) @@ -684,7 +684,7 @@ void WebGLContext::DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, WebGLintptr byteOffset, GLsizei primcount) { - if (!IsContextStable()) + if (IsContextLost()) return; if (!ValidateDrawModeEnum(mode, "drawElementsInstanced: mode")) diff --git a/content/canvas/src/WebGLTypes.h b/content/canvas/src/WebGLTypes.h index 1e77b3d85c8..a8239ae4dbc 100644 --- a/content/canvas/src/WebGLTypes.h +++ b/content/canvas/src/WebGLTypes.h @@ -6,8 +6,11 @@ #ifndef WEBGLTYPES_H_ #define WEBGLTYPES_H_ -// Manual reflection of WebIDL typedefs that are different from the -// corresponding OpenGL typedefs. +// Most WebIDL typedefs are identical to their OpenGL counterparts. +#include "GLTypes.h" + +// Manual reflection of WebIDL typedefs that are different from their +// OpenGL counterparts. typedef int64_t WebGLsizeiptr; typedef int64_t WebGLintptr; typedef bool WebGLboolean; From 4f1dd420f6fc88ffff026b9a1d3b56d0f9be7858 Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Wed, 4 Sep 2013 08:14:46 -0400 Subject: [PATCH 071/171] Bug 911857 - Move CheckedBufferData to WebGLContextBuffers.cpp - r=jgilbert --- content/canvas/src/WebGLContextBuffers.cpp | 36 ++++++++++++++++++++++ content/canvas/src/WebGLContextGL.cpp | 35 --------------------- 2 files changed, 36 insertions(+), 35 deletions(-) diff --git a/content/canvas/src/WebGLContextBuffers.cpp b/content/canvas/src/WebGLContextBuffers.cpp index 8d7d7548161..07784cef547 100644 --- a/content/canvas/src/WebGLContextBuffers.cpp +++ b/content/canvas/src/WebGLContextBuffers.cpp @@ -458,3 +458,39 @@ WebGLContext::GetBufferSlotByTargetIndexed(GLenum target, GLuint index, const ch ErrorInvalidEnum("%s: target: invalid enum value 0x%x", infos, target); return nullptr; } + +GLenum +WebGLContext::CheckedBufferData(GLenum target, + GLsizeiptr size, + const GLvoid *data, + GLenum usage) +{ +#ifdef XP_MACOSX + // bug 790879 + if (gl->WorkAroundDriverBugs() && + int64_t(size) > INT32_MAX) // the cast avoids a potential always-true warning on 32bit + { + GenerateWarning("Rejecting valid bufferData call with size %lu to avoid a Mac bug", size); + return LOCAL_GL_INVALID_VALUE; + } +#endif + WebGLBuffer *boundBuffer = nullptr; + if (target == LOCAL_GL_ARRAY_BUFFER) { + boundBuffer = mBoundArrayBuffer; + } else if (target == LOCAL_GL_ELEMENT_ARRAY_BUFFER) { + boundBuffer = mBoundVertexArray->mBoundElementArrayBuffer; + } + NS_ABORT_IF_FALSE(boundBuffer != nullptr, "no buffer bound for this target"); + + bool sizeChanges = uint32_t(size) != boundBuffer->ByteLength(); + if (sizeChanges) { + UpdateWebGLErrorAndClearGLError(); + gl->fBufferData(target, size, data, usage); + GLenum error = LOCAL_GL_NO_ERROR; + UpdateWebGLErrorAndClearGLError(&error); + return error; + } else { + gl->fBufferData(target, size, data, usage); + return LOCAL_GL_NO_ERROR; + } +} diff --git a/content/canvas/src/WebGLContextGL.cpp b/content/canvas/src/WebGLContextGL.cpp index adb0f88d8c1..b72641af7cb 100644 --- a/content/canvas/src/WebGLContextGL.cpp +++ b/content/canvas/src/WebGLContextGL.cpp @@ -277,41 +277,6 @@ WebGLContext::BlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, gl->fBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha); } -GLenum WebGLContext::CheckedBufferData(GLenum target, - GLsizeiptr size, - const GLvoid *data, - GLenum usage) -{ -#ifdef XP_MACOSX - // bug 790879 - if (gl->WorkAroundDriverBugs() && - int64_t(size) > INT32_MAX) // the cast avoids a potential always-true warning on 32bit - { - GenerateWarning("Rejecting valid bufferData call with size %lu to avoid a Mac bug", size); - return LOCAL_GL_INVALID_VALUE; - } -#endif - WebGLBuffer *boundBuffer = nullptr; - if (target == LOCAL_GL_ARRAY_BUFFER) { - boundBuffer = mBoundArrayBuffer; - } else if (target == LOCAL_GL_ELEMENT_ARRAY_BUFFER) { - boundBuffer = mBoundVertexArray->mBoundElementArrayBuffer; - } - NS_ABORT_IF_FALSE(boundBuffer != nullptr, "no buffer bound for this target"); - - bool sizeChanges = uint32_t(size) != boundBuffer->ByteLength(); - if (sizeChanges) { - UpdateWebGLErrorAndClearGLError(); - gl->fBufferData(target, size, data, usage); - GLenum error = LOCAL_GL_NO_ERROR; - UpdateWebGLErrorAndClearGLError(&error); - return error; - } else { - gl->fBufferData(target, size, data, usage); - return LOCAL_GL_NO_ERROR; - } -} - GLenum WebGLContext::CheckFramebufferStatus(GLenum target) { From 76d307658cdb373d93139b60bfa6b890f534ecc9 Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Wed, 4 Sep 2013 08:14:48 -0400 Subject: [PATCH 072/171] Bug 811371 - Remove nsISupports inheritance in remaining (i.e. new) WebGL classes - r=continuation --- content/canvas/src/WebGLActiveInfo.h | 3 +-- content/canvas/src/WebGLExtensionBase.cpp | 9 ++------- content/canvas/src/WebGLExtensions.h | 7 +++---- content/canvas/src/WebGLQuery.cpp | 9 ++------- content/canvas/src/WebGLQuery.h | 7 +++---- content/canvas/src/WebGLVertexArray.cpp | 9 ++------- content/canvas/src/WebGLVertexArray.h | 7 +++---- 7 files changed, 16 insertions(+), 35 deletions(-) diff --git a/content/canvas/src/WebGLActiveInfo.h b/content/canvas/src/WebGLActiveInfo.h index ab7dd0f270a..4c62fcffba3 100644 --- a/content/canvas/src/WebGLActiveInfo.h +++ b/content/canvas/src/WebGLActiveInfo.h @@ -6,8 +6,7 @@ #ifndef WEBGLACTIVEINFO_H_ #define WEBGLACTIVEINFO_H_ -#include "WebGLTypes.h" -#include "nsISupports.h" +#include "WebGLObjectModel.h" #include "nsString.h" #include "js/TypeDecls.h" diff --git a/content/canvas/src/WebGLExtensionBase.cpp b/content/canvas/src/WebGLExtensionBase.cpp index dda9c0a619b..2b925767dc7 100644 --- a/content/canvas/src/WebGLExtensionBase.cpp +++ b/content/canvas/src/WebGLExtensionBase.cpp @@ -20,10 +20,5 @@ WebGLExtensionBase::~WebGLExtensionBase() NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLExtensionBase) -NS_IMPL_CYCLE_COLLECTING_ADDREF(WebGLExtensionBase) -NS_IMPL_CYCLE_COLLECTING_RELEASE(WebGLExtensionBase) - -NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WebGLExtensionBase) - NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY - NS_INTERFACE_MAP_ENTRY(nsISupports) -NS_INTERFACE_MAP_END +NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLExtensionBase, AddRef) +NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebGLExtensionBase, Release) diff --git a/content/canvas/src/WebGLExtensions.h b/content/canvas/src/WebGLExtensions.h index c85ab02c746..737b1f7c5d7 100644 --- a/content/canvas/src/WebGLExtensions.h +++ b/content/canvas/src/WebGLExtensions.h @@ -11,9 +11,8 @@ namespace mozilla { class WebGLContext; class WebGLExtensionBase - : public nsISupports + : public nsWrapperCache , public WebGLContextBoundObject - , public nsWrapperCache { public: WebGLExtensionBase(WebGLContext*); @@ -23,8 +22,8 @@ public: return Context(); } - NS_DECL_CYCLE_COLLECTING_ISUPPORTS - NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(WebGLExtensionBase) + NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLExtensionBase) + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLExtensionBase) }; #define DECL_WEBGL_EXTENSION_GOOP \ diff --git a/content/canvas/src/WebGLQuery.cpp b/content/canvas/src/WebGLQuery.cpp index bcbe4783f89..456a96e3da9 100644 --- a/content/canvas/src/WebGLQuery.cpp +++ b/content/canvas/src/WebGLQuery.cpp @@ -36,10 +36,5 @@ void WebGLQuery::Delete() { NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLQuery) -NS_IMPL_CYCLE_COLLECTING_ADDREF(WebGLQuery) -NS_IMPL_CYCLE_COLLECTING_RELEASE(WebGLQuery) - -NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WebGLQuery) - NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY - NS_INTERFACE_MAP_ENTRY(nsISupports) -NS_INTERFACE_MAP_END +NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLQuery, AddRef) +NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebGLQuery, Release) diff --git a/content/canvas/src/WebGLQuery.h b/content/canvas/src/WebGLQuery.h index fd12a450fa8..f57781a3847 100644 --- a/content/canvas/src/WebGLQuery.h +++ b/content/canvas/src/WebGLQuery.h @@ -16,11 +16,10 @@ namespace mozilla { class WebGLQuery MOZ_FINAL - : public nsISupports + : public nsWrapperCache , public WebGLRefCountedObject , public LinkedListElement , public WebGLContextBoundObject - , public nsWrapperCache { // ----------------------------------------------------------------------------- // PUBLIC @@ -70,8 +69,8 @@ public: virtual JSObject* WrapObject(JSContext *cx, JS::Handle scope) MOZ_OVERRIDE; - NS_DECL_CYCLE_COLLECTING_ISUPPORTS - NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(WebGLQuery) + NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLQuery) + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLQuery) // ----------------------------------------------------------------------------- diff --git a/content/canvas/src/WebGLVertexArray.cpp b/content/canvas/src/WebGLVertexArray.cpp index 569ad642f61..f24428e081f 100644 --- a/content/canvas/src/WebGLVertexArray.cpp +++ b/content/canvas/src/WebGLVertexArray.cpp @@ -59,10 +59,5 @@ NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_2(WebGLVertexArray, mAttribBuffers, mBoundElementArrayBuffer) -NS_IMPL_CYCLE_COLLECTING_ADDREF(WebGLVertexArray) -NS_IMPL_CYCLE_COLLECTING_RELEASE(WebGLVertexArray) - -NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WebGLVertexArray) - NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY - NS_INTERFACE_MAP_ENTRY(nsISupports) -NS_INTERFACE_MAP_END +NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLVertexArray, AddRef) +NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebGLVertexArray, Release) diff --git a/content/canvas/src/WebGLVertexArray.h b/content/canvas/src/WebGLVertexArray.h index 2d87bc08dd6..ee632c8c8bf 100644 --- a/content/canvas/src/WebGLVertexArray.h +++ b/content/canvas/src/WebGLVertexArray.h @@ -17,11 +17,10 @@ namespace mozilla { class WebGLVertexArray MOZ_FINAL - : public nsISupports + : public nsWrapperCache , public WebGLRefCountedObject , public LinkedListElement , public WebGLContextBoundObject - , public nsWrapperCache { // ----------------------------------------------------------------------------- // PUBLIC @@ -49,8 +48,8 @@ public: virtual JSObject* WrapObject(JSContext *cx, JS::Handle scope) MOZ_OVERRIDE; - NS_DECL_CYCLE_COLLECTING_ISUPPORTS - NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(WebGLVertexArray) + NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLVertexArray) + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLVertexArray) // ------------------------------------------------------------------------- From ba172a45f5a056718e5578b3fab2ffc190d5ede1 Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Wed, 4 Sep 2013 08:14:50 -0400 Subject: [PATCH 073/171] Bug 911879 - Give WebGLContext.h a good round of removing unneeded inline method bodies - r=jgilbert --- content/canvas/src/WebGLContext.h | 135 +++---------------- content/canvas/src/WebGLContextGL.cpp | 48 +++++++ content/canvas/src/WebGLContextLossTimer.cpp | 40 ++++++ content/canvas/src/WebGLContextUtils.cpp | 28 ++++ content/canvas/src/moz.build | 1 + 5 files changed, 138 insertions(+), 114 deletions(-) create mode 100644 content/canvas/src/WebGLContextLossTimer.cpp diff --git a/content/canvas/src/WebGLContext.h b/content/canvas/src/WebGLContext.h index 0025417cf3a..b823d50945f 100644 --- a/content/canvas/src/WebGLContext.h +++ b/content/canvas/src/WebGLContext.h @@ -190,9 +190,7 @@ public: void ErrorInvalidOperation(const char *fmt = 0, ...); void ErrorInvalidValue(const char *fmt = 0, ...); void ErrorInvalidFramebufferOperation(const char *fmt = 0, ...); - void ErrorInvalidEnumInfo(const char *info, GLenum enumvalue) { - return ErrorInvalidEnum("%s: invalid enum value 0x%x", info, enumvalue); - } + void ErrorInvalidEnumInfo(const char *info, GLenum enumvalue); void ErrorOutOfMemory(const char *fmt = 0, ...); const char *ErrorName(GLenum error); @@ -200,7 +198,7 @@ public: void DummyFramebufferOperation(const char *info); - WebGLTexture *activeBoundTextureForTarget(GLenum target) { + WebGLTexture *activeBoundTextureForTarget(GLenum target) const { return target == LOCAL_GL_TEXTURE_2D ? mBound2DTextures[mActiveTexture] : mBoundCubeMapTextures[mActiveTexture]; } @@ -213,13 +211,9 @@ public: // contents of the buffer. void MarkContextClean() MOZ_OVERRIDE { mInvalidated = false; } - gl::GLContext* GL() const { - return gl; - } + gl::GLContext* GL() const { return gl; } - bool IsPremultAlpha() const { - return mOptions.premultipliedAlpha; - } + bool IsPremultAlpha() const { return mOptions.premultipliedAlpha; } bool PresentScreenBuffer(); @@ -240,72 +234,21 @@ public: // Calls ForceClearFramebufferWithDefaultValues() for the Context's 'screen'. void ClearScreen(); - // checks for GL errors, clears any pending GL error, stores the current GL error in currentGLError, + // checks for GL errors, clears any pending GL error, stores the current GL error in currentGLError (if not nullptr), // and copies it into mWebGLError if it doesn't already have an error set - void UpdateWebGLErrorAndClearGLError(GLenum *currentGLError) { - // get and clear GL error in ALL cases - *currentGLError = gl->GetAndClearError(); - // only store in mWebGLError if is hasn't already recorded an error - if (!mWebGLError) - mWebGLError = *currentGLError; - } - - // checks for GL errors, clears any pending GL error, - // and stores the current GL error into mWebGLError if it doesn't already have an error set - void UpdateWebGLErrorAndClearGLError() { - GLenum currentGLError; - UpdateWebGLErrorAndClearGLError(¤tGLError); - } - - bool MinCapabilityMode() const { - return mMinCapability; - } + void UpdateWebGLErrorAndClearGLError(GLenum *currentGLError = nullptr); + + bool MinCapabilityMode() const { return mMinCapability; } void RobustnessTimerCallback(nsITimer* timer); - - static void RobustnessTimerCallbackStatic(nsITimer* timer, void *thisPointer) { - static_cast(thisPointer)->RobustnessTimerCallback(timer); - } - - void SetupContextLossTimer() { - // If the timer was already running, don't restart it here. Instead, - // wait until the previous call is done, then fire it one more time. - // This is an optimization to prevent unnecessary cross-communication - // between threads. - if (mContextLossTimerRunning) { - mDrawSinceContextLossTimerSet = true; - return; - } - - mContextRestorer->InitWithFuncCallback(RobustnessTimerCallbackStatic, - static_cast(this), - 1000, - nsITimer::TYPE_ONE_SHOT); - mContextLossTimerRunning = true; - mDrawSinceContextLossTimerSet = false; - } - - void TerminateContextLossTimer() { - if (mContextLossTimerRunning) { - mContextRestorer->Cancel(); - mContextLossTimerRunning = false; - } - } + static void RobustnessTimerCallbackStatic(nsITimer* timer, void *thisPointer); + void SetupContextLossTimer(); + void TerminateContextLossTimer(); // WebIDL WebGLRenderingContext API - dom::HTMLCanvasElement* GetCanvas() const { - return mCanvasElement; - } - GLsizei DrawingBufferWidth() const { - if (IsContextLost()) - return 0; - return mWidth; - } - GLsizei DrawingBufferHeight() const { - if (IsContextLost()) - return 0; - return mHeight; - } + dom::HTMLCanvasElement* GetCanvas() const { return mCanvasElement; } + GLsizei DrawingBufferWidth() const { return IsContextLost() ? 0 : mWidth; } + GLsizei DrawingBufferHeight() const { return IsContextLost() ? 0 : mHeight; } void GetContextAttributes(dom::Nullable& retval); bool IsContextLost() const { return mContextStatus != ContextNotLost; } @@ -319,12 +262,7 @@ public: void BindRenderbuffer(GLenum target, WebGLRenderbuffer* wrb); void BindTexture(GLenum target, WebGLTexture *tex); void BindVertexArray(WebGLVertexArray *vao); - void BlendColor(GLclampf r, GLclampf g, GLclampf b, GLclampf a) { - if (IsContextLost()) - return; - MakeContextCurrent(); - gl->fBlendColor(r, g, b, a); - } + void BlendColor(GLclampf r, GLclampf g, GLclampf b, GLclampf a); void BlendEquation(GLenum mode); void BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha); void BlendFunc(GLenum sfactor, GLenum dfactor); @@ -370,18 +308,8 @@ public: void DepthRange(GLclampf zNear, GLclampf zFar); void DetachShader(WebGLProgram *program, WebGLShader *shader); void DrawBuffers(const dom::Sequence& buffers); - void Flush() { - if (IsContextLost()) - return; - MakeContextCurrent(); - gl->fFlush(); - } - void Finish() { - if (IsContextLost()) - return; - MakeContextCurrent(); - gl->fFinish(); - } + void Flush(); + void Finish(); void FramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum rbtarget, WebGLRenderbuffer *wrb); void FramebufferTexture2D(GLenum target, GLenum attachment, @@ -445,32 +373,17 @@ public: bool IsShader(WebGLShader *shader); bool IsTexture(WebGLTexture *tex); bool IsVertexArray(WebGLVertexArray *vao); - void LineWidth(GLfloat width) { - if (IsContextLost()) - return; - MakeContextCurrent(); - gl->fLineWidth(width); - } + void LineWidth(GLfloat width); void LinkProgram(WebGLProgram *program); void PixelStorei(GLenum pname, GLint param); - void PolygonOffset(GLfloat factor, GLfloat units) { - if (IsContextLost()) - return; - MakeContextCurrent(); - gl->fPolygonOffset(factor, units); - } + void PolygonOffset(GLfloat factor, GLfloat units); void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, const Nullable &pixels, ErrorResult& rv); void RenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height); - void SampleCoverage(GLclampf value, WebGLboolean invert) { - if (IsContextLost()) - return; - MakeContextCurrent(); - gl->fSampleCoverage(value, invert); - } + void SampleCoverage(GLclampf value, WebGLboolean invert); void Scissor(GLint x, GLint y, GLsizei width, GLsizei height); void ShaderSource(WebGLShader *shader, const nsAString& source); void StencilFunc(GLenum func, GLint ref, GLuint mask); @@ -1204,13 +1117,7 @@ protected: int mMaxWarnings; bool mAlreadyWarnedAboutFakeVertexAttrib0; - bool ShouldGenerateWarnings() const { - if (mMaxWarnings == -1) { - return true; - } - - return mAlreadyGeneratedWarnings < mMaxWarnings; - } + bool ShouldGenerateWarnings() const; uint64_t mLastUseIndex; diff --git a/content/canvas/src/WebGLContextGL.cpp b/content/canvas/src/WebGLContextGL.cpp index b72641af7cb..64a4d77d84b 100644 --- a/content/canvas/src/WebGLContextGL.cpp +++ b/content/canvas/src/WebGLContextGL.cpp @@ -4193,3 +4193,51 @@ WebGLContext::ReattachTextureToAnyFramebufferToWorkAroundBugs(WebGLTexture *tex, BindFramebuffer(LOCAL_GL_FRAMEBUFFER, curFB); } + +void +WebGLContext::BlendColor(GLclampf r, GLclampf g, GLclampf b, GLclampf a) { + if (IsContextLost()) + return; + MakeContextCurrent(); + gl->fBlendColor(r, g, b, a); +} + +void +WebGLContext::Flush() { + if (IsContextLost()) + return; + MakeContextCurrent(); + gl->fFlush(); +} + +void +WebGLContext::Finish() { + if (IsContextLost()) + return; + MakeContextCurrent(); + gl->fFinish(); +} + +void +WebGLContext::LineWidth(GLfloat width) { + if (IsContextLost()) + return; + MakeContextCurrent(); + gl->fLineWidth(width); +} + +void +WebGLContext::PolygonOffset(GLfloat factor, GLfloat units) { + if (IsContextLost()) + return; + MakeContextCurrent(); + gl->fPolygonOffset(factor, units); +} + +void +WebGLContext::SampleCoverage(GLclampf value, WebGLboolean invert) { + if (IsContextLost()) + return; + MakeContextCurrent(); + gl->fSampleCoverage(value, invert); +} \ No newline at end of file diff --git a/content/canvas/src/WebGLContextLossTimer.cpp b/content/canvas/src/WebGLContextLossTimer.cpp new file mode 100644 index 00000000000..4c98b5bf6c8 --- /dev/null +++ b/content/canvas/src/WebGLContextLossTimer.cpp @@ -0,0 +1,40 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* 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 "WebGLContext.h" + +using namespace mozilla; + +/* static */ void +WebGLContext::RobustnessTimerCallbackStatic(nsITimer* timer, void *thisPointer) { + static_cast(thisPointer)->RobustnessTimerCallback(timer); +} + +void +WebGLContext::SetupContextLossTimer() { + // If the timer was already running, don't restart it here. Instead, + // wait until the previous call is done, then fire it one more time. + // This is an optimization to prevent unnecessary cross-communication + // between threads. + if (mContextLossTimerRunning) { + mDrawSinceContextLossTimerSet = true; + return; + } + + mContextRestorer->InitWithFuncCallback(RobustnessTimerCallbackStatic, + static_cast(this), + 1000, + nsITimer::TYPE_ONE_SHOT); + mContextLossTimerRunning = true; + mDrawSinceContextLossTimerSet = false; +} + +void +WebGLContext::TerminateContextLossTimer() { + if (mContextLossTimerRunning) { + mContextRestorer->Cancel(); + mContextLossTimerRunning = false; + } +} diff --git a/content/canvas/src/WebGLContextUtils.cpp b/content/canvas/src/WebGLContextUtils.cpp index e2c183d6213..c18611eed7f 100644 --- a/content/canvas/src/WebGLContextUtils.cpp +++ b/content/canvas/src/WebGLContextUtils.cpp @@ -55,6 +55,16 @@ WebGLContext::GenerateWarning(const char *fmt, va_list ap) } } +bool +WebGLContext::ShouldGenerateWarnings() const +{ + if (mMaxWarnings == -1) { + return true; + } + + return mAlreadyGeneratedWarnings < mMaxWarnings; +} + CheckedUint32 WebGLContext::GetImageSize(GLsizei height, GLsizei width, @@ -111,6 +121,12 @@ WebGLContext::ErrorInvalidEnum(const char *fmt, ...) return SynthesizeGLError(LOCAL_GL_INVALID_ENUM); } +void +WebGLContext::ErrorInvalidEnumInfo(const char *info, GLenum enumvalue) +{ + return ErrorInvalidEnum("%s: invalid enum value 0x%x", info, enumvalue); +} + void WebGLContext::ErrorInvalidOperation(const char *fmt, ...) { @@ -208,3 +224,15 @@ WebGLContext::IsTextureFormatCompressed(GLenum format) NS_ABORT(); return false; } + +void +WebGLContext::UpdateWebGLErrorAndClearGLError(GLenum *currentGLError) +{ + // get and clear GL error in ALL cases + GLenum error = gl->GetAndClearError(); + if (currentGLError) + *currentGLError = error; + // only store in mWebGLError if is hasn't already recorded an error + if (!mWebGLError) + mWebGLError = error; +} diff --git a/content/canvas/src/moz.build b/content/canvas/src/moz.build index cd3c1652e2a..694667da1d6 100644 --- a/content/canvas/src/moz.build +++ b/content/canvas/src/moz.build @@ -33,6 +33,7 @@ if CONFIG['MOZ_WEBGL']: 'WebGLContext.cpp', 'WebGLContextAsyncQueries.cpp', 'WebGLContextBuffers.cpp', + 'WebGLContextLossTimer.cpp', 'WebGLContextGL.cpp', 'WebGLContextUtils.cpp', 'WebGLContextReporter.cpp', From 94f74c705d82a1f9235ae070031fea148a764667 Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Wed, 4 Sep 2013 08:14:52 -0400 Subject: [PATCH 074/171] Bug 912042 - Avoid including GLContext.h in headers that don't need it - r=jrmuizel --- .../canvas/src/CanvasRenderingContext2D.cpp | 2 +- content/canvas/src/WebGL2Context.cpp | 1 + content/canvas/src/WebGLBuffer.cpp | 1 + content/canvas/src/WebGLContext.cpp | 12 +- content/canvas/src/WebGLContext.h | 2 +- .../canvas/src/WebGLContextAsyncQueries.cpp | 1 + content/canvas/src/WebGLContextBuffers.cpp | 1 + .../src/WebGLContextFramebufferOperations.cpp | 1 + content/canvas/src/WebGLContextGL.cpp | 1 + content/canvas/src/WebGLContextState.cpp | 1 + content/canvas/src/WebGLContextUtils.cpp | 1 + content/canvas/src/WebGLContextValidate.cpp | 1 + .../canvas/src/WebGLContextVertexArray.cpp | 1 + content/canvas/src/WebGLContextVertices.cpp | 1 + .../canvas/src/WebGLExtensionDrawBuffers.cpp | 1 + .../src/WebGLExtensionInstancedArrays.cpp | 1 + .../canvas/src/WebGLExtensionVertexArray.cpp | 1 + content/canvas/src/WebGLFramebuffer.cpp | 1 + content/canvas/src/WebGLProgram.cpp | 1 + content/canvas/src/WebGLProgram.h | 1 + content/canvas/src/WebGLQuery.cpp | 10 ++ content/canvas/src/WebGLQuery.h | 10 +- content/canvas/src/WebGLRenderbuffer.cpp | 1 + content/canvas/src/WebGLShader.cpp | 1 + content/canvas/src/WebGLTexture.cpp | 1 + content/canvas/src/WebGLVertexArray.cpp | 1 + dom/ipc/TabChild.cpp | 1 + dom/plugins/base/android/ANPOpenGL.cpp | 1 + dom/plugins/base/nsNPAPIPluginInstance.cpp | 9 +- dom/plugins/base/nsNPAPIPluginInstance.h | 2 +- dom/plugins/base/nsPluginInstanceOwner.cpp | 6 +- dom/plugins/ipc/PluginInstanceParent.cpp | 4 +- dom/plugins/ipc/PluginModuleParent.h | 1 + gfx/gl/GLContext.cpp | 2 +- gfx/gl/GLContext.h | 114 +++++------------- gfx/gl/GLContextProvider.h | 2 +- gfx/gl/GLContextProviderCGL.mm | 11 +- gfx/gl/GLContextProviderEGL.cpp | 35 +++--- gfx/gl/GLContextProviderGLX.cpp | 18 +-- gfx/gl/GLContextProviderImpl.h | 11 +- gfx/gl/GLContextProviderNull.cpp | 6 +- gfx/gl/GLContextProviderWGL.cpp | 18 +-- gfx/gl/GLContextTypes.h | 39 +++++- gfx/gl/GLLibraryEGL.cpp | 21 +++- gfx/gl/GLLibraryEGL.h | 42 ++++--- gfx/gl/GLTypes.h | 9 +- gfx/gl/GLXLibrary.h | 6 +- gfx/gl/SharedSurfaceEGL.h | 1 + gfx/gl/SurfaceStream.h | 6 +- gfx/gl/VBOArena.cpp | 1 + gfx/gl/VBOArena.h | 4 +- gfx/gl/WGLLibrary.h | 5 +- gfx/gl/moz.build | 7 +- gfx/layers/SharedTextureImage.h | 2 +- gfx/layers/client/TextureClient.h | 2 +- gfx/layers/d3d10/CanvasLayerD3D10.cpp | 12 ++ gfx/layers/d3d10/CanvasLayerD3D10.h | 18 +-- gfx/layers/ipc/LayersSurfaces.ipdlh | 3 +- gfx/layers/ipc/ShadowLayerUtils.h | 7 +- gfx/layers/ipc/ShadowLayerUtilsGralloc.cpp | 1 + gfx/layers/moz.build | 1 + gfx/layers/opengl/CanvasLayerOGL.cpp | 1 + gfx/layers/opengl/CanvasLayerOGL.h | 5 +- .../opengl/CompositingRenderTargetOGL.cpp | 87 +++++++++++++ .../opengl/CompositingRenderTargetOGL.h | 76 ++---------- gfx/layers/opengl/CompositorOGL.cpp | 90 ++++++++++++++ gfx/layers/opengl/CompositorOGL.h | 87 ++----------- gfx/layers/opengl/ImageLayerOGL.h | 3 +- gfx/layers/opengl/TextureClientOGL.cpp | 2 +- gfx/layers/opengl/TextureClientOGL.h | 6 +- gfx/layers/opengl/TextureHostOGL.cpp | 17 ++- gfx/layers/opengl/TextureHostOGL.h | 27 ++--- gfx/layers/opengl/TexturePoolOGL.h | 4 +- widget/cocoa/nsChildView.h | 4 +- widget/cocoa/nsChildView.mm | 1 + widget/gonk/nsWindow.cpp | 1 + widget/gtk2/nsWindow.cpp | 1 + 77 files changed, 501 insertions(+), 396 deletions(-) create mode 100644 gfx/layers/opengl/CompositingRenderTargetOGL.cpp diff --git a/content/canvas/src/CanvasRenderingContext2D.cpp b/content/canvas/src/CanvasRenderingContext2D.cpp index 21036799e32..89f040d9319 100644 --- a/content/canvas/src/CanvasRenderingContext2D.cpp +++ b/content/canvas/src/CanvasRenderingContext2D.cpp @@ -874,7 +874,7 @@ CanvasRenderingContext2D::EnsureTarget() if (!mForceSoftware && CheckSizeForSkiaGL(size)) { glContext = GLContextProvider::CreateOffscreen(gfxIntSize(size.width, size.height), - caps, GLContext::ContextFlagsNone); + caps, gl::ContextFlagsNone); } if (glContext) { diff --git a/content/canvas/src/WebGL2Context.cpp b/content/canvas/src/WebGL2Context.cpp index 809cb87aafa..3fe0292157f 100644 --- a/content/canvas/src/WebGL2Context.cpp +++ b/content/canvas/src/WebGL2Context.cpp @@ -4,6 +4,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "WebGL2Context.h" +#include "GLContext.h" #include "mozilla/dom/WebGL2RenderingContextBinding.h" #include "mozilla/Telemetry.h" diff --git a/content/canvas/src/WebGLBuffer.cpp b/content/canvas/src/WebGLBuffer.cpp index 815087b810e..7703e1b0d1e 100644 --- a/content/canvas/src/WebGLBuffer.cpp +++ b/content/canvas/src/WebGLBuffer.cpp @@ -5,6 +5,7 @@ #include "WebGLBuffer.h" #include "WebGLContext.h" +#include "GLContext.h" #include "mozilla/dom/WebGLRenderingContextBinding.h" using namespace mozilla; diff --git a/content/canvas/src/WebGLContext.cpp b/content/canvas/src/WebGLContext.cpp index dadddcf9117..712965cdace 100644 --- a/content/canvas/src/WebGLContext.cpp +++ b/content/canvas/src/WebGLContext.cpp @@ -37,6 +37,7 @@ #include "nsDisplayList.h" #include "GLContextProvider.h" +#include "GLContext.h" #include "gfxCrashReporterUtils.h" @@ -530,9 +531,9 @@ WebGLContext::SetDimensions(int32_t width, int32_t height) // try the default provider, whatever that is if (!gl && useOpenGL) { - GLContext::ContextFlags flag = useMesaLlvmPipe - ? GLContext::ContextFlagsMesaLLVMPipe - : GLContext::ContextFlagsNone; + gl::ContextFlags flag = useMesaLlvmPipe + ? gl::ContextFlagsMesaLLVMPipe + : gl::ContextFlagsNone; gl = gl::GLContextProvider::CreateOffscreen(size, caps, flag); if (gl && !InitAndValidateGL()) { GenerateWarning("Error during %s initialization", @@ -1243,7 +1244,7 @@ WebGLContext::MaybeRestoreContext() if (mContextStatus != ContextNotLost || gl == nullptr) return; - bool isEGL = gl->GetContextType() == GLContext::ContextTypeEGL, + bool isEGL = gl->GetContextType() == gl::ContextTypeEGL, isANGLE = gl->IsANGLE(); GLContext::ContextResetARB resetStatus = GLContext::CONTEXT_NO_ERROR; @@ -1311,6 +1312,9 @@ WebGLContext::ForceRestoreContext() mContextStatus = ContextLostAwaitingRestore; } +void +WebGLContext::MakeContextCurrent() const { gl->MakeCurrent(); } + // // XPCOM goop // diff --git a/content/canvas/src/WebGLContext.h b/content/canvas/src/WebGLContext.h index b823d50945f..4a03e67955e 100644 --- a/content/canvas/src/WebGLContext.h +++ b/content/canvas/src/WebGLContext.h @@ -951,7 +951,7 @@ protected: void Invalidate(); void DestroyResourcesAndContext(); - void MakeContextCurrent() const { gl->MakeCurrent(); } + void MakeContextCurrent() const; // helpers void TexImage2D_base(GLenum target, GLint level, GLenum internalformat, diff --git a/content/canvas/src/WebGLContextAsyncQueries.cpp b/content/canvas/src/WebGLContextAsyncQueries.cpp index 228739bc7c9..e87b5c0f5d8 100644 --- a/content/canvas/src/WebGLContextAsyncQueries.cpp +++ b/content/canvas/src/WebGLContextAsyncQueries.cpp @@ -5,6 +5,7 @@ #include "WebGLContext.h" #include "WebGLQuery.h" +#include "GLContext.h" using namespace mozilla; diff --git a/content/canvas/src/WebGLContextBuffers.cpp b/content/canvas/src/WebGLContextBuffers.cpp index 07784cef547..77e9b1dbcf3 100644 --- a/content/canvas/src/WebGLContextBuffers.cpp +++ b/content/canvas/src/WebGLContextBuffers.cpp @@ -4,6 +4,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "WebGLContext.h" +#include "GLContext.h" #include "WebGLBuffer.h" #include "WebGLVertexArray.h" diff --git a/content/canvas/src/WebGLContextFramebufferOperations.cpp b/content/canvas/src/WebGLContextFramebufferOperations.cpp index 03ceebdaeb0..234f52375f2 100644 --- a/content/canvas/src/WebGLContextFramebufferOperations.cpp +++ b/content/canvas/src/WebGLContextFramebufferOperations.cpp @@ -7,6 +7,7 @@ #include "WebGLTexture.h" #include "WebGLRenderbuffer.h" #include "WebGLFramebuffer.h" +#include "GLContext.h" using namespace mozilla; diff --git a/content/canvas/src/WebGLContextGL.cpp b/content/canvas/src/WebGLContextGL.cpp index 64a4d77d84b..824ffd3b3eb 100644 --- a/content/canvas/src/WebGLContextGL.cpp +++ b/content/canvas/src/WebGLContextGL.cpp @@ -23,6 +23,7 @@ #include "gfxImageSurface.h" #include "gfxContext.h" #include "gfxPlatform.h" +#include "GLContext.h" #include "nsContentUtils.h" #include "nsError.h" diff --git a/content/canvas/src/WebGLContextState.cpp b/content/canvas/src/WebGLContextState.cpp index aab97d6cce7..96ec28f8157 100644 --- a/content/canvas/src/WebGLContextState.cpp +++ b/content/canvas/src/WebGLContextState.cpp @@ -12,6 +12,7 @@ #include "WebGLRenderbuffer.h" #include "WebGLTexture.h" #include "WebGLVertexArray.h" +#include "GLContext.h" using namespace mozilla; using namespace dom; diff --git a/content/canvas/src/WebGLContextUtils.cpp b/content/canvas/src/WebGLContextUtils.cpp index c18611eed7f..1932f088f49 100644 --- a/content/canvas/src/WebGLContextUtils.cpp +++ b/content/canvas/src/WebGLContextUtils.cpp @@ -6,6 +6,7 @@ #include #include "WebGLContext.h" +#include "GLContext.h" #include "prprf.h" diff --git a/content/canvas/src/WebGLContextValidate.cpp b/content/canvas/src/WebGLContextValidate.cpp index 56630d2e046..b5148640329 100644 --- a/content/canvas/src/WebGLContextValidate.cpp +++ b/content/canvas/src/WebGLContextValidate.cpp @@ -13,6 +13,7 @@ #include "WebGLRenderbuffer.h" #include "WebGLTexture.h" #include "WebGLVertexArray.h" +#include "GLContext.h" #include "mozilla/CheckedInt.h" #include "mozilla/Preferences.h" diff --git a/content/canvas/src/WebGLContextVertexArray.cpp b/content/canvas/src/WebGLContextVertexArray.cpp index 26d7a36848c..48d2c6f83c7 100644 --- a/content/canvas/src/WebGLContextVertexArray.cpp +++ b/content/canvas/src/WebGLContextVertexArray.cpp @@ -7,6 +7,7 @@ #include "WebGLBuffer.h" #include "WebGLVertexAttribData.h" #include "WebGLVertexArray.h" +#include "GLContext.h" using namespace mozilla; diff --git a/content/canvas/src/WebGLContextVertices.cpp b/content/canvas/src/WebGLContextVertices.cpp index 768dbdf6255..edb8a308bf6 100644 --- a/content/canvas/src/WebGLContextVertices.cpp +++ b/content/canvas/src/WebGLContextVertices.cpp @@ -13,6 +13,7 @@ #include "WebGLUniformInfo.h" #include "WebGLShader.h" #include "WebGLProgram.h" +#include "GLContext.h" using namespace mozilla; using namespace dom; diff --git a/content/canvas/src/WebGLExtensionDrawBuffers.cpp b/content/canvas/src/WebGLExtensionDrawBuffers.cpp index f2652bb518e..941ccec3f4e 100644 --- a/content/canvas/src/WebGLExtensionDrawBuffers.cpp +++ b/content/canvas/src/WebGLExtensionDrawBuffers.cpp @@ -8,6 +8,7 @@ #include "WebGLTexture.h" #include "WebGLRenderbuffer.h" #include "WebGLFramebuffer.h" +#include "GLContext.h" #include diff --git a/content/canvas/src/WebGLExtensionInstancedArrays.cpp b/content/canvas/src/WebGLExtensionInstancedArrays.cpp index 41c6d7fa05b..2c4ec8e4ba0 100644 --- a/content/canvas/src/WebGLExtensionInstancedArrays.cpp +++ b/content/canvas/src/WebGLExtensionInstancedArrays.cpp @@ -6,6 +6,7 @@ #include "WebGLContext.h" #include "WebGLExtensions.h" #include "mozilla/dom/WebGLRenderingContextBinding.h" +#include "GLContext.h" using namespace mozilla; diff --git a/content/canvas/src/WebGLExtensionVertexArray.cpp b/content/canvas/src/WebGLExtensionVertexArray.cpp index 152f7833ecd..59c72b6b2f7 100644 --- a/content/canvas/src/WebGLExtensionVertexArray.cpp +++ b/content/canvas/src/WebGLExtensionVertexArray.cpp @@ -8,6 +8,7 @@ #include "WebGLVertexArray.h" #include "WebGLExtensions.h" #include "mozilla/dom/WebGLRenderingContextBinding.h" +#include "GLContext.h" using namespace mozilla; diff --git a/content/canvas/src/WebGLFramebuffer.cpp b/content/canvas/src/WebGLFramebuffer.cpp index 655f401a51c..8d65e47c942 100644 --- a/content/canvas/src/WebGLFramebuffer.cpp +++ b/content/canvas/src/WebGLFramebuffer.cpp @@ -11,6 +11,7 @@ #include "mozilla/dom/WebGLRenderingContextBinding.h" #include "WebGLTexture.h" #include "WebGLRenderbuffer.h" +#include "GLContext.h" using namespace mozilla; diff --git a/content/canvas/src/WebGLProgram.cpp b/content/canvas/src/WebGLProgram.cpp index 98893d7c594..1ccbbaa6349 100644 --- a/content/canvas/src/WebGLProgram.cpp +++ b/content/canvas/src/WebGLProgram.cpp @@ -7,6 +7,7 @@ #include "WebGLShader.h" #include "WebGLProgram.h" #include "mozilla/dom/WebGLRenderingContextBinding.h" +#include "GLContext.h" using namespace mozilla; diff --git a/content/canvas/src/WebGLProgram.h b/content/canvas/src/WebGLProgram.h index d4b4ad5b46d..a064ffd3103 100644 --- a/content/canvas/src/WebGLProgram.h +++ b/content/canvas/src/WebGLProgram.h @@ -12,6 +12,7 @@ #include "mozilla/LinkedList.h" #include "mozilla/CheckedInt.h" +#include namespace mozilla { diff --git a/content/canvas/src/WebGLQuery.cpp b/content/canvas/src/WebGLQuery.cpp index 456a96e3da9..8785d6899f1 100644 --- a/content/canvas/src/WebGLQuery.cpp +++ b/content/canvas/src/WebGLQuery.cpp @@ -4,6 +4,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "WebGLContext.h" +#include "GLContext.h" #include "WebGLQuery.h" #include "mozilla/dom/WebGL2RenderingContextBinding.h" #include "nsContentUtils.h" @@ -33,6 +34,15 @@ void WebGLQuery::Delete() { LinkedListElement::removeFrom(mContext->mQueries); } +bool WebGLQuery::IsActive() const +{ + WebGLRefPtr* targetSlot = mContext->GetQueryTargetSlot(mType, "WebGLQuery::IsActive()"); + + MOZ_ASSERT(targetSlot, "unknown query object's type"); + + return *targetSlot == this; +} + NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLQuery) diff --git a/content/canvas/src/WebGLQuery.h b/content/canvas/src/WebGLQuery.h index f57781a3847..1e565ff22c3 100644 --- a/content/canvas/src/WebGLQuery.h +++ b/content/canvas/src/WebGLQuery.h @@ -7,7 +7,6 @@ #define WEBGLQUERY_H_ #include "WebGLObjectModel.h" -#include "WebGLContext.h" #include "nsWrapperCache.h" @@ -38,14 +37,7 @@ public: // ------------------------------------------------------------------------- // MEMBER FUNCTIONS - bool IsActive() const - { - WebGLRefPtr* targetSlot = mContext->GetQueryTargetSlot(mType, "WebGLQuery::IsActive()"); - - MOZ_ASSERT(targetSlot, "unknown query object's type"); - - return *targetSlot == this; - } + bool IsActive() const; bool HasEverBeenActive() { diff --git a/content/canvas/src/WebGLRenderbuffer.cpp b/content/canvas/src/WebGLRenderbuffer.cpp index dc9e595300b..c7321bb7f70 100644 --- a/content/canvas/src/WebGLRenderbuffer.cpp +++ b/content/canvas/src/WebGLRenderbuffer.cpp @@ -7,6 +7,7 @@ #include "WebGLRenderbuffer.h" #include "WebGLTexture.h" #include "mozilla/dom/WebGLRenderingContextBinding.h" +#include "GLContext.h" using namespace mozilla; diff --git a/content/canvas/src/WebGLShader.cpp b/content/canvas/src/WebGLShader.cpp index 943357096b6..e0f8ce43d62 100644 --- a/content/canvas/src/WebGLShader.cpp +++ b/content/canvas/src/WebGLShader.cpp @@ -8,6 +8,7 @@ #include "WebGLContext.h" #include "mozilla/MemoryReporting.h" #include "mozilla/dom/WebGLRenderingContextBinding.h" +#include "GLContext.h" using namespace mozilla; diff --git a/content/canvas/src/WebGLTexture.cpp b/content/canvas/src/WebGLTexture.cpp index e3a6a42dd04..15ccb8c26ea 100644 --- a/content/canvas/src/WebGLTexture.cpp +++ b/content/canvas/src/WebGLTexture.cpp @@ -5,6 +5,7 @@ #include "WebGLContext.h" #include "WebGLTexture.h" +#include "GLContext.h" #include "mozilla/dom/WebGLRenderingContextBinding.h" #include diff --git a/content/canvas/src/WebGLVertexArray.cpp b/content/canvas/src/WebGLVertexArray.cpp index f24428e081f..a85701af55a 100644 --- a/content/canvas/src/WebGLVertexArray.cpp +++ b/content/canvas/src/WebGLVertexArray.cpp @@ -7,6 +7,7 @@ #include "WebGLBuffer.h" #include "WebGLVertexArray.h" #include "mozilla/dom/WebGLRenderingContextBinding.h" +#include "GLContext.h" using namespace mozilla; diff --git a/dom/ipc/TabChild.cpp b/dom/ipc/TabChild.cpp index 2d0fe89a6c1..be0dc87d4f3 100644 --- a/dom/ipc/TabChild.cpp +++ b/dom/ipc/TabChild.cpp @@ -12,6 +12,7 @@ #include "Blob.h" #include "ContentChild.h" #include "IndexedDBChild.h" +#include "mozilla/Preferences.h" #include "mozilla/ClearOnShutdown.h" #include "mozilla/IntentionalCrash.h" #include "mozilla/docshell/OfflineCacheUpdateChild.h" diff --git a/dom/plugins/base/android/ANPOpenGL.cpp b/dom/plugins/base/android/ANPOpenGL.cpp index 598720fa3ed..c6adff8f762 100644 --- a/dom/plugins/base/android/ANPOpenGL.cpp +++ b/dom/plugins/base/android/ANPOpenGL.cpp @@ -10,6 +10,7 @@ #include "nsNPAPIPluginInstance.h" #include "nsPluginInstanceOwner.h" #include "GLContextProvider.h" +#include "GLContext.h" #define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args) #define ASSIGN(obj, name) (obj)->name = anp_opengl_##name diff --git a/dom/plugins/base/nsNPAPIPluginInstance.cpp b/dom/plugins/base/nsNPAPIPluginInstance.cpp index 96fc8b2db44..eb091006b05 100644 --- a/dom/plugins/base/nsNPAPIPluginInstance.cpp +++ b/dom/plugins/base/nsNPAPIPluginInstance.cpp @@ -50,6 +50,7 @@ using namespace mozilla; #include "mozilla/dom/ScreenOrientation.h" #include "mozilla/Hal.h" #include "GLContextProvider.h" +#include "GLContext.h" #include "TexturePoolOGL.h" using namespace mozilla::gl; @@ -135,9 +136,9 @@ public: return 0; SharedTextureHandle handle = - sPluginContext->CreateSharedHandle(GLContext::SameProcess, + sPluginContext->CreateSharedHandle(gl::SameProcess, (void*)mTextureInfo.mTexture, - GLContext::TextureID); + gl::TextureID); // We want forget about this now, so delete the texture. Assigning it to zero // ensures that we create a new one in Lock() @@ -1013,9 +1014,9 @@ SharedTextureHandle nsNPAPIPluginInstance::CreateSharedHandle() return mContentTexture->CreateSharedHandle(); } else if (mContentSurface) { EnsureGLContext(); - return sPluginContext->CreateSharedHandle(GLContext::SameProcess, + return sPluginContext->CreateSharedHandle(gl::SameProcess, mContentSurface, - GLContext::SurfaceTexture); + gl::SurfaceTexture); } else return 0; } diff --git a/dom/plugins/base/nsNPAPIPluginInstance.h b/dom/plugins/base/nsNPAPIPluginInstance.h index 490f00bc343..2dd659620cb 100644 --- a/dom/plugins/base/nsNPAPIPluginInstance.h +++ b/dom/plugins/base/nsNPAPIPluginInstance.h @@ -20,7 +20,7 @@ #ifdef MOZ_WIDGET_ANDROID #include "nsAutoPtr.h" #include "nsIRunnable.h" -#include "GLContext.h" +#include "GLContextTypes.h" #include "nsSurfaceTexture.h" #include "AndroidBridge.h" #include diff --git a/dom/plugins/base/nsPluginInstanceOwner.cpp b/dom/plugins/base/nsPluginInstanceOwner.cpp index a07d3184981..f5ba2c88d79 100644 --- a/dom/plugins/base/nsPluginInstanceOwner.cpp +++ b/dom/plugins/base/nsPluginInstanceOwner.cpp @@ -170,7 +170,7 @@ nsPluginInstanceOwner::GetImageContainer() SharedTextureImage::Data data; data.mHandle = mInstance->CreateSharedHandle(); - data.mShareType = mozilla::gl::GLContext::SameProcess; + data.mShareType = mozilla::gl::SameProcess; data.mInverted = mInstance->Inverted(); LayoutDeviceRect r = GetPluginRect(); @@ -1681,10 +1681,10 @@ already_AddRefed nsPluginInstanceOwner::GetImageContainerForVide SharedTextureImage::Data data; - data.mShareType = gl::GLContext::SameProcess; + data.mShareType = gl::SameProcess; data.mHandle = mInstance->GLContext()->CreateSharedHandle(data.mShareType, aVideoInfo->mSurfaceTexture, - gl::GLContext::SurfaceTexture); + gl::SurfaceTexture); // The logic below for Honeycomb is just a guess, but seems to work. We don't have a separate // inverted flag for video. diff --git a/dom/plugins/ipc/PluginInstanceParent.cpp b/dom/plugins/ipc/PluginInstanceParent.cpp index 718d6147b33..19f32c09d14 100644 --- a/dom/plugins/ipc/PluginInstanceParent.cpp +++ b/dom/plugins/ipc/PluginInstanceParent.cpp @@ -727,10 +727,10 @@ PluginInstanceParent::GetImageContainer(ImageContainer** aContainer) NS_ASSERTION(image->GetFormat() == SHARED_TEXTURE, "Wrong format?"); SharedTextureImage::Data data; - data.mShareType = GLContext::SameProcess; + data.mShareType = gl::SameProcess; data.mHandle = GLContextProviderCGL::CreateSharedHandle(data.mShareType, ioSurface, - GLContext::IOSurface); + gl::IOSurface); data.mInverted = false; // Use the device pixel size of the IOSurface, since layers handles resolution scaling // already. diff --git a/dom/plugins/ipc/PluginModuleParent.h b/dom/plugins/ipc/PluginModuleParent.h index b651ad48c03..27907ef12f3 100644 --- a/dom/plugins/ipc/PluginModuleParent.h +++ b/dom/plugins/ipc/PluginModuleParent.h @@ -17,6 +17,7 @@ #include "nsAutoPtr.h" #include "nsDataHashtable.h" #include "nsHashKeys.h" +#include "nsIObserver.h" #ifdef MOZ_CRASHREPORTER #include "nsExceptionHandler.h" diff --git a/gfx/gl/GLContext.cpp b/gfx/gl/GLContext.cpp index 44938b0015c..7c5885153af 100644 --- a/gfx/gl/GLContext.cpp +++ b/gfx/gl/GLContext.cpp @@ -1034,7 +1034,7 @@ GLContext::InitExtensions() const bool firstRun = false; #endif - mAvailableExtensions.Load(extensions, sExtensionNames, firstRun && DebugMode()); + InitializeExtensionsBitSet(mAvailableExtensions, extensions, sExtensionNames, firstRun && DebugMode()); if (WorkAroundDriverBugs() && Vendor() == VendorQualcomm) { diff --git a/gfx/gl/GLContext.h b/gfx/gl/GLContext.h index 6ec2fec93f4..1173e7d2e69 100644 --- a/gfx/gl/GLContext.h +++ b/gfx/gl/GLContext.h @@ -17,6 +17,7 @@ #include #include #include +#include #ifdef WIN32 #include @@ -118,8 +119,6 @@ namespace GLFeature { }; } -typedef uintptr_t SharedTextureHandle; - MOZ_BEGIN_ENUM_CLASS(ContextProfile, uint8_t) Unknown = 0, OpenGL, // only for IsAtLeast's parameter @@ -128,7 +127,6 @@ MOZ_BEGIN_ENUM_CLASS(ContextProfile, uint8_t) OpenGLES MOZ_END_ENUM_CLASS(ContextProfile) - class GLContext : public GLLibraryLoader , public GenericAtomicRefCounted @@ -158,20 +156,6 @@ public: RendererOther }; - enum ContextFlags { - ContextFlagsNone = 0x0, - ContextFlagsGlobal = 0x1, - ContextFlagsMesaLLVMPipe = 0x2 - }; - - enum GLContextType { - ContextTypeUnknown, - ContextTypeWGL, - ContextTypeCGL, - ContextTypeGLX, - ContextTypeEGL - }; - // ----------------------------------------------------------------------------- // basic getters @@ -438,66 +422,41 @@ public: public: - // this should just be a std::bitset, but that ended up breaking - // MacOS X builds; see bug 584919. We can replace this with one - // later on. This is handy to use in WebGL contexts as well, - // so making it public. - template - struct ExtensionBitset + template + static void InitializeExtensionsBitSet(std::bitset& extensionsBitset, const char* extStr, const char** extList, bool verbose = false) { - ExtensionBitset() - { - for (size_t i = 0; i < Size; ++i) - extensions[i] = false; - } + char* exts = strdup(extStr); - void Load(const char* extStr, const char** extList, bool verbose = false) - { - char* exts = strdup(extStr); + if (verbose) + printf_stderr("Extensions: %s\n", exts); - if (verbose) - printf_stderr("Extensions: %s\n", exts); - - char* cur = exts; - bool done = false; - while (!done) { - char* space = strchr(cur, ' '); - if (space) { - *space = '\0'; - } else { - done = true; - } - - for (int i = 0; extList[i]; ++i) { - if (PL_strcasecmp(cur, extList[i]) == 0) { - if (verbose) - printf_stderr("Found extension %s\n", cur); - extensions[i] = 1; - } - } - - cur = space + 1; + char* cur = exts; + bool done = false; + while (!done) { + char* space = strchr(cur, ' '); + if (space) { + *space = '\0'; + } else { + done = true; } - free(exts); + for (int i = 0; extList[i]; ++i) { + if (PL_strcasecmp(cur, extList[i]) == 0) { + if (verbose) + printf_stderr("Found extension %s\n", cur); + extensionsBitset[i] = true; + } + } + + cur = space + 1; } - bool& operator[](size_t index) { - MOZ_ASSERT(index < Size, "out of range"); - return extensions[index]; - } - - const bool& operator[](size_t index) const { - MOZ_ASSERT(index < Size, "out of range"); - return extensions[index]; - } - - bool extensions[Size]; - }; + free(exts); + } protected: - ExtensionBitset mAvailableExtensions; + std::bitset mAvailableExtensions; // ----------------------------------------------------------------------------- @@ -516,7 +475,7 @@ public: private: - ExtensionBitset mAvailableFeatures; + std::bitset mAvailableFeatures; /** * Init features regarding OpenGL extension and context version and profile @@ -621,6 +580,9 @@ private: // MOZ_GL_DEBUG implementation private: +#undef BEFORE_GL_CALL +#undef AFTER_GL_CALL + #ifdef DEBUG #ifndef MOZ_FUNCTION_NAME @@ -2591,22 +2553,6 @@ public: */ const gfxIntSize& OffscreenSize() const; - - enum SharedTextureShareType { - SameProcess = 0, - CrossProcess - }; - - enum SharedTextureBufferType { - TextureID -#ifdef MOZ_WIDGET_ANDROID - , SurfaceTexture -#endif -#ifdef XP_MACOSX - , IOSurface -#endif - }; - /* * Create a new shared GLContext content handle, using the passed buffer as a source. * Must be released by ReleaseSharedHandle. UpdateSharedHandle will have no effect diff --git a/gfx/gl/GLContextProvider.h b/gfx/gl/GLContextProvider.h index 8e2410025ff..0e1018b09b8 100644 --- a/gfx/gl/GLContextProvider.h +++ b/gfx/gl/GLContextProvider.h @@ -6,7 +6,7 @@ #ifndef GLCONTEXTPROVIDER_H_ #define GLCONTEXTPROVIDER_H_ -#include "GLContext.h" +#include "GLContextTypes.h" #include "gfxTypes.h" #include "gfxPoint.h" #include "nsAutoPtr.h" diff --git a/gfx/gl/GLContextProviderCGL.mm b/gfx/gl/GLContextProviderCGL.mm index 12ec71aeb80..7045a750dfe 100644 --- a/gfx/gl/GLContextProviderCGL.mm +++ b/gfx/gl/GLContextProviderCGL.mm @@ -4,6 +4,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "GLContextProvider.h" +#include "GLContext.h" #include "nsDebug.h" #include "nsIWidget.h" #include "OpenGL/OpenGL.h" @@ -518,12 +519,12 @@ GLContextProviderCGL::GetGlobalContext(const ContextFlags) } SharedTextureHandle -GLContextProviderCGL::CreateSharedHandle(GLContext::SharedTextureShareType shareType, +GLContextProviderCGL::CreateSharedHandle(SharedTextureShareType shareType, void* buffer, - GLContext::SharedTextureBufferType bufferType) + SharedTextureBufferType bufferType) { - if (shareType != GLContext::SameProcess || - bufferType != GLContext::IOSurface) { + if (shareType != SameProcess || + bufferType != gl::IOSurface) { return 0; } @@ -534,7 +535,7 @@ GLContextProviderCGL::CreateSharedHandle(GLContext::SharedTextureShareType share } already_AddRefed -GLContextProviderCGL::GetSharedHandleAsSurface(GLContext::SharedTextureShareType shareType, +GLContextProviderCGL::GetSharedHandleAsSurface(SharedTextureShareType shareType, SharedTextureHandle sharedHandle) { MacIOSurface* surf = reinterpret_cast(sharedHandle); diff --git a/gfx/gl/GLContextProviderEGL.cpp b/gfx/gl/GLContextProviderEGL.cpp index 85d1f2b9c6d..0d201f80fc2 100644 --- a/gfx/gl/GLContextProviderEGL.cpp +++ b/gfx/gl/GLContextProviderEGL.cpp @@ -3,6 +3,7 @@ * 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 "GLContext.h" #include "mozilla/Util.h" // please add new includes below Qt, otherwise it break Qt build due malloc wrapper conflicts @@ -736,12 +737,12 @@ protected: }; -typedef enum { - Image +enum SharedHandleType { + SharedHandleType_Image #ifdef MOZ_WIDGET_ANDROID - , SurfaceTexture + , SharedHandleType_SurfaceTexture #endif -} SharedHandleType; +}; class SharedTextureHandleWrapper { @@ -765,7 +766,7 @@ class SurfaceTextureWrapper: public SharedTextureHandleWrapper { public: SurfaceTextureWrapper(nsSurfaceTexture* aSurfaceTexture) : - SharedTextureHandleWrapper(SharedHandleType::SurfaceTexture) + SharedTextureHandleWrapper(SharedHandleType_SurfaceTexture) , mSurfaceTexture(aSurfaceTexture) { } @@ -785,7 +786,7 @@ class EGLTextureWrapper : public SharedTextureHandleWrapper { public: EGLTextureWrapper() : - SharedTextureHandleWrapper(SharedHandleType::Image) + SharedTextureHandleWrapper(SharedHandleType_Image) , mEGLImage(nullptr) , mSyncObject(nullptr) { @@ -876,7 +877,7 @@ GLContextEGL::UpdateSharedHandle(SharedTextureShareType shareType, SharedTextureHandleWrapper* wrapper = reinterpret_cast(sharedHandle); - NS_ASSERTION(wrapper->Type() == SharedHandleType::Image, "Expected EGLImage shared handle"); + NS_ASSERTION(wrapper->Type() == SharedHandleType_Image, "Expected EGLImage shared handle"); NS_ASSERTION(mShareWithEGLImage, "EGLImage not supported or disabled in runtime"); EGLTextureWrapper* wrap = reinterpret_cast(wrapper); @@ -950,12 +951,12 @@ void GLContextEGL::ReleaseSharedHandle(SharedTextureShareType shareType, switch (wrapper->Type()) { #ifdef MOZ_WIDGET_ANDROID - case SharedHandleType::SurfaceTexture: + case SharedHandleType_SurfaceTexture: delete wrapper; break; #endif - case SharedHandleType::Image: { + case SharedHandleType_Image: { NS_ASSERTION(mShareWithEGLImage, "EGLImage not supported or disabled in runtime"); EGLTextureWrapper* wrap = (EGLTextureWrapper*)sharedHandle; @@ -980,7 +981,7 @@ bool GLContextEGL::GetSharedHandleDetails(SharedTextureShareType shareType, switch (wrapper->Type()) { #ifdef MOZ_WIDGET_ANDROID - case SharedHandleType::SurfaceTexture: { + case SharedHandleType_SurfaceTexture: { SurfaceTextureWrapper* surfaceWrapper = reinterpret_cast(wrapper); details.mTarget = LOCAL_GL_TEXTURE_EXTERNAL; @@ -990,7 +991,7 @@ bool GLContextEGL::GetSharedHandleDetails(SharedTextureShareType shareType, } #endif - case SharedHandleType::Image: + case SharedHandleType_Image: details.mTarget = LOCAL_GL_TEXTURE_2D; details.mTextureFormat = FORMAT_R8G8B8A8; break; @@ -1013,7 +1014,7 @@ bool GLContextEGL::AttachSharedHandle(SharedTextureShareType shareType, switch (wrapper->Type()) { #ifdef MOZ_WIDGET_ANDROID - case SharedHandleType::SurfaceTexture: { + case SharedHandleType_SurfaceTexture: { #ifndef DEBUG /** * NOTE: SurfaceTexture spams us if there are any existing GL errors, so we'll clear @@ -1031,7 +1032,7 @@ bool GLContextEGL::AttachSharedHandle(SharedTextureShareType shareType, } #endif // MOZ_WIDGET_ANDROID - case SharedHandleType::Image: { + case SharedHandleType_Image: { NS_ASSERTION(mShareWithEGLImage, "EGLImage not supported or disabled in runtime"); EGLTextureWrapper* wrap = (EGLTextureWrapper*)sharedHandle; @@ -2012,7 +2013,7 @@ GLContextProviderEGL::CreateOffscreen(const gfxIntSize& size, if (!glContext) return nullptr; - if (flags & GLContext::ContextFlagsGlobal) + if (flags & ContextFlagsGlobal) return glContext.forget(); if (!glContext->InitOffscreen(size, caps)) @@ -2022,15 +2023,15 @@ GLContextProviderEGL::CreateOffscreen(const gfxIntSize& size, } SharedTextureHandle -GLContextProviderEGL::CreateSharedHandle(GLContext::SharedTextureShareType shareType, +GLContextProviderEGL::CreateSharedHandle(SharedTextureShareType shareType, void* buffer, - GLContext::SharedTextureBufferType bufferType) + SharedTextureBufferType bufferType) { return 0; } already_AddRefed -GLContextProviderEGL::GetSharedHandleAsSurface(GLContext::SharedTextureShareType shareType, +GLContextProviderEGL::GetSharedHandleAsSurface(SharedTextureShareType shareType, SharedTextureHandle sharedHandle) { return nullptr; diff --git a/gfx/gl/GLContextProviderGLX.cpp b/gfx/gl/GLContextProviderGLX.cpp index 08ce90928e8..e51f7f04cb8 100644 --- a/gfx/gl/GLContextProviderGLX.cpp +++ b/gfx/gl/GLContextProviderGLX.cpp @@ -50,9 +50,9 @@ typedef GLXLibrary::LibraryType LibType; static LibType gCurrLib = GLXLibrary::OPENGL_LIB; LibType -GLXLibrary::SelectLibrary(const GLContext::ContextFlags& aFlags) +GLXLibrary::SelectLibrary(const ContextFlags& aFlags) { - return (aFlags & GLContext::ContextFlagsMesaLLVMPipe) + return (aFlags & ContextFlagsMesaLLVMPipe) ? GLXLibrary::MESA_LLVMPIPE_LIB : GLXLibrary::OPENGL_LIB; } @@ -1160,7 +1160,7 @@ GLContextGLX::CreateTextureImage(const nsIntSize& aSize, } static GLContextGLX * -GetGlobalContextGLX(const GLContext::ContextFlags aFlags = GLContext::ContextFlagsNone) +GetGlobalContextGLX(const ContextFlags aFlags = ContextFlagsNone) { return static_cast(GLContextProviderGLX::GetGlobalContext(aFlags)); } @@ -1384,9 +1384,9 @@ DONE_CREATING_PIXMAP: if (!error && // earlier recorded error !serverError) { - GLContext::ContextFlags flag = libToUse == GLXLibrary::MESA_LLVMPIPE_LIB - ? GLContext::ContextFlagsMesaLLVMPipe - : GLContext::ContextFlagsNone; + ContextFlags flag = libToUse == GLXLibrary::MESA_LLVMPIPE_LIB + ? ContextFlagsMesaLLVMPipe + : ContextFlagsNone; // We might have an alpha channel, but it doesn't matter. SurfaceCaps dummyCaps = SurfaceCaps::Any(); GLContextGLX* shareContext = GetGlobalContextGLX(flag); @@ -1427,15 +1427,15 @@ GLContextProviderGLX::CreateOffscreen(const gfxIntSize& size, } SharedTextureHandle -GLContextProviderGLX::CreateSharedHandle(GLContext::SharedTextureShareType shareType, +GLContextProviderGLX::CreateSharedHandle(SharedTextureShareType shareType, void* buffer, - GLContext::SharedTextureBufferType bufferType) + SharedTextureBufferType bufferType) { return 0; } already_AddRefed -GLContextProviderGLX::GetSharedHandleAsSurface(GLContext::SharedTextureShareType shareType, +GLContextProviderGLX::GetSharedHandleAsSurface(SharedTextureShareType shareType, SharedTextureHandle sharedHandle) { return nullptr; diff --git a/gfx/gl/GLContextProviderImpl.h b/gfx/gl/GLContextProviderImpl.h index 96b74475ca0..34591f2368b 100644 --- a/gfx/gl/GLContextProviderImpl.h +++ b/gfx/gl/GLContextProviderImpl.h @@ -14,7 +14,6 @@ class GL_CONTEXT_PROVIDER_NAME { public: - typedef GLContext::ContextFlags ContextFlags; typedef gfx::SurfaceCaps SurfaceCaps; /** * Create a context that renders to the surface of the widget that is @@ -61,13 +60,13 @@ public: static already_AddRefed CreateOffscreen(const gfxIntSize& size, const SurfaceCaps& caps, - ContextFlags flags = GLContext::ContextFlagsNone); + ContextFlags flags = ContextFlagsNone); /** * Get a pointer to the global context, creating it if it doesn't exist. */ static GLContext* - GetGlobalContext(ContextFlags flags = GLContext::ContextFlagsNone); + GetGlobalContext(ContextFlags flags = ContextFlagsNone); /* * Create a new shared GLContext content handle, using the passed buffer as a source. @@ -75,11 +74,11 @@ public: * on handles created with this method, as the caller owns the source (the passed buffer) * and is responsible for updating it accordingly. */ - static SharedTextureHandle CreateSharedHandle(GLContext::SharedTextureShareType shareType, + static SharedTextureHandle CreateSharedHandle(SharedTextureShareType shareType, void* buffer, - GLContext::SharedTextureBufferType bufferType); + SharedTextureBufferType bufferType); - static already_AddRefed GetSharedHandleAsSurface(GLContext::SharedTextureShareType shareType, + static already_AddRefed GetSharedHandleAsSurface(SharedTextureShareType shareType, SharedTextureHandle sharedHandle); /** diff --git a/gfx/gl/GLContextProviderNull.cpp b/gfx/gl/GLContextProviderNull.cpp index 72aeb23101e..d6500ce32e5 100644 --- a/gfx/gl/GLContextProviderNull.cpp +++ b/gfx/gl/GLContextProviderNull.cpp @@ -23,15 +23,15 @@ GLContextProviderNull::CreateOffscreen(const gfxIntSize&, } SharedTextureHandle -GLContextProviderNull::CreateSharedHandle(GLContext::SharedTextureShareType shareType, +GLContextProviderNull::CreateSharedHandle(SharedTextureShareType shareType, void* buffer, - GLContext::SharedTextureBufferType bufferType) + SharedTextureBufferType bufferType) { return 0; } already_AddRefed -GLContextProviderNull::GetSharedHandleAsSurface(GLContext::SharedTextureShareType shareType, +GLContextProviderNull::GetSharedHandleAsSurface(SharedTextureShareType shareType, SharedTextureHandle sharedHandle) { return nullptr; diff --git a/gfx/gl/GLContextProviderWGL.cpp b/gfx/gl/GLContextProviderWGL.cpp index afd1cc2cbf9..cfbdcd01f0f 100644 --- a/gfx/gl/GLContextProviderWGL.cpp +++ b/gfx/gl/GLContextProviderWGL.cpp @@ -30,9 +30,9 @@ typedef WGLLibrary::LibraryType LibType; WGLLibrary sWGLLib[WGLLibrary::LIBS_MAX]; LibType -WGLLibrary::SelectLibrary(const GLContext::ContextFlags& aFlags) +WGLLibrary::SelectLibrary(const ContextFlags& aFlags) { - return (aFlags & GLContext::ContextFlagsMesaLLVMPipe) + return (aFlags & ContextFlagsMesaLLVMPipe) ? WGLLibrary::MESA_LLVMPIPE_LIB : WGLLibrary::OPENGL_LIB; } @@ -234,10 +234,10 @@ WGLLibrary::EnsureInitialized(bool aUseMesaLlvmPipe) mInitialized = true; - GLContext::ContextFlags flag = GLContext::ContextFlagsNone; + ContextFlags flag = ContextFlagsNone; if (aUseMesaLlvmPipe) { mLibType = WGLLibrary::MESA_LLVMPIPE_LIB; - flag = GLContext::ContextFlagsMesaLLVMPipe; + flag = ContextFlagsMesaLLVMPipe; } // Call this to create the global GLContext instance, @@ -439,7 +439,7 @@ GLContextWGL::ResizeOffscreen(const gfxIntSize& aNewSize) } static GLContextWGL * -GetGlobalContextWGL(const GLContext::ContextFlags aFlags = GLContext::ContextFlagsNone) +GetGlobalContextWGL(const ContextFlags aFlags = ContextFlagsNone) { return static_cast(GLContextProviderWGL::GetGlobalContext(aFlags)); } @@ -603,7 +603,7 @@ CreatePBufferOffscreenContext(const gfxIntSize& aSize, } static already_AddRefed -CreateWindowOffscreenContext(GLContext::ContextFlags aFlags) +CreateWindowOffscreenContext(ContextFlags aFlags) { // CreateWindowOffscreenContext must return a global-shared context GLContextWGL *shareContext = GetGlobalContextWGL(aFlags); @@ -693,15 +693,15 @@ GLContextProviderWGL::CreateOffscreen(const gfxIntSize& size, } SharedTextureHandle -GLContextProviderWGL::CreateSharedHandle(GLContext::SharedTextureShareType shareType, +GLContextProviderWGL::CreateSharedHandle(SharedTextureShareType shareType, void* buffer, - GLContext::SharedTextureBufferType bufferType) + SharedTextureBufferType bufferType) { return 0; } already_AddRefed -GLContextProviderWGL::GetSharedHandleAsSurface(GLContext::SharedTextureShareType shareType, +GLContextProviderWGL::GetSharedHandleAsSurface(SharedTextureShareType shareType, SharedTextureHandle sharedHandle) { return nullptr; diff --git a/gfx/gl/GLContextTypes.h b/gfx/gl/GLContextTypes.h index 0ed60a01039..00e34c51c61 100644 --- a/gfx/gl/GLContextTypes.h +++ b/gfx/gl/GLContextTypes.h @@ -6,15 +6,44 @@ #ifndef GLCONTEXT_TYPES_H_ #define GLCONTEXT_TYPES_H_ -typedef unsigned int GLenum; -typedef unsigned int GLbitfield; -typedef unsigned int GLuint; -typedef int GLint; -typedef int GLsizei; +#include "GLTypes.h" namespace mozilla { namespace gl { +class GLContext; + +typedef uintptr_t SharedTextureHandle; + +enum SharedTextureShareType { + SameProcess = 0, + CrossProcess +}; + +enum SharedTextureBufferType { + TextureID +#ifdef MOZ_WIDGET_ANDROID + , SurfaceTexture +#endif +#ifdef XP_MACOSX + , IOSurface +#endif +}; + +enum ContextFlags { + ContextFlagsNone = 0x0, + ContextFlagsGlobal = 0x1, + ContextFlagsMesaLLVMPipe = 0x2 +}; + +enum GLContextType { + ContextTypeUnknown, + ContextTypeWGL, + ContextTypeCGL, + ContextTypeGLX, + ContextTypeEGL +}; + struct GLFormats { // Constructs a zeroed object: diff --git a/gfx/gl/GLLibraryEGL.cpp b/gfx/gl/GLLibraryEGL.cpp index a0959c5091c..8691c4b052f 100644 --- a/gfx/gl/GLLibraryEGL.cpp +++ b/gfx/gl/GLLibraryEGL.cpp @@ -319,7 +319,7 @@ GLLibraryEGL::InitExtensions() const bool firstRun = false; #endif - mAvailableExtensions.Load(extensions, sExtensionNames, firstRun && debugMode); + GLContext::InitializeExtensionsBitSet(mAvailableExtensions, extensions, sExtensionNames, firstRun && debugMode); #ifdef DEBUG firstRun = false; @@ -396,6 +396,25 @@ GLLibraryEGL::DumpEGLConfigs() delete [] ec; } +#ifdef DEBUG +/*static*/ void +GLLibraryEGL::BeforeGLCall(const char* glFunction) +{ + if (GLContext::DebugMode()) { + if (GLContext::DebugMode() & GLContext::DebugTrace) + printf_stderr("[egl] > %s\n", glFunction); + } +} + +/*static*/ void +GLLibraryEGL::AfterGLCall(const char* glFunction) +{ + if (GLContext::DebugMode() & GLContext::DebugTrace) { + printf_stderr("[egl] < %s\n", glFunction); + } +} +#endif + } /* namespace gl */ } /* namespace mozilla */ diff --git a/gfx/gl/GLLibraryEGL.h b/gfx/gl/GLLibraryEGL.h index 205dfc2205a..dda99cd8a24 100644 --- a/gfx/gl/GLLibraryEGL.h +++ b/gfx/gl/GLLibraryEGL.h @@ -9,11 +9,11 @@ #include "mozilla/X11Util.h" #endif -#include "GLContext.h" #include "GLLibraryLoader.h" #include "nsIFile.h" +#include #if defined(XP_WIN) @@ -60,10 +60,21 @@ typedef void *EGLNativeWindowType; namespace mozilla { namespace gl { -#ifdef DEBUG #undef BEFORE_GL_CALL #undef AFTER_GL_CALL +#ifdef DEBUG + +#ifndef MOZ_FUNCTION_NAME +# ifdef __GNUC__ +# define MOZ_FUNCTION_NAME __PRETTY_FUNCTION__ +# elif defined(_MSC_VER) +# define MOZ_FUNCTION_NAME __FUNCTION__ +# else +# define MOZ_FUNCTION_NAME __func__ // defined in C99, supported in various C++ compilers. Just raw function name. +# endif +#endif + #define BEFORE_GL_CALL do { \ BeforeGLCall(MOZ_FUNCTION_NAME); \ } while (0) @@ -73,23 +84,11 @@ namespace gl { } while (0) // We rely on the fact that GLLibraryEGL.h #defines BEFORE_GL_CALL and // AFTER_GL_CALL to nothing if !defined(DEBUG). +#else +#define BEFORE_GL_CALL +#define AFTER_GL_CALL #endif -static inline void BeforeGLCall(const char* glFunction) -{ - if (GLContext::DebugMode()) { - if (GLContext::DebugMode() & GLContext::DebugTrace) - printf_stderr("[egl] > %s\n", glFunction); - } -} - -static inline void AfterGLCall(const char* glFunction) -{ - if (GLContext::DebugMode() & GLContext::DebugTrace) { - printf_stderr("[egl] < %s\n", glFunction); - } -} - class GLLibraryEGL { public: @@ -126,11 +125,11 @@ public: } void MarkExtensionUnsupported(EGLExtensions aKnownExtension) { - mAvailableExtensions[aKnownExtension] = 0; + mAvailableExtensions[aKnownExtension] = false; } protected: - GLContext::ExtensionBitset mAvailableExtensions; + std::bitset mAvailableExtensions; public: @@ -518,6 +517,11 @@ public: pfnGetSyncAttrib fGetSyncAttrib; } mSymbols; +#ifdef DEBUG + static void BeforeGLCall(const char* glFunction); + static void AfterGLCall(const char* glFunction); +#endif + private: bool mInitialized; PRLibrary* mEGLLibrary; diff --git a/gfx/gl/GLTypes.h b/gfx/gl/GLTypes.h index 8044370ea4d..d4f0dc5ce98 100644 --- a/gfx/gl/GLTypes.h +++ b/gfx/gl/GLTypes.h @@ -5,19 +5,20 @@ #if !defined(GLTYPES_H_) #define GLTYPES_H_ +#include +#include + +typedef int8_t realGLboolean; + #if !defined(__gltypes_h_) && !defined(__gl_h_) #define __gltypes_h_ #define __gl_h_ -#include -#include - typedef uint32_t GLenum; typedef uint32_t GLbitfield; typedef uint32_t GLuint; typedef int32_t GLint; typedef int32_t GLsizei; -typedef int8_t realGLboolean; typedef int8_t GLbyte; typedef int16_t GLshort; typedef uint8_t GLubyte; diff --git a/gfx/gl/GLXLibrary.h b/gfx/gl/GLXLibrary.h index a2da2a66f67..df782d2cf3d 100644 --- a/gfx/gl/GLXLibrary.h +++ b/gfx/gl/GLXLibrary.h @@ -6,10 +6,12 @@ #ifndef GFX_GLXLIBRARY_H #define GFX_GLXLIBRARY_H -#include "GLContext.h" +#include "GLContextTypes.h" typedef realGLboolean GLboolean; #include +struct PRLibrary; + namespace mozilla { namespace gl { @@ -99,7 +101,7 @@ public: bool SupportsTextureFromPixmap(gfxASurface* aSurface); bool IsATI() { return mIsATI; } bool GLXVersionCheck(int aMajor, int aMinor); - static LibraryType SelectLibrary(const GLContext::ContextFlags& aFlags); + static LibraryType SelectLibrary(const ContextFlags& aFlags); private: diff --git a/gfx/gl/SharedSurfaceEGL.h b/gfx/gl/SharedSurfaceEGL.h index 874bce73179..c2de55d96d7 100644 --- a/gfx/gl/SharedSurfaceEGL.h +++ b/gfx/gl/SharedSurfaceEGL.h @@ -17,6 +17,7 @@ namespace mozilla { namespace gl { class GLContext; +class TextureGarbageBin; class SharedSurface_EGLImage : public SharedSurface_GL diff --git a/gfx/gl/SurfaceStream.h b/gfx/gl/SurfaceStream.h index 57ea8f82c05..b39af35d9b6 100644 --- a/gfx/gl/SurfaceStream.h +++ b/gfx/gl/SurfaceStream.h @@ -12,9 +12,13 @@ #include "mozilla/Attributes.h" #include "gfxPoint.h" #include "SurfaceTypes.h" -#include "GLContext.h" namespace mozilla { + +namespace gl { +class GLContext; +} + namespace gfx { class SharedSurface; class SurfaceFactory; diff --git a/gfx/gl/VBOArena.cpp b/gfx/gl/VBOArena.cpp index 6511bed00f0..77f6fa5ca12 100644 --- a/gfx/gl/VBOArena.cpp +++ b/gfx/gl/VBOArena.cpp @@ -4,6 +4,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "VBOArena.h" +#include "GLContext.h" using namespace mozilla::gl; diff --git a/gfx/gl/VBOArena.h b/gfx/gl/VBOArena.h index 5b52945eb6c..2ae13f92c1f 100644 --- a/gfx/gl/VBOArena.h +++ b/gfx/gl/VBOArena.h @@ -6,12 +6,14 @@ #ifndef VBOARENA_H_ #define VBOARENA_H_ -#include "GLContext.h" +#include "GLTypes.h" #include namespace mozilla { namespace gl { +class GLContext; + class VBOArena { public: // Allocate a new VBO. diff --git a/gfx/gl/WGLLibrary.h b/gfx/gl/WGLLibrary.h index d16e453a5c7..610a55065a7 100644 --- a/gfx/gl/WGLLibrary.h +++ b/gfx/gl/WGLLibrary.h @@ -3,7 +3,8 @@ * 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 "GLContext.h" +#include "GLContextTypes.h" +struct PRLibrary; namespace mozilla { namespace gl { @@ -79,7 +80,7 @@ public: int GetWindowPixelFormat() const { return mWindowPixelFormat; } bool UseDoubleBufferedWindows() const { return mUseDoubleBufferedWindows; } LibraryType GetLibraryType() const { return mLibType; } - static LibraryType SelectLibrary(const GLContext::ContextFlags& aFlags); + static LibraryType SelectLibrary(const ContextFlags& aFlags); private: bool mInitialized; diff --git a/gfx/gl/moz.build b/gfx/gl/moz.build index 360d3eaa2d2..2b85ac5d4a0 100644 --- a/gfx/gl/moz.build +++ b/gfx/gl/moz.build @@ -61,7 +61,6 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows': ] CPP_SOURCES += [ 'GLContextProviderEGL.cpp', - 'GLLibraryEGL.cpp', 'SharedSurfaceANGLE.cpp', ] if CONFIG['MOZ_ENABLE_SKIA_GPU']: @@ -89,11 +88,6 @@ else: 'GLContextProvider%s.cpp' % gl_provider, ] -if gl_provider == 'EGL': - CPP_SOURCES += [ - 'GLLibraryEGL.cpp', - ] - CPP_SOURCES += [ 'GLContext.cpp', 'GLContextFeatures.cpp', @@ -103,6 +97,7 @@ CPP_SOURCES += [ 'GLScreenBuffer.cpp', 'GLTextureImage.cpp', 'SharedSurface.cpp', + 'GLLibraryEGL.cpp', 'SharedSurfaceEGL.cpp', 'SharedSurfaceGL.cpp', 'SurfaceFactory.cpp', diff --git a/gfx/layers/SharedTextureImage.h b/gfx/layers/SharedTextureImage.h index 6fbd8763411..c6f64a0c955 100644 --- a/gfx/layers/SharedTextureImage.h +++ b/gfx/layers/SharedTextureImage.h @@ -27,7 +27,7 @@ class SharedTextureImage : public Image { public: struct Data { gl::SharedTextureHandle mHandle; - gl::GLContext::SharedTextureShareType mShareType; + gl::SharedTextureShareType mShareType; gfxIntSize mSize; bool mInverted; }; diff --git a/gfx/layers/client/TextureClient.h b/gfx/layers/client/TextureClient.h index 1fe5d54e21e..f0b6fe8dbb3 100644 --- a/gfx/layers/client/TextureClient.h +++ b/gfx/layers/client/TextureClient.h @@ -8,7 +8,7 @@ #include // for size_t #include // for uint32_t, uint8_t, uint64_t -#include "GLContext.h" // for GLContext (ptr only), etc +#include "GLContextTypes.h" // for GLContext (ptr only), etc #include "GLTextureImage.h" // for TextureImage #include "ImageContainer.h" // for PlanarYCbCrImage, etc #include "ImageTypes.h" // for StereoMode diff --git a/gfx/layers/d3d10/CanvasLayerD3D10.cpp b/gfx/layers/d3d10/CanvasLayerD3D10.cpp index 767aebfe9f8..e868d1dbbe9 100644 --- a/gfx/layers/d3d10/CanvasLayerD3D10.cpp +++ b/gfx/layers/d3d10/CanvasLayerD3D10.cpp @@ -12,6 +12,7 @@ #include "SurfaceStream.h" #include "SharedSurfaceANGLE.h" #include "gfxContext.h" +#include "GLContext.h" using namespace mozilla::gl; using namespace mozilla::gfx; @@ -19,6 +20,17 @@ using namespace mozilla::gfx; namespace mozilla { namespace layers { +CanvasLayerD3D10::CanvasLayerD3D10(LayerManagerD3D10 *aManager) + : CanvasLayer(aManager, nullptr) + , LayerD3D10(aManager) + , mDataIsPremultiplied(false) + , mNeedsYFlip(false) + , mHasAlpha(true) +{ + mImplData = static_cast(this); + mForceReadback = Preferences::GetBool("webgl.force-layers-readback", false); +} + CanvasLayerD3D10::~CanvasLayerD3D10() { } diff --git a/gfx/layers/d3d10/CanvasLayerD3D10.h b/gfx/layers/d3d10/CanvasLayerD3D10.h index 22a6a038287..977f1ea0a8a 100644 --- a/gfx/layers/d3d10/CanvasLayerD3D10.h +++ b/gfx/layers/d3d10/CanvasLayerD3D10.h @@ -7,29 +7,23 @@ #define GFX_CANVASLAYERD3D10_H #include "LayerManagerD3D10.h" -#include "GLContext.h" #include "gfxASurface.h" #include "mozilla/Preferences.h" namespace mozilla { + +namespace gl { +class GLContext; +} + namespace layers { class CanvasLayerD3D10 : public CanvasLayer, public LayerD3D10 { public: - CanvasLayerD3D10(LayerManagerD3D10 *aManager) - : CanvasLayer(aManager, nullptr) - , LayerD3D10(aManager) - , mDataIsPremultiplied(false) - , mNeedsYFlip(false) - , mHasAlpha(true) - { - mImplData = static_cast(this); - mForceReadback = Preferences::GetBool("webgl.force-layers-readback", false); - } - + CanvasLayerD3D10(LayerManagerD3D10 *aManager); ~CanvasLayerD3D10(); // CanvasLayer implementation diff --git a/gfx/layers/ipc/LayersSurfaces.ipdlh b/gfx/layers/ipc/LayersSurfaces.ipdlh index 91c9f2d51c1..ec1cf5e7c9b 100644 --- a/gfx/layers/ipc/LayersSurfaces.ipdlh +++ b/gfx/layers/ipc/LayersSurfaces.ipdlh @@ -6,6 +6,7 @@ include protocol PGrallocBuffer; include "gfxipc/ShadowLayerUtils.h"; include "mozilla/gfx/Types.h"; +include "nsRegion.h"; using gfx3DMatrix; using gfxIntSize; @@ -23,7 +24,7 @@ using mozilla::layers::SurfaceDescriptorX11; using mozilla::null_t; using mozilla::WindowsHandle; using mozilla::gl::SharedTextureHandle; -using mozilla::gl::GLContext::SharedTextureShareType; +using mozilla::gl::SharedTextureShareType; using mozilla::gfx::SurfaceStreamHandle; using mozilla::gfx::SurfaceFormat; using mozilla::gfx::IntSize; diff --git a/gfx/layers/ipc/ShadowLayerUtils.h b/gfx/layers/ipc/ShadowLayerUtils.h index d60c1967345..5e6d6ed9b7d 100644 --- a/gfx/layers/ipc/ShadowLayerUtils.h +++ b/gfx/layers/ipc/ShadowLayerUtils.h @@ -9,7 +9,8 @@ #define IPC_ShadowLayerUtils_h #include "ipc/IPCMessageUtils.h" -#include "GLContext.h" +#include "GLContextTypes.h" +#include "SurfaceTypes.h" #include "mozilla/WidgetUtils.h" #if defined(MOZ_ENABLE_D3D10_LAYER) @@ -52,9 +53,9 @@ struct ParamTraits { #endif // !defined(MOZ_HAVE_XSURFACEDESCRIPTORX11) template<> -struct ParamTraits +struct ParamTraits { - typedef mozilla::gl::GLContext::SharedTextureShareType paramType; + typedef mozilla::gl::SharedTextureShareType paramType; static void Write(Message* msg, const paramType& param) { diff --git a/gfx/layers/ipc/ShadowLayerUtilsGralloc.cpp b/gfx/layers/ipc/ShadowLayerUtilsGralloc.cpp index 6749fb5f339..b8e10eb9e2b 100644 --- a/gfx/layers/ipc/ShadowLayerUtilsGralloc.cpp +++ b/gfx/layers/ipc/ShadowLayerUtilsGralloc.cpp @@ -22,6 +22,7 @@ #include "gfxImageSurface.h" #include "gfxPlatform.h" +#include "GLContext.h" #include "GeckoProfiler.h" diff --git a/gfx/layers/moz.build b/gfx/layers/moz.build index 1c49fb3efae..736312504fd 100644 --- a/gfx/layers/moz.build +++ b/gfx/layers/moz.build @@ -209,6 +209,7 @@ CPP_SOURCES += [ 'CompositableClient.cpp', 'CompositableHost.cpp', 'CompositableTransactionParent.cpp', + 'CompositingRenderTargetOGL.cpp', 'Compositor.cpp', 'CompositorChild.cpp', 'CompositorCocoaWidgetHelper.cpp', diff --git a/gfx/layers/opengl/CanvasLayerOGL.cpp b/gfx/layers/opengl/CanvasLayerOGL.cpp index 488a597239a..7ca26916259 100644 --- a/gfx/layers/opengl/CanvasLayerOGL.cpp +++ b/gfx/layers/opengl/CanvasLayerOGL.cpp @@ -4,6 +4,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "CanvasLayerOGL.h" +#include "GLContext.h" // for GLContext #include "GLScreenBuffer.h" // for GLScreenBuffer #include "SharedSurface.h" // for SharedSurface #include "SharedSurfaceGL.h" // for SharedSurface_Basic, etc diff --git a/gfx/layers/opengl/CanvasLayerOGL.h b/gfx/layers/opengl/CanvasLayerOGL.h index b40d4480b3a..3362d65bdbe 100644 --- a/gfx/layers/opengl/CanvasLayerOGL.h +++ b/gfx/layers/opengl/CanvasLayerOGL.h @@ -6,9 +6,8 @@ #ifndef GFX_CANVASLAYEROGL_H #define GFX_CANVASLAYEROGL_H -#include "GLContext.h" // for GLContext -#include "GLContextTypes.h" // for GLuint, GLenum -#include "GLDefs.h" // for LOCAL_GL_TEXTURE_2D +#include "GLContextTypes.h" // for GLContext +#include "GLDefs.h" // for GLuint, LOCAL_GL_TEXTURE_2D #include "LayerManagerOGL.h" // for LayerOGL::GLContext, etc #include "Layers.h" // for CanvasLayer, etc #include "gfxASurface.h" // for gfxASurface, etc diff --git a/gfx/layers/opengl/CompositingRenderTargetOGL.cpp b/gfx/layers/opengl/CompositingRenderTargetOGL.cpp new file mode 100644 index 00000000000..44e4ea04c4d --- /dev/null +++ b/gfx/layers/opengl/CompositingRenderTargetOGL.cpp @@ -0,0 +1,87 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * 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 "CompositingRenderTargetOGL.h" +#include "GLContext.h" + +using namespace mozilla; +using namespace mozilla::layers; + +CompositingRenderTargetOGL::~CompositingRenderTargetOGL() +{ + mGL->fDeleteTextures(1, &mTextureHandle); + mGL->fDeleteFramebuffers(1, &mFBO); +} + +void +CompositingRenderTargetOGL::BindTexture(GLenum aTextureUnit, GLenum aTextureTarget) +{ + MOZ_ASSERT(mInitParams.mStatus == InitParams::INITIALIZED); + MOZ_ASSERT(mTextureHandle != 0); + mGL->fActiveTexture(aTextureUnit); + mGL->fBindTexture(aTextureTarget, mTextureHandle); +} + +void +CompositingRenderTargetOGL::BindRenderTarget() +{ + if (mInitParams.mStatus != InitParams::INITIALIZED) { + InitializeImpl(); + } else { + MOZ_ASSERT(mInitParams.mStatus == InitParams::INITIALIZED); + mGL->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mFBO); + GLenum result = mGL->fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER); + if (result != LOCAL_GL_FRAMEBUFFER_COMPLETE) { + nsAutoCString msg; + msg.AppendPrintf("Framebuffer not complete -- error 0x%x, aFBOTextureTarget 0x%x, aRect.width %d, aRect.height %d", + result, mInitParams.mFBOTextureTarget, mInitParams.mSize.width, mInitParams.mSize.height); + NS_WARNING(msg.get()); + } + + mCompositor->PrepareViewport(mInitParams.mSize, mTransform); + } +} + +#ifdef MOZ_DUMP_PAINTING +already_AddRefed +CompositingRenderTargetOGL::Dump(Compositor* aCompositor) +{ + MOZ_ASSERT(mInitParams.mStatus == InitParams::INITIALIZED); + CompositorOGL* compositorOGL = static_cast(aCompositor); + return mGL->GetTexImage(mTextureHandle, true, compositorOGL->GetFBOFormat()); +} +#endif + +void +CompositingRenderTargetOGL::InitializeImpl() +{ + MOZ_ASSERT(mInitParams.mStatus == InitParams::READY); + + mGL->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mFBO); + mGL->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, + LOCAL_GL_COLOR_ATTACHMENT0, + mInitParams.mFBOTextureTarget, + mTextureHandle, + 0); + + // Making this call to fCheckFramebufferStatus prevents a crash on + // PowerVR. See bug 695246. + GLenum result = mGL->fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER); + if (result != LOCAL_GL_FRAMEBUFFER_COMPLETE) { + nsAutoCString msg; + msg.AppendPrintf("Framebuffer not complete -- error 0x%x, aFBOTextureTarget 0x%x, mFBO %d, mTextureHandle %d, aRect.width %d, aRect.height %d", + result, mInitParams.mFBOTextureTarget, mFBO, mTextureHandle, mInitParams.mSize.width, mInitParams.mSize.height); + NS_ERROR(msg.get()); + } + + mCompositor->PrepareViewport(mInitParams.mSize, mTransform); + mGL->fScissor(0, 0, mInitParams.mSize.width, mInitParams.mSize.height); + if (mInitParams.mInit == INIT_MODE_CLEAR) { + mGL->fClearColor(0.0, 0.0, 0.0, 0.0); + mGL->fClear(LOCAL_GL_COLOR_BUFFER_BIT); + } + + mInitParams.mStatus = InitParams::INITIALIZED; +} diff --git a/gfx/layers/opengl/CompositingRenderTargetOGL.h b/gfx/layers/opengl/CompositingRenderTargetOGL.h index ce557b3e9d0..d7fb488a247 100644 --- a/gfx/layers/opengl/CompositingRenderTargetOGL.h +++ b/gfx/layers/opengl/CompositingRenderTargetOGL.h @@ -7,9 +7,8 @@ #define MOZILLA_GFX_COMPOSITINGRENDERTARGETOGL_H #include "mozilla-config.h" // for MOZ_DUMP_PAINTING -#include "GLContext.h" // for GLContext -#include "GLContextTypes.h" // for GLenum, GLuint -#include "GLDefs.h" // for LOCAL_GL_FRAMEBUFFER, etc +#include "GLContextTypes.h" // for GLContext +#include "GLDefs.h" // for GLenum, LOCAL_GL_FRAMEBUFFER, etc #include "gfxMatrix.h" // for gfxMatrix #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc #include "mozilla/Attributes.h" // for MOZ_OVERRIDE @@ -73,11 +72,7 @@ public: , mFBO(aFBO) {} - ~CompositingRenderTargetOGL() - { - mGL->fDeleteTextures(1, &mTextureHandle); - mGL->fDeleteFramebuffers(1, &mFBO); - } + ~CompositingRenderTargetOGL(); /** * Create a render target around the default FBO, for rendering straight to @@ -111,35 +106,12 @@ public: mInitParams = InitParams(aSize, aFBOTextureTarget, aInit); } - void BindTexture(GLenum aTextureUnit, GLenum aTextureTarget) - { - MOZ_ASSERT(mInitParams.mStatus == InitParams::INITIALIZED); - MOZ_ASSERT(mTextureHandle != 0); - mGL->fActiveTexture(aTextureUnit); - mGL->fBindTexture(aTextureTarget, mTextureHandle); - } + void BindTexture(GLenum aTextureUnit, GLenum aTextureTarget); /** * Call when we want to draw into our FBO */ - void BindRenderTarget() - { - if (mInitParams.mStatus != InitParams::INITIALIZED) { - InitializeImpl(); - } else { - MOZ_ASSERT(mInitParams.mStatus == InitParams::INITIALIZED); - mGL->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mFBO); - GLenum result = mGL->fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER); - if (result != LOCAL_GL_FRAMEBUFFER_COMPLETE) { - nsAutoCString msg; - msg.AppendPrintf("Framebuffer not complete -- error 0x%x, aFBOTextureTarget 0x%x, aRect.width %d, aRect.height %d", - result, mInitParams.mFBOTextureTarget, mInitParams.mSize.width, mInitParams.mSize.height); - NS_WARNING(msg.get()); - } - - mCompositor->PrepareViewport(mInitParams.mSize, mTransform); - } - } + void BindRenderTarget(); GLuint GetFBO() const { @@ -179,12 +151,7 @@ public: } #ifdef MOZ_DUMP_PAINTING - virtual already_AddRefed Dump(Compositor* aCompositor) - { - MOZ_ASSERT(mInitParams.mStatus == InitParams::INITIALIZED); - CompositorOGL* compositorOGL = static_cast(aCompositor); - return mGL->GetTexImage(mTextureHandle, true, compositorOGL->GetFBOFormat()); - } + virtual already_AddRefed Dump(Compositor* aCompositor); #endif private: @@ -192,36 +159,7 @@ private: * Actually do the initialisation. Note that we leave our FBO bound, and so * calling this method is only suitable when about to use this render target. */ - void InitializeImpl() - { - MOZ_ASSERT(mInitParams.mStatus == InitParams::READY); - - mGL->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mFBO); - mGL->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, - LOCAL_GL_COLOR_ATTACHMENT0, - mInitParams.mFBOTextureTarget, - mTextureHandle, - 0); - - // Making this call to fCheckFramebufferStatus prevents a crash on - // PowerVR. See bug 695246. - GLenum result = mGL->fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER); - if (result != LOCAL_GL_FRAMEBUFFER_COMPLETE) { - nsAutoCString msg; - msg.AppendPrintf("Framebuffer not complete -- error 0x%x, aFBOTextureTarget 0x%x, mFBO %d, mTextureHandle %d, aRect.width %d, aRect.height %d", - result, mInitParams.mFBOTextureTarget, mFBO, mTextureHandle, mInitParams.mSize.width, mInitParams.mSize.height); - NS_ERROR(msg.get()); - } - - mCompositor->PrepareViewport(mInitParams.mSize, mTransform); - mGL->fScissor(0, 0, mInitParams.mSize.width, mInitParams.mSize.height); - if (mInitParams.mInit == INIT_MODE_CLEAR) { - mGL->fClearColor(0.0, 0.0, 0.0, 0.0); - mGL->fClear(LOCAL_GL_COLOR_BUFFER_BIT); - } - - mInitParams.mStatus = InitParams::INITIALIZED; - } + void InitializeImpl(); InitParams mInitParams; gfxMatrix mTransform; diff --git a/gfx/layers/opengl/CompositorOGL.cpp b/gfx/layers/opengl/CompositorOGL.cpp index 835444b2f17..23ea6a016d9 100644 --- a/gfx/layers/opengl/CompositorOGL.cpp +++ b/gfx/layers/opengl/CompositorOGL.cpp @@ -9,6 +9,7 @@ #include // for free, malloc #include "FPSCounter.h" // for FPSState, FPSCounter #include "GLContextProvider.h" // for GLContextProvider +#include "GLContext.h" // for GLContext #include "LayerManagerOGL.h" // for BUFFER_OFFSET #include "Layers.h" // for WriteSnapshotToDumpFile #include "gfx2DGlue.h" // for ThebesFilter @@ -1446,5 +1447,94 @@ CompositorOGL::CreateDataTextureSource(TextureFlags aFlags) return result; } +bool +CompositorOGL::SupportsPartialTextureUpdate() +{ + return mGLContext->CanUploadSubTextures(); +} + +int32_t +CompositorOGL::GetMaxTextureSize() const +{ + MOZ_ASSERT(mGLContext); + GLint texSize = 0; + mGLContext->fGetIntegerv(LOCAL_GL_MAX_TEXTURE_SIZE, + &texSize); + MOZ_ASSERT(texSize != 0); + return texSize; +} + +void +CompositorOGL::MakeCurrent(MakeCurrentFlags aFlags) { + if (mDestroyed) { + NS_WARNING("Call on destroyed layer manager"); + return; + } + mGLContext->MakeCurrent(aFlags & ForceMakeCurrent); +} + +void +CompositorOGL::BindQuadVBO() { + mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mQuadVBO); +} + +void +CompositorOGL::QuadVBOVerticesAttrib(GLuint aAttribIndex) { + mGLContext->fVertexAttribPointer(aAttribIndex, 2, + LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0, + (GLvoid*) QuadVBOVertexOffset()); +} + +void +CompositorOGL::QuadVBOTexCoordsAttrib(GLuint aAttribIndex) { + mGLContext->fVertexAttribPointer(aAttribIndex, 2, + LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0, + (GLvoid*) QuadVBOTexCoordOffset()); +} + +void +CompositorOGL::QuadVBOFlippedTexCoordsAttrib(GLuint aAttribIndex) { + mGLContext->fVertexAttribPointer(aAttribIndex, 2, + LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0, + (GLvoid*) QuadVBOFlippedTexCoordOffset()); +} + +void +CompositorOGL::BindAndDrawQuad(GLuint aVertAttribIndex, + GLuint aTexCoordAttribIndex, + bool aFlipped) +{ + BindQuadVBO(); + QuadVBOVerticesAttrib(aVertAttribIndex); + + if (aTexCoordAttribIndex != GLuint(-1)) { + if (aFlipped) + QuadVBOFlippedTexCoordsAttrib(aTexCoordAttribIndex); + else + QuadVBOTexCoordsAttrib(aTexCoordAttribIndex); + + mGLContext->fEnableVertexAttribArray(aTexCoordAttribIndex); + } + + mGLContext->fEnableVertexAttribArray(aVertAttribIndex); + mGLContext->fDrawArrays(LOCAL_GL_TRIANGLE_STRIP, 0, 4); + mGLContext->fDisableVertexAttribArray(aVertAttribIndex); + + if (aTexCoordAttribIndex != GLuint(-1)) { + mGLContext->fDisableVertexAttribArray(aTexCoordAttribIndex); + } +} + +void +CompositorOGL::BindAndDrawQuad(ShaderProgramOGL *aProg, + bool aFlipped) +{ + NS_ASSERTION(aProg->HasInitialized(), "Shader program not correctly initialized"); + BindAndDrawQuad(aProg->AttribLocation(ShaderProgramOGL::VertexCoordAttrib), + aProg->AttribLocation(ShaderProgramOGL::TexCoordAttrib), + aFlipped); +} + + } /* layers */ } /* mozilla */ diff --git a/gfx/layers/opengl/CompositorOGL.h b/gfx/layers/opengl/CompositorOGL.h index b2fdb8e9c77..5ba718327ec 100644 --- a/gfx/layers/opengl/CompositorOGL.h +++ b/gfx/layers/opengl/CompositorOGL.h @@ -7,9 +7,8 @@ #define MOZILLA_GFX_COMPOSITOROGL_H #include "./../mozilla-config.h" // for MOZ_DUMP_PAINTING -#include "GLContext.h" // for GLContext -#include "GLContextTypes.h" // for GLuint, GLenum, GLint -#include "GLDefs.h" // for GLintptr, GLvoid, etc +#include "GLContextTypes.h" // for GLContext, etc +#include "GLDefs.h" // for GLuint, LOCAL_GL_TEXTURE_2D, etc #include "LayerManagerOGLProgram.h" // for ShaderProgramOGL, etc #include "Units.h" // for ScreenPoint #include "gfxContext.h" // for gfxContext @@ -106,10 +105,7 @@ public: virtual void EndFrameForExternalComposition(const gfxMatrix& aTransform) MOZ_OVERRIDE; virtual void AbortFrame() MOZ_OVERRIDE; - virtual bool SupportsPartialTextureUpdate() MOZ_OVERRIDE - { - return mGLContext->CanUploadSubTextures(); - } + virtual bool SupportsPartialTextureUpdate() MOZ_OVERRIDE; virtual bool CanUseCanvasLayerForSize(const gfxIntSize &aSize) MOZ_OVERRIDE { @@ -119,15 +115,7 @@ public: return aSize <= gfxIntSize(maxSize, maxSize); } - virtual int32_t GetMaxTextureSize() const MOZ_OVERRIDE - { - MOZ_ASSERT(mGLContext); - GLint texSize = 0; - mGLContext->fGetIntegerv(LOCAL_GL_MAX_TEXTURE_SIZE, - &texSize); - MOZ_ASSERT(texSize != 0); - return texSize; - } + virtual int32_t GetMaxTextureSize() const MOZ_OVERRIDE; /** * Set the size of the EGL surface we're rendering to, if we're rendering to @@ -139,13 +127,7 @@ public: mRenderOffset = aOffset; } - virtual void MakeCurrent(MakeCurrentFlags aFlags = 0) MOZ_OVERRIDE { - if (mDestroyed) { - NS_WARNING("Call on destroyed layer manager"); - return; - } - mGLContext->MakeCurrent(aFlags & ForceMakeCurrent); - } + virtual void MakeCurrent(MakeCurrentFlags aFlags = 0) MOZ_OVERRIDE; virtual void SetTargetContext(gfxContext* aTarget) MOZ_OVERRIDE { @@ -300,62 +282,15 @@ private: GLintptr QuadVBOTexCoordOffset() { return sizeof(float)*4*2; } GLintptr QuadVBOFlippedTexCoordOffset() { return sizeof(float)*8*2; } - void BindQuadVBO() { - mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mQuadVBO); - } - - void QuadVBOVerticesAttrib(GLuint aAttribIndex) { - mGLContext->fVertexAttribPointer(aAttribIndex, 2, - LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0, - (GLvoid*) QuadVBOVertexOffset()); - } - - void QuadVBOTexCoordsAttrib(GLuint aAttribIndex) { - mGLContext->fVertexAttribPointer(aAttribIndex, 2, - LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0, - (GLvoid*) QuadVBOTexCoordOffset()); - } - - void QuadVBOFlippedTexCoordsAttrib(GLuint aAttribIndex) { - mGLContext->fVertexAttribPointer(aAttribIndex, 2, - LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0, - (GLvoid*) QuadVBOFlippedTexCoordOffset()); - } - + void BindQuadVBO(); + void QuadVBOVerticesAttrib(GLuint aAttribIndex); + void QuadVBOTexCoordsAttrib(GLuint aAttribIndex); + void QuadVBOFlippedTexCoordsAttrib(GLuint aAttribIndex); void BindAndDrawQuad(GLuint aVertAttribIndex, GLuint aTexCoordAttribIndex, - bool aFlipped = false) - { - BindQuadVBO(); - QuadVBOVerticesAttrib(aVertAttribIndex); - - if (aTexCoordAttribIndex != GLuint(-1)) { - if (aFlipped) - QuadVBOFlippedTexCoordsAttrib(aTexCoordAttribIndex); - else - QuadVBOTexCoordsAttrib(aTexCoordAttribIndex); - - mGLContext->fEnableVertexAttribArray(aTexCoordAttribIndex); - } - - mGLContext->fEnableVertexAttribArray(aVertAttribIndex); - mGLContext->fDrawArrays(LOCAL_GL_TRIANGLE_STRIP, 0, 4); - mGLContext->fDisableVertexAttribArray(aVertAttribIndex); - - if (aTexCoordAttribIndex != GLuint(-1)) { - mGLContext->fDisableVertexAttribArray(aTexCoordAttribIndex); - } - } - + bool aFlipped = false); void BindAndDrawQuad(ShaderProgramOGL *aProg, - bool aFlipped = false) - { - NS_ASSERTION(aProg->HasInitialized(), "Shader program not correctly initialized"); - BindAndDrawQuad(aProg->AttribLocation(ShaderProgramOGL::VertexCoordAttrib), - aProg->AttribLocation(ShaderProgramOGL::TexCoordAttrib), - aFlipped); - } - + bool aFlipped = false); void BindAndDrawQuadWithTextureRect(ShaderProgramOGL *aProg, const gfx::Rect& aTexCoordRect, TextureSource *aTexture); diff --git a/gfx/layers/opengl/ImageLayerOGL.h b/gfx/layers/opengl/ImageLayerOGL.h index 2c9a8890c67..5ac11537357 100644 --- a/gfx/layers/opengl/ImageLayerOGL.h +++ b/gfx/layers/opengl/ImageLayerOGL.h @@ -6,8 +6,7 @@ #ifndef GFX_IMAGELAYEROGL_H #define GFX_IMAGELAYEROGL_H -#include "GLContext.h" // for GLContext -#include "GLContextTypes.h" // for GLuint +#include "GLContextTypes.h" // for GLContext, GLuint #include "ImageContainer.h" // for ImageBackendData, etc #include "ImageLayers.h" // for ImageLayer #include "LayerManagerOGL.h" // for LayerOGL diff --git a/gfx/layers/opengl/TextureClientOGL.cpp b/gfx/layers/opengl/TextureClientOGL.cpp index 2e6b0f9f07b..b8a905d8089 100644 --- a/gfx/layers/opengl/TextureClientOGL.cpp +++ b/gfx/layers/opengl/TextureClientOGL.cpp @@ -45,7 +45,7 @@ SharedTextureClientOGL::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) void SharedTextureClientOGL::InitWith(gl::SharedTextureHandle aHandle, gfx::IntSize aSize, - gl::GLContext::SharedTextureShareType aShareType, + gl::SharedTextureShareType aShareType, bool aInverted) { MOZ_ASSERT(!IsAllocated()); diff --git a/gfx/layers/opengl/TextureClientOGL.h b/gfx/layers/opengl/TextureClientOGL.h index 72666266c3c..5a639ce201b 100644 --- a/gfx/layers/opengl/TextureClientOGL.h +++ b/gfx/layers/opengl/TextureClientOGL.h @@ -6,7 +6,7 @@ #ifndef MOZILLA_GFX_TEXTURECLIENTOGL_H #define MOZILLA_GFX_TEXTURECLIENTOGL_H -#include "GLContext.h" // for SharedTextureHandle, etc +#include "GLContextTypes.h" // for SharedTextureHandle, etc #include "gfxASurface.h" // for gfxASurface, etc #include "mozilla/Attributes.h" // for MOZ_OVERRIDE #include "mozilla/gfx/Point.h" // for IntSize @@ -36,7 +36,7 @@ public: void InitWith(gl::SharedTextureHandle aHandle, gfx::IntSize aSize, - gl::GLContext::SharedTextureShareType aShareType, + gl::SharedTextureShareType aShareType, bool aInverted = false); virtual gfx::IntSize GetSize() const { return mSize; } @@ -44,7 +44,7 @@ public: protected: gl::SharedTextureHandle mHandle; gfx::IntSize mSize; - gl::GLContext::SharedTextureShareType mShareType; + gl::SharedTextureShareType mShareType; bool mInverted; }; diff --git a/gfx/layers/opengl/TextureHostOGL.cpp b/gfx/layers/opengl/TextureHostOGL.cpp index fa5910e4907..110ce5d7851 100644 --- a/gfx/layers/opengl/TextureHostOGL.cpp +++ b/gfx/layers/opengl/TextureHostOGL.cpp @@ -292,7 +292,7 @@ SharedTextureSourceOGL::gl() const SharedTextureHostOGL::SharedTextureHostOGL(uint64_t aID, TextureFlags aFlags, - gl::GLContext::SharedTextureShareType aShareType, + gl::SharedTextureShareType aShareType, gl::SharedTextureHandle aSharedHandle, gfx::IntSize aSize, bool inverted) @@ -741,6 +741,14 @@ SurfaceStreamHostOGL::Lock() return true; } +void +SurfaceStreamHostOGL::BindTexture(GLenum activetex) +{ + MOZ_ASSERT(mGL); + mGL->fActiveTexture(activetex); + mGL->fBindTexture(mTextureTarget, mTextureHandle); +} + void YCbCrDeprecatedTextureHostOGL::SetCompositor(Compositor* aCompositor) @@ -826,6 +834,13 @@ TiledDeprecatedTextureHostOGL::~TiledDeprecatedTextureHostOGL() DeleteTextures(); } +void +TiledDeprecatedTextureHostOGL::BindTexture(GLenum aTextureUnit) +{ + mGL->fActiveTexture(aTextureUnit); + mGL->fBindTexture(LOCAL_GL_TEXTURE_2D, mTextureHandle); +} + static void GetFormatAndTileForImageFormat(gfxASurface::gfxImageFormat aFormat, GLenum& aOutFormat, diff --git a/gfx/layers/opengl/TextureHostOGL.h b/gfx/layers/opengl/TextureHostOGL.h index 735bd954bd1..e84c5521e68 100644 --- a/gfx/layers/opengl/TextureHostOGL.h +++ b/gfx/layers/opengl/TextureHostOGL.h @@ -8,9 +8,8 @@ #include // for size_t #include // for uint64_t -#include "GLContext.h" // for GLContext, etc -#include "GLContextTypes.h" // for GLenum, GLuint -#include "GLDefs.h" // for LOCAL_GL_CLAMP_TO_EDGE, etc +#include "GLContextTypes.h" // for GLContext +#include "GLDefs.h" // for GLenum, LOCAL_GL_CLAMP_TO_EDGE, etc #include "GLTextureImage.h" // for TextureImage #include "gfx3DMatrix.h" // for gfx3DMatrix #include "gfxASurface.h" // for gfxASurface, etc @@ -219,7 +218,7 @@ class SharedTextureSourceOGL : public NewTextureSource , public TextureSourceOGL { public: - typedef gl::GLContext::SharedTextureShareType SharedTextureShareType; + typedef gl::SharedTextureShareType SharedTextureShareType; SharedTextureSourceOGL(CompositorOGL* aCompositor, gl::SharedTextureHandle aHandle, @@ -278,7 +277,7 @@ class SharedTextureHostOGL : public TextureHost public: SharedTextureHostOGL(uint64_t aID, TextureFlags aFlags, - gl::GLContext::SharedTextureShareType aShareType, + gl::SharedTextureShareType aShareType, gl::SharedTextureHandle aSharedhandle, gfx::IntSize aSize, bool inverted); @@ -318,7 +317,7 @@ protected: gfx::IntSize mSize; CompositorOGL* mCompositor; gl::SharedTextureHandle mSharedHandle; - gl::GLContext::SharedTextureShareType mShareType; + gl::SharedTextureShareType mShareType; RefPtr mTextureSource; }; @@ -581,7 +580,7 @@ public: , mTextureHandle(0) , mWrapMode(LOCAL_GL_CLAMP_TO_EDGE) , mSharedHandle(0) - , mShareType(GLContext::SameProcess) + , mShareType(gl::SameProcess) {} virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE; @@ -661,7 +660,7 @@ protected: GLenum mWrapMode; GLenum mTextureTarget; gl::SharedTextureHandle mSharedHandle; - gl::GLContext::SharedTextureShareType mShareType; + gl::SharedTextureShareType mShareType; }; class SurfaceStreamHostOGL : public DeprecatedTextureHost @@ -716,11 +715,7 @@ public: return mTextureTarget; } - void BindTexture(GLenum activetex) MOZ_OVERRIDE { - MOZ_ASSERT(mGL); - mGL->fActiveTexture(activetex); - mGL->fBindTexture(mTextureTarget, mTextureHandle); - } + void BindTexture(GLenum activetex) MOZ_OVERRIDE; void UnbindTexture() MOZ_OVERRIDE {} @@ -784,11 +779,7 @@ public: virtual TextureSourceOGL* AsSourceOGL() MOZ_OVERRIDE { return this; } virtual bool IsValid() const MOZ_OVERRIDE { return true; } virtual GLenum GetWrapMode() const MOZ_OVERRIDE { return LOCAL_GL_CLAMP_TO_EDGE; } - virtual void BindTexture(GLenum aTextureUnit) MOZ_OVERRIDE - { - mGL->fActiveTexture(aTextureUnit); - mGL->fBindTexture(LOCAL_GL_TEXTURE_2D, mTextureHandle); - } + virtual void BindTexture(GLenum aTextureUnit); virtual void UnbindTexture() MOZ_OVERRIDE {} virtual gfx::IntSize GetSize() const MOZ_OVERRIDE { diff --git a/gfx/layers/opengl/TexturePoolOGL.h b/gfx/layers/opengl/TexturePoolOGL.h index 9b36ebe617a..33270a60e1d 100644 --- a/gfx/layers/opengl/TexturePoolOGL.h +++ b/gfx/layers/opengl/TexturePoolOGL.h @@ -5,13 +5,11 @@ #ifndef GFX_TEXTUREPOOLOGL_H #define GFX_TEXTUREPOOLOGL_H -#include "GLContextTypes.h" // for GLuint +#include "GLContextTypes.h" // for GLContext, GLuint namespace mozilla { namespace gl { -class GLContext; - // A texture pool for for the on-screen GLContext. The main purpose of this class // is to provide the ability to easily allocate an on-screen texture from the // content thread. The unfortunate nature of the SurfaceTexture API (see nsSurfaceTexture) diff --git a/widget/cocoa/nsChildView.h b/widget/cocoa/nsChildView.h index ee7d56140c1..92f5f71a412 100644 --- a/widget/cocoa/nsChildView.h +++ b/widget/cocoa/nsChildView.h @@ -22,7 +22,9 @@ #include "TextInputHandler.h" #include "nsCocoaUtils.h" #include "gfxQuartzSurface.h" -#include "GLContext.h" +#include "GLContextTypes.h" +#include "mozilla/Mutex.h" +#include "nsRegion.h" #include "nsString.h" #include "nsIDragService.h" diff --git a/widget/cocoa/nsChildView.mm b/widget/cocoa/nsChildView.mm index 2f79da6e81e..a72afd47295 100644 --- a/widget/cocoa/nsChildView.mm +++ b/widget/cocoa/nsChildView.mm @@ -56,6 +56,7 @@ #include "mozilla/layers/LayerManagerComposite.h" #include "GLTextureImage.h" #include "GLContextProvider.h" +#include "GLContext.h" #include "mozilla/layers/GLManager.h" #include "mozilla/layers/CompositorCocoaWidgetHelper.h" #include "mozilla/layers/CompositorOGL.h" diff --git a/widget/gonk/nsWindow.cpp b/widget/gonk/nsWindow.cpp index 2fa23d58388..5c967544d18 100644 --- a/widget/gonk/nsWindow.cpp +++ b/widget/gonk/nsWindow.cpp @@ -29,6 +29,7 @@ #include "gfxPlatform.h" #include "gfxUtils.h" #include "GLContextProvider.h" +#include "GLContext.h" #include "LayerManagerOGL.h" #include "nsAutoPtr.h" #include "nsAppShell.h" diff --git a/widget/gtk2/nsWindow.cpp b/widget/gtk2/nsWindow.cpp index d944c5f0070..4d6da69c983 100644 --- a/widget/gtk2/nsWindow.cpp +++ b/widget/gtk2/nsWindow.cpp @@ -67,6 +67,7 @@ #include "mozilla/layers/LayersTypes.h" #include "nsIIdleServiceInternal.h" #include "nsIPropertyBag2.h" +#include "GLContext.h" #ifdef ACCESSIBILITY #include "mozilla/a11y/Accessible.h" From 662162b9a653943c9a78f1ddd099216077d7bac3 Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Wed, 4 Sep 2013 08:14:54 -0400 Subject: [PATCH 075/171] Bug 839452 - Add helpful logging of DOM calls resulting in reboot/poweroff - r=sicking --- dom/power/PowerManagerService.cpp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/dom/power/PowerManagerService.cpp b/dom/power/PowerManagerService.cpp index 30e93c604da..84eb5125512 100644 --- a/dom/power/PowerManagerService.cpp +++ b/dom/power/PowerManagerService.cpp @@ -22,6 +22,23 @@ #include #endif +#ifdef ANDROID +#include +extern "C" char* PrintJSStack(); +static void LogFunctionAndJSStack(const char* funcname) { + char *jsstack = PrintJSStack(); + __android_log_print(ANDROID_LOG_INFO, "PowerManagerService", \ + "Call to %s. The JS stack is:\n%s\n", + funcname, + jsstack ? jsstack : ""); +} +// bug 839452 +#define LOG_FUNCTION_AND_JS_STACK() \ + LogFunctionAndJSStack(__PRETTY_FUNCTION__); +#else +#define LOG_FUNCTION_AND_JS_STACK() +#endif + namespace mozilla { namespace dom { namespace power { @@ -115,6 +132,8 @@ PowerManagerService::SyncProfile() NS_IMETHODIMP PowerManagerService::Reboot() { + LOG_FUNCTION_AND_JS_STACK() // bug 839452 + StartForceQuitWatchdog(eHalShutdownMode_Reboot, mWatchdogTimeoutSecs); // To synchronize any unsaved user data before rebooting. SyncProfile(); @@ -125,6 +144,8 @@ PowerManagerService::Reboot() NS_IMETHODIMP PowerManagerService::PowerOff() { + LOG_FUNCTION_AND_JS_STACK() // bug 839452 + StartForceQuitWatchdog(eHalShutdownMode_PowerOff, mWatchdogTimeoutSecs); // To synchronize any unsaved user data before powering off. SyncProfile(); @@ -135,6 +156,8 @@ PowerManagerService::PowerOff() NS_IMETHODIMP PowerManagerService::Restart() { + LOG_FUNCTION_AND_JS_STACK() // bug 839452 + // FIXME/bug 796826 this implementation is currently gonk-specific, // because it relies on the Gonk to initialize the Gecko processes to // restart B2G. It's better to do it here to have a real "restart". From d5baca5fc233f7aaf2d4f4ee1a99160b0d1e9128 Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Wed, 4 Sep 2013 11:29:36 -0400 Subject: [PATCH 076/171] Bug 912255 - traverse/unlink mDefaultVertexArray - r=smaug --- content/canvas/src/WebGLContext.cpp | 3 +- dom/base/nsWrapperCache.h | 49 +++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/content/canvas/src/WebGLContext.cpp b/content/canvas/src/WebGLContext.cpp index 712965cdace..d27463547ba 100644 --- a/content/canvas/src/WebGLContext.cpp +++ b/content/canvas/src/WebGLContext.cpp @@ -1322,7 +1322,7 @@ WebGLContext::MakeContextCurrent() const { gl->MakeCurrent(); } NS_IMPL_CYCLE_COLLECTING_ADDREF(WebGLContext) NS_IMPL_CYCLE_COLLECTING_RELEASE(WebGLContext) -NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_12(WebGLContext, +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_13(WebGLContext, mCanvasElement, mExtensions, mBound2DTextures, @@ -1333,6 +1333,7 @@ NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_12(WebGLContext, mBoundFramebuffer, mBoundRenderbuffer, mBoundVertexArray, + mDefaultVertexArray, mActiveOcclusionQuery, mActiveTransformFeedbackQuery) diff --git a/dom/base/nsWrapperCache.h b/dom/base/nsWrapperCache.h index 4af57d3d9e5..64bec5c5700 100644 --- a/dom/base/nsWrapperCache.h +++ b/dom/base/nsWrapperCache.h @@ -702,4 +702,53 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsWrapperCache, NS_WRAPPERCACHE_IID) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END \ NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(_class) +#define NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_13(_class, \ + _field1, \ + _field2, \ + _field3, \ + _field4, \ + _field5, \ + _field6, \ + _field7, \ + _field8, \ + _field9, \ + _field10, \ + _field11, \ + _field12, \ + _field13) \ + NS_IMPL_CYCLE_COLLECTION_CLASS(_class) \ + NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_class) \ + NS_IMPL_CYCLE_COLLECTION_UNLINK(_field1) \ + NS_IMPL_CYCLE_COLLECTION_UNLINK(_field2) \ + NS_IMPL_CYCLE_COLLECTION_UNLINK(_field3) \ + NS_IMPL_CYCLE_COLLECTION_UNLINK(_field4) \ + NS_IMPL_CYCLE_COLLECTION_UNLINK(_field5) \ + NS_IMPL_CYCLE_COLLECTION_UNLINK(_field6) \ + NS_IMPL_CYCLE_COLLECTION_UNLINK(_field7) \ + NS_IMPL_CYCLE_COLLECTION_UNLINK(_field8) \ + NS_IMPL_CYCLE_COLLECTION_UNLINK(_field9) \ + NS_IMPL_CYCLE_COLLECTION_UNLINK(_field10) \ + NS_IMPL_CYCLE_COLLECTION_UNLINK(_field11) \ + NS_IMPL_CYCLE_COLLECTION_UNLINK(_field12) \ + NS_IMPL_CYCLE_COLLECTION_UNLINK(_field13) \ + NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER \ + NS_IMPL_CYCLE_COLLECTION_UNLINK_END \ + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_class) \ + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field1) \ + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field2) \ + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field3) \ + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field4) \ + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field5) \ + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field6) \ + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field7) \ + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field8) \ + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field9) \ + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field10) \ + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field11) \ + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field12) \ + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field13) \ + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS \ + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END \ + NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(_class) + #endif /* nsWrapperCache_h___ */ From 0dc7413940b3e015024b41938ff196f072d56b03 Mon Sep 17 00:00:00 2001 From: Kannan Vijayan Date: Wed, 4 Sep 2013 11:37:03 -0400 Subject: [PATCH 077/171] Bug 906781 - Test case for JSOP_FUNAPPLY with arrays. DONTBUILD. r=jandem --- .../jit-test/tests/baseline/funcall-array.js | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 js/src/jit-test/tests/baseline/funcall-array.js diff --git a/js/src/jit-test/tests/baseline/funcall-array.js b/js/src/jit-test/tests/baseline/funcall-array.js new file mode 100644 index 00000000000..f2f8563f19f --- /dev/null +++ b/js/src/jit-test/tests/baseline/funcall-array.js @@ -0,0 +1,70 @@ + +var emptyArray = []; +var denseArray = [1, 2, 3, 4]; +var sparseArray = [1,,2,,3,,4]; +var bigArray = new Array(); +for (var i = 0; i < 128; i++) { + bigArray.push(i); +} +var nonArray = {0:1, 1:2, 2:3, 3:4, length:2}; +var indexedGetterArray = new Array(); +Object.defineProperty(indexedGetterArray, '2', {get:function () { return 51; }}); + +var ARRAYS = [emptyArray, denseArray, sparseArray, bigArray, nonArray, indexedGetterArray]; + +var targetFun = function (a, b, c, d) { + if (a === undefined) + a = 0; + if (b === undefined) + b = 0; + if (c === undefined) + c = 0; + if (d === undefined) + d = 0; + this.count += arguments.length + a + b + c + d; +} + +var PERMUTATIONS = ARRAYS.length * ARRAYS.length; +function arrayPermutation(num) { + var idx1 = num % ARRAYS.length; + var idx2 = ((num / ARRAYS.length)|0) % ARRAYS.length; + var resultArray = []; + resultArray.push(ARRAYS[idx1]); + resultArray.push(ARRAYS[idx2]); + return resultArray; +} +var EXPECTED_RESULTS = { + 0:0, 1:280, 2:200, 3:2680, 4:100, 5:1080, 6:280, 7:560, 8:480, 9:2960, + 10:380, 11:1360, 12:200, 13:480, 14:400, 15:2880, 16:300, 17:1280, 18:2680, + 19:2960, 20:2880, 21:5360, 22:2780, 23:3760, 24:100, 25:380, 26:300, 27:2780, + 28:200, 29:1180, 30:1080, 31:1360, 32:1280, 33:3760, 34:1180, 35:2160 +}; + +var callerNo = 0; +function generateCaller() { + var fn; + + // Salt eval-string with callerNo to make sure eval caching doesn't take effect. + var s = "function caller" + callerNo + "(fn, thisObj, arrays) {" + + " for (var i = 0; i < arrays.length; i++) {" + + " fn.apply(thisObj, arrays[i]);" + + " }" + + "}" + + "fn = caller" + callerNo + ";"; + eval(s); + return fn; +}; + +function main() { + for (var i = 0; i < PERMUTATIONS; i++) { + var obj = {count:0}; + var arrs = arrayPermutation(i); + var fn = generateCaller(arrs.length); + // Loop 20 times so baseline compiler has chance to kick in and compile the scripts. + for (var j = 0; j < 20; j++) + fn(targetFun, obj, arrs); + assertEq(obj.count, EXPECTED_RESULTS[i]); + } +} + +main(); From 7767b636b2c4c0eb170cad899979362dd84e7113 Mon Sep 17 00:00:00 2001 From: Tom Schuster Date: Wed, 4 Sep 2013 11:40:16 -0400 Subject: [PATCH 078/171] Bug 910431 - Electrolysis: Permission code followup. f=felipe --- browser/components/nsBrowserGlue.js | 12 ++++-------- dom/src/notification/DesktopNotification.cpp | 4 +++- dom/src/notification/Notification.cpp | 4 +++- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/browser/components/nsBrowserGlue.js b/browser/components/nsBrowserGlue.js index 731b0c72f7f..f9a7fe13a50 100644 --- a/browser/components/nsBrowserGlue.js +++ b/browser/components/nsBrowserGlue.js @@ -1734,15 +1734,11 @@ ContentPermissionPrompt.prototype = { QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPermissionPrompt]), _getBrowserForRequest: function (aRequest) { - var browser; - try { - // "element" is only defined in e10s mode, otherwise it throws. - browser = aRequest.element; - } catch (e) {} + // "element" is only defined in e10s mode. + let browser = aRequest.element; if (!browser) { - var requestingWindow = aRequest.window.top; - // find the requesting browser or iframe - browser = requestingWindow.QueryInterface(Ci.nsIInterfaceRequestor) + // Find the requesting browser. + browser = aRequest.window.QueryInterface(Ci.nsIInterfaceRequestor) .getInterface(Ci.nsIWebNavigation) .QueryInterface(Ci.nsIDocShell) .chromeEventHandler; diff --git a/dom/src/notification/DesktopNotification.cpp b/dom/src/notification/DesktopNotification.cpp index e7fb1fa813d..cd2024ce5a2 100644 --- a/dom/src/notification/DesktopNotification.cpp +++ b/dom/src/notification/DesktopNotification.cpp @@ -318,7 +318,9 @@ DesktopNotificationRequest::GetWindow(nsIDOMWindow * *aRequestingWindow) NS_IMETHODIMP DesktopNotificationRequest::GetElement(nsIDOMElement * *aElement) { - return NS_ERROR_FAILURE; + NS_ENSURE_ARG_POINTER(aElement); + *aElement = nullptr; + return NS_OK; } NS_IMETHODIMP diff --git a/dom/src/notification/Notification.cpp b/dom/src/notification/Notification.cpp index 8bf70da6317..156ee638591 100644 --- a/dom/src/notification/Notification.cpp +++ b/dom/src/notification/Notification.cpp @@ -179,7 +179,9 @@ NotificationPermissionRequest::GetWindow(nsIDOMWindow** aRequestingWindow) NS_IMETHODIMP NotificationPermissionRequest::GetElement(nsIDOMElement** aElement) { - return NS_ERROR_FAILURE; + NS_ENSURE_ARG_POINTER(aElement); + *aElement = nullptr; + return NS_OK; } NS_IMETHODIMP From c17dd3b37a2c9173b31432e030312eec61434a75 Mon Sep 17 00:00:00 2001 From: Terrence Cole Date: Wed, 4 Sep 2013 08:46:00 -0700 Subject: [PATCH 079/171] Bug 906243 - Handle shrinkSlots correctly for nursery things; r=jonco --HG-- extra : rebase_source : 7c7a94b64d6227f701590d9da14cd6e6f0cde019 --- js/src/gc/Nursery.cpp | 9 +++++++++ js/src/gc/Nursery.h | 3 +++ js/src/jit-test/tests/gc/bug-906243.js | 12 ++++++++++++ js/src/jsobj.cpp | 5 +++-- 4 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 js/src/jit-test/tests/gc/bug-906243.js diff --git a/js/src/gc/Nursery.cpp b/js/src/gc/Nursery.cpp index 651584d1cfa..f68d7deaf0a 100644 --- a/js/src/gc/Nursery.cpp +++ b/js/src/gc/Nursery.cpp @@ -181,6 +181,15 @@ js::Nursery::reallocateElements(JSContext *cx, JSObject *obj, ObjectElements *ol return reinterpret_cast(slots); } +void +js::Nursery::freeSlots(JSContext *cx, HeapSlot *slots) +{ + if (!isInside(slots)) { + hugeSlots.remove(slots); + js_free(slots); + } +} + HeapSlot * js::Nursery::allocateHugeSlots(JSContext *cx, size_t nslots) { diff --git a/js/src/gc/Nursery.h b/js/src/gc/Nursery.h index 28dac3f0f57..4871c87de3b 100644 --- a/js/src/gc/Nursery.h +++ b/js/src/gc/Nursery.h @@ -79,6 +79,9 @@ class Nursery ObjectElements *reallocateElements(JSContext *cx, JSObject *obj, ObjectElements *oldHeader, uint32_t oldCount, uint32_t newCount); + /* Free a slots array. */ + void freeSlots(JSContext *cx, HeapSlot *slots); + /* Add a slots to our tracking list if it is out-of-line. */ void notifyInitialSlots(gc::Cell *cell, HeapSlot *slots); diff --git a/js/src/jit-test/tests/gc/bug-906243.js b/js/src/jit-test/tests/gc/bug-906243.js new file mode 100644 index 00000000000..a9006f18cbd --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-906243.js @@ -0,0 +1,12 @@ +a2 = [] +g = function() r +Object.defineProperty(a2, 0, { + set: function() {} +}) +for (var x = 0; x < 70; ++x) { + Array.prototype.unshift.call(a2, g) +} +a2.length = 8 +for each(e in [0, 0]) { + Array.prototype.shift.call(a2) +} diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index a94c7862f37..89a1333dc66 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -2587,9 +2587,10 @@ FreeSlots(ExclusiveContext *cx, HeapSlot *slots) { // Note: threads without a JSContext do not have access to nursery allocated things. #ifdef JSGC_GENERATIONAL - if (!cx->isJSContext() || !cx->asJSContext()->runtime()->gcNursery.isInside(slots)) + if (cx->isJSContext()) + return cx->asJSContext()->runtime()->gcNursery.freeSlots(cx->asJSContext(), slots); #endif - js_free(slots); + js_free(slots); } /* static */ void From 74862ec49ade2cb91ad7af9d3bda4447c14af3c8 Mon Sep 17 00:00:00 2001 From: Terrence Cole Date: Wed, 4 Sep 2013 08:46:28 -0700 Subject: [PATCH 080/171] Bug 906236 - Sweep DeclEnvObjects in the background; r=luke --- js/src/jit-test/tests/gc/bug-906236.js | 9 +++++++++ js/src/vm/ScopeObject.cpp | 2 ++ js/src/vm/ScopeObject.h | 2 +- 3 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 js/src/jit-test/tests/gc/bug-906236.js diff --git a/js/src/jit-test/tests/gc/bug-906236.js b/js/src/jit-test/tests/gc/bug-906236.js new file mode 100644 index 00000000000..7566bda428d --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-906236.js @@ -0,0 +1,9 @@ +// |jit-test| error: too much recursion +(function() { + (function f(x) { + return x * f(x - 1); + with({}) + var r = "" + })() +})() + diff --git a/js/src/vm/ScopeObject.cpp b/js/src/vm/ScopeObject.cpp index bfcc5160d9a..df9e494262b 100644 --- a/js/src/vm/ScopeObject.cpp +++ b/js/src/vm/ScopeObject.cpp @@ -333,6 +333,8 @@ Class DeclEnvObject::class_ = { DeclEnvObject * DeclEnvObject::createTemplateObject(JSContext *cx, HandleFunction fun, gc::InitialHeap heap) { + JS_ASSERT(IsNurseryAllocable(FINALIZE_KIND)); + RootedTypeObject type(cx, cx->getNewType(&class_, NULL)); if (!type) return NULL; diff --git a/js/src/vm/ScopeObject.h b/js/src/vm/ScopeObject.h index 14f859c81d0..d3468ea75dc 100644 --- a/js/src/vm/ScopeObject.h +++ b/js/src/vm/ScopeObject.h @@ -256,7 +256,7 @@ class DeclEnvObject : public ScopeObject public: static const uint32_t RESERVED_SLOTS = 2; - static const gc::AllocKind FINALIZE_KIND = gc::FINALIZE_OBJECT2; + static const gc::AllocKind FINALIZE_KIND = gc::FINALIZE_OBJECT2_BACKGROUND; static Class class_; From a3c225f686f453ef303f7f70df180941731a6ddf Mon Sep 17 00:00:00 2001 From: Masatoshi Kimura Date: Thu, 5 Sep 2013 01:02:27 +0900 Subject: [PATCH 081/171] Bug 911573 - Enable and use specialpowers in jsreftest. r=terrence, bholley --- js/src/tests/browser.js | 34 ++++++++++-------------------- layout/tools/reftest/runreftest.py | 2 +- 2 files changed, 12 insertions(+), 24 deletions(-) diff --git a/js/src/tests/browser.js b/js/src/tests/browser.js index 17693d9c5bb..970eaadfe46 100644 --- a/js/src/tests/browser.js +++ b/js/src/tests/browser.js @@ -156,8 +156,7 @@ function gc() { try { - netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect'); - Components.utils.forceGC(); + SpecialPowers.forceGC(); } catch(ex) { @@ -169,10 +168,8 @@ function jsdgc() { try { - // Thanks to dveditz - netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect'); - var jsdIDebuggerService = Components.interfaces.jsdIDebuggerService; - var service = Components.classes['@mozilla.org/js/jsd/debugger-service;1']. + var jsdIDebuggerService = SpecialPowers.Ci.jsdIDebuggerService; + var service = SpecialPowers.Cc['@mozilla.org/js/jsd/debugger-service;1']. getService(jsdIDebuggerService); service.GC(); } @@ -202,9 +199,7 @@ function options(aOptionName) } if (aOptionName) { - netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect'); - if (!(aOptionName in Components.utils)) { -// if (!(aOptionName in SpecialPowers.wrap(Components).utils)) { + if (!(aOptionName in SpecialPowers.Cu)) { // This test is trying to flip an unsupported option, so it's // likely no longer testing what it was supposed to. Fail it // hard. @@ -218,8 +213,7 @@ function options(aOptionName) // option is not set, toggle it to set options.currvalues[aOptionName] = true; -// SpecialPowers.wrap(Components).utils[aOptionName] = options.currvalues.hasOwnProperty(aOptionName); - Components.utils[aOptionName] = + SpecialPowers.Cu[aOptionName] = options.currvalues.hasOwnProperty(aOptionName); } @@ -248,18 +242,15 @@ function optionsInit() { // and popping options options.stackvalues = []; - netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect'); for (var optionName in options.currvalues) { var propName = optionName; -// if (!(propName in SpecialPowers.wrap(Components).utils)) - if (!(propName in Components.utils)) + if (!(propName in SpecialPowers.Cu)) { throw "options.currvalues is out of sync with Components.utils"; } -// if (!SpecialPowers.wrap(Components).utils[propName]) - if (!Components.utils[propName]) + if (!SpecialPowers.Cu[propName]) { delete options.currvalues[optionName]; } @@ -272,8 +263,7 @@ function optionsInit() { function gczeal(z) { - netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect'); - Components.utils.setGCZeal(z); + SpecialPowers.setGCZeal(z); } function jit(on) @@ -513,11 +503,9 @@ var gDialogCloserObserver; function registerDialogCloser() { - netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect'); -// gDialogCloser = SpecialPowers.wrap(Components). - gDialogCloser = Components. - classes['@mozilla.org/embedcomp/window-watcher;1']. - getService(Components.interfaces.nsIWindowWatcher); + gDialogCloser = SpecialPowers. + Cc['@mozilla.org/embedcomp/window-watcher;1']. + getService(SpecialPowers.Ci.nsIWindowWatcher); gDialogCloserObserver = {observe: dialogCloser_observe}; diff --git a/layout/tools/reftest/runreftest.py b/layout/tools/reftest/runreftest.py index 9d0690f25f9..50001396e3c 100644 --- a/layout/tools/reftest/runreftest.py +++ b/layout/tools/reftest/runreftest.py @@ -87,7 +87,7 @@ class RefTest(object): # I would prefer to use "--install-extension reftest/specialpowers", but that requires tight coordination with # release engineering and landing on multiple branches at once. - if special_powers and manifest.endswith('crashtests.list'): + if special_powers and (manifest.endswith('crashtests.list') or manifest.endswith('jstests.list')): addons.append(os.path.join(SCRIPT_DIRECTORY, 'specialpowers')) # Install distributed extensions, if application has any. From 216f76200c12c4e06eaaa50ad0445d3a931ba30b Mon Sep 17 00:00:00 2001 From: Masatoshi Kimura Date: Thu, 5 Sep 2013 01:02:34 +0900 Subject: [PATCH 082/171] Bug 911573 - Mochitest fixup to prepare removing Components-in-content with UniversalXPConnect. r=bholley --- .../test_disallowInheritPrincipal.html | 9 +- content/base/test/copypaste.js | 21 +++-- content/base/test/fileutils.js | 14 ++- content/base/test/test_XHRSendData.html | 6 +- content/base/test/test_bug270145.xhtml | 7 +- content/base/test/test_bug401662.html | 5 +- content/base/test/test_bug403852.html | 4 +- content/base/test/test_bug417384.html | 6 +- content/base/test/test_bug422403-2.xhtml | 19 ++--- content/base/test/test_bug424359-1.html | 19 ++--- content/base/test/test_bug424359-2.html | 19 ++--- content/base/test/test_bug498433.html | 19 ++--- content/base/test/test_bug498897.html | 20 ++--- content/base/test/test_bug541937.html | 7 +- content/base/test/test_bug578096.html | 9 +- content/base/test/test_copyimage.html | 15 ++-- content/base/test/test_fileapi.html | 11 ++- content/base/test/test_htmlcopyencoder.html | 7 +- content/base/test/test_htmlcopyencoder.xhtml | 7 +- content/base/test/test_websocket.html | 28 +++--- .../test/websocket_hybi/test_send-blob.html | 16 ++-- content/events/test/test_bug336682.js | 5 +- content/events/test/test_bug508479.html | 12 ++- .../forms/test_formnovalidate_attribute.html | 5 +- .../test/forms/test_max_attribute.html | 15 ++-- .../test/forms/test_min_attribute.html | 15 ++-- .../test/forms/test_required_attribute.html | 55 ++++++------ .../test/forms/test_step_attribute.html | 15 ++-- .../test/forms/test_submit_invalid_file.html | 7 +- .../html/content/test/test_bug557087-3.html | 5 +- content/html/content/test/test_bug561636.html | 5 +- .../html/content/test/test_bug590353-2.html | 14 ++- content/html/content/test/test_bug598643.html | 13 ++- .../html/content/test/test_bug605124-1.html | 5 +- .../html/content/test/test_bug605125-1.html | 5 +- content/media/test/file_access_controls.html | 3 +- .../media/webspeech/recognition/test/head.js | 3 +- content/xml/document/test/test_bug392338.html | 17 ++-- content/xul/content/test/test_bug486990.xul | 7 +- .../test/mochitest/cocoa_window_focus.html | 4 +- dom/plugins/test/mochitest/test_GCrace.html | 6 +- .../mochitest/test_getauthenticationinfo.html | 6 +- .../test/mochitest/test_visibility.html | 2 - dom/plugins/test/mochitest/utils.js | 3 +- .../mochitest/ajax/offline/foreign2.html | 4 +- .../mochitest/ajax/offline/offlineTests.js | 22 +++-- .../ajax/offline/test_bug460353.html | 18 ++-- .../ajax/offline/test_missingManifest.html | 10 +-- .../mochitest/ajax/offline/test_obsolete.html | 10 +-- dom/tests/mochitest/bugs/test_bug61098.html | 14 ++- .../general/test_clipboard_events.html | 25 +++--- .../mochitest/general/test_focusrings.xul | 11 +-- .../test_localStorageBaseSessionOnly.html | 14 ++- .../test_localStorageEnablePref.html | 6 +- .../localstorage/test_localStorageQuota.html | 8 +- .../test_localStorageQuotaSessionOnly.html | 20 ++--- dom/workers/test/test_suspend.html | 5 +- .../html/tests/test_CF_HTML_clipboard.html | 7 +- .../tests/test_contenteditable_focus.html | 43 +++++----- .../test_htmleditor_keyevent_handling.html | 85 +++++++++---------- .../libeditor/text/tests/test_bug569988.html | 6 +- .../libeditor/text/tests/test_bug596333.html | 15 ++-- .../test_texteditor_keyevent_handling.html | 26 +++--- embedding/test/test_bug293834.html | 10 +-- embedding/test/test_bug449141.html | 10 +-- embedding/test/test_bug499115.html | 5 +- embedding/test/test_nsFind.html | 22 +++-- extensions/cookie/test/file_testcommon.js | 25 +++--- extensions/cookie/test/file_testloadflags.js | 38 ++++----- gfx/tests/mochitest/test_bug509244.html | 5 +- gfx/tests/mochitest/test_bug513439.html | 9 +- image/test/mochitest/imgutils.js | 15 +--- image/test/mochitest/test_bug512435.html | 5 +- image/test/mochitest/test_bug601470.html | 7 +- intl/uconv/tests/test_long_doc.html | 5 +- js/jsd/test/jsd-test.js | 10 +-- js/jsd/test/test_bug507448.html | 11 +-- js/jsd/test/test_bug617870-callhooks.html | 5 -- js/jsd/test/test_bug638178-execlines.html | 3 - layout/base/tests/test_bug394057.html | 7 +- layout/base/tests/test_bug399284.html | 5 +- layout/base/tests/test_bug416896.html | 9 +- layout/base/tests/test_bug548545.xhtml | 6 +- layout/base/tests/test_bug603550.html | 5 +- layout/generic/test/test_bug263683.html | 27 +++--- .../tests/mochitest/bugs/test_bug483440.html | 10 +-- .../mixedcontent/test_bug383369.html | 52 ++++++------ .../test_stricttransportsecurity.html | 5 +- .../components/alerts/test/test_alerts.html | 5 +- .../alerts/test/test_alerts_noobserve.html | 5 +- .../microformats/tests/test_Microformats.html | 12 +-- .../tests/test_Microformats_add.html | 7 +- .../tests/test_Microformats_adr.html | 8 +- .../tests/test_Microformats_count.html | 3 +- .../tests/test_Microformats_geo.html | 8 +- .../tests/test_Microformats_getters.html | 3 +- .../tests/test_Microformats_hCalendar.html | 8 +- .../tests/test_Microformats_hCard.html | 8 +- .../tests/test_Microformats_negative.html | 3 +- .../tests/test_framerecursion.html | 3 +- toolkit/components/places/tests/Makefile.in | 4 +- .../tests/mochitest/bug_411966/redirect.js | 11 +-- .../tests/mochitest/test_bug_411966.html | 8 +- .../tests/mochitest/test_bug_94514.html | 7 +- .../tests/mochitest/test_classifier.html | 7 +- .../mochitest/test_classifier_worker.html | 7 +- .../mochitest/test_unsafeBidiChars.xhtml | 22 ++--- widget/tests/test_bug565392.html | 6 +- 108 files changed, 531 insertions(+), 769 deletions(-) diff --git a/caps/tests/mochitest/test_disallowInheritPrincipal.html b/caps/tests/mochitest/test_disallowInheritPrincipal.html index 4e441ee154e..ec59bec3c18 100644 --- a/caps/tests/mochitest/test_disallowInheritPrincipal.html +++ b/caps/tests/mochitest/test_disallowInheritPrincipal.html @@ -22,9 +22,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=732413 aPrincipal is the system principal. **/ -netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect'); -const nsIScriptSecurityManager = Components.interfaces.nsIScriptSecurityManager; -var secMan = Components.classes["@mozilla.org/scriptsecuritymanager;1"] +const nsIScriptSecurityManager = SpecialPowers.Ci.nsIScriptSecurityManager; +var secMan = SpecialPowers.Cc["@mozilla.org/scriptsecuritymanager;1"] .getService(nsIScriptSecurityManager); var sysPrincipal = secMan.getSystemPrincipal(); isnot(sysPrincipal, undefined, "Should have a principal"); @@ -33,8 +32,8 @@ is(secMan.isSystemPrincipal(sysPrincipal), true, "Should have system principal here"); -var ioService = Components.classes["@mozilla.org/network/io-service;1"]. - getService(Components.interfaces.nsIIOService); +var ioService = SpecialPowers.Cc["@mozilla.org/network/io-service;1"]. + getService(SpecialPowers.Ci.nsIIOService); var inheritingURI = ioService.newURI("javascript:1+1", null, null); // First try a normal call to checkLoadURIWithPrincipal diff --git a/content/base/test/copypaste.js b/content/base/test/copypaste.js index 0856277e0b6..6bcf0e31f9f 100644 --- a/content/base/test/copypaste.js +++ b/content/base/test/copypaste.js @@ -23,7 +23,7 @@ function modifySelection(s) { } function getLoadContext() { - var Ci = SpecialPowers.wrap(Components).interfaces; + var Ci = SpecialPowers.Ci; return SpecialPowers.wrap(window).QueryInterface(Ci.nsIInterfaceRequestor) .getInterface(Ci.nsIWebNavigation) .QueryInterface(Ci.nsILoadContext); @@ -35,16 +35,16 @@ function testCopyPaste (isXHTML) { var suppressUnicodeCheckIfHidden = !!isXHTML; var suppressHTMLCheck = !!isXHTML; - var webnav = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor) - .getInterface(Components.interfaces.nsIWebNavigation) + var webnav = window.QueryInterface(SpecialPowers.Ci.nsIInterfaceRequestor) + .getInterface(SpecialPowers.Ci.nsIWebNavigation) - var docShell = webnav.QueryInterface(Components.interfaces.nsIDocShell); + var docShell = webnav.QueryInterface(SpecialPowers.Ci.nsIDocShell); var documentViewer = docShell.contentViewer - .QueryInterface(Components.interfaces.nsIContentViewerEdit); + .QueryInterface(SpecialPowers.Ci.nsIContentViewerEdit); - var clipboard = Components.classes["@mozilla.org/widget/clipboard;1"] - .getService(Components.interfaces.nsIClipboard); + var clipboard = SpecialPowers.Cc["@mozilla.org/widget/clipboard;1"] + .getService(SpecialPowers.Ci.nsIClipboard); var textarea = SpecialPowers.wrap(document.getElementById('input')); @@ -83,8 +83,8 @@ function testCopyPaste (isXHTML) { copySelectionToClipboard(); } function getClipboardData(mime) { - var transferable = Components.classes['@mozilla.org/widget/transferable;1'] - .createInstance(Components.interfaces.nsITransferable); + var transferable = SpecialPowers.Cc['@mozilla.org/widget/transferable;1'] + .createInstance(SpecialPowers.Ci.nsITransferable); transferable.init(getLoadContext()); transferable.addDataFlavor(mime); clipboard.getData(transferable, 1); @@ -97,7 +97,7 @@ function testCopyPaste (isXHTML) { return null; var data = getClipboardData(mime); is (data.value == null ? data.value : - data.value.QueryInterface(Components.interfaces.nsISupportsString).data, + data.value.QueryInterface(SpecialPowers.Ci.nsISupportsString).data, expected, mime + " value in the clipboard"); return data.value; @@ -257,7 +257,6 @@ if (false) { setTimeout(function(){testSelectionToString("div11")},0); setTimeout(function(){ - netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); copyRangeToClipboard($("div12").childNodes[0],0, $("div12").childNodes[1],2); testClipboardValue("text/unicode", "Xdiv12"); testClipboardValue("text/html", "

Xdiv12

"); diff --git a/content/base/test/fileutils.js b/content/base/test/fileutils.js index d1c0bc7c548..90fb49be492 100644 --- a/content/base/test/fileutils.js +++ b/content/base/test/fileutils.js @@ -134,27 +134,25 @@ function testHasRun() { } function createFileWithData(fileData) { - netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); - var dirSvc = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties); - var testFile = dirSvc.get("ProfD", Components.interfaces.nsIFile); + var dirSvc = SpecialPowers.Cc["@mozilla.org/file/directory_service;1"].getService(SpecialPowers.Ci.nsIProperties); + var testFile = dirSvc.get("ProfD", SpecialPowers.Ci.nsIFile); testFile.append("fileAPItestfile2-" + fileNum); fileNum++; - var outStream = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream); + var outStream = SpecialPowers.Cc["@mozilla.org/network/file-output-stream;1"].createInstance(SpecialPowers.Ci.nsIFileOutputStream); outStream.init(testFile, 0x02 | 0x08 | 0x20, // write, create, truncate 0666, 0); outStream.write(fileData, fileData.length); outStream.close(); var fileList = document.getElementById('fileList'); - fileList.value = testFile.path; + SpecialPowers.wrap(fileList).value = testFile.path; return fileList.files[0]; } function gc() { - netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); - window.QueryInterface(Components.interfaces.nsIInterfaceRequestor) - .getInterface(Components.interfaces.nsIDOMWindowUtils) + window.QueryInterface(SpecialPowers.Ci.nsIInterfaceRequestor) + .getInterface(SpecialPowers.Ci.nsIDOMWindowUtils) .garbageCollect(); } diff --git a/content/base/test/test_XHRSendData.html b/content/base/test/test_XHRSendData.html index a7fbae4710d..181fc6786a7 100644 --- a/content/base/test/test_XHRSendData.html +++ b/content/base/test/test_XHRSendData.html @@ -78,10 +78,10 @@ extensions.forEach( ); function createFileWithDataExt(fileData, extension) { - var dirSvc = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties); - var testFile = dirSvc.get("ProfD", Components.interfaces.nsIFile); + var dirSvc = SpecialPowers.Cc["@mozilla.org/file/directory_service;1"].getService(SpecialPowers.Ci.nsIProperties); + var testFile = dirSvc.get("ProfD", SpecialPowers.Ci.nsIFile); testFile.append("testfile" + extension); - var outStream = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream); + var outStream = SpecialPowers.Cc["@mozilla.org/network/file-output-stream;1"].createInstance(SpecialPowers.Ci.nsIFileOutputStream); outStream.init(testFile, 0x02 | 0x08 | 0x20, 0666, 0); outStream.write(fileData, fileData.length); outStream.close(); diff --git a/content/base/test/test_bug270145.xhtml b/content/base/test/test_bug270145.xhtml index 71232286d72..3a6fc0f2bb8 100644 --- a/content/base/test/test_bug270145.xhtml +++ b/content/base/test/test_bug270145.xhtml @@ -17,10 +17,9 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=270145 diff --git a/dom/plugins/test/mochitest/test_getauthenticationinfo.html b/dom/plugins/test/mochitest/test_getauthenticationinfo.html index 0d83b044817..77c725e477b 100644 --- a/dom/plugins/test/mochitest/test_getauthenticationinfo.html +++ b/dom/plugins/test/mochitest/test_getauthenticationinfo.html @@ -15,10 +15,8 @@ Test for NPN_GetAuthenticationInfo + + - - + + +
@@ -20,8 +20,6 @@ + - + Mozilla Bug 94514 @@ -25,8 +25,6 @@ SimpleTest.waitForExplicitFinish(); var startURI = "http://mochi.test:8888/tests/toolkit/components/places/tests/bug94514-postpage.html"; var postedURI = startURI + "?posted=1"; -netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); - const Cc = Components.classes; const Ci = Components.interfaces; @@ -44,7 +42,6 @@ var os = Cc["@mozilla.org/observer-service;1"]. var visitObserver = { _visitCount: 0, observe: function(aSubject, aTopic, aData) { - netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); if (!startPage.equals(aSubject.QueryInterface(Ci.nsIURI)) || ++this._visitCount < 2) { return; diff --git a/toolkit/components/url-classifier/tests/mochitest/test_classifier.html b/toolkit/components/url-classifier/tests/mochitest/test_classifier.html index f0c6e1e4d6f..89493441dda 100644 --- a/toolkit/components/url-classifier/tests/mochitest/test_classifier.html +++ b/toolkit/components/url-classifier/tests/mochitest/test_classifier.html @@ -14,9 +14,8 @@ + + + +Mozilla Bug 887364 +

+ +
+
+ + + diff --git a/dom/bindings/Bindings.conf b/dom/bindings/Bindings.conf index 280dec64d94..221886370ea 100644 --- a/dom/bindings/Bindings.conf +++ b/dom/bindings/Bindings.conf @@ -1232,12 +1232,12 @@ DOMInterfaces = { }, 'URL' : [{ - 'concrete': False, + 'wrapperCache' : False, + 'nativeOwnership': 'refcounted', }, { 'implicitJSContext': [ 'createObjectURL', 'revokeObjectURL' ], 'workers': True, - 'concrete': False, }], 'VTTCue': { diff --git a/dom/bindings/test/Makefile.in b/dom/bindings/test/Makefile.in index bd2b82da1ca..671563c84f2 100644 --- a/dom/bindings/test/Makefile.in +++ b/dom/bindings/test/Makefile.in @@ -75,7 +75,6 @@ MOCHITEST_FILES := \ test_ByteString.html \ test_exception_messages.html \ test_bug707564.html \ - test_bug907548.html \ test_defineProperty.html \ $(NULL) diff --git a/dom/bindings/test/test_bug907548.html b/dom/bindings/test/test_bug907548.html deleted file mode 100644 index 2d254459930..00000000000 --- a/dom/bindings/test/test_bug907548.html +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - Test for Bug 907548 - - - - - -Mozilla Bug 907548 -

- -
-
- - diff --git a/dom/webidl/URL.webidl b/dom/webidl/URL.webidl index ea955bd2c4d..66e8f4b296c 100644 --- a/dom/webidl/URL.webidl +++ b/dom/webidl/URL.webidl @@ -4,6 +4,7 @@ * You can obtain one at http://mozilla.org/MPL/2.0/. * * The origins of this IDL file are + * http://url.spec.whatwg.org/#api * http://dev.w3.org/2006/webapi/FileAPI/#creating-revoking * http://dev.w3.org/2011/webrtc/editor/getusermedia.html#url * @@ -11,7 +12,14 @@ * liability, trademark and document use rules apply. */ +// [Constructor(DOMString url, optional (URL or DOMString) base = "about:blank")] +[Constructor(DOMString url, URL base), + Constructor(DOMString url, optional DOMString base = "about:blank")] interface URL { +}; +URL implements URLUtils; + +partial interface URL { [Throws] static DOMString? createObjectURL(Blob blob, optional objectURLOptions options); [Throws] diff --git a/dom/workers/URL.cpp b/dom/workers/URL.cpp index f7388b11974..abf89803fb1 100644 --- a/dom/workers/URL.cpp +++ b/dom/workers/URL.cpp @@ -225,6 +225,129 @@ public: } }; +// static +URL* +URL::Constructor(const GlobalObject& aGlobal, const nsAString& aUrl, + URL& aBase, ErrorResult& aRv) +{ + aRv.Throw(NS_ERROR_NOT_IMPLEMENTED); + return nullptr; +} + +// static +URL* +URL::Constructor(const GlobalObject& aGlobal, const nsAString& aUrl, + const nsAString& aBase, ErrorResult& aRv) +{ + aRv.Throw(NS_ERROR_NOT_IMPLEMENTED); + return nullptr; +} + +void +URL::GetHref(nsString& aHref) const +{ +} + +void +URL::SetHref(const nsAString& aHref, ErrorResult& aRv) +{ +} + +void +URL::GetOrigin(nsString& aOrigin) const +{ +} + +void +URL::GetProtocol(nsString& aProtocol) const +{ +} + +void +URL::SetProtocol(const nsAString& aProtocol) +{ +} + +void +URL::GetUsername(nsString& aUsername) const +{ +} + +void +URL::SetUsername(const nsAString& aUsername) +{ +} + +void +URL::GetPassword(nsString& aPassword) const +{ +} + +void +URL::SetPassword(const nsAString& aPassword) +{ +} + +void +URL::GetHost(nsString& aHost) const +{ +} + +void +URL::SetHost(const nsAString& aHost) +{ +} + +void +URL::GetHostname(nsString& aHostname) const +{ +} + +void +URL::SetHostname(const nsAString& aHostname) +{ +} + +void +URL::GetPort(nsString& aPort) const +{ +} + +void +URL::SetPort(const nsAString& aPort) +{ +} + +void +URL::GetPathname(nsString& aPathname) const +{ +} + +void +URL::SetPathname(const nsAString& aPathname) +{ +} + +void +URL::GetSearch(nsString& aSearch) const +{ +} + +void +URL::SetSearch(const nsAString& aSearch) +{ +} + +void +URL::GetHash(nsString& aHash) const +{ +} + +void +URL::SetHash(const nsAString& aHash) +{ +} + // static void URL::CreateObjectURL(const GlobalObject& aGlobal, JSObject* aBlob, diff --git a/dom/workers/URL.h b/dom/workers/URL.h index 64c54d30838..e40905bd883 100644 --- a/dom/workers/URL.h +++ b/dom/workers/URL.h @@ -16,6 +16,13 @@ BEGIN_WORKERS_NAMESPACE class URL : public EventTarget { public: // Methods for WebIDL + static URL* + Constructor(const GlobalObject& aGlobal, const nsAString& aUrl, + URL& aBase, ErrorResult& aRv); + static URL* + Constructor(const GlobalObject& aGlobal, const nsAString& aUrl, + const nsAString& aBase, ErrorResult& aRv); + static void CreateObjectURL(const GlobalObject& aGlobal, JSObject* aArg, const objectURLOptions& aOptions, @@ -28,6 +35,56 @@ public: // Methods for WebIDL static void RevokeObjectURL(const GlobalObject& aGlobal, const nsAString& aUrl); + + void GetHref(nsString& aHref) const; + + void SetHref(const nsAString& aHref, ErrorResult& aRv); + + void GetOrigin(nsString& aOrigin) const; + + void GetProtocol(nsString& aProtocol) const; + + void SetProtocol(const nsAString& aProtocol); + + void GetUsername(nsString& aUsername) const; + + void SetUsername(const nsAString& aUsername); + + void GetPassword(nsString& aPassword) const; + + void SetPassword(const nsAString& aPassword); + + void GetHost(nsString& aHost) const; + + void SetHost(const nsAString& aHost); + + void GetHostname(nsString& aHostname) const; + + void SetHostname(const nsAString& aHostname); + + void GetPort(nsString& aPort) const; + + void SetPort(const nsAString& aPort); + + void GetPathname(nsString& aPathname) const; + + void SetPathname(const nsAString& aPathname); + + void GetSearch(nsString& aSearch) const; + + void SetSearch(const nsAString& aSearch); + + void GetHash(nsString& aHost) const; + + void SetHash(const nsAString& aHash); + +private: + mozilla::dom::URL* GetURL() const + { + return mURL; + } + + nsRefPtr mURL; }; END_WORKERS_NAMESPACE diff --git a/netwerk/base/src/nsStandardURL.cpp b/netwerk/base/src/nsStandardURL.cpp index ae872c8a9f4..d8a21f5aba4 100644 --- a/netwerk/base/src/nsStandardURL.cpp +++ b/netwerk/base/src/nsStandardURL.cpp @@ -1409,13 +1409,39 @@ nsStandardURL::SetPassword(const nsACString &input) } NS_IMETHODIMP -nsStandardURL::SetHostPort(const nsACString &value) +nsStandardURL::SetHostPort(const nsACString &aValue) { ENSURE_MUTABLE(); - // XXX needs implementation!! - NS_NOTREACHED("not implemented"); - return NS_ERROR_NOT_IMPLEMENTED; + // We cannot simply call nsIURI::SetHost because that would treat the name as + // an IPv6 address (like http:://[server:443]/). We also cannot call + // nsIURI::SetHostPort because that isn't implemented. Sadfaces. + + // First set the hostname. + nsACString::const_iterator start, end; + aValue.BeginReading(start); + aValue.EndReading(end); + nsACString::const_iterator iter(start); + FindCharInReadable(':', iter, end); + + nsresult rv = SetHost(Substring(start, iter)); + NS_ENSURE_SUCCESS(rv, rv); + + // Also set the port if needed. + if (iter != end) { + iter++; + if (iter != end) { + nsCString portStr(Substring(iter, end)); + nsresult rv; + int32_t port = portStr.ToInteger(&rv); + if (NS_SUCCEEDED(rv)) { + rv = SetPort(port); + NS_ENSURE_SUCCESS(rv, rv); + } + } + } + + return NS_OK; } NS_IMETHODIMP From 98502ae5c7fb169b75ac7d6f63a0224463e8a74d Mon Sep 17 00:00:00 2001 From: Andrea Marchesini Date: Wed, 4 Sep 2013 13:07:34 -0400 Subject: [PATCH 090/171] Bug 887364 - URL API for Workers. r=khuey --- dom/base/URL.h | 6 + dom/workers/DOMBindingInlines.h | 3 + dom/workers/URL.cpp | 557 +++++++++++++++++++++++++++++- dom/workers/URL.h | 26 +- dom/workers/test/Makefile.in | 2 + dom/workers/test/test_urlApi.html | 45 +++ dom/workers/test/urlApi_worker.js | 270 +++++++++++++++ 7 files changed, 898 insertions(+), 11 deletions(-) create mode 100644 dom/workers/test/test_urlApi.html create mode 100644 dom/workers/test/urlApi_worker.js diff --git a/dom/base/URL.h b/dom/base/URL.h index 814d2330781..461ab0c19b9 100644 --- a/dom/base/URL.h +++ b/dom/base/URL.h @@ -26,6 +26,10 @@ class MediaSource; class GlobalObject; struct objectURLOptions; +namespace workers { +class URLProxy; +} + class URL MOZ_FINAL { public: @@ -124,6 +128,8 @@ private: nsRefPtr mWindow; nsCOMPtr mURI; + + friend class mozilla::dom::workers::URLProxy; }; } diff --git a/dom/workers/DOMBindingInlines.h b/dom/workers/DOMBindingInlines.h index e242086c347..493ea38a1f8 100644 --- a/dom/workers/DOMBindingInlines.h +++ b/dom/workers/DOMBindingInlines.h @@ -12,6 +12,7 @@ #include "mozilla/dom/XMLHttpRequestUploadBinding.h" #include "mozilla/dom/WorkerLocationBinding.h" #include "mozilla/dom/WorkerNavigatorBinding.h" +#include "mozilla/dom/URLBinding.h" #include "jsfriendapi.h" BEGIN_WORKERS_NAMESPACE @@ -21,6 +22,7 @@ class XMLHttpRequest; class XMLHttpRequestUpload; class WorkerLocation; class WorkerNavigator; +class URL; namespace { @@ -54,6 +56,7 @@ SPECIALIZE_PROTO_TRAITS(XMLHttpRequest) SPECIALIZE_PROTO_TRAITS(XMLHttpRequestUpload) SPECIALIZE_PROTO_TRAITS(WorkerLocation) SPECIALIZE_PROTO_TRAITS(WorkerNavigator) +SPECIALIZE_PROTO_TRAITS(URL) #undef SPECIALIZE_PROTO_TRAITS diff --git a/dom/workers/URL.cpp b/dom/workers/URL.cpp index abf89803fb1..25527e560db 100644 --- a/dom/workers/URL.cpp +++ b/dom/workers/URL.cpp @@ -14,14 +14,56 @@ #include "nsPIDOMWindow.h" #include "nsGlobalWindow.h" #include "nsHostObjectProtocolHandler.h" +#include "nsServiceManagerUtils.h" #include "nsIDocument.h" #include "nsIDOMFile.h" -USING_WORKERS_NAMESPACE +#include "DOMBindingInlines.h" +#include "mozilla/dom/URL.h" +#include "nsIIOService.h" +#include "nsNetCID.h" + +BEGIN_WORKERS_NAMESPACE using mozilla::dom::GlobalObject; -// Base class for the Revoke and Create runnable objects. +class URLProxy MOZ_FINAL +{ +public: + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(URLProxy) + + URLProxy(mozilla::dom::URL* aURL) + : mURL(aURL) + { + AssertIsOnMainThread(); + } + + ~URLProxy() + { + MOZ_ASSERT(!mURL); + } + + mozilla::dom::URL* URL() + { + return mURL; + } + + nsIURI* URI() + { + return mURL->GetURI(); + } + + void ReleaseURI() + { + AssertIsOnMainThread(); + mURL = nullptr; + } + +private: + nsRefPtr mURL; +}; + +// Base class for the URL runnable objects. class URLRunnable : public nsRunnable { protected: @@ -225,13 +267,306 @@ public: } }; +// This class creates a URL object on the main thread. +class ConstructorRunnable : public URLRunnable +{ +private: + const nsString mURL; + + const nsString mBase; + nsRefPtr mBaseProxy; + mozilla::ErrorResult& mRv; + + nsRefPtr mRetval; + +public: + ConstructorRunnable(WorkerPrivate* aWorkerPrivate, + const nsAString& aURL, const nsAString& aBase, + mozilla::ErrorResult& aRv) + : URLRunnable(aWorkerPrivate) + , mURL(aURL) + , mBase(aBase) + , mRv(aRv) + { + mWorkerPrivate->AssertIsOnWorkerThread(); + } + + ConstructorRunnable(WorkerPrivate* aWorkerPrivate, + const nsAString& aURL, URLProxy* aBaseProxy, + mozilla::ErrorResult& aRv) + : URLRunnable(aWorkerPrivate) + , mURL(aURL) + , mBaseProxy(aBaseProxy) + , mRv(aRv) + { + mWorkerPrivate->AssertIsOnWorkerThread(); + } + + void + MainThreadRun() + { + AssertIsOnMainThread(); + + nsresult rv; + nsCOMPtr ioService(do_GetService(NS_IOSERVICE_CONTRACTID, &rv)); + if (NS_FAILED(rv)) { + mRv.Throw(rv); + return; + } + + nsCOMPtr baseURL; + + if (!mBaseProxy) { + rv = ioService->NewURI(NS_ConvertUTF16toUTF8(mBase), nullptr, nullptr, + getter_AddRefs(baseURL)); + if (NS_FAILED(rv)) { + mRv.Throw(NS_ERROR_DOM_SYNTAX_ERR); + return; + } + } else { + baseURL = mBaseProxy->URI(); + } + + nsCOMPtr url; + rv = ioService->NewURI(NS_ConvertUTF16toUTF8(mURL), nullptr, baseURL, + getter_AddRefs(url)); + if (NS_FAILED(rv)) { + mRv.Throw(NS_ERROR_DOM_SYNTAX_ERR); + return; + } + + mRetval = new URLProxy(new mozilla::dom::URL(nullptr, url)); + } + + URLProxy* + GetURLProxy() + { + return mRetval; + } +}; + +class TeardownRunnable : public nsRunnable +{ +public: + TeardownRunnable(URLProxy* aURLProxy) + : mURLProxy(aURLProxy) + { + } + + NS_IMETHOD Run() + { + AssertIsOnMainThread(); + + mURLProxy->ReleaseURI(); + mURLProxy = nullptr; + + return NS_OK; + } + +private: + nsRefPtr mURLProxy; +}; + +// This class is the generic getter for any URL property. +class GetterRunnable : public URLRunnable +{ +public: + enum GetterType { + GetterHref, + GetterOrigin, + GetterProtocol, + GetterUsername, + GetterPassword, + GetterHost, + GetterHostname, + GetterPort, + GetterPathname, + GetterSearch, + GetterHash, + }; + + GetterRunnable(WorkerPrivate* aWorkerPrivate, + GetterType aType, nsString& aValue, + URLProxy* aURLProxy) + : URLRunnable(aWorkerPrivate) + , mValue(aValue) + , mType(aType) + , mURLProxy(aURLProxy) + { + mWorkerPrivate->AssertIsOnWorkerThread(); + } + + void + MainThreadRun() + { + AssertIsOnMainThread(); + + switch (mType) { + case GetterHref: + mURLProxy->URL()->GetHref(mValue); + break; + + case GetterOrigin: + mURLProxy->URL()->GetOrigin(mValue); + break; + + case GetterProtocol: + mURLProxy->URL()->GetProtocol(mValue); + break; + + case GetterUsername: + mURLProxy->URL()->GetUsername(mValue); + break; + + case GetterPassword: + mURLProxy->URL()->GetPassword(mValue); + break; + + case GetterHost: + mURLProxy->URL()->GetHost(mValue); + break; + + case GetterHostname: + mURLProxy->URL()->GetHostname(mValue); + break; + + case GetterPort: + mURLProxy->URL()->GetPort(mValue); + break; + + case GetterPathname: + mURLProxy->URL()->GetPathname(mValue); + break; + + case GetterSearch: + mURLProxy->URL()->GetSearch(mValue); + break; + + case GetterHash: + mURLProxy->URL()->GetHash(mValue); + break; + } + } + +private: + nsString& mValue; + GetterType mType; + nsRefPtr mURLProxy; +}; + +// This class is the generic setter for any URL property. +class SetterRunnable : public URLRunnable +{ +public: + enum SetterType { + SetterHref, + SetterProtocol, + SetterUsername, + SetterPassword, + SetterHost, + SetterHostname, + SetterPort, + SetterPathname, + SetterSearch, + SetterHash, + }; + + SetterRunnable(WorkerPrivate* aWorkerPrivate, + SetterType aType, const nsAString& aValue, + URLProxy* aURLProxy, mozilla::ErrorResult& aRv) + : URLRunnable(aWorkerPrivate) + , mValue(aValue) + , mType(aType) + , mURLProxy(aURLProxy) + , mRv(aRv) + { + mWorkerPrivate->AssertIsOnWorkerThread(); + } + + void + MainThreadRun() + { + AssertIsOnMainThread(); + + switch (mType) { + case SetterHref: + mURLProxy->URL()->SetHref(mValue, mRv); + break; + + case SetterProtocol: + mURLProxy->URL()->SetProtocol(mValue); + break; + + case SetterUsername: + mURLProxy->URL()->SetUsername(mValue); + break; + + case SetterPassword: + mURLProxy->URL()->SetPassword(mValue); + break; + + case SetterHost: + mURLProxy->URL()->SetHost(mValue); + break; + + case SetterHostname: + mURLProxy->URL()->SetHostname(mValue); + break; + + case SetterPort: + mURLProxy->URL()->SetPort(mValue); + break; + + case SetterPathname: + mURLProxy->URL()->SetPathname(mValue); + break; + + case SetterSearch: + mURLProxy->URL()->SetSearch(mValue); + break; + + case SetterHash: + mURLProxy->URL()->SetHash(mValue); + break; + } + } + +private: + const nsString mValue; + SetterType mType; + nsRefPtr mURLProxy; + mozilla::ErrorResult& mRv; +}; + // static URL* URL::Constructor(const GlobalObject& aGlobal, const nsAString& aUrl, URL& aBase, ErrorResult& aRv) { - aRv.Throw(NS_ERROR_NOT_IMPLEMENTED); - return nullptr; + JSContext* cx = aGlobal.GetContext(); + WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx); + + nsRefPtr runnable = + new ConstructorRunnable(workerPrivate, aUrl, aBase.GetURLProxy(), aRv); + + if (!runnable->Dispatch(cx)) { + JS_ReportPendingException(cx); + } + + nsRefPtr proxy = runnable->GetURLProxy(); + if (!proxy) { + aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR); + return nullptr; + } + + nsRefPtr url = new URL(workerPrivate, proxy); + + if (!Wrap(aGlobal.GetContext(), aGlobal.Get(), url)) { + aRv.Throw(NS_ERROR_FAILURE); + return nullptr; + } + + return url; } // static @@ -239,113 +574,322 @@ URL* URL::Constructor(const GlobalObject& aGlobal, const nsAString& aUrl, const nsAString& aBase, ErrorResult& aRv) { - aRv.Throw(NS_ERROR_NOT_IMPLEMENTED); - return nullptr; + JSContext* cx = aGlobal.GetContext(); + WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx); + + nsRefPtr runnable = + new ConstructorRunnable(workerPrivate, aUrl, aBase, aRv); + + if (!runnable->Dispatch(cx)) { + JS_ReportPendingException(cx); + } + + nsRefPtr proxy = runnable->GetURLProxy(); + if (!proxy) { + aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR); + return nullptr; + } + + nsRefPtr url = new URL(workerPrivate, proxy); + + if (!Wrap(aGlobal.GetContext(), aGlobal.Get(), url)) { + aRv.Throw(NS_ERROR_FAILURE); + return nullptr; + } + + return url; +} + +URL::URL(WorkerPrivate* aWorkerPrivate, URLProxy* aURLProxy) + : DOMBindingBase(aWorkerPrivate->GetJSContext()) + , mWorkerPrivate(aWorkerPrivate) + , mURLProxy(aURLProxy) +{ +} + +URL::~URL() +{ + if (mURLProxy) { + nsRefPtr runnable = new TeardownRunnable(mURLProxy); + mURLProxy = nullptr; + + if (NS_FAILED(NS_DispatchToMainThread(runnable))) { + NS_ERROR("Failed to dispatch teardown runnable!"); + } + } +} + +void +URL::_trace(JSTracer* aTrc) +{ + DOMBindingBase::_trace(aTrc); +} + +void +URL::_finalize(JSFreeOp* aFop) +{ + DOMBindingBase::_finalize(aFop); } void URL::GetHref(nsString& aHref) const { + nsRefPtr runnable = + new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterHref, aHref, + mURLProxy); + + if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) { + JS_ReportPendingException(mWorkerPrivate->GetJSContext()); + } } void URL::SetHref(const nsAString& aHref, ErrorResult& aRv) { + nsRefPtr runnable = + new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterHref, aHref, + mURLProxy, aRv); + + if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) { + JS_ReportPendingException(mWorkerPrivate->GetJSContext()); + } } void URL::GetOrigin(nsString& aOrigin) const { + nsRefPtr runnable = + new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterOrigin, aOrigin, + mURLProxy); + + if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) { + JS_ReportPendingException(mWorkerPrivate->GetJSContext()); + } } void URL::GetProtocol(nsString& aProtocol) const { + nsRefPtr runnable = + new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterProtocol, aProtocol, + mURLProxy); + + if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) { + JS_ReportPendingException(mWorkerPrivate->GetJSContext()); + } } void URL::SetProtocol(const nsAString& aProtocol) { + ErrorResult rv; + nsRefPtr runnable = + new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterProtocol, + aProtocol, mURLProxy, rv); + + if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) { + JS_ReportPendingException(mWorkerPrivate->GetJSContext()); + } } void URL::GetUsername(nsString& aUsername) const { + nsRefPtr runnable = + new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterUsername, aUsername, + mURLProxy); + + if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) { + JS_ReportPendingException(mWorkerPrivate->GetJSContext()); + } } void URL::SetUsername(const nsAString& aUsername) { + ErrorResult rv; + nsRefPtr runnable = + new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterUsername, + aUsername, mURLProxy, rv); + + if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) { + JS_ReportPendingException(mWorkerPrivate->GetJSContext()); + } } void URL::GetPassword(nsString& aPassword) const { + nsRefPtr runnable = + new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterPassword, aPassword, + mURLProxy); + + if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) { + JS_ReportPendingException(mWorkerPrivate->GetJSContext()); + } } void URL::SetPassword(const nsAString& aPassword) { + ErrorResult rv; + nsRefPtr runnable = + new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterPassword, + aPassword, mURLProxy, rv); + + if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) { + JS_ReportPendingException(mWorkerPrivate->GetJSContext()); + } } void URL::GetHost(nsString& aHost) const { + nsRefPtr runnable = + new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterHost, aHost, + mURLProxy); + + if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) { + JS_ReportPendingException(mWorkerPrivate->GetJSContext()); + } } void URL::SetHost(const nsAString& aHost) { + ErrorResult rv; + nsRefPtr runnable = + new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterHost, + aHost, mURLProxy, rv); + + if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) { + JS_ReportPendingException(mWorkerPrivate->GetJSContext()); + } } void URL::GetHostname(nsString& aHostname) const { + nsRefPtr runnable = + new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterHostname, aHostname, + mURLProxy); + + if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) { + JS_ReportPendingException(mWorkerPrivate->GetJSContext()); + } } void URL::SetHostname(const nsAString& aHostname) { + ErrorResult rv; + nsRefPtr runnable = + new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterHostname, + aHostname, mURLProxy, rv); + + if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) { + JS_ReportPendingException(mWorkerPrivate->GetJSContext()); + } } void URL::GetPort(nsString& aPort) const { + nsRefPtr runnable = + new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterPort, aPort, + mURLProxy); + + if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) { + JS_ReportPendingException(mWorkerPrivate->GetJSContext()); + } } void URL::SetPort(const nsAString& aPort) { + ErrorResult rv; + nsRefPtr runnable = + new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterPort, + aPort, mURLProxy, rv); + + if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) { + JS_ReportPendingException(mWorkerPrivate->GetJSContext()); + } } void URL::GetPathname(nsString& aPathname) const { + nsRefPtr runnable = + new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterPathname, aPathname, + mURLProxy); + + if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) { + JS_ReportPendingException(mWorkerPrivate->GetJSContext()); + } } void URL::SetPathname(const nsAString& aPathname) { + ErrorResult rv; + nsRefPtr runnable = + new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterPathname, + aPathname, mURLProxy, rv); + + if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) { + JS_ReportPendingException(mWorkerPrivate->GetJSContext()); + } } void URL::GetSearch(nsString& aSearch) const { + nsRefPtr runnable = + new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterSearch, aSearch, + mURLProxy); + + if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) { + JS_ReportPendingException(mWorkerPrivate->GetJSContext()); + } } void URL::SetSearch(const nsAString& aSearch) { + ErrorResult rv; + nsRefPtr runnable = + new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterSearch, + aSearch, mURLProxy, rv); + + if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) { + JS_ReportPendingException(mWorkerPrivate->GetJSContext()); + } } void URL::GetHash(nsString& aHash) const { + nsRefPtr runnable = + new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterHash, aHash, + mURLProxy); + + if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) { + JS_ReportPendingException(mWorkerPrivate->GetJSContext()); + } } void URL::SetHash(const nsAString& aHash) { + ErrorResult rv; + nsRefPtr runnable = + new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterHash, + aHash, mURLProxy, rv); + + if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) { + JS_ReportPendingException(mWorkerPrivate->GetJSContext()); + } } // static @@ -399,3 +943,4 @@ URL::RevokeObjectURL(const GlobalObject& aGlobal, const nsAString& aUrl) } } +END_WORKERS_NAMESPACE diff --git a/dom/workers/URL.h b/dom/workers/URL.h index e40905bd883..0ea62e7a324 100644 --- a/dom/workers/URL.h +++ b/dom/workers/URL.h @@ -7,15 +7,30 @@ #ifndef mozilla_dom_workers_url_h__ #define mozilla_dom_workers_url_h__ +#include "mozilla/dom/workers/bindings/DOMBindingBase.h" #include "mozilla/dom/URLBinding.h" #include "EventTarget.h" BEGIN_WORKERS_NAMESPACE -class URL : public EventTarget +class URLProxy; + +class URL MOZ_FINAL : public DOMBindingBase { -public: // Methods for WebIDL +public: + + URL(WorkerPrivate* aWorkerPrivate, URLProxy* aURLProxy); + ~URL(); + + virtual void + _trace(JSTracer* aTrc) MOZ_OVERRIDE; + + virtual void + _finalize(JSFreeOp* aFop) MOZ_OVERRIDE; + + // Methods for WebIDL + static URL* Constructor(const GlobalObject& aGlobal, const nsAString& aUrl, URL& aBase, ErrorResult& aRv); @@ -79,12 +94,13 @@ public: // Methods for WebIDL void SetHash(const nsAString& aHash); private: - mozilla::dom::URL* GetURL() const + URLProxy* GetURLProxy() const { - return mURL; + return mURLProxy; } - nsRefPtr mURL; + WorkerPrivate* mWorkerPrivate; + nsRefPtr mURLProxy; }; END_WORKERS_NAMESPACE diff --git a/dom/workers/test/Makefile.in b/dom/workers/test/Makefile.in index 932633f4c8f..a9a4d73b6c1 100644 --- a/dom/workers/test/Makefile.in +++ b/dom/workers/test/Makefile.in @@ -108,6 +108,8 @@ MOCHITEST_FILES = \ url_worker.js \ test_bug911085.html \ bug911085_worker.js \ + test_urlApi.html \ + urlApi_worker.js \ $(NULL) # Bug 842386 - Disabled on OSX due to intermittent failures. diff --git a/dom/workers/test/test_urlApi.html b/dom/workers/test/test_urlApi.html new file mode 100644 index 00000000000..654d2a19745 --- /dev/null +++ b/dom/workers/test/test_urlApi.html @@ -0,0 +1,45 @@ + + + + + Test for URL API object in workers + + + + +

+ +

+
+
+
+
+
+
diff --git a/dom/workers/test/urlApi_worker.js b/dom/workers/test/urlApi_worker.js
new file mode 100644
index 00000000000..5a4633b6ba3
--- /dev/null
+++ b/dom/workers/test/urlApi_worker.js
@@ -0,0 +1,270 @@
+function ok(a, msg) {
+  dump("OK: " + !!a + "  =>  " + a + " " + msg + "\n");
+  postMessage({type: 'status', status: !!a, msg: a + ": " + msg });
+}
+
+function is(a, b, msg) {
+  dump("IS: " + (a===b) + "  =>  " + a + " | " + b + " " + msg + "\n");
+  postMessage({type: 'status', status: a === b, msg: a + " === " + b + ": " + msg });
+}
+
+onmessage = function() {
+  status = false;
+  try {
+    if ((URL instanceof Object)) {
+      status = true;
+    }
+  } catch(e) {
+  }
+
+  var tests = [
+    { url: 'http://www.abc.com',
+      base: undefined,
+      error: false,
+      href: 'http://www.abc.com/',
+      origin: 'http://www.abc.com',
+      protocol: 'http:',
+      username: '',
+      password: '',
+      host: 'www.abc.com',
+      hostname: 'www.abc.com',
+      port: '',
+      pathname: '/',
+      search: '',
+      hash: ''
+    },
+    { url: 'ftp://auser:apw@www.abc.com',
+      base: undefined,
+      error: false,
+      href: 'ftp://auser:apw@www.abc.com/',
+      origin: 'ftp://www.abc.com',
+      protocol: 'ftp:',
+      username: 'auser',
+      password: 'apw',
+      host: 'www.abc.com',
+      hostname: 'www.abc.com',
+      port: '',
+      pathname: '/',
+      search: '',
+      hash: ''
+    },
+    { url: 'http://www.abc.com:90/apath/',
+      base: undefined,
+      error: false,
+      href: 'http://www.abc.com:90/apath/',
+      origin: 'http://www.abc.com:90',
+      protocol: 'http:',
+      username: '',
+      password: '',
+      host: 'www.abc.com:90',
+      hostname: 'www.abc.com',
+      port: '90',
+      pathname: '/apath/',
+      search: '',
+      hash: ''
+    },
+    { url: 'http://www.abc.com/apath/afile.txt#ahash',
+      base: undefined,
+      error: false,
+      href: 'http://www.abc.com/apath/afile.txt#ahash',
+      origin: 'http://www.abc.com',
+      protocol: 'http:',
+      username: '',
+      password: '',
+      host: 'www.abc.com',
+      hostname: 'www.abc.com',
+      port: '',
+      pathname: '/apath/afile.txt',
+      search: '',
+      hash: '#ahash'
+    },
+    { url: 'http://example.com/?test#hash',
+      base: undefined,
+      error: false,
+      href: 'http://example.com/?test#hash',
+      origin: 'http://example.com',
+      protocol: 'http:',
+      username: '',
+      password: '',
+      host: 'example.com',
+      hostname: 'example.com',
+      port: '',
+      pathname: '/',
+      search: '?test',
+      hash: '#hash'
+    },
+    { url: 'http://example.com/?test',
+      base: undefined,
+      error: false,
+      href: 'http://example.com/?test',
+      origin: 'http://example.com',
+      protocol: 'http:',
+      username: '',
+      password: '',
+      host: 'example.com',
+      hostname: 'example.com',
+      port: '',
+      pathname: '/',
+      search: '?test',
+      hash: ''
+    },
+    { url: 'http://example.com/carrot#question%3f',
+      base: undefined,
+      error: false,
+      hash: '#question?'
+    },
+    { url: 'https://example.com:4443?',
+      base: undefined,
+      error: false,
+      protocol: 'https:',
+      port: '4443',
+      pathname: '/',
+      hash: '',
+      search: ''
+    },
+    { url: 'http://www.abc.com/apath/afile.txt#ahash?asearch',
+      base: undefined,
+      error: false,
+      href: 'http://www.abc.com/apath/afile.txt#ahash?asearch',
+      protocol: 'http:',
+      pathname: '/apath/afile.txt',
+      hash: '#ahash?asearch',
+      search: ''
+    },
+    { url: 'http://www.abc.com/apath/afile.txt?asearch#ahash',
+      base: undefined,
+      error: false,
+      href: 'http://www.abc.com/apath/afile.txt?asearch#ahash',
+      protocol: 'http:',
+      pathname: '/apath/afile.txt',
+      hash: '#ahash',
+      search: '?asearch'
+    },
+    { url: 'http://abc.com/apath/afile.txt?#ahash',
+      base: undefined,
+      error: false,
+      pathname: '/apath/afile.txt',
+      hash: '#ahash',
+      search: ''
+    },
+    { url: 'http://auser:apassword@www.abc.com:90/apath/afile.txt?asearch#ahash',
+      base: undefined,
+      error: false,
+      protocol: 'http:',
+      username: 'auser',
+      password: 'apassword',
+      host: 'www.abc.com:90',
+      hostname: 'www.abc.com',
+      port: '90',
+      pathname: '/apath/afile.txt',
+      hash: '#ahash',
+      search: '?asearch',
+      origin: 'http://www.abc.com:90'
+    },
+
+    { url: '/foo#bar',
+      base: 'www.test.org',
+      error: true,
+    },
+    { url: '/foo#bar',
+      base: null,
+      error: true,
+    },
+    { url: '/foo#bar',
+      base: 42,
+      error: true,
+    },
+    { url: 'ftp://ftp.something.net',
+      base: undefined,
+      error: false,
+      protocol: 'ftp:',
+    },
+    { url: 'file:///tmp/file',
+      base: undefined,
+      error: false,
+      protocol: 'file:',
+    },
+    { url: 'gopher://gopher.something.net',
+      base: undefined,
+      error: false,
+      protocol: 'gopher:',
+    },
+    { url: 'ws://ws.something.net',
+      base: undefined,
+      error: false,
+      protocol: 'ws:',
+    },
+    { url: 'wss://ws.something.net',
+      base: undefined,
+      error: false,
+      protocol: 'wss:',
+    },
+    { url: 'foo://foo.something.net',
+      base: undefined,
+      error: false,
+      protocol: 'foo:',
+    },
+  ];
+
+  while(tests.length) {
+    var test = tests.shift();
+
+    var error = false;
+    var url;
+    try {
+      if (test.base) {
+        url = new URL(test.url, test.base);
+      } else {
+        url = new URL(test.url);
+      }
+    } catch(e) {
+      error = true;
+    }
+
+    is(test.error, error, "Error creating URL");
+    if (test.error) {
+      continue;
+    }
+
+    if ('href' in test) is(url.href, test.href, "href");
+    if ('origin' in test) is(url.origin, test.origin, "origin");
+    if ('protocol' in test) is(url.protocol, test.protocol, "protocol");
+    if ('username' in test) is(url.username, test.username, "username");
+    if ('password' in test) is(url.password, test.password, "password");
+    if ('host' in test) is(url.host, test.host, "host");
+    if ('hostname' in test) is(url.hostname, test.hostname, "hostname");
+    if ('port' in test) is(url.port, test.port, "port");
+    if ('pathname' in test) is(url.pathname, test.pathname, "pathname");
+    if ('search' in test) is(url.search, test.search, "search");
+    if ('hash' in test) is(url.hash, test.hash, "hash");
+
+    url = new URL('https://www.example.net/what#foo?bar');
+    ok(url, "Url exists!");
+
+    if ('href' in test) url.href = test.href;
+    if ('protocol' in test) url.protocol = test.protocol;
+    if ('username' in test && test.username) url.username = test.username;
+    if ('password' in test && test.password) url.password = test.password;
+    if ('host' in test) url.host = test.host;
+    if ('hostname' in test) url.hostname = test.hostname;
+    if ('port' in test) url.port = test.port;
+    if ('pathname' in test) url.pathname = test.pathname;
+    if ('search' in test) url.search = test.search;
+    if ('hash' in test) url.hash = test.hash;
+
+    if ('href' in test) is(url.href, test.href, "href");
+    if ('origin' in test) is(url.origin, test.origin, "origin");
+    if ('protocol' in test) is(url.protocol, test.protocol, "protocol");
+    if ('username' in test) is(url.username, test.username, "username");
+    if ('password' in test) is(url.password, test.password, "password");
+    if ('host' in test) is(url.host, test.host, "host");
+    if ('hostname' in test) is(test.hostname, url.hostname, "hostname");
+    if ('port' in test) is(test.port, url.port, "port");
+    if ('pathname' in test) is(test.pathname, url.pathname, "pathname");
+    if ('search' in test) is(test.search, url.search, "search");
+    if ('hash' in test) is(test.hash, url.hash, "hash");
+  }
+
+  postMessage({type: 'finish' });
+}
+

From 89adb4b90a41c80b2ee49dc45b153bd811bfbb01 Mon Sep 17 00:00:00 2001
From: Ted Mielczarek 
Date: Tue, 3 Sep 2013 14:31:14 -0400
Subject: [PATCH 091/171] Bug 910363 - Make gdk-screenshot take an optional
 filename parameter. r=karlt

---
 testing/tools/screenshot/gdk-screenshot.cpp | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/testing/tools/screenshot/gdk-screenshot.cpp b/testing/tools/screenshot/gdk-screenshot.cpp
index c5eb56994a5..a8d713822fa 100644
--- a/testing/tools/screenshot/gdk-screenshot.cpp
+++ b/testing/tools/screenshot/gdk-screenshot.cpp
@@ -29,8 +29,10 @@
  *   Karl Tomlinson 
  */
 /*
- * gdk-screenshot.cpp: Write a screenshot of the root window to stdout in .png
- * format.
+ * gdk-screenshot.cpp: Save a screenshot of the root window in .png format.
+ *  If a filename is specified as the first argument on the commandline,
+ *  then the image will be saved to that filename. Otherwise, the image will
+ *  be written to stdout.
  */
 #include 
 #include 
@@ -139,8 +141,12 @@ int main(int argc, char** argv)
   }
 
   GError* error = NULL;
-  gdk_pixbuf_save_to_callback(screenshot, save_to_stdout, NULL,
-                              "png", NULL, NULL);
+  if (argc > 1) {
+    gdk_pixbuf_save(screenshot, argv[1], "png", &error, NULL);
+  } else {
+    gdk_pixbuf_save_to_callback(screenshot, save_to_stdout, NULL,
+                                "png", &error, NULL);
+  }
   if (error) {
     fprintf(stderr, "%s: failed to write screenshot as png: %s\n",
             argv[0], error->message);

From 9dc844220a5ec7b5931c1fe7ee1c96043b036e22 Mon Sep 17 00:00:00 2001
From: Mihnea Dobrescu-Balaur 
Date: Tue, 3 Sep 2013 13:56:08 -0700
Subject: [PATCH 092/171] Bug 911249 - Make sure harness does not block if
 killing a process hangs. r=ted

---
 testing/xpcshell/runxpcshelltests.py | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/testing/xpcshell/runxpcshelltests.py b/testing/xpcshell/runxpcshelltests.py
index 539c3a4ce6a..91b90e3b2d3 100644
--- a/testing/xpcshell/runxpcshelltests.py
+++ b/testing/xpcshell/runxpcshelltests.py
@@ -1331,10 +1331,11 @@ class XPCShellTests(object):
             for test in running_tests:
                 if test.done:
                     done_tests.add(test)
-                    test.join()
+                    test.join(1) # join with timeout so we don't hang on blocked threads
                     # if the test had trouble, we will try running it again
                     # at the end of the run
-                    if test.retry:
+                    if test.retry or test.is_alive():
+                        # if the join call timed out, test.is_alive => True
                         self.try_again_list.append(test.test_object)
                         continue
                     # did the test encounter any exception?

From c69cff9003cc86c06408f9060d7fc2004341e349 Mon Sep 17 00:00:00 2001
From: Dan Gohman 
Date: Wed, 4 Sep 2013 10:11:22 -0700
Subject: [PATCH 093/171] Bug 910814 - SpiderMonkey: Document that
 js_strtod_harder doesn't actually report overflow errors, and clean up its
 callers accordingly. r=waldo

---
 js/src/jsdtoa.cpp | 1 +
 js/src/jsdtoa.h   | 6 +++---
 js/src/jsnum.cpp  | 6 ------
 3 files changed, 4 insertions(+), 9 deletions(-)

diff --git a/js/src/jsdtoa.cpp b/js/src/jsdtoa.cpp
index 54de74fc853..9c1fbf7f1d9 100644
--- a/js/src/jsdtoa.cpp
+++ b/js/src/jsdtoa.cpp
@@ -48,6 +48,7 @@ inline void* dtoa_malloc(size_t size) { return js_malloc(size); }
 inline void dtoa_free(void* p) { return js_free(p); }
 
 #define NO_GLOBAL_STATE
+#define NO_ERRNO
 #define MALLOC dtoa_malloc
 #define FREE dtoa_free
 #include "dtoa.c"
diff --git a/js/src/jsdtoa.h b/js/src/jsdtoa.h
index 114c0b05bdb..5e3b20399f5 100644
--- a/js/src/jsdtoa.h
+++ b/js/src/jsdtoa.h
@@ -31,10 +31,10 @@ js_DestroyDtoaState(DtoaState *state);
  * scan. If no number can be formed, *se receives a pointer to the first
  * unparseable character in s00, and zero is returned.
  *
- * *err is set to zero on success; it's set to JS_DTOA_ERANGE on range
- * errors and JS_DTOA_ENOMEM on memory failure.
+ * On overflow, this function returns infinity and does not indicate an error.
+ *
+ * *err is set to zero on success; it's set to JS_DTOA_ENOMEM on memory failure.
  */
-#define JS_DTOA_ERANGE 1
 #define JS_DTOA_ENOMEM 2
 double
 js_strtod_harder(DtoaState *state, const char *s00, char **se, int *err);
diff --git a/js/src/jsnum.cpp b/js/src/jsnum.cpp
index 61a3dcb4d92..aed1dce0b9e 100644
--- a/js/src/jsnum.cpp
+++ b/js/src/jsnum.cpp
@@ -79,8 +79,6 @@ ComputeAccurateDecimalInteger(ThreadSafeContext *cx,
         js_free(cstr);
         return false;
     }
-    if (err == JS_DTOA_ERANGE && *dp == HUGE_VAL)
-        *dp = js_PositiveInfinity;
     js_free(cstr);
     return true;
 }
@@ -1718,10 +1716,6 @@ js_strtod(ThreadSafeContext *cx, const jschar *s, const jschar *send,
     } else {
         int err;
         d = js_strtod_harder(cx->dtoaState(), cstr, &estr, &err);
-        if (d == HUGE_VAL)
-            d = js_PositiveInfinity;
-        else if (d == -HUGE_VAL)
-            d = js_NegativeInfinity;
     }
 
     i = estr - cstr;

From 2322f0dca349a71a3175a94bb58da3247c8a48bc Mon Sep 17 00:00:00 2001
From: Andy Wingo 
Date: Wed, 4 Sep 2013 13:20:48 -0400
Subject: [PATCH 094/171] Bug 907744 - Implement iterator result boxing in ES6
 generators. r=jorendorff

This patchset causes the bytecode emitter to yield boxed return values
in ES6 generators, of the form { value: foo, done: bool }.

If the generator function does not end in a return, the compiler inserts
the equivalent of a "return { value: undefined, done:true }" statement
at the end.

When an ES6 generator finishes, it does so with {done:true} instead of
throwing a StopIteration.

This patch also ports lib/asserts.js to "default version" JS, and ports
ecma_6/Generators to use it.
---
 js/src/frontend/BytecodeEmitter.cpp         |  89 +++
 js/src/jit-test/lib/asserts.js              | 167 +-----
 js/src/js.msg                               |   2 +-
 js/src/jsiter.cpp                           | 268 ++++-----
 js/src/jsiter.h                             |   7 -
 js/src/tests/ecma_6/Generators/iteration.js | 615 ++++++++++++++++++++
 js/src/tests/ecma_6/Generators/objects.js   |  52 ++
 js/src/tests/ecma_6/Generators/runtime.js   |  29 +-
 js/src/tests/ecma_6/Generators/shell.js     |  11 +
 js/src/tests/ecma_6/shell.js                | 176 ++++++
 js/src/vm/CommonPropertyNames.h             |   1 +
 11 files changed, 1084 insertions(+), 333 deletions(-)
 create mode 100644 js/src/tests/ecma_6/Generators/iteration.js
 create mode 100644 js/src/tests/ecma_6/Generators/objects.js

diff --git a/js/src/frontend/BytecodeEmitter.cpp b/js/src/frontend/BytecodeEmitter.cpp
index bf3109cd9d0..736e05e0299 100644
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -1790,6 +1790,62 @@ BytecodeEmitter::reportStrictModeError(ParseNode *pn, unsigned errorNumber, ...)
     return result;
 }
 
+static bool
+IteratorResultShape(ExclusiveContext *cx, BytecodeEmitter *bce, unsigned *shape)
+{
+    RootedObject obj(cx);
+    gc::AllocKind kind = GuessObjectGCKind(2);
+    obj = NewBuiltinClassInstance(cx, &JSObject::class_, kind);
+    if (!obj)
+        return false;
+
+    Rooted value_id(cx, AtomToId(cx->names().value));
+    Rooted done_id(cx, AtomToId(cx->names().done));
+    RootedValue undefined(cx, UndefinedValue());
+    if (!DefineNativeProperty(cx, obj, value_id, undefined, NULL, NULL, JSPROP_ENUMERATE, 0, 0))
+        return false;
+    if (!DefineNativeProperty(cx, obj, done_id, undefined, NULL, NULL, JSPROP_ENUMERATE, 0, 0))
+        return false;
+
+    ObjectBox *objbox = bce->parser->newObjectBox(obj);
+    if (!objbox)
+        return false;
+
+    *shape = bce->objectList.add(objbox);
+
+    return true;
+}
+
+static bool
+EmitPrepareIteratorResult(ExclusiveContext *cx, BytecodeEmitter *bce)
+{
+    unsigned shape;
+    if (!IteratorResultShape(cx, bce, &shape))
+        return false;
+    return EmitIndex32(cx, JSOP_NEWOBJECT, shape, bce);
+}
+
+static bool
+EmitFinishIteratorResult(ExclusiveContext *cx, BytecodeEmitter *bce, bool done)
+{
+    jsatomid value_id;
+    if (!bce->makeAtomIndex(cx->names().value, &value_id))
+        return UINT_MAX;
+    jsatomid done_id;
+    if (!bce->makeAtomIndex(cx->names().done, &done_id))
+        return UINT_MAX;
+
+    if (!EmitIndex32(cx, JSOP_INITPROP, value_id, bce))
+        return false;
+    if (Emit1(cx, bce, done ? JSOP_TRUE : JSOP_FALSE) < 0)
+        return false;
+    if (!EmitIndex32(cx, JSOP_INITPROP, done_id, bce))
+        return false;
+    if (Emit1(cx, bce, JSOP_ENDINIT) < 0)
+        return false;
+    return true;
+}
+
 static bool
 EmitNameOp(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, bool callContext)
 {
@@ -2573,6 +2629,21 @@ frontend::EmitFunctionScript(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNo
     if (!EmitTree(cx, bce, body))
         return false;
 
+    // If we fall off the end of an ES6 generator, return a boxed iterator
+    // result object of the form { value: undefined, done: true }.
+    if (bce->sc->isFunctionBox() && bce->sc->asFunctionBox()->isStarGenerator()) {
+        if (!EmitPrepareIteratorResult(cx, bce))
+            return false;
+        if (Emit1(cx, bce, JSOP_UNDEFINED) < 0)
+            return false;
+        if (!EmitFinishIteratorResult(cx, bce, true))
+            return false;
+
+        // No need to check for finally blocks, etc as in EmitReturn.
+        if (Emit1(cx, bce, JSOP_RETURN) < 0)
+            return false;
+    }
+
     /*
      * Always end the script with a JSOP_STOP. Some other parts of the codebase
      * depend on this opcode, e.g. js_InternalInterpret.
@@ -4772,6 +4843,11 @@ EmitReturn(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
     if (!UpdateSourceCoordNotes(cx, bce, pn->pn_pos.begin))
         return false;
 
+    if (bce->sc->isFunctionBox() && bce->sc->asFunctionBox()->isStarGenerator()) {
+        if (!EmitPrepareIteratorResult(cx, bce))
+            return false;
+    }
+
     /* Push a return value */
     if (ParseNode *pn2 = pn->pn_kid) {
         if (!EmitTree(cx, bce, pn2))
@@ -4782,6 +4858,11 @@ EmitReturn(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
             return false;
     }
 
+    if (bce->sc->isFunctionBox() && bce->sc->asFunctionBox()->isStarGenerator()) {
+        if (!EmitFinishIteratorResult(cx, bce, true))
+            return false;
+    }
+
     /*
      * EmitNonLocalJumpFixup may add fixup bytecode to close open try
      * blocks having finally clauses and to exit intermingled let blocks.
@@ -5793,6 +5874,10 @@ frontend::EmitTree(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
 
       case PNK_YIELD:
         JS_ASSERT(bce->sc->isFunctionBox());
+        if (bce->sc->asFunctionBox()->isStarGenerator()) {
+            if (!EmitPrepareIteratorResult(cx, bce))
+                return false;
+        }
         if (pn->pn_kid) {
             if (!EmitTree(cx, bce, pn->pn_kid))
                 return false;
@@ -5800,6 +5885,10 @@ frontend::EmitTree(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
             if (Emit1(cx, bce, JSOP_UNDEFINED) < 0)
                 return false;
         }
+        if (bce->sc->asFunctionBox()->isStarGenerator()) {
+            if (!EmitFinishIteratorResult(cx, bce, false))
+                return false;
+        }
         if (pn->pn_hidden && NewSrcNote(cx, bce, SRC_HIDDEN) < 0)
             return false;
         if (Emit1(cx, bce, JSOP_YIELD) < 0)
diff --git a/js/src/jit-test/lib/asserts.js b/js/src/jit-test/lib/asserts.js
index 00901f4ecab..a8736454221 100644
--- a/js/src/jit-test/lib/asserts.js
+++ b/js/src/jit-test/lib/asserts.js
@@ -3,41 +3,7 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 
-if (typeof assertThrowsInstanceOf === 'undefined') {
-    var assertThrowsInstanceOf = function assertThrowsInstanceOf(f, ctor, msg) {
-        var fullmsg;
-        try {
-            f();
-        } catch (exc) {
-            if (exc instanceof ctor)
-                return;
-            fullmsg = "Assertion failed: expected exception " + ctor.name + ", got " + exc;
-        }
-        if (fullmsg === undefined)
-            fullmsg = "Assertion failed: expected exception " + ctor.name + ", no exception thrown";
-        if (msg !== undefined)
-            fullmsg += " - " + msg;
-        throw new Error(fullmsg);
-    };
-}
-
-if (typeof assertThrowsValue === 'undefined') {
-    var assertThrowsValue = function assertThrowsValue(f, val, msg) {
-        var fullmsg;
-        try {
-            f();
-        } catch (exc) {
-            if ((exc === val) === (val === val) && (val !== 0 || 1 / exc === 1 / val))
-                return;
-            fullmsg = "Assertion failed: expected exception " + val + ", got " + exc;
-        }
-        if (fullmsg === undefined)
-            fullmsg = "Assertion failed: expected exception " + val + ", no exception thrown";
-        if (msg !== undefined)
-            fullmsg += " - " + msg;
-        throw new Error(fullmsg);
-    };
-}
+load(libdir + "../../tests/ecma_6/shell.js");
 
 if (typeof assertWarning === 'undefined') {
     var assertWarning = function assertWarning(f, errorClass, msg) {
@@ -99,134 +65,3 @@ if (typeof assertNoWarning === 'undefined') {
         }
     };
 }
-
-if (typeof assertDeepEq === 'undefined') {
-    let call = Function.prototype.call,
-        Map_ = Map,
-        Error_ = Error,
-        Map_has = call.bind(Map.prototype.has),
-        Map_get = call.bind(Map.prototype.get),
-        Map_set = call.bind(Map.prototype.set),
-        Object_toString = call.bind(Object.prototype.toString),
-        Function_toString = call.bind(Function.prototype.toString),
-        Object_getPrototypeOf = Object.getPrototypeOf,
-        Object_hasOwnProperty = call.bind(Object.prototype.hasOwnProperty),
-        Object_getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor,
-        Object_isExtensible = Object.isExtensible,
-        Object_getOwnPropertyNames = Object.getOwnPropertyNames,
-        uneval_ = uneval;
-
-    // Return true iff ES6 Type(v) isn't Object.
-    // Note that `typeof document.all === "undefined"`.
-    let isPrimitive = v =>
-        v === null ||
-        v === undefined ||
-        typeof v === "boolean" ||
-        typeof v === "number" ||
-        typeof v === "string" ||
-        typeof v === "symbol";
-
-    let assertSameValue = (a, b, msg) => {
-        try {
-            assertEq(a, b);
-        } catch (exc) {
-            throw new Error(exc.message + (msg ? " " + msg : ""));
-        }
-    };
-
-    let assertSameClass = (a, b, msg) => {
-        var ac = Object_toString(a), bc = Object_toString(b);
-        assertSameValue(ac, bc, msg);
-        switch (ac) {
-        case "[object Function]":
-            assertSameValue(Function_toString(a), Function_toString(b), msg);
-        }
-    };
-
-    let at = (prevmsg, segment) => prevmsg ? prevmsg + segment : "at _" + segment;
-
-    // Assert that the arguments a and b are thoroughly structurally equivalent.
-    //
-    // For the sake of speed, we cut a corner:
-    //        var x = {}, y = {}, ax = [x];
-    //        assertDeepEq([ax, x], [ax, y]);  // passes (?!)
-    //
-    // Technically this should fail, since the two object graphs are different.
-    // (The graph of [ax, y] contains one more object than the graph of [ax, x].)
-    //
-    // To get technically correct behavior, pass {strictEquivalence: true}.
-    // This is slower because we have to walk the entire graph, and Object.prototype
-    // is big.
-    //
-    var assertDeepEq = function assertDeepEq(a, b, options) {
-        let strictEquivalence = options ? options.strictEquivalence : false;
-
-        let assertSameProto = (a, b, msg) => {
-            check(Object_getPrototypeOf(a), Object_getPrototypeOf(b), at(msg, ".__proto__"))
-        };
-
-        let failPropList = (na, nb, msg) => {
-            throw Error_("got own properties " + uneval_(na) + ", expected " + uneval_(nb) +
-                         (msg ? " " + msg : ""));
-        }
-
-        let assertSameProps = (a, b, msg) => {
-            var na = Object_getOwnPropertyNames(a),
-                nb = Object_getOwnPropertyNames(b);
-            if (na.length !== nb.length)
-                failPropList(na, nb, msg);
-            for (var i = 0; i < na.length; i++) {
-                var name = na[i];
-                if (name !== nb[i])
-                    failPropList(na, nb, msg);
-                var da = Object_getOwnPropertyDescriptor(a, name),
-                    db = Object_getOwnPropertyDescriptor(b, name);
-                var pmsg = at(msg, /^[_$A-Za-z0-9]+$/.test(name)
-                                   ? /0|[1-9][0-9]*/.test(name) ? "[" + name + "]" : "." + name
-                                   : "[" + uneval_(name) + "]");
-                assertSameValue(da.configurable, db.configurable, at(pmsg, ".[[Configurable]]"));
-                assertSameValue(da.enumerable, db.enumerable, at(pmsg, ".[[Enumerable]]"));
-                if (Object_hasOwnProperty(da, "value")) {
-                    if (!Object_hasOwnProperty(db, "value"))
-                        throw Error_("got data property, expected accessor property" + pmsg);
-                    check(da.value, db.value, pmsg);
-                } else {
-                    if (Object_hasOwnProperty(db, "value"))
-                        throw Error_("got accessor property, expected data property" + pmsg);
-                    check(da.get, db.get, at(pmsg, ".[[Get]]"));
-                    check(da.set, db.set, at(pmsg, ".[[Set]]"));
-                }
-            }
-        };
-
-        var ab = Map_();
-        var bpath = Map_();
-
-        let check = (a, b, path) => {
-            if (isPrimitive(a)) {
-                assertSameValue(a, b, path);
-            } else if (isPrimitive(b)) {
-                throw Error_("got " + Object_toString(a) + ", expected " + uneval_(b) + " " + path);
-            } else if (Map_has(ab, a)) {
-                assertSameValue(Map_get(ab, a), b, path);
-            } else if (Map_has(bpath, b)) {
-                var bPrevPath = Map_get(bpath, b) || "_";
-                throw Error_("got distinct objects " + at(path, "") + " and " + at(bPrevPath, "") +
-                             ", expected the same object both places");
-            } else {
-                Map_set(ab, a, b);
-                Map_set(bpath, b, path);
-                if (a !== b || strictEquivalence) {
-                    assertSameClass(a, b, path);
-                    assertSameProto(a, b, path);
-                    assertSameProps(a, b, path);
-                    assertSameValue(Object_isExtensible(a),
-                                    Object_isExtensible(b),
-                                    at(path, ".[[Extensible]]"));
-                }
-            }
-        }
-
-        check(a, b, "");
-    };
-}
diff --git a/js/src/js.msg b/js/src/js.msg
index 4a7524ec35f..49d2763a1e2 100644
--- a/js/src/js.msg
+++ b/js/src/js.msg
@@ -409,6 +409,6 @@ MSG_DEF(JSMSG_BINARYDATA_NOT_BINARYSTRUCT,   355, 1, JSEXN_TYPEERR, "{0} is not
 MSG_DEF(JSMSG_BINARYDATA_SUBARRAY_INTEGER_ARG, 356, 1, JSEXN_ERR, "argument {0} must be an integer")
 MSG_DEF(JSMSG_BINARYDATA_STRUCTTYPE_EMPTY_DESCRIPTOR, 357, 0, JSEXN_ERR, "field descriptor cannot be empty")
 MSG_DEF(JSMSG_BINARYDATA_STRUCTTYPE_BAD_FIELD, 358, 1, JSEXN_ERR, "field {0} is not a valid BinaryData Type descriptor")
-MSG_DEF(JSMSG_ES6_UNIMPLEMENTED,      359, 0, JSEXN_ERR, "ES6 functionality not yet implemented")
+MSG_DEF(JSMSG_GENERATOR_FINISHED,     359, 0, JSEXN_TYPEERR, "generator has already finished")
 MSG_DEF(JSMSG_BINARYDATA_TOO_BIG, 360, 0, JSEXN_ERR, "Type is too large to allocate")
 MSG_DEF(JSMSG_BINARYDATA_NOT_TYPE_OBJECT, 361, 0, JSEXN_ERR, "Expected a type object")
diff --git a/js/src/jsiter.cpp b/js/src/jsiter.cpp
index 1ead377f523..3581081e314 100644
--- a/js/src/jsiter.cpp
+++ b/js/src/jsiter.cpp
@@ -999,24 +999,6 @@ js::ValueToIterator(JSContext *cx, unsigned flags, MutableHandleValue vp)
     return GetIterator(cx, obj, flags, vp);
 }
 
-bool
-IsStarGeneratorObject(HandleValue v)
-{
-    return v.isObject() && v.toObject().is();
-}
-
-bool
-IsLegacyGeneratorObject(HandleValue v)
-{
-    return v.isObject() && v.toObject().is();
-}
-
-bool
-IsGeneratorObject(HandleValue v)
-{
-    return IsLegacyGeneratorObject(v) || IsStarGeneratorObject(v);
-}
-
 bool
 js::CloseIterator(JSContext *cx, HandleObject obj)
 {
@@ -1339,26 +1321,15 @@ Class StopIterationObject::class_ = {
 
 /*** Generators **********************************************************************************/
 
-static JSGenerator*
-GetGenerator(JSObject *obj)
-{
-    if (obj->is())
-        return obj->as().getGenerator();
-    JS_ASSERT(obj->is());
-    return obj->as().getGenerator();
-}
-
+template
 static void
-generator_finalize(FreeOp *fop, JSObject *obj)
+FinalizeGenerator(FreeOp *fop, JSObject *obj)
 {
-    JSGenerator *gen = GetGenerator(obj);
-    if (!gen)
-        return;
-
-    /*
-     * gen is open when a script has not called its close method while
-     * explicitly manipulating it.
-     */
+    JS_ASSERT(obj->is());
+    JSGenerator *gen = obj->as().getGenerator();
+    JS_ASSERT(gen);
+    // gen is open when a script has not called its close method while
+    // explicitly manipulating it.
     JS_ASSERT(gen->state == JSGEN_NEWBORN ||
               gen->state == JSGEN_CLOSED ||
               gen->state == JSGEN_OPEN);
@@ -1404,8 +1375,8 @@ GeneratorWriteBarrierPost(JSContext *cx, JSGenerator *gen)
  * stack or closed. Barriers when copying onto the stack or closing preserve
  * gc invariants.
  */
-bool
-js::GeneratorHasMarkableFrame(JSGenerator *gen)
+static bool
+GeneratorHasMarkableFrame(JSGenerator *gen)
 {
     return gen->state == JSGEN_NEWBORN || gen->state == JSGEN_OPEN;
 }
@@ -1432,6 +1403,17 @@ SetGeneratorClosed(JSContext *cx, JSGenerator *gen)
 #endif
 }
 
+template
+static void
+TraceGenerator(JSTracer *trc, JSObject *obj)
+{
+    JS_ASSERT(obj->is());
+    JSGenerator *gen = obj->as().getGenerator();
+    JS_ASSERT(gen);
+    if (GeneratorHasMarkableFrame(gen))
+        MarkGeneratorFrame(trc, gen);
+}
+
 GeneratorState::GeneratorState(JSContext *cx, JSGenerator *gen, JSGeneratorState futureState)
   : RunState(cx, Generator, gen->fp->script()),
     cx_(cx),
@@ -1472,17 +1454,6 @@ GeneratorState::pushInterpreterFrame(JSContext *cx, FrameGuard *)
     return gen_->fp;
 }
 
-static void
-generator_trace(JSTracer *trc, JSObject *obj)
-{
-    JSGenerator *gen = GetGenerator(obj);
-    if (!gen)
-        return;
-
-    if (GeneratorHasMarkableFrame(gen))
-        MarkGeneratorFrame(trc, gen);
-}
-
 Class LegacyGeneratorObject::class_ = {
     "Generator",
     JSCLASS_HAS_PRIVATE | JSCLASS_IMPLEMENTS_BARRIERS,
@@ -1493,12 +1464,12 @@ Class LegacyGeneratorObject::class_ = {
     JS_EnumerateStub,
     JS_ResolveStub,
     JS_ConvertStub,
-    generator_finalize,
+    FinalizeGenerator,
     NULL,                    /* checkAccess */
     NULL,                    /* call        */
     NULL,                    /* hasInstance */
     NULL,                    /* construct   */
-    generator_trace,
+    TraceGenerator,
     {
         NULL,                /* outerObject    */
         NULL,                /* innerObject    */
@@ -1516,12 +1487,12 @@ Class StarGeneratorObject::class_ = {
     JS_EnumerateStub,
     JS_ResolveStub,
     JS_ConvertStub,
-    generator_finalize,
+    FinalizeGenerator,
     NULL,                    /* checkAccess */
     NULL,                    /* call        */
     NULL,                    /* hasInstance */
     NULL,                    /* construct   */
-    generator_trace,
+    TraceGenerator,
     {
         NULL,                /* outerObject    */
         NULL,                /* innerObject    */
@@ -1626,8 +1597,11 @@ typedef enum JSGeneratorOp {
  */
 static bool
 SendToGenerator(JSContext *cx, JSGeneratorOp op, HandleObject obj,
-                JSGenerator *gen, HandleValue arg)
+                JSGenerator *gen, HandleValue arg, GeneratorKind generatorKind,
+                MutableHandleValue rval)
 {
+    JS_ASSERT(generatorKind == LegacyGenerator || generatorKind == StarGenerator);
+
     if (gen->state == JSGEN_RUNNING || gen->state == JSGEN_CLOSING) {
         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NESTING_GENERATOR);
         return false;
@@ -1658,6 +1632,7 @@ SendToGenerator(JSContext *cx, JSGeneratorOp op, HandleObject obj,
 
       default:
         JS_ASSERT(op == JSGENOP_CLOSE);
+        JS_ASSERT(generatorKind == LegacyGenerator);
         cx->setPendingException(MagicValue(JS_GENERATOR_CLOSING));
         futureState = JSGEN_CLOSING;
         break;
@@ -1681,45 +1656,72 @@ SendToGenerator(JSContext *cx, JSGeneratorOp op, HandleObject obj,
         gen->fp->clearYielding();
         gen->state = JSGEN_OPEN;
         GeneratorWriteBarrierPost(cx, gen);
+        rval.set(gen->fp->returnValue());
         return ok;
     }
 
-    gen->fp->clearReturnValue();
-    SetGeneratorClosed(cx, gen);
     if (ok) {
-        /* Returned, explicitly or by falling off the end. */
-        if (op == JSGENOP_CLOSE)
-            return true;
-        return js_ThrowStopIteration(cx);
+        if (generatorKind == StarGenerator) {
+            // Star generators return a {value:FOO, done:true} object.
+            rval.set(gen->fp->returnValue());
+        } else {
+            JS_ASSERT(generatorKind == LegacyGenerator);
+
+            // Otherwise we discard the return value and throw a StopIteration
+            // if needed.
+            rval.setUndefined();
+            if (op != JSGENOP_CLOSE)
+                ok = js_ThrowStopIteration(cx);
+        }
     }
 
-    /*
-     * An error, silent termination by operation callback or an exception.
-     * Propagate the condition to the caller.
-     */
-    return false;
-}
-
-static bool
-CloseLegacyGenerator(JSContext *cx, HandleObject obj)
-{
-    JS_ASSERT(obj->is());
-
-    JSGenerator *gen = GetGenerator(obj);
-    if (gen->state == JSGEN_CLOSED)
-        return true;
-
-    return SendToGenerator(cx, JSGENOP_CLOSE, obj, gen, JS::UndefinedHandleValue);
+    SetGeneratorClosed(cx, gen);
+    return ok;
 }
 
 JS_ALWAYS_INLINE bool
-generator_next_impl(JSContext *cx, CallArgs args)
+star_generator_next(JSContext *cx, CallArgs args)
 {
-    JS_ASSERT(IsGeneratorObject(args.thisv()));
+    RootedObject thisObj(cx, &args.thisv().toObject());
+    JSGenerator *gen = thisObj->as().getGenerator();
 
+    if (gen->state == JSGEN_CLOSED) {
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_GENERATOR_FINISHED);
+        return false;
+    }
+
+    if (gen->state == JSGEN_NEWBORN && args.hasDefined(0)) {
+        RootedValue val(cx, args[0]);
+        js_ReportValueError(cx, JSMSG_BAD_GENERATOR_SEND,
+                            JSDVG_SEARCH_STACK, val, NullPtr());
+        return false;
+    }
+
+    return SendToGenerator(cx, JSGENOP_SEND, thisObj, gen, args.get(0), StarGenerator,
+                           args.rval());
+}
+
+JS_ALWAYS_INLINE bool
+star_generator_throw(JSContext *cx, CallArgs args)
+{
     RootedObject thisObj(cx, &args.thisv().toObject());
 
-    JSGenerator *gen = GetGenerator(thisObj);
+    JSGenerator *gen = thisObj->as().getGenerator();
+    if (gen->state == JSGEN_CLOSED) {
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_GENERATOR_FINISHED);
+        return false;
+    }
+
+    return SendToGenerator(cx, JSGENOP_THROW, thisObj, gen, args.get(0), StarGenerator,
+                           args.rval());
+}
+
+JS_ALWAYS_INLINE bool
+legacy_generator_next(JSContext *cx, CallArgs args)
+{
+    RootedObject thisObj(cx, &args.thisv().toObject());
+
+    JSGenerator *gen = thisObj->as().getGenerator();
     if (gen->state == JSGEN_CLOSED)
         return js_ThrowStopIteration(cx);
 
@@ -1730,96 +1732,94 @@ generator_next_impl(JSContext *cx, CallArgs args)
         return false;
     }
 
-    if (!SendToGenerator(cx, JSGENOP_SEND, thisObj, gen, args.get(0)))
-        return false;
-
-    args.rval().set(gen->fp->returnValue());
-    return true;
-}
-
-bool
-generator_next(JSContext *cx, unsigned argc, Value *vp)
-{
-    CallArgs args = CallArgsFromVp(argc, vp);
-    return CallNonGenericMethod(cx, args);
+    return SendToGenerator(cx, JSGENOP_SEND, thisObj, gen, args.get(0), LegacyGenerator,
+                           args.rval());
 }
 
 JS_ALWAYS_INLINE bool
-generator_throw_impl(JSContext *cx, CallArgs args)
+legacy_generator_throw(JSContext *cx, CallArgs args)
 {
-    JS_ASSERT(IsGeneratorObject(args.thisv()));
-
     RootedObject thisObj(cx, &args.thisv().toObject());
 
-    JSGenerator *gen = GetGenerator(thisObj);
+    JSGenerator *gen = thisObj->as().getGenerator();
     if (gen->state == JSGEN_CLOSED) {
         cx->setPendingException(args.length() >= 1 ? args[0] : UndefinedValue());
         return false;
     }
 
-    if (!SendToGenerator(cx, JSGENOP_THROW, thisObj, gen, args.get(0)))
-        return false;
-
-    args.rval().set(gen->fp->returnValue());
-    return true;
+    return SendToGenerator(cx, JSGENOP_THROW, thisObj, gen, args.get(0), LegacyGenerator,
+                           args.rval());
 }
 
-bool
-generator_throw(JSContext *cx, unsigned argc, Value *vp)
+static bool
+CloseLegacyGenerator(JSContext *cx, HandleObject obj, MutableHandleValue rval)
 {
-    CallArgs args = CallArgsFromVp(argc, vp);
-    return CallNonGenericMethod(cx, args);
-}
+    JS_ASSERT(obj->is());
 
-JS_ALWAYS_INLINE bool
-generator_close_impl(JSContext *cx, CallArgs args)
-{
-    JS_ASSERT(IsLegacyGeneratorObject(args.thisv()));
+    JSGenerator *gen = obj->as().getGenerator();
 
-    RootedObject thisObj(cx, &args.thisv().toObject());
-
-    JSGenerator *gen = GetGenerator(thisObj);
     if (gen->state == JSGEN_CLOSED) {
-        args.rval().setUndefined();
+        rval.setUndefined();
         return true;
     }
 
     if (gen->state == JSGEN_NEWBORN) {
         SetGeneratorClosed(cx, gen);
-        args.rval().setUndefined();
+        rval.setUndefined();
         return true;
     }
 
-    if (!SendToGenerator(cx, JSGENOP_CLOSE, thisObj, gen, JS::UndefinedHandleValue))
-        return false;
-
-    args.rval().setUndefined();
-    return true;
+    return SendToGenerator(cx, JSGENOP_CLOSE, obj, gen, JS::UndefinedHandleValue, LegacyGenerator,
+                           rval);
 }
 
-bool
-generator_close(JSContext *cx, unsigned argc, Value *vp)
+static bool
+CloseLegacyGenerator(JSContext *cx, HandleObject obj)
+{
+    RootedValue rval(cx);
+    return CloseLegacyGenerator(cx, obj, &rval);
+}
+
+JS_ALWAYS_INLINE bool
+legacy_generator_close(JSContext *cx, CallArgs args)
+{
+    RootedObject thisObj(cx, &args.thisv().toObject());
+
+    return CloseLegacyGenerator(cx, thisObj, args.rval());
+}
+
+template
+JS_ALWAYS_INLINE bool
+IsObjectOfType(HandleValue v)
+{
+    return v.isObject() && v.toObject().is();
+}
+
+template
+static bool
+NativeMethod(JSContext *cx, unsigned argc, Value *vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
-    return CallNonGenericMethod(cx, args);
+    return CallNonGenericMethod, Impl>(cx, args);
 }
 
 #define JSPROP_ROPERM   (JSPROP_READONLY | JSPROP_PERMANENT)
+#define JS_METHOD(name, T, impl, len, perms) JS_FN(name, (NativeMethod), len, perms)
 
-static const JSFunctionSpec legacy_generator_methods[] = {
-    JS_FN("iterator",  iterator_iterator,  0, 0),
-    JS_FN("next",      generator_next,     1,JSPROP_ROPERM),
-    // Send is exactly the same as next.
-    JS_FN("send",      generator_next,     1,JSPROP_ROPERM),
-    JS_FN("throw",     generator_throw,    1,JSPROP_ROPERM),
-    JS_FN("close",     generator_close,    0,JSPROP_ROPERM),
+static const JSFunctionSpec star_generator_methods[] = {
+    JS_FN("iterator", iterator_iterator, 0, 0),
+    JS_METHOD("next", StarGeneratorObject, star_generator_next, 1, JSPROP_ROPERM),
+    JS_METHOD("throw", StarGeneratorObject, star_generator_throw, 1, JSPROP_ROPERM),
     JS_FS_END
 };
 
-static const JSFunctionSpec star_generator_methods[] = {
-    JS_FN("iterator",  iterator_iterator,  0, 0),
-    JS_FN("next",      generator_next,     1,JSPROP_ROPERM),
-    JS_FN("throw",     generator_throw,    1,JSPROP_ROPERM),
+static const JSFunctionSpec legacy_generator_methods[] = {
+    JS_FN("iterator", iterator_iterator, 0, 0),
+    // "send" is an alias for "next".
+    JS_METHOD("next", LegacyGeneratorObject, legacy_generator_next, 1, JSPROP_ROPERM),
+    JS_METHOD("send", LegacyGeneratorObject, legacy_generator_next, 1, JSPROP_ROPERM),
+    JS_METHOD("throw", LegacyGeneratorObject, legacy_generator_throw, 1, JSPROP_ROPERM),
+    JS_METHOD("close", LegacyGeneratorObject, legacy_generator_close, 0, JSPROP_ROPERM),
     JS_FS_END
 };
 
diff --git a/js/src/jsiter.h b/js/src/jsiter.h
index b894a851f90..09efecd1824 100644
--- a/js/src/jsiter.h
+++ b/js/src/jsiter.h
@@ -351,13 +351,6 @@ struct JSGenerator
 extern JSObject *
 js_NewGenerator(JSContext *cx, const js::FrameRegs ®s);
 
-namespace js {
-
-bool
-GeneratorHasMarkableFrame(JSGenerator *gen);
-
-} /* namespace js */
-
 extern JSObject *
 js_InitIteratorClasses(JSContext *cx, js::HandleObject obj);
 
diff --git a/js/src/tests/ecma_6/Generators/iteration.js b/js/src/tests/ecma_6/Generators/iteration.js
new file mode 100644
index 00000000000..14b21143bd7
--- /dev/null
+++ b/js/src/tests/ecma_6/Generators/iteration.js
@@ -0,0 +1,615 @@
+// This file was written by Andy Wingo  and originally
+// contributed to V8 as generators-objects.js, available here:
+//
+// http://code.google.com/p/v8/source/browse/branches/bleeding_edge/test/mjsunit/harmony/generators-objects.js
+
+// Test aspects of the generator runtime.
+
+
+var GeneratorFunction = (function*(){yield 1;}).constructor;
+
+
+function TestGeneratorResultPrototype() {
+    function* g() { yield 1; }
+    var iter = g();
+    var result = iter.next();
+    assertIteratorResult(1, false, result);
+    result = iter.next();
+    assertIteratorResult(undefined, true, result);
+    assertThrowsInstanceOf(function() { iter.next() }, TypeError);
+}
+TestGeneratorResultPrototype();
+
+function TestGenerator(g, expected_values_for_next,
+                       send_val, expected_values_for_send) {
+    function testNext(thunk) {
+        var iter = thunk();
+        for (var i = 0; i < expected_values_for_next.length; i++) {
+            assertIteratorResult(expected_values_for_next[i],
+                                 i == expected_values_for_next.length - 1,
+                                 iter.next());
+        }
+        assertThrowsInstanceOf(function() { iter.next(); }, TypeError);
+    }
+    function testSend(thunk) {
+        var iter = thunk();
+        for (var i = 0; i < expected_values_for_send.length; i++) {
+            assertIteratorResult(expected_values_for_send[i],
+                                 i == expected_values_for_send.length - 1,
+                                 i ? iter.next(send_val) : iter.next());
+        }
+        assertThrowsInstanceOf(function() { iter.next(send_val); }, TypeError);
+    }
+    function testThrow(thunk) {
+        for (var i = 0; i < expected_values_for_next.length; i++) {
+            var iter = thunk();
+            for (var j = 0; j < i; j++) {
+                assertIteratorResult(expected_values_for_next[j],
+                                     j == expected_values_for_next.length - 1,
+                                     iter.next());
+            }
+            var Sentinel = function () {}
+            assertThrowsInstanceOf(function () { iter.throw(new Sentinel); }, Sentinel);
+            assertThrowsInstanceOf(function () { iter.next(); }, TypeError);
+        }
+    }
+
+    testNext(g);
+    testSend(g);
+    testThrow(g);
+
+    // FIXME: Implement yield*.  Bug 907738.
+    //
+    // testNext(function*() { return yield* g(); });
+    // testSend(function*() { return yield* g(); });
+    // testThrow(function*() { return yield* g(); });
+
+    if (g instanceof GeneratorFunction) {
+        testNext(function() { return new g(); });
+        testSend(function() { return new g(); });
+        testThrow(function() { return new g(); });
+    }
+}
+
+TestGenerator(function* g1() { },
+              [undefined],
+              "foo",
+              [undefined]);
+
+TestGenerator(function* g2() { yield 1; },
+              [1, undefined],
+              "foo",
+              [1, undefined]);
+
+TestGenerator(function* g3() { yield 1; yield 2; },
+              [1, 2, undefined],
+              "foo",
+              [1, 2, undefined]);
+
+TestGenerator(function* g4() { yield 1; yield 2; return 3; },
+              [1, 2, 3],
+              "foo",
+              [1, 2, 3]);
+
+TestGenerator(function* g5() { return 1; },
+              [1],
+              "foo",
+              [1]);
+
+TestGenerator(function* g6() { var x = yield 1; return x; },
+              [1, undefined],
+              "foo",
+              [1, "foo"]);
+
+TestGenerator(function* g7() { var x = yield 1; yield 2; return x; },
+              [1, 2, undefined],
+              "foo",
+              [1, 2, "foo"]);
+
+TestGenerator(function* g8() { for (var x = 0; x < 4; x++) { yield x; } },
+              [0, 1, 2, 3, undefined],
+              "foo",
+              [0, 1, 2, 3, undefined]);
+
+// Generator with arguments.
+TestGenerator(
+    function g9() {
+        return (function*(a, b, c, d) {
+            yield a; yield b; yield c; yield d;
+        })("fee", "fi", "fo", "fum");
+    },
+    ["fee", "fi", "fo", "fum", undefined],
+    "foo",
+    ["fee", "fi", "fo", "fum", undefined]);
+
+// Too few arguments.
+TestGenerator(
+    function g10() {
+        return (function*(a, b, c, d) {
+            yield a; yield b; yield c; yield d;
+        })("fee", "fi");
+    },
+    ["fee", "fi", undefined, undefined, undefined],
+    "foo",
+    ["fee", "fi", undefined, undefined, undefined]);
+
+// Too many arguments.
+TestGenerator(
+    function g11() {
+        return (function*(a, b, c, d) {
+            yield a; yield b; yield c; yield d;
+        })("fee", "fi", "fo", "fum", "I smell the blood of an Englishman");
+    },
+    ["fee", "fi", "fo", "fum", undefined],
+    "foo",
+    ["fee", "fi", "fo", "fum", undefined]);
+
+// The arguments object.
+TestGenerator(
+    function g12() {
+        return (function*(a, b, c, d) {
+            for (var i = 0; i < arguments.length; i++) {
+                yield arguments[i];
+            }
+        })("fee", "fi", "fo", "fum", "I smell the blood of an Englishman");
+    },
+    ["fee", "fi", "fo", "fum", "I smell the blood of an Englishman",
+     undefined],
+    "foo",
+    ["fee", "fi", "fo", "fum", "I smell the blood of an Englishman",
+     undefined]);
+
+// Access to captured free variables.
+TestGenerator(
+    function g13() {
+        return (function(a, b, c, d) {
+            return (function*() {
+                yield a; yield b; yield c; yield d;
+            })();
+        })("fee", "fi", "fo", "fum");
+    },
+    ["fee", "fi", "fo", "fum", undefined],
+    "foo",
+    ["fee", "fi", "fo", "fum", undefined]);
+
+// Abusing the arguments object.
+TestGenerator(
+    function g14() {
+        return (function*(a, b, c, d) {
+            arguments[0] = "Be he live";
+            arguments[1] = "or be he dead";
+            arguments[2] = "I'll grind his bones";
+            arguments[3] = "to make my bread";
+            yield a; yield b; yield c; yield d;
+        })("fee", "fi", "fo", "fum");
+    },
+    ["Be he live", "or be he dead", "I'll grind his bones", "to make my bread",
+     undefined],
+    "foo",
+    ["Be he live", "or be he dead", "I'll grind his bones", "to make my bread",
+     undefined]);
+
+// Abusing the arguments object: strict mode.
+TestGenerator(
+    function g15() {
+        return (function*(a, b, c, d) {
+            "use strict";
+            arguments[0] = "Be he live";
+            arguments[1] = "or be he dead";
+            arguments[2] = "I'll grind his bones";
+            arguments[3] = "to make my bread";
+            yield a; yield b; yield c; yield d;
+        })("fee", "fi", "fo", "fum");
+    },
+    ["fee", "fi", "fo", "fum", undefined],
+    "foo",
+    ["fee", "fi", "fo", "fum", undefined]);
+
+// GC.
+if (typeof gc == 'function') {
+    TestGenerator(function* g16() { yield "baz"; gc(); yield "qux"; },
+                  ["baz", "qux", undefined],
+                  "foo",
+                  ["baz", "qux", undefined]);
+}
+
+// Receivers.
+TestGenerator(
+    function g17() {
+        function* g() { yield this.x; yield this.y; }
+        var o = { start: g, x: 1, y: 2 };
+        return o.start();
+    },
+    [1, 2, undefined],
+    "foo",
+    [1, 2, undefined]);
+
+// FIXME: Capture the generator object as "this" in new g().  Bug 907742.
+// TestGenerator(
+//     function g18() {
+//         function* g() { yield this.x; yield this.y; }
+//         var iter = new g;
+//         iter.x = 1;
+//         iter.y = 2;
+//         return iter;
+//     },
+//     [1, 2, undefined],
+//     "foo",
+//     [1, 2, undefined]);
+
+TestGenerator(
+    function* g19() {
+        var x = 1;
+        yield x;
+        with({x:2}) { yield x; }
+        yield x;
+    },
+    [1, 2, 1, undefined],
+    "foo",
+    [1, 2, 1, undefined]);
+
+TestGenerator(
+    function* g20() { yield (1 + (yield 2) + 3); },
+    [2, NaN, undefined],
+    "foo",
+    [2, "1foo3", undefined]);
+
+TestGenerator(
+    function* g21() { return (1 + (yield 2) + 3); },
+    [2, NaN],
+    "foo",
+    [2, "1foo3"]);
+
+TestGenerator(
+    function* g22() { yield (1 + (yield 2) + 3); yield (4 + (yield 5) + 6); },
+    [2, NaN, 5, NaN, undefined],
+    "foo",
+    [2, "1foo3", 5, "4foo6", undefined]);
+
+TestGenerator(
+    function* g23() {
+        return (yield (1 + (yield 2) + 3)) + (yield (4 + (yield 5) + 6));
+    },
+    [2, NaN, 5, NaN, NaN],
+    "foo",
+    [2, "1foo3", 5, "4foo6", "foofoo"]);
+
+// Rewind a try context with and without operands on the stack.
+TestGenerator(
+    function* g24() {
+        try {
+            return (yield (1 + (yield 2) + 3)) + (yield (4 + (yield 5) + 6));
+        } catch (e) {
+            throw e;
+        }
+    },
+    [2, NaN, 5, NaN, NaN],
+    "foo",
+    [2, "1foo3", 5, "4foo6", "foofoo"]);
+
+// Yielding in a catch context, with and without operands on the stack.
+TestGenerator(
+    function* g25() {
+        try {
+            throw (yield (1 + (yield 2) + 3))
+        } catch (e) {
+            if (typeof e == 'object') throw e;
+            return e + (yield (4 + (yield 5) + 6));
+        }
+    },
+    [2, NaN, 5, NaN, NaN],
+    "foo",
+    [2, "1foo3", 5, "4foo6", "foofoo"]);
+
+// Generator function instances.
+TestGenerator(GeneratorFunction(),
+              [undefined],
+              "foo",
+              [undefined]);
+
+TestGenerator(new GeneratorFunction(),
+              [undefined],
+              "foo",
+              [undefined]);
+
+TestGenerator(GeneratorFunction('yield 1;'),
+              [1, undefined],
+              "foo",
+              [1, undefined]);
+
+TestGenerator(
+    function() { return GeneratorFunction('x', 'y', 'yield x + y;')(1, 2) },
+    [3, undefined],
+    "foo",
+    [3, undefined]);
+
+// Access to this with formal arguments.
+TestGenerator(
+    function () {
+        return ({ x: 42, g: function* (a) { yield this.x } }).g(0);
+    },
+    [42, undefined],
+    "foo",
+    [42, undefined]);
+
+/* FIXME: Implement yield*.  Bug 907738.
+
+// Test that yield* re-yields received results without re-boxing.
+function TestDelegatingYield() {
+    function results(results) {
+        var i = 0;
+        function next() {
+            return results[i++];
+        }
+        return { next: next }
+    }
+    function* yield_results(expected) {
+        return yield* results(expected);
+    }
+    function collect_results(iter) {
+        var ret = [];
+        var result;
+        do {
+            result = iter.next();
+            ret.push(result);
+        } while (!result.done);
+        return ret;
+    }
+    // We have to put a full result for the end, because the return will re-box.
+    var expected = [{value: 1}, 13, "foo", {value: 34, done: true}];
+
+    // Sanity check.
+    assertDeepEq(expected, collect_results(results(expected)));
+    assertDeepEq(expected, collect_results(yield_results(expected)));
+}
+TestDelegatingYield();
+*/
+
+function TestTryCatch(instantiate) {
+    function* g() { yield 1; try { yield 2; } catch (e) { yield e; } yield 3; }
+    function Sentinel() {}
+
+    function Test1(iter) {
+        assertIteratorResult(1, false, iter.next());
+        assertIteratorResult(2, false, iter.next());
+        assertIteratorResult(3, false, iter.next());
+        assertIteratorResult(undefined, true, iter.next());
+        assertThrowsInstanceOf(function() { iter.next(); }, TypeError);
+    }
+    Test1(instantiate(g));
+
+    function Test2(iter) {
+        assertThrowsInstanceOf(function() { iter.throw(new Sentinel); }, Sentinel);
+        assertThrowsInstanceOf(function() { iter.next(); }, TypeError);
+    }
+    Test2(instantiate(g));
+
+    function Test3(iter) {
+        assertIteratorResult(1, false, iter.next());
+        assertThrowsInstanceOf(function() { iter.throw(new Sentinel); }, Sentinel);
+        assertThrowsInstanceOf(function() { iter.next(); }, TypeError);
+    }
+    Test3(instantiate(g));
+
+    function Test4(iter) {
+        assertIteratorResult(1, false, iter.next());
+        assertIteratorResult(2, false, iter.next());
+        var exn = new Sentinel;
+        assertIteratorResult(exn, false, iter.throw(exn));
+        assertIteratorResult(3, false, iter.next());
+        assertIteratorResult(undefined, true, iter.next());
+        assertThrowsInstanceOf(function() { iter.next(); }, TypeError);
+    }
+    Test4(instantiate(g));
+
+    function Test5(iter) {
+        assertIteratorResult(1, false, iter.next());
+        assertIteratorResult(2, false, iter.next());
+        var exn = new Sentinel;
+        assertIteratorResult(exn, false, iter.throw(exn));
+        assertIteratorResult(3, false, iter.next());
+        assertThrowsInstanceOf(function() { iter.throw(new Sentinel); }, Sentinel);
+        assertThrowsInstanceOf(function() { iter.next(); }, TypeError);
+
+    }
+    Test5(instantiate(g));
+
+    function Test6(iter) {
+        assertIteratorResult(1, false, iter.next());
+        assertIteratorResult(2, false, iter.next());
+        var exn = new Sentinel;
+        assertIteratorResult(exn, false, iter.throw(exn));
+        assertThrowsInstanceOf(function() { iter.throw(new Sentinel); }, Sentinel);
+        assertThrowsInstanceOf(function() { iter.next(); }, TypeError);
+    }
+    Test6(instantiate(g));
+}
+TestTryCatch(function (g) { return g(); });
+// FIXME: Implement yield*.  Bug 907738.
+// TestTryCatch(function* (g) { return yield* g(); });
+
+function TestTryFinally(instantiate) {
+    function* g() { yield 1; try { yield 2; } finally { yield 3; } yield 4; }
+    function Sentinel() {}
+    function Sentinel2() {}
+
+    function Test1(iter) {
+        assertIteratorResult(1, false, iter.next());
+        assertIteratorResult(2, false, iter.next());
+        assertIteratorResult(3, false, iter.next());
+        assertIteratorResult(4, false, iter.next());
+        assertIteratorResult(undefined, true, iter.next());
+        assertThrowsInstanceOf(function() { iter.next(); }, TypeError);
+    }
+    Test1(instantiate(g));
+
+    function Test2(iter) {
+        assertThrowsInstanceOf(function() { iter.throw(new Sentinel); }, Sentinel);
+        assertThrowsInstanceOf(function() { iter.next(); }, TypeError);
+    }
+    Test2(instantiate(g));
+
+    function Test3(iter) {
+        assertIteratorResult(1, false, iter.next());
+        assertThrowsInstanceOf(function() { iter.throw(new Sentinel); }, Sentinel);
+        assertThrowsInstanceOf(function() { iter.next(); }, TypeError);
+    }
+    Test3(instantiate(g));
+
+    function Test4(iter) {
+        assertIteratorResult(1, false, iter.next());
+        assertIteratorResult(2, false, iter.next());
+        assertIteratorResult(3, false, iter.throw(new Sentinel));
+        assertThrowsInstanceOf(function() { iter.next(); }, Sentinel);
+        assertThrowsInstanceOf(function() { iter.next(); }, TypeError);
+
+    }
+    Test4(instantiate(g));
+
+    function Test5(iter) {
+        assertIteratorResult(1, false, iter.next());
+        assertIteratorResult(2, false, iter.next());
+        assertIteratorResult(3, false, iter.throw(new Sentinel));
+        assertThrowsInstanceOf(function() { iter.throw(new Sentinel2); }, Sentinel2);
+        assertThrowsInstanceOf(function() { iter.next(); }, TypeError);
+    }
+    Test5(instantiate(g));
+
+    function Test6(iter) {
+        assertIteratorResult(1, false, iter.next());
+        assertIteratorResult(2, false, iter.next());
+        assertIteratorResult(3, false, iter.next());
+        assertThrowsInstanceOf(function() { iter.throw(new Sentinel); }, Sentinel);
+        assertThrowsInstanceOf(function() { iter.next(); }, TypeError);
+    }
+    Test6(instantiate(g));
+
+    function Test7(iter) {
+        assertIteratorResult(1, false, iter.next());
+        assertIteratorResult(2, false, iter.next());
+        assertIteratorResult(3, false, iter.next());
+        assertIteratorResult(4, false, iter.next());
+        assertThrowsInstanceOf(function() { iter.throw(new Sentinel); }, Sentinel);
+        assertThrowsInstanceOf(function() { iter.next(); }, TypeError);
+    }
+    Test7(instantiate(g));
+}
+TestTryFinally(function (g) { return g(); });
+// FIXME: Implement yield*.  Bug 907738.
+// TestTryFinally(function* (g) { return yield* g(); });
+
+function TestNestedTry(instantiate) {
+    function* g() {
+        try {
+            yield 1;
+            try { yield 2; } catch (e) { yield e; }
+            yield 3;
+        } finally {
+            yield 4;
+        }
+        yield 5;
+    }
+    function Sentinel() {}
+    function Sentinel2() {}
+
+    function Test1(iter) {
+        assertIteratorResult(1, false, iter.next());
+        assertIteratorResult(2, false, iter.next());
+        assertIteratorResult(3, false, iter.next());
+        assertIteratorResult(4, false, iter.next());
+        assertIteratorResult(5, false, iter.next());
+        assertIteratorResult(undefined, true, iter.next());
+        assertThrowsInstanceOf(function() { iter.next(); }, TypeError);
+    }
+    Test1(instantiate(g));
+
+    function Test2(iter) {
+        assertThrowsInstanceOf(function() { iter.throw(new Sentinel); }, Sentinel);
+        assertThrowsInstanceOf(function() { iter.next(); }, TypeError);
+    }
+    Test2(instantiate(g));
+
+    function Test3(iter) {
+        assertIteratorResult(1, false, iter.next());
+        assertIteratorResult(4, false, iter.throw(new Sentinel));
+        assertThrowsInstanceOf(function() { iter.next(); }, Sentinel);
+        assertThrowsInstanceOf(function() { iter.next(); }, TypeError);
+    }
+    Test3(instantiate(g));
+
+    function Test4(iter) {
+        assertIteratorResult(1, false, iter.next());
+        assertIteratorResult(4, false, iter.throw(new Sentinel));
+        assertThrowsInstanceOf(function() { iter.throw(new Sentinel2); }, Sentinel2);
+        assertThrowsInstanceOf(function() { iter.next(); }, TypeError);
+    }
+    Test4(instantiate(g));
+
+    function Test5(iter) {
+        assertIteratorResult(1, false, iter.next());
+        assertIteratorResult(2, false, iter.next());
+        var exn = new Sentinel;
+        assertIteratorResult(exn, false, iter.throw(exn));
+        assertIteratorResult(3, false, iter.next());
+        assertIteratorResult(4, false, iter.next());
+        assertIteratorResult(5, false, iter.next());
+        assertIteratorResult(undefined, true, iter.next());
+        assertThrowsInstanceOf(function() { iter.next(); }, TypeError);
+
+    }
+    Test5(instantiate(g));
+
+    function Test6(iter) {
+        assertIteratorResult(1, false, iter.next());
+        assertIteratorResult(2, false, iter.next());
+        var exn = new Sentinel;
+        assertIteratorResult(exn, false, iter.throw(exn));
+        assertIteratorResult(4, false, iter.throw(new Sentinel2));
+        assertThrowsInstanceOf(function() { iter.next(); }, Sentinel2);
+        assertThrowsInstanceOf(function() { iter.next(); }, TypeError);
+    }
+    Test6(instantiate(g));
+
+    function Test7(iter) {
+        assertIteratorResult(1, false, iter.next());
+        assertIteratorResult(2, false, iter.next());
+        var exn = new Sentinel;
+        assertIteratorResult(exn, false, iter.throw(exn));
+        assertIteratorResult(3, false, iter.next());
+        assertIteratorResult(4, false, iter.throw(new Sentinel2));
+        assertThrowsInstanceOf(function() { iter.next(); }, Sentinel2);
+        assertThrowsInstanceOf(function() { iter.next(); }, TypeError);
+
+    }
+    Test7(instantiate(g));
+
+    // That's probably enough.
+}
+TestNestedTry(function (g) { return g(); });
+// FIXME: Implement yield*.  Bug 907738.
+// TestNestedTry(function* (g) { return yield* g(); });
+
+function TestRecursion() {
+    function TestNextRecursion() {
+        function* g() { yield iter.next(); }
+        var iter = g();
+        return iter.next();
+    }
+    function TestSendRecursion() {
+        function* g() { yield iter.next(42); }
+        var iter = g();
+        return iter.next();
+    }
+    function TestThrowRecursion() {
+        function* g() { yield iter.throw(1); }
+        var iter = g();
+        return iter.next();
+    }
+    assertThrowsInstanceOf(TestNextRecursion, TypeError);
+    assertThrowsInstanceOf(TestSendRecursion, TypeError);
+    assertThrowsInstanceOf(TestThrowRecursion, TypeError);
+}
+TestRecursion();
+
+if (typeof reportCompare == "function")
+    reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/Generators/objects.js b/js/src/tests/ecma_6/Generators/objects.js
new file mode 100644
index 00000000000..aaeba185118
--- /dev/null
+++ b/js/src/tests/ecma_6/Generators/objects.js
@@ -0,0 +1,52 @@
+// This file was written by Andy Wingo  and originally
+// contributed to V8 as generators-objects.js, available here:
+//
+// http://code.google.com/p/v8/source/browse/branches/bleeding_edge/test/mjsunit/harmony/generators-objects.js
+
+// Test aspects of the generator runtime.
+
+// Test the properties and prototype of a generator object.
+function TestGeneratorObject() {
+  function* g() { yield 1; }
+
+  var iter = g();
+  assertEq(Object.getPrototypeOf(iter), g.prototype);
+  assertTrue(iter instanceof g);
+  assertEq(String(iter), "[object Generator]");
+  assertDeepEq(Object.getOwnPropertyNames(iter), []);
+  assertNotEq(g(), iter);
+
+  // g() is the same as new g().
+  iter = new g();
+  assertEq(Object.getPrototypeOf(iter), g.prototype);
+  assertTrue(iter instanceof g);
+  assertEq(String(iter), "[object Generator]");
+  assertDeepEq(Object.getOwnPropertyNames(iter), []);
+  assertNotEq(new g(), iter);
+}
+TestGeneratorObject();
+
+
+// Test the methods of generator objects.
+function TestGeneratorObjectMethods() {
+  function* g() { yield 1; }
+  var iter = g();
+
+  function TestNonGenerator(non_generator) {
+    assertThrowsInstanceOf(function() { iter.next.call(non_generator); }, TypeError);
+    assertThrowsInstanceOf(function() { iter.next.call(non_generator, 1); }, TypeError);
+    assertThrowsInstanceOf(function() { iter.throw.call(non_generator, 1); }, TypeError);
+    assertThrowsInstanceOf(function() { iter.close.call(non_generator); }, TypeError);
+  }
+
+  TestNonGenerator(1);
+  TestNonGenerator({});
+  TestNonGenerator(function(){});
+  TestNonGenerator(g);
+  TestNonGenerator(g.prototype);
+}
+TestGeneratorObjectMethods();
+
+
+if (typeof reportCompare == "function")
+    reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/Generators/runtime.js b/js/src/tests/ecma_6/Generators/runtime.js
index a55c0d1562c..93c6f746b2d 100644
--- a/js/src/tests/ecma_6/Generators/runtime.js
+++ b/js/src/tests/ecma_6/Generators/runtime.js
@@ -8,28 +8,7 @@
 // See http://people.mozilla.org/~jorendorff/es6-draft.html#sec-15.19.3.
 
 function assertSyntaxError(str) {
-    var msg;
-    var evil = eval;
-    try {
-        // Non-direct eval.
-        evil(str);
-    } catch (exc) {
-        if (exc instanceof SyntaxError)
-            return;
-        msg = "Assertion failed: expected SyntaxError, got " + exc;
-    }
-    if (msg === undefined)
-        msg = "Assertion failed: expected SyntaxError, but no exception thrown";
-    throw new Error(msg + " - " + str);
-}
-
-function assertFalse(a) { assertEq(a, false) }
-function assertTrue(a) { assertEq(a, true) }
-function assertNotEq(found, not_expected) { assertFalse(found === expected) }
-function assertArrayEq(found, expected) {
-    assertEq(found.length, expected.length);
-    for (var i = 0; i < expected.length; i++)
-        assertEq(found[i], expected[i]);
+    assertThrowsInstanceOf(Function(str), SyntaxError);
 }
 
 
@@ -49,7 +28,7 @@ function TestGeneratorFunctionInstance() {
     f_own_property_names.sort();
     g_own_property_names.sort();
 
-    assertArrayEq(f_own_property_names, g_own_property_names);
+    assertDeepEq(f_own_property_names, g_own_property_names);
     var i;
     for (i = 0; i < f_own_property_names.length; i++) {
         var prop = f_own_property_names[i];
@@ -92,7 +71,7 @@ function TestGeneratorObjectPrototype() {
     expected_property_names.sort();
     found_property_names.sort();
 
-    assertArrayEq(found_property_names, expected_property_names);
+    assertDeepEq(found_property_names, expected_property_names);
 }
 TestGeneratorObjectPrototype();
 
@@ -141,7 +120,7 @@ function TestPerGeneratorPrototype() {
     assertFalse(g.prototype instanceof Function);
     assertEq(typeof (g.prototype), "object");
 
-    assertArrayEq(Object.getOwnPropertyNames(g.prototype), []);
+    assertDeepEq(Object.getOwnPropertyNames(g.prototype), []);
 }
 TestPerGeneratorPrototype();
 
diff --git a/js/src/tests/ecma_6/Generators/shell.js b/js/src/tests/ecma_6/Generators/shell.js
index e69de29bb2d..d63297f0370 100644
--- a/js/src/tests/ecma_6/Generators/shell.js
+++ b/js/src/tests/ecma_6/Generators/shell.js
@@ -0,0 +1,11 @@
+/* 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/. */
+
+
+function assertFalse(a) { assertEq(a, false) }
+function assertTrue(a) { assertEq(a, true) }
+function assertNotEq(found, not_expected) { assertFalse(found === expected) }
+function assertIteratorResult(value, done, result) {
+    assertDeepEq(result, { value: value, done: done });
+}
diff --git a/js/src/tests/ecma_6/shell.js b/js/src/tests/ecma_6/shell.js
index e69de29bb2d..3b5fc1a6f58 100644
--- a/js/src/tests/ecma_6/shell.js
+++ b/js/src/tests/ecma_6/shell.js
@@ -0,0 +1,176 @@
+/* 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/. */
+
+
+if (typeof assertThrowsInstanceOf === 'undefined') {
+    var assertThrowsInstanceOf = function assertThrowsInstanceOf(f, ctor, msg) {
+        var fullmsg;
+        try {
+            f();
+        } catch (exc) {
+            if (exc instanceof ctor)
+                return;
+            fullmsg = "Assertion failed: expected exception " + ctor.name + ", got " + exc;
+        }
+        if (fullmsg === undefined)
+            fullmsg = "Assertion failed: expected exception " + ctor.name + ", no exception thrown";
+        if (msg !== undefined)
+            fullmsg += " - " + msg;
+        throw new Error(fullmsg);
+    };
+}
+
+if (typeof assertThrowsValue === 'undefined') {
+    var assertThrowsValue = function assertThrowsValue(f, val, msg) {
+        var fullmsg;
+        try {
+            f();
+        } catch (exc) {
+            if ((exc === val) === (val === val) && (val !== 0 || 1 / exc === 1 / val))
+                return;
+            fullmsg = "Assertion failed: expected exception " + val + ", got " + exc;
+        }
+        if (fullmsg === undefined)
+            fullmsg = "Assertion failed: expected exception " + val + ", no exception thrown";
+        if (msg !== undefined)
+            fullmsg += " - " + msg;
+        throw new Error(fullmsg);
+    };
+}
+
+if (typeof assertDeepEq === 'undefined') {
+    var assertDeepEq = (function(){
+        var call = Function.prototype.call,
+            Map_ = Map,
+            Error_ = Error,
+            Map_has = call.bind(Map.prototype.has),
+            Map_get = call.bind(Map.prototype.get),
+            Map_set = call.bind(Map.prototype.set),
+            Object_toString = call.bind(Object.prototype.toString),
+            Function_toString = call.bind(Function.prototype.toString),
+            Object_getPrototypeOf = Object.getPrototypeOf,
+            Object_hasOwnProperty = call.bind(Object.prototype.hasOwnProperty),
+            Object_getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor,
+            Object_isExtensible = Object.isExtensible,
+            Object_getOwnPropertyNames = Object.getOwnPropertyNames,
+            uneval_ = uneval;
+
+        // Return true iff ES6 Type(v) isn't Object.
+        // Note that `typeof document.all === "undefined"`.
+        function isPrimitive(v) {
+            return (v === null ||
+                    v === undefined ||
+                    typeof v === "boolean" ||
+                    typeof v === "number" ||
+                    typeof v === "string" ||
+                    typeof v === "symbol");
+        }
+
+        function assertSameValue(a, b, msg) {
+            try {
+                assertEq(a, b);
+            } catch (exc) {
+                throw new Error(exc.message + (msg ? " " + msg : ""));
+            }
+        }
+
+        function assertSameClass(a, b, msg) {
+            var ac = Object_toString(a), bc = Object_toString(b);
+            assertSameValue(ac, bc, msg);
+            switch (ac) {
+            case "[object Function]":
+                assertSameValue(Function_toString(a), Function_toString(b), msg);
+            }
+        }
+
+        function at(prevmsg, segment) {
+            return prevmsg ? prevmsg + segment : "at _" + segment;
+        }
+
+        // Assert that the arguments a and b are thoroughly structurally equivalent.
+        //
+        // For the sake of speed, we cut a corner:
+        //        var x = {}, y = {}, ax = [x];
+        //        assertDeepEq([ax, x], [ax, y]);  // passes (?!)
+        //
+        // Technically this should fail, since the two object graphs are different.
+        // (The graph of [ax, y] contains one more object than the graph of [ax, x].)
+        //
+        // To get technically correct behavior, pass {strictEquivalence: true}.
+        // This is slower because we have to walk the entire graph, and Object.prototype
+        // is big.
+        //
+        return function assertDeepEq(a, b, options) {
+            var strictEquivalence = options ? options.strictEquivalence : false;
+
+            function assertSameProto(a, b, msg) {
+                check(Object_getPrototypeOf(a), Object_getPrototypeOf(b), at(msg, ".__proto__"));
+            }
+
+            function failPropList(na, nb, msg) {
+                throw Error_("got own properties " + uneval_(na) + ", expected " + uneval_(nb) +
+                             (msg ? " " + msg : ""));
+            }
+
+            function assertSameProps(a, b, msg) {
+                var na = Object_getOwnPropertyNames(a),
+                    nb = Object_getOwnPropertyNames(b);
+                if (na.length !== nb.length)
+                    failPropList(na, nb, msg);
+                for (var i = 0; i < na.length; i++) {
+                    var name = na[i];
+                    if (name !== nb[i])
+                        failPropList(na, nb, msg);
+                    var da = Object_getOwnPropertyDescriptor(a, name),
+                        db = Object_getOwnPropertyDescriptor(b, name);
+                    var pmsg = at(msg, /^[_$A-Za-z0-9]+$/.test(name)
+                                       ? /0|[1-9][0-9]*/.test(name) ? "[" + name + "]" : "." + name
+                                       : "[" + uneval_(name) + "]");
+                    assertSameValue(da.configurable, db.configurable, at(pmsg, ".[[Configurable]]"));
+                    assertSameValue(da.enumerable, db.enumerable, at(pmsg, ".[[Enumerable]]"));
+                    if (Object_hasOwnProperty(da, "value")) {
+                        if (!Object_hasOwnProperty(db, "value"))
+                            throw Error_("got data property, expected accessor property" + pmsg);
+                        check(da.value, db.value, pmsg);
+                    } else {
+                        if (Object_hasOwnProperty(db, "value"))
+                            throw Error_("got accessor property, expected data property" + pmsg);
+                        check(da.get, db.get, at(pmsg, ".[[Get]]"));
+                        check(da.set, db.set, at(pmsg, ".[[Set]]"));
+                    }
+                }
+            };
+
+            var ab = Map_();
+            var bpath = Map_();
+
+            function check(a, b, path) {
+                if (isPrimitive(a)) {
+                    assertSameValue(a, b, path);
+                } else if (isPrimitive(b)) {
+                    throw Error_("got " + Object_toString(a) + ", expected " + uneval_(b) + " " + path);
+                } else if (Map_has(ab, a)) {
+                    assertSameValue(Map_get(ab, a), b, path);
+                } else if (Map_has(bpath, b)) {
+                    var bPrevPath = Map_get(bpath, b) || "_";
+                    throw Error_("got distinct objects " + at(path, "") + " and " + at(bPrevPath, "") +
+                                 ", expected the same object both places");
+                } else {
+                    Map_set(ab, a, b);
+                    Map_set(bpath, b, path);
+                    if (a !== b || strictEquivalence) {
+                        assertSameClass(a, b, path);
+                        assertSameProto(a, b, path);
+                        assertSameProps(a, b, path);
+                        assertSameValue(Object_isExtensible(a),
+                                        Object_isExtensible(b),
+                                        at(path, ".[[Extensible]]"));
+                    }
+                }
+            }
+
+            check(a, b, "");
+        };
+    })();
+}
diff --git a/js/src/vm/CommonPropertyNames.h b/js/src/vm/CommonPropertyNames.h
index 82d7c1fa5ee..916e4c63764 100644
--- a/js/src/vm/CommonPropertyNames.h
+++ b/js/src/vm/CommonPropertyNames.h
@@ -46,6 +46,7 @@
     macro(defineSetter, defineSetter, "__defineSetter__") \
     macro(delete, delete_, "delete") \
     macro(deleteProperty, deleteProperty, "deleteProperty") \
+    macro(done, done, "done") \
     macro(each, each, "each") \
     macro(elementType, elementType, "elementType") \
     macro(empty, empty, "") \

From a366778fcd06520471fbb9201f1e8b9d1359a146 Mon Sep 17 00:00:00 2001
From: Mike Hordecki 
Date: Wed, 4 Sep 2013 13:20:51 -0400
Subject: [PATCH 095/171] Bug 909672 - Make cross-compartment cloning possible
 with JS_StructuredClone. r=jorendorff

---
 js/src/jsapi-tests/moz.build               |  1 +
 js/src/jsapi-tests/testStructuredClone.cpp | 79 ++++++++++++++++++++++
 js/src/vm/StructuredClone.cpp              | 26 ++++++-
 3 files changed, 103 insertions(+), 3 deletions(-)
 create mode 100644 js/src/jsapi-tests/testStructuredClone.cpp

diff --git a/js/src/jsapi-tests/moz.build b/js/src/jsapi-tests/moz.build
index 56f2681e207..391846cacb2 100644
--- a/js/src/jsapi-tests/moz.build
+++ b/js/src/jsapi-tests/moz.build
@@ -60,6 +60,7 @@ CPP_SOURCES += [
     'testSetProperty.cpp',
     'testSourcePolicy.cpp',
     'testStringBuffer.cpp',
+    'testStructuredClone.cpp',
     'testToIntWidth.cpp',
     'testTrap.cpp',
     'testTypedArrays.cpp',
diff --git a/js/src/jsapi-tests/testStructuredClone.cpp b/js/src/jsapi-tests/testStructuredClone.cpp
new file mode 100644
index 00000000000..af0b7cf9d03
--- /dev/null
+++ b/js/src/jsapi-tests/testStructuredClone.cpp
@@ -0,0 +1,79 @@
+/* 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 "jsfriendapi.h"
+#include "js/StructuredClone.h"
+
+#include "jsapi-tests/tests.h"
+
+BEGIN_TEST(testStructuredClone_object)
+{
+    JS::RootedObject g1(cx, createGlobal());
+    JS::RootedObject g2(cx, createGlobal());
+    CHECK(g1);
+    CHECK(g2);
+
+    JS::RootedValue v1(cx);
+
+    {
+        JSAutoCompartment ac(cx, g1);
+        JS::RootedValue prop(cx, JS::Int32Value(1337));
+
+        v1 = JS::ObjectOrNullValue(JS_NewObject(cx, NULL, NULL, NULL));
+        CHECK(v1.isObject());
+        CHECK(JS_SetProperty(cx, &v1.toObject(), "prop", prop));
+    }
+
+    {
+        JSAutoCompartment ac(cx, g2);
+        JS::RootedValue v2(cx);
+
+        CHECK(JS_StructuredClone(cx, v1, v2.address(), NULL, NULL));
+        CHECK(v2.isObject());
+
+        JS::RootedValue prop(cx);
+        CHECK(JS_GetProperty(cx, &v2.toObject(), "prop", &prop));
+        CHECK(prop.isInt32());
+        CHECK(&v1.toObject() != &v2.toObject());
+        CHECK_EQUAL(prop.toInt32(), 1337);
+    }
+
+    return true;
+}
+END_TEST(testStructuredClone_object)
+
+BEGIN_TEST(testStructuredClone_string)
+{
+    JS::RootedObject g1(cx, createGlobal());
+    JS::RootedObject g2(cx, createGlobal());
+    CHECK(g1);
+    CHECK(g2);
+
+    JS::RootedValue v1(cx);
+
+    {
+        JSAutoCompartment ac(cx, g1);
+        JS::RootedValue prop(cx, JS::Int32Value(1337));
+
+        v1 = JS::StringValue(JS_NewStringCopyZ(cx, "Hello World!"));
+        CHECK(v1.isString());
+        CHECK(v1.toString());
+    }
+
+    {
+        JSAutoCompartment ac(cx, g2);
+        JS::RootedValue v2(cx);
+
+        CHECK(JS_StructuredClone(cx, v1, v2.address(), NULL, NULL));
+        CHECK(v2.isString());
+        CHECK(v2.toString());
+        
+        JS::RootedValue expected(cx, JS::StringValue(
+            JS_NewStringCopyZ(cx, "Hello World!")));
+        CHECK_SAME(v2, expected);
+    }
+
+    return true;
+}
+END_TEST(testStructuredClone_string)
diff --git a/js/src/vm/StructuredClone.cpp b/js/src/vm/StructuredClone.cpp
index 76d48610f38..88e1c262ec7 100644
--- a/js/src/vm/StructuredClone.cpp
+++ b/js/src/vm/StructuredClone.cpp
@@ -1488,15 +1488,35 @@ JS_StructuredClone(JSContext *cx, JS::Value valueArg, JS::Value *vp,
     RootedValue value(cx, valueArg);
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
-    assertSameCompartment(cx, value);
+
+    // Strings are associated with zones, not compartments,
+    // so we copy the string by wrapping it.
+    if (value.isString()) {
+      RootedString strValue(cx, value.toString());
+      if (!cx->compartment()->wrap(cx, strValue.address())) {
+        return false;
+      }
+      *vp = JS::StringValue(strValue);
+      return true;
+    }
 
     const JSStructuredCloneCallbacks *callbacks =
         optionalCallbacks ?
         optionalCallbacks :
         cx->runtime()->structuredCloneCallbacks;
+
     JSAutoStructuredCloneBuffer buf;
-    return buf.write(cx, value, callbacks, closure) &&
-           buf.read(cx, vp, callbacks, closure);
+    {
+        mozilla::Maybe ac;
+        if (value.isObject()) {
+            ac.construct(cx, &value.toObject());
+        }
+
+        if (!buf.write(cx, value, callbacks, closure))
+            return false;
+    }
+
+    return buf.read(cx, vp, callbacks, closure);
 }
 
 void

From 387047cba6de2ead1b04db403cc540872c3c54fb Mon Sep 17 00:00:00 2001
From: Andrea Marchesini 
Date: Wed, 4 Sep 2013 13:20:51 -0400
Subject: [PATCH 096/171] Bug 912086 - Several Workers methods do not set their
 return value. r=mrbkap

--HG--
rename : dom/workers/test/bug911085_worker.js => dom/workers/test/rvals_worker.js
rename : dom/workers/test/test_bug911085.html => dom/workers/test/test_rvals.html
---
 dom/workers/Worker.cpp                        |  7 +++++-
 dom/workers/WorkerScope.cpp                   | 23 ++++++++++++++++---
 dom/workers/test/Makefile.in                  |  4 ++--
 dom/workers/test/bug911085_worker.js          |  3 ---
 dom/workers/test/rvals_worker.js              | 13 +++++++++++
 .../{test_bug911085.html => test_rvals.html}  | 11 ++++++---
 6 files changed, 49 insertions(+), 12 deletions(-)
 delete mode 100644 dom/workers/test/bug911085_worker.js
 create mode 100644 dom/workers/test/rvals_worker.js
 rename dom/workers/test/{test_bug911085.html => test_rvals.html} (70%)

diff --git a/dom/workers/Worker.cpp b/dom/workers/Worker.cpp
index 314d290899c..ac227edbbe0 100644
--- a/dom/workers/Worker.cpp
+++ b/dom/workers/Worker.cpp
@@ -270,7 +270,12 @@ private:
       return !JS_IsExceptionPending(aCx);
     }
 
-    return worker->Terminate(aCx);
+    if (!worker->Terminate(aCx)) {
+      return false;
+    }
+
+    JS_RVAL(aCx, aVp).setUndefined();
+    return true;
   }
 
   static bool
diff --git a/dom/workers/WorkerScope.cpp b/dom/workers/WorkerScope.cpp
index 7fb24186c64..88c69174e19 100644
--- a/dom/workers/WorkerScope.cpp
+++ b/dom/workers/WorkerScope.cpp
@@ -400,7 +400,12 @@ private:
       return false;
     }
 
-    return scope->mWorker->CloseInternal(aCx);
+    if (!scope->mWorker->CloseInternal(aCx)) {
+      return false;
+    }
+
+    JS_RVAL(aCx, aVp).setUndefined();
+    return true;
   }
 
   static bool
@@ -420,6 +425,7 @@ private:
       return false;
     }
 
+    JS_RVAL(aCx, aVp).setUndefined();
     return true;
   }
 
@@ -462,7 +468,12 @@ private:
       return false;
     }
 
-    return scope->mWorker->ClearTimeout(aCx, id);
+    if (!scope->mWorker->ClearTimeout(aCx, id)) {
+      return false;
+    }
+
+    JS_RVAL(aCx, aVp).setUndefined();
+    return true;
   }
 
   static bool
@@ -504,7 +515,12 @@ private:
       return false;
     }
 
-    return scope->mWorker->ClearTimeout(aCx, id);
+    if (!scope->mWorker->ClearTimeout(aCx, id)) {
+      return false;
+    }
+
+    JS_RVAL(aCx, aVp).setUndefined();
+    return true;
   }
 
   static bool
@@ -537,6 +553,7 @@ private:
       fflush(stdout);
     }
 
+    JS_RVAL(aCx, aVp).setUndefined();
     return true;
   }
 
diff --git a/dom/workers/test/Makefile.in b/dom/workers/test/Makefile.in
index a9a4d73b6c1..50507348920 100644
--- a/dom/workers/test/Makefile.in
+++ b/dom/workers/test/Makefile.in
@@ -106,8 +106,8 @@ MOCHITEST_FILES = \
   content_worker.js \
   test_url.html \
   url_worker.js \
-  test_bug911085.html \
-  bug911085_worker.js \
+  test_rvals.html \
+  rvals_worker.js \
   test_urlApi.html \
   urlApi_worker.js \
   $(NULL)
diff --git a/dom/workers/test/bug911085_worker.js b/dom/workers/test/bug911085_worker.js
deleted file mode 100644
index 74baeca2f85..00000000000
--- a/dom/workers/test/bug911085_worker.js
+++ /dev/null
@@ -1,3 +0,0 @@
-onmessage = function(evt) {
-  postMessage(postMessage('ignore') == undefined);
-}
diff --git a/dom/workers/test/rvals_worker.js b/dom/workers/test/rvals_worker.js
new file mode 100644
index 00000000000..b6be439ff2d
--- /dev/null
+++ b/dom/workers/test/rvals_worker.js
@@ -0,0 +1,13 @@
+onmessage = function(evt) {
+  postMessage(postMessage('ignore') == undefined);
+
+  var id = setInterval(function() {}, 200);
+  postMessage(clearInterval(id) == undefined);
+
+  id = setTimeout(function() {}, 200);
+  postMessage(clearTimeout(id) == undefined);
+
+  postMessage(dump(42) == undefined);
+
+  postMessage('finished');
+}
diff --git a/dom/workers/test/test_bug911085.html b/dom/workers/test/test_rvals.html
similarity index 70%
rename from dom/workers/test/test_bug911085.html
rename to dom/workers/test/test_rvals.html
index 7c534c1ac10..eba8589282c 100644
--- a/dom/workers/test/test_bug911085.html
+++ b/dom/workers/test/test_rvals.html
@@ -12,13 +12,18 @@
 
  :postMessage(importScripts('data:;base64,cG9zdE1lc3NhZ2UoJ2FsZXJ0KDEpJyk'))",
+    "sanitized": "0? :postMessage(importScripts('data:;base64,cG9zdE1lc3NhZ2UoJ2FsZXJ0KDEpJyk'))"
+  },
+  {
+    "data": "",
+    "sanitized": ""
+  },
+  {
+    "data": "",
+    "sanitized": ""
+  },
+  {
+    "data": "",
+    "sanitized": ""
+  },
+  {
+    "data": "",
+    "sanitized": ""
+  },
+  {
+    "data": "X",
+    "sanitized": "X"
+  },
+  {
+    "data": "",
+    "sanitized": ""
+  },
+  {
+    "data": "",
+    "sanitized": ""
+  },
+  {
+    "data": "





...



", + "sanitized": "





...



" + }, + { + "data": "01", + "sanitized": "01" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "X", + "sanitized": "X" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "�script �alert(1)//�/script �", + "sanitized": "�script �alert(1)//�/script �" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "
", + "sanitized": "" + }, + { + "data": "1", + "sanitized": "1" + }, + { + "data": ";1", + "sanitized": ";1" + }, + { + "data": "+ADw-html+AD4APA-body+AD4APA-div+AD4-top secret+ADw-/div+AD4APA-/body+AD4APA-/html+AD4-.toXMLString().match(/.*/m),alert(RegExp.input);", + "sanitized": "+ADw-html+AD4APA-body+AD4APA-div+AD4-top secret+ADw-/div+AD4APA-/body+AD4APA-/html+AD4-.toXMLString().match(/.*/m),alert(RegExp.input);" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "1", + "sanitized": "1" + }, + { + "data": "" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "
", + "sanitized": "
" + }, + { + "data": "XXXXXX", + "sanitized": "XXXXXX" + }, + { + "data": "1", + "sanitized": "1" + }, + { + "data": "1", + "sanitized": "1" + }, + { + "data": "XXX", + "sanitized": "XXX" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "\r\n\r\n\r\n\r\n><image xlink:href=\"", + "sanitized": "\n\n\n><image xlink:href=\"" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "
  • \n
    ", + "sanitized": "
  • \n
    " + }, + { + "data": "XXX", + "sanitized": "XXX" + }, + { + "data": "\r\n\r\n\r\n\r\n\r\nHello\r\n", + "sanitized": "\n\n\nHello\n" + }, + { + "data": "X", + "sanitized": "X" + }, + { + "data": "
    XXX
    ", + "sanitized": "
    XXX
    " + }, + { + "data": "
    XXX
    ", + "sanitized": "
    XXX
    " + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "\r\n", + "sanitized": "\n" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "
    ", + "sanitized": "" + }, + { + "data": "
    ", + "sanitized": "
    " + }, + { + "data": "
    XXX
    ", + "sanitized": "
    XXX
    " + }, + { + "data": "
    XXX
    ", + "sanitized": "
    XXX
    " + }, + { + "data": "\r\n\r\n\r\n\r\n\r\n", + "sanitized": "\n\n\n\n" + }, + { + "data": " // O10.10�, OM10.0�, GC6�, FF\r\n\r\n // IE6, O10.10�, OM10.0�\r\n // IE6, O11.01�, OM10.1�", + "sanitized": " // O10.10�, OM10.0�, GC6�, FF\n\n // IE6, O10.10�, OM10.0�\n // IE6, O11.01�, OM10.1�" + }, + { + "data": "]>&x;", + "sanitized": "\n]>&x;" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "\n\n", + "sanitized": "" + }, + { + "data": "\r\n]>", + "sanitized": "\n]>" + }, + { + "data": "\r\n\tXXX\r\n", + "sanitized": "\n\tXXX\n" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "
    x
    ", + "sanitized": "
    x
    " + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "
    ", + "sanitized": "" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "&x;", + "sanitized": "\n&x;" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "\n\n", + "sanitized": "\n\n" + }, + { + "data": "\n\n\n\n\n\n\n\n\n\n", + "sanitized": "\n\n\n\n\n\n\n\n\n\n" + }, + { + "data": "\n\n\n", + "sanitized": "\n\n\n" + }, + { + "data": "\r\n
    \r\n\r\n\r\n\r\n\r\n
    PRESS ENTER
    ", + "sanitized": "
    \n\n\n\n\n
    PRESS ENTER
    " + }, + { + "data": "[A]\n\">\n\">\n\">\n[B]\n\">\n[C]\n\">\n[D]\n<% foo>\">", + "sanitized": "[A]\n\">\n\">\n\">\n[B]\n\">\n[C]\n\n[D]\n<% foo>" + }, + { + "data": "
    X
    ", + "sanitized": "
    X
    " + }, + { + "data": "
    X
    ", + "sanitized": "
    X
    " + }, + { + "data": "\nalert(1)\n", + "sanitized": "\nalert(1)\n" + }, + { + "data": "\n\n\n\n", + "sanitized": "\n\n\n\n" + }, + { + "data": "\n", + "sanitized": "\n" + }, + { + "data": "\r\n
    ", + "sanitized": "" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "\r\n\"`\">\r\n\r\n\r\n\"`\r\n\"`", + "sanitized": "\"`><img\n\n\n\"`><img\n\"`><img" + }, + { + "data": "\n\n\n", + "sanitized": "\n\n\n" + }, + { + "data": "\r\n\r\n", + "sanitized": "\n\n" + }, + { + "data": "
    X
    ", + "sanitized": "
    X
    " + }, + { + "data": "
    X
    ", + "sanitized": "
    X
    " + }, + { + "data": "
    XXX
    \n", + "sanitized": "
    XXX
    \n" + }, + { + "data": "XXX", + "sanitized": "XXX" + }, + { + "data": "\r\n", + "sanitized": "" + }, + { + "data": "
    x
    \n\n\n", + "sanitized": "
    x
    \n\n\n" + }, + { + "data": "\n\t\n", + "sanitized": "\n\t\n" + }, + { + "data": "
    \n\t

    Drop me

    \n
    \n\n", + "sanitized": "
    \n\t

    Drop me

    \n
    \n\n" + }, + { + "data": "\n\n", + "sanitized": "\n\n" + }, + { + "data": "\n\n\nSpam", + "sanitized": "\n\n\nSpam" + }, + { + "data": "\n\n", + "sanitized": "" + }, + { + "data": "Some text\nwww.example.org\n\n\n", + "sanitized": "Some text\nwww.example.org\n\n\n" + }, + { + "data": " // Safari 5.0, Chrome 9, 10\n // Safari 5.0", + "sanitized": " // Safari 5.0, Chrome 9, 10\n // Safari 5.0" + }, + { + "data": "\r\n\r\n]>\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n", + "sanitized": "\n]>\n\n \n \n \n \n \n \n" + }, + { + "data": "\r\n", + "sanitized": "\n" + }, + { + "data": "\r\n\r\nalert(1)\r\n", + "sanitized": "\n\nalert(1)\n" + }, + { + "data": "" + }, + { + "data": "\n\n\n", + "sanitized": "\n\n\n" + }, + { + "data": "CLICKME\r\n\r\n\r\n\r\nCLICKME\r\n\r\n\r\nCLICKMEhttp://http://google.com\r\n", + "sanitized": "CLICKME\n\n\n\nCLICKME\n\n\nCLICKMEhttp://http://google.com\n" + }, + { + "data": "drag and drop one of the following strings to the drop box:\r\n

    \r\njAvascript:alert('Top Page Location: '+document.location+' Host Page Cookies: '+document.cookie);//\r\n

    \r\nfeed:javascript:alert('Top Page Location: '+document.location+' Host Page Cookies: '+document.cookie);//\r\n

    \r\nfeed:data:text/html,<script>alert('Top Page Location: '+document.location+' Host Page Cookies: '+document.cookie)</script><b>\r\n

    \r\nfeed:feed:javAscript:javAscript:feed:alert('Top Page Location: '+document.location+' Host Page Cookies: '+document.cookie);//\r\n

    \r\n
    + Drop Box +
    ", + "sanitized": "drag and drop one of the following strings to the drop box:\n

    \njAvascript:alert('Top Page Location: '+document.location+' Host Page Cookies: '+document.cookie);//\n

    \nfeed:javascript:alert('Top Page Location: '+document.location+' Host Page Cookies: '+document.cookie);//\n

    \nfeed:data:text/html,<script>alert('Top Page Location: '+document.location+' Host Page Cookies: '+document.cookie)</script><b>\n

    \nfeed:feed:javAscript:javAscript:feed:alert('Top Page Location: '+document.location+' Host Page Cookies: '+document.cookie);//\n

    \n
    + Drop Box +
    " + }, + { + "data": "\r\n\r\n\r\n
    \r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n", + "sanitized": "\n\n\n
    \n\n\n\n\n\n\n\n\n\n" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "\r\n<%\r\n\r\n%></xmp><img src=xx:x onerror=alert(1)//\r\n\r\n %>/\r\nalert(2)\r\n\r\n\r\nXXX\r\n\r\n-->{}\r\n*{color:red}", + "sanitized": "\n<%\n\n\"%></xmp><img\n\n %>/\nalert(2)\n\n\nXXX\n\n-->{}\n*{color:red}" + }, + { + "data": "\r\n\r\n\r\n", + "sanitized": "\n\n" + }, + { + "data": "
    \r\n\r\n\r\n\r\n\r\n
    ", + "sanitized": "\n\n\n\n\n" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "'';!--\"=&{()}", + "sanitized": "'';!--\"=&{()}" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "SRC= ", + "sanitized": "SRC=\n" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "'\"-->", + "sanitized": "" + }, + { + "data": "" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": " +ADw-SCRIPT+AD4-alert('XSS');+ADw-/SCRIPT+AD4-", + "sanitized": " +ADw-SCRIPT+AD4-alert('XSS');+ADw-/SCRIPT+AD4-" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "", + "sanitized": "" + }, + { + "data": "PT SRC", + "sanitized": "PT SRC" + }, + { + "data": "", + "sanitized": "" + } +] diff --git a/parser/xml/test/unit/test_sanitizer.js b/parser/xml/test/unit/test_sanitizer.js new file mode 100644 index 00000000000..b8aaa1e08f4 --- /dev/null +++ b/parser/xml/test/unit/test_sanitizer.js @@ -0,0 +1,21 @@ +function run_test() { + var Ci = Components.interfaces; + var Cc = Components.classes; + + // vectors by the html5security project (https://code.google.com/p/html5security/ & Creative Commons 3.0 BY), see CC-BY-LICENSE for the full license + load("results.js"); // gives us a `vectors' array + + var ParserUtils = Cc["@mozilla.org/parserutils;1"].getService(Ci.nsIParserUtils); + var sanitizeFlags = ParserUtils.SanitizerCidEmbedsOnly|ParserUtils.SanitizerDropForms|ParserUtils.SanitizerDropNonCSSPresentation; + // flags according to + // http://mxr.mozilla.org/comm-central/source/mailnews/mime/src/mimemoz2.cpp#2218 + // and default settings + + + for (var item in vectors) { + var evil = vectors[item].data; + var sanitized = vectors[item].sanitized; + var out = ParserUtils.sanitize(evil, sanitizeFlags); + do_check_eq(sanitized, out); + } +} From 50abb51412c5ea2d4b4f09500958cb34fefedbc6 Mon Sep 17 00:00:00 2001 From: Kartikaya Gupta Date: Wed, 4 Sep 2013 09:12:46 -0400 Subject: [PATCH 098/171] Bug 884047 - Add some diagnostic logging to help investigation. r=blassey --- mobile/android/base/gfx/GLController.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/mobile/android/base/gfx/GLController.java b/mobile/android/base/gfx/GLController.java index 851c927b5d1..bb9c474a1f0 100644 --- a/mobile/android/base/gfx/GLController.java +++ b/mobile/android/base/gfx/GLController.java @@ -85,6 +85,7 @@ public class GLController { synchronized void surfaceDestroyed() { ThreadUtils.assertOnUiThread(); + Log.w(LOGTAG, "GLController::surfaceDestroyed() with mCompositorCreated=" + mCompositorCreated); mSurfaceValid = false; mEGLSurface = null; @@ -100,10 +101,12 @@ public class GLController { if (mCompositorCreated) { GeckoAppShell.sendEventToGeckoSync(GeckoEvent.createCompositorPauseEvent()); } + Log.w(LOGTAG, "done GLController::surfaceDestroyed()"); } synchronized void surfaceChanged(int newWidth, int newHeight) { ThreadUtils.assertOnUiThread(); + Log.w(LOGTAG, "GLController::surfaceChanged(" + newWidth + ", " + newHeight + ") with mSurfaceValid=" + mSurfaceValid); mWidth = newWidth; mHeight = newHeight; @@ -113,6 +116,7 @@ public class GLController { // paused (e.g. during an orientation change), to make the compositor // aware of the changed surface. resumeCompositor(mWidth, mHeight); + Log.w(LOGTAG, "done GLController::surfaceChanged with compositor resume"); return; } mSurfaceValid = true; @@ -130,6 +134,7 @@ public class GLController { mView.post(new Runnable() { @Override public void run() { + Log.w(LOGTAG, "GLController::surfaceChanged, creating compositor; mCompositorCreated=" + mCompositorCreated + ", mSurfaceValid=" + mSurfaceValid); // If we haven't yet created the compositor, and the GfxInfoThread // isn't done it's data gathering activities, then postpone creating // the compositor a little bit more. Don't block though, since this is @@ -171,12 +176,14 @@ public class GLController { void createCompositor() { ThreadUtils.assertOnUiThread(); + Log.w(LOGTAG, "GLController::createCompositor with mCompositorCreated=" + mCompositorCreated); if (mCompositorCreated) { // If the compositor has already been created, just resume it instead. We don't need // to block here because if the surface is destroyed before the compositor grabs it, // we can handle that gracefully (i.e. the compositor will remain paused). resumeCompositor(mWidth, mHeight); + Log.w(LOGTAG, "done GLController::createCompositor with compositor resume"); return; } @@ -187,9 +194,11 @@ public class GLController { if (mEGLSurface != null && GeckoThread.checkLaunchState(GeckoThread.LaunchState.GeckoRunning)) { GeckoAppShell.sendEventToGeckoSync(GeckoEvent.createCompositorCreateEvent(mWidth, mHeight)); } + Log.w(LOGTAG, "done GLController::createCompositor"); } void compositorCreated() { + Log.w(LOGTAG, "GLController::compositorCreated"); // This is invoked on the compositor thread, while the java UI thread // is blocked on the gecko sync event in createCompositor() above mCompositorCreated = true; @@ -263,6 +272,7 @@ public class GLController { } void resumeCompositor(int width, int height) { + Log.w(LOGTAG, "GLController::resumeCompositor(" + width + ", " + height + ") and mCompositorCreated=" + mCompositorCreated); // Asking Gecko to resume the compositor takes too long (see // https://bugzilla.mozilla.org/show_bug.cgi?id=735230#c23), so we // resume the compositor directly. We still need to inform Gecko about @@ -273,6 +283,7 @@ public class GLController { GeckoAppShell.scheduleResumeComposition(width, height); GeckoAppShell.sendEventToGecko(GeckoEvent.createCompositorResumeEvent()); } + Log.w(LOGTAG, "done GLController::resumeCompositor"); } public static class GLControllerException extends RuntimeException { From d8a1513d26bf48bebaa9be723b42757ddd3a4ca2 Mon Sep 17 00:00:00 2001 From: Sam Foster Date: Tue, 3 Sep 2013 17:24:47 -0700 Subject: [PATCH 099/171] Bug 898650 - Simplified scroll direction heuristics using scrollMaX/Y then document aspect ratio. r=mbrubeck --HG-- extra : rebase_source : 4cd41227c60ea10294453d1e6a7aaf68dc6ca39b --- browser/metro/modules/CrossSlide.jsm | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/browser/metro/modules/CrossSlide.jsm b/browser/metro/modules/CrossSlide.jsm index ec72a5f4d9f..6d70b3f8c30 100644 --- a/browser/metro/modules/CrossSlide.jsm +++ b/browser/metro/modules/CrossSlide.jsm @@ -42,32 +42,28 @@ function isSelectable(aElement) { // placeholder logic return aElement.nodeName == 'richgriditem'; } - function withinCone(aLen, aHeight) { // check pt falls within 45deg either side of the cross axis return aLen > aHeight; } - function getScrollAxisFromElement(aElement) { - let elem = aElement, - win = elem.ownerDocument.defaultView; - let scrollX, scrollY; - for (; elem && 1==elem.nodeType; elem = elem.parentNode) { - let cs = win.getComputedStyle(elem); - scrollX = (cs.overflowX=='scroll' || cs.overflowX=='auto'); - scrollY = (cs.overflowX=='scroll' || cs.overflowX=='auto'); - if (scrollX || scrollY) { - break; - } - } - return scrollX ? 'x' : 'y'; -} + // keeping it simple - just return apparent scroll axis for the document + let win = aElement.ownerDocument.defaultView; + let scrollX = win.scrollMaxX, + scrollY = win.scrollMaxY; + // determine scroll axis from scrollable content when possible + if (scrollX || scrollY) + return scrollX >= scrollY ? 'x' : 'y'; + // fall back to guessing at scroll axis from document aspect ratio + let docElem = aElement.ownerDocument.documentElement; + return docElem.clientWidth >= docElem.clientHeight ? + 'x' : 'y'; +} function pointFromTouchEvent(aEvent) { let touch = aEvent.touches[0]; return { x: touch.clientX, y: touch.clientY }; } - // This damping function has these important properties: // f(0) = 0 // f'(0) = 1 From 17febdfd3787efad5ca2b0e49dfc5d3642481aac Mon Sep 17 00:00:00 2001 From: Lucas Rocha Date: Wed, 4 Sep 2013 15:20:55 +0100 Subject: [PATCH 100/171] Bug 899183 - Update testBookmarklets for new about:home (r=margaret) --- mobile/android/base/tests/robocop.ini | 2 +- .../base/tests/testBookmarklets.java.in | 38 +++++++++++-------- 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/mobile/android/base/tests/robocop.ini b/mobile/android/base/tests/robocop.ini index eba2ff8fe2f..b62b7743355 100644 --- a/mobile/android/base/tests/robocop.ini +++ b/mobile/android/base/tests/robocop.ini @@ -1,7 +1,7 @@ [testAwesomebar] # [testAwesomebarSwipes] # disabled on fig - bug 880060 # [testBookmark] # disabled on fig - bug 880060 -# [testBookmarklets] # disabled on fig - bug 880060 +[testBookmarklets] [testBookmarkKeyword] [testBrowserSearchVisibility] [testJNI] diff --git a/mobile/android/base/tests/testBookmarklets.java.in b/mobile/android/base/tests/testBookmarklets.java.in index dce4c9d5263..cc4f0efe5d4 100644 --- a/mobile/android/base/tests/testBookmarklets.java.in +++ b/mobile/android/base/tests/testBookmarklets.java.in @@ -23,6 +23,7 @@ public class testBookmarklets extends AboutHomeTest { // load a standard page so bookmarklets work inputAndLoadUrl(url); + verifyPageTitle("Browser Blank Page 01"); // Waiting for page title to ensure the page is loaded // verify that user-entered bookmarklets do *not* work enterUrl(js); @@ -39,28 +40,33 @@ public class testBookmarklets extends AboutHomeTest { // add this using the UI, so we go through the content provider. addOrUpdateMobileBookmark(title, js); - // verify that bookmarklets clicked in awesomescreen work - /* Removed by Bug 896576 - [fig] Remove [getBookmarksList] from BaseTest - ListView bookmarks = getBookmarksList(title); + // Open about:home in the Bookmarks page + openAboutHomeTab(AboutHomeTabs.BOOKMARKS); - Boolean found = false; - if (bookmarks == null) { - mAsserter.is(true, true, "Did not find the bookmarks section in the awesomebar"); - } else { - for (int i = 0; i < bookmarks.getAdapter().getCount(); i++) { - Cursor c = (Cursor)bookmarks.getItemAtPosition(i); - String turl = c.getString(c.getColumnIndexOrThrow("url")); - if (turl.equals(js)) { - found = true; - mAsserter.is(1, 1, "Found bookmarklet added to bookmarks: " + js); - mSolo.clickOnView(bookmarks.getChildAt(i)); - } + ListView bookmarks = findListViewWithTag("bookmarks"); + mAsserter.is(waitForListToLoad(bookmarks), true, "list is properly loaded"); + + int width = mDriver.getGeckoWidth(); + int height = mDriver.getGeckoHeight(); + + // Scroll down so that the bookmarks list has more items on screen. + mActions.drag(width / 2, width / 2, height - 10, height / 2); + + // Verify that bookmarklets clicked in awesomescreen work + boolean found = false; + for (int i = bookmarks.getHeaderViewsCount(); i < bookmarks.getAdapter().getCount(); i++) { + Cursor c = (Cursor)bookmarks.getItemAtPosition(i); + String aUrl = c.getString(c.getColumnIndexOrThrow("url")); + if (aUrl.equals(js)) { + found = true; + mAsserter.is(1, 1, "Found bookmarklet added to bookmarks: " + js); + mSolo.clickOnView(bookmarks.getChildAt(i)); } } + if (!found) { mAsserter.is(found, true, "Found the bookmark: " + js + " and clicked on it"); } - */ alerted = waitForTest(new BooleanTest() { @Override From 5f9714b86fb7b6dec7c7ff1025e2e23cfefc7305 Mon Sep 17 00:00:00 2001 From: Rob Campbell Date: Wed, 4 Sep 2013 07:52:00 -0400 Subject: [PATCH 101/171] Bug 912120 - Debug spew in the console output when adding style properties via the Inspector; r=dcamp --- browser/devtools/styleinspector/rule-view.js | 1 - 1 file changed, 1 deletion(-) diff --git a/browser/devtools/styleinspector/rule-view.js b/browser/devtools/styleinspector/rule-view.js index 7f3d7fec492..163b5d2b5fa 100644 --- a/browser/devtools/styleinspector/rule-view.js +++ b/browser/devtools/styleinspector/rule-view.js @@ -642,7 +642,6 @@ Rule.prototype = { let props = []; for (let line of lines) { - dump("line: " + line + "\n"); let [, name, value, priority] = CSS_PROP_RE.exec(line) || [] if (!name || !value) { continue; From 6d96d85783e93df86fd5882909ad414e0b67c760 Mon Sep 17 00:00:00 2001 From: Michael Ratcliffe Date: Wed, 4 Sep 2013 17:43:40 +0200 Subject: [PATCH 102/171] Bug 694019 - we should be able to highlight and inspect a :pseudo element r=mratcliffe --- browser/app/profile/firefox.js | 1 + browser/devtools/styleinspector/rule-view.js | 151 ++++++++- browser/devtools/styleinspector/ruleview.css | 18 + .../devtools/styleinspector/test/Makefile.in | 2 + .../test/browser_ruleview_pseudoelement.html | 115 +++++++ .../test/browser_ruleview_pseudoelement.js | 317 ++++++++++++++++++ .../devtools/styleinspector.properties | 8 + browser/themes/linux/devtools/ruleview.css | 2 +- browser/themes/osx/devtools/ruleview.css | 8 +- browser/themes/windows/devtools/ruleview.css | 2 +- toolkit/devtools/server/actors/styles.js | 55 +-- 11 files changed, 639 insertions(+), 40 deletions(-) create mode 100644 browser/devtools/styleinspector/test/browser_ruleview_pseudoelement.html create mode 100644 browser/devtools/styleinspector/test/browser_ruleview_pseudoelement.js diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js index f2b93c002b2..5d4373491da 100644 --- a/browser/app/profile/firefox.js +++ b/browser/app/profile/firefox.js @@ -1075,6 +1075,7 @@ pref("devtools.inspector.enabled", true); pref("devtools.inspector.activeSidebar", "ruleview"); pref("devtools.inspector.markupPreview", false); pref("devtools.inspector.remote", false); +pref("devtools.inspector.show_pseudo_elements", true); // Enable the Layout View pref("devtools.layoutview.enabled", true); diff --git a/browser/devtools/styleinspector/rule-view.js b/browser/devtools/styleinspector/rule-view.js index 163b5d2b5fa..3f0351b356d 100644 --- a/browser/devtools/styleinspector/rule-view.js +++ b/browser/devtools/styleinspector/rule-view.js @@ -11,7 +11,7 @@ const promise = require("sdk/core/promise"); let {CssLogic} = require("devtools/styleinspector/css-logic"); let {InplaceEditor, editableField, editableItem} = require("devtools/shared/inplace-editor"); -let {ELEMENT_STYLE} = require("devtools/server/actors/styles"); +let {ELEMENT_STYLE, PSEUDO_ELEMENTS} = require("devtools/server/actors/styles"); Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/XPCOMUtils.jsm"); @@ -203,7 +203,9 @@ ElementStyle.prototype = { } // Mark overridden computed styles. - this.markOverridden(); + this.markOverriddenAll(); + + this._sortRulesForPseudoElement(); // We're done with the previous list of rules. delete this._refreshRules; @@ -215,6 +217,16 @@ ElementStyle.prototype = { return this.populated; }, + /** + * Put pseudo elements in front of others. + */ + _sortRulesForPseudoElement: function ElementStyle_sortRulesForPseudoElement() + { + this.rules = this.rules.sort((a, b) => { + return (a.pseudoElement || "z") > (b.pseudoElement || "z"); + }); + }, + /** * Add a rule if it's one we care about. Filters out duplicates and * inherited styles with no inherited properties. @@ -266,22 +278,38 @@ ElementStyle.prototype = { }, /** - * Mark the properties listed in this.rules with an overridden flag - * if an earlier property overrides it. + * Calls markOverridden with all supported pseudo elements */ - markOverridden: function ElementStyle_markOverridden() + markOverriddenAll: function ElementStyle_markOverriddenAll() + { + this.markOverridden(); + for (let pseudo of PSEUDO_ELEMENTS) { + this.markOverridden(pseudo); + } + }, + + /** + * Mark the properties listed in this.rules for a given pseudo element + * with an overridden flag if an earlier property overrides it. + * @param {string} pseudo + * Which pseudo element to flag as overridden. + * Empty string or undefined will default to no pseudo element. + */ + markOverridden: function ElementStyle_markOverridden(pseudo="") { // Gather all the text properties applied by these rules, ordered // from more- to less-specific. let textProps = []; - for each (let rule in this.rules) { - textProps = textProps.concat(rule.textProps.slice(0).reverse()); + for (let rule of this.rules) { + if (rule.pseudoElement == pseudo) { + textProps = textProps.concat(rule.textProps.slice(0).reverse()); + } } // Gather all the computed properties applied by those text // properties. let computedProps = []; - for each (let textProp in textProps) { + for (let textProp of textProps) { computedProps = computedProps.concat(textProp.computed); } @@ -302,7 +330,7 @@ ElementStyle.prototype = { // _overriddenDirty will be set on each prop, indicating whether its // dirty status changed during this pass. let taken = {}; - for each (let computedProp in computedProps) { + for (let computedProp of computedProps) { let earlier = taken[computedProp.name]; let overridden; if (earlier @@ -328,7 +356,7 @@ ElementStyle.prototype = { // computed properties are marked overridden. Update the text // property's associated editor, if any. This will clear the // _overriddenDirty state on all computed properties. - for each (let textProp in textProps) { + for (let textProp of textProps) { // _updatePropertyOverridden will return true if the // overridden state has changed for the text property. if (this._updatePropertyOverridden(textProp)) { @@ -384,6 +412,7 @@ function Rule(aElementStyle, aOptions) this.domRule = aOptions.rule || null; this.style = aOptions.rule; this.matchedSelectors = aOptions.matchedSelectors || []; + this.pseudoElement = aOptions.pseudoElement || ""; this.inherited = aOptions.inherited || null; this._modificationDepth = 0; @@ -558,7 +587,7 @@ Rule.prototype = { textProp.priority = cssProp.priority; } - this.elementStyle.markOverridden(); + this.elementStyle.markOverriddenAll(); if (promise === this._applyingModifications) { this._applyingModifications = null; @@ -1077,6 +1106,7 @@ CssRuleView.prototype = { } this._createEditors(); + // Notify anyone that cares that we refreshed. var evt = this.doc.createEvent("Events"); evt.initEvent("CssRuleViewRefreshed", true, false); @@ -1131,6 +1161,59 @@ CssRuleView.prototype = { this.element.dispatchEvent(evt); }, + /** + * Text for header that shows above rules for this element + */ + get selectedElementLabel () + { + if (this._selectedElementLabel) { + return this._selectedElementLabel; + } + this._selectedElementLabel = CssLogic.l10n("rule.selectedElement"); + return this._selectedElementLabel; + }, + + /** + * Text for header that shows above rules for pseudo elements + */ + get pseudoElementLabel () + { + if (this._pseudoElementLabel) { + return this._pseudoElementLabel; + } + this._pseudoElementLabel = CssLogic.l10n("rule.pseudoElement"); + return this._pseudoElementLabel; + }, + + togglePseudoElementVisibility: function(value) + { + this._showPseudoElements = !!value; + let isOpen = this.showPseudoElements; + + Services.prefs.setBoolPref("devtools.inspector.show_pseudo_elements", + isOpen); + + this.element.classList.toggle("show-pseudo-elements", isOpen); + + if (this.pseudoElementTwisty) { + if (isOpen) { + this.pseudoElementTwisty.setAttribute("open", "true"); + } + else { + this.pseudoElementTwisty.removeAttribute("open"); + } + } + }, + + get showPseudoElements () + { + if (this._showPseudoElements === undefined) { + this._showPseudoElements = + Services.prefs.getBoolPref("devtools.inspector.show_pseudo_elements"); + } + return this._showPseudoElements; + }, + /** * Creates editor UI for each of the rules in _elementStyle. */ @@ -1139,18 +1222,48 @@ CssRuleView.prototype = { // Run through the current list of rules, attaching // their editors in order. Create editors if needed. let lastInheritedSource = ""; + let seenPseudoElement = false; + let seenNormalElement = false; + for (let rule of this._elementStyle.rules) { if (rule.domRule.system) { continue; } + // Only print header for this element if there are pseudo elements + if (seenPseudoElement && !seenNormalElement && !rule.pseudoElement) { + seenNormalElement = true; + let div = this.doc.createElementNS(HTML_NS, "div"); + div.className = "theme-gutter ruleview-header"; + div.textContent = this.selectedElementLabel; + this.element.appendChild(div); + } + let inheritedSource = rule.inheritedSource; if (inheritedSource != lastInheritedSource) { - let h2 = this.doc.createElementNS(HTML_NS, "div"); - h2.className = "ruleview-rule-inheritance theme-gutter"; - h2.textContent = inheritedSource; + let div = this.doc.createElementNS(HTML_NS, "div"); + div.className = "theme-gutter ruleview-header"; + div.textContent = inheritedSource; lastInheritedSource = inheritedSource; - this.element.appendChild(h2); + this.element.appendChild(div); + } + + if (!seenPseudoElement && rule.pseudoElement) { + seenPseudoElement = true; + + let div = this.doc.createElementNS(HTML_NS, "div"); + div.className = "theme-gutter ruleview-header"; + div.textContent = this.pseudoElementLabel; + + let twisty = this.pseudoElementTwisty = + this.doc.createElementNS(HTML_NS, "span"); + twisty.className = "ruleview-expander theme-twisty"; + twisty.addEventListener("click", () => { + this.togglePseudoElementVisibility(!this.showPseudoElements); + }, false); + + div.insertBefore(twisty, div.firstChild); + this.element.appendChild(div); } if (!rule.editor) { @@ -1159,6 +1272,8 @@ CssRuleView.prototype = { this.element.appendChild(rule.editor.element); } + + this.togglePseudoElementVisibility(this.showPseudoElements); }, /** @@ -1226,6 +1341,9 @@ RuleEditor.prototype = { this.element = this.doc.createElementNS(HTML_NS, "div"); this.element.className = "ruleview-rule theme-separator"; this.element._ruleEditor = this; + if (this.rule.pseudoElement) { + this.element.classList.add("ruleview-rule-pseudo-element"); + } // Give a relative position for the inplace editor's measurement // span to be placed absolutely against. @@ -1357,12 +1475,15 @@ RuleEditor.prototype = { * Property value. * @param {string} aPriority * Property priority. + * @return {TextProperty} + * The new property */ addProperty: function RuleEditor_addProperty(aName, aValue, aPriority) { let prop = this.rule.createProperty(aName, aValue, aPriority); let editor = new TextPropertyEditor(this, prop); this.propertyList.appendChild(editor.element); + return prop; }, /** diff --git a/browser/devtools/styleinspector/ruleview.css b/browser/devtools/styleinspector/ruleview.css index 086e506fc49..d35c62ea5bb 100644 --- a/browser/devtools/styleinspector/ruleview.css +++ b/browser/devtools/styleinspector/ruleview.css @@ -36,3 +36,21 @@ .ruleview-warning[hidden] { display: none; } + +.ruleview-rule-pseudo-element { + display: none; +} + +.show-pseudo-elements .ruleview-rule-pseudo-element { + display: block; +} + +.ruleview .ruleview-expander { + vertical-align: middle; +} + +.ruleview-header { + vertical-align:middle; + height: 1.5em; + line-height: 1.5em; +} \ No newline at end of file diff --git a/browser/devtools/styleinspector/test/Makefile.in b/browser/devtools/styleinspector/test/Makefile.in index 2db33c1792c..99549826443 100644 --- a/browser/devtools/styleinspector/test/Makefile.in +++ b/browser/devtools/styleinspector/test/Makefile.in @@ -43,6 +43,7 @@ MOCHITEST_BROWSER_FILES = \ browser_bug894376_css_value_completion_new_property_value_pair.js \ browser_bug894376_css_value_completion_existing_property_value_pair.js \ browser_ruleview_bug_902966_revert_value_on_ESC.js \ + browser_ruleview_pseudoelement.js \ head.js \ $(NULL) @@ -60,6 +61,7 @@ MOCHITEST_BROWSER_FILES += \ browser_styleinspector_bug_677930_urls_clickable \ browser_styleinspector_bug_677930_urls_clickable/browser_styleinspector_bug_677930_urls_clickable.css \ test-image.png \ + browser_ruleview_pseudoelement.html \ $(NULL) include $(topsrcdir)/config/rules.mk diff --git a/browser/devtools/styleinspector/test/browser_ruleview_pseudoelement.html b/browser/devtools/styleinspector/test/browser_ruleview_pseudoelement.html new file mode 100644 index 00000000000..9c286b7cd73 --- /dev/null +++ b/browser/devtools/styleinspector/test/browser_ruleview_pseudoelement.html @@ -0,0 +1,115 @@ + + + + + + +

    ruleview pseudoelement($("test"));

    + +
    +

    Top Left
    Position

    +
    + +
    +

    Top Right
    Position

    +
    + +
    +

    Bottom Right
    Position

    +
    + +
    +

    Bottom Left
    Position

    +
    + + + diff --git a/browser/devtools/styleinspector/test/browser_ruleview_pseudoelement.js b/browser/devtools/styleinspector/test/browser_ruleview_pseudoelement.js new file mode 100644 index 00000000000..d4bff429691 --- /dev/null +++ b/browser/devtools/styleinspector/test/browser_ruleview_pseudoelement.js @@ -0,0 +1,317 @@ +/* vim: set ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +let doc; +let inspector; +let view; + +const TEST_URI = "http://example.com/browser/browser/" + + "devtools/styleinspector/test/" + + "browser_ruleview_pseudoelement.html"; + +function testPseudoElements(aInspector, aRuleView) +{ + inspector = aInspector; + view = aRuleView; + + testTopLeft(); +} + +function testTopLeft() +{ + testNode(doc.querySelector("#topleft"), (element, elementStyle) => { + let elementRules = elementStyle.rules.filter((rule) => { return !rule.pseudoElement; }); + let afterRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":after"; }); + let beforeRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":before"; }); + let firstLineRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":first-line"; }); + let firstLetterRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":first-letter"; }); + let selectionRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":-moz-selection"; }); + + is(elementRules.length, 4, "TopLeft has the correct number of non psuedo element rules"); + is(afterRules.length, 1, "TopLeft has the correct number of :after rules"); + is(beforeRules.length, 2, "TopLeft has the correct number of :before rules"); + is(firstLineRules.length, 0, "TopLeft has the correct number of :first-line rules"); + is(firstLetterRules.length, 0, "TopLeft has the correct number of :first-letter rules"); + is(selectionRules.length, 0, "TopLeft has the correct number of :selection rules"); + + let gutters = view.element.querySelectorAll(".theme-gutter"); + is (gutters.length, 3, "There are three gutter headings"); + is (gutters[0].textContent, "Pseudo-elements", "Gutter heading is correct"); + is (gutters[1].textContent, "This Element", "Gutter heading is correct"); + is (gutters[2].textContent, "Inherited from body", "Gutter heading is correct"); + + // Make sure that clicking on the twisty hides pseudo elements + let expander = gutters[0].querySelector(".ruleview-expander"); + ok (view.element.classList.contains("show-pseudo-elements"), "Pseudo Elements are expanded"); + expander.click(); + ok (!view.element.classList.contains("show-pseudo-elements"), "Pseudo Elements are collapsed by twisty"); + expander.click(); + ok (view.element.classList.contains("show-pseudo-elements"), "Pseudo Elements are expanded again"); + expander.click(); + + let defaultView = element.ownerDocument.defaultView; + let elementRule = elementRules[0]; + let elementRuleView = [].filter.call(view.element.children, (e) => { + return e._ruleEditor && e._ruleEditor.rule === elementRule; + })[0]._ruleEditor; + + let elementAfterRule = afterRules[0]; + let elementAfterRuleView = [].filter.call(view.element.children, (e) => { + return e._ruleEditor && e._ruleEditor.rule === elementAfterRule; + })[0]._ruleEditor; + + is + ( + convertTextPropsToString(elementAfterRule.textProps), + "background: none repeat scroll 0% 0% red; content: \" \"; position: absolute; " + + "border-radius: 50%; height: 32px; width: 32px; top: 50%; left: 50%; margin-top: -16px; margin-left: -16px", + "TopLeft after properties are correct" + ); + + let elementBeforeRule = beforeRules[0]; + let elementBeforeRuleView = [].filter.call(view.element.children, (e) => { + return e._ruleEditor && e._ruleEditor.rule === elementBeforeRule; + })[0]._ruleEditor; + + is + ( + convertTextPropsToString(elementBeforeRule.textProps), + "top: 0px; left: 0px", + "TopLeft before properties are correct" + ); + + let firstProp = elementAfterRuleView.addProperty("background-color", "rgb(0, 255, 0)", ""); + let secondProp = elementAfterRuleView.addProperty("padding", "100px", ""); + + is (firstProp, elementAfterRule.textProps[elementAfterRule.textProps.length - 2], + "First added property is on back of array"); + is (secondProp, elementAfterRule.textProps[elementAfterRule.textProps.length - 1], + "Second added property is on back of array"); + + promiseDone(elementAfterRule._applyingModifications.then(() => { + is(defaultView.getComputedStyle(element, ":after").getPropertyValue("background-color"), + "rgb(0, 255, 0)", "Added property should have been used."); + is(defaultView.getComputedStyle(element, ":after").getPropertyValue("padding-top"), + "100px", "Added property should have been used."); + is(defaultView.getComputedStyle(element).getPropertyValue("padding-top"), + "32px", "Added property should not apply to element"); + + secondProp.setEnabled(false); + + return elementAfterRule._applyingModifications; + }).then(() => { + is(defaultView.getComputedStyle(element, ":after").getPropertyValue("padding-top"), "0px", + "Disabled property should have been used."); + is(defaultView.getComputedStyle(element).getPropertyValue("padding-top"), "32px", + "Added property should not apply to element"); + + secondProp.setEnabled(true); + + return elementAfterRule._applyingModifications; + }).then(() => { + is(defaultView.getComputedStyle(element, ":after").getPropertyValue("padding-top"), "100px", + "Enabled property should have been used."); + is(defaultView.getComputedStyle(element).getPropertyValue("padding-top"), "32px", + "Added property should not apply to element"); + + let firstProp = elementRuleView.addProperty("background-color", "rgb(0, 0, 255)", ""); + + return elementRule._applyingModifications; + }).then(() => { + is(defaultView.getComputedStyle(element).getPropertyValue("background-color"), "rgb(0, 0, 255)", + "Added property should have been used."); + is(defaultView.getComputedStyle(element, ":after").getPropertyValue("background-color"), "rgb(0, 255, 0)", + "Added prop does not apply to pseudo"); + + testTopRight(); + })); + }); +} + +function testTopRight() +{ + testNode(doc.querySelector("#topright"), (element, elementStyle) => { + + let elementRules = elementStyle.rules.filter((rule) => { return !rule.pseudoElement; }); + let afterRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":after"; }); + let beforeRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":before"; }); + let firstLineRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":first-line"; }); + let firstLetterRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":first-letter"; }); + let selectionRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":-moz-selection"; }); + + is(elementRules.length, 4, "TopRight has the correct number of non psuedo element rules"); + is(afterRules.length, 1, "TopRight has the correct number of :after rules"); + is(beforeRules.length, 2, "TopRight has the correct number of :before rules"); + is(firstLineRules.length, 0, "TopRight has the correct number of :first-line rules"); + is(firstLetterRules.length, 0, "TopRight has the correct number of :first-letter rules"); + is(selectionRules.length, 0, "TopRight has the correct number of :selection rules"); + + let gutters = view.element.querySelectorAll(".theme-gutter"); + is (gutters.length, 3, "There are three gutter headings"); + is (gutters[0].textContent, "Pseudo-elements", "Gutter heading is correct"); + is (gutters[1].textContent, "This Element", "Gutter heading is correct"); + is (gutters[2].textContent, "Inherited from body", "Gutter heading is correct"); + + let expander = gutters[0].querySelector(".ruleview-expander"); + ok (!view.element.classList.contains("show-pseudo-elements"), "Pseudo Elements remain collapsed after switching element"); + expander.scrollIntoView(); + expander.click(); + ok (view.element.classList.contains("show-pseudo-elements"), "Pseudo Elements are shown again after clicking twisty"); + + testBottomRight(); + }); +} + +function testBottomRight() +{ + testNode(doc.querySelector("#bottomright"), (element, elementStyle) => { + + let elementRules = elementStyle.rules.filter((rule) => { return !rule.pseudoElement; }); + let afterRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":after"; }); + let beforeRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":before"; }); + let firstLineRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":first-line"; }); + let firstLetterRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":first-letter"; }); + let selectionRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":-moz-selection"; }); + + is(elementRules.length, 4, "BottomRight has the correct number of non psuedo element rules"); + is(afterRules.length, 1, "BottomRight has the correct number of :after rules"); + is(beforeRules.length, 3, "BottomRight has the correct number of :before rules"); + is(firstLineRules.length, 0, "BottomRight has the correct number of :first-line rules"); + is(firstLetterRules.length, 0, "BottomRight has the correct number of :first-letter rules"); + is(selectionRules.length, 0, "BottomRight has the correct number of :selection rules"); + + testBottomLeft(); + }); +} + +function testBottomLeft() +{ + testNode(doc.querySelector("#bottomleft"), (element, elementStyle) => { + + let elementRules = elementStyle.rules.filter((rule) => { return !rule.pseudoElement; }); + let afterRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":after"; }); + let beforeRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":before"; }); + let firstLineRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":first-line"; }); + let firstLetterRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":first-letter"; }); + let selectionRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":-moz-selection"; }); + + is(elementRules.length, 4, "BottomLeft has the correct number of non psuedo element rules"); + is(afterRules.length, 1, "BottomLeft has the correct number of :after rules"); + is(beforeRules.length, 2, "BottomLeft has the correct number of :before rules"); + is(firstLineRules.length, 0, "BottomLeft has the correct number of :first-line rules"); + is(firstLetterRules.length, 0, "BottomLeft has the correct number of :first-letter rules"); + is(selectionRules.length, 0, "BottomLeft has the correct number of :selection rules"); + + testParagraph(); + }); +} + +function testParagraph() +{ + testNode(doc.querySelector("#bottomleft p"), (element, elementStyle) => { + + let elementRules = elementStyle.rules.filter((rule) => { return !rule.pseudoElement; }); + let afterRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":after"; }); + let beforeRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":before"; }); + let firstLineRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":first-line"; }); + let firstLetterRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":first-letter"; }); + let selectionRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":-moz-selection"; }); + + is(elementRules.length, 3, "Paragraph has the correct number of non psuedo element rules"); + is(afterRules.length, 0, "Paragraph has the correct number of :after rules"); + is(beforeRules.length, 0, "Paragraph has the correct number of :before rules"); + is(firstLineRules.length, 1, "Paragraph has the correct number of :first-line rules"); + is(firstLetterRules.length, 1, "Paragraph has the correct number of :first-letter rules"); + is(selectionRules.length, 1, "Paragraph has the correct number of :selection rules"); + + let gutters = view.element.querySelectorAll(".theme-gutter"); + is (gutters.length, 3, "There are three gutter headings"); + is (gutters[0].textContent, "Pseudo-elements", "Gutter heading is correct"); + is (gutters[1].textContent, "This Element", "Gutter heading is correct"); + is (gutters[2].textContent, "Inherited from body", "Gutter heading is correct"); + + let elementFirstLineRule = firstLineRules[0]; + let elementFirstLineRuleView = [].filter.call(view.element.children, (e) => { + return e._ruleEditor && e._ruleEditor.rule === elementFirstLineRule; + })[0]._ruleEditor; + + is + ( + convertTextPropsToString(elementFirstLineRule.textProps), + "background: none repeat scroll 0% 0% blue", + "Paragraph first-line properties are correct" + ); + + let elementFirstLetterRule = firstLetterRules[0]; + let elementFirstLetterRuleView = [].filter.call(view.element.children, (e) => { + return e._ruleEditor && e._ruleEditor.rule === elementFirstLetterRule; + })[0]._ruleEditor; + + is + ( + convertTextPropsToString(elementFirstLetterRule.textProps), + "color: red; font-size: 130%", + "Paragraph first-letter properties are correct" + ); + + let elementSelectionRule = selectionRules[0]; + let elementSelectionRuleView = [].filter.call(view.element.children, (e) => { + return e._ruleEditor && e._ruleEditor.rule === elementSelectionRule; + })[0]._ruleEditor; + + is + ( + convertTextPropsToString(elementSelectionRule.textProps), + "color: white; background: none repeat scroll 0% 0% black", + "Paragraph first-letter properties are correct" + ); + + testBody(); + }); +} + +function testBody() { + + testNode(doc.querySelector("body"), (element, elementStyle) => { + + let gutters = view.element.querySelectorAll(".theme-gutter"); + is (gutters.length, 0, "There are no gutter headings"); + + finishTest(); + }); + +} +function convertTextPropsToString(textProps) { + return textProps.map((t) => { + return t.name + ": " + t.value; + }).join("; "); +} + +function testNode(node, cb) +{ + inspector.once("inspector-updated", () => { + cb(node, view._elementStyle) + }); + inspector.selection.setNode(node); +} + +function finishTest() +{ + doc = null; + gBrowser.removeCurrentTab(); + finish(); +} + +function test() +{ + waitForExplicitFinish(); + gBrowser.selectedTab = gBrowser.addTab(); + gBrowser.selectedBrowser.addEventListener("load", function(evt) { + gBrowser.selectedBrowser.removeEventListener(evt.type, arguments.callee, true); + doc = content.document; + waitForFocus(() => openRuleView(testPseudoElements), content); + }, true); + + content.location = TEST_URI; +} diff --git a/browser/locales/en-US/chrome/browser/devtools/styleinspector.properties b/browser/locales/en-US/chrome/browser/devtools/styleinspector.properties index 5c17ac28b8d..028b2f43bd8 100644 --- a/browser/locales/en-US/chrome/browser/devtools/styleinspector.properties +++ b/browser/locales/en-US/chrome/browser/devtools/styleinspector.properties @@ -35,6 +35,14 @@ rule.sourceElement=element # e.g "Inherited from body#bodyID" rule.inheritedFrom=Inherited from %S +# LOCALIZATION NOTE (rule.pseudoElement): Shown for CSS rules +# pseudo element header +rule.pseudoElement=Pseudo-elements + +# LOCALIZATION NOTE (rule.pseudoElement): Shown for CSS rules +# pseudo element header +rule.selectedElement=This Element + # LOCALIZATION NOTE (helpLinkTitle): For each style property # the user can hover it and get a help link button which allows one to # quickly jump to the documentation from the Mozilla Developer Network site. diff --git a/browser/themes/linux/devtools/ruleview.css b/browser/themes/linux/devtools/ruleview.css index b0ddd80e619..171a7658923 100644 --- a/browser/themes/linux/devtools/ruleview.css +++ b/browser/themes/linux/devtools/ruleview.css @@ -14,7 +14,7 @@ -moz-user-select: none; } -.ruleview-rule-inheritance { +.ruleview-header { border-top-width: 1px; border-bottom-width: 1px; border-top-style: solid; diff --git a/browser/themes/osx/devtools/ruleview.css b/browser/themes/osx/devtools/ruleview.css index 039b82f9c4e..e3d65ba7734 100644 --- a/browser/themes/osx/devtools/ruleview.css +++ b/browser/themes/osx/devtools/ruleview.css @@ -14,16 +14,20 @@ -moz-user-select: none; } -.ruleview-rule-inheritance { +.ruleview-header { border-top-width: 1px; border-bottom-width: 1px; border-top-style: solid; border-bottom-style: solid; padding: 1px 4px; - margin-top: 4px; -moz-user-select: none; } +.ruleview-rule-pseudo-element { + padding-left:20px; + border-left: solid 10px; +} + .ruleview-rule-source:hover { text-decoration: underline; } diff --git a/browser/themes/windows/devtools/ruleview.css b/browser/themes/windows/devtools/ruleview.css index b0ddd80e619..171a7658923 100644 --- a/browser/themes/windows/devtools/ruleview.css +++ b/browser/themes/windows/devtools/ruleview.css @@ -14,7 +14,7 @@ -moz-user-select: none; } -.ruleview-rule-inheritance { +.ruleview-header { border-top-width: 1px; border-bottom-width: 1px; border-top-style: solid; diff --git a/toolkit/devtools/server/actors/styles.js b/toolkit/devtools/server/actors/styles.js index d204146f63a..f825f8006f9 100644 --- a/toolkit/devtools/server/actors/styles.js +++ b/toolkit/devtools/server/actors/styles.js @@ -20,6 +20,9 @@ loader.lazyGetter(this, "DOMUtils", () => Cc["@mozilla.org/inspector/dom-utils;1 const ELEMENT_STYLE = 100; exports.ELEMENT_STYLE = ELEMENT_STYLE; +const PSEUDO_ELEMENTS = [":first-line", ":first-letter", ":before", ":after", ":-moz-selection"]; +exports.PSEUDO_ELEMENTS = PSEUDO_ELEMENTS; + // Predeclare the domnode actor type for use in requests. types.addActorType("domnode"); @@ -360,36 +363,46 @@ var PageStyleActor = protocol.ActorClass({ }); } - // Get the styles that apply to the element. - let domRules = DOMUtils.getCSSStyleRules(element); + let pseudoElements = inherited ? [null] : [null, ...PSEUDO_ELEMENTS]; + for (let pseudo of pseudoElements) { - // getCSSStyleRules returns ordered from least-specific to - // most-specific. - for (let i = domRules.Count() - 1; i >= 0; i--) { - let domRule = domRules.GetElementAt(i); + // Get the styles that apply to the element. + let domRules = DOMUtils.getCSSStyleRules(element, pseudo); - let isSystem = !CssLogic.isContentStylesheet(domRule.parentStyleSheet); - - if (isSystem && options.filter != CssLogic.FILTER.UA) { + if (!domRules) { continue; } - if (inherited) { - // Don't include inherited rules if none of its properties - // are inheritable. - let hasInherited = Array.prototype.some.call(domRule.style, prop => { - return DOMUtils.isInheritedProperty(prop); - }); - if (!hasInherited) { + // getCSSStyleRules returns ordered from least-specific to + // most-specific. + for (let i = domRules.Count() - 1; i >= 0; i--) { + let domRule = domRules.GetElementAt(i); + + let isSystem = !CssLogic.isContentStylesheet(domRule.parentStyleSheet); + + if (isSystem && options.filter != CssLogic.FILTER.UA) { continue; } + + if (inherited) { + // Don't include inherited rules if none of its properties + // are inheritable. + let hasInherited = Array.prototype.some.call(domRule.style, prop => { + return DOMUtils.isInheritedProperty(prop); + }); + if (!hasInherited) { + continue; + } + } + + let ruleActor = this._styleRef(domRule); + rules.push({ + rule: ruleActor, + inherited: inherited, + pseudoElement: pseudo + }); } - let ruleActor = this._styleRef(domRule); - rules.push({ - rule: ruleActor, - inherited: inherited, - }); } }, From cbac25c28b40b16addaab4228528ab26d498430c Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Tue, 3 Sep 2013 19:22:08 -0700 Subject: [PATCH 103/171] Bug 906640 - add a pretty print button to the scratchpad; r=anton --- browser/devtools/scratchpad/scratchpad.js | 17 ++++++++++++ browser/devtools/scratchpad/scratchpad.xul | 10 +++++++ browser/devtools/scratchpad/test/Makefile.in | 1 + .../test/browser_scratchpad_pprint.js | 26 +++++++++++++++++++ .../chrome/browser/devtools/scratchpad.dtd | 3 +++ 5 files changed, 57 insertions(+) create mode 100644 browser/devtools/scratchpad/test/browser_scratchpad_pprint.js diff --git a/browser/devtools/scratchpad/scratchpad.js b/browser/devtools/scratchpad/scratchpad.js index ea01475dd24..5587bf9a135 100644 --- a/browser/devtools/scratchpad/scratchpad.js +++ b/browser/devtools/scratchpad/scratchpad.js @@ -20,6 +20,7 @@ let { Cc, Ci, Cu } = require("chrome"); let promise = require("sdk/core/promise"); let Telemetry = require("devtools/shared/telemetry"); let TargetFactory = require("devtools/framework/target").TargetFactory; +const escodegen = require("escodegen/escodegen"); Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/Services.jsm"); @@ -31,6 +32,8 @@ Cu.import("resource://gre/modules/jsdebugger.jsm"); Cu.import("resource:///modules/devtools/gDevTools.jsm"); Cu.import("resource://gre/modules/osfile.jsm"); Cu.import("resource:///modules/devtools/ViewHelpers.jsm"); +Cu.import("resource://gre/modules/reflect.jsm"); +Cu.import("resource://gre/modules/devtools/DevToolsUtils.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "VariablesView", "resource:///modules/devtools/VariablesView.jsm"); @@ -521,6 +524,20 @@ var Scratchpad = { return deferred.promise; }, + /** + * Pretty print the source text inside the scratchpad. + */ + prettyPrint: function SP_prettyPrint() { + const uglyText = this.getText(); + try { + const ast = Reflect.parse(uglyText); + const prettyText = escodegen.generate(ast); + this.setText(prettyText); + } catch (e) { + this.writeAsErrorComment(DevToolsUtils.safeErrorString(e)); + } + }, + /** * Writes out a primitive value as a comment. This handles values which are * to be printed directly (number, string) as well as grips to values diff --git a/browser/devtools/scratchpad/scratchpad.xul b/browser/devtools/scratchpad/scratchpad.xul index 7abcbfc57e5..878defc0a45 100644 --- a/browser/devtools/scratchpad/scratchpad.xul +++ b/browser/devtools/scratchpad/scratchpad.xul @@ -46,6 +46,7 @@ + @@ -94,6 +95,10 @@ key="&display.key;" command="sp-cmd-display" modifiers="accel"/> + + + diff --git a/browser/devtools/scratchpad/test/Makefile.in b/browser/devtools/scratchpad/test/Makefile.in index e24f3d2363c..21e888516a1 100644 --- a/browser/devtools/scratchpad/test/Makefile.in +++ b/browser/devtools/scratchpad/test/Makefile.in @@ -39,6 +39,7 @@ MOCHITEST_BROWSER_FILES = \ browser_scratchpad_bug807924_cannot_convert_to_string.js \ browser_scratchpad_long_string.js \ browser_scratchpad_open_error_console.js \ + browser_scratchpad_pprint.js \ head.js \ # Disable test due to bug 807234 becoming basically permanent diff --git a/browser/devtools/scratchpad/test/browser_scratchpad_pprint.js b/browser/devtools/scratchpad/test/browser_scratchpad_pprint.js new file mode 100644 index 00000000000..9b5a6b3d243 --- /dev/null +++ b/browser/devtools/scratchpad/test/browser_scratchpad_pprint.js @@ -0,0 +1,26 @@ +/* vim: set ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +function test() +{ + waitForExplicitFinish(); + + gBrowser.selectedTab = gBrowser.addTab(); + gBrowser.selectedBrowser.addEventListener("load", function onLoad() { + gBrowser.selectedBrowser.removeEventListener("load", onLoad, true); + openScratchpad(runTests); + }, true); + + content.location = "data:text/html;charset=utf8,test Scratchpad pretty print."; +} + +function runTests(sw) +{ + const sp = sw.Scratchpad; + sp.setText("function main() { console.log(5); }"); + sp.prettyPrint(); + const prettyText = sp.getText(); + ok(prettyText.contains("\n")); + finish(); +} diff --git a/browser/locales/en-US/chrome/browser/devtools/scratchpad.dtd b/browser/locales/en-US/chrome/browser/devtools/scratchpad.dtd index 7210060e0c1..e1d5d2a6c79 100644 --- a/browser/locales/en-US/chrome/browser/devtools/scratchpad.dtd +++ b/browser/locales/en-US/chrome/browser/devtools/scratchpad.dtd @@ -65,6 +65,9 @@ + + + + true + 64dp + horizontal + @drawable/toast + true + middle + 16dp + + 0dp + 0dp + 0dp + 0dp + +