Merge b2g-inbound to m-c on a CLOSED TREE.

This commit is contained in:
Ryan VanderMeulen 2013-11-14 20:57:32 -05:00
Родитель 442418699d 301d7ba8b5
Коммит 3af5f0a28a
150 изменённых файлов: 3680 добавлений и 998 удалений

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

@ -18,4 +18,4 @@
# Modifying this file will now automatically clobber the buildbot machines \o/
#
Another Windows WebIDL clobber needed due to bug 928195
Another Windows WebIDL clobber needed due to bug 674741

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

@ -1,4 +1,4 @@
{
"revision": "f6f928dc9106402f7101dc55f9401cd136622faf",
"revision": "88cc9854d6daff8c577e3867b95a1e523e429112",
"repo_path": "/integration/gaia-central"
}

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

@ -189,6 +189,9 @@
@BINPATH@/components/dom_geolocation.xpt
@BINPATH@/components/dom_media.xpt
@BINPATH@/components/dom_network.xpt
#ifdef MOZ_NFC
@BINPATH@/components/dom_nfc.xpt
#endif
@BINPATH@/components/dom_notification.xpt
@BINPATH@/components/dom_html.xpt
@BINPATH@/components/dom_indexeddb.xpt
@ -494,6 +497,13 @@
@BINPATH@/components/webvtt.xpt
@BINPATH@/components/WebVTT.manifest
@BINPATH@/components/WebVTTParserWrapper.js
#ifdef MOZ_NFC
@BINPATH@/components/nsNfc.manifest
@BINPATH@/components/nsNfc.js
@BINPATH@/components/Nfc.manifest
@BINPATH@/components/Nfc.js
@BINPATH@/components/NfcContentHelper.js
#endif
#ifdef MOZ_ENABLE_DBUS
@BINPATH@/components/@DLL_PREFIX@dbusservice@DLL_SUFFIX@
#endif

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

@ -7,10 +7,10 @@
jar = add_java_jar('annotationProcessors')
jar.sources += [
'AnnotationProcessor.java',
'CodeGenerator.java',
'MethodWithAnnotationInfo.java',
'classloader/IterableJarLoadingURLClassLoader.java',
'classloader/JarClassIterator.java',
'CodeGenerator.java',
'MethodWithAnnotationInfo.java',
'utils/AlphabeticMethodComparator.java',
'utils/GeneratableEntryPointIterator.java',
'utils/Utils.java',

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

@ -223,6 +223,7 @@ if test -n "$gonkdir" ; then
GONK_INCLUDES="-I$gonkdir/frameworks/base/opengl/include -I$gonkdir/frameworks/base/native/include -I$gonkdir/frameworks/base/include -I$gonkdir/frameworks/base/services/camera -I$gonkdir/frameworks/base/include/media/stagefright -I$gonkdir/frameworks/base/include/media/stagefright/openmax -I$gonkdir/frameworks/base/media/libstagefright/rtsp -I$gonkdir/frameworks/base/media/libstagefright/include -I$gonkdir/external/dbus -I$gonkdir/external/bluetooth/bluez/lib -I$gonkdir/dalvik/libnativehelper/include/nativehelper"
MOZ_B2G_BT=1
MOZ_B2G_BT_BLUEZ=1
MOZ_NFC=1
MOZ_B2G_CAMERA=1
MOZ_OMX_DECODER=1
AC_SUBST(MOZ_OMX_DECODER)
@ -239,6 +240,7 @@ if test -n "$gonkdir" ; then
MOZ_B2G_BT_BLUEDROID=1
fi
MOZ_NFC=1
MOZ_B2G_CAMERA=1
MOZ_OMX_DECODER=1
AC_SUBST(MOZ_OMX_DECODER)
@ -7306,6 +7308,18 @@ AC_SUBST(MOZ_B2G_BT)
AC_SUBST(MOZ_B2G_BT_BLUEZ)
AC_SUBST(MOZ_B2G_BT_BLUEDROID)
dnl ========================================================
dnl = Enable NFC Interface for B2G (Gonk usually)
dnl ========================================================
MOZ_ARG_ENABLE_BOOL(b2g-nfc,
[ --enable-nfc Set compile flags necessary for compiling NFC API ],
MOZ_NFC=1,
MOZ_NFC= )
if test -n "$MOZ_NFC"; then
AC_DEFINE(MOZ_NFC)
fi
AC_SUBST(MOZ_NFC)
dnl ========================================================
dnl = Enable Pico Speech Synthesis (Gonk usually)
dnl ========================================================
@ -8883,7 +8897,7 @@ dnl so that regeneration via dependencies works correctly
GYP_MOZMAKE_OPTIONS="${GYP_MOZMAKE_OPTIONS} -D mac_sdk_path=$MACOS_SDK_DIR"
fi
;;
*-android*)
*-*linux*)
GYP_MOZMAKE_OPTIONS="-G os=linux"
;;
*)

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

@ -718,6 +718,7 @@ GK_ATOM(onheadphoneschange, "onheadphoneschange")
GK_ATOM(onheld, "onheld")
GK_ATOM(onhfpstatuschanged, "onhfpstatuschanged")
GK_ATOM(onholding, "onholding")
GK_ATOM(oniccchange, "oniccchange")
GK_ATOM(oniccinfochange, "oniccinfochange")
GK_ATOM(onincoming, "onincoming")
GK_ATOM(oninput, "oninput")

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

@ -302,6 +302,17 @@ this.PermissionsTable = { geolocation: {
privileged: PROMPT_ACTION,
certified: PROMPT_ACTION
},
"nfc": {
app: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION,
access: ["read", "write"]
},
"nfc-manager": {
app: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
};
/**

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

@ -40,7 +40,7 @@
#ifdef MOZ_B2G_RIL
#include "mozilla/dom/IccManager.h"
#include "mozilla/dom/CellBroadcast.h"
#include "mozilla/dom/network/MobileConnection.h"
#include "mozilla/dom/network/MobileConnectionArray.h"
#include "mozilla/dom/Voicemail.h"
#endif
#include "nsIIdleObserver.h"
@ -141,7 +141,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Navigator)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTelephony)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mConnection)
#ifdef MOZ_B2G_RIL
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMobileConnection)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMobileConnections)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCellBroadcast)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIccManager)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mVoicemail)
@ -219,9 +219,8 @@ Navigator::Invalidate()
}
#ifdef MOZ_B2G_RIL
if (mMobileConnection) {
mMobileConnection->Shutdown();
mMobileConnection = nullptr;
if (mMobileConnections) {
mMobileConnections = nullptr;
}
if (mCellBroadcast) {
@ -1181,6 +1180,20 @@ Navigator::GetMozTelephony(ErrorResult& aRv)
#ifdef MOZ_B2G_RIL
network::MobileConnectionArray*
Navigator::GetMozMobileConnections(ErrorResult& aRv)
{
if (!mMobileConnections) {
if (!mWindow) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
mMobileConnections = new network::MobileConnectionArray(mWindow);
}
return mMobileConnections;
}
CellBroadcast*
Navigator::GetMozCellBroadcast(ErrorResult& aRv)
{
@ -1272,23 +1285,6 @@ Navigator::GetMozConnection()
return mConnection;
}
#ifdef MOZ_B2G_RIL
nsIDOMMozMobileConnection*
Navigator::GetMozMobileConnection(ErrorResult& aRv)
{
if (!mMobileConnection) {
if (!mWindow) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
mMobileConnection = new network::MobileConnection();
mMobileConnection->Init(mWindow);
}
return mMobileConnection;
}
#endif // MOZ_B2G_RIL
#ifdef MOZ_B2G_BT
bluetooth::BluetoothManager*
Navigator::GetMozBluetooth(ErrorResult& aRv)
@ -1797,6 +1793,18 @@ Navigator::HasFMRadioSupport(JSContext* /* unused */, JSObject* aGlobal)
}
#endif // MOZ_B2G_FM
#ifdef MOZ_NFC
/* static */
bool
Navigator::HasNfcSupport(JSContext* /* unused */, JSObject* aGlobal)
{
nsCOMPtr<nsPIDOMWindow> win = GetWindowFromGlobal(aGlobal);
return win && (CheckPermission(win, "nfc-read") ||
CheckPermission(win, "nfc-write"));
}
#endif // MOZ_NFC
#ifdef MOZ_TIME_MANAGER
/* static */
bool

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

@ -35,7 +35,6 @@ class MediaStreamConstraintsInternal;
}
#ifdef MOZ_B2G_RIL
class nsIDOMMozMobileConnection;
class nsIDOMMozIccManager;
#endif // MOZ_B2G_RIL
@ -73,7 +72,7 @@ class MozGetUserMediaDevicesSuccessCallback;
namespace network {
class Connection;
#ifdef MOZ_B2G_RIL
class MobileConnection;
class MobileConnectionArray;
#endif
} // namespace Connection;
@ -219,7 +218,7 @@ public:
ErrorResult& aRv);
bool MozHasPendingMessage(const nsAString& aType, ErrorResult& aRv);
#ifdef MOZ_B2G_RIL
nsIDOMMozMobileConnection* GetMozMobileConnection(ErrorResult& aRv);
network::MobileConnectionArray* GetMozMobileConnections(ErrorResult& aRv);
CellBroadcast* GetMozCellBroadcast(ErrorResult& aRv);
Voicemail* GetMozVoicemail(ErrorResult& aRv);
nsIDOMMozIccManager* GetMozIccManager(ErrorResult& aRv);
@ -288,6 +287,9 @@ public:
#ifdef MOZ_B2G_FM
static bool HasFMRadioSupport(JSContext* /* unused */, JSObject* aGlobal);
#endif // MOZ_B2G_FM
#ifdef MOZ_NFC
static bool HasNfcSupport(JSContext* /* unused */, JSObject* aGlobal);
#endif // MOZ_NFC
#ifdef MOZ_TIME_MANAGER
static bool HasTimeSupport(JSContext* /* unused */, JSObject* aGlobal);
#endif // MOZ_TIME_MANAGER
@ -329,7 +331,7 @@ private:
nsRefPtr<Telephony> mTelephony;
nsRefPtr<network::Connection> mConnection;
#ifdef MOZ_B2G_RIL
nsRefPtr<network::MobileConnection> mMobileConnection;
nsRefPtr<network::MobileConnectionArray> mMobileConnections;
nsRefPtr<CellBroadcast> mCellBroadcast;
nsRefPtr<IccManager> mIccManager;
nsRefPtr<Voicemail> mVoicemail;

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

@ -7959,9 +7959,12 @@ nsGlobalWindow::Close(ErrorResult& aError)
return;
}
// Don't allow scripts from content to close non-app windows that were not
// opened by script.
// Don't allow scripts from content to close non-app or non-neterror
// windows that were not opened by script.
nsAutoString url;
mDoc->GetURL(url);
if (!mDocShell->GetIsApp() &&
!StringBeginsWith(url, NS_LITERAL_STRING("about:neterror")) &&
!mHadOriginalOpener && !nsContentUtils::IsCallerChrome()) {
bool allowClose = mAllowScriptsToClose ||
Preferences::GetBool("dom.allow_scripts_to_close_windows", true);

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

@ -789,6 +789,11 @@ DOMInterfaces = {
'nativeType': 'mozilla::dom::CellBroadcast',
},
'MozMobileConnectionArray': {
'nativeType': 'mozilla::dom::network::MobileConnectionArray',
'resultNotAddRefed': [ 'item' ]
},
'MozNamedAttrMap': {
'nativeType': 'nsDOMAttributeMap',
},

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

@ -249,7 +249,14 @@ AdapterPropertiesChangeCallback(bt_status_t aStatus, int aNumProperties,
propertiesArray.AppendElement(
BluetoothNamedValue(NS_LITERAL_STRING("Name"), propertyValue));
} else if (p.type == BT_PROPERTY_ADAPTER_SCAN_MODE) {
propertyValue = sAdapterDiscoverable = *(uint32_t*)p.val;
bt_scan_mode_t newMode = *(bt_scan_mode_t*)p.val;
if (newMode == BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
propertyValue = sAdapterDiscoverable = true;
} else {
propertyValue = sAdapterDiscoverable = false;
}
propertiesArray.AppendElement(
BluetoothNamedValue(NS_LITERAL_STRING("Discoverable"), propertyValue));
} else if (p.type == BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT) {
@ -637,9 +644,12 @@ ReplyStatusError(BluetoothReplyRunnable* aBluetoothReplyRunnable,
int aStatusCode, const nsAString& aCustomMsg)
{
MOZ_ASSERT(aBluetoothReplyRunnable, "Reply runnable is nullptr");
nsAutoString replyError;
BT_LOGR("%s: error code(%d)", __FUNCTION__, aStatusCode);
nsAutoString replyError;
replyError.Assign(aCustomMsg);
if (aStatusCode == BT_STATUS_BUSY) {
replyError.AppendLiteral(":BT_STATUS_BUSY");
} else if (aStatusCode == BT_STATUS_NOT_READY) {
@ -840,6 +850,7 @@ BluetoothServiceBluedroid::SetProperty(BluetoothObjectType aType,
const nsString propName = aValue.name();
bt_property_t prop;
bt_scan_mode_t scanMode;
nsString str;
// For Bluedroid, it's necessary to check property name for SetProperty
@ -863,22 +874,23 @@ BluetoothServiceBluedroid::SetProperty(BluetoothObjectType aType,
prop.val = (void*)name;
prop.len = strlen(name);
} else if (aValue.value().type() == BluetoothValue::Tbool) {
bt_scan_mode_t mode = aValue.value().get_bool() ?
BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE :
BT_SCAN_MODE_CONNECTABLE;
bt_scan_mode_t* sss = &mode;
prop.val = (void*)sss;
prop.len = sizeof(sss);
scanMode = aValue.value().get_bool() ?
BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE :
BT_SCAN_MODE_CONNECTABLE;
prop.val = (void*)&scanMode;
prop.len = sizeof(scanMode);
} else {
BT_LOGR("SetProperty but the property cannot be recognized correctly.");
return NS_OK;
}
sSetPropertyRunnableArray.AppendElement(aRunnable);
int ret = sBtInterface->set_adapter_property(&prop);
if (ret != BT_STATUS_SUCCESS)
int ret = sBtInterface->set_adapter_property(&prop);
if (ret != BT_STATUS_SUCCESS) {
ReplyStatusError(aRunnable, ret, NS_LITERAL_STRING("SetProperty"));
}
return NS_OK;
}

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

@ -29,6 +29,11 @@ const browserElementTestHelpers = {
}
},
_setPrefs: function() {
this.lockTestReady();
SpecialPowers.pushPrefEnv({'set': Array.slice(arguments)}, this.unlockTestReady.bind(this));
},
_testReadyLockCount: 0,
_firedTestReady: false,
lockTestReady: function() {
@ -44,9 +49,11 @@ const browserElementTestHelpers = {
},
enableProcessPriorityManager: function() {
this._setPref('dom.ipc.processPriorityManager.testMode', true);
this._setPref('dom.ipc.processPriorityManager.enabled', true);
this._setPref('dom.ipc.processPriorityManager.backgroundLRUPoolLevels', 2);
this._setPrefs(
['dom.ipc.processPriorityManager.testMode', true],
['dom.ipc.processPriorityManager.enabled', true],
['dom.ipc.processPriorityManager.backgroundLRUPoolLevels', 2]
);
},
setEnabledPref: function(value) {

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

@ -641,7 +641,10 @@ nsGonkCameraControl::SetParameter(uint32_t aKey,
if (!length) {
// This tells the camera driver to revert to automatic regioning.
mParams.set(key, "(0,0,0,0,0)");
{
RwAutoLockWrite lock(mRwLock);
mParams.set(key, "(0,0,0,0,0)");
}
PushParameters();
return;
}
@ -1230,7 +1233,10 @@ nsGonkCameraControl::SetPreviewSize(uint32_t aWidth, uint32_t aHeight)
uint32_t delta;
Size size;
mParams.getSupportedPreviewSizes(previewSizes);
{
RwAutoLockRead lock(mRwLock);
mParams.getSupportedPreviewSizes(previewSizes);
}
if (!aWidth && !aHeight) {
// no size specified, take the first supported size
@ -1274,7 +1280,10 @@ nsGonkCameraControl::SetPreviewSize(uint32_t aWidth, uint32_t aHeight)
mWidth = bestWidth;
mHeight = bestHeight;
mParams.setPreviewSize(mWidth, mHeight);
{
RwAutoLockWrite lock(mRwLock);
mParams.setPreviewSize(mWidth, mHeight);
}
PushParameters();
}
@ -1306,16 +1315,19 @@ nsGonkCameraControl::SetupVideoMode(const nsAString& aProfile)
const size_t SIZE = 256;
char buffer[SIZE];
mParams.setPreviewSize(width, height);
mParams.setPreviewFrameRate(fps);
{
RwAutoLockWrite lock(mRwLock);
mParams.setPreviewSize(width, height);
mParams.setPreviewFrameRate(fps);
/**
* "record-size" is probably deprecated in later ICS;
* might need to set "video-size" instead of "record-size".
* See bug 795332.
*/
snprintf(buffer, SIZE, "%dx%d", width, height);
mParams.set("record-size", buffer);
/**
* "record-size" is probably deprecated in later ICS;
* might need to set "video-size" instead of "record-size".
* See bug 795332.
*/
snprintf(buffer, SIZE, "%dx%d", width, height);
mParams.set("record-size", buffer);
}
// push the updated camera configuration immediately
PushParameters();
@ -1607,10 +1619,14 @@ nsGonkCameraControl::GetVideoSizes(nsTArray<idl::CameraSize>& aVideoSizes)
aVideoSizes.Clear();
android::Vector<Size> sizes;
mParams.getSupportedVideoSizes(sizes);
if (sizes.size() == 0) {
DOM_CAMERA_LOGI("Camera doesn't support video independent of the preview\n");
mParams.getSupportedPreviewSizes(sizes);
{
RwAutoLockRead lock(mRwLock);
mParams.getSupportedVideoSizes(sizes);
if (sizes.size() == 0) {
DOM_CAMERA_LOGI("Camera doesn't support video independent of the preview\n");
mParams.getSupportedPreviewSizes(sizes);
}
}
if (sizes.size() == 0) {

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

@ -263,6 +263,6 @@ function cleanUp() {
}
waitFor(testEtwsMessageAttributes, function () {
return navigator.mozMobileConnection.voice.connected;
return navigator.mozMobileConnections[0].voice.connected;
});

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

@ -476,6 +476,6 @@ function cleanUp() {
}
waitFor(testGsmMessageAttributes, function () {
return navigator.mozMobileConnection.voice.connected;
return navigator.mozMobileConnections[0].voice.connected;
});

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

@ -23,6 +23,7 @@ using struct gfxMatrix from "gfxMatrix.h";
using struct gfxSize from "gfxPoint.h";
using CSSRect from "Units.h";
using struct mozilla::layers::FrameMetrics from "FrameMetrics.h";
using struct mozilla::layers::ScrollableLayerGuid from "FrameMetrics.h";
using FrameMetrics::ViewID from "FrameMetrics.h";
using mozilla::layout::ScrollingBehavior from "mozilla/layout/RenderFrameUtils.h";
using struct mozilla::void_t from "ipc/IPCMessageUtils.h";
@ -276,7 +277,7 @@ parent:
* Instructs the TabParent to forward a request to zoom to a rect given in
* CSS pixels. This rect is relative to the document.
*/
ZoomToRect(CSSRect aRect);
ZoomToRect(uint32_t aPresShellId, ViewID aViewId, CSSRect aRect);
/**
* We know for sure that content has either preventDefaulted or not
@ -285,13 +286,15 @@ parent:
* batched and only processed for panning and zooming if content does not
* preventDefault.
*/
ContentReceivedTouch(bool aPreventDefault);
ContentReceivedTouch(ScrollableLayerGuid aGuid, bool aPreventDefault);
/**
* Updates any zoom constraints on the parent and anything tied to it. This
* is useful for control logic that resides outside of the remote browser.
* Updates the zoom constraints for a scrollable frame in this tab.
* The zoom controller code lives on the parent side and so this allows it to
* have up-to-date zoom constraints.
*/
UpdateZoomConstraints(bool aAllowZoom, CSSToScreenScale aMinZoom, CSSToScreenScale aMaxZoom);
UpdateZoomConstraints(uint32_t aPresShellId, ViewID aViewId,
bool aAllowZoom, CSSToScreenScale aMinZoom, CSSToScreenScale aMaxZoom);
/**
* Notifies the parent about a scroll event. The pres shell ID and
@ -372,10 +375,10 @@ child:
RealMouseEvent(WidgetMouseEvent event);
RealKeyEvent(WidgetKeyboardEvent event);
MouseWheelEvent(WidgetWheelEvent event);
RealTouchEvent(WidgetTouchEvent event);
RealTouchEvent(WidgetTouchEvent aEvent, ScrollableLayerGuid aGuid);
// We use a separate message for touchmove events only to apply
// compression to them.
RealTouchMoveEvent(WidgetTouchEvent event) compress;
RealTouchMoveEvent(WidgetTouchEvent aEvent, ScrollableLayerGuid aGuid) compress;
/**
* @see nsIDOMWindowUtils sendKeyEvent.

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

@ -362,18 +362,22 @@ TabChild::Observe(nsISupports *aSubject,
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(aSubject));
nsCOMPtr<nsITabChild> tabChild(TabChild::GetFrom(docShell));
if (tabChild == this) {
CSSRect rect;
sscanf(NS_ConvertUTF16toUTF8(aData).get(),
"{\"x\":%f,\"y\":%f,\"w\":%f,\"h\":%f}",
&rect.x, &rect.y, &rect.width, &rect.height);
SendZoomToRect(rect);
nsCOMPtr<nsIDocument> doc(GetDocument());
uint32_t presShellId;
ViewID viewId;
if (APZCCallbackHelper::GetScrollIdentifiers(doc->GetDocumentElement(),
&presShellId, &viewId)) {
CSSRect rect;
sscanf(NS_ConvertUTF16toUTF8(aData).get(),
"{\"x\":%f,\"y\":%f,\"w\":%f,\"h\":%f}",
&rect.x, &rect.y, &rect.width, &rect.height);
SendZoomToRect(presShellId, viewId, rect);
}
}
} else if (!strcmp(aTopic, BEFORE_FIRST_PAINT)) {
if (IsAsyncPanZoomEnabled()) {
nsCOMPtr<nsIDocument> subject(do_QueryInterface(aSubject));
nsCOMPtr<nsIDOMDocument> domDoc;
mWebNav->GetDocument(getter_AddRefs(domDoc));
nsCOMPtr<nsIDocument> doc(do_QueryInterface(domDoc));
nsCOMPtr<nsIDocument> doc(GetDocument());
if (SameCOMIdentity(subject, doc)) {
nsCOMPtr<nsIDOMWindowUtils> utils(GetDOMWindowUtils());
@ -533,8 +537,17 @@ TabChild::HandlePossibleViewportChange()
nsCOMPtr<nsIDOMWindowUtils> utils(GetDOMWindowUtils());
uint32_t presShellId;
ViewID viewId;
if (!APZCCallbackHelper::GetScrollIdentifiers(document->GetDocumentElement(),
&presShellId, &viewId)) {
return;
}
nsViewportInfo viewportInfo = nsContentUtils::GetViewportInfo(document, mInnerSize);
SendUpdateZoomConstraints(viewportInfo.IsZoomAllowed(),
SendUpdateZoomConstraints(presShellId,
viewId,
viewportInfo.IsZoomAllowed(),
viewportInfo.GetMinZoom(),
viewportInfo.GetMaxZoom());
@ -1068,6 +1081,15 @@ TabChild::GetDOMWindowUtils()
return utils.forget();
}
already_AddRefed<nsIDocument>
TabChild::GetDocument()
{
nsCOMPtr<nsIDOMDocument> domDoc;
mWebNav->GetDocument(getter_AddRefs(domDoc));
nsCOMPtr<nsIDocument> doc(do_QueryInterface(domDoc));
return doc.forget();
}
static nsInterfaceHashtable<nsPtrHashKey<PContentDialogChild>, nsIDialogParamBlock>* gActiveDialogs;
NS_IMETHODIMP
@ -1854,7 +1876,8 @@ TabChild::CancelTapTracking()
}
bool
TabChild::RecvRealTouchEvent(const WidgetTouchEvent& aEvent)
TabChild::RecvRealTouchEvent(const WidgetTouchEvent& aEvent,
const ScrollableLayerGuid& aGuid)
{
WidgetTouchEvent localEvent(aEvent);
nsEventStatus status = DispatchWidgetEvent(localEvent);
@ -1864,7 +1887,7 @@ TabChild::RecvRealTouchEvent(const WidgetTouchEvent& aEvent)
nsCOMPtr<nsPIDOMWindow> innerWindow = outerWindow->GetCurrentInnerWindow();
if (innerWindow && innerWindow->HasTouchEventListeners()) {
SendContentReceivedTouch(nsIPresShell::gPreventMouseEvents);
SendContentReceivedTouch(aGuid, nsIPresShell::gPreventMouseEvents);
}
} else {
UpdateTapState(aEvent, status);
@ -1874,9 +1897,10 @@ TabChild::RecvRealTouchEvent(const WidgetTouchEvent& aEvent)
}
bool
TabChild::RecvRealTouchMoveEvent(const WidgetTouchEvent& aEvent)
TabChild::RecvRealTouchMoveEvent(const WidgetTouchEvent& aEvent,
const ScrollableLayerGuid& aGuid)
{
return RecvRealTouchEvent(aEvent);
return RecvRealTouchEvent(aEvent, aGuid);
}
bool

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

@ -229,8 +229,10 @@ public:
virtual bool RecvRealMouseEvent(const mozilla::WidgetMouseEvent& event);
virtual bool RecvRealKeyEvent(const mozilla::WidgetKeyboardEvent& event);
virtual bool RecvMouseWheelEvent(const mozilla::WidgetWheelEvent& event);
virtual bool RecvRealTouchEvent(const WidgetTouchEvent& event);
virtual bool RecvRealTouchMoveEvent(const WidgetTouchEvent& event);
virtual bool RecvRealTouchEvent(const WidgetTouchEvent& aEvent,
const ScrollableLayerGuid& aGuid);
virtual bool RecvRealTouchMoveEvent(const WidgetTouchEvent& aEvent,
const ScrollableLayerGuid& aGuid);
virtual bool RecvKeyEvent(const nsString& aType,
const int32_t& aKeyCode,
const int32_t& aCharCode,
@ -451,6 +453,8 @@ private:
// Get the DOMWindowUtils for the top-level window in this tab.
already_AddRefed<nsIDOMWindowUtils> GetDOMWindowUtils();
// Get the Document for the top-level window in this tab.
already_AddRefed<nsIDocument> GetDocument();
class CachedFileDescriptorInfo;
class CachedFileDescriptorCallbackRunnable;

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

@ -649,7 +649,7 @@ bool TabParent::SendRealMouseEvent(WidgetMouseEvent& event)
return false;
}
WidgetMouseEvent e(event);
MaybeForwardEventToRenderFrame(event, &e);
MaybeForwardEventToRenderFrame(event, nullptr, &e);
if (!MapEventCoordinatesForChildProcess(&e)) {
return false;
}
@ -662,7 +662,7 @@ bool TabParent::SendMouseWheelEvent(WidgetWheelEvent& event)
return false;
}
WidgetWheelEvent e(event);
MaybeForwardEventToRenderFrame(event, &e);
MaybeForwardEventToRenderFrame(event, nullptr, &e);
if (!MapEventCoordinatesForChildProcess(&e)) {
return false;
}
@ -675,7 +675,7 @@ bool TabParent::SendRealKeyEvent(WidgetKeyboardEvent& event)
return false;
}
WidgetKeyboardEvent e(event);
MaybeForwardEventToRenderFrame(event, &e);
MaybeForwardEventToRenderFrame(event, nullptr, &e);
if (!MapEventCoordinatesForChildProcess(&e)) {
return false;
}
@ -720,13 +720,14 @@ bool TabParent::SendRealTouchEvent(WidgetTouchEvent& event)
}
}
MaybeForwardEventToRenderFrame(event, &e);
ScrollableLayerGuid guid;
MaybeForwardEventToRenderFrame(event, &guid, &e);
MapEventCoordinatesForChildProcess(mChildProcessOffsetAtTouchStart, &e);
return (e.message == NS_TOUCH_MOVE) ?
PBrowserParent::SendRealTouchMoveEvent(e) :
PBrowserParent::SendRealTouchEvent(e);
PBrowserParent::SendRealTouchMoveEvent(e, guid) :
PBrowserParent::SendRealTouchEvent(e, guid);
}
/*static*/ TabParent*
@ -1576,10 +1577,11 @@ TabParent::UseAsyncPanZoom()
void
TabParent::MaybeForwardEventToRenderFrame(const WidgetInputEvent& aEvent,
ScrollableLayerGuid* aOutTargetGuid,
WidgetInputEvent* aOutEvent)
{
if (RenderFrameParent* rfp = GetRenderFrame()) {
rfp->NotifyInputEvent(aEvent, aOutEvent);
rfp->NotifyInputEvent(aEvent, aOutTargetGuid, aOutEvent);
}
}
@ -1613,21 +1615,25 @@ TabParent::RecvPRenderFrameConstructor(PRenderFrameParent* actor,
}
bool
TabParent::RecvZoomToRect(const CSSRect& aRect)
TabParent::RecvZoomToRect(const uint32_t& aPresShellId,
const ViewID& aViewId,
const CSSRect& aRect)
{
if (RenderFrameParent* rfp = GetRenderFrame()) {
rfp->ZoomToRect(aRect);
rfp->ZoomToRect(aPresShellId, aViewId, aRect);
}
return true;
}
bool
TabParent::RecvUpdateZoomConstraints(const bool& aAllowZoom,
TabParent::RecvUpdateZoomConstraints(const uint32_t& aPresShellId,
const ViewID& aViewId,
const bool& aAllowZoom,
const CSSToScreenScale& aMinZoom,
const CSSToScreenScale& aMaxZoom)
{
if (RenderFrameParent* rfp = GetRenderFrame()) {
rfp->UpdateZoomConstraints(aAllowZoom, aMinZoom, aMaxZoom);
rfp->UpdateZoomConstraints(aPresShellId, aViewId, aAllowZoom, aMinZoom, aMaxZoom);
}
return true;
}
@ -1644,10 +1650,11 @@ TabParent::RecvUpdateScrollOffset(const uint32_t& aPresShellId,
}
bool
TabParent::RecvContentReceivedTouch(const bool& aPreventDefault)
TabParent::RecvContentReceivedTouch(const ScrollableLayerGuid& aGuid,
const bool& aPreventDefault)
{
if (RenderFrameParent* rfp = GetRenderFrame()) {
rfp->ContentReceivedTouch(aPreventDefault);
rfp->ContentReceivedTouch(aGuid, aPreventDefault);
}
return true;
}

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

@ -162,12 +162,17 @@ public:
virtual bool RecvGetDPI(float* aValue);
virtual bool RecvGetDefaultScale(double* aValue);
virtual bool RecvGetWidgetNativeData(WindowsHandle* aValue);
virtual bool RecvZoomToRect(const CSSRect& aRect);
virtual bool RecvUpdateZoomConstraints(const bool& aAllowZoom,
virtual bool RecvZoomToRect(const uint32_t& aPresShellId,
const ViewID& aViewId,
const CSSRect& aRect);
virtual bool RecvUpdateZoomConstraints(const uint32_t& aPresShellId,
const ViewID& aViewId,
const bool& aAllowZoom,
const CSSToScreenScale& aMinZoom,
const CSSToScreenScale& aMaxZoom);
virtual bool RecvUpdateScrollOffset(const uint32_t& aPresShellId, const ViewID& aViewId, const CSSIntPoint& aScrollOffset);
virtual bool RecvContentReceivedTouch(const bool& aPreventDefault);
virtual bool RecvContentReceivedTouch(const ScrollableLayerGuid& aGuid,
const bool& aPreventDefault);
virtual bool RecvRecordingDeviceEvents(const nsString& aRecordingStatus,
const bool& aIsAudio,
const bool& aIsVideo);
@ -343,8 +348,11 @@ private:
// If we have a render frame currently, notify it that we're about
// to dispatch |aEvent| to our child. If there's a relevant
// transform in place, |aOutEvent| is the transformed |aEvent| to
// dispatch to content.
// dispatch to content. |aOutTargetGuid| will contain the identifier
// of the APZC instance that handled the event. aOutTargetGuid may be
// null but aOutEvent must not be.
void MaybeForwardEventToRenderFrame(const WidgetInputEvent& aEvent,
ScrollableLayerGuid* aOutTargetGuid,
WidgetInputEvent* aOutEvent);
// The offset for the child process which is sampled at touch start. This
// means that the touch events are relative to where the frame was at the

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

@ -95,6 +95,15 @@ this.SystemMessagePermissionsTable = {
"cdma-info-rec-received": {
"mobileconnection": []
},
"nfc-manager-tech-discovered": {
"nfc-manager": []
},
"nfc-manager-tech-lost": {
"nfc-manager": []
},
"nfc-powerlevel-change": {
"settings": ["read", "write"]
}
};
this.SystemMessagePermissionsChecker = {

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

@ -37,9 +37,6 @@ const NS_XPCOM_SHUTDOWN_OBSERVER_ID = "xpcom-shutdown";
const kNetworkInterfaceStateChangedTopic = "network-interface-state-changed";
const kMobileMessageDeletedObserverTopic = "mobile-message-deleted";
const kPrefRilMmsc = "ril.mms.mmsc";
const kPrefRilMmsProxy = "ril.mms.mmsproxy";
const kPrefRilMmsPort = "ril.mms.mmsport";
const kPrefRilRadioDisabled = "ril.radio.disabled";
// HTTP status codes:
@ -174,7 +171,8 @@ MmsConnection.prototype = {
}
let port = this.mmsPort;
if (port == -1) {
if (port <= 0) {
port = 80;
if (DEBUG) debug("getProxyInfo: port is not valid. Set to defult (80).");
}
@ -190,7 +188,7 @@ MmsConnection.prototype = {
// For keeping track of the radio status.
radioDisabled: false,
settings: ["ril.radio.disabled"],
settings: [kPrefRilRadioDisabled],
connected: false,
//A queue to buffer the MMS HTTP requests when the MMS network
@ -1172,6 +1170,7 @@ SendTransaction.prototype = Object.create(CancellableTransaction.prototype, {
if (!this.istreamComposed) {
this.loadBlobs(this.msg.parts, (function () {
this.istream = MMS.PduHelper.compose(null, this.msg);
this.istreamSize = this.istream.available();
this.istreamComposed = true;
if (this.isCancelled) {
this.runCallbackIfValid(_MMS_ERROR_MESSAGE_DELETED, null);
@ -1202,6 +1201,13 @@ SendTransaction.prototype = Object.create(CancellableTransaction.prototype, {
this.retryCount++;
// the input stream may be read in the previous failure request so
// we have to re-compose it.
if (this.istreamSize == null ||
this.istreamSize != this.istream.available()) {
this.istream = MMS.PduHelper.compose(null, this.msg);
}
this.timer.initWithCallback(this.send.bind(this, retryCallback),
PREF_SEND_RETRY_INTERVAL,
Ci.nsITimer.TYPE_ONE_SHOT);

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

@ -2446,17 +2446,18 @@ this.PduHelper = {
// Encode headersLen, DataLen
let headersLen = data.offset;
let content = part.content;
UintVar.encode(data, headersLen);
if (typeof part.content === "string") {
if (typeof content === "string") {
let charset;
if (contentType && contentType.params && contentType.params.charset &&
contentType.params.charset.charset) {
charset = contentType.params.charset.charset;
}
part.content = this.encodeStringContent(part.content, charset);
UintVar.encode(data, part.content.length);
content = this.encodeStringContent(content, charset);
UintVar.encode(data, content.length);
} else if (part.content instanceof Uint8Array) {
UintVar.encode(data, part.content.length);
UintVar.encode(data, content.length);
} else {
throw new TypeError();
}
@ -2470,7 +2471,7 @@ this.PduHelper = {
// Append per-part header
this.appendArrayToMultiStream(multiStream, data.array, data.offset);
// Append part content
this.appendArrayToMultiStream(multiStream, part.content, part.content.length);
this.appendArrayToMultiStream(multiStream, content, content.length);
}
},
};

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

@ -53,9 +53,7 @@ function do_check_throws(func, result, stack)
function wsp_test_func(func, data, expect) {
let result_str = JSON.stringify(func(data));
let expect_str = JSON.stringify(expect);
if (result_str !== expect_str) {
do_throw("expect value: '" + expect_str + "', got '" + result_str + "'");
}
do_check_eq(result_str, expect_str);
}
/**

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

@ -1314,3 +1314,44 @@ add_test(function StringContent_decode() {
run_next_test();
});
//// PduHelper.composeMultiPart ////
add_test(function test_PduHelper_composeMultiPart() {
let multiStream = Components.classes["@mozilla.org/io/multiplex-input-stream;1"]
.createInstance(Ci.nsIMultiplexInputStream);
let uint8Array = new Uint8Array(5);
uint8Array[0] = 0x00;
uint8Array[1] = 0x01;
uint8Array[2] = 0x02;
uint8Array[3] = 0x03;
uint8Array[4] = 0x04;
let parts = [
{
content: "content",
headers: {
"content-type": {
media: "text/plain",
params: {}
}
}
},
{
content: uint8Array,
headers: {
"content-type": {
media: "text/plain",
params: {}
}
}
}
];
let beforeCompose = JSON.stringify(parts);
WSP.PduHelper.composeMultiPart(multiStream, parts);
let afterCompose = JSON.stringify(parts);
do_check_eq(beforeCompose, afterCompose);
run_next_test();
});

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

@ -97,6 +97,9 @@ if CONFIG['MOZ_PAY']:
if CONFIG['MOZ_GAMEPAD']:
PARALLEL_DIRS += ['gamepad']
if CONFIG['MOZ_NFC']:
PARALLEL_DIRS += ['nfc']
# bindings/test is here, because it needs to build after bindings/, and
# we build subdirectories before ourselves.
TEST_DIRS += [

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

@ -11,7 +11,7 @@ interface nsIDOMMozMobileNetworkInfo;
interface nsIDOMMozMobileCellInfo;
interface nsIDOMMozMobileCFInfo;
[scriptable, builtinclass, uuid(095b3720-058c-11e3-8ffd-0800200c9a66)]
[scriptable, builtinclass, uuid(052550e3-7466-4941-80d7-405c169652f9)]
interface nsIDOMMozMobileConnection : nsIDOMEventTarget
{
const long ICC_SERVICE_CLASS_VOICE = (1 << 0);
@ -69,6 +69,12 @@ interface nsIDOMMozMobileConnection : nsIDOMEventTarget
*/
readonly attribute nsIDOMMozMobileConnectionInfo data;
/**
* Integrated Circuit Card Identifier of the SIM this
* mobile connection corresponds to.
*/
readonly attribute DOMString iccId;
/**
* The selection mode of the voice and data networks.
*
@ -383,6 +389,12 @@ interface nsIDOMMozMobileConnection : nsIDOMEventTarget
* changes.
*/
[implicit_jscontext] attribute jsval onotastatuschange;
/**
* The 'oniccchange' event is notified whenever the iccid value
* changes.
*/
[implicit_jscontext] attribute jsval oniccchange;
};
[scriptable, uuid(49706beb-a160-40b7-b745-50f62e389a2c)]

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

@ -211,11 +211,12 @@ interface nsIDOMTCPSocket : nsISupports
};
/*
* Internal interfaces for use in cross-process socket implementation.
* This interface is implemented in TCPSocket.js as an internal interfaces
* for use in cross-process socket implementation.
* Needed to account for multiple possible types that can be provided to
* the socket callbacks as arguments.
*/
[scriptable, uuid(234c664c-3d6c-4859-b45c-4e9a98cb5bdc)]
[scriptable, uuid(017f130f-2477-4215-8783-57eada957699)]
interface nsITCPSocketInternal : nsISupports {
// Trigger the callback for |type| and provide a DOMError() object with the given data
void callListenerError(in DOMString type, in DOMString name);
@ -229,8 +230,20 @@ interface nsITCPSocketInternal : nsISupports {
// Trigger the callback for |type| with no argument
void callListenerVoid(in DOMString type);
// Update the DOM object's readyState and bufferedAmount values with the provided data
void updateReadyStateAndBuffered(in DOMString readyState, in uint32_t bufferedAmount);
// Update the DOM object's readyState.
// @param readyState
// new ready state to be set to TCPSocket.
void updateReadyState(in DOMString readyState);
// Update the DOM object's bufferedAmount value with a tracking number to
// ensure the update request is sent after child's send() invocation.
// @param bufferedAmount
// TCPSocket parent's bufferedAmount.
// @param trackingNumber
// A number to ensure the bufferedAmount is updated after data
// from child are sent to parent.
void updateBufferedAmount(in uint32_t bufferedAmount,
in uint32_t trackingNumber);
// Create a socket object on the parent side.
// This is called in accepting any open request on the parent side.
@ -259,6 +272,18 @@ interface nsITCPSocketInternal : nsISupports {
// Set App ID.
void setAppId(in unsigned long appId);
// Set a callback that handles the request from a TCP socket parent when that
// socket parent wants to notify that its bufferedAmount is updated.
void setOnUpdateBufferedAmountHandler(in jsval handler);
// Providing child process with ability to pass more arguments to parent's
// send() function.
// @param trackingNumber
// To ensure the request to update bufferedAmount in child is after
// lastest send() invocation from child.
void onRecvSendFromChild(in jsval data, in unsigned long byteOffset,
in unsigned long byteLength, in unsigned long trackingNumber);
};
/**

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

@ -8,22 +8,26 @@ interface nsITCPSocketInternal;
interface nsIDOMWindow;
// Interface to allow the content process socket to reach the IPC bridge.
[scriptable, uuid(ada5342d-6d45-4ff1-a7d3-6a4b150d0385)]
// Implemented in C++ as TCPSocketChild, referenced as _socketBridge in TCPSocket.js
[scriptable, uuid(292ebb3a-beac-4e06-88b0-b5b4e88ebd1c)]
interface nsITCPSocketChild : nsISupports
{
// Tell the chrome process to open a corresponding connection with the given parameters
[implicit_jscontext]
void open(in nsITCPSocketInternal socket, in DOMString host,
in unsigned short port, in boolean ssl, in DOMString binaryType,
in nsIDOMWindow window, in jsval windowVal);
void sendOpen(in nsITCPSocketInternal socket, in DOMString host,
in unsigned short port, in boolean ssl, in DOMString binaryType,
in nsIDOMWindow window, in jsval windowVal);
// Tell the chrome process to perform send and update the tracking number.
[implicit_jscontext]
void sendSend(in jsval data, in unsigned long byteOffset,
in unsigned long byteLength, in unsigned long trackingNumber);
// Tell the chrome process to perform equivalent operations to all following methods
[implicit_jscontext]
void send(in jsval data, in unsigned long byteOffset, in unsigned long byteLength);
void resume();
void suspend();
void close();
void startTLS();
void sendResume();
void sendSuspend();
void sendClose();
void sendStartTLS();
/**
* Initialize the TCP socket on the child side for IPC. It is called from the child side,

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

@ -9,20 +9,28 @@ interface nsIDOMTCPServerSocket;
interface nsITCPServerSocketParent;
interface nsITCPSocketIntermediary;
// Interface required to allow the TCP socket object in the parent process
// to talk to the parent IPC actor
[scriptable, uuid(123f654b-4435-43c8-8447-db1b5420a1c2)]
// Interface required to allow the TCP socket object (TCPSocket.js) in the
// parent process to talk to the parent IPC actor, TCPSocketParent, which
// is written in C++.
[scriptable, uuid(868662a4-681c-4b89-9f02-6fe5b7ace265)]
interface nsITCPSocketParent : nsISupports
{
[implicit_jscontext] void initJS(in jsval intermediary);
// Trigger a callback in the content process for |type|, providing a serialized
// argument of |data|, and update the child's readyState and bufferedAmount values
// with the given values.
[implicit_jscontext] void sendCallback(in DOMString type,
in jsval data,
in DOMString readyState,
in uint32_t bufferedAmount);
// argument of |data|, and update the child's readyState value with the given
// values.
//
// @param type
// Event type: 'onopen', 'ondata', 'onerror' or 'onclose'. 'odrain' is
// controlled by child.
// @param data
// Serialized data that is passed to event handler.
// @param readyState
// Current ready state.
[implicit_jscontext] void sendEvent(in DOMString type,
in jsval data,
in DOMString readyState);
// Initialize a parent socket object. It is called from the parent side socket,
// which is generated in accepting any open request on the parent side.
@ -34,11 +42,27 @@ interface nsITCPSocketParent : nsISupports
// Intermediate class object. See nsITCPSocketIntermediary.
[implicit_jscontext] void setSocketAndIntermediary(in nsIDOMTCPSocket socket,
in nsITCPSocketIntermediary intermediary);
// When parent's buffered amount is updated and it wants to inform child to
// update the bufferedAmount as well.
//
// @param bufferedAmount
// The new value of bufferedAmount that is going to be set to child's
// bufferedAmount.
// @param trackingNumber
// Parent's current tracking number, reflecting the number of calls to
// send() on the child process. This number is sent back to the child
// to make sure the bufferedAmount updated on the child will correspond
// to the latest call of send().
void sendUpdateBufferedAmount(in uint32_t bufferedAmount, in uint32_t trackingNumber);
};
// Intermediate class to handle sending multiple possible data types
// and kicking off the chrome process socket object's connection.
[scriptable, uuid(be67b1b8-03b0-4171-a791-d004458021b6)]
// This interface is the bridge of TCPSocketParent, which is written in C++,
// and TCPSocket, which is written in Javascript. TCPSocketParentIntermediary
// implements nsITCPSocketIntermediary in Javascript.
[scriptable, uuid(c434224a-dbb7-4869-8b2b-e49cee990e85)]
interface nsITCPSocketIntermediary : nsISupports {
// Open the connection to the server with the given parameters
nsIDOMTCPSocket open(in nsITCPSocketParent parent,
@ -51,9 +75,9 @@ interface nsITCPSocketIntermediary : nsISupports {
in unsigned short port, in unsigned short backlog,
in DOMString binaryType);
// Send a basic string along the connection
void sendString(in DOMString data);
// Called when received a child request to send a string.
void onRecvSendString(in DOMString data, in uint32_t trackingNumber);
// Send a typed array
void sendArrayBuffer(in jsval data);
// Called when received a child request to send an array buffer.
void onRecvSendArrayBuffer(in jsval data, in uint32_t trackingNumber);
};

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

@ -77,15 +77,14 @@ NS_IMPL_EVENT_HANDLER(MobileConnection, dataerror)
NS_IMPL_EVENT_HANDLER(MobileConnection, cfstatechange)
NS_IMPL_EVENT_HANDLER(MobileConnection, emergencycbmodechange)
NS_IMPL_EVENT_HANDLER(MobileConnection, otastatuschange)
NS_IMPL_EVENT_HANDLER(MobileConnection, iccchange)
MobileConnection::MobileConnection()
MobileConnection::MobileConnection(uint32_t aClientId)
: mClientId(aClientId)
{
mProvider = do_GetService(NS_RILCONTENTHELPER_CONTRACTID);
mWindow = nullptr;
// TODO: Bug 814629 - WebMobileConnection API: support multiple sim cards
mClientId = 0;
// Not being able to acquire the provider isn't fatal since we check
// for it explicitly below.
if (!mProvider) {
@ -126,35 +125,35 @@ MobileConnection::Shutdown()
// nsIDOMMozMobileConnection
NS_IMETHODIMP
MobileConnection::GetLastKnownNetwork(nsAString& network)
MobileConnection::GetLastKnownNetwork(nsAString& aNetwork)
{
network.SetIsVoid(true);
aNetwork.SetIsVoid(true);
if (!CheckPermission("mobilenetwork")) {
return NS_OK;
}
network = mozilla::Preferences::GetString("ril.lastKnownNetwork");
aNetwork = mozilla::Preferences::GetString("ril.lastKnownNetwork");
return NS_OK;
}
NS_IMETHODIMP
MobileConnection::GetLastKnownHomeNetwork(nsAString& network)
MobileConnection::GetLastKnownHomeNetwork(nsAString& aNetwork)
{
network.SetIsVoid(true);
aNetwork.SetIsVoid(true);
if (!CheckPermission("mobilenetwork")) {
return NS_OK;
}
network = mozilla::Preferences::GetString("ril.lastKnownHomeNetwork");
aNetwork = mozilla::Preferences::GetString("ril.lastKnownHomeNetwork");
return NS_OK;
}
// All fields below require the "mobileconnection" permission.
bool
MobileConnection::CheckPermission(const char* type)
MobileConnection::CheckPermission(const char* aType)
{
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_TRUE(window, false);
@ -164,47 +163,58 @@ MobileConnection::CheckPermission(const char* type)
NS_ENSURE_TRUE(permMgr, false);
uint32_t permission = nsIPermissionManager::DENY_ACTION;
permMgr->TestPermissionFromWindow(window, type, &permission);
permMgr->TestPermissionFromWindow(window, aType, &permission);
return permission == nsIPermissionManager::ALLOW_ACTION;
}
NS_IMETHODIMP
MobileConnection::GetVoice(nsIDOMMozMobileConnectionInfo** voice)
MobileConnection::GetVoice(nsIDOMMozMobileConnectionInfo** aVoice)
{
*voice = nullptr;
*aVoice = nullptr;
if (!mProvider || !CheckPermission("mobileconnection")) {
return NS_OK;
}
return mProvider->GetVoiceConnectionInfo(mClientId, voice);
return mProvider->GetVoiceConnectionInfo(mClientId, aVoice);
}
NS_IMETHODIMP
MobileConnection::GetData(nsIDOMMozMobileConnectionInfo** data)
MobileConnection::GetData(nsIDOMMozMobileConnectionInfo** aData)
{
*data = nullptr;
*aData = nullptr;
if (!mProvider || !CheckPermission("mobileconnection")) {
return NS_OK;
}
return mProvider->GetDataConnectionInfo(mClientId, data);
return mProvider->GetDataConnectionInfo(mClientId, aData);
}
NS_IMETHODIMP
MobileConnection::GetNetworkSelectionMode(nsAString& networkSelectionMode)
MobileConnection::GetIccId(nsAString& aIccId)
{
networkSelectionMode.SetIsVoid(true);
aIccId.SetIsVoid(true);
if (!mProvider || !CheckPermission("mobileconnection")) {
return NS_OK;
}
return mProvider->GetNetworkSelectionMode(mClientId, networkSelectionMode);
return mProvider->GetIccId(mClientId, aIccId);
}
NS_IMETHODIMP
MobileConnection::GetNetworks(nsIDOMDOMRequest** request)
MobileConnection::GetNetworkSelectionMode(nsAString& aNetworkSelectionMode)
{
*request = nullptr;
aNetworkSelectionMode.SetIsVoid(true);
if (!mProvider || !CheckPermission("mobileconnection")) {
return NS_OK;
}
return mProvider->GetNetworkSelectionMode(mClientId, aNetworkSelectionMode);
}
NS_IMETHODIMP
MobileConnection::GetNetworks(nsIDOMDOMRequest** aRequest)
{
*aRequest = nullptr;
if (!CheckPermission("mobileconnection")) {
return NS_OK;
@ -214,13 +224,13 @@ MobileConnection::GetNetworks(nsIDOMDOMRequest** request)
return NS_ERROR_FAILURE;
}
return mProvider->GetNetworks(mClientId, GetOwner(), request);
return mProvider->GetNetworks(mClientId, GetOwner(), aRequest);
}
NS_IMETHODIMP
MobileConnection::SelectNetwork(nsIDOMMozMobileNetworkInfo* network, nsIDOMDOMRequest** request)
MobileConnection::SelectNetwork(nsIDOMMozMobileNetworkInfo* aNetwork, nsIDOMDOMRequest** aRequest)
{
*request = nullptr;
*aRequest = nullptr;
if (!CheckPermission("mobileconnection")) {
return NS_OK;
@ -230,13 +240,13 @@ MobileConnection::SelectNetwork(nsIDOMMozMobileNetworkInfo* network, nsIDOMDOMRe
return NS_ERROR_FAILURE;
}
return mProvider->SelectNetwork(mClientId, GetOwner(), network, request);
return mProvider->SelectNetwork(mClientId, GetOwner(), aNetwork, aRequest);
}
NS_IMETHODIMP
MobileConnection::SelectNetworkAutomatically(nsIDOMDOMRequest** request)
MobileConnection::SelectNetworkAutomatically(nsIDOMDOMRequest** aRequest)
{
*request = nullptr;
*aRequest = nullptr;
if (!CheckPermission("mobileconnection")) {
return NS_OK;
@ -246,7 +256,7 @@ MobileConnection::SelectNetworkAutomatically(nsIDOMDOMRequest** request)
return NS_ERROR_FAILURE;
}
return mProvider->SelectNetworkAutomatically(mClientId, GetOwner(), request);
return mProvider->SelectNetworkAutomatically(mClientId, GetOwner(), aRequest);
}
NS_IMETHODIMP
@ -638,7 +648,9 @@ MobileConnection::NotifyOtaStatusChanged(const nsAString& aStatus)
NS_IMETHODIMP
MobileConnection::NotifyIccChanged()
{
// TODO: Bug 814629 - WebMobileConnection API: support multiple sim cards
// Return NS_OK for now, will be implemented in Bug 814629.
return NS_OK;
}
if (!CheckPermission("mobileconnection")) {
return NS_OK;
}
return DispatchTrustedEvent(NS_LITERAL_STRING("iccchange"));
}

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

@ -35,7 +35,7 @@ public:
NS_REALLY_FORWARD_NSIDOMEVENTTARGET(nsDOMEventTargetHelper)
MobileConnection();
MobileConnection(uint32_t aClientId);
void Init(nsPIDOMWindow *aWindow);
void Shutdown();
@ -50,7 +50,7 @@ private:
uint32_t mClientId;
bool CheckPermission(const char* type);
bool CheckPermission(const char* aType);
};
} // namespace network

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

@ -0,0 +1,81 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "MobileConnectionArray.h"
#include "mozilla/dom/MozMobileConnectionArrayBinding.h"
#include "mozilla/Preferences.h"
using namespace mozilla::dom::network;
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_2(MobileConnectionArray,
mWindow,
mMobileConnections)
NS_IMPL_CYCLE_COLLECTING_ADDREF(MobileConnectionArray)
NS_IMPL_CYCLE_COLLECTING_RELEASE(MobileConnectionArray)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MobileConnectionArray)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
MobileConnectionArray::MobileConnectionArray(nsPIDOMWindow* aWindow)
: mWindow(aWindow)
{
int32_t numRil = mozilla::Preferences::GetInt("ril.numRadioInterfaces", 1);
MOZ_ASSERT(numRil > 0);
for (int32_t id = 0; id < numRil; id++) {
nsRefPtr<MobileConnection> mobileConnection = new MobileConnection(id);
mobileConnection->Init(aWindow);
mMobileConnections.AppendElement(mobileConnection);
}
SetIsDOMBinding();
}
MobileConnectionArray::~MobileConnectionArray()
{
for (uint32_t i = 0; i < mMobileConnections.Length(); i++) {
mMobileConnections[i]->Shutdown();
}
mMobileConnections.Clear();
}
nsPIDOMWindow*
MobileConnectionArray::GetParentObject() const
{
MOZ_ASSERT(mWindow);
return mWindow;
}
JSObject*
MobileConnectionArray::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope)
{
return MozMobileConnectionArrayBinding::Wrap(aCx, aScope, this);
}
nsIDOMMozMobileConnection*
MobileConnectionArray::Item(uint32_t aIndex) const
{
bool unused;
return IndexedGetter(aIndex, unused);
}
uint32_t
MobileConnectionArray::Length() const
{
return mMobileConnections.Length();
}
nsIDOMMozMobileConnection*
MobileConnectionArray::IndexedGetter(uint32_t aIndex, bool& aFound) const
{
aFound = false;
aFound = aIndex < mMobileConnections.Length();
return aFound ? mMobileConnections[aIndex] : nullptr;
}

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

@ -0,0 +1,56 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_network_MobileConnectionArray_h__
#define mozilla_dom_network_MobileConnectionArray_h__
#include "nsWrapperCache.h"
#include "mozilla/dom/network/MobileConnection.h"
class nsIDOMMozMobileConnection;
namespace mozilla {
namespace dom {
namespace network {
class MobileConnectionArray MOZ_FINAL : public nsISupports,
public nsWrapperCache
{
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(MobileConnectionArray)
MobileConnectionArray(nsPIDOMWindow* aWindow);
nsPIDOMWindow*
GetParentObject() const;
// WrapperCache
virtual JSObject*
WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
// WebIDL
nsIDOMMozMobileConnection*
Item(uint32_t aIndex) const;
uint32_t
Length() const;
nsIDOMMozMobileConnection*
IndexedGetter(uint32_t aIndex, bool& aFound) const;
private:
~MobileConnectionArray();
nsCOMPtr<nsPIDOMWindow> mWindow;
nsTArray<nsRefPtr<MobileConnection>> mMobileConnections;
};
} // namespace network
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_network_MobileConnectionArray_h__

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

@ -362,6 +362,7 @@ this.NetworkStatsService = {
this.updateQueue.push({netId: aNetId, callbacks: [aCallback]});
} else {
this.updateQueue[index].callbacks.push(aCallback);
return;
}
// Call the function that process the elements of the queue.

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

@ -35,16 +35,35 @@ protocol PTCPSocket
manager PNecko;
parent:
// Forward calling to child's open() method to parent, expect TCPOptions
// is expanded to |useSSL| (from TCPOptions.useSecureTransport) and
// |binaryType| (from TCPOption.binaryType).
Open(nsString host, uint16_t port, bool useSSL, nsString binaryType);
Data(SendableData data);
// When child's send() is called, this message requrests parent to send
// data and update it's trackingNumber.
Data(SendableData data, uint32_t trackingNumber);
// Forward calling to child's upgradeToSecure() method to parent.
StartTLS();
// Forward calling to child's send() method to parent.
Suspend();
// Forward calling to child's resume() method to parent.
Resume();
// Forward calling to child's close() method to parent.
Close();
child:
Callback(nsString type, CallbackData data,
nsString readyState, uint32_t bufferedAmount);
// Forward events that are dispatched by parent.
Callback(nsString type, CallbackData data, nsString readyState);
// Update child's bufferedAmount when parent's bufferedAmount is updated.
// trackingNumber is also passed back to child to ensure the bufferedAmount
// is corresponding the last call to send().
UpdateBufferedAmount(uint32_t bufferedAmount, uint32_t trackingNumber);
both:
RequestDelete();

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

@ -162,6 +162,10 @@ TCPSocket.prototype = {
_waitingForStartTLS: false,
_pendingDataAfterStartTLS: [],
// Used to notify when update bufferedAmount is updated.
_onUpdateBufferedAmount: null,
_trackingNumber: 0,
#ifdef MOZ_WIDGET_GONK
// Network statistics (Gonk-specific feature)
_txBytes: 0,
@ -242,6 +246,12 @@ TCPSocket.prototype = {
.createTransport(options, 1, host, port, null);
},
_sendBufferedAmount: function ts_sendBufferedAmount() {
if (this._onUpdateBufferedAmount) {
this._onUpdateBufferedAmount(this.bufferedAmount, this._trackingNumber);
}
},
_ensureCopying: function ts_ensureCopying() {
let self = this;
if (this._asyncCopierActive) {
@ -254,6 +264,7 @@ TCPSocket.prototype = {
onStopRequest: function ts_output_onStopRequest(request, context, status) {
self._asyncCopierActive = false;
self._multiplexStream.removeStream(0);
self._sendBufferedAmount();
if (!Components.isSuccessCode(status)) {
// Note that we can/will get an error here as well as in the
@ -280,7 +291,9 @@ TCPSocket.prototype = {
}
}
if (self._waitingForDrain) {
// If we have a callback to update bufferedAmount, we let child to
// decide whether ondrain should be dispatched.
if (self._waitingForDrain && !self._onUpdateBufferedAmount) {
self._waitingForDrain = false;
self.callListener("drain");
}
@ -382,9 +395,36 @@ TCPSocket.prototype = {
this.callListener(type);
},
updateReadyStateAndBuffered: function ts_setReadyState(readyState, bufferedAmount) {
/**
* This method is expected to be called by TCPSocketChild to update child's
* readyState.
*/
updateReadyState: function ts_updateReadyState(readyState) {
if (!this._inChild) {
LOG("Calling updateReadyState in parent, which should only be called " +
"in child");
return;
}
this._readyState = readyState;
},
updateBufferedAmount: function ts_updateBufferedAmount(bufferedAmount, trackingNumber) {
if (trackingNumber != this._trackingNumber) {
LOG("updateBufferedAmount is called but trackingNumber is not matched " +
"parent's trackingNumber: " + trackingNumber + ", child's trackingNumber: " +
this._trackingNumber);
return;
}
this._bufferedAmount = bufferedAmount;
if (bufferedAmount == 0) {
if (this._waitingForDrain) {
this._waitingForDrain = false;
this.callListener("drain");
}
} else {
LOG("bufferedAmount is updated but haven't reaches zero. bufferedAmount: " +
bufferedAmount);
}
},
createAcceptedParent: function ts_createAcceptedParent(transport, binaryType) {
@ -420,6 +460,25 @@ TCPSocket.prototype = {
#endif
},
setOnUpdateBufferedAmountHandler: function(aFunction) {
if (typeof(aFunction) == 'function') {
this._onUpdateBufferedAmount = aFunction;
} else {
throw new Error("only function can be passed to " +
"setOnUpdateBufferedAmountHandler");
}
},
/**
* Handle the requst of sending data and update trackingNumber from
* child.
* This function is expected to be called by TCPSocketChild.
*/
onRecvSendFromChild: function(data, byteOffset, byteLength, trackingNumber) {
this._trackingNumber = trackingNumber;
this.send(data, byteOffset, byteLength);
},
/* end nsITCPSocketInternal methods */
initWindowless: function ts_initWindowless() {
@ -517,8 +576,8 @@ TCPSocket.prototype = {
if (this._inChild) {
that._socketBridge = Cc["@mozilla.org/tcp-socket-child;1"]
.createInstance(Ci.nsITCPSocketChild);
that._socketBridge.open(that, host, port, !!that._ssl,
that._binaryType, this.useWin, this.useWin || this);
that._socketBridge.sendOpen(that, host, port, !!that._ssl,
that._binaryType, this.useWin, this.useWin || this);
return that;
}
@ -551,7 +610,7 @@ TCPSocket.prototype = {
this._ssl = 'ssl';
if (this._inChild) {
this._socketBridge.startTLS();
this._socketBridge.sendStartTLS();
return;
}
@ -585,7 +644,7 @@ TCPSocket.prototype = {
this._readyState = kCLOSING;
if (this._inChild) {
this._socketBridge.close();
this._socketBridge.sendClose();
return;
}
@ -605,15 +664,27 @@ TCPSocket.prototype = {
}
if (this._inChild) {
this._socketBridge.send(data, byteOffset, byteLength);
this._socketBridge.sendSend(data, byteOffset, byteLength, ++this._trackingNumber);
}
let length = this._binaryType === "arraybuffer" ? byteLength : data.length;
let newBufferedAmount = this.bufferedAmount + length;
let bufferFull = newBufferedAmount >= BUFFER_SIZE;
if (bufferFull) {
// If we buffered more than some arbitrary amount of data,
// (65535 right now) we should tell the caller so they can
// wait until ondrain is called if they so desire. Once all the
// buffered data has been written to the socket, ondrain is
// called.
this._waitingForDrain = true;
}
var newBufferedAmount = this.bufferedAmount + length;
var bufferNotFull = newBufferedAmount < BUFFER_SIZE;
if (this._inChild) {
return bufferNotFull;
// In child, we just add buffer length to our bufferedAmount and let
// parent to update our bufferedAmount when data have been sent.
this._bufferedAmount = newBufferedAmount;
return !bufferFull;
}
let new_stream;
@ -633,15 +704,6 @@ TCPSocket.prototype = {
this._multiplexStream.appendStream(new_stream);
}
if (newBufferedAmount >= BUFFER_SIZE) {
// If we buffered more than some arbitrary amount of data,
// (65535 right now) we should tell the caller so they can
// wait until ondrain is called if they so desire. Once all the
//buffered data has been written to the socket, ondrain is
// called.
this._waitingForDrain = true;
}
this._ensureCopying();
#ifdef MOZ_WIDGET_GONK
@ -650,12 +712,12 @@ TCPSocket.prototype = {
this._saveNetworkStats(false);
#endif
return bufferNotFull;
return !bufferFull;
},
suspend: function ts_suspend() {
if (this._inChild) {
this._socketBridge.suspend();
this._socketBridge.sendSuspend();
return;
}
@ -668,7 +730,7 @@ TCPSocket.prototype = {
resume: function ts_resume() {
if (this._inChild) {
this._socketBridge.resume();
this._socketBridge.sendResume();
return;
}

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

@ -77,10 +77,11 @@ TCPSocketChild::TCPSocketChild()
}
NS_IMETHODIMP
TCPSocketChild::Open(nsITCPSocketInternal* aSocket, const nsAString& aHost,
uint16_t aPort, bool aUseSSL, const nsAString& aBinaryType,
nsIDOMWindow* aWindow, const JS::Value& aWindowObj,
JSContext* aCx)
TCPSocketChild::SendOpen(nsITCPSocketInternal* aSocket,
const nsAString& aHost, uint16_t aPort,
bool aUseSSL, const nsAString& aBinaryType,
nsIDOMWindow* aWindow, const JS::Value& aWindowObj,
JSContext* aCx)
{
mSocket = aSocket;
@ -91,7 +92,8 @@ TCPSocketChild::Open(nsITCPSocketInternal* aSocket, const nsAString& aHost,
}
AddIPDLReference();
gNeckoChild->SendPTCPSocketConstructor(this);
SendOpen(nsString(aHost), aPort, aUseSSL, nsString(aBinaryType));
PTCPSocketChild::SendOpen(nsString(aHost), aPort,
aUseSSL, nsString(aBinaryType));
return NS_OK;
}
@ -115,13 +117,22 @@ TCPSocketChild::~TCPSocketChild()
{
}
bool
TCPSocketChild::RecvUpdateBufferedAmount(const uint32_t& aBuffered,
const uint32_t& aTrackingNumber)
{
if (NS_FAILED(mSocket->UpdateBufferedAmount(aBuffered, aTrackingNumber))) {
NS_ERROR("Shouldn't fail!");
}
return true;
}
bool
TCPSocketChild::RecvCallback(const nsString& aType,
const CallbackData& aData,
const nsString& aReadyState,
const uint32_t& aBuffered)
const nsString& aReadyState)
{
if (NS_FAILED(mSocket->UpdateReadyStateAndBuffered(aReadyState, aBuffered)))
if (NS_FAILED(mSocket->UpdateReadyState(aReadyState)))
NS_ERROR("Shouldn't fail!");
nsresult rv = NS_ERROR_FAILURE;
@ -159,46 +170,46 @@ TCPSocketChild::RecvCallback(const nsString& aType,
}
NS_IMETHODIMP
TCPSocketChild::StartTLS()
TCPSocketChild::SendStartTLS()
{
SendStartTLS();
PTCPSocketChild::SendStartTLS();
return NS_OK;
}
NS_IMETHODIMP
TCPSocketChild::Suspend()
TCPSocketChild::SendSuspend()
{
SendSuspend();
PTCPSocketChild::SendSuspend();
return NS_OK;
}
NS_IMETHODIMP
TCPSocketChild::Resume()
TCPSocketChild::SendResume()
{
SendResume();
PTCPSocketChild::SendResume();
return NS_OK;
}
NS_IMETHODIMP
TCPSocketChild::Close()
TCPSocketChild::SendClose()
{
SendClose();
PTCPSocketChild::SendClose();
return NS_OK;
}
NS_IMETHODIMP
TCPSocketChild::Send(const JS::Value& aData,
uint32_t aByteOffset,
uint32_t aByteLength,
JSContext* aCx)
TCPSocketChild::SendSend(const JS::Value& aData,
uint32_t aByteOffset,
uint32_t aByteLength,
uint32_t aTrackingNumber,
JSContext* aCx)
{
if (aData.isString()) {
JSString* jsstr = aData.toString();
nsDependentJSString str;
bool ok = str.init(aCx, jsstr);
NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
SendData(str);
SendData(str, aTrackingNumber);
} else {
NS_ENSURE_TRUE(aData.isObject(), NS_ERROR_FAILURE);
JS::Rooted<JSObject*> obj(aCx, &aData.toObject());
@ -216,15 +227,15 @@ TCPSocketChild::Send(const JS::Value& aData,
}
InfallibleTArray<uint8_t> arr;
arr.SwapElements(fallibleArr);
SendData(arr);
SendData(arr, aTrackingNumber);
}
return NS_OK;
}
NS_IMETHODIMP
TCPSocketChild::SetSocketAndWindow(nsITCPSocketInternal *aSocket,
const JS::Value& aWindowObj,
JSContext* aCx)
const JS::Value& aWindowObj,
JSContext* aCx)
{
mSocket = aSocket;
MOZ_ASSERT(aWindowObj.isObject());

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

@ -44,9 +44,10 @@ public:
virtual bool RecvCallback(const nsString& aType,
const CallbackData& aData,
const nsString& aReadyState,
const uint32_t& aBuffered) MOZ_OVERRIDE;
const nsString& aReadyState) MOZ_OVERRIDE;
virtual bool RecvRequestDelete() MOZ_OVERRIDE;
virtual bool RecvUpdateBufferedAmount(const uint32_t& aBufferred,
const uint32_t& aTrackingNumber) MOZ_OVERRIDE;
private:
JSObject* mWindowObj;
};

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

@ -35,7 +35,7 @@ FireInteralError(mozilla::net::PTCPSocketParent* aActor, uint32_t aLineNo)
mozilla::unused <<
aActor->SendCallback(NS_LITERAL_STRING("onerror"),
TCPError(NS_LITERAL_STRING("InvalidStateError")),
NS_LITERAL_STRING("connecting"), 0);
NS_LITERAL_STRING("connecting"));
}
NS_IMPL_CYCLE_COLLECTION_2(TCPSocketParentBase, mSocket, mIntermediary)
@ -156,7 +156,8 @@ TCPSocketParent::RecvResume()
}
bool
TCPSocketParent::RecvData(const SendableData& aData)
TCPSocketParent::RecvData(const SendableData& aData,
const uint32_t& aTrackingNumber)
{
NS_ENSURE_TRUE(mIntermediary, true);
@ -168,13 +169,13 @@ TCPSocketParent::RecvData(const SendableData& aData)
JS::Rooted<JS::Value> val(cx);
JS::Rooted<JSObject*> obj(cx, mIntermediaryObj);
IPC::DeserializeArrayBuffer(obj, aData.get_ArrayOfuint8_t(), &val);
rv = mIntermediary->SendArrayBuffer(val);
rv = mIntermediary->OnRecvSendArrayBuffer(val, aTrackingNumber);
NS_ENSURE_SUCCESS(rv, true);
break;
}
case SendableData::TnsString:
rv = mIntermediary->SendString(aData.get_nsString());
rv = mIntermediary->OnRecvSendString(aData.get_nsString(), aTrackingNumber);
NS_ENSURE_SUCCESS(rv, true);
break;
@ -194,9 +195,8 @@ TCPSocketParent::RecvClose()
}
NS_IMETHODIMP
TCPSocketParent::SendCallback(const nsAString& aType, const JS::Value& aDataVal,
const nsAString& aReadyState, uint32_t aBuffered,
JSContext* aCx)
TCPSocketParent::SendEvent(const nsAString& aType, const JS::Value& aDataVal,
const nsAString& aReadyState, JSContext* aCx)
{
if (!mIPCOpen) {
NS_WARNING("Dropping callback due to no IPC connection");
@ -255,7 +255,7 @@ TCPSocketParent::SendCallback(const nsAString& aType, const JS::Value& aDataVal,
}
mozilla::unused <<
PTCPSocketParent::SendCallback(nsString(aType), data,
nsString(aReadyState), aBuffered);
nsString(aReadyState));
return NS_OK;
}
@ -269,6 +269,15 @@ TCPSocketParent::SetSocketAndIntermediary(nsIDOMTCPSocket *socket,
return NS_OK;
}
NS_IMETHODIMP
TCPSocketParent::SendUpdateBufferedAmount(uint32_t aBufferedAmount,
uint32_t aTrackingNumber)
{
mozilla::unused << PTCPSocketParent::SendUpdateBufferedAmount(aBufferedAmount,
aTrackingNumber);
return NS_OK;
}
void
TCPSocketParent::ActorDestroy(ActorDestroyReason why)
{

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

@ -51,7 +51,8 @@ public:
virtual bool RecvSuspend() MOZ_OVERRIDE;
virtual bool RecvResume() MOZ_OVERRIDE;
virtual bool RecvClose() MOZ_OVERRIDE;
virtual bool RecvData(const SendableData& aData) MOZ_OVERRIDE;
virtual bool RecvData(const SendableData& aData,
const uint32_t& aTrackingNumber) MOZ_OVERRIDE;
virtual bool RecvRequestDelete() MOZ_OVERRIDE;
private:

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

@ -20,15 +20,21 @@ TCPSocketParentIntermediary.prototype = {
// Create handlers for every possible callback that attempt to trigger
// corresponding callbacks on the child object.
["open", "drain", "data", "error", "close"].forEach(
// ondrain event is not forwarded, since the decision of firing ondrain
// is made in child.
["open", "data", "error", "close"].forEach(
function(p) {
socket["on" + p] = function(data) {
aParentSide.sendCallback(p, data.data, socket.readyState,
socket.bufferedAmount);
aParentSide.sendEvent(p, data.data, socket.readyState,
socket.bufferedAmount);
};
}
);
},
},
_onUpdateBufferedAmountHandler: function(aParentSide, aBufferedAmount, aTrackingNumber) {
aParentSide.sendUpdateBufferedAmount(aBufferedAmount, aTrackingNumber);
},
open: function(aParentSide, aHost, aPort, aUseSSL, aBinaryType, aAppId) {
let baseSocket = Cc["@mozilla.org/tcp-socket;1"].createInstance(Ci.nsIDOMTCPSocket);
@ -41,6 +47,10 @@ TCPSocketParentIntermediary.prototype = {
socketInternal.setAppId(aAppId);
}
// Handle parent's request to update buffered amount.
socketInternal.setOnUpdateBufferedAmountHandler(
this._onUpdateBufferedAmountHandler.bind(this, aParentSide));
// Handlers are set to the JS-implemented socket object on the parent side.
this._setCallbacks(aParentSide, socket);
return socket;
@ -79,12 +89,15 @@ TCPSocketParentIntermediary.prototype = {
return serverSocket;
},
sendString: function(aData) {
return this._socket.send(aData);
onRecvSendString: function(aData, aTrackingNumber) {
let socketInternal = this._socket.QueryInterface(Ci.nsITCPSocketInternal);
return socketInternal.onRecvSendFromChild(aData, 0, 0, aTrackingNumber);
},
sendArrayBuffer: function(aData) {
return this._socket.send(aData, 0, aData.byteLength);
onRecvSendArrayBuffer: function(aData, aTrackingNumber) {
let socketInternal = this._socket.QueryInterface(Ci.nsITCPSocketInternal);
return socketInternal.onRecvSendFromChild(aData, 0, aData.byteLength,
aTrackingNumber);
},
classID: Components.ID("{afa42841-a6cb-4a91-912f-93099f6a3d18}"),

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

@ -28,9 +28,11 @@ SOURCES += [
if CONFIG['MOZ_B2G_RIL']:
EXPORTS.mozilla.dom.network += [
'MobileConnection.h',
'MobileConnectionArray.h',
]
SOURCES += [
'MobileConnection.cpp',
'MobileConnectionArray.cpp',
]
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':

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

@ -10,7 +10,7 @@ SpecialPowers.addPermission("mobileconnection", true, document);
let ifr = document.createElement("iframe");
let connection;
ifr.onload = function() {
connection = ifr.contentWindow.navigator.mozMobileConnection;
connection = ifr.contentWindow.navigator.mozMobileConnections[0];
ok(connection instanceof ifr.contentWindow.MozMobileConnection,
"connection is instanceof " + connection.constructor);

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

@ -10,7 +10,7 @@ SpecialPowers.addPermission("mobileconnection", true, document);
let ifr = document.createElement("iframe");
let connection;
ifr.onload = function() {
connection = ifr.contentWindow.navigator.mozMobileConnection;
connection = ifr.contentWindow.navigator.mozMobileConnections[0];
ok(connection instanceof ifr.contentWindow.MozMobileConnection,
"connection is instanceof " + connection.constructor);

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

@ -10,7 +10,7 @@ SpecialPowers.addPermission("mobileconnection", true, document);
let ifr = document.createElement("iframe");
let connection;
ifr.onload = function() {
connection = ifr.contentWindow.navigator.mozMobileConnection;
connection = ifr.contentWindow.navigator.mozMobileConnections[0];
ok(connection instanceof ifr.contentWindow.MozMobileConnection,
"connection is instanceof " + connection.constructor);

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

@ -13,7 +13,7 @@ SpecialPowers.addPermission("settings-read", true, document);
SpecialPowers.addPermission("settings-write", true, document);
let settings = window.navigator.mozSettings;
let connection = window.navigator.mozMobileConnection;
let connection = window.navigator.mozMobileConnections[0];
ok(connection instanceof MozMobileConnection,
"connection is instanceof " + connection.constructor);

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

@ -10,7 +10,7 @@ SpecialPowers.addPermission("mobileconnection", true, document);
let ifr = document.createElement("iframe");
let mobileConnection;
ifr.onload = function() {
mobileConnection = ifr.contentWindow.navigator.mozMobileConnection;
mobileConnection = ifr.contentWindow.navigator.mozMobileConnections[0];
// Start the test
verifyInitialState();

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

@ -10,7 +10,7 @@ SpecialPowers.addPermission("mobileconnection", true, document);
let ifr = document.createElement("iframe");
let mobileConnection;
ifr.onload = function() {
mobileConnection = ifr.contentWindow.navigator.mozMobileConnection;
mobileConnection = ifr.contentWindow.navigator.mozMobileConnections[0];
// Start the test
verifyInitialState();

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

@ -10,7 +10,7 @@ SpecialPowers.addPermission("mobileconnection", true, document);
let ifr = document.createElement("iframe");
let mobileConnection;
ifr.onload = function() {
mobileConnection = ifr.contentWindow.navigator.mozMobileConnection;
mobileConnection = ifr.contentWindow.navigator.mozMobileConnections[0];
tasks.run();
};

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

@ -6,7 +6,7 @@ MARIONETTE_TIMEOUT = 60000;
SpecialPowers.addPermission("mobileconnection", true, document);
let connection = navigator.mozMobileConnection;
let connection = navigator.mozMobileConnections[0];
ok(connection instanceof MozMobileConnection,
"connection is instanceof " + connection.constructor);

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

@ -15,7 +15,7 @@ let connection;
let voice;
let network;
ifr.onload = function() {
connection = ifr.contentWindow.navigator.mozMobileConnection;
connection = ifr.contentWindow.navigator.mozMobileConnections[0];
ok(connection instanceof ifr.contentWindow.MozMobileConnection,
"connection is instanceof " + connection.constructor);

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

@ -60,6 +60,6 @@ function cleanUp() {
}
waitFor(test_revert_previous_setting_on_invalid_value, function () {
return navigator.mozMobileConnection.voice.connected;
return navigator.mozMobileConnections[0].voice.connected;
});

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

@ -5,7 +5,7 @@ MARIONETTE_TIMEOUT = 60000;
SpecialPowers.addPermission("mobileconnection", true, document);
let connection = navigator.mozMobileConnection;
let connection = navigator.mozMobileConnections[0];
ok(connection instanceof MozMobileConnection,
"connection is instanceof " + connection.constructor);

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

@ -10,7 +10,7 @@ SpecialPowers.addPermission("mobileconnection", true, document);
let ifr = document.createElement("iframe");
let connection;
ifr.onload = function() {
connection = ifr.contentWindow.navigator.mozMobileConnection;
connection = ifr.contentWindow.navigator.mozMobileConnections[0];
ok(connection instanceof ifr.contentWindow.MozMobileConnection,
"connection is instanceof " + connection.constructor);
testConnectionInfo();

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

@ -80,6 +80,11 @@ function get_platform() {
return xulRuntime.OS;
}
function is_content() {
return this._inChild = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime)
.processType != Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
}
/**
* Spin up a listening socket and associate at most one live, accepted socket
* with ourselves.
@ -418,9 +423,15 @@ function drainTwice() {
['ondrain', 'ondrain2',
'ondata', 'ondata2',
'serverclose', 'clientclose']);
let ondrainCalled = false,
ondataCalled = false;
function maybeSendNextData() {
if (!ondrainCalled || !ondataCalled) {
// make sure server got data and client got ondrain.
return;
}
function serverSideCallback() {
yays.ondata();
server.ondata = makeExpectData(
"ondata2", BIG_TYPED_ARRAY_2, false, yays.ondata2);
@ -433,12 +444,24 @@ function drainTwice() {
sock.close();
}
function clientOndrain() {
yays.ondrain();
ondrainCalled = true;
maybeSendNextData();
}
function serverSideCallback() {
yays.ondata();
ondataCalled = true;
maybeSendNextData();
}
server.onclose = yays.serverclose;
server.ondata = makeExpectData(
"ondata", BIG_TYPED_ARRAY, false, serverSideCallback);
sock.onclose = yays.clientclose;
sock.ondrain = yays.ondrain;
sock.ondrain = clientOndrain;
if (sock.send(BIG_ARRAY_BUFFER)) {
throw new Error("sock.send(BIG_TYPED_ARRAY) did not return false to indicate buffering");
@ -482,6 +505,62 @@ function bufferTwice() {
}
}
// Test child behavior when child thinks it's buffering but parent doesn't
// buffer.
// 1. set bufferedAmount of content socket to a value that will make next
// send() call return false.
// 2. send a small data to make send() return false, but it won't make
// parent buffer.
// 3. we should get a ondrain.
function childbuffered() {
let yays = makeJointSuccess(['ondrain', 'serverdata',
'clientclose', 'serverclose']);
sock.ondrain = function() {
yays.ondrain();
sock.close();
};
server.ondata = makeExpectData(
'ondata', DATA_ARRAY, false, yays.serverdata);
let internalSocket = sock.QueryInterface(Ci.nsITCPSocketInternal);
internalSocket.updateBufferedAmount(65535, // almost reach buffering threshold
0);
if (sock.send(DATA_ARRAY_BUFFER)) {
do_throw("expected sock.send to return false.");
}
sock.onclose = yays.clientclose;
server.onclose = yays.serverclose;
}
// Test child's behavior when send() of child return true but parent buffers
// data.
// 1. send BIG_ARRAY to make parent buffer. This would make child wait for
// drain as well.
// 2. set child's bufferedAmount to zero, so child will no longer wait for
// drain but parent will dispatch a drain event.
// 3. wait for 1 second, to make sure there's no ondrain event dispatched in
// child.
function childnotbuffered() {
let yays = makeJointSuccess(['serverdata', 'clientclose', 'serverclose']);
server.ondata = makeExpectData('ondata', BIG_ARRAY, false, yays.serverdata);
if (sock.send(BIG_ARRAY_BUFFER)) {
do_throw("sock.send(BIG_TYPED_ARRAY) did not return false to indicate buffering");
}
let internalSocket = sock.QueryInterface(Ci.nsITCPSocketInternal);
internalSocket.updateBufferedAmount(0, // setting zero will clear waitForDrain in sock.
1);
// shouldn't get ondrain, even after parent have cleared its buffer.
sock.ondrain = makeFailureCase('drain');
sock.onclose = yays.clientclose;
server.onclose = yays.serverclose;
do_timeout(1000, function() {
sock.close();
});
};
// - connect, data and events work both ways
add_test(connectSock);
add_test(sendData);
@ -513,6 +592,14 @@ add_test(drainTwice);
add_test(connectSock);
add_test(bufferTwice);
if (is_content()) {
add_test(connectSock);
add_test(childnotbuffered);
add_test(connectSock);
add_test(childbuffered);
}
// clean up
add_test(cleanup);

64
dom/nfc/MozNdefRecord.cpp Normal file
Просмотреть файл

@ -0,0 +1,64 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* 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/. */
/* Copyright © 2013 Deutsche Telekom, Inc. */
#include "MozNdefRecord.h"
#include "mozilla/dom/MozNdefRecordBinding.h"
#include "nsContentUtils.h"
namespace mozilla {
namespace dom {
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_1(MozNdefRecord, mWindow)
NS_IMPL_CYCLE_COLLECTING_ADDREF(MozNdefRecord)
NS_IMPL_CYCLE_COLLECTING_RELEASE(MozNdefRecord)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MozNdefRecord)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
/* static */
already_AddRefed<MozNdefRecord>
MozNdefRecord::Constructor(const GlobalObject& aGlobal,
uint8_t aTnf, const nsAString& aType,
const nsAString& aId, const nsAString& aPayload,
ErrorResult& aRv)
{
nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(aGlobal.GetAsSupports());
if (!win) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
nsRefPtr<MozNdefRecord> ndefrecord =
new MozNdefRecord(win, aTnf, aType, aId, aPayload);
return ndefrecord.forget();
}
MozNdefRecord::MozNdefRecord(nsPIDOMWindow* aWindow,
uint8_t aTnf, const nsAString& aType,
const nsAString& aId, const nsAString& aPayload)
: mTnf(aTnf)
, mType(aType)
, mId(aId)
, mPayload(aPayload)
{
mWindow = aWindow;
SetIsDOMBinding();
}
MozNdefRecord::~MozNdefRecord()
{
}
JSObject*
MozNdefRecord::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope)
{
return MozNdefRecordBinding::Wrap(aCx, aScope, this);
}
} // namespace dom
} // namespace mozilla

88
dom/nfc/MozNdefRecord.h Normal file
Просмотреть файл

@ -0,0 +1,88 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* 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/. */
/* Copyright © 2013 Deutsche Telekom, Inc. */
#ifndef mozilla_dom_MozNdefRecord_h__
#define mozilla_dom_MozNdefRecord_h__
#include "mozilla/Attributes.h"
#include "mozilla/ErrorResult.h"
#include "nsCycleCollectionParticipant.h"
#include "nsWrapperCache.h"
#include "jsapi.h"
#include "nsIDocument.h"
struct JSContext;
namespace mozilla {
namespace dom {
class MozNdefRecord MOZ_FINAL : public nsISupports,
public nsWrapperCache
{
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(MozNdefRecord)
public:
MozNdefRecord(nsPIDOMWindow* aWindow,
uint8_t aTnf, const nsAString& aType,
const nsAString& aId, const nsAString& aPlayload);
~MozNdefRecord();
nsIDOMWindow* GetParentObject() const
{
return mWindow;
}
virtual JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
static already_AddRefed<MozNdefRecord> Constructor(
const GlobalObject& aGlobal,
uint8_t aTnf, const nsAString& aType,
const nsAString& aId,
const nsAString& aPayload,
ErrorResult& aRv);
uint8_t Tnf() const
{
return mTnf;
}
void GetType(nsString& aType) const
{
aType = mType;
}
void GetId(nsString& aId) const
{
aId = mId;
}
void GetPayload(nsString& aPayload) const
{
aPayload = mPayload;
}
private:
MozNdefRecord() MOZ_DELETE;
nsRefPtr<nsPIDOMWindow> mWindow;
uint8_t mTnf;
nsString mType;
nsString mId;
nsString mPayload;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_MozNdefRecord_h__

25
dom/nfc/moz.build Normal file
Просмотреть файл

@ -0,0 +1,25 @@
# 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/.
#
# Copyright © 2013 Deutsche Telekom, Inc.
if CONFIG['MOZ_NFC']:
MODULE = 'dom'
EXPORTS.mozilla.dom += [
'MozNdefRecord.h',
]
SOURCES += [
'MozNdefRecord.cpp',
]
EXTRA_COMPONENTS += [
'nsNfc.js',
'nsNfc.manifest',
]
FAIL_ON_WARNINGS = True
LIBRARY_NAME = 'dom_nfc_s'
LIBXUL_LIBRARY = True

178
dom/nfc/nsNfc.js Normal file
Просмотреть файл

@ -0,0 +1,178 @@
/* 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/. */
/* Copyright © 2013, Deutsche Telekom, Inc. */
"use strict";
const DEBUG = false;
function debug(s) {
if (DEBUG) dump("-*- Nfc DOM: " + s + "\n");
}
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/ObjectWrapper.jsm");
/**
* NFCTag
*/
function MozNFCTag() {
debug("In MozNFCTag Constructor");
this._nfcContentHelper = Cc["@mozilla.org/nfc/content-helper;1"]
.getService(Ci.nsINfcContentHelper);
this.session = null;
// Map WebIDL declared enum map names to integer
this._techTypesMap = [];
this._techTypesMap['NFC_A'] = 0;
this._techTypesMap['NFC_B'] = 1;
this._techTypesMap['NFC_ISO_DEP'] = 2;
this._techTypesMap['NFC_F'] = 3;
this._techTypesMap['NFC_V'] = 4;
this._techTypesMap['NDEF'] = 5;
this._techTypesMap['NDEF_FORMATABLE'] = 6;
this._techTypesMap['MIFARE_CLASSIC'] = 7;
this._techTypesMap['MIFARE_ULTRALIGHT'] = 8;
this._techTypesMap['NFC_BARCODE'] = 9;
this._techTypesMap['P2P'] = 10;
}
MozNFCTag.prototype = {
_nfcContentHelper: null,
_window: null,
initialize: function(aWindow, aSessionToken) {
this._window = aWindow;
this.setSessionToken(aSessionToken);
},
// ChromeOnly interface
setSessionToken: function setSessionToken(aSessionToken) {
debug("Setting session token.");
this.session = aSessionToken;
// report to NFC worker:
this._nfcContentHelper.setSessionToken(aSessionToken);
},
_techTypesMap: null,
// NFCTag interface:
getDetailsNDEF: function getDetailsNDEF() {
return this._nfcContentHelper.getDetailsNDEF(this._window, this.session);
},
readNDEF: function readNDEF() {
return this._nfcContentHelper.readNDEF(this._window, this.session);
},
writeNDEF: function writeNDEF(records) {
return this._nfcContentHelper.writeNDEF(this._window, records, this.session);
},
makeReadOnlyNDEF: function makeReadOnlyNDEF() {
return this._nfcContentHelper.makeReadOnlyNDEF(this._window, this.session);
},
connect: function connect(enum_tech_type) {
let int_tech_type = this._techTypesMap[enum_tech_type];
return this._nfcContentHelper.connect(this._window, int_tech_type, this.session);
},
close: function close() {
return this._nfcContentHelper.close(this._window, this.session);
},
classID: Components.ID("{4e1e2e90-3137-11e3-aa6e-0800200c9a66}"),
contractID: "@mozilla.org/nfc/NFCTag;1",
QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports,
Ci.nsIDOMGlobalPropertyInitializer]),
};
/**
* NFCPeer
*/
function MozNFCPeer() {
debug("In MozNFCPeer Constructor");
this._nfcContentHelper = Cc["@mozilla.org/nfc/content-helper;1"]
.getService(Ci.nsINfcContentHelper);
this.session = null;
}
MozNFCPeer.prototype = {
_nfcContentHelper: null,
_window: null,
initialize: function(aWindow, aSessionToken) {
this._window = aWindow;
this.setSessionToken(aSessionToken);
},
// ChromeOnly interface
setSessionToken: function setSessionToken(aSessionToken) {
debug("Setting session token.");
this.session = aSessionToken;
// report to NFC worker:
return this._nfcContentHelper.setSessionToken(aSessionToken);
},
// NFCPeer interface:
sendNDEF: function sendNDEF(records) {
// Just forward sendNDEF to writeNDEF
return this._nfcContentHelper.writeNDEF(this._window, records);
},
classID: Components.ID("{c1b2bcf0-35eb-11e3-aa6e-0800200c9a66}"),
contractID: "@mozilla.org/nfc/NFCPeer;1",
QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports,
Ci.nsIDOMGlobalPropertyInitializer]),
};
/**
* Navigator NFC object
*/
function mozNfc() {
debug("In mozNfc Constructor");
}
mozNfc.prototype = {
_nfcContentHelper: null,
_window: null,
_wrap: function _wrap(obj) {
return ObjectWrapper.wrap(obj, this._window);
},
init: function init(aWindow) {
debug("mozNfc init called");
this._window = aWindow;
},
getNFCTag: function getNFCTag(sessionToken) {
let obj = new MozNFCTag();
let nfcTag = this._window.MozNFCTag._create(this._window, obj);
if (nfcTag) {
obj.initialize(this._window, sessionToken);
return nfcTag;
} else {
debug("Error: Unable to create NFCTag");
return null;
}
},
getNFCPeer: function getNFCPeer(sessionToken) {
let obj = new MozNFCPeer();
let nfcPeer = this._window.MozNFCTag._create(this._window, obj);
if (nfcPeer) {
obj.initialize(this._window, sessionToken);
return nfcPeer;
} else {
debug("Error: Unable to create NFCPeer");
return null;
}
},
// get/set onpeerfound/lost onforegrounddispatch
classID: Components.ID("{6ff2b290-2573-11e3-8224-0800200c9a66}"),
contractID: "@mozilla.org/navigatorNfc;1",
QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports,
Ci.nsIDOMGlobalPropertyInitializer]),
};
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([MozNFCTag, MozNFCPeer, mozNfc]);

8
dom/nfc/nsNfc.manifest Normal file
Просмотреть файл

@ -0,0 +1,8 @@
component {6ff2b290-2573-11e3-8224-0800200c9a66} nsNfc.js
contract @mozilla.org/navigatorNfc;1 {6ff2b290-2573-11e3-8224-0800200c9a66}
component {4e1e2e90-3137-11e3-aa6e-0800200c9a66} nsNfc.js
contract @mozilla.org/nfc/NFCTag;1 {4e1e2e90-3137-11e3-aa6e-0800200c9a66}
component {c1b2bcf0-35eb-11e3-aa6e-0800200c9a66} nsNfc.js
contract @mozilla.org/nfc/NFCPeer;1 {c1b2bcf0-35eb-11e3-aa6e-0800200c9a66}

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

@ -19,8 +19,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=815105
var gData = [
{
perm: ["mobileconnection"],
obj: "mozMobileConnection",
idl: "nsIDOMMozMobileConnection",
obj: "mozMobileConnections",
webidl: "MozMobileConnectionArray",
},
]
</script>

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

@ -4,7 +4,7 @@
this.EXPORTED_SYMBOLS = ["PHONE_NUMBER_META_DATA"];
this.PHONE_NUMBER_META_DATA = {
"46": '["SE","00","0",,,"$NP$FG","\\d{5,10}","[1-9]\\d{6,9}",[["(8)(\\d{2,3})(\\d{2,3})(\\d{2})","$1-$2 $3 $4","8",,"$1 $2 $3 $4"],["([1-69]\\d)(\\d{2,3})(\\d{2})(\\d{2})","$1-$2 $3 $4","1[013689]|2[0136]|3[1356]|4[0246]|54|6[03]|90",,"$1 $2 $3 $4"],["([1-69]\\d)(\\d{3})(\\d{2})","$1-$2 $3","1[13689]|2[136]|3[1356]|4[0246]|54|6[03]|90",,"$1 $2 $3"],["(\\d{3})(\\d{2})(\\d{2})(\\d{2})","$1-$2 $3 $4","1[2457]|2[2457-9]|3[0247-9]|4[1357-9]|5[0-35-9]|6[124-9]|9(?:[125-8]|3[0-5]|4[0-3])",,"$1 $2 $3 $4"],["(\\d{3})(\\d{2,3})(\\d{2})","$1-$2 $3","1[2457]|2[2457-9]|3[0247-9]|4[1357-9]|5[0-35-9]|6[124-9]|9(?:[125-8]|3[0-5]|4[0-3])",,"$1 $2 $3"],["(7\\d)(\\d{3})(\\d{2})(\\d{2})","$1-$2 $3 $4","7",,"$1 $2 $3 $4"],["(20)(\\d{2,3})(\\d{2})","$1-$2 $3","20",,"$1 $2 $3"],["(9[034]\\d)(\\d{2})(\\d{2})(\\d{3})","$1-$2 $3 $4","9[034]",,"$1 $2 $3 $4"]]]',
"46": '["SE","00","0",,,"$NP$FG","\\d{5,10}","[1-9]\\d{5,9}",[["(8)(\\d{2,3})(\\d{2,3})(\\d{2})","$1-$2 $3 $4","8",,"$1 $2 $3 $4"],["([1-69]\\d)(\\d{2,3})(\\d{2})(\\d{2})","$1-$2 $3 $4","1[013689]|2[0136]|3[1356]|4[0246]|54|6[03]|90",,"$1 $2 $3 $4"],["([1-69]\\d)(\\d{3})(\\d{2})","$1-$2 $3","1[13689]|2[136]|3[1356]|4[0246]|54|6[03]|90",,"$1 $2 $3"],["(\\d{3})(\\d{2})(\\d{2})(\\d{2})","$1-$2 $3 $4","1[2457]|2[2457-9]|3[0247-9]|4[1357-9]|5[0-35-9]|6[124-9]|9(?:[125-8]|3[0-5]|4[0-3])",,"$1 $2 $3 $4"],["(\\d{3})(\\d{2,3})(\\d{2})","$1-$2 $3","1[2457]|2[2457-9]|3[0247-9]|4[1357-9]|5[0-35-9]|6[124-9]|9(?:[125-8]|3[0-5]|4[0-3])",,"$1 $2 $3"],["(7\\d)(\\d{3})(\\d{2})(\\d{2})","$1-$2 $3 $4","7",,"$1 $2 $3 $4"],["(77)(\\d{2})(\\d{2})","$1-$2$3","7",,"$1 $2 $3"],["(20)(\\d{2,3})(\\d{2})","$1-$2 $3","20",,"$1 $2 $3"],["(9[034]\\d)(\\d{2})(\\d{2})(\\d{3})","$1-$2 $3 $4","9[034]",,"$1 $2 $3 $4"],["(9[034]\\d)(\\d{4})","$1-$2","9[034]",,"$1 $2"]]]',
"299": '["GL","00",,,,,"\\d{6}","[1-689]\\d{5}",[["(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3",,,]]]',
"385": '["HR","00","0",,,"$NP$FG","\\d{6,12}","[1-7]\\d{5,8}|[89]\\d{6,11}",[["(1)(\\d{4})(\\d{3})","$1 $2 $3","1",,],["(6[09])(\\d{4})(\\d{3})","$1 $2 $3","6[09]",,],["(62)(\\d{3})(\\d{3,4})","$1 $2 $3","62",,],["([2-5]\\d)(\\d{3})(\\d{3})","$1 $2 $3","[2-5]",,],["(9\\d)(\\d{3})(\\d{3,4})","$1 $2 $3","9",,],["(9\\d)(\\d{4})(\\d{4})","$1 $2 $3","9",,],["(9\\d)(\\d{3,4})(\\d{3})(\\d{3})","$1 $2 $3 $4","9",,],["(\\d{2})(\\d{2})(\\d{2,3})","$1 $2 $3","6[145]|7",,],["(\\d{2})(\\d{3,4})(\\d{3})","$1 $2 $3","6[145]|7",,],["(80[01])(\\d{2})(\\d{2,3})","$1 $2 $3","8",,],["(80[01])(\\d{3,4})(\\d{3})","$1 $2 $3","8",,]]]',
"670": '["TL","00",,,,,"\\d{7,8}","[2-489]\\d{6}|7\\d{6,7}",[["(\\d{3})(\\d{4})","$1 $2","[2-489]",,],["(\\d{4})(\\d{4})","$1 $2","7",,]]]',
@ -14,7 +14,7 @@ this.PHONE_NUMBER_META_DATA = {
"852": '["HK","00",,,,,"\\d{5,11}","[235-7]\\d{7}|8\\d{7,8}|9\\d{4,10}",[["(\\d{4})(\\d{4})","$1 $2","[235-7]|[89](?:0[1-9]|[1-9])",,],["(800)(\\d{3})(\\d{3})","$1 $2 $3","800",,],["(900)(\\d{2})(\\d{3})(\\d{3})","$1 $2 $3 $4","900",,],["(900)(\\d{2,5})","$1 $2","900",,]]]',
"998": '["UZ","810","8",,,"$NP $FG","\\d{7,9}","[679]\\d{8}",[["([679]\\d)(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4",,,]]]',
"291": '["ER","00","0",,,"$NP$FG","\\d{6,7}","[178]\\d{6}",[["(\\d)(\\d{3})(\\d{3})","$1 $2 $3",,,]]]',
"95": '["MM","00","0",,,"$NP$FG","\\d{5,10}","[14578]\\d{5,7}|[26]\\d{5,8}|9(?:[258]|3\\d|4\\d{1,2}|[679]\\d?)\\d{6}",[["(\\d)(\\d{3})(\\d{3,4})","$1 $2 $3","1|2[45]",,],["(2)(\\d{4})(\\d{4})","$1 $2 $3","251",,],["(\\d)(\\d{2})(\\d{3})","$1 $2 $3","16|2",,],["(\\d{2})(\\d{3})(\\d{3,4})","$1 $2 $3","67|81",,],["(\\d{2})(\\d{2})(\\d{3,4})","$1 $2 $3","[4-8]",,],["(9)(\\d{3})(\\d{4,5})","$1 $2 $3","9(?:[235-9]|4[13789])",,],["(9)(4\\d{4})(\\d{4})","$1 $2 $3","94[0245]",,]]]',
"95": '["MM","00","0",,,"$NP$FG","\\d{5,10}","[14578]\\d{5,7}|[26]\\d{5,8}|9(?:2\\d{0,2}|[58]|3\\d|4\\d{1,2}|[679]\\d?)\\d{6}",[["(\\d)(\\d{3})(\\d{3,4})","$1 $2 $3","1|2[45]",,],["(2)(\\d{4})(\\d{4})","$1 $2 $3","251",,],["(\\d)(\\d{2})(\\d{3})","$1 $2 $3","16|2",,],["(\\d{2})(\\d{3})(\\d{3,4})","$1 $2 $3","67|81",,],["(\\d{2})(\\d{2})(\\d{3,4})","$1 $2 $3","[4-8]",,],["(9)(\\d{3})(\\d{4,5})","$1 $2 $3","9(?:2[0-4]|[35-9]|4[13789])",,],["(9)(4\\d{4})(\\d{4})","$1 $2 $3","94[0245]",,],["(9)(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3 $4","925",,]]]',
"266": '["LS","00",,,,,"\\d{8}","[2568]\\d{7}",[["(\\d{4})(\\d{4})","$1 $2",,,]]]',
"245": '["GW","00",,,,,"\\d{7}","[3-79]\\d{6}",[["(\\d{3})(\\d{4})","$1 $2",,,]]]',
"374": '["AM","00","0",,,"($NP$FG)","\\d{5,8}","[1-9]\\d{7}",[["(\\d{2})(\\d{6})","$1 $2","1|47",,],["(\\d{2})(\\d{6})","$1 $2","[5-7]|9[1-9]","$NP$FG",],["(\\d{3})(\\d{5})","$1 $2","[23]",,],["(\\d{3})(\\d{2})(\\d{3})","$1 $2 $3","8|90","$NP $FG",]]]',
@ -24,7 +24,7 @@ this.PHONE_NUMBER_META_DATA = {
"261": '["MG","00","0",,,"$NP$FG","\\d{7,9}","[23]\\d{8}",[["([23]\\d)(\\d{2})(\\d{3})(\\d{2})","$1 $2 $3 $4",,,]]]',
"92": '["PK","00","0",,,"($NP$FG)","\\d{6,12}","1\\d{8}|[2-8]\\d{5,11}|9(?:[013-9]\\d{4,9}|2\\d(?:111\\d{6}|\\d{3,7}))",[["(\\d{2})(111)(\\d{3})(\\d{3})","$1 $2 $3 $4","(?:2[125]|4[0-246-9]|5[1-35-7]|6[1-8]|7[14]|8[16]|91)1",,],["(\\d{3})(111)(\\d{3})(\\d{3})","$1 $2 $3 $4","2[349]|45|54|60|72|8[2-5]|9[2-9]",,],["(\\d{2})(\\d{7,8})","$1 $2","(?:2[125]|4[0-246-9]|5[1-35-7]|6[1-8]|7[14]|8[16]|91)[2-9]",,],["(\\d{3})(\\d{6,7})","$1 $2","2[349]|45|54|60|72|8[2-5]|9[2-9]",,],["(3\\d{2})(\\d{7})","$1 $2","3","$NP$FG",],["([15]\\d{3})(\\d{5,6})","$1 $2","58[12]|1",,],["(586\\d{2})(\\d{5})","$1 $2","586",,],["([89]00)(\\d{3})(\\d{2})","$1 $2 $3","[89]00","$NP$FG",]]]',
"234": '["NG","009","0",,,"$NP$FG","\\d{5,14}","[1-69]\\d{5,8}|[78]\\d{5,13}",[["([129])(\\d{3})(\\d{3,4})","$1 $2 $3","[129]",,],["([3-8]\\d)(\\d{3})(\\d{2,3})","$1 $2 $3","[3-6]|7(?:[1-79]|0[1-9])|8[2-9]",,],["([78]\\d{2})(\\d{3})(\\d{3,4})","$1 $2 $3","70|8[01]",,],["([78]00)(\\d{4})(\\d{4,5})","$1 $2 $3","[78]00",,],["([78]00)(\\d{5})(\\d{5,6})","$1 $2 $3","[78]00",,],["(78)(\\d{2})(\\d{3})","$1 $2 $3","78",,]]]',
"350": '["GI","00",,,,,"\\d{8}","[2568]\\d{7}",]',
"350": '["GI","00",,,,,"\\d{8}","[2568]\\d{7}",[["(\\d{3})(\\d{5})","$1 $2","2",,]]]',
"45": '["DK","00",,,,,"\\d{8}","[2-9]\\d{7}",[["(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",,,]]]',
"963": '["SY","00","0",,,"$NP$FG","\\d{6,9}","[1-59]\\d{7,8}",[["(\\d{2})(\\d{3})(\\d{3,4})","$1 $2 $3","[1-5]",,],["(9\\d{2})(\\d{3})(\\d{3})","$1 $2 $3","9",,]]]',
"226": '["BF","00",,,,,"\\d{8}","[24-7]\\d{7}",[["(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",,,]]]',
@ -35,7 +35,7 @@ this.PHONE_NUMBER_META_DATA = {
"298": '["FO","00",,"(10(?:01|[12]0|88))",,,"\\d{6}","[2-9]\\d{5}",[["(\\d{6})","$1",,,]]]',
"381": '["RS","00","0",,,"$NP$FG","\\d{5,12}","[126-9]\\d{4,11}|3(?:[0-79]\\d{3,10}|8[2-9]\\d{2,9})",[["([23]\\d{2})(\\d{4,9})","$1 $2","(?:2[389]|39)0",,],["([1-3]\\d)(\\d{5,10})","$1 $2","1|2(?:[0-24-7]|[389][1-9])|3(?:[0-8]|9[1-9])",,],["(6\\d)(\\d{6,8})","$1 $2","6",,],["([89]\\d{2})(\\d{3,9})","$1 $2","[89]",,],["(7[26])(\\d{4,9})","$1 $2","7[26]",,],["(7[08]\\d)(\\d{4,9})","$1 $2","7[08]",,]]]',
"975": '["BT","00",,,,,"\\d{6,8}","[1-8]\\d{6,7}",[["([17]7)(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4","1|77",,],["([2-8])(\\d{3})(\\d{3})","$1 $2 $3","[2-68]|7[246]",,]]]',
"34": '["ES","00",,,,,"\\d{9}","[5-9]\\d{8}",[["([5-9]\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",,,]]]',
"34": '["ES","00",,,,,"\\d{9}","[5-9]\\d{8}",[["([5-9]\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4","[568]|[79][0-8]",,]]]',
"881": '["001",,,,,,"\\d{9}","[67]\\d{8}",[["(\\d)(\\d{3})(\\d{5})","$1 $2 $3","[67]",,]]]',
"855": '["KH","00[14-9]","0",,,,"\\d{6,10}","[1-9]\\d{7,9}",[["(\\d{2})(\\d{3})(\\d{3,4})","$1 $2 $3","1\\d[1-9]|[2-9]","$NP$FG",],["(1[89]00)(\\d{3})(\\d{3})","$1 $2 $3","1[89]0",,]]]',
"420": '["CZ","00",,,,,"\\d{9,12}","[2-8]\\d{8}|9\\d{8,11}",[["([2-9]\\d{2})(\\d{3})(\\d{3})","$1 $2 $3","[2-8]|9[015-7]",,],["(96\\d)(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3 $4","96",,],["(9\\d)(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3 $4","9[36]",,]]]',
@ -46,7 +46,7 @@ this.PHONE_NUMBER_META_DATA = {
"267": '["BW","00",,,,,"\\d{7,8}","[2-79]\\d{6,7}",[["(\\d{3})(\\d{4})","$1 $2","[2-6]",,],["(7\\d)(\\d{3})(\\d{3})","$1 $2 $3","7",,],["(90)(\\d{5})","$1 $2","9",,]]]',
"94": '["LK","00","0",,,"$NP$FG","\\d{7,9}","[1-9]\\d{8}",[["(\\d{2})(\\d{1})(\\d{6})","$1 $2 $3","[1-689]",,],["(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3","7",,]]]',
"356": '["MT","00",,,,,"\\d{8}","[2357-9]\\d{7}",[["(\\d{4})(\\d{4})","$1 $2",,,]]]',
"375": '["BY","810","8","8?0?",,,"\\d{7,11}","[1-4]\\d{8}|[89]\\d{9,10}",[["([1-4]\\d)(\\d{3})(\\d{4})","$1 $2 $3","[1-4]","$NP 0$FG",],["([89]\\d{2})(\\d{3})(\\d{4})","$1 $2 $3","8[01]|9","$NP $FG",],["(8\\d{2})(\\d{4})(\\d{4})","$1 $2 $3","82","$NP $FG",]]]',
"375": '["BY","810","8","8?0?",,,"\\d{7,11}","[1-4]\\d{8}|[89]\\d{9,10}",[["(\\d{2})(\\d{3})(\\d{2})(\\d{2})","$1 $2-$3-$4","17[0-3589]|2[4-9]|[34]","$NP 0$FG",],["(\\d{3})(\\d{2})(\\d{2})(\\d{2})","$1 $2-$3-$4","1(?:5[24]|6[235]|7[467])|2(?:1[246]|2[25]|3[26])","$NP 0$FG",],["(\\d{4})(\\d{2})(\\d{3})","$1 $2-$3","1(?:5[169]|6[3-5]|7[179])|2(?:1[35]|2[34]|3[3-5])","$NP 0$FG",],["([89]\\d{2})(\\d{3})(\\d{4})","$1 $2 $3","8[01]|9","$NP $FG",],["(8\\d{2})(\\d{4})(\\d{4})","$1 $2 $3","82","$NP $FG",]]]',
"690": '["TK","00",,,,,"\\d{4}","[2-9]\\d{3}",]',
"507": '["PA","00",,,,,"\\d{7,8}","[1-9]\\d{6,7}",[["(\\d{3})(\\d{4})","$1-$2","[1-57-9]",,],["(\\d{4})(\\d{4})","$1-$2","6",,]]]',
"692": '["MH","011","1",,,,"\\d{7}","[2-6]\\d{6}",[["(\\d{3})(\\d{4})","$1-$2",,,]]]',
@ -59,7 +59,7 @@ this.PHONE_NUMBER_META_DATA = {
"27": '["ZA","00","0",,,"$NP$FG","\\d{5,9}","[1-79]\\d{8}|8(?:[067]\\d{7}|[1-4]\\d{3,7})",[["(860)(\\d{3})(\\d{3})","$1 $2 $3","860",,],["(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3","[1-79]|8(?:[0-47]|6[1-9])",,],["(\\d{2})(\\d{3,4})","$1 $2","8[1-4]",,],["(\\d{2})(\\d{3})(\\d{2,3})","$1 $2 $3","8[1-4]",,]]]',
"962": '["JO","00","0",,,"$NP$FG","\\d{7,9}","[235-9]\\d{7,8}",[["(\\d)(\\d{3})(\\d{4})","$1 $2 $3","[2356]|87","($NP$FG)",],["(7)(\\d{4})(\\d{4})","$1 $2 $3","7[457-9]",,],["(\\d{3})(\\d{5,6})","$1 $2","70|8[0158]|9",,]]]',
"387": '["BA","00","0",,,"$NP$FG","\\d{6,9}","[3-9]\\d{7,8}",[["(\\d{2})(\\d{3})(\\d{3})","$1 $2-$3","[3-5]",,],["(\\d{2})(\\d{3})(\\d{3})","$1 $2 $3","6[1-356]|[7-9]",,],["(\\d{2})(\\d{2})(\\d{2})(\\d{3})","$1 $2 $3 $4","6[047]",,]]]',
"33": '["FR","[04579]0","0",,,"$NP$FG","\\d{4}(?:\\d{5})?","[124-9]\\d{8}|3\\d{3}(?:\\d{5})?",[["([1-79])(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4 $5","[1-79]",,],["(8\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4","8","$NP $FG",]]]',
"33": '["FR","00","0",,,"$NP$FG","\\d{9}","[1-9]\\d{8}",[["([1-79])(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4 $5","[1-79]",,],["(1\\d{2})(\\d{3})","$1 $2","11","$FG","NA"],["(8\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4","8","$NP $FG",]]]',
"972": '["IL","0(?:0|1[2-9])","0",,,"$FG","\\d{4,10}","[17]\\d{6,9}|[2-589]\\d{3}(?:\\d{3,6})?|6\\d{3}",[["([2-489])(\\d{3})(\\d{4})","$1-$2-$3","[2-489]","$NP$FG",],["([57]\\d)(\\d{3})(\\d{4})","$1-$2-$3","[57]","$NP$FG",],["(1)([7-9]\\d{2})(\\d{3})(\\d{3})","$1-$2-$3-$4","1[7-9]",,],["(1255)(\\d{3})","$1-$2","125",,],["(1200)(\\d{3})(\\d{3})","$1-$2-$3","120",,],["(1212)(\\d{2})(\\d{2})","$1-$2-$3","121",,],["(1599)(\\d{6})","$1-$2","15",,],["(\\d{4})","*$1","[2-689]",,]]]',
"248": '["SC","0[0-2]",,,,,"\\d{6,7}","[24689]\\d{5,6}",[["(\\d{3})(\\d{3})","$1 $2","[89]",,],["(\\d)(\\d{3})(\\d{3})","$1 $2 $3","[246]",,]]]',
"297": '["AW","00",,,,,"\\d{7}","[25-9]\\d{6}",[["(\\d{3})(\\d{4})","$1 $2",,,]]]',
@ -72,13 +72,13 @@ this.PHONE_NUMBER_META_DATA = {
"239": '["ST","00",,,,,"\\d{7}","[29]\\d{6}",[["(\\d{3})(\\d{4})","$1 $2",,,]]]',
"357": '["CY","00",,,,,"\\d{8}","[257-9]\\d{7}",[["(\\d{2})(\\d{6})","$1 $2",,,]]]',
"240": '["GQ","00",,,,,"\\d{9}","[23589]\\d{8}",[["(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3","[235]",,],["(\\d{3})(\\d{6})","$1 $2","[89]",,]]]',
"506": '["CR","00",,"(19(?:0[0-2468]|19|20|66|77))",,,"\\d{8,10}","[24-9]\\d{7,9}",[["(\\d{4})(\\d{4})","$1 $2","[24-7]|8[3-9]",,],["(\\d{3})(\\d{3})(\\d{4})","$1-$2-$3","[89]0",,]]]',
"86": '["CN","(1[1279]\\d{3})?00","0","(1[1279]\\d{3})|0",,,"\\d{4,12}","[1-7]\\d{6,11}|8[0-357-9]\\d{6,9}|9(?:5\\d{3,4}|\\d{9})",[["(80\\d{2})(\\d{4})","$1 $2","80[2678]","$NP$FG",],["([48]00)(\\d{3})(\\d{4})","$1 $2 $3","[48]00",,],["(\\d{5})","$1","95",,],["(\\d{2})(\\d{5,6})","$1 $2","(?:10|2\\d)9","$NP$FG",],["(\\d{3})(\\d{5,6})","$1 $2","[3-9]","$NP$FG",],["(\\d{3,4})(\\d{4})","$1 $2","[2-9]",,"NA"],["(21)(\\d{4})(\\d{4,6})","$1 $2 $3","21","$NP$FG",],["([12]\\d)(\\d{4})(\\d{4})","$1 $2 $3","10[1-9]|2[02-9]","$NP$FG",],["(\\d{3})(\\d{4})(\\d{4})","$1 $2 $3","3(?:11|7[179])|4(?:[15]1|3[12])|5(?:1|2[37]|3[12]|51|7[13-79]|9[15])|7(?:31|5[457]|6[09]|91)|8(?:71|98)","$NP$FG",],["(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3","3(?:1[02-9]|35|49|5|7[02-68]|9[1-68])|4(?:1[02-9]|2[179]|[35][2-9]|6[4789]|7\\d|8[23])|5(?:3[03-9]|4[36]|5[02-9]|6[1-46]|7[028]|80|9[2-46-9])|6(?:3[1-5]|6[0238]|9[12])|7(?:01|[1579]|2[248]|3[04-9]|4[3-6]|6[2368])|8(?:1[236-8]|2[5-7]|3|5[1-9]|7[02-9]|8[3678]|9[1-7])|9(?:0[1-3689]|1[1-79]|[379]|4[13]|5[1-5])","$NP$FG",],["(1[3-58]\\d)(\\d{4})(\\d{4})","$1 $2 $3","1[3-58]",,],["(10800)(\\d{3})(\\d{4})","$1 $2 $3","108",,]]]',
"506": '["CR","00",,"(19(?:0[01468]|19|20|66|77))",,,"\\d{8,10}","[24-9]\\d{7,9}",[["(\\d{4})(\\d{4})","$1 $2","[24-7]|8[3-9]",,],["(\\d{3})(\\d{3})(\\d{4})","$1-$2-$3","[89]0",,]]]',
"86": '["CN","(1[1279]\\d{3})?00","0","(1[1279]\\d{3})|0",,,"\\d{4,12}","1(?:00\\d{2}|\\d{6,11})|[2-7]\\d{6,11}|8[0-357-9]\\d{6,9}|9(?:5\\d{3,4}|\\d{9})",[["(80\\d{2})(\\d{4})","$1 $2","80[2678]","$NP$FG",],["([48]00)(\\d{3})(\\d{4})","$1 $2 $3","[48]00",,],["(\\d{5,6})","$1","100|95",,"NA"],["(\\d{2})(\\d{5,6})","$1 $2","(?:10|2\\d)[19]","$NP$FG",],["(\\d{3})(\\d{5,6})","$1 $2","[3-9]","$NP$FG",],["(\\d{3,4})(\\d{4})","$1 $2","[2-9]",,"NA"],["(21)(\\d{4})(\\d{4,6})","$1 $2 $3","21","$NP$FG",],["([12]\\d)(\\d{4})(\\d{4})","$1 $2 $3","10[1-9]|2[02-9]","$NP$FG",],["(\\d{3})(\\d{4})(\\d{4})","$1 $2 $3","3(?:11|7[179])|4(?:[15]1|3[12])|5(?:1|2[37]|3[12]|51|7[13-79]|9[15])|7(?:31|5[457]|6[09]|91)|8(?:71|98)","$NP$FG",],["(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3","3(?:1[02-9]|35|49|5|7[02-68]|9[1-68])|4(?:1[02-9]|2[179]|[35][2-9]|6[4789]|7\\d|8[23])|5(?:3[03-9]|4[36]|5[02-9]|6[1-46]|7[028]|80|9[2-46-9])|6(?:3[1-5]|6[0238]|9[12])|7(?:01|[1579]|2[248]|3[04-9]|4[3-6]|6[2368])|8(?:1[236-8]|2[5-7]|3|5[1-9]|7[02-9]|8[3678]|9[1-7])|9(?:0[1-3689]|1[1-79]|[379]|4[13]|5[1-5])","$NP$FG",],["(1[3-58]\\d)(\\d{4})(\\d{4})","$1 $2 $3","1[3-58]",,],["(10800)(\\d{3})(\\d{4})","$1 $2 $3","108",,]]]',
"257": '["BI","00",,,,,"\\d{8}","[27]\\d{7}",[["([27]\\d)(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",,,]]]',
"683": '["NU","00",,,,,"\\d{4}","[1-5]\\d{3}",]',
"43": '["AT","00","0",,,"$NP$FG","\\d{3,13}","[1-9]\\d{3,12}",[["(1)(\\d{3,12})","$1 $2","1",,],["(5\\d)(\\d{3,5})","$1 $2","5[079]",,],["(5\\d)(\\d{3})(\\d{3,4})","$1 $2 $3","5[079]",,],["(5\\d)(\\d{4})(\\d{4,7})","$1 $2 $3","5[079]",,],["(\\d{3})(\\d{3,10})","$1 $2","316|46|51|732|6(?:44|5[0-3579]|[6-9])|7(?:1|[28]0)|[89]",,],["(\\d{4})(\\d{3,9})","$1 $2","2|3(?:1[1-578]|[3-8])|4[2378]|5[2-6]|6(?:[12]|4[1-35-9]|5[468])|7(?:2[1-8]|35|4[1-8]|[57-9])",,]]]',
"43": '["AT","00","0",,,"$NP$FG","\\d{3,13}","[1-9]\\d{3,12}",[["(1)(\\d{3,12})","$1 $2","1",,],["(5\\d)(\\d{3,5})","$1 $2","5[079]",,],["(5\\d)(\\d{3})(\\d{3,4})","$1 $2 $3","5[079]",,],["(5\\d)(\\d{4})(\\d{4,7})","$1 $2 $3","5[079]",,],["(\\d{3})(\\d{3,10})","$1 $2","316|46|51|732|6(?:44|5[0-3579]|[6-9])|7(?:1|[28]0)|[89]",,],["(\\d{4})(\\d{3,9})","$1 $2","2|3(?:1[1-578]|[3-8])|4[2378]|5[2-6]|6(?:[12]|4[1-35-9]|5[468])|7(?:2[1-8]|35|4[1-8]|[5-79])",,]]]',
"247": '["AC","00",,,,,"\\d{4}","[2-467]\\d{3}",]',
"675": '["PG","00",,,,,"\\d{7,8}","[1-9]\\d{6,7}",[["(\\d{3})(\\d{4})","$1 $2","[1-689]",,],["(7\\d{2})(\\d{2})(\\d{3})","$1 $2 $3","7",,]]]',
"675": '["PG","00",,,,,"\\d{7,8}","[1-9]\\d{6,7}",[["(\\d{3})(\\d{4})","$1 $2","[1-689]",,],["(7\\d{3})(\\d{4})","$1 $2","7",,]]]',
"376": '["AD","00",,,,,"\\d{6,8}","(?:[346-9]|180)\\d{5}",[["(\\d{3})(\\d{3})","$1 $2","[346-9]",,],["(180[02])(\\d{4})","$1 $2","1",,]]]',
"63": '["PH","00","0",,,,"\\d{5,13}","2\\d{5,7}|[3-9]\\d{7,9}|1800\\d{7,9}",[["(2)(\\d{3})(\\d{4})","$1 $2 $3","2","($NP$FG)",],["(2)(\\d{5})","$1 $2","2","($NP$FG)",],["(\\d{4})(\\d{4,6})","$1 $2","3(?:23|39|46)|4(?:2[3-6]|[35]9|4[26]|76)|5(?:22|44)|642|8(?:62|8[245])","($NP$FG)",],["(\\d{5})(\\d{4})","$1 $2","346|4(?:27|9[35])|883","($NP$FG)",],["([3-8]\\d)(\\d{3})(\\d{4})","$1 $2 $3","[3-8]","($NP$FG)",],["(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3","81|9","$NP$FG",],["(1800)(\\d{3})(\\d{4})","$1 $2 $3","1",,],["(1800)(\\d{1,2})(\\d{3})(\\d{4})","$1 $2 $3 $4","1",,]]]',
"236": '["CF","00",,,,,"\\d{8}","[278]\\d{7}",[["(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",,,]]]',
@ -88,7 +88,7 @@ this.PHONE_NUMBER_META_DATA = {
"965": '["KW","00",,,,,"\\d{7,8}","[12569]\\d{6,7}",[["(\\d{4})(\\d{3,4})","$1 $2","[1269]",,],["(5[015]\\d)(\\d{5})","$1 $2","5",,]]]',
"224": '["GN","00",,,,,"\\d{8,9}","[367]\\d{7,8}",[["(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4","3",,],["(\\d{3})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4","[67]",,]]]',
"973": '["BH","00",,,,,"\\d{8}","[136-9]\\d{7}",[["(\\d{4})(\\d{4})","$1 $2",,,]]]',
"32": '["BE","00","0",,,"$NP$FG","\\d{8,9}","[1-9]\\d{7,8}",[["(4[6-9]\\d)(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4","4[6-9]",,],["([2-49])(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4","[23]|[49][23]",,],["([15-8]\\d)(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4","[156]|7[0178]|8(?:0[1-9]|[1-79])",,],["([89]\\d{2})(\\d{2})(\\d{3})","$1 $2 $3","(?:80|9)0",,]]]',
"32": '["BE","00","0",,,"$NP$FG","\\d{8,9}","[1-9]\\d{7,8}",[["(4[6-9]\\d)(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4","4[6-9]",,],["([2-49])(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4","[23]|[49][23]",,],["([15-8]\\d)(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4","[156]|7[018]|8(?:0[1-9]|[1-79])",,],["([89]\\d{2})(\\d{2})(\\d{3})","$1 $2 $3","(?:80|9)0",,]]]',
"249": '["SD","00","0",,,"$NP$FG","\\d{9}","[19]\\d{8}",[["(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3",,,]]]',
"678": '["VU","00",,,,,"\\d{5,7}","[2-57-9]\\d{4,6}",[["(\\d{3})(\\d{4})","$1 $2","[579]",,]]]',
"52": '["MX","0[09]","01","0[12]|04[45](\\d{10})","1$1","$NP $FG","\\d{7,11}","[1-9]\\d{9,10}",[["([358]\\d)(\\d{4})(\\d{4})","$1 $2 $3","33|55|81",,],["(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3","[2467]|3[12457-9]|5[89]|8[02-9]|9[0-35-9]",,],["(1)([358]\\d)(\\d{4})(\\d{4})","044 $2 $3 $4","1(?:33|55|81)","$FG","$1 $2 $3 $4"],["(1)(\\d{3})(\\d{3})(\\d{4})","044 $2 $3 $4","1(?:[2467]|3[12457-9]|5[89]|8[2-9]|9[1-35-9])","$FG","$1 $2 $3 $4"]]]',
@ -110,15 +110,15 @@ this.PHONE_NUMBER_META_DATA = {
"591": '["BO","00(1\\d)?","0","0(1\\d)?",,,"\\d{7,8}","[23467]\\d{7}",[["([234])(\\d{7})","$1 $2","[234]",,],["([67]\\d{7})","$1","[67]",,]]]',
"808": '["001",,,,,,"\\d{8}","\\d{8}",[["(\\d{4})(\\d{4})","$1 $2",,,]]]',
"964": '["IQ","00","0",,,"$NP$FG","\\d{6,10}","[1-7]\\d{7,9}",[["(1)(\\d{3})(\\d{4})","$1 $2 $3","1",,],["([2-6]\\d)(\\d{3})(\\d{3,4})","$1 $2 $3","[2-6]",,],["(7\\d{2})(\\d{3})(\\d{4})","$1 $2 $3","7",,]]]',
"225": '["CI","00",,,,,"\\d{8}","[02-6]\\d{7}",[["(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",,,]]]',
"225": '["CI","00",,,,,"\\d{8}","[02-7]\\d{7}",[["(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",,,]]]',
"992": '["TJ","810","8",,,"($NP) $FG","\\d{3,9}","[3-59]\\d{8}",[["([349]\\d{2})(\\d{2})(\\d{4})","$1 $2 $3","[34]7|91[78]",,],["([459]\\d)(\\d{3})(\\d{4})","$1 $2 $3","4[48]|5|9(?:1[59]|[0235-9])",,],["(331700)(\\d)(\\d{2})","$1 $2 $3","331",,],["(\\d{4})(\\d)(\\d{4})","$1 $2 $3","3[1-5]",,]]]',
"55": '["BR","00(?:1[45]|2[135]|[34]1|43)","0","(?:0|90)(?:(1[245]|2[135]|[34]1)(\\d{10,11}))?","$2",,"\\d{8,11}","[1-46-9]\\d{7,10}|5\\d{8,9}",[["(\\d{4})(\\d{4})","$1-$2","[2-9](?:[1-9]|0[1-9])","$FG","NA"],["(\\d{5})(\\d{4})","$1-$2","9(?:[1-9]|0[1-9])","$FG","NA"],["(\\d{3,5})","$1","1[125689]","$FG","NA"],["(\\d{2})(\\d{5})(\\d{4})","$1 $2-$3","(?:1[1-9]|2[12478])9","($FG)",],["(\\d{2})(\\d{4})(\\d{4})","$1 $2-$3","[1-9][1-9]","($FG)",],["([34]00\\d)(\\d{4})","$1-$2","[34]00",,],["([3589]00)(\\d{2,3})(\\d{4})","$1 $2 $3","[3589]00","$NP$FG",]]]',
"674": '["NR","00",,,,,"\\d{7}","[458]\\d{6}",[["(\\d{3})(\\d{4})","$1 $2",,,]]]',
"967": '["YE","00","0",,,"$NP$FG","\\d{6,9}","[1-7]\\d{6,8}",[["([1-7])(\\d{3})(\\d{3,4})","$1 $2 $3","[1-6]|7[24-68]",,],["(7\\d{2})(\\d{3})(\\d{3})","$1 $2 $3","7[0137]",,]]]',
"49": '["DE","00","0",,,"$NP$FG","\\d{2,15}","[1-35-9]\\d{3,14}|4(?:[0-8]\\d{4,12}|9(?:[0-37]\\d|4(?:[1-35-8]|4\\d?)|5\\d{1,2}|6[1-8]\\d?)\\d{2,7})",[["(1\\d{2})(\\d{7,8})","$1 $2","1[67]",,],["(1\\d{3})(\\d{7})","$1 $2","15",,],["(\\d{2})(\\d{4,11})","$1 $2","3[02]|40|[68]9",,],["(\\d{3})(\\d{3,11})","$1 $2","2(?:\\d1|0[2389]|1[24]|28|34)|3(?:[3-9][15]|40)|[4-8][1-9]1|9(?:06|[1-9]1)",,],["(\\d{4})(\\d{2,11})","$1 $2","[24-6]|[7-9](?:\\d[1-9]|[1-9]\\d)|3(?:[3569][02-46-9]|4[2-4679]|7[2-467]|8[2-46-8])",,],["(3\\d{4})(\\d{1,10})","$1 $2","3",,],["(800)(\\d{7,12})","$1 $2","800",,],["(177)(99)(\\d{7,8})","$1 $2 $3","177",,],["(\\d{3})(\\d)(\\d{4,10})","$1 $2 $3","(?:18|90)0",,],["(1\\d{2})(\\d{5,11})","$1 $2","181",,],["(18\\d{3})(\\d{6})","$1 $2","185",,],["(18\\d{2})(\\d{7})","$1 $2","18[68]",,],["(18\\d)(\\d{8})","$1 $2","18[2-579]",,],["(700)(\\d{4})(\\d{4})","$1 $2 $3","700",,]]]',
"49": '["DE","00","0",,,"$NP$FG","\\d{2,15}","[1-35-9]\\d{3,14}|4(?:[0-8]\\d{4,12}|9(?:[0-37]\\d|4(?:[1-35-8]|4\\d?)|5\\d{1,2}|6[1-8]\\d?)\\d{2,7})",[["(1\\d{2})(\\d{7,8})","$1 $2","1[67]",,],["(1\\d{3})(\\d{7})","$1 $2","15",,],["(\\d{2})(\\d{3,11})","$1 $2","3[02]|40|[68]9",,],["(\\d{3})(\\d{3,11})","$1 $2","2(?:\\d1|0[2389]|1[24]|28|34)|3(?:[3-9][15]|40)|[4-8][1-9]1|9(?:06|[1-9]1)",,],["(\\d{4})(\\d{2,11})","$1 $2","[24-6]|[7-9](?:\\d[1-9]|[1-9]\\d)|3(?:[3569][02-46-9]|4[2-4679]|7[2-467]|8[2-46-8])",,],["(3\\d{4})(\\d{1,10})","$1 $2","3",,],["(800)(\\d{7,12})","$1 $2","800",,],["(177)(99)(\\d{7,8})","$1 $2 $3","177",,],["(\\d{3})(\\d)(\\d{4,10})","$1 $2 $3","(?:18|90)0",,],["(1\\d{2})(\\d{5,11})","$1 $2","181",,],["(18\\d{3})(\\d{6})","$1 $2","185",,],["(18\\d{2})(\\d{7})","$1 $2","18[68]",,],["(18\\d)(\\d{8})","$1 $2","18[2-579]",,],["(700)(\\d{4})(\\d{4})","$1 $2 $3","700",,]]]',
"31": '["NL","00","0",,,"$NP$FG","\\d{5,10}","1\\d{4,8}|[2-7]\\d{8}|[89]\\d{6,9}",[["([1-578]\\d)(\\d{3})(\\d{4})","$1 $2 $3","1[035]|2[0346]|3[03568]|4[0356]|5[0358]|7|8[4578]",,],["([1-5]\\d{2})(\\d{3})(\\d{3})","$1 $2 $3","1[16-8]|2[259]|3[124]|4[17-9]|5[124679]",,],["(6)(\\d{8})","$1 $2","6[0-57-9]",,],["(66)(\\d{7})","$1 $2","66",,],["(14)(\\d{3,4})","$1 $2","14","$FG",],["([89]0\\d)(\\d{4,7})","$1 $2","80|9",,]]]',
"970": '["PS","00","0",,,"$NP$FG","\\d{4,10}","[24589]\\d{7,8}|1(?:[78]\\d{8}|[49]\\d{2,3})",[["([2489])(2\\d{2})(\\d{4})","$1 $2 $3","[2489]",,],["(5[69]\\d)(\\d{3})(\\d{3})","$1 $2 $3","5",,],["(1[78]00)(\\d{3})(\\d{3})","$1 $2 $3","1[78]","$FG",]]]',
"58": '["VE","00","0","(1\\d{2})|0",,"$NP$FG","\\d{7,10}","[24589]\\d{9}",[["(\\d{3})(\\d{7})","$1-$2",,,]]]',
"58": '["VE","00","0",,,"$NP$FG","\\d{7,10}","[24589]\\d{9}",[["(\\d{3})(\\d{7})","$1-$2",,,]]]',
"856": '["LA","00","0",,,"$NP$FG","\\d{6,10}","[2-8]\\d{7,9}",[["(20)(\\d{2})(\\d{3})(\\d{3})","$1 $2 $3 $4","20",,],["([2-8]\\d)(\\d{3})(\\d{3})","$1 $2 $3","2[13]|[3-8]",,]]]',
"354": '["IS","00",,,,,"\\d{7,9}","[4-9]\\d{6}|38\\d{7}",[["(\\d{3})(\\d{4})","$1 $2","[4-9]",,],["(3\\d{2})(\\d{3})(\\d{3})","$1 $2 $3","3",,]]]',
"242": '["CG","00",,,,,"\\d{9}","[028]\\d{8}",[["(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3","[02]",,],["(\\d)(\\d{4})(\\d{4})","$1 $2 $3","8",,]]]',
@ -142,7 +142,7 @@ this.PHONE_NUMBER_META_DATA = {
"993": '["TM","810","8",,,"($NP $FG)","\\d{8}","[1-6]\\d{7}",[["(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2-$3-$4","12",,],["(\\d{2})(\\d{6})","$1 $2","6","$NP $FG",],["(\\d{3})(\\d)(\\d{2})(\\d{2})","$1 $2-$3-$4","13|[2-5]",,]]]',
"888": '["001",,,,,,"\\d{11}","\\d{11}",[["(\\d{3})(\\d{3})(\\d{5})","$1 $2 $3",,,]]]',
"353": '["IE","00","0",,,"($NP$FG)","\\d{5,10}","[124-9]\\d{6,9}",[["(1)(\\d{3,4})(\\d{4})","$1 $2 $3","1",,],["(\\d{2})(\\d{5})","$1 $2","2[24-9]|47|58|6[237-9]|9[35-9]",,],["(\\d{3})(\\d{5})","$1 $2","40[24]|50[45]",,],["(48)(\\d{4})(\\d{4})","$1 $2 $3","48",,],["(818)(\\d{3})(\\d{3})","$1 $2 $3","81",,],["(\\d{2})(\\d{3})(\\d{3,4})","$1 $2 $3","[24-69]|7[14]",,],["([78]\\d)(\\d{3,4})(\\d{4})","$1 $2 $3","76|8[35-9]","$NP$FG",],["(700)(\\d{3})(\\d{3})","$1 $2 $3","70","$NP$FG",],["(\\d{4})(\\d{3})(\\d{3})","$1 $2 $3","1(?:8[059]|5)","$FG",]]]',
"966": '["SA","00","0",,,"$NP$FG","\\d{7,10}","1\\d{7,8}|(?:[2-467]|92)\\d{7}|5\\d{8}|8\\d{9}",[["([1-467])(\\d{3})(\\d{4})","$1 $2 $3","[1-467]",,],["(1\\d)(\\d{3})(\\d{4})","$1 $2 $3","1[1-467]",,],["(5\\d)(\\d{3})(\\d{4})","$1 $2 $3","5",,],["(92\\d{2})(\\d{5})","$1 $2","9","$FG",],["(800)(\\d{3})(\\d{4})","$1 $2 $3","80","$FG",],["(811)(\\d{3})(\\d{3,4})","$1 $2 $3","81",,]]]',
"966": '["SA","00","0",,,"$NP$FG","\\d{7,10}","1\\d{7,8}|(?:[2-467]|92)\\d{7}|5\\d{8}|8\\d{9}",[["([1-467])(\\d{3})(\\d{4})","$1 $2 $3","[1-467]",,],["(1\\d)(\\d{3})(\\d{4})","$1 $2 $3","1[1-467]",,],["(5\\d)(\\d{3})(\\d{4})","$1 $2 $3","5",,],["(92\\d{2})(\\d{5})","$1 $2","92","$FG",],["(800)(\\d{3})(\\d{4})","$1 $2 $3","80","$FG",],["(811)(\\d{3})(\\d{3,4})","$1 $2 $3","81",,]]]',
"380": '["UA","00","0",,,"$NP$FG","\\d{5,9}","[3-689]\\d{8}",[["([3-689]\\d)(\\d{3})(\\d{4})","$1 $2 $3","[38]9|4(?:[45][0-5]|87)|5(?:0|6[37]|7[37])|6[36-8]|9[1-9]",,],["([3-689]\\d{2})(\\d{3})(\\d{3})","$1 $2 $3","3[1-8]2|4[13678]2|5(?:[12457]2|6[24])|6(?:[49]2|[12][29]|5[24])|8[0-8]|90",,],["([3-6]\\d{3})(\\d{5})","$1 $2","3(?:5[013-9]|[1-46-8])|4(?:[137][013-9]|6|[45][6-9]|8[4-6])|5(?:[1245][013-9]|6[0135-9]|3|7[4-6])|6(?:[49][013-9]|5[0135-9]|[12][13-8])",,]]]',
"98": '["IR","00","0",,,"$NP$FG","\\d{4,10}","[14-8]\\d{6,9}|[23]\\d{4,9}|9(?:[1-4]\\d{8}|9\\d{2,8})",[["(2[15])(\\d{3,5})","$1 $2","2(?:1|5[0-47-9])",,],["(2[15])(\\d{3})(\\d{3,4})","$1 $2 $3","2(?:1|5[0-47-9])",,],["(2\\d)(\\d{4})(\\d{4})","$1 $2 $3","2(?:[16]|5[0-47-9])",,],["(\\d{3})(\\d{3})(\\d{3,4})","$1 $2 $3","[13-9]|2[02-57-9]",,],["(\\d{3})(\\d{2})(\\d{2,3})","$1 $2 $3","[13-9]|2[02-57-9]",,],["(\\d{3})(\\d{3})","$1 $2","[13-9]|2[02-57-9]",,]]]',
"971": '["AE","00","0",,,"$NP$FG","\\d{5,12}","[2-79]\\d{7,8}|800\\d{2,9}",[["([2-4679])(\\d{3})(\\d{4})","$1 $2 $3","[2-4679][2-8]",,],["(5[0256])(\\d{3})(\\d{4})","$1 $2 $3","5",,],["([479]00)(\\d)(\\d{5})","$1 $2 $3","[479]0","$FG",],["([68]00)(\\d{2,9})","$1 $2","60|8","$FG",]]]',
@ -156,25 +156,25 @@ this.PHONE_NUMBER_META_DATA = {
"502": '["GT","00",,,,,"\\d{8}(?:\\d{3})?","[2-7]\\d{7}|1[89]\\d{9}",[["(\\d{4})(\\d{4})","$1 $2","[2-7]",,],["(\\d{4})(\\d{3})(\\d{4})","$1 $2 $3","1",,]]]',
"82": '["KR","00(?:[124-68]|[37]\\d{2})","0","0(8[1-46-8]|85\\d{2})?",,"$NP$FG","\\d{4,10}","[1-7]\\d{3,9}|8\\d{8}",[["(\\d{2})(\\d{4})(\\d{4})","$1-$2-$3","1(?:0|1[19]|[69]9|5[458])|[57]0",,],["(\\d{2})(\\d{3,4})(\\d{4})","$1-$2-$3","1(?:[169][2-8]|[78]|5[1-4])|[68]0|[3-6][1-9][1-9]",,],["(\\d{3})(\\d)(\\d{4})","$1-$2-$3","131",,],["(\\d{3})(\\d{2})(\\d{4})","$1-$2-$3","131",,],["(\\d{3})(\\d{3})(\\d{4})","$1-$2-$3","13[2-9]",,],["(\\d{2})(\\d{2})(\\d{3})(\\d{4})","$1-$2-$3-$4","30",,],["(\\d)(\\d{3,4})(\\d{4})","$1-$2-$3","2[1-9]",,],["(\\d)(\\d{3,4})","$1-$2","21[0-46-9]",,],["(\\d{2})(\\d{3,4})","$1-$2","[3-6][1-9]1",,],["(\\d{4})(\\d{4})","$1-$2","1(?:5[46-9]|6[04678])","$FG",]]]',
"253": '["DJ","00",,,,,"\\d{8}","[27]\\d{7}",[["(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",,,]]]',
"91": '["IN","00","0",,,"$NP$FG","\\d{6,13}","1\\d{7,12}|[2-9]\\d{9,10}",[["(\\d{2})(\\d{2})(\\d{6})","$1 $2 $3","7(?:2[0579]|3[057-9]|4[0-389]|5[024-9]|6[0-35-9]|7|8[0-79])|8(?:0[015689]|1[0-57-9]|2[2356-9]|3[0-57-9]|[45]|6[0245789]|7[1-69]|8[0124-9]|9[02-9])|9",,],["(\\d{2})(\\d{4})(\\d{4})","$1 $2 $3","11|2[02]|33|4[04]|79|80[2-46]",,],["(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3","1(?:2[0-249]|3[0-25]|4[145]|[569][14]|7[1257]|8[1346]|[68][1-9])|2(?:1[257]|3[013]|4[01]|5[0137]|6[0158]|78|8[1568]|9[14])|3(?:26|4[1-3]|5[34]|6[01489]|7[02-46]|8[159])|4(?:1[36]|2[1-47]|3[15]|5[12]|6[126-9]|7[0-24-9]|8[013-57]|9[014-7])|5(?:[136][25]|22|4[28]|5[12]|[78]1|9[15])|6(?:12|[2345]1|57|6[13]|7[14]|80)",,],["(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3","7(?:12|2[14]|3[134]|4[47]|5[15]|[67]1|88)",,],["(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3","8(?:16|2[014]|3[126]|6[136]|7[078]|8[34]|91)",,],["(\\d{4})(\\d{3})(\\d{3})","$1 $2 $3","1(?:[2-579]|[68][1-9])|[2-8]",,],["(1600)(\\d{2})(\\d{4})","$1 $2 $3","160","$FG",],["(1800)(\\d{4,5})","$1 $2","180","$FG",],["(18[06]0)(\\d{2,4})(\\d{4})","$1 $2 $3","18[06]","$FG",],["(\\d{4})(\\d{3})(\\d{4})(\\d{2})","$1 $2 $3 $4","18[06]","$FG",]]]',
"91": '["IN","00","0",,,"$NP$FG","\\d{6,13}","1\\d{7,12}|[2-9]\\d{9,10}",[["(\\d{2})(\\d{2})(\\d{6})","$1 $2 $3","7(?:2[0579]|3[057-9]|4[0-389]|6[0-35-9]|[57]|8[0-79])|8(?:0[015689]|1[0-57-9]|2[2356-9]|3[0-57-9]|[45]|6[02457-9]|7[1-69]|8[0124-9]|9[02-9])|9",,],["(\\d{2})(\\d{4})(\\d{4})","$1 $2 $3","11|2[02]|33|4[04]|79|80[2-46]",,],["(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3","1(?:2[0-249]|3[0-25]|4[145]|[569][14]|7[1257]|8[1346]|[68][1-9])|2(?:1[257]|3[013]|4[01]|5[0137]|6[0158]|78|8[1568]|9[14])|3(?:26|4[1-3]|5[34]|6[01489]|7[02-46]|8[159])|4(?:1[36]|2[1-47]|3[15]|5[12]|6[126-9]|7[0-24-9]|8[013-57]|9[014-7])|5(?:[136][25]|22|4[28]|5[12]|[78]1|9[15])|6(?:12|[2345]1|57|6[13]|7[14]|80)",,],["(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3","7(?:12|2[14]|3[134]|4[47]|5[15]|[67]1|88)",,],["(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3","8(?:16|2[014]|3[126]|6[136]|7[078]|8[34]|91)",,],["(\\d{4})(\\d{3})(\\d{3})","$1 $2 $3","1(?:[2-579]|[68][1-9])|[2-8]",,],["(1600)(\\d{2})(\\d{4})","$1 $2 $3","160","$FG",],["(1800)(\\d{4,5})","$1 $2","180","$FG",],["(18[06]0)(\\d{2,4})(\\d{4})","$1 $2 $3","18[06]","$FG",],["(\\d{4})(\\d{3})(\\d{4})(\\d{2})","$1 $2 $3 $4","18[06]","$FG",]]]',
"389": '["MK","00","0",,,"$NP$FG","\\d{8}","[2-578]\\d{7}",[["(2)(\\d{3})(\\d{4})","$1 $2 $3","2",,],["([347]\\d)(\\d{3})(\\d{3})","$1 $2 $3","[347]",,],["([58]\\d{2})(\\d)(\\d{2})(\\d{2})","$1 $2 $3 $4","[58]",,]]]',
"1": ['["US","011","1",,,,"\\d{7}(?:\\d{3})?","[2-9]\\d{9}",[["(\\d{3})(\\d{4})","$1-$2",,,"NA"],["(\\d{3})(\\d{3})(\\d{4})","($1) $2-$3",,,"$1-$2-$3"]]]','["AI","011","1",,,,"\\d{7}(?:\\d{3})?","[2589]\\d{9}",]','["AS","011","1",,,,"\\d{7}(?:\\d{3})?","[5689]\\d{9}",]','["BB","011","1",,,,"\\d{7}(?:\\d{3})?","[2589]\\d{9}",]','["BM","011","1",,,,"\\d{7}(?:\\d{3})?","[4589]\\d{9}",]','["BS","011","1",,,,"\\d{7}(?:\\d{3})?","[2589]\\d{9}",]','["CA","011","1",,,,"\\d{7}(?:\\d{3})?","[2-9]\\d{9}|3\\d{6}",]','["DM","011","1",,,,"\\d{7}(?:\\d{3})?","[57-9]\\d{9}",]','["DO","011","1",,,,"\\d{7}(?:\\d{3})?","[589]\\d{9}",]','["GD","011","1",,,,"\\d{7}(?:\\d{3})?","[4589]\\d{9}",]','["GU","011","1",,,,"\\d{7}(?:\\d{3})?","[5689]\\d{9}",]','["JM","011","1",,,,"\\d{7}(?:\\d{3})?","[589]\\d{9}",]','["KN","011","1",,,,"\\d{7}(?:\\d{3})?","[589]\\d{9}",]','["KY","011","1",,,,"\\d{7}(?:\\d{3})?","[3589]\\d{9}",]','["LC","011","1",,,,"\\d{7}(?:\\d{3})?","[5789]\\d{9}",]','["MP","011","1",,,,"\\d{7}(?:\\d{3})?","[5689]\\d{9}",]','["MS","011","1",,,,"\\d{7}(?:\\d{3})?","[5689]\\d{9}",]','["PR","011","1",,,,"\\d{7}(?:\\d{3})?","[5789]\\d{9}",]','["SX","011","1",,,,"\\d{7}(?:\\d{3})?","[5789]\\d{9}",]','["TC","011","1",,,,"\\d{7}(?:\\d{3})?","[5689]\\d{9}",]','["TT","011","1",,,,"\\d{7}(?:\\d{3})?","[589]\\d{9}",]','["AG","011","1",,,,"\\d{7}(?:\\d{3})?","[2589]\\d{9}",]','["VC","011","1",,,,"\\d{7}(?:\\d{3})?","[5789]\\d{9}",]','["VG","011","1",,,,"\\d{7}(?:\\d{3})?","[2589]\\d{9}",]','["VI","011","1",,,,"\\d{7}(?:\\d{3})?","[3589]\\d{9}",]'],
"60": '["MY","00","0",,,,"\\d{6,10}","[13-9]\\d{7,9}",[["([4-79])(\\d{3})(\\d{4})","$1-$2 $3","[4-79]","$NP$FG",],["(3)(\\d{4})(\\d{4})","$1-$2 $3","3","$NP$FG",],["([18]\\d)(\\d{3})(\\d{3,4})","$1-$2 $3","1[02-46-9][1-9]|8","$NP$FG",],["(1)([36-8]00)(\\d{2})(\\d{4})","$1-$2-$3-$4","1[36-8]0",,],["(11)(\\d{4})(\\d{4})","$1-$2 $3","11","$NP$FG",],["(15[49])(\\d{3})(\\d{4})","$1-$2 $3","15","$NP$FG",]]]',
"355": '["AL","00","0",,,"$NP$FG","\\d{5,9}","[2-57]\\d{7}|6\\d{8}|8\\d{5,7}|9\\d{5}",[["(4)(\\d{3})(\\d{4})","$1 $2 $3","4[0-6]",,],["(6[6-9])(\\d{3})(\\d{4})","$1 $2 $3","6",,],["(\\d{2})(\\d{3})(\\d{3})","$1 $2 $3","[2358][2-5]|4[7-9]",,],["(\\d{3})(\\d{3,5})","$1 $2","[235][16-9]|8[016-9]|[79]",,]]]',
"254": '["KE","000","0",,,"$NP$FG","\\d{5,10}","20\\d{6,7}|[4-9]\\d{6,9}",[["(\\d{2})(\\d{4,7})","$1 $2","[24-6]",,],["(\\d{3})(\\d{6,7})","$1 $2","7",,],["(\\d{3})(\\d{3})(\\d{3,4})","$1 $2 $3","[89]",,]]]',
"223": '["ML","00",,,,,"\\d{8}","[246-8]\\d{7}",[["([246-8]\\d)(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",,,]]]',
"686": '["KI","00",,"0",,,"\\d{5}","[2-689]\\d{4}",]',
"223": '["ML","00",,,,,"\\d{8}","[246-9]\\d{7}",[["(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4","[246-9]",,],["(\\d{4})","$1","67|74",,"NA"]]]',
"686": '["KI","00",,"0",,,"\\d{5,8}","[2-689]\\d{4}|7\\d{7}",]',
"994": '["AZ","00","0",,,"($NP$FG)","\\d{7,9}","[1-9]\\d{8}",[["(\\d{2})(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4","(?:1[28]|2(?:[45]2|[0-36])|365)",,],["(\\d{2})(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4","[4-8]","$NP$FG",],["(\\d{3})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4","9","$NP$FG",]]]',
"979": '["001",,,,,,"\\d{9}","\\d{9}",[["(\\d)(\\d{4})(\\d{4})","$1 $2 $3",,,]]]',
"66": '["TH","00","0",,,"$NP$FG","\\d{4}|\\d{8,10}","[2-9]\\d{7,8}|1\\d{3}(?:\\d{6})?",[["(2)(\\d{3})(\\d{4})","$1 $2 $3","2",,],["([3-9]\\d)(\\d{3})(\\d{3,4})","$1 $2 $3","[3-9]",,],["(1[89]00)(\\d{3})(\\d{3})","$1 $2 $3","1","$FG",]]]',
"233": '["GH","00","0",,,"$NP$FG","\\d{7,9}","[235]\\d{8}|8\\d{7}",[["(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3","[235]",,],["(\\d{3})(\\d{5})","$1 $2","8",,]]]',
"593": '["EC","00","0",,,"($NP$FG)","\\d{7,11}","1\\d{9,10}|[2-8]\\d{7}|9\\d{8}",[["(\\d)(\\d{3})(\\d{4})","$1 $2-$3","[247]|[356][2-8]",,"$1-$2-$3"],["(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3","9","$NP$FG",],["(1800)(\\d{3})(\\d{3,4})","$1 $2 $3","1","$FG",]]]',
"509": '["HT","00",,,,,"\\d{8}","[2-489]\\d{7}",[["(\\d{2})(\\d{2})(\\d{4})","$1 $2 $3",,,]]]',
"54": '["AR","00","0","0?(?:(11|2(?:2(?:02?|[13]|2[13-79]|4[1-6]|5[2457]|6[124-8]|7[1-4]|8[13-6]|9[1267])|3(?:02?|1[467]|2[03-6]|3[13-8]|[49][2-6]|5[2-8]|[67])|4(?:7[3-578]|9)|6(?:[0136]|2[24-6]|4[6-8]?|5[15-8])|80|9(?:0[1-3]|[19]|2\\d|3[1-6]|4[02568]?|5[2-4]|6[2-46]|72?|8[23]?))|3(?:3(?:2[79]|6|8[2578])|4(?:0[124-9]|[12]|3[5-8]?|4[24-7]|5[4-68]?|6[02-9]|7[126]|8[2379]?|9[1-36-8])|5(?:1|2[1245]|3[237]?|4[1-46-9]|6[2-4]|7[1-6]|8[2-5]?)|6[24]|7(?:1[1568]|2[15]|3[145]|4[13]|5[14-8]|[069]|7[2-57]|8[126])|8(?:[01]|2[15-7]|3[2578]?|4[13-6]|5[4-8]?|6[1-357-9]|7[36-8]?|8[5-8]?|9[124])))15)?","9$1","$NP$FG","\\d{6,11}","[1-368]\\d{9}|9\\d{10}",[["([68]\\d{2})(\\d{3})(\\d{4})","$1-$2-$3","[68]",,],["(9)(11)(\\d{4})(\\d{4})","$2 15-$3-$4","911",,"$1 $2 $3-$4"],["(9)(\\d{3})(\\d{3})(\\d{4})","$2 15-$3-$4","9(?:2[234689]|3[3-8])",,"$1 $2 $3-$4"],["(9)(\\d{4})(\\d{3})(\\d{3})","$2 15-$3-$4","93[58]",,"$1 $2 $3-$4"],["(9)(\\d{4})(\\d{2})(\\d{4})","$2 15-$3-$4","9[23]",,"$1 $2 $3-$4"],["(11)(\\d{4})(\\d{4})","$1 $2-$3","1",,],["(\\d{3})(\\d{3})(\\d{4})","$1 $2-$3","2(?:2[013]|3[067]|49|6[01346]|80|9[147-9])|3(?:36|4[12358]|5[138]|6[24]|7[069]|8[013578])",,],["(\\d{4})(\\d{3})(\\d{3})","$1 $2-$3","3(?:53|8[78])",,],["(\\d{4})(\\d{2})(\\d{4})","$1 $2-$3","[23]",,]]]',
"57": '["CO","00[579]|#555|#999","0","0([3579]|4(?:44|56))?",,,"\\d{7,11}","(?:[13]\\d{0,3}|[24-8])\\d{7}",[["(\\d)(\\d{7})","$1 $2","1(?:8[2-9]|9[0-3]|[2-7])|[24-8]","($FG)",],["(\\d{3})(\\d{7})","$1 $2","3",,],["(1)(\\d{3})(\\d{7})","$1-$2-$3","1(?:80|9[04])","$NP$FG","$1 $2 $3"]]]',
"54": '["AR","00","0","0?(?:(11|2(?:2(?:02?|[13]|2[13-79]|4[1-6]|5[2457]|6[124-8]|7[1-4]|8[13-6]|9[1267])|3(?:02?|1[467]|2[03-6]|3[13-8]|[49][2-6]|5[2-8]|[67])|4(?:7[3-578]|9)|6(?:[0136]|2[24-6]|4[6-8]?|5[15-8])|80|9(?:0[1-3]|[19]|2\\d|3[1-6]|4[02568]?|5[2-4]|6[2-46]|72?|8[23]?))|3(?:3(?:2[79]|6|8[2578])|4(?:0[124-9]|[12]|3[5-8]?|4[24-7]|5[4-68]?|6[02-9]|7[126]|8[2379]?|9[1-36-8])|5(?:1|2[1245]|3[237]?|4[1-46-9]|6[2-4]|7[1-6]|8[2-5]?)|6[24]|7(?:1[1568]|2[15]|3[145]|4[13]|5[14-8]|[069]|7[2-57]|8[126])|8(?:[01]|2[15-7]|3[2578]?|4[13-6]|5[4-8]?|6[1-357-9]|7[36-8]?|8[5-8]?|9[124])))15)?","9$1","$NP$FG","\\d{6,11}","[1-368]\\d{9}|9\\d{10}",[["([68]\\d{2})(\\d{3})(\\d{4})","$1-$2-$3","[68]",,],["(9)(11)(\\d{4})(\\d{4})","$2 15-$3-$4","911",,"$1 $2 $3-$4"],["(9)(\\d{3})(\\d{3})(\\d{4})","$2 15-$3-$4","9(?:2[234689]|3[3-8])",,"$1 $2 $3-$4"],["(9)(\\d{4})(\\d{3})(\\d{3})","$2 15-$3-$4","93[58]",,"$1 $2 $3-$4"],["(9)(\\d{4})(\\d{2})(\\d{4})","$2 15-$3-$4","9[23]",,"$1 $2 $3-$4"],["(11)(\\d{4})(\\d{4})","$1 $2-$3","1",,],["(\\d{3})(\\d{3})(\\d{4})","$1 $2-$3","2(?:2[013]|3[067]|49|6[01346]|80|9[147-9])|3(?:36|4[12358]|5[138]|6[24]|7[069]|8[013578])",,],["(\\d{4})(\\d{3})(\\d{3})","$1 $2-$3","3(?:53|8[78])",,],["(\\d{4})(\\d{2})(\\d{4})","$1 $2-$3","[23]",,],["(\\d{3})","$1","1[012]|911","$FG","NA"]]]',
"57": '["CO","00(?:4(?:[14]4|56)|[579])","0","0([3579]|4(?:44|56))?",,,"\\d{7,11}","(?:[13]\\d{0,3}|[24-8])\\d{7}",[["(\\d)(\\d{7})","$1 $2","1(?:8[2-9]|9[0-3]|[2-7])|[24-8]","($FG)",],["(\\d{3})(\\d{7})","$1 $2","3",,],["(1)(\\d{3})(\\d{7})","$1-$2-$3","1(?:80|9[04])","$NP$FG","$1 $2 $3"]]]',
"597": '["SR","00",,,,,"\\d{6,7}","[2-8]\\d{5,6}",[["(\\d{3})(\\d{3})","$1-$2","[2-4]|5[2-58]",,],["(\\d{2})(\\d{2})(\\d{2})","$1-$2-$3","56",,],["(\\d{3})(\\d{4})","$1-$2","[6-8]",,]]]',
"676": '["TO","00",,,,,"\\d{5,7}","[02-8]\\d{4,6}",[["(\\d{2})(\\d{3})","$1-$2","[1-6]|7[0-4]|8[05]",,],["(\\d{3})(\\d{4})","$1 $2","7[5-9]|8[7-9]",,],["(\\d{4})(\\d{3})","$1 $2","0",,]]]',
"505": '["NI","00",,,,,"\\d{8}","[128]\\d{7}",[["(\\d{4})(\\d{4})","$1 $2",,,]]]',
"505": '["NI","00",,,,,"\\d{8}","[1258]\\d{7}",[["(\\d{4})(\\d{4})","$1 $2",,,]]]',
"850": '["KP","00|99","0",,,"$NP$FG","\\d{6,8}|\\d{10}","1\\d{9}|[28]\\d{7}",[["(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3","1",,],["(\\d)(\\d{3})(\\d{4})","$1 $2 $3","2",,],["(\\d{2})(\\d{3})(\\d{3})","$1 $2 $3","8",,]]]',
"7": ['["RU","810","8",,,"$NP ($FG)","\\d{10}","[3489]\\d{9}",[["(\\d{3})(\\d{2})(\\d{2})","$1-$2-$3","[1-79]","$FG","NA"],["([3489]\\d{2})(\\d{3})(\\d{2})(\\d{2})","$1 $2-$3-$4","[34689]",,],["(7\\d{2})(\\d{3})(\\d{4})","$1 $2 $3","7",,]]]','["KZ","810","8",,,,"\\d{10}","(?:33\\d|7\\d{2}|80[09])\\d{7}",]'],
"268": '["SZ","00",,,,,"\\d{8}","[027]\\d{7}",[["(\\d{4})(\\d{4})","$1 $2","[027]",,]]]',
@ -188,7 +188,7 @@ this.PHONE_NUMBER_META_DATA = {
"47": ['["NO","00",,,,,"\\d{5}(?:\\d{3})?","0\\d{4}|[2-9]\\d{7}",[["([489]\\d{2})(\\d{2})(\\d{3})","$1 $2 $3","[489]",,],["([235-7]\\d)(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4","[235-7]",,]]]','["SJ","00",,,,,"\\d{5}(?:\\d{3})?","0\\d{4}|[4789]\\d{7}",]'],
"243": '["CD","00","0",,,"$NP$FG","\\d{7,9}","[2-6]\\d{6}|[18]\\d{6,8}|9\\d{8}",[["(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3","12",,],["([89]\\d{2})(\\d{3})(\\d{3})","$1 $2 $3","8[0-2459]|9",,],["(\\d{2})(\\d{2})(\\d{3})","$1 $2 $3","88",,],["(\\d{2})(\\d{5})","$1 $2","[1-6]",,]]]',
"220": '["GM","00",,,,,"\\d{7}","[2-9]\\d{6}",[["(\\d{3})(\\d{4})","$1 $2",,,]]]',
"687": '["NC","00",,,,,"\\d{6}","[2-47-9]\\d{5}",[["(\\d{2})(\\d{2})(\\d{2})","$1.$2.$3",,,]]]',
"687": '["NC","00",,,,,"\\d{6}","[2-57-9]\\d{5}",[["(\\d{2})(\\d{2})(\\d{2})","$1.$2.$3","[2-46-9]|5[0-4]",,]]]',
"995": '["GE","00","0",,,,"\\d{6,9}","[34578]\\d{8}",[["(\\d{3})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4","[348]","$NP$FG",],["(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3","7","$NP$FG",],["(\\d{3})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4","5","$FG",]]]',
"961": '["LB","00","0",,,,"\\d{7,8}","[13-9]\\d{6,7}",[["(\\d)(\\d{3})(\\d{3})","$1 $2 $3","[13-6]|7(?:[2-579]|62|8[0-7])|[89][2-9]","$NP$FG",],["([7-9]\\d)(\\d{3})(\\d{3})","$1 $2 $3","[89][01]|7(?:[01]|6[013-9]|8[89]|91)",,]]]',
"40": '["RO","00","0",,,"$NP$FG","\\d{6,9}","2\\d{5,8}|[37-9]\\d{8}",[["([237]\\d)(\\d{3})(\\d{4})","$1 $2 $3","[23]1",,],["(21)(\\d{4})","$1 $2","21",,],["(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3","[23][3-7]|[7-9]",,],["(2\\d{2})(\\d{3})","$1 $2","2[3-6]",,]]]',
@ -197,11 +197,11 @@ this.PHONE_NUMBER_META_DATA = {
"976": '["MN","001","0",,,"$NP$FG","\\d{6,10}","[12]\\d{7,9}|[57-9]\\d{7}",[["([12]\\d)(\\d{2})(\\d{4})","$1 $2 $3","[12]1",,],["([12]2\\d)(\\d{5,6})","$1 $2","[12]2[1-3]",,],["([12]\\d{3})(\\d{5})","$1 $2","[12](?:27|[3-5])",,],["(\\d{4})(\\d{4})","$1 $2","[57-9]","$FG",],["([12]\\d{4})(\\d{4,5})","$1 $2","[12](?:27|[3-5])",,]]]',
"20": '["EG","00","0",,,"$NP$FG","\\d{5,10}","1\\d{4,9}|[2456]\\d{8}|3\\d{7}|[89]\\d{8,9}",[["(\\d)(\\d{7,8})","$1 $2","[23]",,],["(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3","1[012]|[89]00",,],["(\\d{2})(\\d{6,7})","$1 $2","1(?:3|5[23])|[4-6]|[89][2-9]",,]]]',
"689": '["PF","00",,,,,"\\d{6}(?:\\d{2})?","[2-79]\\d{5}|8\\d{5,7}",[["(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4","89",,],["(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3",,,]]]',
"56": '["CL","(?:0|1(?:1[0-69]|2[0-57]|5[13-58]|69|7[0167]|8[018]))0","0","0|(1(?:1[0-69]|2[0-57]|5[13-58]|69|7[0167]|8[018]))",,"$NP$FG","\\d{6,11}","(?:[2-9]|600|123)\\d{7,8}",[["(2)(\\d{3,4})(\\d{4})","$1 $2 $3","2","($FG)",],["(\\d{2})(\\d{2,3})(\\d{4})","$1 $2 $3","[357]|4[1-35]|6[13-57]","($FG)",],["(9)([5-9]\\d{3})(\\d{4})","$1 $2 $3","9",,],["(44)(\\d{3})(\\d{4})","$1 $2 $3","44",,],["([68]00)(\\d{3})(\\d{3,4})","$1 $2 $3","60|8","$FG",],["(600)(\\d{3})(\\d{2})(\\d{3})","$1 $2 $3 $4","60","$FG",],["(1230)(\\d{3})(\\d{4})","$1 $2 $3","1","$FG",]]]',
"56": '["CL","(?:0|1(?:1[0-69]|2[0-57]|5[13-58]|69|7[0167]|8[018]))0","0","0|(1(?:1[0-69]|2[0-57]|5[13-58]|69|7[0167]|8[018]))",,"$NP$FG","\\d{6,11}","(?:[2-9]|600|123)\\d{7,8}",[["(2)(\\d{3,4})(\\d{4})","$1 $2 $3","2","($FG)",],["(\\d{2})(\\d{2,3})(\\d{4})","$1 $2 $3","[357]|4[1-35]|6[13-57]","($FG)",],["(9)([5-9]\\d{3})(\\d{4})","$1 $2 $3","9",,],["(44)(\\d{3})(\\d{4})","$1 $2 $3","44",,],["([68]00)(\\d{3})(\\d{3,4})","$1 $2 $3","60|8","$FG",],["(600)(\\d{3})(\\d{2})(\\d{3})","$1 $2 $3 $4","60","$FG",],["(1230)(\\d{3})(\\d{4})","$1 $2 $3","1","$FG",],["(\\d{4,5})","$1","[1-9]","$FG","NA"]]]',
"596": '["MQ","00","0",,,"$NP$FG","\\d{9}","[56]\\d{8}",[["(\\d{3})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",,,]]]',
"508": '["PM","00","0",,,"$NP$FG","\\d{6}","[45]\\d{5}",[["([45]\\d)(\\d{2})(\\d{2})","$1 $2 $3",,,]]]',
"269": '["KM","00",,,,,"\\d{7}","[379]\\d{6}",[["(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3",,,]]]',
"358": ['["FI","00|99[049]","0",,,"$NP$FG","\\d{5,12}","1\\d{4,11}|[2-9]\\d{4,10}",[["(\\d{3})(\\d{3,7})","$1 $2","(?:[1-3]00|[6-8]0)",,],["(\\d{2})(\\d{4,10})","$1 $2","2[09]|[14]|50|7[135]",,],["(\\d)(\\d{4,11})","$1 $2","[25689][1-8]|3",,]]]','["AX","00|99[049]","0",,,"$NP$FG","\\d{5,12}","[135]\\d{5,9}|[27]\\d{4,9}|4\\d{5,10}|6\\d{7,8}|8\\d{6,9}",]'],
"358": ['["FI","00|99[049]","0",,,"$NP$FG","\\d{5,12}","1\\d{4,11}|[2-9]\\d{4,10}",[["(\\d{3})(\\d{3,7})","$1 $2","(?:[1-3]00|[6-8]0)",,],["(\\d{2})(\\d{4,10})","$1 $2","[14]|2[09]|50|7[135]",,],["(\\d)(\\d{4,11})","$1 $2","[25689][1-8]|3",,]]]','["AX","00|99[049]","0",,,"$NP$FG","\\d{5,12}","[135]\\d{5,9}|[27]\\d{4,9}|4\\d{5,10}|6\\d{7,8}|8\\d{6,9}",]'],
"251": '["ET","00","0",,,"$NP$FG","\\d{7,9}","[1-59]\\d{8}",[["([1-59]\\d)(\\d{3})(\\d{4})","$1 $2 $3",,,]]]',
"681": '["WF","00",,,,,"\\d{6}","[5-7]\\d{5}",[["(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3",,,]]]',
"853": '["MO","00",,,,,"\\d{8}","[268]\\d{7}",[["([268]\\d{3})(\\d{4})","$1 $2",,,]]]',

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

@ -1434,8 +1434,8 @@ this.PushService = {
return;
}
this._udpServer = Cc["@mozilla.org/network/socket-udp;1"]
.createInstance(Ci.nsIUDPServerSocket);
this._udpServer = Cc["@mozilla.org/network/udp-socket;1"]
.createInstance(Ci.nsIUDPSocket);
this._udpServer.init(-1, false);
this._udpServer.asyncListen(this);
debug("listenForUDPWakeup listening on " + this._udpPort);

486
dom/system/gonk/Nfc.js Normal file
Просмотреть файл

@ -0,0 +1,486 @@
/* Copyright 2012 Mozilla Foundation and Mozilla contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* Copyright © 2013, Deutsche Telekom, Inc. */
"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");
let NFC = {};
Cu.import("resource://gre/modules/nfc_consts.js", NFC);
// set to true in nfc_consts.js to see debug messages
let DEBUG = NFC.DEBUG_NFC;
let debug;
if (DEBUG) {
debug = function (s) {
dump("-*- Nfc: " + s + "\n");
};
} else {
debug = function (s) {};
}
const NFC_CONTRACTID = "@mozilla.org/nfc;1";
const NFC_CID =
Components.ID("{2ff24790-5e74-11e1-b86c-0800200c9a66}");
const NFC_IPC_MSG_NAMES = [
"NFC:SetSessionToken",
"NFC:ReadNDEF",
"NFC:WriteNDEF",
"NFC:GetDetailsNDEF",
"NFC:MakeReadOnlyNDEF",
"NFC:Connect",
"NFC:Close"
];
XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
"@mozilla.org/parentprocessmessagemanager;1",
"nsIMessageBroadcaster");
XPCOMUtils.defineLazyServiceGetter(this, "gSystemMessenger",
"@mozilla.org/system-message-internal;1",
"nsISystemMessagesInternal");
XPCOMUtils.defineLazyServiceGetter(this, "gSystemWorkerManager",
"@mozilla.org/telephony/system-worker-manager;1",
"nsISystemWorkerManager");
XPCOMUtils.defineLazyServiceGetter(this, "gSettingsService",
"@mozilla.org/settingsService;1",
"nsISettingsService");
XPCOMUtils.defineLazyServiceGetter(this, "UUIDGenerator",
"@mozilla.org/uuid-generator;1",
"nsIUUIDGenerator");
XPCOMUtils.defineLazyGetter(this, "gMessageManager", function () {
return {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIMessageListener,
Ci.nsIObserver]),
nfc: null,
// Manage message targets in terms of sessionToken. Only the authorized and
// registered contents can receive related messages.
targetsBySessionTokens: {},
sessionTokens: [],
init: function init(nfc) {
this.nfc = nfc;
Services.obs.addObserver(this, "xpcom-shutdown", false);
this._registerMessageListeners();
},
_shutdown: function _shutdown() {
this.nfc = null;
Services.obs.removeObserver(this, "xpcom-shutdown");
this._unregisterMessageListeners();
},
_registerMessageListeners: function _registerMessageListeners() {
ppmm.addMessageListener("child-process-shutdown", this);
for (let msgname of NFC_IPC_MSG_NAMES) {
ppmm.addMessageListener(msgname, this);
}
},
_unregisterMessageListeners: function _unregisterMessageListeners() {
ppmm.removeMessageListener("child-process-shutdown", this);
for (let msgname of NFC_IPC_MSG_NAMES) {
ppmm.removeMessageListener(msgname, this);
}
ppmm = null;
},
_registerMessageTarget: function _registerMessageTarget(sessionToken, target) {
let targets = this.targetsBySessionTokens[sessionToken];
if (!targets) {
targets = this.targetsBySessionTokens[sessionToken] = [];
let list = this.sessionTokens;
if (list.indexOf(sessionToken) == -1) {
list.push(sessionToken);
}
}
if (targets.indexOf(target) != -1) {
debug("Already registered this target!");
return;
}
targets.push(target);
debug("Registered :" + sessionToken + " target: " + target);
},
_unregisterMessageTarget: function _unregisterMessageTarget(sessionToken, target) {
if (sessionToken == null) {
// Unregister the target for every sessionToken when no sessionToken is specified.
for (let session of this.sessionTokens) {
this._unregisterMessageTarget(session, target);
}
return;
}
// Unregister the target for a specified sessionToken.
let targets = this.targetsBySessionTokens[sessionToken];
if (!targets) {
return;
}
if (target == null) {
debug("Unregistered all targets for the " + sessionToken + " targets: " + targets);
targets = [];
let list = this.sessionTokens;
if (sessionToken !== null) {
let index = list.indexOf(sessionToken);
if (index > -1) {
list.splice(index, 1);
}
}
return;
}
let index = targets.indexOf(target);
if (index != -1) {
targets.splice(index, 1);
}
},
_sendTargetMessage: function _sendTargetMessage(sessionToken, message, options) {
let targets = this.targetsBySessionTokens[sessionToken];
if (!targets) {
return;
}
for (let target of targets) {
target.sendAsyncMessage(message, options);
}
},
/**
* nsIMessageListener interface methods.
*/
receiveMessage: function receiveMessage(msg) {
debug("Received '" + msg.name + "' message from content process");
if (msg.name == "child-process-shutdown") {
// By the time we receive child-process-shutdown, the child process has
// already forgotten its permissions so we need to unregister the target
// for every permission.
this._unregisterMessageTarget(null, msg.target);
return null;
}
if (NFC_IPC_MSG_NAMES.indexOf(msg.name) != -1) {
if (!msg.target.assertPermission("nfc-read")) {
debug("Nfc message " + msg.name +
" from a content process with no 'nfc-read' privileges.");
return null;
}
} else {
debug("Ignoring unknown message type: " + msg.name);
return null;
}
switch (msg.name) {
case "NFC:SetSessionToken":
this._registerMessageTarget(this.nfc.sessionTokenMap[this.nfc._currentSessionId], msg.target);
debug("Registering target for this SessionToken : " +
this.nfc.sessionTokenMap[this.nfc._currentSessionId]);
return null;
}
return null;
},
/**
* nsIObserver interface methods.
*/
observe: function observe(subject, topic, data) {
switch (topic) {
case "xpcom-shutdown":
this._shutdown();
break;
}
},
sendNfcResponseMessage: function sendNfcResponseMessage(message, data) {
this._sendTargetMessage(this.nfc.sessionTokenMap[this.nfc._currentSessionId], message, data);
},
};
});
function Nfc() {
debug("Starting Worker");
this.worker = new ChromeWorker("resource://gre/modules/nfc_worker.js");
this.worker.onerror = this.onerror.bind(this);
this.worker.onmessage = this.onmessage.bind(this);
for each (let msgname in NFC_IPC_MSG_NAMES) {
ppmm.addMessageListener(msgname, this);
}
Services.obs.addObserver(this, NFC.TOPIC_MOZSETTINGS_CHANGED, false);
Services.obs.addObserver(this, NFC.TOPIC_XPCOM_SHUTDOWN, false);
gMessageManager.init(this);
let lock = gSettingsService.createLock();
lock.get(NFC.SETTING_NFC_POWER_LEVEL, this);
lock.get(NFC.SETTING_NFC_ENABLED, this);
// Maps sessionId (that are generated from nfcd) with a unique guid : 'SessionToken'
this.sessionTokenMap = {};
gSystemWorkerManager.registerNfcWorker(this.worker);
}
Nfc.prototype = {
classID: NFC_CID,
classInfo: XPCOMUtils.generateCI({classID: NFC_CID,
classDescription: "Nfc",
interfaces: [Ci.nsIWorkerHolder]}),
QueryInterface: XPCOMUtils.generateQI([Ci.nsIWorkerHolder,
Ci.nsIObserver,
Ci.nsISettingsServiceCallback]),
_currentSessionId: null,
_enabled: false,
onerror: function onerror(event) {
debug("Got an error: " + event.filename + ":" +
event.lineno + ": " + event.message + "\n");
event.preventDefault();
},
/**
* Send arbitrary message to worker.
*
* @param nfcMessageType
* A text message type.
* @param message [optional]
* An optional message object to send.
*/
sendToWorker: function sendToWorker(nfcMessageType, message) {
message = message || {};
message.type = nfcMessageType;
this.worker.postMessage(message);
},
/**
* Send Error response to content.
*
* @param message
* An nsIMessageListener's message parameter.
*/
sendNfcErrorResponse: function sendNfcErrorResponse(message) {
if (!message.target) {
return;
}
let nfcMsgType = message.name + "Response";
message.target.sendAsyncMessage(nfcMsgType, {
sessionId: message.json.sessionToken,
requestId: message.json.requestId,
status: NFC.GECKO_NFC_ERROR_GENERIC_FAILURE
});
},
/**
* Process the incoming message from the NFC worker
*/
onmessage: function onmessage(event) {
let message = event.data;
debug("Received message from NFC worker: " + JSON.stringify(message));
switch (message.type) {
case "techDiscovered":
this._currentSessionId = message.sessionId;
// Check if the session token already exists. If exists, continue to use the same one.
// If not, generate a new token.
if (!this.sessionTokenMap[this._currentSessionId]) {
this.sessionTokenMap[this._currentSessionId] = UUIDGenerator.generateUUID().toString();
}
// Update the upper layers with a session token (alias)
message.sessionToken = this.sessionTokenMap[this._currentSessionId];
// Do not expose the actual session to the content
delete message.sessionId;
gSystemMessenger.broadcastMessage("nfc-manager-tech-discovered", message);
break;
case "techLost":
gMessageManager._unregisterMessageTarget(this.sessionTokenMap[this._currentSessionId], null);
// Update the upper layers with a session token (alias)
message.sessionToken = this.sessionTokenMap[this._currentSessionId];
// Do not expose the actual session to the content
delete message.sessionId;
gSystemMessenger.broadcastMessage("nfc-manager-tech-lost", message);
delete this.sessionTokenMap[this._currentSessionId];
this._currentSessionId = null;
break;
case "ConfigResponse":
gSystemMessenger.broadcastMessage("nfc-powerlevel-change", message);
break;
case "ConnectResponse": // Fall through.
case "CloseResponse":
case "GetDetailsNDEFResponse":
case "ReadNDEFResponse":
case "MakeReadOnlyNDEFResponse":
case "WriteNDEFResponse":
message.sessionToken = this.sessionTokenMap[this._currentSessionId];
// Do not expose the actual session to the content
delete message.sessionId;
gMessageManager.sendNfcResponseMessage("NFC:" + message.type, message);
break;
default:
throw new Error("Don't know about this message type: " + message.type);
}
},
// nsINfcWorker
worker: null,
powerLevel: NFC.NFC_POWER_LEVEL_DISABLED,
sessionTokenMap: null,
/**
* Process a message from the content process.
*/
receiveMessage: function receiveMessage(message) {
debug("Received '" + JSON.stringify(message) + "' message from content process");
if (!this._enabled) {
debug("NFC is not enabled.");
this.sendNfcErrorResponse(message);
return null;
}
// Enforce bare minimums for NFC permissions
switch (message.name) {
case "NFC:Connect": // Fall through
case "NFC:Close":
case "NFC:GetDetailsNDEF":
case "NFC:ReadNDEF":
if (!message.target.assertPermission("nfc-read")) {
debug("NFC message " + message.name +
" from a content process with no 'nfc-read' privileges.");
this.sendNfcErrorResponse(message);
return null;
}
break;
case "NFC:WriteNDEF": // Fall through
case "NFC:MakeReadOnlyNDEF":
if (!message.target.assertPermission("nfc-write")) {
debug("NFC message " + message.name +
" from a content process with no 'nfc-write' privileges.");
this.sendNfcErrorResponse(message);
return null;
}
break;
case "NFC:SetSessionToken":
//Do nothing here. No need to process this message further
return null;
}
// Sanity check on sessionId
if (message.json.sessionToken !== this.sessionTokenMap[this._currentSessionId]) {
debug("Invalid Session Token: " + message.json.sessionToken +
" Expected Session Token: " + this.sessionTokenMap[this._currentSessionId]);
this.sendNfcErrorResponse(message);
return null;
}
// Update the current sessionId before sending to the worker
message.sessionId = this._currentSessionId;
switch (message.name) {
case "NFC:GetDetailsNDEF":
this.sendToWorker("getDetailsNDEF", message.json);
break;
case "NFC:ReadNDEF":
this.sendToWorker("readNDEF", message.json);
break;
case "NFC:WriteNDEF":
this.sendToWorker("writeNDEF", message.json);
break;
case "NFC:MakeReadOnlyNDEF":
this.sendToWorker("makeReadOnlyNDEF", message.json);
break;
case "NFC:Connect":
this.sendToWorker("connect", message.json);
break;
case "NFC:Close":
this.sendToWorker("close", message.json);
break;
default:
debug("UnSupported : Message Name " + message.name);
return null;
}
},
/**
* nsISettingsServiceCallback
*/
handle: function handle(aName, aResult) {
switch(aName) {
case NFC.SETTING_NFC_ENABLED:
debug("'nfc.enabled' is now " + aResult);
this._enabled = aResult;
// General power setting
let powerLevel = this._enabled ? NFC.NFC_POWER_LEVEL_ENABLED :
NFC.NFC_POWER_LEVEL_DISABLED;
// Only if the value changes, set the power config and persist
if (powerLevel !== this.powerLevel) {
debug("New Power Level " + powerLevel);
this.setConfig({powerLevel: powerLevel});
this.powerLevel = powerLevel;
}
break;
}
},
/**
* nsIObserver
*/
observe: function observe(subject, topic, data) {
switch (topic) {
case NFC.TOPIC_XPCOM_SHUTDOWN:
for each (let msgname in NFC_IPC_MSG_NAMES) {
ppmm.removeMessageListener(msgname, this);
}
ppmm = null;
Services.obs.removeObserver(this, NFC.TOPIC_XPCOM_SHUTDOWN);
break;
case NFC.TOPIC_MOZSETTINGS_CHANGED:
let setting = JSON.parse(data);
if (setting) {
let setting = JSON.parse(data);
this.handle(setting.key, setting.value);
}
break;
}
},
setConfig: function setConfig(prop) {
this.sendToWorker("config", prop);
}
};
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([Nfc]);

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

@ -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/.
#
# Copyright © 2013 Deutsche Telekom, Inc.
# Nfc.js
component {2ff24790-5e74-11e1-b86c-0800200c9a66} Nfc.js
contract @mozilla.org/nfc;1 {2ff24790-5e74-11e1-b86c-0800200c9a66}
category profile-after-change Nfc @mozilla.org/nfc;1
# NfcContentHelper.js
component {4d72c120-da5f-11e1-9b23-0800200c9a66} NfcContentHelper.js
contract @mozilla.org/nfc/content-helper;1 {4d72c120-da5f-11e1-9b23-0800200c9a66}
category profile-after-change NfcContentHelper @mozilla.org/nfc/content-helper;1

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

@ -0,0 +1,314 @@
/* Copyright 2012 Mozilla Foundation and Mozilla contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* Copyright © 2013, Deutsche Telekom, Inc. */
"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");
Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
let NFC = {};
Cu.import("resource://gre/modules/nfc_consts.js", NFC);
// set to true to in nfc_consts.js to see debug messages
let DEBUG = NFC.DEBUG_CONTENT_HELPER;
let debug;
if (DEBUG) {
debug = function (s) {
dump("-*- NfcContentHelper: " + s + "\n");
};
} else {
debug = function (s) {};
}
const NFCCONTENTHELPER_CID =
Components.ID("{4d72c120-da5f-11e1-9b23-0800200c9a66}");
const NFC_IPC_MSG_NAMES = [
"NFC:ReadNDEFResponse",
"NFC:WriteNDEFResponse",
"NFC:GetDetailsNDEFResponse",
"NFC:MakeReadOnlyNDEFResponse",
"NFC:ConnectResponse",
"NFC:CloseResponse"
];
XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
"@mozilla.org/childprocessmessagemanager;1",
"nsISyncMessageSender");
function NfcContentHelper() {
this.initDOMRequestHelper(/* aWindow */ null, NFC_IPC_MSG_NAMES);
Services.obs.addObserver(this, "xpcom-shutdown", false);
this._requestMap = [];
}
NfcContentHelper.prototype = {
__proto__: DOMRequestIpcHelper.prototype,
QueryInterface: XPCOMUtils.generateQI([Ci.nsINfcContentHelper,
Ci.nsISupportsWeakReference,
Ci.nsIObserver]),
classID: NFCCONTENTHELPER_CID,
classInfo: XPCOMUtils.generateCI({
classID: NFCCONTENTHELPER_CID,
classDescription: "NfcContentHelper",
interfaces: [Ci.nsINfcContentHelper]
}),
_requestMap: null,
/* TODO: Bug 815526: This is a limitation when a DOMString is used in sequences of Moz DOM Objects.
* Strings such as 'type', 'id' 'payload' will not be acccessible to NfcWorker.
* Therefore this function exists till the bug is addressed.
*/
encodeNdefRecords: function encodeNdefRecords(records) {
let encodedRecords = [];
for (let i = 0; i < records.length; i++) {
let record = records[i];
encodedRecords.push({
tnf: record.tnf,
type: record.type,
id: record.id,
payload: record.payload,
});
}
return encodedRecords;
},
// NFC interface:
setSessionToken: function setSessionToken(sessionToken) {
if (sessionToken == null) {
throw Components.Exception("No session token!",
Cr.NS_ERROR_UNEXPECTED);
return;
}
// Report session to Nfc.js only.
cpmm.sendAsyncMessage("NFC:SetSessionToken", {
sessionToken: sessionToken,
});
},
// NFCTag interface
getDetailsNDEF: function getDetailsNDEF(window, sessionToken) {
if (window == null) {
throw Components.Exception("Can't get window object",
Cr.NS_ERROR_UNEXPECTED);
}
let request = Services.DOMRequest.createRequest(window);
let requestId = btoa(this.getRequestId(request));
this._requestMap[requestId] = window;
cpmm.sendAsyncMessage("NFC:GetDetailsNDEF", {
requestId: requestId,
sessionToken: sessionToken
});
return request;
},
readNDEF: function readNDEF(window, sessionToken) {
if (window == null) {
throw Components.Exception("Can't get window object",
Cr.NS_ERROR_UNEXPECTED);
}
let request = Services.DOMRequest.createRequest(window);
let requestId = btoa(this.getRequestId(request));
this._requestMap[requestId] = window;
cpmm.sendAsyncMessage("NFC:ReadNDEF", {
requestId: requestId,
sessionToken: sessionToken
});
return request;
},
writeNDEF: function writeNDEF(window, records, sessionToken) {
if (window == null) {
throw Components.Exception("Can't get window object",
Cr.NS_ERROR_UNEXPECTED);
}
let request = Services.DOMRequest.createRequest(window);
let requestId = btoa(this.getRequestId(request));
this._requestMap[requestId] = window;
let encodedRecords = this.encodeNdefRecords(records);
cpmm.sendAsyncMessage("NFC:WriteNDEF", {
requestId: requestId,
sessionToken: sessionToken,
records: encodedRecords
});
return request;
},
makeReadOnlyNDEF: function makeReadOnlyNDEF(window, sessionToken) {
if (window == null) {
throw Components.Exception("Can't get window object",
Cr.NS_ERROR_UNEXPECTED);
}
let request = Services.DOMRequest.createRequest(window);
let requestId = btoa(this.getRequestId(request));
this._requestMap[requestId] = window;
cpmm.sendAsyncMessage("NFC:MakeReadOnlyNDEF", {
requestId: requestId,
sessionToken: sessionToken
});
return request;
},
connect: function connect(window, techType, sessionToken) {
if (window == null) {
throw Components.Exception("Can't get window object",
Cr.NS_ERROR_UNEXPECTED);
}
let request = Services.DOMRequest.createRequest(window);
let requestId = btoa(this.getRequestId(request));
this._requestMap[requestId] = window;
cpmm.sendAsyncMessage("NFC:Connect", {
requestId: requestId,
sessionToken: sessionToken,
techType: techType
});
return request;
},
close: function close(window, sessionToken) {
if (window == null) {
throw Components.Exception("Can't get window object",
Cr.NS_ERROR_UNEXPECTED);
}
let request = Services.DOMRequest.createRequest(window);
let requestId = btoa(this.getRequestId(request));
this._requestMap[requestId] = window;
cpmm.sendAsyncMessage("NFC:Close", {
requestId: requestId,
sessionToken: sessionToken
});
return request;
},
// nsIObserver
observe: function observe(subject, topic, data) {
if (topic == "xpcom-shutdown") {
this.removeMessageListener();
Services.obs.removeObserver(this, "xpcom-shutdown");
cpmm = null;
}
},
// nsIMessageListener
fireRequestSuccess: function fireRequestSuccess(requestId, result) {
let request = this.takeRequest(requestId);
if (!request) {
debug("not firing success for id: " + requestId +
", result: " + JSON.stringify(result));
return;
}
debug("fire request success, id: " + requestId +
", result: " + JSON.stringify(result));
Services.DOMRequest.fireSuccess(request, result);
},
fireRequestError: function fireRequestError(requestId, error) {
let request = this.takeRequest(requestId);
if (!request) {
debug("not firing error for id: " + requestId +
", error: " + JSON.stringify(error));
return;
}
debug("fire request error, id: " + requestId +
", result: " + JSON.stringify(error));
Services.DOMRequest.fireError(request, error);
},
receiveMessage: function receiveMessage(message) {
debug("Message received: " + JSON.stringify(message));
switch (message.name) {
case "NFC:ReadNDEFResponse":
this.handleReadNDEFResponse(message.json);
break;
case "NFC:ConnectResponse": // Fall through.
case "NFC:CloseResponse":
case "NFC:WriteNDEFResponse":
case "NFC:MakeReadOnlyNDEFResponse":
case "NFC:GetDetailsNDEFResponse":
this.handleResponse(message.json);
break;
}
},
handleReadNDEFResponse: function handleReadNDEFResponse(message) {
debug("ReadNDEFResponse(" + JSON.stringify(message) + ")");
let requester = this._requestMap[message.requestId];
if (!requester) {
debug("ReadNDEFResponse Invalid requester=" + requester +
" message.sessionToken=" + message.sessionToken);
return; // Nothing to do in this instance.
}
delete this._requestMap[message.requestId];
let records = message.records;
let requestId = atob(message.requestId);
if (message.status !== NFC.GECKO_NFC_ERROR_SUCCESS) {
this.fireRequestError(requestId, message.status);
} else {
let ndefMsg = [];
for (let i = 0; i < records.length; i++) {
let record = records[i];
ndefMsg.push(new requester.MozNdefRecord(record.tnf,
record.type,
record.id,
record.payload));
}
this.fireRequestSuccess(requestId, ndefMsg);
}
},
handleResponse: function handleResponse(message) {
debug("Response(" + JSON.stringify(message) + ")");
let requester = this._requestMap[message.requestId];
if (!requester) {
debug("Response Invalid requester=" + requester +
" message.sessionToken=" + message.sessionToken);
return; // Nothing to do in this instance.
}
delete this._requestMap[message.requestId];
let result = message;
let requestId = atob(message.requestId);
if (message.status !== NFC.GECKO_NFC_ERROR_SUCCESS) {
this.fireRequestError(requestId, result.status);
} else {
this.fireRequestSuccess(requestId, result);
}
},
};
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([NfcContentHelper]);

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

@ -85,6 +85,20 @@ if CONFIG['MOZ_B2G_RIL']:
'ril_worker.js',
]
if CONFIG['MOZ_NFC']:
XPIDL_SOURCES += [
'nsINfcContentHelper.idl',
]
EXTRA_COMPONENTS += [
'Nfc.js',
'Nfc.manifest',
'NfcContentHelper.js',
]
EXTRA_JS_MODULES += [
'nfc_consts.js',
'nfc_worker.js',
]
FAIL_ON_WARNINGS = True
LIBXUL_LIBRARY = True
@ -97,6 +111,7 @@ LOCAL_INCLUDES += [
'/content/events/src',
'/dom/base',
'/dom/bluetooth',
'/dom/nfc',
'/dom/src/geolocation',
'/dom/wifi',
]

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

@ -555,16 +555,8 @@ function enableNat(params, callback) {
}
function disableNat(params, callback) {
let command;
// Don't disable nat because others interface still need it.
// Send the dummy command to continue the function chain.
if ("interfaceList" in params && params.interfaceList.length > 1) {
command = DUMMY_COMMAND;
} else {
command = "nat disable " + params.internalIfname + " " +
params.externalIfname + " " + "0";
}
let command = "nat disable " + params.internalIfname + " " +
params.externalIfname + " " + "0";
return doCommand(command, callback);
}

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

@ -0,0 +1,71 @@
/* Copyright 2012 Mozilla Foundation and Mozilla contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* Copyright © 2013, Deutsche Telekom, Inc. */
// Set to true to debug all NFC layers
this.DEBUG_ALL = false;
// Set individually to debug specific layers
this.DEBUG_WORKER = false || DEBUG_ALL;
this.DEBUG_CONTENT_HELPER = false || DEBUG_ALL;
this.DEBUG_NFC = false || DEBUG_ALL;
// Current version
this.NFC_MAJOR_VERSION = 1;
this.NFC_MINOR_VERSION = 7;
this.NFC_REQUEST_CONFIG = 0;
this.NFC_REQUEST_CONNECT = 1;
this.NFC_REQUEST_CLOSE = 2;
this.NFC_REQUEST_GET_DETAILS = 3;
this.NFC_REQUEST_READ_NDEF = 4;
this.NFC_REQUEST_WRITE_NDEF = 5;
this.NFC_REQUEST_MAKE_NDEF_READ_ONLY = 6;
this.NFC_RESPONSE_GENERAL = 1000;
this.NFC_RESPONSE_CONFIG = 1001;
this.NFC_RESPONSE_READ_NDEF_DETAILS = 1002;
this.NFC_RESPONSE_READ_NDEF = 1003;
this.NFC_NOTIFICATION_INITIALIZED = 2000;
this.NFC_NOTIFICATION_TECH_DISCOVERED = 2001;
this.NFC_NOTIFICATION_TECH_LOST = 2002;
this.NFC_TECHS = {
0:'NDEF',
1:'NDEF_WRITEABLE',
2:'NDEF_FORMATABLE',
3:'P2P',
4:'NFC_A'
};
// TODO: Bug 933595. Fill-in all error codes for Gonk/nfcd protocol
this.GECKO_NFC_ERROR_SUCCESS = 0;
this.GECKO_NFC_ERROR_GENERIC_FAILURE = 1;
// NFC powerlevels must match config PDUs.
this.NFC_POWER_LEVEL_UNKNOWN = -1;
this.NFC_POWER_LEVEL_DISABLED = 0;
this.NFC_POWER_LEVEL_LOW = 1;
this.NFC_POWER_LEVEL_ENABLED = 2;
this.TOPIC_MOZSETTINGS_CHANGED = "mozsettings-changed";
this.TOPIC_XPCOM_SHUTDOWN = "xpcom-shutdown";
this.SETTING_NFC_ENABLED = "nfc.enabled";
this.SETTING_NFC_POWER_LEVEL = "nfc.powerlevel";
// Allow this file to be imported via Components.utils.import().
this.EXPORTED_SYMBOLS = Object.keys(this);

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

@ -0,0 +1,440 @@
/* Copyright 2012 Mozilla Foundation and Mozilla contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* Copyright © 2013, Deutsche Telekom, Inc. */
"use strict";
importScripts("systemlibs.js", "nfc_consts.js");
importScripts("resource://gre/modules/workers/require.js");
// set to true in nfc_consts.js to see debug messages
let DEBUG = DEBUG_WORKER;
function getPaddingLen(len) {
return (len % 4) ? (4 - len % 4) : 0;
}
let Buf = {
__proto__: (function(){
return require("resource://gre/modules/workers/worker_buf.js").Buf;
})(),
init: function init() {
this._init();
},
/**
* Process one parcel.
*/
processParcel: function processParcel() {
let pduType = this.readInt32();
if (DEBUG) debug("Number of bytes available in Parcel : " + this.readAvailable);
NfcWorker.handleParcel(pduType, this.mCallback);
},
/**
* Start a new outgoing parcel.
*
* @param type
* Integer specifying the request type.
* @param callback
*/
newParcel: function newParcel(type, callback) {
if (DEBUG) debug("New outgoing parcel of type " + type);
this.mCallback = callback;
// We're going to leave room for the parcel size at the beginning.
this.outgoingIndex = this.PARCEL_SIZE_SIZE;
this.writeInt32(type);
},
simpleRequest: function simpleRequest(type) {
this.newParcel(type);
this.sendParcel();
},
onSendParcel: function onSendParcel(parcel) {
postNfcMessage(parcel);
},
/**
* TODO: Bug 933593. Callback map of NFC_RESPONSE_XXX and RequestID
* needs to be maintained
*/
mCallback: null,
};
/**
* Provide a high-level API representing NFC capabilities.
* Rensponsible for converting NFC requests from Content process to binary data
* and NFC Responses from binary data to dictionary objects.
*/
let NfcWorker = {
/**
* Handle incoming messages from the main UI thread.
*
* @param message
* Object containing the message. Messages are supposed
*/
handleDOMMessage: function handleMessage(message) {
if (DEBUG) debug("Received DOM message " + JSON.stringify(message));
let method = this[message.type];
if (typeof method != "function") {
if (DEBUG) {
debug("Don't know what to do with message " + JSON.stringify(message));
}
return;
}
method.call(this, message);
},
/**
* Unmarshals a NDEF message
*/
unMarshallNdefMessage: function unMarshallNdefMessage() {
let numOfRecords = Buf.readInt32();
debug("numOfRecords = " + numOfRecords);
if (numOfRecords <= 0) {
return null;
}
let records = [];
for (let i = 0; i < numOfRecords; i++) {
let tnf = Buf.readInt32();
let typeLength = Buf.readInt32();
let type = [];
for (let i = 0; i < typeLength; i++) {
type.push(Buf.readUint8());
}
let padding = getPaddingLen(typeLength);
for (let i = 0; i < padding; i++) {
Buf.readUint8();
}
let idLength = Buf.readInt32();
let id = [];
for (let i = 0; i < idLength; i++) {
id.push(Buf.readUint8());
}
padding = getPaddingLen(idLength);
for (let i = 0; i < padding; i++) {
Buf.readUint8();
}
let payloadLength = Buf.readInt32();
let payload = [];
for (let i = 0; i < payloadLength; i++) {
payload.push(Buf.readUint8());
}
padding = getPaddingLen(payloadLength);
for (let i = 0; i < padding; i++) {
Buf.readUint8();
}
records.push({tnf: tnf,
type: type,
id: id,
payload: payload});
}
return records;
},
/**
* Read and return NDEF data, if present.
*/
readNDEF: function readNDEF(message) {
let cb = function callback() {
let error = Buf.readInt32();
let sessionId = Buf.readInt32();
let records = this.unMarshallNdefMessage();
message.type = "ReadNDEFResponse";
message.sessionId = sessionId;
message.records = records;
message.status = (error === 0) ? GECKO_NFC_ERROR_SUCCESS :
GECKO_NFC_ERROR_GENERIC_FAILURE;
this.sendDOMMessage(message);
}
Buf.newParcel(NFC_REQUEST_READ_NDEF, cb);
Buf.writeInt32(message.sessionId);
Buf.sendParcel();
},
/**
* Write to a target that accepts NDEF formattable data
*/
writeNDEF: function writeNDEF(message) {
let cb = function callback() {
let error = Buf.readInt32();
let sessionId = Buf.readInt32();
message.type = "WriteNDEFResponse";
message.sessionId = sessionId;
message.status = (error === 0) ? GECKO_NFC_ERROR_SUCCESS :
GECKO_NFC_ERROR_GENERIC_FAILURE;
this.sendDOMMessage(message);
};
Buf.newParcel(NFC_REQUEST_WRITE_NDEF, cb);
Buf.writeInt32(message.sessionId);
let records = message.records;
let numRecords = records.length;
Buf.writeInt32(numRecords);
for (let i = 0; i < numRecords; i++) {
let record = records[i];
Buf.writeInt32(record.tnf);
let typeLength = record.type.length;
Buf.writeInt32(typeLength);
for (let j = 0; j < typeLength; j++) {
Buf.writeUint8(record.type.charCodeAt(j));
}
let padding = getPaddingLen(typeLength);
for (let i = 0; i < padding; i++) {
Buf.writeUint8(0x00);
}
let idLength = record.id.length;
Buf.writeInt32(idLength);
for (let j = 0; j < idLength; j++) {
Buf.writeUint8(record.id.charCodeAt(j));
}
padding = getPaddingLen(idLength);
for (let i = 0; i < padding; i++) {
Buf.writeUint8(0x00);
}
let payloadLength = record.payload && record.payload.length;
Buf.writeInt32(payloadLength);
for (let j = 0; j < payloadLength; j++) {
Buf.writeUint8(record.payload.charCodeAt(j));
}
padding = getPaddingLen(payloadLength);
for (let i = 0; i < padding; i++) {
Buf.writeUint8(0x00);
}
}
Buf.sendParcel();
},
/**
* Make the NFC NDEF tag permanently read only
*/
makeReadOnlyNDEF: function makeReadOnlyNDEF(message) {
let cb = function callback() {
let error = Buf.readInt32();
let sessionId = Buf.readInt32();
message.type = "MakeReadOnlyNDEFResponse";
message.sessionId = sessionId;
message.status = (error === 0) ? GECKO_NFC_ERROR_SUCCESS :
GECKO_NFC_ERROR_GENERIC_FAILURE;
this.sendDOMMessage(message);
};
Buf.newParcel(NFC_REQUEST_MAKE_NDEF_READ_ONLY, cb);
Buf.writeInt32(message.sessionId);
Buf.sendParcel();
},
/**
* Retrieve metadata describing the NDEF formatted data, if present.
*/
getDetailsNDEF: function getDetailsNDEF(message) {
let cb = function callback() {
let error = Buf.readInt32();
let sessionId = Buf.readInt32();
let isReadOnly = Buf.readUint8();
let canBeMadeReadOnly = Buf.readUint8();
// Ensure that padding is taken care here after reading two successive uint8's
Buf.readUint8();
Buf.readUint8();
let maxSupportedLength = Buf.readInt32();
message.type = "GetDetailsNDEFResponse";
message.sessionId = sessionId;
message.isReadOnly = isReadOnly;
message.canBeMadeReadOnly = canBeMadeReadOnly;
message.maxSupportedLength = maxSupportedLength;
message.status = (error === 0) ? GECKO_NFC_ERROR_SUCCESS :
GECKO_NFC_ERROR_GENERIC_FAILURE;
this.sendDOMMessage(message);
};
Buf.newParcel(NFC_REQUEST_GET_DETAILS, cb);
Buf.writeInt32(message.sessionId);
Buf.sendParcel();
},
/**
* Open a connection to the NFC target.
*/
connect: function connect(message) {
let cb = function callback() {
let error = Buf.readInt32();
let sessionId = Buf.readInt32();
message.type = "ConnectResponse";
message.sessionId = sessionId;
message.status = (error === 0) ? GECKO_NFC_ERROR_SUCCESS :
GECKO_NFC_ERROR_GENERIC_FAILURE;
this.sendDOMMessage(message);
};
Buf.newParcel(NFC_REQUEST_CONNECT, cb);
Buf.writeInt32(message.sessionId);
Buf.writeInt32(message.techType);
Buf.sendParcel();
},
/**
* NFC Configuration
*/
config: function config(message) {
let cb = function callback() {
let error = Buf.readInt32();
message.type = "ConfigResponse";
message.status = (error === 0) ? GECKO_NFC_ERROR_SUCCESS :
GECKO_NFC_ERROR_GENERIC_FAILURE;
this.sendDOMMessage(message);
};
Buf.newParcel(NFC_REQUEST_CONFIG , cb);
Buf.writeInt32(message.powerLevel);
Buf.sendParcel();
},
/**
* Close connection to the NFC target.
*/
close: function close(message) {
let cb = function callback() {
let error = Buf.readInt32();
let sessionId = Buf.readInt32();
message.type = "CloseResponse";
message.sessionId = sessionId;
message.status = (error === 0) ? GECKO_NFC_ERROR_SUCCESS :
GECKO_NFC_ERROR_GENERIC_FAILURE;
this.sendDOMMessage(message);
};
Buf.newParcel(NFC_REQUEST_CLOSE , cb);
Buf.writeInt32(message.sessionId);
Buf.sendParcel();
},
handleParcel: function handleParcel(request_type, callback) {
let method = this[request_type];
if (typeof method == "function") {
if (DEBUG) debug("Handling parcel as " + method.name);
method.call(this);
} else if (typeof callback == "function") {
callback.call(this, request_type);
this.mCallback = null;
} else {
debug("Unable to handle ReqType:"+request_type);
}
},
/**
* Send messages to the main UI thread.
*/
sendDOMMessage: function sendDOMMessage(message) {
postMessage(message);
}
};
/**
* Notification Handlers
*/
NfcWorker[NFC_NOTIFICATION_INITIALIZED] = function NFC_NOTIFICATION_INITIALIZED () {
let status = Buf.readInt32();
let majorVersion = Buf.readInt32();
let minorVersion = Buf.readInt32();
debug("NFC_NOTIFICATION_INITIALIZED status:" + status);
if ((majorVersion != NFC_MAJOR_VERSION) || (minorVersion != NFC_MINOR_VERSION)) {
debug("Version Mismatch! Current Supported Version : " +
NFC_MAJOR_VERSION + "." + NFC_MINOR_VERSION +
" Received Version : " + majorVersion + "." + minorVersion);
}
};
NfcWorker[NFC_NOTIFICATION_TECH_DISCOVERED] = function NFC_NOTIFICATION_TECH_DISCOVERED() {
debug("NFC_NOTIFICATION_TECH_DISCOVERED");
let techs = [];
let ndefMsgs = [];
let sessionId = Buf.readInt32();
let techCount = Buf.readInt32();
for (let count = 0; count < techCount; count++) {
techs.push(NFC_TECHS[Buf.readUint8()]);
}
let padding = getPaddingLen(techCount);
for (let i = 0; i < padding; i++) {
Buf.readUint8();
}
let ndefMsgCount = Buf.readInt32();
for (let count = 0; count < ndefMsgCount; count++) {
ndefMsgs.push(this.unMarshallNdefMessage());
}
this.sendDOMMessage({type: "techDiscovered",
sessionId: sessionId,
tech: techs,
ndef: ndefMsgs
});
};
NfcWorker[NFC_NOTIFICATION_TECH_LOST] = function NFC_NOTIFICATION_TECH_LOST() {
debug("NFC_NOTIFICATION_TECH_LOST");
let sessionId = Buf.readInt32();
debug("sessionId = " + sessionId);
this.sendDOMMessage({type: "techLost",
sessionId: sessionId,
});
};
/**
* Global stuff.
*/
if (!this.debug) {
// Debugging stub that goes nowhere.
this.debug = function debug(message) {
dump("Nfc Worker: " + message + "\n");
};
}
// Initialize buffers. This is a separate function so that unit tests can
// re-initialize the buffers at will.
Buf.init();
function onNfcMessage(data) {
Buf.processIncoming(data);
};
onmessage = function onmessage(event) {
NfcWorker.handleDOMMessage(event.data);
};
onerror = function onerror(event) {
debug("OnError: event: " + JSON.stringify(event));
debug("NFC Worker error " + event.message + " " + event.filename + ":" +
event.lineno + ":\n");
};

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

@ -0,0 +1,22 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsISupports.idl"
#include "nsIDOMDOMRequest.idl"
interface nsIVariant;
[scriptable, uuid(28c8f240-da8c-11e1-9b23-0800200c9a66)]
interface nsINfcContentHelper : nsISupports
{
void setSessionToken(in DOMString sessionToken);
nsIDOMDOMRequest getDetailsNDEF(in nsIDOMWindow window, in DOMString sessionToken);
nsIDOMDOMRequest readNDEF(in nsIDOMWindow window, in DOMString sessionToken);
nsIDOMDOMRequest writeNDEF(in nsIDOMWindow window, in nsIVariant records, in DOMString sessionToken);
nsIDOMDOMRequest makeReadOnlyNDEF(in nsIDOMWindow window, in DOMString sessionToken);
nsIDOMDOMRequest connect(in nsIDOMWindow window, in unsigned long techType, in DOMString sessionToken);
nsIDOMDOMRequest close(in nsIDOMWindow window, in DOMString sessionToken);
};

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

@ -81,7 +81,7 @@ let permissions = [
];
startTestWithPermissions(permissions, function() {
connection = navigator.mozMobileConnection;
connection = navigator.mozMobileConnections[0];
ok(connection instanceof MozMobileConnection,
"connection is instanceof " + connection.constructor);

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

@ -351,9 +351,14 @@ var interfaceNamesInGlobalScope =
"MozMmsEvent",
"MozMmsMessage",
{name: "MozMobileConnection", b2g: true, pref: "dom.mobileconnection.enabled"},
{name: "MozMobileConnectionArray", b2g: true, pref: "dom.mobileconnection.enabled"},
"MozMobileMessageManager",
"MozMobileMessageThread",
"MozNamedAttrMap",
{name: "MozNdefRecord", b2g: true},
{name: "MozNfc", b2g: true},
{name: "MozNFCPeer", b2g: true},
{name: "MozNFCTag", b2g: true},
{name: "MozOtaStatusEvent", b2g: true, pref: "dom.mobileconnection.enabled"},
"MozPowerManager",
"mozRTCIceCandidate",

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

@ -111,7 +111,7 @@ function testLevel2DiscardActive() {
// TODO: bug 905228 - MozVoicemailStatus is not defined.
//ok(status instanceof MozVoicemailStatus);
is(status.hasMessages, true);
is(status.messageCount, status.MESSAGE_COUNT_UNKNOWN);
is(status.messageCount, -1);
is(status.returnNumber, MWI_LEVEL2_SENDER);
is(status.returnMessage, MWI_DEFAULT_BODY);
isVoicemailStatus(status);

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

@ -0,0 +1,12 @@
/* -*- 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/.
*/
interface MozMobileConnection;
interface MozMobileConnectionArray {
getter MozMobileConnection? item(unsigned long index);
readonly attribute unsigned long length;
};

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

@ -0,0 +1,22 @@
/* 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/.
*
* Part of this IDL file is from:
* http://w3c.github.io/nfc/proposals/common/nfc.html#idl-def-NFCPeer
*
* Copyright © 2013 Deutsche Telekom, Inc.
*/
[JSImplementation="@mozilla.org/nfc/NFCPeer;1"]
interface MozNFCPeer {
DOMRequest sendNDEF(sequence<MozNdefRecord> records);
};
// Mozilla Only
partial interface MozNFCPeer {
[ChromeOnly]
attribute DOMString session;
[ChromeOnly]
void setSessionToken(DOMString sessionToken);
};

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

@ -0,0 +1,43 @@
/* 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/.
*
* Part of this idl is from:
* http://w3c.github.io/nfc/proposals/common/nfc.html#nfctag-interface
*
* Copyright © 2013 Deutsche Telekom, Inc.
*/
enum NFCTechType {
"NFC_A",
"NFC_B",
"NFC_ISO_DEP",
"NFC_F",
"NFC_V",
"NDEF",
"NDEF_FORMATABLE",
"MIFARE_CLASSIC",
"MIFARE_ULTRALIGHT",
"NFC_BARCODE",
"P2P",
"UNKNOWN_TECH"
};
[JSImplementation="@mozilla.org/nfc/NFCTag;1"]
interface MozNFCTag {
DOMRequest getDetailsNDEF();
DOMRequest readNDEF();
DOMRequest writeNDEF(sequence<MozNdefRecord> records);
DOMRequest makeReadOnlyNDEF();
DOMRequest connect(NFCTechType techType);
DOMRequest close();
};
// Mozilla Only
partial interface MozNFCTag {
[ChromeOnly]
attribute DOMString session;
[ChromeOnly]
void setSessionToken(DOMString sessionToken);
};

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

@ -0,0 +1,38 @@
/* -*- 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/. */
/* Copyright © 2013 Deutsche Telekom, Inc. */
[Constructor(octet tnf, DOMString type, DOMString id, DOMString payload)]
interface MozNdefRecord
{
/**
* Type Name Field (3-bits) - Specifies the NDEF record type in general.
* tnf_empty: 0x00
* tnf_well_known: 0x01
* tnf_mime_media: 0x02
* tnf_absolute_uri: 0x03
* tnf_external type: 0x04
* tnf_unknown: 0x05
* tnf_unchanged: 0x06
* tnf_reserved: 0x07
*/
readonly attribute octet tnf;
/**
* type - Describes the content of the payload. This can be a mime type.
*/
readonly attribute DOMString type;
/**
* id - Identifer is application dependent.
*/
readonly attribute DOMString id;
/**
* payload - Binary data blob. The meaning of this field is application dependent.
*/
readonly attribute DOMString payload;
};

16
dom/webidl/MozNfc.webidl Normal file
Просмотреть файл

@ -0,0 +1,16 @@
/* 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/. */
/* Copyright © 2013 Deutsche Telekom, Inc. */
[JSImplementation="@mozilla.org/navigatorNfc;1",
NavigatorProperty="mozNfc"]
interface MozNfc : EventTarget {
MozNFCTag getNFCTag(DOMString sessionId);
MozNFCPeer getNFCPeer(DOMString sessionId);
/*attribute EventHandler onpeerfound;
attribute EventHandler onpeerlost;
attribute EventHandler onforegrounddispatch;*/
};

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

@ -255,11 +255,9 @@ partial interface Navigator {
};
#ifdef MOZ_B2G_RIL
// nsIMozNavigatorMobileConnection
interface MozMobileConnection;
partial interface Navigator {
[Throws, Func="Navigator::HasMobileConnectionSupport"]
readonly attribute MozMobileConnection mozMobileConnection;
readonly attribute MozMobileConnectionArray mozMobileConnections;
};
partial interface Navigator {

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

@ -515,12 +515,21 @@ if CONFIG['MOZ_B2G_RIL']:
'MozCellBroadcast.webidl',
'MozCellBroadcastEvent.webidl',
'MozEmergencyCbModeEvent.webidl',
'MozMobileConnectionArray.webidl',
'MozOtaStatusEvent.webidl',
'MozVoicemail.webidl',
'MozVoicemailEvent.webidl',
'USSDReceivedEvent.webidl',
]
if CONFIG['MOZ_NFC']:
WEBIDL_FILES += [
'MozNdefRecord.webidl',
'MozNfc.webidl',
'MozNFCPeer.webidl',
'MozNFCTag.webidl',
]
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
WEBIDL_FILES += [
'MozWifiConnectionInfoEvent.webidl',

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

@ -852,8 +852,10 @@ void
DrawTargetCairo::SetPermitSubpixelAA(bool aPermitSubpixelAA)
{
DrawTarget::SetPermitSubpixelAA(aPermitSubpixelAA);
#ifdef MOZ_TREE_CAIRO
cairo_surface_set_subpixel_antialiasing(mSurface,
aPermitSubpixelAA ? CAIRO_SUBPIXEL_ANTIALIASING_ENABLED : CAIRO_SUBPIXEL_ANTIALIASING_DISABLED);
#endif
}
void

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

@ -59,7 +59,7 @@ struct IntRectTyped :
typedef BaseRect<int32_t, IntRectTyped<units>, IntPointTyped<units>, IntSizeTyped<units>, IntMarginTyped<units> > Super;
IntRectTyped() : Super() {}
IntRectTyped(IntPointTyped<units> aPos, IntSizeTyped<units> aSize) :
IntRectTyped(const IntPointTyped<units>& aPos, const IntSizeTyped<units>& aSize) :
Super(aPos, aSize) {}
IntRectTyped(int32_t _x, int32_t _y, int32_t _width, int32_t _height) :
Super(_x, _y, _width, _height) {}
@ -89,7 +89,7 @@ struct RectTyped :
typedef BaseRect<Float, RectTyped<units>, PointTyped<units>, SizeTyped<units>, MarginTyped<units> > Super;
RectTyped() : Super() {}
RectTyped(PointTyped<units> aPos, SizeTyped<units> aSize) :
RectTyped(const PointTyped<units>& aPos, const SizeTyped<units>& aSize) :
Super(aPos, aSize) {}
RectTyped(Float _x, Float _y, Float _width, Float _height) :
Super(_x, _y, _width, _height) {}

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

@ -6,6 +6,7 @@
#include "SanityChecks.h"
#include "TestPoint.h"
#include "TestScaling.h"
#include "TestBugs.h"
#ifdef WIN32
#include "TestDrawTargetD2D.h"
#endif
@ -32,6 +33,7 @@ main()
#endif
{ new TestPoint(), "Point Tests" },
{ new TestScaling(), "Scaling Tests" }
{ new TestBugs(), "Bug Tests" }
};
int totalFailures = 0;

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

@ -0,0 +1,68 @@
/* -*- 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 "TestBugs.h"
#include "2D.h"
using namespace mozilla;
using namespace mozilla::gfx;
TestBugs::TestBugs()
{
REGISTER_TEST(TestBugs, CairoClip918671);
}
void
TestBugs::CairoClip918671()
{
RefPtr<DrawTarget> dt = Factory::CreateDrawTarget(BACKEND_CAIRO,
IntSize(100, 100),
FORMAT_B8G8R8A8);
RefPtr<DrawTarget> ref = Factory::CreateDrawTarget(BACKEND_CAIRO,
IntSize(100, 100),
FORMAT_B8G8R8A8);
// Create a path that extends around the center rect but doesn't intersect it.
RefPtr<PathBuilder> pb1 = dt->CreatePathBuilder();
pb1->MoveTo(Point(10, 10));
pb1->LineTo(Point(90, 10));
pb1->LineTo(Point(90, 20));
pb1->LineTo(Point(10, 20));
pb1->Close();
pb1->MoveTo(Point(90, 90));
pb1->LineTo(Point(91, 90));
pb1->LineTo(Point(91, 91));
pb1->LineTo(Point(91, 90));
pb1->Close();
RefPtr<Path> path1 = pb1->Finish();
dt->PushClip(path1);
// This center rect must NOT be rectilinear!
RefPtr<PathBuilder> pb2 = dt->CreatePathBuilder();
pb2->MoveTo(Point(50, 50));
pb2->LineTo(Point(55, 51));
pb2->LineTo(Point(54, 55));
pb2->LineTo(Point(50, 56));
pb2->Close();
RefPtr<Path> path2 = pb2->Finish();
dt->PushClip(path2);
dt->FillRect(Rect(0, 0, 100, 100), ColorPattern(Color(1,0,0)));
RefPtr<SourceSurface> surf1 = dt->Snapshot();
RefPtr<SourceSurface> surf2 = ref->Snapshot();
RefPtr<DataSourceSurface> dataSurf1 = surf1->GetDataSurface();
RefPtr<DataSourceSurface> dataSurf2 = surf2->GetDataSurface();
for (int y = 0; y < dt->GetSize().height; y++) {
VERIFY(memcmp(dataSurf1->GetData() + y * dataSurf1->Stride(),
dataSurf2->GetData() + y * dataSurf2->Stride(),
dataSurf1->GetSize().width * 4) == 0);
}
}

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

@ -0,0 +1,17 @@
/* -*- 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/. */
#pragma once
#include "TestBase.h"
class TestBugs : public TestBase
{
public:
TestBugs();
void CairoClip918671();
};

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

@ -208,6 +208,8 @@ xlib-flush-glyphs.patch: bug 839745, flush glyphs when necessary
dasharray-zero-gap.patch: bug 885585, ensure strokes get painted when the gaps in a dash array are all zero length
cairo-mask-extends-bug.patch: bug 918671, sometimes when building a mask we wouldn't clear it properly. This is fixed in cairo 1.12
==== pixman patches ====
pixman-android-cpu-detect.patch: Add CPU detection support for Android, where we can't reliably access /proc/self/auxv.

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

@ -0,0 +1,41 @@
diff --git a/gfx/cairo/cairo/src/cairo-image-surface.c b/gfx/cairo/cairo/src/cairo-image-surface.c
--- a/gfx/cairo/cairo/src/cairo-image-surface.c
+++ b/gfx/cairo/cairo/src/cairo-image-surface.c
@@ -1788,18 +1788,35 @@ static cairo_status_t
cairo_boxes_t *boxes)
{
cairo_boxes_t clear;
cairo_box_t box;
cairo_status_t status;
struct _cairo_boxes_chunk *chunk;
int i;
- if (boxes->num_boxes < 1 && clip_region == NULL)
- return _cairo_image_surface_fixup_unbounded (dst, extents, NULL);
+ // If we have no boxes then we need to clear the entire extents
+ // because we have nothing to draw.
+ if (boxes->num_boxes < 1 && clip_region == NULL) {
+ int x = extents->unbounded.x;
+ int y = extents->unbounded.y;
+ int width = extents->unbounded.width;
+ int height = extents->unbounded.height;
+
+ pixman_color_t color = { 0 };
+ pixman_box32_t box = { x, y, x + width, y + height };
+
+ if (! pixman_image_fill_boxes (PIXMAN_OP_CLEAR,
+ dst->pixman_image,
+ &color,
+ 1, &box)) {
+ return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ }
+ return CAIRO_STATUS_SUCCESS;
+ }
_cairo_boxes_init (&clear);
box.p1.x = _cairo_fixed_from_int (extents->unbounded.x + extents->unbounded.width);
box.p1.y = _cairo_fixed_from_int (extents->unbounded.y);
box.p2.x = _cairo_fixed_from_int (extents->unbounded.x);
box.p2.y = _cairo_fixed_from_int (extents->unbounded.y + extents->unbounded.height);

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

@ -1793,8 +1793,25 @@ _cairo_image_surface_fixup_unbounded_boxes (cairo_image_surface_t *dst,
struct _cairo_boxes_chunk *chunk;
int i;
if (boxes->num_boxes < 1 && clip_region == NULL)
return _cairo_image_surface_fixup_unbounded (dst, extents, NULL);
// If we have no boxes then we need to clear the entire extents
// because we have nothing to draw.
if (boxes->num_boxes < 1 && clip_region == NULL) {
int x = extents->unbounded.x;
int y = extents->unbounded.y;
int width = extents->unbounded.width;
int height = extents->unbounded.height;
pixman_color_t color = { 0 };
pixman_box32_t box = { x, y, x + width, y + height };
if (! pixman_image_fill_boxes (PIXMAN_OP_CLEAR,
dst->pixman_image,
&color,
1, &box)) {
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
return CAIRO_STATUS_SUCCESS;
}
_cairo_boxes_init (&clear);

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

@ -660,6 +660,26 @@ struct ParamTraits<mozilla::gfx::SurfaceFormat>
mozilla::gfx::FORMAT_UNKNOWN>
{};
template <>
struct ParamTraits<mozilla::layers::ScrollableLayerGuid>
{
typedef mozilla::layers::ScrollableLayerGuid paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
WriteParam(aMsg, aParam.mLayersId);
WriteParam(aMsg, aParam.mPresShellId);
WriteParam(aMsg, aParam.mScrollId);
}
static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
{
return (ReadParam(aMsg, aIter, &aResult->mLayersId) &&
ReadParam(aMsg, aIter, &aResult->mPresShellId) &&
ReadParam(aMsg, aIter, &aResult->mScrollId));
}
};
} /* namespace IPC */
#endif /* __GFXMESSAGEUTILS_H__ */

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

@ -255,6 +255,72 @@ public:
uint32_t mPresShellId;
};
/**
* This class allows us to uniquely identify a scrollable layer. The
* mLayersId identifies the layer tree (corresponding to a child process
* and/or tab) that the scrollable layer belongs to. The mPresShellId
* is a temporal identifier (corresponding to the document loaded that
* contains the scrollable layer, which may change over time). The
* mScrollId corresponds to the actual frame that is scrollable.
*/
struct ScrollableLayerGuid {
uint64_t mLayersId;
uint32_t mPresShellId;
FrameMetrics::ViewID mScrollId;
ScrollableLayerGuid()
: mLayersId(0)
, mPresShellId(0)
, mScrollId(0)
{
MOZ_COUNT_CTOR(ScrollableLayerGuid);
}
ScrollableLayerGuid(uint64_t aLayersId, uint32_t aPresShellId,
FrameMetrics::ViewID aScrollId)
: mLayersId(aLayersId)
, mPresShellId(aPresShellId)
, mScrollId(aScrollId)
{
MOZ_COUNT_CTOR(ScrollableLayerGuid);
}
ScrollableLayerGuid(uint64_t aLayersId, const FrameMetrics& aMetrics)
: mLayersId(aLayersId)
, mPresShellId(aMetrics.mPresShellId)
, mScrollId(aMetrics.mScrollId)
{
MOZ_COUNT_CTOR(ScrollableLayerGuid);
}
ScrollableLayerGuid(uint64_t aLayersId)
: mLayersId(aLayersId)
, mPresShellId(0)
, mScrollId(FrameMetrics::ROOT_SCROLL_ID)
{
MOZ_COUNT_CTOR(ScrollableLayerGuid);
// TODO: get rid of this constructor once all callers know their
// presShellId and scrollId
}
~ScrollableLayerGuid()
{
MOZ_COUNT_DTOR(ScrollableLayerGuid);
}
bool operator==(const ScrollableLayerGuid& other) const
{
return mLayersId == other.mLayersId
&& mPresShellId == other.mPresShellId
&& mScrollId == other.mScrollId;
}
bool operator!=(const ScrollableLayerGuid& other) const
{
return !(*this == other);
}
};
}
}

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

@ -121,6 +121,22 @@ APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor,
apzc = container->GetAsyncPanZoomController();
// If the container doesn't have an APZC already, try to find one of our
// pre-existing ones that matches. In particular, if we find an APZC whose
// ScrollableLayerGuid is the same, then we know what happened is that the
// layout of the page changed causing the layer tree to be rebuilt, but the
// underlying content for which the APZC was originally created is still
// there. So it makes sense to pick up that APZC instance again and use it here.
if (apzc == nullptr) {
ScrollableLayerGuid target(aLayersId, container->GetFrameMetrics());
for (size_t i = 0; i < aApzcsToDestroy->Length(); i++) {
if (aApzcsToDestroy->ElementAt(i)->Matches(target)) {
apzc = aApzcsToDestroy->ElementAt(i);
break;
}
}
}
// The APZC we get off the layer may have been destroyed previously if the layer was inactive
// or omitted from the layer tree for whatever reason from a layers update. If it later comes
// back it will have a reference to a destroyed APZC and so we need to throw that out and make
@ -169,7 +185,7 @@ APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor,
// was created
bool allowZoom;
CSSToScreenScale minZoom, maxZoom;
if (state->mController->GetZoomConstraints(&allowZoom, &minZoom, &maxZoom)) {
if (state->mController->GetRootZoomConstraints(&allowZoom, &minZoom, &maxZoom)) {
apzc->UpdateZoomConstraints(allowZoom, minZoom, maxZoom);
}
}
@ -505,12 +521,16 @@ APZCTreeManager::ReceiveInputEvent(WidgetInputEvent& aEvent,
}
void
APZCTreeManager::UpdateCompositionBounds(const ScrollableLayerGuid& aGuid,
const ScreenIntRect& aCompositionBounds)
APZCTreeManager::UpdateRootCompositionBounds(const uint64_t& aLayersId,
const ScreenIntRect& aCompositionBounds)
{
nsRefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(aGuid);
if (apzc) {
apzc->UpdateCompositionBounds(aCompositionBounds);
// There can be multiple root APZCs for a given layers id (e.g. tabs in
// a single-process setup) and in such a case we probably want to notify
// all of them.
nsTArray< nsRefPtr<AsyncPanZoomController> > rootApzcs;
GetRootAPZCsFor(aLayersId, &rootApzcs);
for (size_t i = 0; i < rootApzcs.Length(); i++) {
rootApzcs[i]->UpdateCompositionBounds(aCompositionBounds);
}
}
@ -651,8 +671,20 @@ APZCTreeManager::GetTargetAPZC(const ScreenPoint& aPoint)
return target.forget();
}
void
APZCTreeManager::GetRootAPZCsFor(const uint64_t& aLayersId,
nsTArray< nsRefPtr<AsyncPanZoomController> >* aOutRootApzcs)
{
MonitorAutoLock lock(mTreeLock);
// The root may have siblings, check those too
for (AsyncPanZoomController* apzc = mRootApzc; apzc; apzc = apzc->GetPrevSibling()) {
FindRootAPZCs(apzc, aLayersId, aOutRootApzcs);
}
}
AsyncPanZoomController*
APZCTreeManager::FindTargetAPZC(AsyncPanZoomController* aApzc, const ScrollableLayerGuid& aGuid) {
APZCTreeManager::FindTargetAPZC(AsyncPanZoomController* aApzc, const ScrollableLayerGuid& aGuid)
{
mTreeLock.AssertCurrentThreadOwns();
// This walks the tree in depth-first, reverse order, so that it encounters
@ -726,6 +758,25 @@ APZCTreeManager::GetAPZCAtPoint(AsyncPanZoomController* aApzc, const gfxPoint& a
return nullptr;
}
void
APZCTreeManager::FindRootAPZCs(AsyncPanZoomController* aApzc,
const uint64_t& aLayersId,
nsTArray< nsRefPtr<AsyncPanZoomController> >* aOutRootApzcs)
{
mTreeLock.AssertCurrentThreadOwns();
if (aApzc->IsRootForLayersId(aLayersId)) {
aOutRootApzcs->AppendElement(aApzc);
// If this APZC is a root for this layers id then we know nothing else
// in the subtree rooted here will match so we can early-exit
return;
}
for (AsyncPanZoomController* child = aApzc->GetLastChild(); child; child = child->GetPrevSibling()) {
FindRootAPZCs(child, aLayersId, aOutRootApzcs);
}
}
/* This function sets the aTransformToApzcOut and aTransformToGeckoOut out-parameters
to some useful transformations that input events may need applied. This is best
illustrated with an example. Consider a chain of layers, L, M, N, O, P, Q, R. Layer L

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

@ -31,72 +31,6 @@ class Layer;
class AsyncPanZoomController;
class CompositorParent;
/**
* This class allows us to uniquely identify a scrollable layer. The
* mLayersId identifies the layer tree (corresponding to a child process
* and/or tab) that the scrollable layer belongs to. The mPresShellId
* is a temporal identifier (corresponding to the document loaded that
* contains the scrollable layer, which may change over time). The
* mScrollId corresponds to the actual frame that is scrollable.
*/
struct ScrollableLayerGuid {
uint64_t mLayersId;
uint32_t mPresShellId;
FrameMetrics::ViewID mScrollId;
ScrollableLayerGuid()
: mLayersId(0)
, mPresShellId(0)
, mScrollId(0)
{
MOZ_COUNT_CTOR(ScrollableLayerGuid);
}
ScrollableLayerGuid(uint64_t aLayersId, uint32_t aPresShellId,
FrameMetrics::ViewID aScrollId)
: mLayersId(aLayersId)
, mPresShellId(aPresShellId)
, mScrollId(aScrollId)
{
MOZ_COUNT_CTOR(ScrollableLayerGuid);
}
ScrollableLayerGuid(uint64_t aLayersId, const FrameMetrics& aMetrics)
: mLayersId(aLayersId)
, mPresShellId(aMetrics.mPresShellId)
, mScrollId(aMetrics.mScrollId)
{
MOZ_COUNT_CTOR(ScrollableLayerGuid);
}
ScrollableLayerGuid(uint64_t aLayersId)
: mLayersId(aLayersId)
, mPresShellId(0)
, mScrollId(FrameMetrics::ROOT_SCROLL_ID)
{
MOZ_COUNT_CTOR(ScrollableLayerGuid);
// TODO: get rid of this constructor once all callers know their
// presShellId and scrollId
}
~ScrollableLayerGuid()
{
MOZ_COUNT_DTOR(ScrollableLayerGuid);
}
bool operator==(const ScrollableLayerGuid& other) const
{
return mLayersId == other.mLayersId
&& mPresShellId == other.mPresShellId
&& mScrollId == other.mScrollId;
}
bool operator!=(const ScrollableLayerGuid& other) const
{
return !(*this == other);
}
};
/**
* This class manages the tree of AsyncPanZoomController instances. There is one
* instance of this class owned by each CompositorParent, and it contains as
@ -200,14 +134,15 @@ public:
LayoutDeviceIntPoint* aOutTransformedPoint);
/**
* Updates the composition bounds, i.e. the dimensions of the final size of
* the frame this is tied to during composition onto, in device pixels. In
* general, this will just be:
* { x = 0, y = 0, width = surface.width, height = surface.height }, however
* there is no hard requirement for this.
* Updates the composition bounds on the root APZC for the given layers id.
* See FrameMetrics::mCompositionBounds for the definition of what the
* composition bounds are. This function is only meant for updating the
* composition bounds on the root APZC because that is the one that is
* zoomable, and the zoom may need to be adjusted immediately upon a change
* in the composition bounds.
*/
void UpdateCompositionBounds(const ScrollableLayerGuid& aGuid,
const ScreenIntRect& aCompositionBounds);
void UpdateRootCompositionBounds(const uint64_t& aLayersId,
const ScreenIntRect& aCompositionBounds);
/**
* Kicks an animation to zoom to a rect. This may be either a zoom out or zoom
@ -304,12 +239,17 @@ public:
*/
already_AddRefed<AsyncPanZoomController> GetTargetAPZC(const ScrollableLayerGuid& aGuid);
already_AddRefed<AsyncPanZoomController> GetTargetAPZC(const ScreenPoint& aPoint);
void GetRootAPZCsFor(const uint64_t& aLayersId,
nsTArray< nsRefPtr<AsyncPanZoomController> >* aOutRootApzcs);
void GetInputTransforms(AsyncPanZoomController *aApzc, gfx3DMatrix& aTransformToApzcOut,
gfx3DMatrix& aTransformToGeckoOut);
private:
/* Helpers */
AsyncPanZoomController* FindTargetAPZC(AsyncPanZoomController* aApzc, const ScrollableLayerGuid& aGuid);
AsyncPanZoomController* GetAPZCAtPoint(AsyncPanZoomController* aApzc, const gfxPoint& aHitTestPoint);
void FindRootAPZCs(AsyncPanZoomController* aApzc,
const uint64_t& aLayersId,
nsTArray< nsRefPtr<AsyncPanZoomController> >* aOutRootApzcs);
already_AddRefed<AsyncPanZoomController> CommonAncestor(AsyncPanZoomController* aApzc1, AsyncPanZoomController* aApzc2);
already_AddRefed<AsyncPanZoomController> RootAPZCForLayersId(AsyncPanZoomController* aApzc);
already_AddRefed<AsyncPanZoomController> GetTouchInputBlockAPZC(const WidgetTouchEvent& aEvent, ScreenPoint aPoint);

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

@ -1290,13 +1290,9 @@ void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aLayerMetri
aLayerMetrics.mCompositionBounds.height == mFrameMetrics.mCompositionBounds.height) {
// Remote content has sync'd up to the composition geometry
// change, so we can accept the viewport it's calculated.
CSSToScreenScale previousResolution = mFrameMetrics.CalculateIntrinsicScale();
mFrameMetrics.mViewport = aLayerMetrics.mViewport;
CSSToScreenScale newResolution = mFrameMetrics.CalculateIntrinsicScale();
if (previousResolution != newResolution) {
if (mFrameMetrics.mViewport.width != aLayerMetrics.mViewport.width)
needContentRepaint = true;
mFrameMetrics.mZoom.scale *= newResolution.scale / previousResolution.scale;
}
mFrameMetrics.mViewport = aLayerMetrics.mViewport;
}
if (aIsFirstPaint || isDefault) {
@ -1545,9 +1541,7 @@ void AsyncPanZoomController::UpdateScrollOffset(const CSSPoint& aScrollOffset)
bool AsyncPanZoomController::Matches(const ScrollableLayerGuid& aGuid)
{
// TODO: also check the presShellId, once that is fully propagated
// everywhere in RenderFrameParent and AndroidJNI.
return aGuid.mLayersId == mLayersId && aGuid.mScrollId == mFrameMetrics.mScrollId;
return aGuid == ScrollableLayerGuid(mLayersId, mFrameMetrics);
}
void AsyncPanZoomController::GetGuid(ScrollableLayerGuid* aGuidOut)

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

@ -642,6 +642,10 @@ public:
return !mParent || (mParent->mLayersId != mLayersId);
}
bool IsRootForLayersId(const uint64_t& aLayersId) const {
return (mLayersId == aLayersId) && IsRootForLayersId();
}
private:
// This is a raw pointer to avoid introducing a reference cycle between
// AsyncPanZoomController and APZCTreeManager. Since these objects don't

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

@ -65,12 +65,13 @@ public:
virtual void PostDelayedTask(Task* aTask, int aDelayMs) = 0;
/**
* Retrieves the last known zoom constraints. This function should return
* false if there are no last known zoom constraints.
* Retrieves the last known zoom constraints for the root scrollable layer
* for this layers tree. This function should return false if there are no
* last known zoom constraints.
*/
virtual bool GetZoomConstraints(bool* aOutAllowZoom,
CSSToScreenScale* aOutMinZoom,
CSSToScreenScale* aOutMaxZoom)
virtual bool GetRootZoomConstraints(bool* aOutAllowZoom,
CSSToScreenScale* aOutMinZoom,
CSSToScreenScale* aOutMaxZoom)
{
return false;
}

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

@ -7,6 +7,16 @@
#include "TestBase.h"
#include "TestPoint.h"
#include "TestScaling.h"
#include "TestBugs.h"
TEST(Moz2D, Bugs) {
TestBugs* test = new TestBugs();
int failures = 0;
test->RunTests(&failures);
delete test;
ASSERT_EQ(failures, 0);
}
TEST(Moz2D, Point) {
TestBase* test = new TestPoint();

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

@ -29,6 +29,7 @@ GTEST_SOURCES += [
if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'windows':
GTEST_SOURCES += [ '%s/gfx/2d/unittest/%s' % (TOPSRCDIR, p) for p in [
'TestBase.cpp',
'TestBugs.cpp',
'TestPoint.cpp',
'TestScaling.cpp',
]]

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше