mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-11 12:25:53 +00:00
Merge m-c to b2g-inbound.
This commit is contained in:
commit
629221439d
@ -15,6 +15,7 @@ let Cr = Components.results;
|
||||
*/
|
||||
|
||||
var APZCObserver = {
|
||||
_debugEvents: false,
|
||||
init: function() {
|
||||
this._enabled = Services.prefs.getBoolPref(kAsyncPanZoomEnabled);
|
||||
if (!this._enabled) {
|
||||
@ -95,25 +96,23 @@ var APZCObserver = {
|
||||
id: scrollId
|
||||
});
|
||||
|
||||
Util.dumpLn("APZC scrollId: " + scrollId);
|
||||
Util.dumpLn("APZC scrollTo.x: " + scrollTo.x + ", scrollTo.y: " + scrollTo.y);
|
||||
Util.dumpLn("APZC setResolution: " + resolution);
|
||||
Util.dumpLn("APZC setDisplayPortForElement: displayPort.x: " +
|
||||
displayPort.x + ", displayPort.y: " + displayPort.y +
|
||||
", displayPort.width: " + displayPort.width +
|
||||
", displayort.height: " + displayPort.height);
|
||||
if (this._debugEvents) {
|
||||
Util.dumpLn("APZC scrollId: " + scrollId);
|
||||
Util.dumpLn("APZC scrollTo.x: " + scrollTo.x + ", scrollTo.y: " + scrollTo.y);
|
||||
Util.dumpLn("APZC setResolution: " + resolution);
|
||||
Util.dumpLn("APZC setDisplayPortForElement: displayPort.x: " +
|
||||
displayPort.x + ", displayPort.y: " + displayPort.y +
|
||||
", displayPort.width: " + displayPort.width +
|
||||
", displayort.height: " + displayPort.height);
|
||||
}
|
||||
} else if (aTopic == "apzc-handle-pan-begin") {
|
||||
// When we're panning, hide the main scrollbars by setting imprecise
|
||||
// input (which sets a property on the browser which hides the scrollbar
|
||||
// via CSS). This reduces jittering from left to right. We may be able
|
||||
// to get rid of this once we implement axis locking in /gfx APZC.
|
||||
Util.dumpLn("APZC pan-begin");
|
||||
if (InputSourceHelper.isPrecise) {
|
||||
InputSourceHelper._imprecise();
|
||||
}
|
||||
|
||||
} else if (aTopic == "apzc-handle-pan-end") {
|
||||
Util.dumpLn("APZC pan-end");
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -34,7 +34,7 @@ pref("prompts.tab_modal.enabled", true);
|
||||
|
||||
// Enable off main thread compositing
|
||||
pref("layers.offmainthreadcomposition.enabled", true);
|
||||
pref("layers.async-pan-zoom.enabled", false);
|
||||
pref("layers.async-pan-zoom.enabled", true);
|
||||
pref("layers.componentalpha.enabled", false);
|
||||
pref("gfx.azpc.touch_start_tolerance", "0.1"); // dpi * tolerance = pixel threshold
|
||||
pref("gfx.axis.fling_friction", "0.002");
|
||||
|
@ -488,9 +488,6 @@ private:
|
||||
InitDomainPolicy(JSContext* cx, const char* aPolicyName,
|
||||
DomainPolicy* aDomainPolicy);
|
||||
|
||||
// JS strings we need to clean up on shutdown
|
||||
static jsid sEnabledID;
|
||||
|
||||
inline void
|
||||
ScriptSecurityPrefChanged();
|
||||
|
||||
|
@ -77,6 +77,18 @@ nsIStringBundle *nsScriptSecurityManager::sStrBundle = nullptr;
|
||||
JSRuntime *nsScriptSecurityManager::sRuntime = 0;
|
||||
bool nsScriptSecurityManager::sStrictFileOriginPolicy = true;
|
||||
|
||||
// Lazily initialized. Use the getter below.
|
||||
static jsid sEnabledID = JSID_VOID;
|
||||
static jsid
|
||||
EnabledID()
|
||||
{
|
||||
if (sEnabledID != JSID_VOID)
|
||||
return sEnabledID;
|
||||
AutoSafeJSContext cx;
|
||||
sEnabledID = INTERNED_STRING_TO_JSID(cx, JS_InternString(cx, "enabled"));
|
||||
return sEnabledID;
|
||||
}
|
||||
|
||||
bool
|
||||
nsScriptSecurityManager::SubjectIsPrivileged()
|
||||
{
|
||||
@ -1446,7 +1458,7 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal,
|
||||
ClassInfoData nameData(nullptr, loadURIPrefGroup);
|
||||
|
||||
SecurityLevel secLevel;
|
||||
rv = LookupPolicy(aPrincipal, nameData, sEnabledID,
|
||||
rv = LookupPolicy(aPrincipal, nameData, EnabledID(),
|
||||
nsIXPCSecurityManager::ACCESS_GET_PROPERTY,
|
||||
nullptr, &secLevel);
|
||||
if (NS_SUCCEEDED(rv) && secLevel.level == SCRIPT_SECURITY_ALL_ACCESS)
|
||||
@ -1733,7 +1745,7 @@ nsScriptSecurityManager::CanExecuteScripts(JSContext* cx,
|
||||
ClassInfoData nameData(nullptr, jsPrefGroupName);
|
||||
|
||||
SecurityLevel secLevel;
|
||||
rv = LookupPolicy(aPrincipal, nameData, sEnabledID,
|
||||
rv = LookupPolicy(aPrincipal, nameData, EnabledID(),
|
||||
nsIXPCSecurityManager::ACCESS_GET_PROPERTY,
|
||||
nullptr, &secLevel);
|
||||
if (NS_FAILED(rv) || secLevel.level == SCRIPT_SECURITY_NO_ACCESS)
|
||||
@ -2330,14 +2342,6 @@ nsScriptSecurityManager::nsScriptSecurityManager(void)
|
||||
|
||||
nsresult nsScriptSecurityManager::Init()
|
||||
{
|
||||
JSContext* cx = GetSafeJSContext();
|
||||
if (!cx) return NS_ERROR_FAILURE; // this can happen of xpt loading fails
|
||||
|
||||
::JS_BeginRequest(cx);
|
||||
if (sEnabledID == JSID_VOID)
|
||||
sEnabledID = INTERNED_STRING_TO_JSID(cx, ::JS_InternString(cx, "enabled"));
|
||||
::JS_EndRequest(cx);
|
||||
|
||||
InitPrefs();
|
||||
|
||||
nsresult rv = CallGetService(NS_IOSERVICE_CONTRACTID, &sIOService);
|
||||
@ -2378,8 +2382,6 @@ nsresult nsScriptSecurityManager::Init()
|
||||
|
||||
static StaticRefPtr<nsScriptSecurityManager> gScriptSecMan;
|
||||
|
||||
jsid nsScriptSecurityManager::sEnabledID = JSID_VOID;
|
||||
|
||||
nsScriptSecurityManager::~nsScriptSecurityManager(void)
|
||||
{
|
||||
Preferences::RemoveObservers(this, kObservedPrefs);
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "nsIProtocolHandler.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIInputStream.h"
|
||||
|
||||
#define BLOBURI_SCHEME "blob"
|
||||
#define MEDIASTREAMURI_SCHEME "mediastream"
|
||||
@ -18,7 +19,6 @@
|
||||
class nsIDOMBlob;
|
||||
class nsIDOMMediaStream;
|
||||
class nsIPrincipal;
|
||||
class nsIInputStream;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
@ -67,6 +67,7 @@
|
||||
#include "nsCharSeparatedTokenizer.h"
|
||||
#include "nsFormData.h"
|
||||
#include "nsStreamListenerWrapper.h"
|
||||
#include "xpcjsid.h"
|
||||
|
||||
#include "nsWrapperCacheInlines.h"
|
||||
|
||||
|
@ -48,6 +48,7 @@ class nsFormData;
|
||||
class nsIJARChannel;
|
||||
class nsILoadGroup;
|
||||
class nsIUnicodeDecoder;
|
||||
class nsIJSID;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
|
@ -5,4 +5,5 @@
|
||||
|
||||
MOCHITEST_FILES = \
|
||||
test_webgl_conformance.html \
|
||||
test_webgl_request_mismatch.html \
|
||||
$(NULL)
|
||||
|
@ -0,0 +1,36 @@
|
||||
<!DOCTYPE HTML>
|
||||
<title>WebGL test: Mismatched 'webgl' and 'experimental-webgl' context requests</title>
|
||||
<script src="/MochiKit/MochiKit.js"></script>
|
||||
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
|
||||
<body>
|
||||
<canvas id="c1"></canvas>
|
||||
<canvas id="c2"></canvas>
|
||||
<canvas id="c3"></canvas>
|
||||
<canvas id="c4"></canvas>
|
||||
<script>
|
||||
|
||||
function testContextRetrieval(canvasId, creationId, requestId) {
|
||||
var canvas = document.getElementById(canvasId);
|
||||
ok(canvas, 'Invalid `canvasId`: ' + canvasId);
|
||||
|
||||
var createdGL = canvas.getContext(creationId);
|
||||
if (!createdGL)
|
||||
return; // No WebGL on this machine?
|
||||
|
||||
var requestedGL = canvas.getContext(requestId);
|
||||
if (creationId == requestId) {
|
||||
ok(requestedGL, 'Request for \'' + requestId + '\' on from \'' + creationId + '\' should succeed.');
|
||||
ok(requestedGL == createdGL, 'Request for \'' + requestId + '\' on from \'' + creationId + '\' should match.');
|
||||
} else {
|
||||
ok(!requestedGL, 'Request for \'' + requestId + '\' on from \'' + creationId + '\' should fail.');
|
||||
}
|
||||
}
|
||||
|
||||
testContextRetrieval('c1', 'experimental-webgl', 'webgl');
|
||||
testContextRetrieval('c2', 'webgl', 'experimental-webgl');
|
||||
testContextRetrieval('c3', 'experimental-webgl', 'experimental-webgl');
|
||||
testContextRetrieval('c4', 'webgl', 'webgl');
|
||||
|
||||
</script>
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "AudioChannelCommon.h"
|
||||
#include <algorithm>
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
|
||||
static bool
|
||||
IsAudioAPIEnabled()
|
||||
|
@ -671,6 +671,14 @@ HTMLCanvasElement::GetContext(const nsAString& aContextId,
|
||||
return rv.ErrorCode();
|
||||
}
|
||||
|
||||
static bool
|
||||
IsContextIdWebGL(const nsAString& str)
|
||||
{
|
||||
return str.EqualsLiteral("webgl") ||
|
||||
str.EqualsLiteral("experimental-webgl") ||
|
||||
str.EqualsLiteral("moz-webgl");
|
||||
}
|
||||
|
||||
already_AddRefed<nsISupports>
|
||||
HTMLCanvasElement::GetContext(JSContext* aCx,
|
||||
const nsAString& aContextId,
|
||||
@ -702,6 +710,20 @@ HTMLCanvasElement::GetContext(JSContext* aCx,
|
||||
}
|
||||
|
||||
if (!mCurrentContextId.Equals(aContextId)) {
|
||||
if (IsContextIdWebGL(aContextId) &&
|
||||
IsContextIdWebGL(mCurrentContextId))
|
||||
{
|
||||
// Warn when we get a request for a webgl context with an id that differs
|
||||
// from the id it was created with.
|
||||
nsCString creationId = NS_LossyConvertUTF16toASCII(mCurrentContextId);
|
||||
nsCString requestId = NS_LossyConvertUTF16toASCII(aContextId);
|
||||
JS_ReportWarning(aCx, "WebGL: Retrieving a WebGL context from a canvas "
|
||||
"via a request id ('%s') different from the id used "
|
||||
"to create the context ('%s') is not allowed.",
|
||||
requestId.get(),
|
||||
creationId.get());
|
||||
}
|
||||
|
||||
//XXX eventually allow for more than one active context on a given canvas
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "WebVTTLoadListener.h"
|
||||
#include "mozilla/dom/TextTrackCue.h"
|
||||
#include "mozilla/dom/HTMLTrackElement.h"
|
||||
#include "nsIInputStream.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "SourceBuffer.h"
|
||||
#include "SourceBufferList.h"
|
||||
#include "nsContentTypeParser.h"
|
||||
#include "nsIInputStream.h"
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
PRLogModuleInfo* gMediaSourceLog;
|
||||
|
@ -18,6 +18,8 @@
|
||||
#include "nsWrapperCache.h"
|
||||
#include "nscore.h"
|
||||
|
||||
class nsIInputStream;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
|
@ -190,6 +190,7 @@
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/Likely.h"
|
||||
#include "WindowNamedPropertiesHandler.h"
|
||||
#include "nsIInterfaceInfoManager.h"
|
||||
|
||||
#ifdef MOZ_TIME_MANAGER
|
||||
#include "TimeManager.h"
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "nsIDocument.h"
|
||||
#include "nsString.h"
|
||||
#include "prprf.h"
|
||||
#include "nsIException.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
|
@ -49,6 +49,7 @@
|
||||
|
||||
#include "mozilla/dom/EventTarget.h"
|
||||
#include "Units.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
|
||||
#ifdef MOZ_B2G
|
||||
#include "nsIDOMWindowB2G.h"
|
||||
|
@ -55,6 +55,7 @@
|
||||
#include "StructuredCloneTags.h"
|
||||
#include "mozilla/dom/ImageData.h"
|
||||
#include "mozilla/dom/ImageDataBinding.h"
|
||||
#include "nsAXPCNativeCallContext.h"
|
||||
|
||||
#include "nsJSPrincipals.h"
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "mozilla/Likely.h"
|
||||
#include <algorithm>
|
||||
#include "mozilla/dom/FunctionBinding.h"
|
||||
#include "nsAXPCNativeCallContext.h"
|
||||
|
||||
static const char kSetIntervalStr[] = "setInterval";
|
||||
static const char kSetTimeoutStr[] = "setTimeout";
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "nsTraceRefcnt.h"
|
||||
#include "qsObjectHelper.h"
|
||||
#include "xpcpublic.h"
|
||||
#include "nsIVariant.h"
|
||||
|
||||
#include "nsWrapperCacheInlines.h"
|
||||
|
||||
|
@ -23,6 +23,8 @@
|
||||
#define DEVICESTORAGE_SDCARD "sdcard"
|
||||
#define DEVICESTORAGE_CRASHES "crashes"
|
||||
|
||||
class nsIInputStream;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
class DeviceStorageEnumerationParameters;
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "nsError.h"
|
||||
#include "nsStringGlue.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsIInputStream.h"
|
||||
|
||||
#define BEGIN_INDEXEDDB_NAMESPACE \
|
||||
namespace mozilla { namespace dom { namespace indexedDB {
|
||||
@ -28,7 +29,6 @@
|
||||
using namespace mozilla::dom::indexedDB;
|
||||
|
||||
class nsIDOMBlob;
|
||||
class nsIInputStream;
|
||||
|
||||
BEGIN_INDEXEDDB_NAMESPACE
|
||||
|
||||
|
@ -8,26 +8,23 @@ interface nsIDOMGeoPositionCallback;
|
||||
interface nsIDOMGeoPositionErrorCallback;
|
||||
|
||||
%{C++
|
||||
#include "DictionaryHelpers.h"
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
class PositionOptions;
|
||||
}
|
||||
}
|
||||
%}
|
||||
|
||||
dictionary GeoPositionOptions
|
||||
{
|
||||
boolean enableHighAccuracy;
|
||||
long timeout;
|
||||
long maximumAge;
|
||||
};
|
||||
|
||||
[ptr] native NamespacedGeoPositionOptions(mozilla::idl::GeoPositionOptions);
|
||||
[ptr] native NamespacedPositionOptions(mozilla::dom::PositionOptions);
|
||||
|
||||
[builtinclass, uuid(1bc7d103-c7ae-4467-881c-21a8dfa17938)]
|
||||
interface nsIDOMGeoGeolocation : nsISupports
|
||||
{
|
||||
int32_t watchPosition(in nsIDOMGeoPositionCallback callback,
|
||||
in nsIDOMGeoPositionErrorCallback errorCallback,
|
||||
in NamespacedGeoPositionOptions options);
|
||||
in NamespacedPositionOptions options);
|
||||
void getCurrentPosition(in nsIDOMGeoPositionCallback callback,
|
||||
in nsIDOMGeoPositionErrorCallback errorCallback,
|
||||
in NamespacedGeoPositionOptions options);
|
||||
in NamespacedPositionOptions options);
|
||||
void clearWatch(in long watchId);
|
||||
};
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include "mozilla/dom/bluetooth/PBluetoothParent.h"
|
||||
#include "mozilla/dom/PFMRadioParent.h"
|
||||
#include "mozilla/dom/devicestorage/DeviceStorageRequestParent.h"
|
||||
#include "mozilla/dom/GeolocationBinding.h"
|
||||
#include "SmsParent.h"
|
||||
#include "mozilla/Hal.h"
|
||||
#include "mozilla/hal_sandbox/PHalParent.h"
|
||||
@ -148,7 +149,6 @@ using namespace mozilla::dom::indexedDB;
|
||||
using namespace mozilla::dom::power;
|
||||
using namespace mozilla::dom::mobilemessage;
|
||||
using namespace mozilla::hal;
|
||||
using namespace mozilla::idl;
|
||||
using namespace mozilla::ipc;
|
||||
using namespace mozilla::layers;
|
||||
using namespace mozilla::net;
|
||||
@ -2621,8 +2621,8 @@ AddGeolocationListener(nsIDOMGeoPositionCallback* watcher, bool highAccuracy)
|
||||
return -1;
|
||||
}
|
||||
|
||||
GeoPositionOptions* options = new GeoPositionOptions();
|
||||
options->enableHighAccuracy = highAccuracy;
|
||||
PositionOptions* options = new PositionOptions();
|
||||
options->mEnableHighAccuracy = highAccuracy;
|
||||
int32_t retval = 1;
|
||||
geo->WatchPosition(watcher, nullptr, options, &retval);
|
||||
return retval;
|
||||
|
@ -71,13 +71,13 @@ class nsGeolocationRequest
|
||||
nsGeolocationRequest(Geolocation* aLocator,
|
||||
const GeoPositionCallback& aCallback,
|
||||
const GeoPositionErrorCallback& aErrorCallback,
|
||||
idl::GeoPositionOptions* aOptions,
|
||||
PositionOptions* aOptions,
|
||||
bool aWatchPositionRequest = false,
|
||||
int32_t aWatchId = 0);
|
||||
void Shutdown();
|
||||
|
||||
void SendLocation(nsIDOMGeoPosition* location);
|
||||
bool WantsHighAccuracy() {return mOptions && mOptions->enableHighAccuracy;}
|
||||
bool WantsHighAccuracy() {return mOptions && mOptions->mEnableHighAccuracy;}
|
||||
void SetTimeoutTimer();
|
||||
nsIPrincipal* GetPrincipal();
|
||||
|
||||
@ -94,7 +94,7 @@ class nsGeolocationRequest
|
||||
nsCOMPtr<nsITimer> mTimeoutTimer;
|
||||
GeoPositionCallback mCallback;
|
||||
GeoPositionErrorCallback mErrorCallback;
|
||||
nsAutoPtr<idl::GeoPositionOptions> mOptions;
|
||||
nsAutoPtr<PositionOptions> mOptions;
|
||||
|
||||
nsRefPtr<Geolocation> mLocator;
|
||||
|
||||
@ -102,15 +102,14 @@ class nsGeolocationRequest
|
||||
bool mShutdown;
|
||||
};
|
||||
|
||||
static idl::GeoPositionOptions*
|
||||
GeoPositionOptionsFromPositionOptions(const PositionOptions& aOptions)
|
||||
static PositionOptions*
|
||||
CreatePositionOptionsCopy(const PositionOptions& aOptions)
|
||||
{
|
||||
nsAutoPtr<idl::GeoPositionOptions> geoOptions(
|
||||
new idl::GeoPositionOptions());
|
||||
nsAutoPtr<PositionOptions> geoOptions(new PositionOptions());
|
||||
|
||||
geoOptions->enableHighAccuracy = aOptions.mEnableHighAccuracy;
|
||||
geoOptions->maximumAge = aOptions.mMaximumAge;
|
||||
geoOptions->timeout = aOptions.mTimeout;
|
||||
geoOptions->mEnableHighAccuracy = aOptions.mEnableHighAccuracy;
|
||||
geoOptions->mMaximumAge = aOptions.mMaximumAge;
|
||||
geoOptions->mTimeout = aOptions.mTimeout;
|
||||
|
||||
return geoOptions.forget();
|
||||
}
|
||||
@ -336,7 +335,7 @@ PositionError::NotifyCallback(const GeoPositionErrorCallback& aCallback)
|
||||
nsGeolocationRequest::nsGeolocationRequest(Geolocation* aLocator,
|
||||
const GeoPositionCallback& aCallback,
|
||||
const GeoPositionErrorCallback& aErrorCallback,
|
||||
idl::GeoPositionOptions* aOptions,
|
||||
PositionOptions* aOptions,
|
||||
bool aWatchPositionRequest,
|
||||
int32_t aWatchId)
|
||||
: mIsWatchPositionRequest(aWatchPositionRequest),
|
||||
@ -460,11 +459,11 @@ nsGeolocationRequest::Allow()
|
||||
|
||||
uint32_t maximumAge = 30 * PR_MSEC_PER_SEC;
|
||||
if (mOptions) {
|
||||
if (mOptions->maximumAge >= 0) {
|
||||
maximumAge = mOptions->maximumAge;
|
||||
if (mOptions->mMaximumAge >= 0) {
|
||||
maximumAge = mOptions->mMaximumAge;
|
||||
}
|
||||
}
|
||||
gs->SetHigherAccuracy(mOptions && mOptions->enableHighAccuracy);
|
||||
gs->SetHigherAccuracy(mOptions && mOptions->mEnableHighAccuracy);
|
||||
|
||||
bool canUseCache = lastPosition && maximumAge > 0 &&
|
||||
(PRTime(PR_Now() / PR_USEC_PER_MSEC) - maximumAge <=
|
||||
@ -497,7 +496,7 @@ nsGeolocationRequest::SetTimeoutTimer()
|
||||
}
|
||||
|
||||
int32_t timeout;
|
||||
if (mOptions && (timeout = mOptions->timeout) != 0) {
|
||||
if (mOptions && (timeout = mOptions->mTimeout) != 0) {
|
||||
|
||||
if (timeout < 0) {
|
||||
timeout = 0;
|
||||
@ -600,7 +599,7 @@ nsGeolocationRequest::Shutdown()
|
||||
|
||||
// This should happen last, to ensure that this request isn't taken into consideration
|
||||
// when deciding whether existing requests still require high accuracy.
|
||||
if (mOptions && mOptions->enableHighAccuracy) {
|
||||
if (mOptions && mOptions->mEnableHighAccuracy) {
|
||||
nsRefPtr<nsGeolocationService> gs = nsGeolocationService::GetGeolocationService();
|
||||
if (gs) {
|
||||
gs->SetHigherAccuracy(false);
|
||||
@ -1200,9 +1199,8 @@ Geolocation::GetCurrentPosition(PositionCallback& aCallback,
|
||||
GeoPositionCallback successCallback(&aCallback);
|
||||
GeoPositionErrorCallback errorCallback(aErrorCallback);
|
||||
|
||||
nsresult rv =
|
||||
GetCurrentPosition(successCallback, errorCallback,
|
||||
GeoPositionOptionsFromPositionOptions(aOptions));
|
||||
nsresult rv = GetCurrentPosition(successCallback, errorCallback,
|
||||
CreatePositionOptionsCopy(aOptions));
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
aRv.Throw(rv);
|
||||
@ -1214,7 +1212,7 @@ Geolocation::GetCurrentPosition(PositionCallback& aCallback,
|
||||
NS_IMETHODIMP
|
||||
Geolocation::GetCurrentPosition(nsIDOMGeoPositionCallback* aCallback,
|
||||
nsIDOMGeoPositionErrorCallback* aErrorCallback,
|
||||
idl::GeoPositionOptions* aOptions)
|
||||
PositionOptions* aOptions)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aCallback);
|
||||
|
||||
@ -1227,7 +1225,7 @@ Geolocation::GetCurrentPosition(nsIDOMGeoPositionCallback* aCallback,
|
||||
nsresult
|
||||
Geolocation::GetCurrentPosition(GeoPositionCallback& callback,
|
||||
GeoPositionErrorCallback& errorCallback,
|
||||
idl::GeoPositionOptions *options)
|
||||
PositionOptions *options)
|
||||
{
|
||||
if (mPendingCallbacks.Length() > MAX_GEO_REQUESTS_PER_WINDOW) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
@ -1289,9 +1287,8 @@ Geolocation::WatchPosition(PositionCallback& aCallback,
|
||||
GeoPositionCallback successCallback(&aCallback);
|
||||
GeoPositionErrorCallback errorCallback(aErrorCallback);
|
||||
|
||||
nsresult rv =
|
||||
WatchPosition(successCallback, errorCallback,
|
||||
GeoPositionOptionsFromPositionOptions(aOptions), &ret);
|
||||
nsresult rv = WatchPosition(successCallback, errorCallback,
|
||||
CreatePositionOptionsCopy(aOptions), &ret);
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
aRv.Throw(rv);
|
||||
@ -1303,7 +1300,7 @@ Geolocation::WatchPosition(PositionCallback& aCallback,
|
||||
NS_IMETHODIMP
|
||||
Geolocation::WatchPosition(nsIDOMGeoPositionCallback *aCallback,
|
||||
nsIDOMGeoPositionErrorCallback *aErrorCallback,
|
||||
idl::GeoPositionOptions *aOptions,
|
||||
PositionOptions *aOptions,
|
||||
int32_t* aRv)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aCallback);
|
||||
@ -1317,7 +1314,7 @@ Geolocation::WatchPosition(nsIDOMGeoPositionCallback *aCallback,
|
||||
nsresult
|
||||
Geolocation::WatchPosition(GeoPositionCallback& aCallback,
|
||||
GeoPositionErrorCallback& aErrorCallback,
|
||||
idl::GeoPositionOptions* aOptions,
|
||||
PositionOptions* aOptions,
|
||||
int32_t* aRv)
|
||||
{
|
||||
if (mWatchingCallbacks.Length() > MAX_GEO_REQUESTS_PER_WINDOW) {
|
||||
|
@ -176,8 +176,8 @@ private:
|
||||
|
||||
~Geolocation();
|
||||
|
||||
nsresult GetCurrentPosition(GeoPositionCallback& aCallback, GeoPositionErrorCallback& aErrorCallback, mozilla::idl::GeoPositionOptions* aOptions);
|
||||
nsresult WatchPosition(GeoPositionCallback& aCallback, GeoPositionErrorCallback& aErrorCallback, mozilla::idl::GeoPositionOptions* aOptions, int32_t* aRv);
|
||||
nsresult GetCurrentPosition(GeoPositionCallback& aCallback, GeoPositionErrorCallback& aErrorCallback, PositionOptions* aOptions);
|
||||
nsresult WatchPosition(GeoPositionCallback& aCallback, GeoPositionErrorCallback& aErrorCallback, PositionOptions* aOptions, int32_t* aRv);
|
||||
|
||||
bool RegisterRequestWithPrompt(nsGeolocationRequest* request);
|
||||
|
||||
|
@ -30,6 +30,7 @@
|
||||
|
||||
#include "DOMBindingInlines.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include "nsFocusManager.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "nsISimpleEnumerator.h"
|
||||
|
||||
#if DEBUG
|
||||
#include "nsIWebNavigation.h"
|
||||
|
@ -246,9 +246,7 @@ void nsRegion::Init()
|
||||
mRectListHead.prev = mRectListHead.next = &mRectListHead;
|
||||
mCurRect = &mRectListHead;
|
||||
mRectCount = 0;
|
||||
MOZ_ASSERT(mBoundRect.x == 0 && mBoundRect.y == 0 &&
|
||||
mBoundRect.width == 0 && mBoundRect.height == 0,
|
||||
"Caller must have initialized mBoundRect");
|
||||
mBoundRect.SetRect (0, 0, 0, 0);
|
||||
}
|
||||
|
||||
inline void nsRegion::InsertBefore (RgnRect* aNewRect, RgnRect* aRelativeRect)
|
||||
|
@ -477,10 +477,7 @@ jsd_GetValueProperty(JSDContext* jsdc, JSDValue* jsdval, JSString* nameStr)
|
||||
JSDProperty* jsdprop;
|
||||
JSDProperty* iter = NULL;
|
||||
JS::RootedObject obj(cx);
|
||||
unsigned attrs = 0;
|
||||
bool found;
|
||||
const jschar * nameChars;
|
||||
size_t nameLen;
|
||||
JS::RootedValue val(cx), nameval(cx);
|
||||
JS::RootedId nameid(cx);
|
||||
JS::RootedValue propId(cx);
|
||||
@ -504,24 +501,28 @@ jsd_GetValueProperty(JSDContext* jsdc, JSDValue* jsdval, JSString* nameStr)
|
||||
}
|
||||
/* Not found in property list, look it up explicitly */
|
||||
|
||||
nameval = STRING_TO_JSVAL(name);
|
||||
if(!JS_ValueToId(cx, nameval, nameid.address()))
|
||||
return NULL;
|
||||
|
||||
if(!(obj = JSVAL_TO_OBJECT(jsdval->val)))
|
||||
return NULL;
|
||||
|
||||
if (!(nameChars = JS_GetStringCharsZAndLength(cx, name, &nameLen)))
|
||||
return NULL;
|
||||
|
||||
JS::Rooted<JSPropertyDescriptor> desc(cx);
|
||||
{
|
||||
JSAutoCompartment ac(cx, obj);
|
||||
JS::RootedId id(cx, nameid);
|
||||
|
||||
JS_GetUCPropertyAttributes(cx, obj, nameChars, nameLen, &attrs, &found);
|
||||
if (!found)
|
||||
{
|
||||
if(!JS_WrapId(cx, id.address()))
|
||||
return NULL;
|
||||
if(!JS_GetOwnPropertyDescriptorById(cx, obj, id, 0, &desc))
|
||||
return NULL;
|
||||
if(!desc.object())
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JS_ClearPendingException(cx);
|
||||
|
||||
if(!JS_GetUCProperty(cx, obj, nameChars, nameLen, &val))
|
||||
if(!JS_GetPropertyById(cx, obj, id, &val))
|
||||
{
|
||||
if (JS_IsExceptionPending(cx))
|
||||
{
|
||||
@ -543,16 +544,13 @@ jsd_GetValueProperty(JSDContext* jsdc, JSDValue* jsdval, JSString* nameStr)
|
||||
}
|
||||
}
|
||||
|
||||
nameval = STRING_TO_JSVAL(name);
|
||||
if (!JS_ValueToId(cx, nameval, nameid.address()) ||
|
||||
!JS_IdToValue(cx, nameid, propId.address())) {
|
||||
if (!JS_IdToValue(cx, nameid, propId.address()))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
propAlias = JSVAL_NULL;
|
||||
propFlags |= (attrs & JSPROP_ENUMERATE) ? JSPD_ENUMERATE : 0
|
||||
| (attrs & JSPROP_READONLY) ? JSPD_READONLY : 0
|
||||
| (attrs & JSPROP_PERMANENT) ? JSPD_PERMANENT : 0;
|
||||
propFlags |= desc.isEnumerable() ? JSPD_ENUMERATE : 0
|
||||
| desc.isReadonly() ? JSPD_READONLY : 0
|
||||
| desc.isPermanent() ? JSPD_PERMANENT : 0;
|
||||
|
||||
return _newProperty(jsdc, propId, propValue, propAlias, propFlags, JSDPD_HINTED);
|
||||
}
|
||||
|
@ -373,10 +373,6 @@ typedef bool
|
||||
(* PropertyAttributesOp)(JSContext *cx, JS::HandleObject obj, JS::Handle<PropertyName*> name,
|
||||
unsigned *attrsp);
|
||||
typedef bool
|
||||
(* ElementAttributesOp)(JSContext *cx, JS::HandleObject obj, uint32_t index, unsigned *attrsp);
|
||||
typedef bool
|
||||
(* SpecialAttributesOp)(JSContext *cx, JS::HandleObject obj, HandleSpecialId sid, unsigned *attrsp);
|
||||
typedef bool
|
||||
(* DeletePropertyOp)(JSContext *cx, JS::HandleObject obj, JS::Handle<PropertyName*> name,
|
||||
bool *succeeded);
|
||||
typedef bool
|
||||
@ -468,13 +464,7 @@ struct ObjectOps
|
||||
StrictElementIdOp setElement;
|
||||
StrictSpecialIdOp setSpecial;
|
||||
GenericAttributesOp getGenericAttributes;
|
||||
PropertyAttributesOp getPropertyAttributes;
|
||||
ElementAttributesOp getElementAttributes;
|
||||
SpecialAttributesOp getSpecialAttributes;
|
||||
GenericAttributesOp setGenericAttributes;
|
||||
PropertyAttributesOp setPropertyAttributes;
|
||||
ElementAttributesOp setElementAttributes;
|
||||
SpecialAttributesOp setSpecialAttributes;
|
||||
DeletePropertyOp deleteProperty;
|
||||
DeleteElementOp deleteElement;
|
||||
DeleteSpecialOp deleteSpecial;
|
||||
@ -485,8 +475,7 @@ struct ObjectOps
|
||||
|
||||
#define JS_NULL_OBJECT_OPS \
|
||||
{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, \
|
||||
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, \
|
||||
NULL,NULL,NULL}
|
||||
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}
|
||||
|
||||
} // namespace js
|
||||
|
||||
|
@ -1664,13 +1664,7 @@ Class BinaryBlock::class_ = {
|
||||
BinaryBlock::obj_setElement,
|
||||
BinaryBlock::obj_setSpecial,
|
||||
BinaryBlock::obj_getGenericAttributes,
|
||||
BinaryBlock::obj_getPropertyAttributes,
|
||||
BinaryBlock::obj_getElementAttributes,
|
||||
BinaryBlock::obj_getSpecialAttributes,
|
||||
BinaryBlock::obj_setGenericAttributes,
|
||||
BinaryBlock::obj_setPropertyAttributes,
|
||||
BinaryBlock::obj_setElementAttributes,
|
||||
BinaryBlock::obj_setSpecialAttributes,
|
||||
BinaryBlock::obj_deleteProperty,
|
||||
BinaryBlock::obj_deleteElement,
|
||||
BinaryBlock::obj_deleteSpecial,
|
||||
@ -2204,33 +2198,6 @@ BinaryBlock::obj_getGenericAttributes(JSContext *cx, HandleObject obj,
|
||||
return JSObject::getGenericAttributes(cx, proto, id, attrsp);
|
||||
}
|
||||
|
||||
bool
|
||||
BinaryBlock::obj_getPropertyAttributes(JSContext *cx, HandleObject obj,
|
||||
HandlePropertyName name,
|
||||
unsigned *attrsp)
|
||||
{
|
||||
RootedId id(cx, NameToId(name));
|
||||
return obj_getGenericAttributes(cx, obj, id, attrsp);
|
||||
}
|
||||
|
||||
bool
|
||||
BinaryBlock::obj_getElementAttributes(JSContext *cx, HandleObject obj,
|
||||
uint32_t index, unsigned *attrsp)
|
||||
{
|
||||
RootedId id(cx);
|
||||
if (!IndexToId(cx, index, &id))
|
||||
return false;
|
||||
return obj_getGenericAttributes(cx, obj, id, attrsp);
|
||||
}
|
||||
|
||||
bool
|
||||
BinaryBlock::obj_getSpecialAttributes(JSContext *cx, HandleObject obj,
|
||||
HandleSpecialId sid, unsigned *attrsp)
|
||||
{
|
||||
RootedId id(cx, SPECIALID_TO_JSID(sid));
|
||||
return obj_getGenericAttributes(cx, obj, id, attrsp);
|
||||
}
|
||||
|
||||
static bool
|
||||
IsOwnId(JSContext *cx, HandleObject obj, HandleId id)
|
||||
{
|
||||
@ -2270,33 +2237,6 @@ BinaryBlock::obj_setGenericAttributes(JSContext *cx, HandleObject obj,
|
||||
return JSObject::setGenericAttributes(cx, proto, id, attrsp);
|
||||
}
|
||||
|
||||
bool
|
||||
BinaryBlock::obj_setPropertyAttributes(JSContext *cx, HandleObject obj,
|
||||
HandlePropertyName name,
|
||||
unsigned *attrsp)
|
||||
{
|
||||
RootedId id(cx, NameToId(name));
|
||||
return obj_setGenericAttributes(cx, obj, id, attrsp);
|
||||
}
|
||||
|
||||
bool
|
||||
BinaryBlock::obj_setElementAttributes(JSContext *cx, HandleObject obj,
|
||||
uint32_t index, unsigned *attrsp)
|
||||
{
|
||||
RootedId id(cx);
|
||||
if (!IndexToId(cx, index, &id))
|
||||
return false;
|
||||
return obj_setGenericAttributes(cx, obj, id, attrsp);
|
||||
}
|
||||
|
||||
bool
|
||||
BinaryBlock::obj_setSpecialAttributes(JSContext *cx, HandleObject obj,
|
||||
HandleSpecialId sid, unsigned *attrsp)
|
||||
{
|
||||
RootedId id(cx, SPECIALID_TO_JSID(sid));
|
||||
return obj_setGenericAttributes(cx, obj, id, attrsp);
|
||||
}
|
||||
|
||||
bool
|
||||
BinaryBlock::obj_deleteProperty(JSContext *cx, HandleObject obj,
|
||||
HandlePropertyName name, bool *succeeded)
|
||||
|
@ -181,21 +181,8 @@ class BinaryBlock
|
||||
|
||||
static bool obj_getGenericAttributes(JSContext *cx, HandleObject obj,
|
||||
HandleId id, unsigned *attrsp);
|
||||
static bool obj_getPropertyAttributes(JSContext *cx, HandleObject obj,
|
||||
HandlePropertyName name, unsigned *attrsp);
|
||||
static bool obj_getElementAttributes(JSContext *cx, HandleObject obj,
|
||||
uint32_t index, unsigned *attrsp);
|
||||
static bool obj_getSpecialAttributes(JSContext *cx, HandleObject obj,
|
||||
HandleSpecialId sid, unsigned *attrsp);
|
||||
|
||||
static bool obj_setGenericAttributes(JSContext *cx, HandleObject obj,
|
||||
HandleId id, unsigned *attrsp);
|
||||
static bool obj_setPropertyAttributes(JSContext *cx, HandleObject obj,
|
||||
HandlePropertyName name, unsigned *attrsp);
|
||||
static bool obj_setElementAttributes(JSContext *cx, HandleObject obj,
|
||||
uint32_t index, unsigned *attrsp);
|
||||
static bool obj_setSpecialAttributes(JSContext *cx, HandleObject obj,
|
||||
HandleSpecialId sid, unsigned *attrsp);
|
||||
|
||||
static bool obj_deleteProperty(JSContext *cx, HandleObject obj, HandlePropertyName name,
|
||||
bool *succeeded);
|
||||
|
@ -1652,6 +1652,11 @@ IonCompile(JSContext *cx, JSScript *script,
|
||||
IonSpewNewFunction(graph, builderScript);
|
||||
|
||||
if (!builder->build()) {
|
||||
if (cx->isExceptionPending()) {
|
||||
IonSpew(IonSpew_Abort, "Builder raised exception.");
|
||||
return AbortReason_Error;
|
||||
}
|
||||
|
||||
IonSpew(IonSpew_Abort, "Builder failed to build.");
|
||||
return builder->abortReason();
|
||||
}
|
||||
@ -1832,6 +1837,9 @@ Compile(JSContext *cx, HandleScript script, BaselineFrame *osrFrame, jsbytecode
|
||||
}
|
||||
|
||||
AbortReason reason = IonCompile(cx, script, osrFrame, osrPc, constructing, executionMode);
|
||||
if (reason == AbortReason_Error)
|
||||
return Method_Error;
|
||||
|
||||
if (reason == AbortReason_Disable)
|
||||
return Method_CantCompile;
|
||||
|
||||
|
@ -255,6 +255,7 @@ enum AbortReason {
|
||||
AbortReason_Alloc,
|
||||
AbortReason_Inlining,
|
||||
AbortReason_Disable,
|
||||
AbortReason_Error,
|
||||
AbortReason_NoAbort
|
||||
};
|
||||
|
||||
|
@ -3772,14 +3772,23 @@ IonBuilder::inlineScriptedCall(CallInfo &callInfo, JSFunction *target)
|
||||
AutoAccumulateExits aae(graph(), saveExits);
|
||||
|
||||
// Build the graph.
|
||||
JS_ASSERT(!cx->isExceptionPending());
|
||||
IonBuilder inlineBuilder(cx, &temp(), &graph(), &inspector, info, NULL,
|
||||
inliningDepth_ + 1, loopDepth_);
|
||||
if (!inlineBuilder.buildInline(this, outerResumePoint, callInfo)) {
|
||||
JS_ASSERT(calleeScript->hasAnalysis());
|
||||
if (cx->isExceptionPending()) {
|
||||
IonSpew(IonSpew_Abort, "Inline builder raised exception.");
|
||||
abortReason_ = AbortReason_Error;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Inlining the callee failed. Disable inlining the function
|
||||
if (inlineBuilder.abortReason_ == AbortReason_Disable)
|
||||
if (inlineBuilder.abortReason_ == AbortReason_Disable) {
|
||||
// Only mark callee as un-inlineable only if the inlining was aborted
|
||||
// for a non-exception reason.
|
||||
calleeScript->analysis()->setIonUninlineable();
|
||||
}
|
||||
|
||||
abortReason_ = AbortReason_Inlining;
|
||||
return false;
|
||||
@ -5565,9 +5574,20 @@ IonBuilder::jsop_initprop(HandlePropertyName name)
|
||||
if (!res)
|
||||
return false;
|
||||
|
||||
if (!shape || holder != templateObject ||
|
||||
PropertyWriteNeedsTypeBarrier(cx, current, &obj, name, &value))
|
||||
if (!shape || holder != templateObject) {
|
||||
// JSOP_NEWINIT becomes an MNewObject without preconfigured properties.
|
||||
MInitProp *init = MInitProp::New(obj, name, value);
|
||||
current->add(init);
|
||||
return resumeAfter(init);
|
||||
}
|
||||
|
||||
bool writeNeedsBarrier = false;
|
||||
if (!PropertyWriteNeedsTypeBarrier(cx, current, &obj, name, &value, /* canModify = */ true,
|
||||
&writeNeedsBarrier))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (writeNeedsBarrier) {
|
||||
// JSOP_NEWINIT becomes an MNewObject without preconfigured properties.
|
||||
MInitProp *init = MInitProp::New(obj, name, value);
|
||||
current->add(init);
|
||||
@ -6267,7 +6287,12 @@ IonBuilder::getStaticName(HandleObject staticObject, HandlePropertyName name, bo
|
||||
}
|
||||
|
||||
types::StackTypeSet *types = types::TypeScript::BytecodeTypes(script(), pc);
|
||||
bool barrier = PropertyReadNeedsTypeBarrier(cx, staticType, name, types);
|
||||
bool barrier;
|
||||
if (!PropertyReadNeedsTypeBarrier(cx, staticType, name, types, /* updateObserved = */ true,
|
||||
&barrier))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the property is permanent, a shape guard isn't necessary.
|
||||
|
||||
@ -6791,7 +6816,9 @@ IonBuilder::getElemTryCache(bool *emitted, MDefinition *obj, MDefinition *index)
|
||||
// Emit GetElementCache.
|
||||
|
||||
types::StackTypeSet *types = types::TypeScript::BytecodeTypes(script(), pc);
|
||||
bool barrier = PropertyReadNeedsTypeBarrier(cx, obj, NULL, types);
|
||||
bool barrier;
|
||||
if (!PropertyReadNeedsTypeBarrier(cx, obj, NULL, types, &barrier))
|
||||
return false;
|
||||
|
||||
// Always add a barrier if the index might be a string, so that the cache
|
||||
// can attach stubs for particular properties.
|
||||
@ -6835,10 +6862,14 @@ IonBuilder::jsop_getelem_dense(MDefinition *obj, MDefinition *index)
|
||||
// Indexed call on an element of an array. Populate the observed types
|
||||
// with any objects that could be in the array, to avoid extraneous
|
||||
// type barriers.
|
||||
AddObjectsForPropertyRead(cx, obj, NULL, types);
|
||||
if (!AddObjectsForPropertyRead(cx, obj, NULL, types))
|
||||
return false;
|
||||
}
|
||||
|
||||
bool barrier = PropertyReadNeedsTypeBarrier(cx, obj, NULL, types);
|
||||
bool barrier;
|
||||
if (!PropertyReadNeedsTypeBarrier(cx, obj, NULL, types, &barrier))
|
||||
return false;
|
||||
|
||||
bool needsHoleCheck = !ElementAccessIsPacked(cx, obj);
|
||||
|
||||
// Reads which are on holes in the object do not have to bail out if
|
||||
@ -7203,7 +7234,13 @@ IonBuilder::setElemTryDense(bool *emitted, MDefinition *object,
|
||||
|
||||
if (!ElementAccessIsDenseNative(object, index))
|
||||
return true;
|
||||
if (PropertyWriteNeedsTypeBarrier(cx, current, &object, NULL, &value))
|
||||
bool needsBarrier;
|
||||
if (!PropertyWriteNeedsTypeBarrier(cx, current, &object, NULL, &value, /* canModify = */ true,
|
||||
&needsBarrier))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (needsBarrier)
|
||||
return true;
|
||||
if (!object->resultTypeSet())
|
||||
return true;
|
||||
@ -7263,7 +7300,14 @@ IonBuilder::setElemTryCache(bool *emitted, MDefinition *object,
|
||||
if (!icInspect.sawDenseWrite())
|
||||
return true;
|
||||
|
||||
if (PropertyWriteNeedsTypeBarrier(cx, current, &object, NULL, &value))
|
||||
bool needsBarrier;
|
||||
if (PropertyWriteNeedsTypeBarrier(cx, current, &object, NULL, &value, /* canModify = */ true,
|
||||
&needsBarrier))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (needsBarrier)
|
||||
return true;
|
||||
|
||||
// Emit SetElementCache.
|
||||
@ -7283,7 +7327,10 @@ IonBuilder::jsop_setelem_dense(types::StackTypeSet::DoubleConversion conversion,
|
||||
SetElemSafety safety,
|
||||
MDefinition *obj, MDefinition *id, MDefinition *value)
|
||||
{
|
||||
MIRType elementType = DenseNativeElementType(cx, obj);
|
||||
MIRType elementType;
|
||||
if (!DenseNativeElementType(cx, obj, &elementType))
|
||||
return false;
|
||||
|
||||
bool packed = ElementAccessIsPacked(cx, obj);
|
||||
|
||||
// Writes which are on holes in the object do not have to bail out if they
|
||||
@ -8100,7 +8147,9 @@ IonBuilder::jsop_getprop(HandlePropertyName name)
|
||||
if (!getPropTryArgumentsLength(&emitted) || emitted)
|
||||
return emitted;
|
||||
|
||||
bool barrier = PropertyReadNeedsTypeBarrier(cx, current->peek(-1), name, types);
|
||||
bool barrier;
|
||||
if (!PropertyReadNeedsTypeBarrier(cx, current->peek(-1), name, types, &barrier))
|
||||
return false;
|
||||
|
||||
// Try to hardcode known constants.
|
||||
if (!getPropTryConstant(&emitted, id, types) || emitted)
|
||||
@ -8405,7 +8454,11 @@ IonBuilder::getPropTryCache(bool *emitted, HandlePropertyName name, HandleId id,
|
||||
if (obj->type() == MIRType_Object && !invalidatedIdempotentCache() &&
|
||||
info().executionMode() != ParallelExecution)
|
||||
{
|
||||
if (PropertyReadIsIdempotent(cx, obj, name))
|
||||
bool idempotent;
|
||||
if (!PropertyReadIsIdempotent(cx, obj, name, &idempotent))
|
||||
return false;
|
||||
|
||||
if (idempotent)
|
||||
load->setIdempotent();
|
||||
}
|
||||
|
||||
@ -8480,7 +8533,12 @@ IonBuilder::jsop_setprop(HandlePropertyName name)
|
||||
return emitted;
|
||||
|
||||
types::StackTypeSet *objTypes = obj->resultTypeSet();
|
||||
bool barrier = PropertyWriteNeedsTypeBarrier(cx, current, &obj, name, &value);
|
||||
bool barrier;
|
||||
if (!PropertyWriteNeedsTypeBarrier(cx, current, &obj, name, &value,
|
||||
/* canModify = */ true, &barrier))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Try to emit store from definite slots.
|
||||
if (!setPropTryDefiniteSlot(&emitted, obj, name, value, barrier, objTypes) || emitted)
|
||||
|
@ -323,7 +323,10 @@ IonBuilder::inlineArrayPopShift(CallInfo &callInfo, MArrayPopShift::Mode mode)
|
||||
bool needsHoleCheck = thisTypes->hasObjectFlags(cx, types::OBJECT_FLAG_NON_PACKED);
|
||||
bool maybeUndefined = returnTypes->hasType(types::Type::UndefinedType());
|
||||
|
||||
bool barrier = PropertyReadNeedsTypeBarrier(cx, callInfo.thisArg(), NULL, returnTypes);
|
||||
bool barrier;
|
||||
if (!PropertyReadNeedsTypeBarrier(cx, callInfo.thisArg(), NULL, returnTypes, &barrier))
|
||||
return InliningStatus_Error;
|
||||
|
||||
if (barrier)
|
||||
returnType = MIRType_Value;
|
||||
|
||||
@ -350,7 +353,13 @@ IonBuilder::inlineArrayPush(CallInfo &callInfo)
|
||||
|
||||
MDefinition *obj = callInfo.thisArg();
|
||||
MDefinition *value = callInfo.getArg(0);
|
||||
if (PropertyWriteNeedsTypeBarrier(cx, current, &obj, NULL, &value, /* canModify = */ false))
|
||||
bool writeNeedsBarrier;
|
||||
if (!PropertyWriteNeedsTypeBarrier(cx, current, &obj, NULL, &value, /* canModify = */ false,
|
||||
&writeNeedsBarrier))
|
||||
{
|
||||
return InliningStatus_Error;
|
||||
}
|
||||
if (writeNeedsBarrier)
|
||||
return InliningStatus_NotInlined;
|
||||
JS_ASSERT(obj == callInfo.thisArg() && value == callInfo.getArg(0));
|
||||
|
||||
@ -1002,12 +1011,22 @@ IonBuilder::inlineUnsafePutElements(CallInfo &callInfo)
|
||||
MDefinition *id = callInfo.getArg(idxi);
|
||||
MDefinition *elem = callInfo.getArg(elemi);
|
||||
|
||||
bool isDenseNative = ElementAccessIsDenseNative(obj, id);
|
||||
|
||||
bool writeNeedsBarrier = false;
|
||||
if (isDenseNative) {
|
||||
if (!PropertyWriteNeedsTypeBarrier(cx, current, &obj, NULL, &elem,
|
||||
/* canModify = */ false,
|
||||
&writeNeedsBarrier))
|
||||
{
|
||||
return InliningStatus_Error;
|
||||
}
|
||||
}
|
||||
|
||||
// We can only inline setelem on dense arrays that do not need type
|
||||
// barriers and on typed arrays.
|
||||
ScalarTypeRepresentation::Type arrayType;
|
||||
if ((!ElementAccessIsDenseNative(obj, id) ||
|
||||
PropertyWriteNeedsTypeBarrier(cx, current, &obj, NULL,
|
||||
&elem, /* canModify = */ false)) &&
|
||||
if ((!isDenseNative || writeNeedsBarrier) &&
|
||||
!ElementAccessIsTypedArray(obj, id, &arrayType))
|
||||
{
|
||||
return InliningStatus_NotInlined;
|
||||
|
@ -2530,48 +2530,61 @@ jit::ElementAccessHasExtraIndexedProperty(JSContext *cx, MDefinition *obj)
|
||||
return types::TypeCanHaveExtraIndexedProperties(cx, types);
|
||||
}
|
||||
|
||||
MIRType
|
||||
jit::DenseNativeElementType(JSContext *cx, MDefinition *obj)
|
||||
bool
|
||||
jit::DenseNativeElementType(JSContext *cx, MDefinition *obj, MIRType *result)
|
||||
{
|
||||
JS_ASSERT(result);
|
||||
*result = MIRType_None;
|
||||
|
||||
types::StackTypeSet *types = obj->resultTypeSet();
|
||||
MIRType elementType = MIRType_None;
|
||||
unsigned count = types->getObjectCount();
|
||||
|
||||
for (unsigned i = 0; i < count; i++) {
|
||||
if (types::TypeObject *object = types->getTypeOrSingleObject(cx, i)) {
|
||||
if (object->unknownProperties())
|
||||
return MIRType_None;
|
||||
types::TypeObject *object;
|
||||
if (!types->getTypeOrSingleObject(cx, i, &object))
|
||||
return false;
|
||||
|
||||
types::HeapTypeSet *elementTypes = object->getProperty(cx, JSID_VOID, false);
|
||||
if (!elementTypes)
|
||||
return MIRType_None;
|
||||
if (!object)
|
||||
continue;
|
||||
|
||||
MIRType type = MIRTypeFromValueType(elementTypes->getKnownTypeTag(cx));
|
||||
if (type == MIRType_None)
|
||||
return MIRType_None;
|
||||
if (object->unknownProperties())
|
||||
return true;
|
||||
|
||||
if (elementType == MIRType_None)
|
||||
elementType = type;
|
||||
else if (elementType != type)
|
||||
return MIRType_None;
|
||||
}
|
||||
types::HeapTypeSet *elementTypes = object->getProperty(cx, JSID_VOID, false);
|
||||
if (!elementTypes)
|
||||
return true;
|
||||
|
||||
MIRType type = MIRTypeFromValueType(elementTypes->getKnownTypeTag(cx));
|
||||
if (type == MIRType_None)
|
||||
return true;
|
||||
|
||||
if (elementType == MIRType_None)
|
||||
elementType = type;
|
||||
else if (elementType != type)
|
||||
return true;
|
||||
}
|
||||
|
||||
return elementType;
|
||||
*result = elementType;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
jit::PropertyReadNeedsTypeBarrier(JSContext *cx, types::TypeObject *object, PropertyName *name,
|
||||
types::StackTypeSet *observed, bool updateObserved)
|
||||
types::StackTypeSet *observed, bool updateObserved, bool *result)
|
||||
{
|
||||
// If the object being read from has types for the property which haven't
|
||||
// been observed at this access site, the read could produce a new type and
|
||||
// a barrier is needed. Note that this only covers reads from properties
|
||||
// which are accounted for by type information, i.e. native data properties
|
||||
// and elements.
|
||||
JS_ASSERT(result);
|
||||
*result = false;
|
||||
|
||||
if (object->unknownProperties())
|
||||
if (object->unknownProperties()) {
|
||||
*result = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
jsid id = name ? types::IdToTypeId(NameToId(name)) : JSID_VOID;
|
||||
|
||||
@ -2596,8 +2609,10 @@ jit::PropertyReadNeedsTypeBarrier(JSContext *cx, types::TypeObject *object, Prop
|
||||
}
|
||||
|
||||
types::HeapTypeSet *property = object->getProperty(cx, id, false);
|
||||
if (!property)
|
||||
if (!property) {
|
||||
*result = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
// We need to consider possible types for the property both as an 'own'
|
||||
// property on the object and as inherited from any prototype. Type sets
|
||||
@ -2606,8 +2621,10 @@ jit::PropertyReadNeedsTypeBarrier(JSContext *cx, types::TypeObject *object, Prop
|
||||
if (!property->hasPropagatedProperty())
|
||||
object->getFromPrototypes(cx, id, property);
|
||||
|
||||
if (!TypeSetIncludes(observed, MIRType_Value, property))
|
||||
if (!TypeSetIncludes(observed, MIRType_Value, property)) {
|
||||
*result = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Type information for singleton objects is not required to reflect the
|
||||
// initial 'undefined' value for native properties, in particular global
|
||||
@ -2619,62 +2636,85 @@ jit::PropertyReadNeedsTypeBarrier(JSContext *cx, types::TypeObject *object, Prop
|
||||
shape->hasDefaultGetter() &&
|
||||
object->singleton->nativeGetSlot(shape->slot()).isUndefined())
|
||||
{
|
||||
*result = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
property->addFreeze(cx);
|
||||
return false;
|
||||
*result = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
jit::PropertyReadNeedsTypeBarrier(JSContext *cx, MDefinition *obj, PropertyName *name,
|
||||
types::StackTypeSet *observed)
|
||||
types::StackTypeSet *observed, bool *result)
|
||||
{
|
||||
JS_ASSERT(result);
|
||||
*result = false;
|
||||
|
||||
if (observed->unknown())
|
||||
return false;
|
||||
return true;
|
||||
|
||||
types::TypeSet *types = obj->resultTypeSet();
|
||||
if (!types || types->unknownObject())
|
||||
if (!types || types->unknownObject()) {
|
||||
*result = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool updateObserved = types->getObjectCount() == 1;
|
||||
for (size_t i = 0; i < types->getObjectCount(); i++) {
|
||||
types::TypeObject *object = types->getTypeOrSingleObject(cx, i);
|
||||
if (object && PropertyReadNeedsTypeBarrier(cx, object, name, observed, updateObserved))
|
||||
return true;
|
||||
types::TypeObject *object;
|
||||
if (!types->getTypeOrSingleObject(cx, i, &object))
|
||||
return false;
|
||||
|
||||
if (object) {
|
||||
if (!PropertyReadNeedsTypeBarrier(cx, object, name, observed, updateObserved, result))
|
||||
return false;
|
||||
|
||||
if (*result)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
*result = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
jit::PropertyReadIsIdempotent(JSContext *cx, MDefinition *obj, PropertyName *name)
|
||||
jit::PropertyReadIsIdempotent(JSContext *cx, MDefinition *obj, PropertyName *name, bool *result)
|
||||
{
|
||||
JS_ASSERT(result);
|
||||
*result = false;
|
||||
// Determine if reading a property from obj is likely to be idempotent.
|
||||
|
||||
jsid id = types::IdToTypeId(NameToId(name));
|
||||
|
||||
types::TypeSet *types = obj->resultTypeSet();
|
||||
if (!types || types->unknownObject())
|
||||
return false;
|
||||
return true;
|
||||
|
||||
for (size_t i = 0; i < types->getObjectCount(); i++) {
|
||||
if (types::TypeObject *object = types->getTypeOrSingleObject(cx, i)) {
|
||||
types::TypeObject *object;
|
||||
if (!types->getTypeOrSingleObject(cx, i, &object))
|
||||
return false;
|
||||
|
||||
if (object) {
|
||||
if (object->unknownProperties())
|
||||
return false;
|
||||
return true;
|
||||
|
||||
// Check if the property has been reconfigured or is a getter.
|
||||
types::HeapTypeSet *property = object->getProperty(cx, id, false);
|
||||
if (!property || property->isOwnProperty(cx, object, true))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
*result = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
bool
|
||||
jit::AddObjectsForPropertyRead(JSContext *cx, MDefinition *obj, PropertyName *name,
|
||||
types::StackTypeSet *observed)
|
||||
{
|
||||
@ -2686,25 +2726,28 @@ jit::AddObjectsForPropertyRead(JSContext *cx, MDefinition *obj, PropertyName *na
|
||||
types::StackTypeSet *types = obj->resultTypeSet();
|
||||
if (!types || types->unknownObject()) {
|
||||
observed->addType(cx, types::Type::AnyObjectType());
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
jsid id = name ? types::IdToTypeId(NameToId(name)) : JSID_VOID;
|
||||
|
||||
for (size_t i = 0; i < types->getObjectCount(); i++) {
|
||||
types::TypeObject *object = types->getTypeOrSingleObject(cx, i);
|
||||
types::TypeObject *object;
|
||||
if (!types->getTypeOrSingleObject(cx, i, &object))
|
||||
return false;
|
||||
|
||||
if (!object)
|
||||
continue;
|
||||
|
||||
if (object->unknownProperties()) {
|
||||
observed->addType(cx, types::Type::AnyObjectType());
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
types::HeapTypeSet *property = object->getProperty(cx, id, false);
|
||||
if (property->unknownObject()) {
|
||||
observed->addType(cx, types::Type::AnyObjectType());
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < property->getObjectCount(); i++) {
|
||||
@ -2714,6 +2757,8 @@ jit::AddObjectsForPropertyRead(JSContext *cx, MDefinition *obj, PropertyName *na
|
||||
observed->addType(cx, types::Type::ObjectType(object));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
@ -2730,7 +2775,10 @@ TryAddTypeBarrierForWrite(JSContext *cx, MBasicBlock *current, types::StackTypeS
|
||||
types::HeapTypeSet *aggregateProperty = NULL;
|
||||
|
||||
for (size_t i = 0; i < objTypes->getObjectCount(); i++) {
|
||||
types::TypeObject *object = objTypes->getTypeOrSingleObject(cx, i);
|
||||
types::TypeObject *object;
|
||||
if (!objTypes->getTypeOrSingleObject(cx, i, &object))
|
||||
return false;
|
||||
|
||||
if (!object)
|
||||
continue;
|
||||
|
||||
@ -2808,8 +2856,12 @@ AddTypeGuard(MBasicBlock *current, MDefinition *obj, types::TypeObject *typeObje
|
||||
|
||||
bool
|
||||
jit::PropertyWriteNeedsTypeBarrier(JSContext *cx, MBasicBlock *current, MDefinition **pobj,
|
||||
PropertyName *name, MDefinition **pvalue, bool canModify)
|
||||
PropertyName *name, MDefinition **pvalue, bool canModify,
|
||||
bool *result)
|
||||
{
|
||||
JS_ASSERT(result);
|
||||
*result = false;
|
||||
|
||||
// If any value being written is not reflected in the type information for
|
||||
// objects which obj could represent, a type barrier is needed when writing
|
||||
// the value. As for propertyReadNeedsTypeBarrier, this only applies for
|
||||
@ -2817,8 +2869,10 @@ jit::PropertyWriteNeedsTypeBarrier(JSContext *cx, MBasicBlock *current, MDefinit
|
||||
// properties and elements.
|
||||
|
||||
types::StackTypeSet *types = (*pobj)->resultTypeSet();
|
||||
if (!types || types->unknownObject())
|
||||
if (!types || types->unknownObject()) {
|
||||
*result = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
jsid id = name ? types::IdToTypeId(NameToId(name)) : JSID_VOID;
|
||||
|
||||
@ -2829,7 +2883,10 @@ jit::PropertyWriteNeedsTypeBarrier(JSContext *cx, MBasicBlock *current, MDefinit
|
||||
|
||||
bool success = true;
|
||||
for (size_t i = 0; i < types->getObjectCount(); i++) {
|
||||
types::TypeObject *object = types->getTypeOrSingleObject(cx, i);
|
||||
types::TypeObject *object;
|
||||
if (!types->getTypeOrSingleObject(cx, i, &object))
|
||||
return false;
|
||||
|
||||
if (!object || object->unknownProperties())
|
||||
continue;
|
||||
|
||||
@ -2843,43 +2900,54 @@ jit::PropertyWriteNeedsTypeBarrier(JSContext *cx, MBasicBlock *current, MDefinit
|
||||
// types which the value could have but are not in the property,
|
||||
// or a VM call is required. A VM call is always required if pobj
|
||||
// and pvalue cannot be modified.
|
||||
if (!canModify)
|
||||
if (!canModify) {
|
||||
*result = true;
|
||||
return true;
|
||||
}
|
||||
success = TryAddTypeBarrierForWrite(cx, current, types, id, pvalue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (success)
|
||||
return false;
|
||||
return true;
|
||||
|
||||
// If all of the objects except one have property types which reflect the
|
||||
// value, and the remaining object has no types at all for the property,
|
||||
// add a guard that the object does not have that remaining object's type.
|
||||
|
||||
if (types->getObjectCount() <= 1)
|
||||
if (types->getObjectCount() <= 1) {
|
||||
*result = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
types::TypeObject *excluded = NULL;
|
||||
for (size_t i = 0; i < types->getObjectCount(); i++) {
|
||||
types::TypeObject *object = types->getTypeOrSingleObject(cx, i);
|
||||
types::TypeObject *object;
|
||||
if (!types->getTypeOrSingleObject(cx, i, &object))
|
||||
return false;
|
||||
|
||||
if (!object || object->unknownProperties())
|
||||
continue;
|
||||
|
||||
types::HeapTypeSet *property = object->getProperty(cx, id, false);
|
||||
if (!property)
|
||||
if (!property) {
|
||||
*result = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (TypeSetIncludes(property, (*pvalue)->type(), (*pvalue)->resultTypeSet()))
|
||||
continue;
|
||||
|
||||
if (!property->empty() || excluded)
|
||||
if (!property->empty() || excluded) {
|
||||
*result = true;
|
||||
return true;
|
||||
}
|
||||
excluded = object;
|
||||
}
|
||||
|
||||
JS_ASSERT(excluded);
|
||||
|
||||
*pobj = AddTypeGuard(current, *pobj, excluded, /* bailOnEquality = */ true);
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
@ -8510,17 +8510,17 @@ bool ElementAccessIsTypedArray(MDefinition *obj, MDefinition *id,
|
||||
ScalarTypeRepresentation::Type *arrayType);
|
||||
bool ElementAccessIsPacked(JSContext *cx, MDefinition *obj);
|
||||
bool ElementAccessHasExtraIndexedProperty(JSContext *cx, MDefinition *obj);
|
||||
MIRType DenseNativeElementType(JSContext *cx, MDefinition *obj);
|
||||
bool DenseNativeElementType(JSContext *cx, MDefinition *obj, MIRType *result);
|
||||
bool PropertyReadNeedsTypeBarrier(JSContext *cx, types::TypeObject *object, PropertyName *name,
|
||||
types::StackTypeSet *observed, bool updateObserved = true);
|
||||
types::StackTypeSet *observed, bool updateObserved, bool *result);
|
||||
bool PropertyReadNeedsTypeBarrier(JSContext *cx, MDefinition *obj, PropertyName *name,
|
||||
types::StackTypeSet *observed);
|
||||
bool PropertyReadIsIdempotent(JSContext *cx, MDefinition *obj, PropertyName *name);
|
||||
void AddObjectsForPropertyRead(JSContext *cx, MDefinition *obj, PropertyName *name,
|
||||
types::StackTypeSet *observed, bool *result);
|
||||
bool PropertyReadIsIdempotent(JSContext *cx, MDefinition *obj, PropertyName *name, bool *result);
|
||||
bool AddObjectsForPropertyRead(JSContext *cx, MDefinition *obj, PropertyName *name,
|
||||
types::StackTypeSet *observed);
|
||||
bool PropertyWriteNeedsTypeBarrier(JSContext *cx, MBasicBlock *current, MDefinition **pobj,
|
||||
PropertyName *name, MDefinition **pvalue,
|
||||
bool canModify = true);
|
||||
bool canModify, bool *result);
|
||||
|
||||
} // namespace jit
|
||||
} // namespace js
|
||||
|
@ -45,14 +45,13 @@ BEGIN_TEST(testDefineGetterSetterNonEnumerable)
|
||||
JS_DATA_TO_FUNC_PTR(JSStrictPropertyOp, (JSObject*) funSetObj),
|
||||
JSPROP_GETTER | JSPROP_SETTER | JSPROP_PERMANENT));
|
||||
|
||||
bool found = false;
|
||||
unsigned attrs = 0;
|
||||
CHECK(JS_GetPropertyAttributes(cx, vObject, PROPERTY_NAME, &attrs, &found));
|
||||
CHECK(found);
|
||||
CHECK(attrs & JSPROP_GETTER);
|
||||
CHECK(attrs & JSPROP_SETTER);
|
||||
CHECK(attrs & JSPROP_PERMANENT);
|
||||
CHECK(!(attrs & JSPROP_ENUMERATE));
|
||||
JS::Rooted<JSPropertyDescriptor> desc(cx);
|
||||
CHECK(JS_GetOwnPropertyDescriptor(cx, vObject, PROPERTY_NAME, 0, &desc));
|
||||
CHECK(desc.object());
|
||||
CHECK(desc.hasGetterObject());
|
||||
CHECK(desc.hasSetterObject());
|
||||
CHECK(desc.isPermanent());
|
||||
CHECK(!desc.isEnumerable());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
133
js/src/jsapi.cpp
133
js/src/jsapi.cpp
@ -3633,6 +3633,27 @@ GetPropertyDescriptorById(JSContext *cx, HandleObject obj, HandleId id, unsigned
|
||||
return true;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_GetOwnPropertyDescriptorById(JSContext *cx, JSObject *objArg, jsid idArg, unsigned flags,
|
||||
MutableHandle<JSPropertyDescriptor> desc)
|
||||
{
|
||||
RootedObject obj(cx, objArg);
|
||||
RootedId id(cx, idArg);
|
||||
AssertHeapIsIdle(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
|
||||
return GetPropertyDescriptorById(cx, obj, id, flags, true, desc);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_GetOwnPropertyDescriptor(JSContext *cx, JSObject *objArg, const char *name, unsigned flags,
|
||||
MutableHandle<JSPropertyDescriptor> desc)
|
||||
{
|
||||
RootedObject obj(cx, objArg);
|
||||
JSAtom *atom = Atomize(cx, name, strlen(name));
|
||||
return atom && JS_GetOwnPropertyDescriptorById(cx, obj, AtomToId(atom), flags, desc);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_GetPropertyDescriptorById(JSContext *cx, JSObject *objArg, jsid idArg, unsigned flags,
|
||||
MutableHandle<JSPropertyDescriptor> desc)
|
||||
@ -3643,117 +3664,12 @@ JS_GetPropertyDescriptorById(JSContext *cx, JSObject *objArg, jsid idArg, unsign
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_GetPropertyAttrsGetterAndSetterById(JSContext *cx, JSObject *objArg, jsid idArg,
|
||||
unsigned *attrsp, bool *foundp,
|
||||
JSPropertyOp *getterp, JSStrictPropertyOp *setterp)
|
||||
{
|
||||
RootedObject obj(cx, objArg);
|
||||
RootedId id(cx, idArg);
|
||||
Rooted<PropertyDescriptor> desc(cx);
|
||||
if (!GetPropertyDescriptorById(cx, obj, id, 0, false, &desc))
|
||||
return false;
|
||||
|
||||
*attrsp = desc.attributes();
|
||||
*foundp = !!desc.object();
|
||||
if (getterp)
|
||||
*getterp = desc.getter();
|
||||
if (setterp)
|
||||
*setterp = desc.setter();
|
||||
return true;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_GetPropertyAttributes(JSContext *cx, JSObject *objArg, const char *name,
|
||||
unsigned *attrsp, bool *foundp)
|
||||
JS_GetPropertyDescriptor(JSContext *cx, JSObject *objArg, const char *name, unsigned flags,
|
||||
MutableHandle<JSPropertyDescriptor> desc)
|
||||
{
|
||||
RootedObject obj(cx, objArg);
|
||||
JSAtom *atom = Atomize(cx, name, strlen(name));
|
||||
return atom && JS_GetPropertyAttrsGetterAndSetterById(cx, obj, AtomToId(atom),
|
||||
attrsp, foundp, NULL, NULL);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_GetUCPropertyAttributes(JSContext *cx, JSObject *objArg, const jschar *name, size_t namelen,
|
||||
unsigned *attrsp, bool *foundp)
|
||||
{
|
||||
RootedObject obj(cx, objArg);
|
||||
JSAtom *atom = AtomizeChars<CanGC>(cx, name, AUTO_NAMELEN(name, namelen));
|
||||
return atom && JS_GetPropertyAttrsGetterAndSetterById(cx, obj, AtomToId(atom),
|
||||
attrsp, foundp, NULL, NULL);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_GetPropertyAttrsGetterAndSetter(JSContext *cx, JSObject *objArg, const char *name,
|
||||
unsigned *attrsp, bool *foundp,
|
||||
JSPropertyOp *getterp, JSStrictPropertyOp *setterp)
|
||||
{
|
||||
RootedObject obj(cx, objArg);
|
||||
JSAtom *atom = Atomize(cx, name, strlen(name));
|
||||
return atom && JS_GetPropertyAttrsGetterAndSetterById(cx, obj, AtomToId(atom),
|
||||
attrsp, foundp, getterp, setterp);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_GetUCPropertyAttrsGetterAndSetter(JSContext *cx, JSObject *objArg,
|
||||
const jschar *name, size_t namelen,
|
||||
unsigned *attrsp, bool *foundp,
|
||||
JSPropertyOp *getterp, JSStrictPropertyOp *setterp)
|
||||
{
|
||||
RootedObject obj(cx, objArg);
|
||||
JSAtom *atom = AtomizeChars<CanGC>(cx, name, AUTO_NAMELEN(name, namelen));
|
||||
return atom && JS_GetPropertyAttrsGetterAndSetterById(cx, obj, AtomToId(atom),
|
||||
attrsp, foundp, getterp, setterp);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_GetOwnPropertyDescriptor(JSContext *cx, JSObject *objArg, jsid idArg, MutableHandleValue vp)
|
||||
{
|
||||
RootedObject obj(cx, objArg);
|
||||
RootedId id(cx, idArg);
|
||||
AssertHeapIsIdle(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
|
||||
return GetOwnPropertyDescriptor(cx, obj, id, vp);
|
||||
}
|
||||
|
||||
static bool
|
||||
SetPropertyAttributesById(JSContext *cx, HandleObject obj, HandleId id, unsigned attrs, bool *foundp)
|
||||
{
|
||||
RootedObject obj2(cx);
|
||||
RootedShape shape(cx);
|
||||
|
||||
if (!LookupPropertyById(cx, obj, id, 0, &obj2, &shape))
|
||||
return false;
|
||||
if (!shape || obj != obj2) {
|
||||
*foundp = false;
|
||||
return true;
|
||||
}
|
||||
bool ok = obj->isNative()
|
||||
? JSObject::changePropertyAttributes(cx, obj, shape, attrs)
|
||||
: JSObject::setGenericAttributes(cx, obj, id, &attrs);
|
||||
if (ok)
|
||||
*foundp = true;
|
||||
return ok;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_SetPropertyAttributes(JSContext *cx, JSObject *objArg, const char *name,
|
||||
unsigned attrs, bool *foundp)
|
||||
{
|
||||
RootedObject obj(cx, objArg);
|
||||
JSAtom *atom = Atomize(cx, name, strlen(name));
|
||||
RootedId id(cx, AtomToId(atom));
|
||||
return atom && SetPropertyAttributesById(cx, obj, id, attrs, foundp);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_SetUCPropertyAttributes(JSContext *cx, JSObject *objArg, const jschar *name, size_t namelen,
|
||||
unsigned attrs, bool *foundp)
|
||||
{
|
||||
RootedObject obj(cx, objArg);
|
||||
JSAtom *atom = AtomizeChars<CanGC>(cx, name, AUTO_NAMELEN(name, namelen));
|
||||
RootedId id(cx, AtomToId(atom));
|
||||
return atom && SetPropertyAttributesById(cx, obj, id, attrs, foundp);
|
||||
return atom && JS_GetPropertyDescriptorById(cx, obj, AtomToId(atom), flags, desc);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
@ -6664,4 +6580,3 @@ JS_PreventExtensions(JSContext *cx, JS::HandleObject obj)
|
||||
return true;
|
||||
return JSObject::preventExtensions(cx, obj);
|
||||
}
|
||||
|
||||
|
@ -2791,45 +2791,6 @@ JS_DefinePropertyById(JSContext *cx, JSObject *obj, jsid id, jsval value,
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_DefineOwnProperty(JSContext *cx, JSObject *obj, jsid id, jsval descriptor, bool *bp);
|
||||
|
||||
/*
|
||||
* Determine the attributes (JSPROP_* flags) of a property on a given object.
|
||||
*
|
||||
* If the object does not have a property by that name, *foundp will be
|
||||
* false and the value of *attrsp is undefined.
|
||||
*/
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_GetPropertyAttributes(JSContext *cx, JSObject *obj, const char *name,
|
||||
unsigned *attrsp, bool *foundp);
|
||||
|
||||
/*
|
||||
* The same, but if the property is native, return its getter and setter via
|
||||
* *getterp and *setterp, respectively (and only if the out parameter pointer
|
||||
* is not null).
|
||||
*/
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_GetPropertyAttrsGetterAndSetter(JSContext *cx, JSObject *obj,
|
||||
const char *name,
|
||||
unsigned *attrsp, bool *foundp,
|
||||
JSPropertyOp *getterp,
|
||||
JSStrictPropertyOp *setterp);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_GetPropertyAttrsGetterAndSetterById(JSContext *cx, JSObject *obj,
|
||||
jsid id,
|
||||
unsigned *attrsp, bool *foundp,
|
||||
JSPropertyOp *getterp,
|
||||
JSStrictPropertyOp *setterp);
|
||||
|
||||
/*
|
||||
* Set the attributes of a property on a given object.
|
||||
*
|
||||
* If the object does not have a property by that name, *foundp will be
|
||||
* false and nothing will be altered.
|
||||
*/
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_SetPropertyAttributes(JSContext *cx, JSObject *obj, const char *name,
|
||||
unsigned attrs, bool *foundp);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_DefinePropertyWithTinyId(JSContext *cx, JSObject *obj, const char *name,
|
||||
int8_t tinyid, jsval value,
|
||||
@ -3013,9 +2974,17 @@ class MutableHandleBase<JSPropertyDescriptor>
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_GetOwnPropertyDescriptorById(JSContext *cx, JSObject *objArg, jsid id, unsigned flags,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_GetOwnPropertyDescriptor(JSContext *cx, JSObject *objArg, const char *name, unsigned flags,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc);
|
||||
|
||||
/*
|
||||
* Like JS_GetPropertyAttrsGetterAndSetterById but will return a property on
|
||||
* an object on the prototype chain (returned in objp). If data->obj is null,
|
||||
* Like JS_GetOwnPropertyDescriptorById but will return a property on
|
||||
* an object on the prototype chain (returned in desc->obj). If desc->obj is null,
|
||||
* then this property was not found on the prototype chain.
|
||||
*/
|
||||
extern JS_PUBLIC_API(bool)
|
||||
@ -3023,7 +2992,8 @@ JS_GetPropertyDescriptorById(JSContext *cx, JSObject *obj, jsid id, unsigned fla
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_GetOwnPropertyDescriptor(JSContext *cx, JSObject *obj, jsid id, JS::MutableHandle<JS::Value> vp);
|
||||
JS_GetPropertyDescriptor(JSContext *cx, JSObject *obj, const char *name, unsigned flags,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_GetProperty(JSContext *cx, JSObject *obj, const char *name, JS::MutableHandle<JS::Value> vp);
|
||||
@ -3067,41 +3037,6 @@ JS_DefineUCProperty(JSContext *cx, JSObject *obj,
|
||||
JSPropertyOp getter, JSStrictPropertyOp setter,
|
||||
unsigned attrs);
|
||||
|
||||
/*
|
||||
* Determine the attributes (JSPROP_* flags) of a property on a given object.
|
||||
*
|
||||
* If the object does not have a property by that name, *foundp will be
|
||||
* false and the value of *attrsp is undefined.
|
||||
*/
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_GetUCPropertyAttributes(JSContext *cx, JSObject *obj,
|
||||
const jschar *name, size_t namelen,
|
||||
unsigned *attrsp, bool *foundp);
|
||||
|
||||
/*
|
||||
* The same, but if the property is native, return its getter and setter via
|
||||
* *getterp and *setterp, respectively (and only if the out parameter pointer
|
||||
* is not null).
|
||||
*/
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_GetUCPropertyAttrsGetterAndSetter(JSContext *cx, JSObject *obj,
|
||||
const jschar *name, size_t namelen,
|
||||
unsigned *attrsp, bool *foundp,
|
||||
JSPropertyOp *getterp,
|
||||
JSStrictPropertyOp *setterp);
|
||||
|
||||
/*
|
||||
* Set the attributes of a property on a given object.
|
||||
*
|
||||
* If the object does not have a property by that name, *foundp will be
|
||||
* false and nothing will be altered.
|
||||
*/
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_SetUCPropertyAttributes(JSContext *cx, JSObject *obj,
|
||||
const jschar *name, size_t namelen,
|
||||
unsigned attrs, bool *foundp);
|
||||
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_DefineUCPropertyWithTinyId(JSContext *cx, JSObject *obj,
|
||||
const jschar *name, size_t namelen,
|
||||
|
@ -511,7 +511,7 @@ class TypeSet
|
||||
inline TypeObjectKey *getObject(unsigned i) const;
|
||||
inline JSObject *getSingleObject(unsigned i) const;
|
||||
inline TypeObject *getTypeObject(unsigned i) const;
|
||||
inline TypeObject *getTypeOrSingleObject(JSContext *cx, unsigned i) const;
|
||||
inline bool getTypeOrSingleObject(JSContext *cx, unsigned i, TypeObject **obj) const;
|
||||
|
||||
void setOwnProperty(bool configurable) {
|
||||
flags |= TYPE_FLAG_OWN_PROPERTY;
|
||||
|
@ -1407,20 +1407,28 @@ TypeSet::getTypeObject(unsigned i) const
|
||||
return (key && !(uintptr_t(key) & 1)) ? (TypeObject *) key : NULL;
|
||||
}
|
||||
|
||||
inline TypeObject *
|
||||
TypeSet::getTypeOrSingleObject(JSContext *cx, unsigned i) const
|
||||
inline bool
|
||||
TypeSet::getTypeOrSingleObject(JSContext *cx, unsigned i, TypeObject **result) const
|
||||
{
|
||||
JS_ASSERT(result);
|
||||
JS_ASSERT(cx->compartment()->activeAnalysis);
|
||||
|
||||
*result = NULL;
|
||||
|
||||
TypeObject *type = getTypeObject(i);
|
||||
if (!type) {
|
||||
JSObject *singleton = getSingleObject(i);
|
||||
if (!singleton)
|
||||
return NULL;
|
||||
return true;
|
||||
|
||||
type = singleton->uninlinedGetType(cx);
|
||||
if (!type)
|
||||
if (!type) {
|
||||
cx->compartment()->types.setPendingNukeTypes(cx);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return type;
|
||||
*result = type;
|
||||
return true;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
@ -4775,24 +4775,6 @@ baseops::GetAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned *a
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
baseops::GetElementAttributes(JSContext *cx, HandleObject obj, uint32_t index, unsigned *attrsp)
|
||||
{
|
||||
RootedObject nobj(cx);
|
||||
RootedShape shape(cx);
|
||||
if (!baseops::LookupElement(cx, obj, index, &nobj, &shape))
|
||||
return false;
|
||||
if (!shape) {
|
||||
*attrsp = 0;
|
||||
return true;
|
||||
}
|
||||
if (!nobj->isNative())
|
||||
return JSObject::getElementAttributes(cx, nobj, index, attrsp);
|
||||
|
||||
*attrsp = GetShapeAttributes(shape);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
baseops::SetAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned *attrsp)
|
||||
{
|
||||
@ -4812,26 +4794,6 @@ baseops::SetAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned *a
|
||||
: JSObject::setGenericAttributes(cx, nobj, id, attrsp);
|
||||
}
|
||||
|
||||
bool
|
||||
baseops::SetElementAttributes(JSContext *cx, HandleObject obj, uint32_t index, unsigned *attrsp)
|
||||
{
|
||||
RootedObject nobj(cx);
|
||||
RootedShape shape(cx);
|
||||
if (!baseops::LookupElement(cx, obj, index, &nobj, &shape))
|
||||
return false;
|
||||
if (!shape)
|
||||
return true;
|
||||
if (nobj->isNative() && IsImplicitDenseElement(shape)) {
|
||||
if (!JSObject::sparsifyDenseElement(cx, obj, index))
|
||||
return false;
|
||||
jsid id = INT_TO_JSID(index);
|
||||
shape = obj->nativeLookup(cx, HandleId::fromMarkedLocation(&id)); // not a gcthing
|
||||
}
|
||||
return nobj->isNative()
|
||||
? JSObject::changePropertyAttributes(cx, nobj, shape, *attrsp)
|
||||
: JSObject::setElementAttributes(cx, nobj, index, attrsp);
|
||||
}
|
||||
|
||||
bool
|
||||
baseops::DeleteGeneric(JSContext *cx, HandleObject obj, HandleId id, bool *succeeded)
|
||||
{
|
||||
|
@ -143,12 +143,6 @@ GetAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned *attrsp);
|
||||
extern bool
|
||||
SetAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned *attrsp);
|
||||
|
||||
extern bool
|
||||
GetElementAttributes(JSContext *cx, HandleObject obj, uint32_t index, unsigned *attrsp);
|
||||
|
||||
extern bool
|
||||
SetElementAttributes(JSContext *cx, HandleObject obj, uint32_t index, unsigned *attrsp);
|
||||
|
||||
extern bool
|
||||
DeleteProperty(JSContext *cx, HandleObject obj, HandlePropertyName name, bool *succeeded);
|
||||
|
||||
@ -881,31 +875,8 @@ class JSObject : public js::ObjectImpl
|
||||
return (op ? op : js::baseops::GetAttributes)(cx, obj, id, attrsp);
|
||||
}
|
||||
|
||||
static bool getPropertyAttributes(JSContext *cx, js::HandleObject obj,
|
||||
js::PropertyName *name, unsigned *attrsp)
|
||||
{
|
||||
JS::RootedId id(cx, js::NameToId(name));
|
||||
return getGenericAttributes(cx, obj, id, attrsp);
|
||||
}
|
||||
|
||||
static inline bool getElementAttributes(JSContext *cx, js::HandleObject obj,
|
||||
uint32_t index, unsigned *attrsp);
|
||||
|
||||
static bool getSpecialAttributes(JSContext *cx, js::HandleObject obj,
|
||||
js::SpecialId sid, unsigned *attrsp)
|
||||
{
|
||||
JS::RootedId id(cx, SPECIALID_TO_JSID(sid));
|
||||
return getGenericAttributes(cx, obj, id, attrsp);
|
||||
}
|
||||
|
||||
static inline bool setGenericAttributes(JSContext *cx, js::HandleObject obj,
|
||||
js::HandleId id, unsigned *attrsp);
|
||||
static inline bool setPropertyAttributes(JSContext *cx, js::HandleObject obj,
|
||||
js::PropertyName *name, unsigned *attrsp);
|
||||
static inline bool setElementAttributes(JSContext *cx, js::HandleObject obj,
|
||||
uint32_t index, unsigned *attrsp);
|
||||
static inline bool setSpecialAttributes(JSContext *cx, js::HandleObject obj,
|
||||
js::SpecialId sid, unsigned *attrsp);
|
||||
|
||||
static inline bool deleteProperty(JSContext *cx, js::HandleObject obj,
|
||||
js::HandlePropertyName name,
|
||||
|
@ -31,30 +31,6 @@ JSObject::setGenericAttributes(JSContext *cx, js::HandleObject obj,
|
||||
return (op ? op : js::baseops::SetAttributes)(cx, obj, id, attrsp);
|
||||
}
|
||||
|
||||
/* static */ inline bool
|
||||
JSObject::setPropertyAttributes(JSContext *cx, js::HandleObject obj,
|
||||
js::PropertyName *name, unsigned *attrsp)
|
||||
{
|
||||
JS::RootedId id(cx, js::NameToId(name));
|
||||
return setGenericAttributes(cx, obj, id, attrsp);
|
||||
}
|
||||
|
||||
/* static */ inline bool
|
||||
JSObject::setElementAttributes(JSContext *cx, js::HandleObject obj,
|
||||
uint32_t index, unsigned *attrsp)
|
||||
{
|
||||
js::ElementAttributesOp op = obj->getOps()->setElementAttributes;
|
||||
return (op ? op : js::baseops::SetElementAttributes)(cx, obj, index, attrsp);
|
||||
}
|
||||
|
||||
/* static */ inline bool
|
||||
JSObject::setSpecialAttributes(JSContext *cx, js::HandleObject obj,
|
||||
js::SpecialId sid, unsigned *attrsp)
|
||||
{
|
||||
JS::RootedId id(cx, SPECIALID_TO_JSID(sid));
|
||||
return setGenericAttributes(cx, obj, id, attrsp);
|
||||
}
|
||||
|
||||
/* static */ inline bool
|
||||
JSObject::changePropertyAttributes(JSContext *cx, js::HandleObject obj,
|
||||
js::HandleShape shape, unsigned attrs)
|
||||
@ -747,16 +723,6 @@ JSObject::getElementIfPresent(JSContext *cx, js::HandleObject obj, js::HandleObj
|
||||
return getGeneric(cx, obj, receiver, id, vp);
|
||||
}
|
||||
|
||||
/* static */ inline bool
|
||||
JSObject::getElementAttributes(JSContext *cx, js::HandleObject obj,
|
||||
uint32_t index, unsigned *attrsp)
|
||||
{
|
||||
JS::RootedId id(cx);
|
||||
if (!js::IndexToId(cx, index, &id))
|
||||
return false;
|
||||
return getGenericAttributes(cx, obj, id, attrsp);
|
||||
}
|
||||
|
||||
inline js::GlobalObject &
|
||||
JSObject::global() const
|
||||
{
|
||||
|
@ -2892,29 +2892,6 @@ proxy_GetGenericAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigne
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
proxy_GetPropertyAttributes(JSContext *cx, HandleObject obj, HandlePropertyName name, unsigned *attrsp)
|
||||
{
|
||||
Rooted<jsid> id(cx, NameToId(name));
|
||||
return proxy_GetGenericAttributes(cx, obj, id, attrsp);
|
||||
}
|
||||
|
||||
static bool
|
||||
proxy_GetElementAttributes(JSContext *cx, HandleObject obj, uint32_t index, unsigned *attrsp)
|
||||
{
|
||||
RootedId id(cx);
|
||||
if (!IndexToId(cx, index, &id))
|
||||
return false;
|
||||
return proxy_GetGenericAttributes(cx, obj, id, attrsp);
|
||||
}
|
||||
|
||||
static bool
|
||||
proxy_GetSpecialAttributes(JSContext *cx, HandleObject obj, HandleSpecialId sid, unsigned *attrsp)
|
||||
{
|
||||
Rooted<jsid> id(cx, SPECIALID_TO_JSID(sid));
|
||||
return proxy_GetGenericAttributes(cx, obj, id, attrsp);
|
||||
}
|
||||
|
||||
static bool
|
||||
proxy_SetGenericAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned *attrsp)
|
||||
{
|
||||
@ -2926,29 +2903,6 @@ proxy_SetGenericAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigne
|
||||
return Proxy::defineProperty(cx, obj, id, &desc);
|
||||
}
|
||||
|
||||
static bool
|
||||
proxy_SetPropertyAttributes(JSContext *cx, HandleObject obj, HandlePropertyName name, unsigned *attrsp)
|
||||
{
|
||||
Rooted<jsid> id(cx, NameToId(name));
|
||||
return proxy_SetGenericAttributes(cx, obj, id, attrsp);
|
||||
}
|
||||
|
||||
static bool
|
||||
proxy_SetElementAttributes(JSContext *cx, HandleObject obj, uint32_t index, unsigned *attrsp)
|
||||
{
|
||||
RootedId id(cx);
|
||||
if (!IndexToId(cx, index, &id))
|
||||
return false;
|
||||
return proxy_SetGenericAttributes(cx, obj, id, attrsp);
|
||||
}
|
||||
|
||||
static bool
|
||||
proxy_SetSpecialAttributes(JSContext *cx, HandleObject obj, HandleSpecialId sid, unsigned *attrsp)
|
||||
{
|
||||
Rooted<jsid> id(cx, SPECIALID_TO_JSID(sid));
|
||||
return proxy_SetGenericAttributes(cx, obj, id, attrsp);
|
||||
}
|
||||
|
||||
static bool
|
||||
proxy_DeleteGeneric(JSContext *cx, HandleObject obj, HandleId id, bool *succeeded)
|
||||
{
|
||||
@ -3103,13 +3057,7 @@ Class js::ObjectProxyObject::class_ = {
|
||||
proxy_SetElement,
|
||||
proxy_SetSpecial,
|
||||
proxy_GetGenericAttributes,
|
||||
proxy_GetPropertyAttributes,
|
||||
proxy_GetElementAttributes,
|
||||
proxy_GetSpecialAttributes,
|
||||
proxy_SetGenericAttributes,
|
||||
proxy_SetPropertyAttributes,
|
||||
proxy_SetElementAttributes,
|
||||
proxy_SetSpecialAttributes,
|
||||
proxy_DeleteProperty,
|
||||
proxy_DeleteElement,
|
||||
proxy_DeleteSpecial,
|
||||
@ -3162,13 +3110,7 @@ Class js::OuterWindowProxyObject::class_ = {
|
||||
proxy_SetElement,
|
||||
proxy_SetSpecial,
|
||||
proxy_GetGenericAttributes,
|
||||
proxy_GetPropertyAttributes,
|
||||
proxy_GetElementAttributes,
|
||||
proxy_GetSpecialAttributes,
|
||||
proxy_SetGenericAttributes,
|
||||
proxy_SetPropertyAttributes,
|
||||
proxy_SetElementAttributes,
|
||||
proxy_SetSpecialAttributes,
|
||||
proxy_DeleteProperty,
|
||||
proxy_DeleteElement,
|
||||
proxy_DeleteSpecial,
|
||||
@ -3233,13 +3175,7 @@ Class js::FunctionProxyObject::class_ = {
|
||||
proxy_SetElement,
|
||||
proxy_SetSpecial,
|
||||
proxy_GetGenericAttributes,
|
||||
proxy_GetPropertyAttributes,
|
||||
proxy_GetElementAttributes,
|
||||
proxy_GetSpecialAttributes,
|
||||
proxy_SetGenericAttributes,
|
||||
proxy_SetPropertyAttributes,
|
||||
proxy_SetElementAttributes,
|
||||
proxy_SetSpecialAttributes,
|
||||
proxy_DeleteProperty,
|
||||
proxy_DeleteElement,
|
||||
proxy_DeleteSpecial,
|
||||
|
@ -275,27 +275,27 @@ DefVarOrConstOperation(JSContext *cx, HandleObject varobj, HandlePropertyName dn
|
||||
JS_StrictPropertyStub, attrs)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
} else if (attrs & JSPROP_READONLY) {
|
||||
/*
|
||||
* Extension: ordinarily we'd be done here -- but for |const|. If we
|
||||
* see a redeclaration that's |const|, we consider it a conflict.
|
||||
*/
|
||||
unsigned oldAttrs;
|
||||
if (!JSObject::getPropertyAttributes(cx, varobj, dn, &oldAttrs))
|
||||
return false;
|
||||
if (attrs & JSPROP_READONLY) {
|
||||
JSAutoByteString bytes;
|
||||
if (AtomToPrintableString(cx, dn, &bytes)) {
|
||||
JS_ALWAYS_FALSE(JS_ReportErrorFlagsAndNumber(cx, JSREPORT_ERROR,
|
||||
js_GetErrorMessage,
|
||||
NULL, JSMSG_REDECLARED_VAR,
|
||||
(oldAttrs & JSPROP_READONLY)
|
||||
? "const"
|
||||
: "var",
|
||||
bytes.ptr()));
|
||||
}
|
||||
RootedId id(cx, NameToId(dn));
|
||||
if (!JSObject::getGenericAttributes(cx, varobj, id, &oldAttrs))
|
||||
return false;
|
||||
|
||||
JSAutoByteString bytes;
|
||||
if (AtomToPrintableString(cx, dn, &bytes)) {
|
||||
JS_ALWAYS_FALSE(JS_ReportErrorFlagsAndNumber(cx, JSREPORT_ERROR,
|
||||
js_GetErrorMessage,
|
||||
NULL, JSMSG_REDECLARED_VAR,
|
||||
(oldAttrs & JSPROP_READONLY)
|
||||
? "const"
|
||||
: "var",
|
||||
bytes.ptr()));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -511,27 +511,6 @@ with_GetGenericAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned
|
||||
return JSObject::getGenericAttributes(cx, actual, id, attrsp);
|
||||
}
|
||||
|
||||
static bool
|
||||
with_GetPropertyAttributes(JSContext *cx, HandleObject obj, HandlePropertyName name, unsigned *attrsp)
|
||||
{
|
||||
RootedObject actual(cx, &obj->as<WithObject>().object());
|
||||
return JSObject::getPropertyAttributes(cx, actual, name, attrsp);
|
||||
}
|
||||
|
||||
static bool
|
||||
with_GetElementAttributes(JSContext *cx, HandleObject obj, uint32_t index, unsigned *attrsp)
|
||||
{
|
||||
RootedObject actual(cx, &obj->as<WithObject>().object());
|
||||
return JSObject::getElementAttributes(cx, actual, index, attrsp);
|
||||
}
|
||||
|
||||
static bool
|
||||
with_GetSpecialAttributes(JSContext *cx, HandleObject obj, HandleSpecialId sid, unsigned *attrsp)
|
||||
{
|
||||
RootedObject actual(cx, &obj->as<WithObject>().object());
|
||||
return JSObject::getSpecialAttributes(cx, actual, sid, attrsp);
|
||||
}
|
||||
|
||||
static bool
|
||||
with_SetGenericAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned *attrsp)
|
||||
{
|
||||
@ -539,27 +518,6 @@ with_SetGenericAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned
|
||||
return JSObject::setGenericAttributes(cx, actual, id, attrsp);
|
||||
}
|
||||
|
||||
static bool
|
||||
with_SetPropertyAttributes(JSContext *cx, HandleObject obj, HandlePropertyName name, unsigned *attrsp)
|
||||
{
|
||||
RootedObject actual(cx, &obj->as<WithObject>().object());
|
||||
return JSObject::setPropertyAttributes(cx, actual, name, attrsp);
|
||||
}
|
||||
|
||||
static bool
|
||||
with_SetElementAttributes(JSContext *cx, HandleObject obj, uint32_t index, unsigned *attrsp)
|
||||
{
|
||||
RootedObject actual(cx, &obj->as<WithObject>().object());
|
||||
return JSObject::setElementAttributes(cx, actual, index, attrsp);
|
||||
}
|
||||
|
||||
static bool
|
||||
with_SetSpecialAttributes(JSContext *cx, HandleObject obj, HandleSpecialId sid, unsigned *attrsp)
|
||||
{
|
||||
RootedObject actual(cx, &obj->as<WithObject>().object());
|
||||
return JSObject::setSpecialAttributes(cx, actual, sid, attrsp);
|
||||
}
|
||||
|
||||
static bool
|
||||
with_DeleteProperty(JSContext *cx, HandleObject obj, HandlePropertyName name,
|
||||
bool *succeeded)
|
||||
@ -635,13 +593,7 @@ Class WithObject::class_ = {
|
||||
with_SetElement,
|
||||
with_SetSpecial,
|
||||
with_GetGenericAttributes,
|
||||
with_GetPropertyAttributes,
|
||||
with_GetElementAttributes,
|
||||
with_GetSpecialAttributes,
|
||||
with_SetGenericAttributes,
|
||||
with_SetPropertyAttributes,
|
||||
with_SetElementAttributes,
|
||||
with_SetSpecialAttributes,
|
||||
with_DeleteProperty,
|
||||
with_DeleteElement,
|
||||
with_DeleteSpecial,
|
||||
@ -1408,7 +1360,7 @@ class DebugScopeProxy : public BaseProxyHandler
|
||||
return true;
|
||||
}
|
||||
|
||||
return JS_GetPropertyDescriptorById(cx, scope, id, 0, desc);
|
||||
return JS_GetOwnPropertyDescriptorById(cx, scope, id, flags, desc);
|
||||
}
|
||||
|
||||
bool get(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id,
|
||||
|
@ -1020,32 +1020,6 @@ ArrayBufferObject::obj_getGenericAttributes(JSContext *cx, HandleObject obj,
|
||||
return baseops::GetAttributes(cx, delegate, id, attrsp);
|
||||
}
|
||||
|
||||
bool
|
||||
ArrayBufferObject::obj_getPropertyAttributes(JSContext *cx, HandleObject obj,
|
||||
HandlePropertyName name, unsigned *attrsp)
|
||||
{
|
||||
Rooted<jsid> id(cx, NameToId(name));
|
||||
return obj_getGenericAttributes(cx, obj, id, attrsp);
|
||||
}
|
||||
|
||||
bool
|
||||
ArrayBufferObject::obj_getElementAttributes(JSContext *cx, HandleObject obj,
|
||||
uint32_t index, unsigned *attrsp)
|
||||
{
|
||||
RootedObject delegate(cx, ArrayBufferDelegate(cx, obj));
|
||||
if (!delegate)
|
||||
return false;
|
||||
return baseops::GetElementAttributes(cx, delegate, index, attrsp);
|
||||
}
|
||||
|
||||
bool
|
||||
ArrayBufferObject::obj_getSpecialAttributes(JSContext *cx, HandleObject obj,
|
||||
HandleSpecialId sid, unsigned *attrsp)
|
||||
{
|
||||
Rooted<jsid> id(cx, SPECIALID_TO_JSID(sid));
|
||||
return obj_getGenericAttributes(cx, obj, id, attrsp);
|
||||
}
|
||||
|
||||
bool
|
||||
ArrayBufferObject::obj_setGenericAttributes(JSContext *cx, HandleObject obj,
|
||||
HandleId id, unsigned *attrsp)
|
||||
@ -1056,32 +1030,6 @@ ArrayBufferObject::obj_setGenericAttributes(JSContext *cx, HandleObject obj,
|
||||
return baseops::SetAttributes(cx, delegate, id, attrsp);
|
||||
}
|
||||
|
||||
bool
|
||||
ArrayBufferObject::obj_setPropertyAttributes(JSContext *cx, HandleObject obj,
|
||||
HandlePropertyName name, unsigned *attrsp)
|
||||
{
|
||||
Rooted<jsid> id(cx, NameToId(name));
|
||||
return obj_setGenericAttributes(cx, obj, id, attrsp);
|
||||
}
|
||||
|
||||
bool
|
||||
ArrayBufferObject::obj_setElementAttributes(JSContext *cx, HandleObject obj,
|
||||
uint32_t index, unsigned *attrsp)
|
||||
{
|
||||
RootedObject delegate(cx, ArrayBufferDelegate(cx, obj));
|
||||
if (!delegate)
|
||||
return false;
|
||||
return baseops::SetElementAttributes(cx, delegate, index, attrsp);
|
||||
}
|
||||
|
||||
bool
|
||||
ArrayBufferObject::obj_setSpecialAttributes(JSContext *cx, HandleObject obj,
|
||||
HandleSpecialId sid, unsigned *attrsp)
|
||||
{
|
||||
Rooted<jsid> id(cx, SPECIALID_TO_JSID(sid));
|
||||
return obj_setGenericAttributes(cx, obj, id, attrsp);
|
||||
}
|
||||
|
||||
bool
|
||||
ArrayBufferObject::obj_deleteProperty(JSContext *cx, HandleObject obj, HandlePropertyName name,
|
||||
bool *succeeded)
|
||||
@ -1231,30 +1179,6 @@ TypedArrayObject::obj_getGenericAttributes(JSContext *cx, HandleObject obj, Hand
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TypedArrayObject::obj_getPropertyAttributes(JSContext *cx, HandleObject obj,
|
||||
HandlePropertyName name, unsigned *attrsp)
|
||||
{
|
||||
*attrsp = JSPROP_PERMANENT | JSPROP_ENUMERATE;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TypedArrayObject::obj_getElementAttributes(JSContext *cx, HandleObject obj, uint32_t index,
|
||||
unsigned *attrsp)
|
||||
{
|
||||
*attrsp = JSPROP_PERMANENT | JSPROP_ENUMERATE;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TypedArrayObject::obj_getSpecialAttributes(JSContext *cx, HandleObject obj, HandleSpecialId sid,
|
||||
unsigned *attrsp)
|
||||
{
|
||||
Rooted<jsid> id(cx, SPECIALID_TO_JSID(sid));
|
||||
return obj_getGenericAttributes(cx, obj, id, attrsp);
|
||||
}
|
||||
|
||||
bool
|
||||
TypedArrayObject::obj_setGenericAttributes(JSContext *cx, HandleObject obj, HandleId id,
|
||||
unsigned *attrsp)
|
||||
@ -1263,30 +1187,6 @@ TypedArrayObject::obj_setGenericAttributes(JSContext *cx, HandleObject obj, Hand
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
TypedArrayObject::obj_setPropertyAttributes(JSContext *cx, HandleObject obj,
|
||||
HandlePropertyName name, unsigned *attrsp)
|
||||
{
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_SET_ARRAY_ATTRS);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
TypedArrayObject::obj_setElementAttributes(JSContext *cx, HandleObject obj, uint32_t index,
|
||||
unsigned *attrsp)
|
||||
{
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_SET_ARRAY_ATTRS);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
TypedArrayObject::obj_setSpecialAttributes(JSContext *cx, HandleObject obj, HandleSpecialId sid,
|
||||
unsigned *attrsp)
|
||||
{
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_SET_ARRAY_ATTRS);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* static */ int
|
||||
TypedArrayObject::lengthOffset()
|
||||
{
|
||||
@ -3494,13 +3394,7 @@ Class ArrayBufferObject::class_ = {
|
||||
ArrayBufferObject::obj_setElement,
|
||||
ArrayBufferObject::obj_setSpecial,
|
||||
ArrayBufferObject::obj_getGenericAttributes,
|
||||
ArrayBufferObject::obj_getPropertyAttributes,
|
||||
ArrayBufferObject::obj_getElementAttributes,
|
||||
ArrayBufferObject::obj_getSpecialAttributes,
|
||||
ArrayBufferObject::obj_setGenericAttributes,
|
||||
ArrayBufferObject::obj_setPropertyAttributes,
|
||||
ArrayBufferObject::obj_setElementAttributes,
|
||||
ArrayBufferObject::obj_setSpecialAttributes,
|
||||
ArrayBufferObject::obj_deleteProperty,
|
||||
ArrayBufferObject::obj_deleteElement,
|
||||
ArrayBufferObject::obj_deleteSpecial,
|
||||
@ -3662,13 +3556,7 @@ IMPL_TYPED_ARRAY_COMBINED_UNWRAPPERS(Float64, double, double)
|
||||
_typedArray##Object::obj_setElement, \
|
||||
_typedArray##Object::obj_setSpecial, \
|
||||
_typedArray##Object::obj_getGenericAttributes, \
|
||||
_typedArray##Object::obj_getPropertyAttributes, \
|
||||
_typedArray##Object::obj_getElementAttributes, \
|
||||
_typedArray##Object::obj_getSpecialAttributes, \
|
||||
_typedArray##Object::obj_setGenericAttributes, \
|
||||
_typedArray##Object::obj_setPropertyAttributes, \
|
||||
_typedArray##Object::obj_setElementAttributes, \
|
||||
_typedArray##Object::obj_setSpecialAttributes, \
|
||||
_typedArray##Object::obj_deleteProperty, \
|
||||
_typedArray##Object::obj_deleteElement, \
|
||||
_typedArray##Object::obj_deleteSpecial, \
|
||||
|
@ -124,21 +124,8 @@ class ArrayBufferObject : public JSObject
|
||||
|
||||
static bool obj_getGenericAttributes(JSContext *cx, HandleObject obj,
|
||||
HandleId id, unsigned *attrsp);
|
||||
static bool obj_getPropertyAttributes(JSContext *cx, HandleObject obj,
|
||||
HandlePropertyName name, unsigned *attrsp);
|
||||
static bool obj_getElementAttributes(JSContext *cx, HandleObject obj,
|
||||
uint32_t index, unsigned *attrsp);
|
||||
static bool obj_getSpecialAttributes(JSContext *cx, HandleObject obj,
|
||||
HandleSpecialId sid, unsigned *attrsp);
|
||||
|
||||
static bool obj_setGenericAttributes(JSContext *cx, HandleObject obj,
|
||||
HandleId id, unsigned *attrsp);
|
||||
static bool obj_setPropertyAttributes(JSContext *cx, HandleObject obj,
|
||||
HandlePropertyName name, unsigned *attrsp);
|
||||
static bool obj_setElementAttributes(JSContext *cx, HandleObject obj,
|
||||
uint32_t index, unsigned *attrsp);
|
||||
static bool obj_setSpecialAttributes(JSContext *cx, HandleObject obj,
|
||||
HandleSpecialId sid, unsigned *attrsp);
|
||||
|
||||
static bool obj_deleteProperty(JSContext *cx, HandleObject obj, HandlePropertyName name,
|
||||
bool *succeeded);
|
||||
@ -295,21 +282,8 @@ class TypedArrayObject : public ArrayBufferViewObject
|
||||
|
||||
static bool obj_getGenericAttributes(JSContext *cx, HandleObject obj,
|
||||
HandleId id, unsigned *attrsp);
|
||||
static bool obj_getPropertyAttributes(JSContext *cx, HandleObject obj,
|
||||
HandlePropertyName name, unsigned *attrsp);
|
||||
static bool obj_getElementAttributes(JSContext *cx, HandleObject obj,
|
||||
uint32_t index, unsigned *attrsp);
|
||||
static bool obj_getSpecialAttributes(JSContext *cx, HandleObject obj,
|
||||
HandleSpecialId sid, unsigned *attrsp);
|
||||
|
||||
static bool obj_setGenericAttributes(JSContext *cx, HandleObject obj,
|
||||
HandleId id, unsigned *attrsp);
|
||||
static bool obj_setPropertyAttributes(JSContext *cx, HandleObject obj,
|
||||
HandlePropertyName name, unsigned *attrsp);
|
||||
static bool obj_setElementAttributes(JSContext *cx, HandleObject obj,
|
||||
uint32_t index, unsigned *attrsp);
|
||||
static bool obj_setSpecialAttributes(JSContext *cx, HandleObject obj,
|
||||
HandleSpecialId sid, unsigned *attrsp);
|
||||
|
||||
static Value bufferValue(TypedArrayObject *tarr) {
|
||||
return tarr->getFixedSlot(BUFFER_SLOT);
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "nsISupports.idl"
|
||||
#include "nsIXPConnect.idl"
|
||||
#include "nsIClassInfo.idl"
|
||||
|
||||
%{C++
|
||||
#ifdef XP_WIN
|
||||
|
@ -7,26 +7,15 @@
|
||||
/* The core XPConnect public interfaces. */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
#include "nsIClassInfo.idl"
|
||||
#include "xpccomponents.idl"
|
||||
#include "xpcjsid.idl"
|
||||
#include "xpcexception.idl"
|
||||
#include "nsIInterfaceInfo.idl"
|
||||
#include "nsIInterfaceInfoManager.idl"
|
||||
#include "nsIExceptionService.idl"
|
||||
#include "nsIVariant.idl"
|
||||
#include "nsIObjectOutputStream.idl"
|
||||
#include "nsIObjectInputStream.idl"
|
||||
|
||||
%{ C++
|
||||
#include "jspubtd.h"
|
||||
#include "js/TypeDecls.h"
|
||||
#include "xptinfo.h"
|
||||
#include "nsAXPCNativeCallContext.h"
|
||||
|
||||
struct JSFreeOp;
|
||||
|
||||
class nsWrapperCache;
|
||||
class nsAXPCNativeCallContext;
|
||||
%}
|
||||
|
||||
/***************************************************************************/
|
||||
@ -58,6 +47,11 @@ interface nsIXPConnectWrappedNative;
|
||||
interface nsIInterfaceInfo;
|
||||
interface nsIXPCSecurityManager;
|
||||
interface nsIPrincipal;
|
||||
interface nsIClassInfo;
|
||||
interface nsIVariant;
|
||||
interface nsIStackFrame;
|
||||
interface nsIObjectInputStream;
|
||||
interface nsIObjectOutputStream;
|
||||
|
||||
/***************************************************************************/
|
||||
[uuid(909e8641-7c54-4dff-9b94-ba631f057b33)]
|
||||
|
@ -1676,6 +1676,11 @@ main(int argc, char **argv, char **envp)
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Force the SafeJSContext to be created. This is a workaround for our
|
||||
// implicit dependency on keeping at least one JSContext alive until the
|
||||
// end of shutdown. This can go away when we get bug 905926 landed.
|
||||
xpc->GetSafeJSContext();
|
||||
|
||||
nsCOMPtr<nsIPrincipal> systemprincipal;
|
||||
// Fetch the system principal and store it away in a global, to use for
|
||||
// script compilation in Load() and ProcessFile() (including interactive
|
||||
|
@ -1170,14 +1170,13 @@ XPCConvert::JSValToXPCException(MutableHandleValue s,
|
||||
}
|
||||
|
||||
|
||||
unsigned ignored;
|
||||
bool found;
|
||||
|
||||
// heuristic to see if it might be usable as an xpcexception
|
||||
if (!JS_GetPropertyAttributes(cx, obj, "message", &ignored, &found))
|
||||
return NS_ERROR_FAILURE;
|
||||
if (!JS_HasProperty(cx, obj, "message", &found))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (found && !JS_GetPropertyAttributes(cx, obj, "result", &ignored, &found))
|
||||
if (found && !JS_HasProperty(cx, obj, "result", &found))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (found) {
|
||||
|
@ -125,7 +125,7 @@ SafeFinalize(JSFreeOp *fop, JSObject* obj)
|
||||
DestroyProtoAndIfaceCache(obj);
|
||||
}
|
||||
|
||||
static JSClass global_class = {
|
||||
JSClass xpc::SafeJSContextGlobalClass = {
|
||||
"global_for_XPCJSContextStack_SafeJSContext",
|
||||
XPCONNECT_GLOBAL_FLAGS,
|
||||
JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
|
||||
@ -161,7 +161,7 @@ XPCJSContextStack::GetSafeJSContext()
|
||||
|
||||
JS::CompartmentOptions options;
|
||||
options.setZone(JS::SystemZone);
|
||||
glob = xpc::CreateGlobalObject(mSafeJSContext, &global_class, principal, options);
|
||||
glob = xpc::CreateGlobalObject(mSafeJSContext, &SafeJSContextGlobalClass, principal, options);
|
||||
if (!glob)
|
||||
MOZ_CRASH();
|
||||
|
||||
|
@ -735,13 +735,7 @@ XPCWrappedNativeJSClass XPC_WN_NoHelper_JSClass = {
|
||||
nullptr, // setElement
|
||||
nullptr, // setSpecial
|
||||
nullptr, // getGenericAttributes
|
||||
nullptr, // getAttributes
|
||||
nullptr, // getElementAttributes
|
||||
nullptr, // getSpecialAttributes
|
||||
nullptr, // setGenericAttributes
|
||||
nullptr, // setAttributes
|
||||
nullptr, // setElementAttributes
|
||||
nullptr, // setSpecialAttributes
|
||||
nullptr, // deleteProperty
|
||||
nullptr, // deleteElement
|
||||
nullptr, // deleteSpecial
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace xpc;
|
||||
using namespace JS;
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
@ -97,17 +98,24 @@ XPCWrappedNativeScope::GetNewOrUsed(JSContext *cx, JS::HandleObject aGlobal)
|
||||
}
|
||||
|
||||
static bool
|
||||
RemoteXULForbidsXBLScope(nsIPrincipal *aPrincipal)
|
||||
RemoteXULForbidsXBLScope(nsIPrincipal *aPrincipal, HandleObject aGlobal)
|
||||
{
|
||||
// We end up getting called during SSM bootstrapping to create the
|
||||
// SafeJSContext. In that case, nsContentUtils isn't ready for us.
|
||||
//
|
||||
// Also check for random JSD scopes that don't have a principal.
|
||||
if (!nsContentUtils::IsInitialized() || !aPrincipal)
|
||||
// Check for random JSD scopes that don't have a principal.
|
||||
if (!aPrincipal)
|
||||
return false;
|
||||
|
||||
// The SafeJSContext is lazily created, and tends to be created at really
|
||||
// weird times, at least for xpcshell (often very early in startup or late
|
||||
// in shutdown). Its scope isn't system principal, so if we proceeded we'd
|
||||
// end up calling into AllowXULXBLForPrincipal, which depends on all kinds
|
||||
// of persistent storage and permission machinery that may or not be running.
|
||||
// We know the answer to the question here, so just short-circuit.
|
||||
if (JS_GetClass(aGlobal) == &SafeJSContextGlobalClass)
|
||||
return false;
|
||||
|
||||
// AllowXULXBLForPrincipal will return true for system principal, but we
|
||||
// don't want that here.
|
||||
MOZ_ASSERT(nsContentUtils::IsInitialized());
|
||||
if (nsContentUtils::IsSystemPrincipal(aPrincipal))
|
||||
return false;
|
||||
|
||||
@ -161,7 +169,7 @@ XPCWrappedNativeScope::XPCWrappedNativeScope(JSContext *cx,
|
||||
// In addition to being pref-controlled, we also disable XBL scopes for
|
||||
// remote XUL domains, _except_ if we have an additional pref override set.
|
||||
nsIPrincipal *principal = GetPrincipal();
|
||||
mAllowXBLScope = !RemoteXULForbidsXBLScope(principal);
|
||||
mAllowXBLScope = !RemoteXULForbidsXBLScope(principal, aGlobal);
|
||||
|
||||
// Determine whether to use an XBL scope.
|
||||
mUseXBLScope = mAllowXBLScope;
|
||||
|
@ -4,7 +4,6 @@
|
||||
|
||||
# Dictionary interface name, interface file name
|
||||
dictionaries = [
|
||||
[ 'GeoPositionOptions', 'nsIDOMGeoGeolocation.idl' ],
|
||||
[ 'DOMFileMetadataParameters', 'nsIDOMLockedFile.idl' ],
|
||||
[ 'CameraSize', 'nsIDOMCameraManager.idl' ],
|
||||
[ 'CameraRegion', 'nsIDOMCameraManager.idl' ],
|
||||
|
@ -53,6 +53,8 @@
|
||||
#include "nsICycleCollectorListener.h"
|
||||
#include "nsThread.h"
|
||||
#include "mozilla/XPTInterfaceInfoManager.h"
|
||||
#include "nsIObjectInputStream.h"
|
||||
#include "nsIObjectOutputStream.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
@ -97,7 +97,6 @@
|
||||
#include "nsXPCOM.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "mozilla/CycleCollectedJSRuntime.h"
|
||||
#include "nsDebug.h"
|
||||
#include "nsISupports.h"
|
||||
#include "nsIServiceManager.h"
|
||||
@ -160,6 +159,7 @@
|
||||
#include "SandboxPrivate.h"
|
||||
#include "BackstagePass.h"
|
||||
#include "nsCxPusher.h"
|
||||
#include "nsAXPCNativeCallContext.h"
|
||||
|
||||
#ifdef XP_WIN
|
||||
// Nasty MS defines
|
||||
@ -1203,13 +1203,7 @@ XPC_WN_JSOp_ThisObject(JSContext *cx, JS::HandleObject obj);
|
||||
nullptr, /* setElement */ \
|
||||
nullptr, /* setSpecial */ \
|
||||
nullptr, /* getGenericAttributes */ \
|
||||
nullptr, /* getAttributes */ \
|
||||
nullptr, /* getElementAttributes */ \
|
||||
nullptr, /* getSpecialAttributes */ \
|
||||
nullptr, /* setGenericAttributes */ \
|
||||
nullptr, /* setAttributes */ \
|
||||
nullptr, /* setElementAttributes */ \
|
||||
nullptr, /* setSpecialAttributes */ \
|
||||
nullptr, /* deleteProperty */ \
|
||||
nullptr, /* deleteElement */ \
|
||||
nullptr, /* deleteSpecial */ \
|
||||
@ -1237,13 +1231,7 @@ XPC_WN_JSOp_ThisObject(JSContext *cx, JS::HandleObject obj);
|
||||
nullptr, /* setElement */ \
|
||||
nullptr, /* setSpecial */ \
|
||||
nullptr, /* getGenericAttributes */ \
|
||||
nullptr, /* getAttributes */ \
|
||||
nullptr, /* getElementAttributes */ \
|
||||
nullptr, /* getSpecialAttributes */ \
|
||||
nullptr, /* setGenericAttributes */ \
|
||||
nullptr, /* setAttributes */ \
|
||||
nullptr, /* setElementAttributes */ \
|
||||
nullptr, /* setSpecialAttributes */ \
|
||||
nullptr, /* deleteProperty */ \
|
||||
nullptr, /* deleteElement */ \
|
||||
nullptr, /* deleteSpecial */ \
|
||||
@ -3869,6 +3857,8 @@ GetObjectScope(JSObject *obj)
|
||||
extern bool gDebugMode;
|
||||
extern bool gDesiredDebugMode;
|
||||
|
||||
extern JSClass SafeJSContextGlobalClass;
|
||||
|
||||
JSObject* NewOutObject(JSContext* cx, JSObject* scope);
|
||||
bool IsOutObject(JSContext* cx, JSObject* obj);
|
||||
|
||||
|
@ -1168,7 +1168,6 @@ nsRefreshDriver::Tick(int64_t aNowEpoch, TimeStamp aNowTime)
|
||||
for (uint32_t i = 0; i < imagesToRefresh.Length(); i++) {
|
||||
imagesToRefresh[i]->RequestRefresh(aNowTime);
|
||||
}
|
||||
imagesToRefresh.Clear();
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < mPresShellsToInvalidateIfHidden.Length(); i++) {
|
||||
|
@ -3,7 +3,7 @@ test-pref(layout.css.sticky.enabled,true) == pref-1.html pref-1-enabled-ref.html
|
||||
default-preferences pref(layout.css.sticky.enabled,true)
|
||||
|
||||
== top-1.html top-1-ref.html
|
||||
fuzzy-if(Android,4,914) == top-2.html top-2-ref.html
|
||||
fuzzy-if(Android,6,914) == top-2.html top-2-ref.html
|
||||
fuzzy-if(Android,4,2729) == top-3.html top-3-ref.html
|
||||
== top-4.html top-4-ref.html
|
||||
== top-5.html top-5-ref.html
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include "nsDOMClassInfoID.h"
|
||||
#include "mozilla/Likely.h"
|
||||
#include "mozilla/dom/CSSStyleSheetBinding.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsSupportsPrimitives.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
|
||||
using namespace mozilla::dom;
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "nsAsyncDOMEvent.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
|
||||
// A helper class for managing our ranges of selection.
|
||||
struct nsTreeRange
|
||||
|
@ -69,11 +69,13 @@ int VcmSIPCCBinding::gAudioCodecMask = 0;
|
||||
int VcmSIPCCBinding::gVideoCodecMask = 0;
|
||||
nsIThread *VcmSIPCCBinding::gMainThread = NULL;
|
||||
|
||||
static mozilla::RefPtr<TransportFlow> vcmCreateTransportFlow(sipcc::PeerConnectionImpl *pc,
|
||||
int level, bool rtcp,
|
||||
const char *fingerprint_alg,
|
||||
const char *fingerprint
|
||||
);
|
||||
static mozilla::RefPtr<TransportFlow> vcmCreateTransportFlow(
|
||||
sipcc::PeerConnectionImpl *pc,
|
||||
int level,
|
||||
bool rtcp,
|
||||
sdp_setup_type_e setup_type,
|
||||
const char *fingerprint_alg,
|
||||
const char *fingerprint);
|
||||
|
||||
// Convenience macro to acquire PC
|
||||
|
||||
@ -1349,6 +1351,7 @@ int vcmRxStart(cc_mcapid_t mcap_id,
|
||||
* @param[in] peerconnection - the peerconnection in use
|
||||
* @param[in] num_payloads - number of negotiated payloads
|
||||
* @param[in] payloads - negotiated codec details list
|
||||
* @param[in] setup - whether playing client or server role
|
||||
* @param[in] fingerprint_alg - the DTLS fingerprint algorithm
|
||||
* @param[in] fingerprint - the DTLS fingerprint
|
||||
* @param[in] attrs - media attributes
|
||||
@ -1366,6 +1369,7 @@ static int vcmRxStartICE_m(cc_mcapid_t mcap_id,
|
||||
const char *peerconnection,
|
||||
int num_payloads,
|
||||
const vcm_payload_info_t* payloads,
|
||||
sdp_setup_type_e setup_type,
|
||||
const char *fingerprint_alg,
|
||||
const char *fingerprint,
|
||||
vcm_mediaAttrs_t *attrs)
|
||||
@ -1378,7 +1382,7 @@ static int vcmRxStartICE_m(cc_mcapid_t mcap_id,
|
||||
|
||||
// Datachannel will use this though not for RTP
|
||||
mozilla::RefPtr<TransportFlow> rtp_flow =
|
||||
vcmCreateTransportFlow(pc.impl(), level, false,
|
||||
vcmCreateTransportFlow(pc.impl(), level, false, setup_type,
|
||||
fingerprint_alg, fingerprint);
|
||||
if (!rtp_flow) {
|
||||
CSFLogError( logTag, "Could not create RTP flow");
|
||||
@ -1407,7 +1411,7 @@ static int vcmRxStartICE_m(cc_mcapid_t mcap_id,
|
||||
|
||||
mozilla::RefPtr<TransportFlow> rtcp_flow = nullptr;
|
||||
if(!attrs->rtcp_mux) {
|
||||
rtcp_flow = vcmCreateTransportFlow(pc.impl(), level, true,
|
||||
rtcp_flow = vcmCreateTransportFlow(pc.impl(), level, true, setup_type,
|
||||
fingerprint_alg, fingerprint);
|
||||
if (!rtcp_flow) {
|
||||
CSFLogError( logTag, "Could not create RTCP flow");
|
||||
@ -1535,6 +1539,7 @@ static int vcmRxStartICE_m(cc_mcapid_t mcap_id,
|
||||
* @param[in] peerconnection - the peerconnection in use
|
||||
* @param[in] num_payloads - number of negotiated payloads
|
||||
* @param[in] payloads - negotiated codec details list
|
||||
* @param[in] setup_type - whether playing client or server role
|
||||
* @param[in] fingerprint_alg - the DTLS fingerprint algorithm
|
||||
* @param[in] fingerprint - the DTLS fingerprint
|
||||
* @param[in] attrs - media attributes
|
||||
@ -1552,6 +1557,7 @@ int vcmRxStartICE(cc_mcapid_t mcap_id,
|
||||
const char *peerconnection,
|
||||
int num_payloads,
|
||||
const vcm_payload_info_t* payloads,
|
||||
sdp_setup_type_e setup_type,
|
||||
const char *fingerprint_alg,
|
||||
const char *fingerprint,
|
||||
vcm_mediaAttrs_t *attrs)
|
||||
@ -1570,6 +1576,7 @@ int vcmRxStartICE(cc_mcapid_t mcap_id,
|
||||
peerconnection,
|
||||
num_payloads,
|
||||
payloads,
|
||||
setup_type,
|
||||
fingerprint_alg,
|
||||
fingerprint,
|
||||
attrs,
|
||||
@ -2009,6 +2016,7 @@ int vcmTxStart(cc_mcapid_t mcap_id,
|
||||
* @param[in] peerconnection - the peerconnection in use
|
||||
* @param[in] payload - payload information
|
||||
* @param[in] tos - bit marking
|
||||
* @param[in] setup_type - whether playing the client or server role
|
||||
* @param[in] fingerprint_alg - the DTLS fingerprint algorithm
|
||||
* @param[in] fingerprint - the DTLS fingerprint
|
||||
* @param[in] attrs - media attributes
|
||||
@ -2028,6 +2036,7 @@ static int vcmTxStartICE_m(cc_mcapid_t mcap_id,
|
||||
const char *peerconnection,
|
||||
const vcm_payload_info_t *payload,
|
||||
short tos,
|
||||
sdp_setup_type_e setup_type,
|
||||
const char *fingerprint_alg,
|
||||
const char *fingerprint,
|
||||
vcm_mediaAttrs_t *attrs)
|
||||
@ -2042,7 +2051,7 @@ static int vcmTxStartICE_m(cc_mcapid_t mcap_id,
|
||||
|
||||
// Create the transport flows
|
||||
mozilla::RefPtr<TransportFlow> rtp_flow =
|
||||
vcmCreateTransportFlow(pc.impl(), level, false,
|
||||
vcmCreateTransportFlow(pc.impl(), level, false, setup_type,
|
||||
fingerprint_alg, fingerprint);
|
||||
if (!rtp_flow) {
|
||||
CSFLogError( logTag, "Could not create RTP flow");
|
||||
@ -2050,7 +2059,7 @@ static int vcmTxStartICE_m(cc_mcapid_t mcap_id,
|
||||
}
|
||||
mozilla::RefPtr<TransportFlow> rtcp_flow = nullptr;
|
||||
if(!attrs->rtcp_mux) {
|
||||
rtcp_flow = vcmCreateTransportFlow(pc.impl(), level, true,
|
||||
rtcp_flow = vcmCreateTransportFlow(pc.impl(), level, true, setup_type,
|
||||
fingerprint_alg, fingerprint);
|
||||
if (!rtcp_flow) {
|
||||
CSFLogError( logTag, "Could not create RTCP flow");
|
||||
@ -2166,6 +2175,7 @@ static int vcmTxStartICE_m(cc_mcapid_t mcap_id,
|
||||
* @param[in] peerconnection - the peerconnection in use
|
||||
* @param[in] payload - payload type
|
||||
* @param[in] tos - bit marking
|
||||
* @param[in] setup_type - whether playing client or server role.
|
||||
* @param[in] fingerprint_alg - the DTLS fingerprint algorithm
|
||||
* @param[in] fingerprint - the DTLS fingerprint
|
||||
* @param[in] attrs - media attributes
|
||||
@ -2185,6 +2195,7 @@ int vcmTxStartICE(cc_mcapid_t mcap_id,
|
||||
const char *peerconnection,
|
||||
const vcm_payload_info_t *payload,
|
||||
short tos,
|
||||
sdp_setup_type_e setup_type,
|
||||
const char *fingerprint_alg,
|
||||
const char *fingerprint,
|
||||
vcm_mediaAttrs_t *attrs)
|
||||
@ -2203,6 +2214,7 @@ int vcmTxStartICE(cc_mcapid_t mcap_id,
|
||||
peerconnection,
|
||||
payload,
|
||||
tos,
|
||||
setup_type,
|
||||
fingerprint_alg,
|
||||
fingerprint,
|
||||
attrs,
|
||||
@ -2700,8 +2712,8 @@ int vcmGetILBCMode()
|
||||
|
||||
static mozilla::RefPtr<TransportFlow>
|
||||
vcmCreateTransportFlow(sipcc::PeerConnectionImpl *pc, int level, bool rtcp,
|
||||
const char *fingerprint_alg,
|
||||
const char *fingerprint) {
|
||||
sdp_setup_type_e setup_type, const char *fingerprint_alg,
|
||||
const char *fingerprint) {
|
||||
|
||||
// TODO(ekr@rtfm.com): Check that if the flow already exists the digest
|
||||
// is the same. The only way that can happen is if
|
||||
@ -2743,13 +2755,14 @@ vcmCreateTransportFlow(sipcc::PeerConnectionImpl *pc, int level, bool rtcp,
|
||||
// party is active MUST initiate a DTLS handshake by sending a
|
||||
// ClientHello over each flow (host/port quartet).
|
||||
//
|
||||
// Currently we just hardwire the roles to be that the offerer is the
|
||||
// server, which is what you would expect from the "recommended"
|
||||
// behavior above.
|
||||
//
|
||||
// TODO(ekr@rtfm.com): implement the actpass logic above.
|
||||
dtls->SetRole(pc->GetRole() == sipcc::PeerConnectionImpl::kRoleOfferer ?
|
||||
TransportLayerDtls::SERVER : TransportLayerDtls::CLIENT);
|
||||
|
||||
// setup_type should at this point be either PASSIVE or ACTIVE
|
||||
// other a=setup values should have been negotiated out.
|
||||
MOZ_ASSERT(setup_type == SDP_SETUP_PASSIVE ||
|
||||
setup_type == SDP_SETUP_ACTIVE);
|
||||
dtls->SetRole(
|
||||
setup_type == SDP_SETUP_PASSIVE ?
|
||||
TransportLayerDtls::SERVER : TransportLayerDtls::CLIENT);
|
||||
mozilla::RefPtr<DtlsIdentity> pcid = pc->GetIdentity();
|
||||
if (!pcid) {
|
||||
return nullptr;
|
||||
@ -2859,4 +2872,52 @@ int vcmOnSdpParseError(const char *peerconnection, const char *message) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* vcmDisableRtcpComponent_m
|
||||
*
|
||||
* If we are doing rtcp-mux we need to disable component number 2 in the ICE
|
||||
* layer. Otherwise we will wait for it to connect when it is unused
|
||||
*/
|
||||
static int vcmDisableRtcpComponent_m(const char *peerconnection, int level) {
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
#endif
|
||||
MOZ_ASSERT(level > 0);
|
||||
|
||||
sipcc::PeerConnectionWrapper pc(peerconnection);
|
||||
ENSURE_PC(pc, VCM_ERROR);
|
||||
|
||||
CSFLogDebug( logTag, "%s: disabling rtcp component %d", __FUNCTION__, level);
|
||||
mozilla::RefPtr<NrIceMediaStream> stream = pc.impl()->media()->
|
||||
ice_media_stream(level-1);
|
||||
MOZ_ASSERT(stream);
|
||||
if (!stream) {
|
||||
return VCM_ERROR;
|
||||
}
|
||||
|
||||
// The second component is for RTCP
|
||||
nsresult res = stream->DisableComponent(2);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(res));
|
||||
if (!NS_SUCCEEDED(res)) {
|
||||
return VCM_ERROR;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* vcmDisableRtcpComponent
|
||||
*
|
||||
* If we are doing rtcp-mux we need to disable component number 2 in the ICE
|
||||
* layer. Otherwise we will wait for it to connect when it is unused
|
||||
*/
|
||||
int vcmDisableRtcpComponent(const char *peerconnection, int level) {
|
||||
int ret;
|
||||
mozilla::SyncRunnable::DispatchToThread(VcmSIPCCBinding::getMainThread(),
|
||||
WrapRunnableNMRet(&vcmDisableRtcpComponent_m,
|
||||
peerconnection,
|
||||
level,
|
||||
&ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -335,7 +335,6 @@ NS_IMPL_ISUPPORTS1(PeerConnectionImpl, IPeerConnection)
|
||||
PeerConnectionImpl::PeerConnectionImpl()
|
||||
: mTimeCard(PR_LOG_TEST(signalingLogInfo(),PR_LOG_ERROR) ?
|
||||
create_timecard() : nullptr)
|
||||
, mRole(kRoleUnknown)
|
||||
, mCall(NULL)
|
||||
, mReadyState(kNew)
|
||||
, mSignalingState(kSignalingStable)
|
||||
@ -1022,8 +1021,6 @@ PeerConnectionImpl::CreateOffer(MediaConstraints& constraints)
|
||||
mTimeCard = nullptr;
|
||||
STAMP_TIMECARD(tc, "Create Offer");
|
||||
|
||||
mRole = kRoleOfferer; // TODO(ekr@rtfm.com): Interrogate SIPCC here?
|
||||
|
||||
cc_media_constraints_t* cc_constraints = nullptr;
|
||||
constraints.buildArray(&cc_constraints);
|
||||
|
||||
@ -1054,8 +1051,6 @@ PeerConnectionImpl::CreateAnswer(MediaConstraints& constraints)
|
||||
mTimeCard = nullptr;
|
||||
STAMP_TIMECARD(tc, "Create Answer");
|
||||
|
||||
mRole = kRoleAnswerer; // TODO(ekr@rtfm.com): Interrogate SIPCC here?
|
||||
|
||||
cc_media_constraints_t* cc_constraints = nullptr;
|
||||
constraints.buildArray(&cc_constraints);
|
||||
|
||||
|
@ -165,12 +165,6 @@ public:
|
||||
kIceFailed
|
||||
};
|
||||
|
||||
enum Role {
|
||||
kRoleUnknown,
|
||||
kRoleOfferer,
|
||||
kRoleAnswerer
|
||||
};
|
||||
|
||||
enum Error {
|
||||
kNoError = 0,
|
||||
kInvalidConstraintsType = 1,
|
||||
@ -195,11 +189,6 @@ public:
|
||||
static already_AddRefed<DOMMediaStream> MakeMediaStream(nsPIDOMWindow* aWindow,
|
||||
uint32_t aHint);
|
||||
|
||||
Role GetRole() const {
|
||||
PC_AUTO_ENTER_API_CALL_NO_CHECK();
|
||||
return mRole;
|
||||
}
|
||||
|
||||
nsresult CreateRemoteSourceStreamInfo(nsRefPtr<RemoteSourceStreamInfo>* aInfo);
|
||||
|
||||
// Implementation of the only observer we need
|
||||
@ -339,9 +328,6 @@ private:
|
||||
// any other attributes of this class.
|
||||
Timecard *mTimeCard;
|
||||
|
||||
// The role we are adopting
|
||||
Role mRole;
|
||||
|
||||
// The call
|
||||
CSF::CC_CallPtr mCall;
|
||||
ReadyState mReadyState;
|
||||
|
@ -528,6 +528,9 @@ gsmsdp_init_media (fsmdef_media_t *media)
|
||||
media->candidate_ct = 0;
|
||||
media->rtcp_mux = FALSE;
|
||||
|
||||
/* ACTPASS is the value we put in every offer */
|
||||
media->setup = SDP_SETUP_ACTPASS;
|
||||
|
||||
media->local_datachannel_port = 0;
|
||||
media->remote_datachannel_port = 0;
|
||||
media->datachannel_streams = WEBRTC_DATACHANNEL_STREAMS_DEFAULT;
|
||||
@ -1821,6 +1824,71 @@ gsmsdp_set_rtcp_mux_attribute (sdp_attr_e sdp_attr, uint16_t level, void *sdp_p,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* gsmsdp_set_setup_attribute
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* Adds a setup attribute to the specified SDP.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* level - The media level of the SDP where the media attribute exists.
|
||||
* sdp_p - Pointer to the SDP to set the ice candidate attribute against.
|
||||
* setup_type - Value for the a=setup line
|
||||
*/
|
||||
static void
|
||||
gsmsdp_set_setup_attribute(uint16_t level,
|
||||
void *sdp_p, sdp_setup_type_e setup_type) {
|
||||
uint16_t a_instance = 0;
|
||||
sdp_result_e result;
|
||||
|
||||
result = sdp_add_new_attr(sdp_p, level, 0, SDP_ATTR_SETUP, &a_instance);
|
||||
if (result != SDP_SUCCESS) {
|
||||
GSM_ERR_MSG("Failed to add attribute");
|
||||
return;
|
||||
}
|
||||
|
||||
result = sdp_attr_set_setup_attribute(sdp_p, level, 0,
|
||||
a_instance, setup_type);
|
||||
if (result != SDP_SUCCESS) {
|
||||
GSM_ERR_MSG("Failed to set attribute");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* gsmsdp_set_connection_attribute
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* Adds a connection attribute to the specified SDP.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* level - The media level of the SDP where the media attribute exists.
|
||||
* sdp_p - Pointer to the SDP to set the ice candidate attribute against.
|
||||
* connection_type - Value for the a=connection line
|
||||
*/
|
||||
static void
|
||||
gsmsdp_set_connection_attribute(uint16_t level,
|
||||
void *sdp_p, sdp_connection_type_e connection_type) {
|
||||
uint16_t a_instance = 0;
|
||||
sdp_result_e result;
|
||||
|
||||
result = sdp_add_new_attr(sdp_p, level, 0, SDP_ATTR_CONNECTION,
|
||||
&a_instance);
|
||||
if (result != SDP_SUCCESS) {
|
||||
GSM_ERR_MSG("Failed to add attribute");
|
||||
return;
|
||||
}
|
||||
|
||||
result = sdp_attr_set_connection_attribute(sdp_p, level, 0,
|
||||
a_instance, connection_type);
|
||||
if (result != SDP_SUCCESS) {
|
||||
GSM_ERR_MSG("Failed to set attribute");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* gsmsdp_set_dtls_fingerprint_attribute
|
||||
*
|
||||
@ -4641,6 +4709,7 @@ gsmsdp_negotiate_media_lines (fsm_fcb_t *fcb_p, cc_sdp_t *sdp_p, boolean initial
|
||||
sdp_result_e sdp_res;
|
||||
boolean created_media_stream = FALSE;
|
||||
int lsm_rc;
|
||||
sdp_setup_type_e remote_setup_type;
|
||||
|
||||
config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode));
|
||||
|
||||
@ -4939,6 +5008,40 @@ gsmsdp_negotiate_media_lines (fsm_fcb_t *fcb_p, cc_sdp_t *sdp_p, boolean initial
|
||||
if (sdpmode) {
|
||||
int j;
|
||||
|
||||
/* Find the remote a=setup value */
|
||||
sdp_res = sdp_attr_get_setup_attribute(
|
||||
sdp_p->dest_sdp, i, 0, 1, &remote_setup_type);
|
||||
|
||||
|
||||
/* setup attribute
|
||||
We are setting our local SDP to be ACTIVE if the value
|
||||
in the remote SDP is missing, PASSIVE or ACTPASS.
|
||||
If the remote value is ACTIVE, then we will respond
|
||||
with PASSIVE.
|
||||
If the remote value is HOLDCONN we will respond with
|
||||
HOLDCONN and set the direction to INACTIVE
|
||||
The DTLS role will then be set when the TransportFlow
|
||||
is created */
|
||||
media->setup = SDP_SETUP_ACTIVE;
|
||||
|
||||
if (sdp_res == SDP_SUCCESS) {
|
||||
if (remote_setup_type == SDP_SETUP_ACTIVE) {
|
||||
media->setup = SDP_SETUP_PASSIVE;
|
||||
} else if (remote_setup_type == SDP_SETUP_HOLDCONN) {
|
||||
media->setup = SDP_SETUP_HOLDCONN;
|
||||
media->direction = SDP_DIRECTION_INACTIVE;
|
||||
}
|
||||
}
|
||||
|
||||
gsmsdp_set_setup_attribute(media->level, dcb_p->sdp->src_sdp,
|
||||
media->setup);
|
||||
|
||||
/* TODO(ehugg) we are not yet supporting existing connections
|
||||
See bug 857115. We currently always respond with
|
||||
connection:new */
|
||||
gsmsdp_set_connection_attribute(media->level,
|
||||
dcb_p->sdp->src_sdp, SDP_CONNECTION_NEW);
|
||||
|
||||
/* Set ICE */
|
||||
for (j=0; j<media->candidate_ct; j++) {
|
||||
gsmsdp_set_ice_attribute (SDP_ATTR_ICE_CANDIDATE, media->level,
|
||||
@ -5456,6 +5559,13 @@ gsmsdp_add_media_line (fsmdef_dcb_t *dcb_p, const cc_media_cap_t *media_cap,
|
||||
SDP_RTCP_FB_CCM_TO_BITMAP(SDP_RTCP_FB_CCM_FIR));
|
||||
}
|
||||
|
||||
/* setup and connection attributes */
|
||||
gsmsdp_set_setup_attribute(level, dcb_p->sdp->src_sdp, media->setup);
|
||||
|
||||
/* This is a new media line so we should send connection:new */
|
||||
gsmsdp_set_connection_attribute(level, dcb_p->sdp->src_sdp,
|
||||
SDP_CONNECTION_NEW);
|
||||
|
||||
/*
|
||||
* wait until here to set ICE candidates as SDP is now initialized
|
||||
*/
|
||||
@ -6834,6 +6944,17 @@ gsmsdp_install_peer_ice_attributes(fsm_fcb_t *fcb_p)
|
||||
if (!GSMSDP_MEDIA_ENABLED(media))
|
||||
continue;
|
||||
|
||||
/* If we are muxing, disable the second
|
||||
component of the ICE stream */
|
||||
if (media->rtcp_mux) {
|
||||
vcm_res = vcmDisableRtcpComponent(dcb_p->peerconnection,
|
||||
media->level);
|
||||
|
||||
if (vcm_res) {
|
||||
return (CC_CAUSE_SETTING_ICE_SESSION_PARAMETERS_FAILED);
|
||||
}
|
||||
}
|
||||
|
||||
sdp_res = sdp_attr_get_ice_attribute(sdp_p->dest_sdp, media->level, 0,
|
||||
SDP_ATTR_ICE_UFRAG, 1, &ufrag);
|
||||
if (sdp_res != SDP_SUCCESS)
|
||||
|
@ -207,6 +207,11 @@ typedef struct fsmdef_media_t_ {
|
||||
*/
|
||||
boolean rtcp_mux;
|
||||
|
||||
/*
|
||||
* The value of the a=setup line
|
||||
*/
|
||||
sdp_setup_type_e setup;
|
||||
|
||||
/*
|
||||
* port number used in m= data channel line
|
||||
*/
|
||||
|
@ -1006,6 +1006,7 @@ lsm_rx_start (lsm_lcb_t *lcb, const char *fname, fsmdef_media_t *media)
|
||||
dcb->peerconnection,
|
||||
media->num_payloads,
|
||||
media->payloads,
|
||||
media->setup,
|
||||
FSM_NEGOTIATED_CRYPTO_DIGEST_ALGORITHM(media),
|
||||
FSM_NEGOTIATED_CRYPTO_DIGEST(media),
|
||||
&attrs);
|
||||
@ -1276,6 +1277,7 @@ lsm_tx_start (lsm_lcb_t *lcb, const char *fname, fsmdef_media_t *media)
|
||||
dcb->peerconnection,
|
||||
media->payloads,
|
||||
(short)dscp,
|
||||
media->setup,
|
||||
FSM_NEGOTIATED_CRYPTO_DIGEST_ALGORITHM(media),
|
||||
FSM_NEGOTIATED_CRYPTO_DIGEST(media),
|
||||
&attrs) == -1)
|
||||
|
@ -179,7 +179,7 @@ static const int gDscpCallControl = 1;
|
||||
static const int gSpeakerEnabled = 1;
|
||||
static const char gExternalNumberMask[] = "";
|
||||
static const char gVersion[] = "0.1";
|
||||
static const boolean gRTCPMUX = FALSE;
|
||||
static const boolean gRTCPMUX = TRUE;
|
||||
static boolean gRTPSAVPF = TRUE; /* TRUE = RTP/SAVPF , FALSE = RTP/SAVP */
|
||||
static const boolean gMAXAVBITRATE = FALSE; /* Following six are OPUS fmtp options */
|
||||
static const boolean gMAXCODEDAUDIOBW = FALSE;
|
||||
|
@ -519,6 +519,14 @@ typedef enum {
|
||||
SDP_RTCP_FB_CCM_UNKNOWN
|
||||
} sdp_rtcp_fb_ccm_type_e;
|
||||
|
||||
typedef enum {
|
||||
SDP_CONNECTION_NOT_FOUND = -1,
|
||||
SDP_CONNECTION_NEW = 0,
|
||||
SDP_CONNECTION_EXISTING,
|
||||
SDP_MAX_CONNECTION,
|
||||
SDP_CONNECTION_UNKNOWN
|
||||
} sdp_connection_type_e;
|
||||
|
||||
#define SDP_RTCP_FB_NACK_TO_BITMAP(type) (1 << (type))
|
||||
#define SDP_RTCP_FB_ACK_TO_BITMAP(type) (1 << (SDP_MAX_RTCP_FB_NACK + (type)))
|
||||
#define SDP_RTCP_FB_CCM_TO_BITMAP(type) (1 << (SDP_MAX_RTCP_FB_NACK + \
|
||||
@ -1017,6 +1025,8 @@ typedef struct sdp_attr {
|
||||
char unknown[SDP_MAX_STRING_LEN+1];
|
||||
sdp_source_filter_t source_filter;
|
||||
sdp_fmtp_fb_t rtcp_fb;
|
||||
sdp_setup_type_e setup;
|
||||
sdp_connection_type_e connection;
|
||||
} attr;
|
||||
struct sdp_attr *next_p;
|
||||
} sdp_attr_t;
|
||||
@ -2069,6 +2079,23 @@ sdp_result_e
|
||||
sdp_attr_set_rtcp_mux_attribute(void *sdp_ptr, u16 level,
|
||||
u8 cap_num, sdp_attr_e sdp_attr, u16 inst_num, const tinybool rtcp_mux);
|
||||
|
||||
|
||||
sdp_result_e
|
||||
sdp_attr_get_setup_attribute (void *sdp_ptr, u16 level,
|
||||
u8 cap_num, u16 inst_num, sdp_setup_type_e *setup_type);
|
||||
|
||||
sdp_result_e
|
||||
sdp_attr_set_setup_attribute(void *sdp_ptr, u16 level,
|
||||
u8 cap_num, u16 inst_num, sdp_setup_type_e setup_type);
|
||||
|
||||
sdp_result_e
|
||||
sdp_attr_get_connection_attribute (void *sdp_ptr, u16 level,
|
||||
u8 cap_num, u16 inst_num, sdp_connection_type_e *connection_type);
|
||||
|
||||
sdp_result_e
|
||||
sdp_attr_set_connection_attribute(void *sdp_ptr, u16 level,
|
||||
u8 cap_num, u16 inst_num, sdp_connection_type_e connection_type);
|
||||
|
||||
sdp_result_e
|
||||
sdp_attr_get_dtls_fingerprint_attribute (void *sdp_ptr, u16 level,
|
||||
u8 cap_num, sdp_attr_e sdp_attr, u16 inst_num,
|
||||
|
@ -4986,3 +4986,127 @@ sdp_result_e sdp_parse_attr_rtcp_fb (sdp_t *sdp_p,
|
||||
|
||||
return SDP_SUCCESS;
|
||||
}
|
||||
|
||||
sdp_result_e sdp_build_attr_setup(sdp_t *sdp_p,
|
||||
sdp_attr_t *attr_p,
|
||||
flex_string *fs)
|
||||
{
|
||||
switch (attr_p->attr.setup) {
|
||||
case SDP_SETUP_ACTIVE:
|
||||
case SDP_SETUP_PASSIVE:
|
||||
case SDP_SETUP_ACTPASS:
|
||||
case SDP_SETUP_HOLDCONN:
|
||||
flex_string_sprintf(fs, "a=%s:%s\r\n",
|
||||
sdp_attr[attr_p->type].name,
|
||||
sdp_setup_type_val[attr_p->attr.setup].name);
|
||||
break;
|
||||
default:
|
||||
CSFLogError(logTag, "%s Error: Invalid setup enum (%d)",
|
||||
sdp_p->debug_str, attr_p->attr.setup);
|
||||
return SDP_FAILURE;
|
||||
}
|
||||
|
||||
return SDP_SUCCESS;
|
||||
}
|
||||
|
||||
sdp_result_e sdp_parse_attr_setup(sdp_t *sdp_p,
|
||||
sdp_attr_t *attr_p,
|
||||
const char *ptr)
|
||||
{
|
||||
int i = find_token_enum("setup attribute", sdp_p, &ptr,
|
||||
sdp_setup_type_val,
|
||||
SDP_MAX_SETUP, SDP_SETUP_UNKNOWN);
|
||||
|
||||
if (i < 0) {
|
||||
sdp_parse_error(sdp_p->peerconnection,
|
||||
"%s Warning: could not parse setup attribute",
|
||||
sdp_p->debug_str);
|
||||
sdp_p->conf_p->num_invalid_param++;
|
||||
return SDP_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
attr_p->attr.setup = (sdp_setup_type_e) i;
|
||||
|
||||
switch (attr_p->attr.setup) {
|
||||
case SDP_SETUP_ACTIVE:
|
||||
case SDP_SETUP_PASSIVE:
|
||||
case SDP_SETUP_ACTPASS:
|
||||
case SDP_SETUP_HOLDCONN:
|
||||
/* All these values are OK */
|
||||
break;
|
||||
case SDP_SETUP_UNKNOWN:
|
||||
sdp_parse_error(sdp_p->peerconnection,
|
||||
"%s Warning: Unknown setup attribute",
|
||||
sdp_p->debug_str);
|
||||
return SDP_INVALID_PARAMETER;
|
||||
break;
|
||||
default:
|
||||
/* This is an internal error, not a parsing error */
|
||||
CSFLogError(logTag, "%s Error: Invalid setup enum (%d)",
|
||||
sdp_p->debug_str, attr_p->attr.setup);
|
||||
return SDP_FAILURE;
|
||||
break;
|
||||
}
|
||||
|
||||
return SDP_SUCCESS;
|
||||
}
|
||||
|
||||
sdp_result_e sdp_build_attr_connection(sdp_t *sdp_p,
|
||||
sdp_attr_t *attr_p,
|
||||
flex_string *fs)
|
||||
{
|
||||
switch (attr_p->attr.connection) {
|
||||
case SDP_CONNECTION_NEW:
|
||||
case SDP_CONNECTION_EXISTING:
|
||||
flex_string_sprintf(fs, "a=%s:%s\r\n",
|
||||
sdp_attr[attr_p->type].name,
|
||||
sdp_connection_type_val[attr_p->attr.connection].name);
|
||||
break;
|
||||
default:
|
||||
CSFLogError(logTag, "%s Error: Invalid connection enum (%d)",
|
||||
sdp_p->debug_str, attr_p->attr.connection);
|
||||
return SDP_FAILURE;
|
||||
}
|
||||
|
||||
return SDP_SUCCESS;
|
||||
}
|
||||
|
||||
sdp_result_e sdp_parse_attr_connection(sdp_t *sdp_p,
|
||||
sdp_attr_t *attr_p,
|
||||
const char *ptr)
|
||||
{
|
||||
int i = find_token_enum("connection attribute", sdp_p, &ptr,
|
||||
sdp_connection_type_val,
|
||||
SDP_MAX_CONNECTION, SDP_CONNECTION_UNKNOWN);
|
||||
|
||||
if (i < 0) {
|
||||
sdp_parse_error(sdp_p->peerconnection,
|
||||
"%s Warning: could not parse connection attribute",
|
||||
sdp_p->debug_str);
|
||||
sdp_p->conf_p->num_invalid_param++;
|
||||
return SDP_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
attr_p->attr.connection = (sdp_connection_type_e) i;
|
||||
|
||||
switch (attr_p->attr.connection) {
|
||||
case SDP_CONNECTION_NEW:
|
||||
case SDP_CONNECTION_EXISTING:
|
||||
/* All these values are OK */
|
||||
break;
|
||||
case SDP_CONNECTION_UNKNOWN:
|
||||
sdp_parse_error(sdp_p->peerconnection,
|
||||
"%s Warning: Unknown connection attribute",
|
||||
sdp_p->debug_str);
|
||||
return SDP_INVALID_PARAMETER;
|
||||
break;
|
||||
default:
|
||||
/* This is an internal error, not a parsing error */
|
||||
CSFLogError(logTag, "%s Error: Invalid connection enum (%d)",
|
||||
sdp_p->debug_str, attr_p->attr.connection);
|
||||
return SDP_FAILURE;
|
||||
break;
|
||||
}
|
||||
|
||||
return SDP_SUCCESS;
|
||||
}
|
||||
|
@ -4084,6 +4084,163 @@ sdp_result_e sdp_attr_set_rtcp_mux_attribute(void *sdp_ptr, u16 level,
|
||||
return (SDP_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
/* Function: sdp_attr_get_setup_attribute
|
||||
* Description: Returns the value of a setup attribute at a given level
|
||||
*
|
||||
* Parameters: sdp_ptr The SDP handle returned by sdp_init_description.
|
||||
* level The level to check for the attribute.
|
||||
* cap_num The capability number associated with the
|
||||
* attribute if any. If none, should be zero.
|
||||
* inst_num The attribute instance number to check.
|
||||
* setup_type Returns sdp_setup_type_e enum
|
||||
* Returns:
|
||||
* SDP_SUCCESS Attribute param was set successfully.
|
||||
* SDP_INVALID_SDP_PTR SDP pointer invalid
|
||||
* SDP_INVALID_PARAMETER Specified attribute is not defined.
|
||||
*/
|
||||
sdp_result_e sdp_attr_get_setup_attribute (void *sdp_ptr, u16 level,
|
||||
u8 cap_num, u16 inst_num, sdp_setup_type_e *setup_type)
|
||||
{
|
||||
sdp_t *sdp_p = (sdp_t *)sdp_ptr;
|
||||
sdp_attr_t *attr_p;
|
||||
|
||||
if (!sdp_verify_sdp_ptr(sdp_p)) {
|
||||
return SDP_INVALID_SDP_PTR;
|
||||
}
|
||||
|
||||
attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_SETUP, inst_num);
|
||||
if (!attr_p) {
|
||||
if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
|
||||
CSFLogError(logTag,
|
||||
"%s setup attribute, level %u instance %u not found.",
|
||||
sdp_p->debug_str, level, inst_num);
|
||||
}
|
||||
sdp_p->conf_p->num_invalid_param++;
|
||||
return SDP_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
*setup_type = attr_p->attr.setup;
|
||||
return SDP_SUCCESS;
|
||||
}
|
||||
|
||||
/* Function: sdp_attr_set_setup_attribute
|
||||
* Description: Sets the value of a setup attribute parameter
|
||||
*
|
||||
* Parameters: sdp_ptr The SDP handle returned by sdp_init_description.
|
||||
* level The level to set the attribute.
|
||||
* cap_num The capability number associated with the
|
||||
* attribute if any. If none, should be zero.
|
||||
* inst_num The attribute instance number to check.
|
||||
* setup_type setup attribute value to set
|
||||
* Returns: SDP_SUCCESS Attribute param was set successfully.
|
||||
* SDP_INVALID_SDP_PTR SDP ptr invalid
|
||||
* SDP_INVALID_PARAMETER Specified attribute is not defined.
|
||||
*/
|
||||
sdp_result_e
|
||||
sdp_attr_set_setup_attribute(void *sdp_ptr, u16 level,
|
||||
u8 cap_num, u16 inst_num, sdp_setup_type_e setup_type)
|
||||
{
|
||||
sdp_t *sdp_p = (sdp_t *)sdp_ptr;
|
||||
sdp_attr_t *attr_p;
|
||||
|
||||
if (!sdp_verify_sdp_ptr(sdp_p)) {
|
||||
return SDP_INVALID_SDP_PTR;
|
||||
}
|
||||
|
||||
attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_SETUP, inst_num);
|
||||
if (!attr_p) {
|
||||
if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
|
||||
CSFLogError(logTag, "%s setup attribute, level %u instance %u "
|
||||
"not found.", sdp_p->debug_str, level, inst_num);
|
||||
}
|
||||
sdp_p->conf_p->num_invalid_param++;
|
||||
return SDP_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
attr_p->attr.setup = setup_type;
|
||||
return SDP_SUCCESS;
|
||||
}
|
||||
|
||||
/* Function: sdp_attr_get_connection_attribute
|
||||
* Description: Returns the value of a connection attribute at a given level
|
||||
*
|
||||
* Parameters: sdp_ptr The SDP handle returned by sdp_init_description.
|
||||
* level The level to check for the attribute.
|
||||
* cap_num The capability number associated with the
|
||||
* attribute if any. If none, should be zero.
|
||||
* inst_num The attribute instance number to check.
|
||||
* connection_type Returns sdp_connection_type_e enum
|
||||
* Returns:
|
||||
* SDP_SUCCESS Attribute param was set successfully.
|
||||
* SDP_INVALID_SDP_PTR SDP pointer invalid
|
||||
* SDP_INVALID_PARAMETER Specified attribute is not defined.
|
||||
*/
|
||||
sdp_result_e sdp_attr_get_connection_attribute (void *sdp_ptr, u16 level,
|
||||
u8 cap_num, u16 inst_num, sdp_connection_type_e *connection_type)
|
||||
{
|
||||
sdp_t *sdp_p = (sdp_t *)sdp_ptr;
|
||||
sdp_attr_t *attr_p;
|
||||
|
||||
if (!sdp_verify_sdp_ptr(sdp_p)) {
|
||||
return SDP_INVALID_SDP_PTR;
|
||||
}
|
||||
|
||||
attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_CONNECTION,
|
||||
inst_num);
|
||||
if (!attr_p) {
|
||||
if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
|
||||
CSFLogError(logTag,
|
||||
"%s setup attribute, level %u instance %u not found.",
|
||||
sdp_p->debug_str, level, inst_num);
|
||||
}
|
||||
sdp_p->conf_p->num_invalid_param++;
|
||||
return SDP_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
*connection_type = attr_p->attr.connection;
|
||||
return SDP_SUCCESS;
|
||||
}
|
||||
|
||||
/* Function: sdp_attr_set_connection_attribute
|
||||
* Description: Sets the value of a connection attribute parameter
|
||||
*
|
||||
* Parameters: sdp_ptr The SDP handle returned by sdp_init_description.
|
||||
* level The level to set the attribute.
|
||||
* cap_num The capability number associated with the
|
||||
* attribute if any. If none, should be zero.
|
||||
* inst_num The attribute instance number to check.
|
||||
* connection_type connection attribute value to set
|
||||
* Returns: SDP_SUCCESS Attribute param was set successfully.
|
||||
* SDP_INVALID_SDP_PTR SDP ptr invalid
|
||||
* SDP_INVALID_PARAMETER Specified attribute is not defined.
|
||||
*/
|
||||
sdp_result_e
|
||||
sdp_attr_set_connection_attribute(void *sdp_ptr, u16 level,
|
||||
u8 cap_num, u16 inst_num, sdp_connection_type_e connection_type)
|
||||
{
|
||||
sdp_t *sdp_p = (sdp_t *)sdp_ptr;
|
||||
sdp_attr_t *attr_p;
|
||||
|
||||
if (!sdp_verify_sdp_ptr(sdp_p)) {
|
||||
return SDP_INVALID_SDP_PTR;
|
||||
}
|
||||
|
||||
attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_CONNECTION,
|
||||
inst_num);
|
||||
if (!attr_p) {
|
||||
if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
|
||||
CSFLogError(logTag, "%s connection attribute, level %u instance %u "
|
||||
"not found.", sdp_p->debug_str, level, inst_num);
|
||||
}
|
||||
sdp_p->conf_p->num_invalid_param++;
|
||||
return SDP_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
attr_p->attr.connection = connection_type;
|
||||
return SDP_SUCCESS;
|
||||
}
|
||||
|
||||
/* Function: sdp_attr_get_dtls_fingerprint_attribute
|
||||
* Description: Returns the value of dtls fingerprint attribute at a given level
|
||||
*
|
||||
|
@ -169,7 +169,11 @@ const sdp_attrarray_t sdp_attr[SDP_MAX_ATTR_TYPES] =
|
||||
{"maxptime", sizeof("maxptime"),
|
||||
sdp_parse_attr_simple_u32, sdp_build_attr_simple_u32},
|
||||
{"rtcp-fb", sizeof("rtcp-fb"),
|
||||
sdp_parse_attr_rtcp_fb, sdp_build_attr_rtcp_fb}
|
||||
sdp_parse_attr_rtcp_fb, sdp_build_attr_rtcp_fb},
|
||||
{"setup", sizeof("setup"),
|
||||
sdp_parse_attr_setup, sdp_build_attr_setup},
|
||||
{"connection", sizeof("connection"),
|
||||
sdp_parse_attr_connection, sdp_build_attr_connection},
|
||||
};
|
||||
|
||||
/* Note: These *must* be in the same order as the enum types. */
|
||||
@ -483,6 +487,21 @@ const sdp_namearray_t sdp_rtcp_fb_ccm_type_val[SDP_MAX_RTCP_FB_CCM] =
|
||||
SDP_NAME("vbcm")
|
||||
};
|
||||
|
||||
/* Maintain the same order as defined in typedef sdp_setup_type_e */
|
||||
const sdp_namearray_t sdp_setup_type_val[SDP_MAX_SETUP] =
|
||||
{
|
||||
SDP_NAME("active"),
|
||||
SDP_NAME("passive"),
|
||||
SDP_NAME("actpass"),
|
||||
SDP_NAME("holdconn")
|
||||
};
|
||||
|
||||
/* Maintain the same order as defined in typedef sdp_connection_type_e */
|
||||
const sdp_namearray_t sdp_connection_type_val[SDP_MAX_CONNECTION] =
|
||||
{
|
||||
SDP_NAME("new"),
|
||||
SDP_NAME("existing")
|
||||
};
|
||||
|
||||
/* Maintain same order as defined in typedef sdp_srtp_crypto_suite_t */
|
||||
const sdp_srtp_crypto_suite_list sdp_srtp_crypto_suite_array[SDP_SRTP_MAX_NUM_CRYPTO_SUITES] =
|
||||
|
@ -37,6 +37,8 @@ extern const sdp_namearray_t sdp_rtcp_fb_type_val[];
|
||||
extern const sdp_namearray_t sdp_rtcp_fb_nack_type_val[];
|
||||
extern const sdp_namearray_t sdp_rtcp_fb_ack_type_val[];
|
||||
extern const sdp_namearray_t sdp_rtcp_fb_ccm_type_val[];
|
||||
extern const sdp_namearray_t sdp_setup_type_val[];
|
||||
extern const sdp_namearray_t sdp_connection_type_val[];
|
||||
|
||||
|
||||
extern const sdp_srtp_crypto_suite_list sdp_srtp_crypto_suite_array[];
|
||||
@ -149,6 +151,18 @@ extern sdp_result_e sdp_parse_attr_rtcp_fb(sdp_t *sdp_p,
|
||||
extern sdp_result_e sdp_build_attr_rtcp_fb(sdp_t *sdp_p,
|
||||
sdp_attr_t *attr_p,
|
||||
flex_string *fs);
|
||||
extern sdp_result_e sdp_parse_attr_setup(sdp_t *sdp_p,
|
||||
sdp_attr_t *attr_p,
|
||||
const char *ptr);
|
||||
extern sdp_result_e sdp_build_attr_setup(sdp_t *sdp_p,
|
||||
sdp_attr_t *attr_p,
|
||||
flex_string *fs);
|
||||
extern sdp_result_e sdp_parse_attr_connection(sdp_t *sdp_p,
|
||||
sdp_attr_t *attr_p,
|
||||
const char *ptr);
|
||||
extern sdp_result_e sdp_build_attr_connection(sdp_t *sdp_p,
|
||||
sdp_attr_t *attr_p,
|
||||
flex_string *fs);
|
||||
extern sdp_result_e sdp_parse_attr_mptime(
|
||||
sdp_t *sdp_p, sdp_attr_t *attr_p, const char *ptr);
|
||||
extern sdp_result_e sdp_build_attr_mptime(
|
||||
|
@ -242,10 +242,23 @@ typedef enum {
|
||||
SDP_ATTR_DTLS_FINGERPRINT,
|
||||
SDP_ATTR_MAXPTIME,
|
||||
SDP_ATTR_RTCP_FB, /* RFC 4585 */
|
||||
SDP_ATTR_SETUP,
|
||||
SDP_ATTR_CONNECTION,
|
||||
SDP_MAX_ATTR_TYPES,
|
||||
SDP_ATTR_INVALID
|
||||
} sdp_attr_e;
|
||||
|
||||
/* This is here so that it can be used in the VcmSIPCCBinding interface */
|
||||
typedef enum {
|
||||
SDP_SETUP_NOT_FOUND = -1,
|
||||
SDP_SETUP_ACTIVE = 0,
|
||||
SDP_SETUP_PASSIVE,
|
||||
SDP_SETUP_ACTPASS,
|
||||
SDP_SETUP_HOLDCONN,
|
||||
SDP_MAX_SETUP,
|
||||
SDP_SETUP_UNKNOWN
|
||||
} sdp_setup_type_e;
|
||||
|
||||
/**
|
||||
* Gets the value of the fmtp attribute- parameter-sets parameter for H.264 codec
|
||||
*
|
||||
|
@ -585,6 +585,7 @@ int vcmRxStart(cc_mcapid_t mcap_id,
|
||||
* @param[in] peerconnection - the peerconnection in use
|
||||
* @param[in] num_payloads - number of codecs negotiated
|
||||
* @param[in] payloads - list of negotiated codec details
|
||||
* @param[in] setup_t - whether playing client or server role
|
||||
* @param[in] fingerprint_alg - the DTLS fingerprint algorithm
|
||||
* @param[in] fingerprint - the DTLS fingerprint
|
||||
* @param[in] attrs - media attributes
|
||||
@ -603,6 +604,7 @@ int vcmRxStartICE(cc_mcapid_t mcap_id,
|
||||
const char *peerconnection,
|
||||
int num_payloads,
|
||||
const vcm_payload_info_t* payloads,
|
||||
sdp_setup_type_e setup_type,
|
||||
const char *fingerprint_alg,
|
||||
const char *fingerprint,
|
||||
vcm_mediaAttrs_t *attrs);
|
||||
@ -663,6 +665,7 @@ int vcmTxStart(cc_mcapid_t mcap_id,
|
||||
* @param[in] peerconnection - the peerconnection in use
|
||||
* @param[in] payload - payload information
|
||||
* @param[in] tos - bit marking
|
||||
* @param[in] setup_type - whether playing client or server role
|
||||
* @param[in] fingerprint_alg - the DTLS fingerprint algorithm
|
||||
* @param[in] fingerprint - the DTLS fingerprint
|
||||
* @param[in] attrs - media attributes
|
||||
@ -681,6 +684,7 @@ int vcmTxStart(cc_mcapid_t mcap_id,
|
||||
const char *peerconnection,
|
||||
const vcm_payload_info_t *payload,
|
||||
short tos,
|
||||
sdp_setup_type_e setup_type,
|
||||
const char *fingerprint_alg,
|
||||
const char *fingerprint,
|
||||
vcm_mediaAttrs_t *attrs);
|
||||
@ -1035,6 +1039,14 @@ int vcmGetILBCMode();
|
||||
*/
|
||||
int vcmOnSdpParseError(const char *peercconnection, const char *message);
|
||||
|
||||
/**
|
||||
* vcmDisableRtcpComponent
|
||||
*
|
||||
* If we are doing rtcp-mux we need to disable component number 2 in the ICE
|
||||
* layer. Otherwise we will wait for it to connect when it is unused
|
||||
*/
|
||||
int vcmDisableRtcpComponent(const char *peerconnection, int level);
|
||||
|
||||
//Using C++ for gips. This is the end of extern "C" above.
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ MtransportTestUtils *test_utils;
|
||||
nsCOMPtr<nsIThread> gThread;
|
||||
|
||||
static int kDefaultTimeout = 5000;
|
||||
static bool fRtcpMux = false;
|
||||
static bool fRtcpMux = true;
|
||||
|
||||
static std::string callerName = "caller";
|
||||
static std::string calleeName = "callee";
|
||||
@ -2472,6 +2472,352 @@ TEST_F(SignalingTest, FullCallAudioNoMuxVideoMux)
|
||||
PIPELINE_VIDEO);
|
||||
}
|
||||
|
||||
// In this test we will change the offer SDP's a=setup value
|
||||
// from actpass to passive. This will make the answer do active.
|
||||
TEST_F(SignalingTest, AudioCallForceDtlsRoles)
|
||||
{
|
||||
sipcc::MediaConstraints constraints;
|
||||
size_t match;
|
||||
|
||||
a1_.CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
|
||||
|
||||
// By default the offer should give actpass
|
||||
std::string offer(a1_.offer());
|
||||
match = offer.find("\r\na=setup:actpass");
|
||||
ASSERT_NE(match, std::string::npos);
|
||||
// Now replace the actpass with passive so that the answer will
|
||||
// return active
|
||||
offer.replace(match, strlen("\r\na=setup:actpass"),
|
||||
"\r\na=setup:passive");
|
||||
std::cout << "Modified SDP " << std::endl
|
||||
<< indent(offer) << std::endl;
|
||||
|
||||
a1_.SetLocal(TestObserver::OFFER, offer.c_str(), false);
|
||||
a2_.SetRemote(TestObserver::OFFER, offer.c_str(), false);
|
||||
a2_.CreateAnswer(constraints, offer.c_str(), OFFER_AUDIO | ANSWER_AUDIO);
|
||||
|
||||
// Now the answer should contain a=setup:active
|
||||
std::string answer(a2_.answer());
|
||||
match = answer.find("\r\na=setup:active");
|
||||
ASSERT_NE(match, std::string::npos);
|
||||
|
||||
// This should setup the DTLS with the same roles
|
||||
// as the regular tests above.
|
||||
a2_.SetLocal(TestObserver::ANSWER, a2_.answer(), false);
|
||||
a1_.SetRemote(TestObserver::ANSWER, a2_.answer(), false);
|
||||
|
||||
ASSERT_TRUE_WAIT(a1_.IceCompleted() == true, kDefaultTimeout);
|
||||
ASSERT_TRUE_WAIT(a2_.IceCompleted() == true, kDefaultTimeout);
|
||||
|
||||
// Wait for some data to get written
|
||||
ASSERT_TRUE_WAIT(a1_.GetPacketsSent(0) >= 40 &&
|
||||
a2_.GetPacketsReceived(0) >= 40, kDefaultTimeout * 2);
|
||||
|
||||
a1_.CloseSendStreams();
|
||||
a2_.CloseReceiveStreams();
|
||||
|
||||
ASSERT_GE(a1_.GetPacketsSent(0), 40);
|
||||
ASSERT_GE(a2_.GetPacketsReceived(0), 40);
|
||||
}
|
||||
|
||||
// In this test we will change the offer SDP's a=setup value
|
||||
// from actpass to active. This will make the answer do passive
|
||||
TEST_F(SignalingTest, AudioCallReverseDtlsRoles)
|
||||
{
|
||||
sipcc::MediaConstraints constraints;
|
||||
size_t match;
|
||||
|
||||
a1_.CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
|
||||
|
||||
// By default the offer should give actpass
|
||||
std::string offer(a1_.offer());
|
||||
match = offer.find("\r\na=setup:actpass");
|
||||
ASSERT_NE(match, std::string::npos);
|
||||
// Now replace the actpass with active so that the answer will
|
||||
// return passive
|
||||
offer.replace(match, strlen("\r\na=setup:actpass"),
|
||||
"\r\na=setup:active");
|
||||
std::cout << "Modified SDP " << std::endl
|
||||
<< indent(offer) << std::endl;
|
||||
|
||||
a1_.SetLocal(TestObserver::OFFER, offer.c_str(), false);
|
||||
a2_.SetRemote(TestObserver::OFFER, offer.c_str(), false);
|
||||
a2_.CreateAnswer(constraints, offer.c_str(), OFFER_AUDIO | ANSWER_AUDIO);
|
||||
|
||||
// Now the answer should contain a=setup:passive
|
||||
std::string answer(a2_.answer());
|
||||
match = answer.find("\r\na=setup:passive");
|
||||
ASSERT_NE(match, std::string::npos);
|
||||
|
||||
// This should setup the DTLS with the opposite roles
|
||||
// than the regular tests above.
|
||||
a2_.SetLocal(TestObserver::ANSWER, a2_.answer(), false);
|
||||
a1_.SetRemote(TestObserver::ANSWER, a2_.answer(), false);
|
||||
|
||||
ASSERT_TRUE_WAIT(a1_.IceCompleted() == true, kDefaultTimeout);
|
||||
ASSERT_TRUE_WAIT(a2_.IceCompleted() == true, kDefaultTimeout);
|
||||
|
||||
// Wait for some data to get written
|
||||
ASSERT_TRUE_WAIT(a1_.GetPacketsSent(0) >= 40 &&
|
||||
a2_.GetPacketsReceived(0) >= 40, kDefaultTimeout * 2);
|
||||
|
||||
a1_.CloseSendStreams();
|
||||
a2_.CloseReceiveStreams();
|
||||
|
||||
ASSERT_GE(a1_.GetPacketsSent(0), 40);
|
||||
ASSERT_GE(a2_.GetPacketsReceived(0), 40);
|
||||
}
|
||||
|
||||
// In this test we will change the answer SDP's a=setup value
|
||||
// from active to passive. This will make both sides do
|
||||
// active and should not connect.
|
||||
TEST_F(SignalingTest, AudioCallMismatchDtlsRoles)
|
||||
{
|
||||
sipcc::MediaConstraints constraints;
|
||||
size_t match;
|
||||
|
||||
a1_.CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
|
||||
|
||||
// By default the offer should give actpass
|
||||
std::string offer(a1_.offer());
|
||||
match = offer.find("\r\na=setup:actpass");
|
||||
ASSERT_NE(match, std::string::npos);
|
||||
a1_.SetLocal(TestObserver::OFFER, offer.c_str(), false);
|
||||
a2_.SetRemote(TestObserver::OFFER, offer.c_str(), false);
|
||||
a2_.CreateAnswer(constraints, offer.c_str(), OFFER_AUDIO | ANSWER_AUDIO);
|
||||
|
||||
// Now the answer should contain a=setup:active
|
||||
std::string answer(a2_.answer());
|
||||
match = answer.find("\r\na=setup:active");
|
||||
ASSERT_NE(match, std::string::npos);
|
||||
|
||||
// Now replace the active with passive so that the offerer will
|
||||
// also do active.
|
||||
answer.replace(match, strlen("\r\na=setup:active"),
|
||||
"\r\na=setup:passive");
|
||||
std::cout << "Modified SDP " << std::endl
|
||||
<< indent(answer) << std::endl;
|
||||
|
||||
// This should setup the DTLS with both sides playing active
|
||||
a2_.SetLocal(TestObserver::ANSWER, answer.c_str(), false);
|
||||
a1_.SetRemote(TestObserver::ANSWER, answer.c_str(), false);
|
||||
|
||||
ASSERT_TRUE_WAIT(a1_.IceCompleted() == true, kDefaultTimeout);
|
||||
ASSERT_TRUE_WAIT(a2_.IceCompleted() == true, kDefaultTimeout);
|
||||
|
||||
// Not using ASSERT_TRUE_WAIT here because we expect failure
|
||||
PR_Sleep(kDefaultTimeout * 2); // Wait for some data to get written
|
||||
|
||||
a1_.CloseSendStreams();
|
||||
a2_.CloseReceiveStreams();
|
||||
|
||||
ASSERT_GE(a1_.GetPacketsSent(0), 40);
|
||||
// In this case we should receive nothing.
|
||||
ASSERT_EQ(a2_.GetPacketsReceived(0), 0);
|
||||
}
|
||||
|
||||
// In this test we will change the offer SDP's a=setup value
|
||||
// from actpass to garbage. It should ignore the garbage value
|
||||
// and respond with setup:active
|
||||
TEST_F(SignalingTest, AudioCallGarbageSetup)
|
||||
{
|
||||
sipcc::MediaConstraints constraints;
|
||||
size_t match;
|
||||
|
||||
a1_.CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
|
||||
|
||||
// By default the offer should give actpass
|
||||
std::string offer(a1_.offer());
|
||||
match = offer.find("\r\na=setup:actpass");
|
||||
ASSERT_NE(match, std::string::npos);
|
||||
// Now replace the actpass with a garbage value
|
||||
offer.replace(match, strlen("\r\na=setup:actpass"),
|
||||
"\r\na=setup:G4rb4g3V4lu3");
|
||||
std::cout << "Modified SDP " << std::endl
|
||||
<< indent(offer) << std::endl;
|
||||
|
||||
a1_.SetLocal(TestObserver::OFFER, offer.c_str(), false);
|
||||
a2_.SetRemote(TestObserver::OFFER, offer.c_str(), false);
|
||||
a2_.CreateAnswer(constraints, offer.c_str(), OFFER_AUDIO | ANSWER_AUDIO);
|
||||
|
||||
// Now the answer should contain a=setup:active
|
||||
std::string answer(a2_.answer());
|
||||
match = answer.find("\r\na=setup:active");
|
||||
ASSERT_NE(match, std::string::npos);
|
||||
|
||||
// This should setup the DTLS with the same roles
|
||||
// as the regular tests above.
|
||||
a2_.SetLocal(TestObserver::ANSWER, a2_.answer(), false);
|
||||
a1_.SetRemote(TestObserver::ANSWER, a2_.answer(), false);
|
||||
|
||||
ASSERT_TRUE_WAIT(a1_.IceCompleted() == true, kDefaultTimeout);
|
||||
ASSERT_TRUE_WAIT(a2_.IceCompleted() == true, kDefaultTimeout);
|
||||
|
||||
// Wait for some data to get written
|
||||
ASSERT_TRUE_WAIT(a1_.GetPacketsSent(0) >= 40 &&
|
||||
a2_.GetPacketsReceived(0) >= 40, kDefaultTimeout * 2);
|
||||
|
||||
a1_.CloseSendStreams();
|
||||
a2_.CloseReceiveStreams();
|
||||
|
||||
ASSERT_GE(a1_.GetPacketsSent(0), 40);
|
||||
ASSERT_GE(a2_.GetPacketsReceived(0), 40);
|
||||
}
|
||||
|
||||
// In this test we will change the offer SDP's a=connection value
|
||||
// from new to garbage. It should ignore the garbage value
|
||||
// and respond with connection:new
|
||||
TEST_F(SignalingTest, AudioCallGarbageConnection)
|
||||
{
|
||||
sipcc::MediaConstraints constraints;
|
||||
size_t match;
|
||||
|
||||
a1_.CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
|
||||
|
||||
// By default the offer should give connection:new
|
||||
std::string offer(a1_.offer());
|
||||
match = offer.find("\r\na=connection:new");
|
||||
ASSERT_NE(match, std::string::npos);
|
||||
// Now replace the 'new' with a garbage value
|
||||
offer.replace(match, strlen("\r\na=connection:new"),
|
||||
"\r\na=connection:G4rb4g3V4lu3");
|
||||
std::cout << "Modified SDP " << std::endl
|
||||
<< indent(offer) << std::endl;
|
||||
|
||||
a1_.SetLocal(TestObserver::OFFER, offer.c_str(), false);
|
||||
a2_.SetRemote(TestObserver::OFFER, offer.c_str(), false);
|
||||
a2_.CreateAnswer(constraints, offer.c_str(), OFFER_AUDIO | ANSWER_AUDIO);
|
||||
|
||||
// Now the answer should contain a=connection:new
|
||||
std::string answer(a2_.answer());
|
||||
match = answer.find("\r\na=connection:new");
|
||||
ASSERT_NE(match, std::string::npos);
|
||||
|
||||
// This should setup the DTLS with the same roles
|
||||
// as the regular tests above.
|
||||
a2_.SetLocal(TestObserver::ANSWER, a2_.answer(), false);
|
||||
a1_.SetRemote(TestObserver::ANSWER, a2_.answer(), false);
|
||||
|
||||
ASSERT_TRUE_WAIT(a1_.IceCompleted() == true, kDefaultTimeout);
|
||||
ASSERT_TRUE_WAIT(a2_.IceCompleted() == true, kDefaultTimeout);
|
||||
|
||||
// Wait for some data to get written
|
||||
ASSERT_TRUE_WAIT(a1_.GetPacketsSent(0) >= 40 &&
|
||||
a2_.GetPacketsReceived(0) >= 40, kDefaultTimeout * 2);
|
||||
|
||||
a1_.CloseSendStreams();
|
||||
a2_.CloseReceiveStreams();
|
||||
|
||||
ASSERT_GE(a1_.GetPacketsSent(0), 40);
|
||||
ASSERT_GE(a2_.GetPacketsReceived(0), 40);
|
||||
}
|
||||
|
||||
// In this test we will change the offer SDP to remove the
|
||||
// a=setup and a=connection lines. Answer should respond with
|
||||
// a=setup:active and a=connection:new
|
||||
TEST_F(SignalingTest, AudioCallOfferNoSetupOrConnection)
|
||||
{
|
||||
sipcc::MediaConstraints constraints;
|
||||
size_t match;
|
||||
|
||||
a1_.CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
|
||||
|
||||
// By default the offer should give setup:actpass and connection:new
|
||||
std::string offer(a1_.offer());
|
||||
match = offer.find("\r\na=setup:actpass");
|
||||
ASSERT_NE(match, std::string::npos);
|
||||
// Remove the a=setup line
|
||||
offer.replace(match, strlen("\r\na=setup:actpass"), "");
|
||||
match = offer.find("\r\na=connection:new");
|
||||
ASSERT_NE(match, std::string::npos);
|
||||
// Remove the a=connection line
|
||||
offer.replace(match, strlen("\r\na=connection:new"), "");
|
||||
std::cout << "Modified SDP " << std::endl
|
||||
<< indent(offer) << std::endl;
|
||||
|
||||
a1_.SetLocal(TestObserver::OFFER, offer.c_str(), false);
|
||||
a2_.SetRemote(TestObserver::OFFER, offer.c_str(), false);
|
||||
a2_.CreateAnswer(constraints, offer.c_str(), OFFER_AUDIO | ANSWER_AUDIO);
|
||||
|
||||
// Now the answer should contain a=setup:active and a=connection:new
|
||||
std::string answer(a2_.answer());
|
||||
match = answer.find("\r\na=setup:active");
|
||||
ASSERT_NE(match, std::string::npos);
|
||||
match = answer.find("\r\na=connection:new");
|
||||
ASSERT_NE(match, std::string::npos);
|
||||
|
||||
// This should setup the DTLS with the same roles
|
||||
// as the regular tests above.
|
||||
a2_.SetLocal(TestObserver::ANSWER, a2_.answer(), false);
|
||||
a1_.SetRemote(TestObserver::ANSWER, a2_.answer(), false);
|
||||
|
||||
ASSERT_TRUE_WAIT(a1_.IceCompleted() == true, kDefaultTimeout);
|
||||
ASSERT_TRUE_WAIT(a2_.IceCompleted() == true, kDefaultTimeout);
|
||||
|
||||
// Wait for some data to get written
|
||||
ASSERT_TRUE_WAIT(a1_.GetPacketsSent(0) >= 40 &&
|
||||
a2_.GetPacketsReceived(0) >= 40, kDefaultTimeout * 2);
|
||||
|
||||
a1_.CloseSendStreams();
|
||||
a2_.CloseReceiveStreams();
|
||||
|
||||
ASSERT_GE(a1_.GetPacketsSent(0), 40);
|
||||
ASSERT_GE(a2_.GetPacketsReceived(0), 40);
|
||||
}
|
||||
|
||||
// In this test we will change the answer SDP to remove the
|
||||
// a=setup and a=connection lines. ICE should still connect
|
||||
// since active will be assumed.
|
||||
TEST_F(SignalingTest, AudioCallAnswerNoSetupOrConnection)
|
||||
{
|
||||
sipcc::MediaConstraints constraints;
|
||||
size_t match;
|
||||
|
||||
a1_.CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
|
||||
|
||||
// By default the offer should give setup:actpass and connection:new
|
||||
std::string offer(a1_.offer());
|
||||
match = offer.find("\r\na=setup:actpass");
|
||||
ASSERT_NE(match, std::string::npos);
|
||||
match = offer.find("\r\na=connection:new");
|
||||
ASSERT_NE(match, std::string::npos);
|
||||
|
||||
a1_.SetLocal(TestObserver::OFFER, offer.c_str(), false);
|
||||
a2_.SetRemote(TestObserver::OFFER, offer.c_str(), false);
|
||||
a2_.CreateAnswer(constraints, offer.c_str(), OFFER_AUDIO | ANSWER_AUDIO);
|
||||
|
||||
// Now the answer should contain a=setup:active and a=connection:new
|
||||
std::string answer(a2_.answer());
|
||||
match = answer.find("\r\na=setup:active");
|
||||
ASSERT_NE(match, std::string::npos);
|
||||
// Remove the a=setup line
|
||||
answer.replace(match, strlen("\r\na=setup:active"), "");
|
||||
match = answer.find("\r\na=connection:new");
|
||||
ASSERT_NE(match, std::string::npos);
|
||||
// Remove the a=connection line
|
||||
answer.replace(match, strlen("\r\na=connection:new"), "");
|
||||
std::cout << "Modified SDP " << std::endl
|
||||
<< indent(answer) << std::endl;
|
||||
|
||||
// This should setup the DTLS with the same roles
|
||||
// as the regular tests above.
|
||||
a2_.SetLocal(TestObserver::ANSWER, a2_.answer(), false);
|
||||
a1_.SetRemote(TestObserver::ANSWER, a2_.answer(), false);
|
||||
|
||||
ASSERT_TRUE_WAIT(a1_.IceCompleted() == true, kDefaultTimeout);
|
||||
ASSERT_TRUE_WAIT(a2_.IceCompleted() == true, kDefaultTimeout);
|
||||
|
||||
// Wait for some data to get written
|
||||
ASSERT_TRUE_WAIT(a1_.GetPacketsSent(0) >= 40 &&
|
||||
a2_.GetPacketsReceived(0) >= 40, kDefaultTimeout * 2);
|
||||
|
||||
a1_.CloseSendStreams();
|
||||
a2_.CloseReceiveStreams();
|
||||
|
||||
ASSERT_GE(a1_.GetPacketsSent(0), 40);
|
||||
ASSERT_GE(a2_.GetPacketsReceived(0), 40);
|
||||
}
|
||||
|
||||
} // End namespace test.
|
||||
|
||||
bool is_color_terminal(const char *terminal) {
|
||||
|
@ -68,18 +68,18 @@ class RefCounted
|
||||
|
||||
public:
|
||||
// Compatibility with nsRefPtr.
|
||||
void AddRef() {
|
||||
void AddRef() const {
|
||||
MOZ_ASSERT(refCnt >= 0);
|
||||
++refCnt;
|
||||
}
|
||||
|
||||
void Release() {
|
||||
void Release() const {
|
||||
MOZ_ASSERT(refCnt > 0);
|
||||
if (0 == --refCnt) {
|
||||
#ifdef DEBUG
|
||||
refCnt = detail::DEAD;
|
||||
#endif
|
||||
delete static_cast<T*>(this);
|
||||
delete static_cast<const T*>(this);
|
||||
}
|
||||
}
|
||||
|
||||
@ -93,7 +93,7 @@ class RefCounted
|
||||
}
|
||||
|
||||
private:
|
||||
typename Conditional<Atomicity == AtomicRefCount, Atomic<int>, int>::Type refCnt;
|
||||
mutable typename Conditional<Atomicity == AtomicRefCount, Atomic<int>, int>::Type refCnt;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ import org.mozilla.gecko.gfx.GeckoLayerClient;
|
||||
import org.mozilla.gecko.gfx.ImmutableViewportMetrics;
|
||||
import org.mozilla.gecko.gfx.LayerView;
|
||||
import org.mozilla.gecko.gfx.PanZoomController;
|
||||
import org.mozilla.gecko.health.BrowserHealthRecorder;
|
||||
import org.mozilla.gecko.health.BrowserHealthReporter;
|
||||
import org.mozilla.gecko.home.BrowserSearch;
|
||||
import org.mozilla.gecko.home.HomePager;
|
||||
@ -1464,6 +1465,8 @@ abstract public class BrowserApp extends GeckoApp
|
||||
return;
|
||||
}
|
||||
|
||||
recordSearch(null, "barkeyword");
|
||||
|
||||
// Otherwise, construct a search query from the bookmark keyword.
|
||||
final String searchUrl = keywordUrl.replace("%s", URLEncoder.encode(keywordSearch));
|
||||
Tabs.getInstance().loadUrl(searchUrl, Tabs.LOADURL_USER_ENTERED);
|
||||
@ -1471,6 +1474,28 @@ abstract public class BrowserApp extends GeckoApp
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Record in Health Report that a search has occurred.
|
||||
*
|
||||
* @param identifier
|
||||
* a search identifier, such as "partnername". Can be null.
|
||||
* @param where
|
||||
* where the search was initialized; one of the values in
|
||||
* {@link BrowserHealthRecorder#SEARCH_LOCATIONS}.
|
||||
*/
|
||||
private static void recordSearch(String identifier, String where) {
|
||||
Log.i(LOGTAG, "Recording search: " + identifier + ", " + where);
|
||||
try {
|
||||
JSONObject message = new JSONObject();
|
||||
message.put("type", BrowserHealthRecorder.EVENT_SEARCH);
|
||||
message.put("location", where);
|
||||
message.put("identifier", identifier);
|
||||
GeckoAppShell.getEventDispatcher().dispatchEvent(message);
|
||||
} catch (Exception e) {
|
||||
Log.w(LOGTAG, "Error recording search.", e);
|
||||
}
|
||||
}
|
||||
|
||||
boolean dismissEditingMode() {
|
||||
if (!mBrowserToolbar.isEditing()) {
|
||||
return false;
|
||||
@ -2209,6 +2234,7 @@ abstract public class BrowserApp extends GeckoApp
|
||||
// BrowserSearch.OnSearchListener
|
||||
@Override
|
||||
public void onSearch(String engineId, String text) {
|
||||
recordSearch(engineId, "barsuggest");
|
||||
openUrl(text, engineId);
|
||||
}
|
||||
|
||||
|
@ -861,11 +861,11 @@ public class BrowserToolbar extends GeckoRelativeLayout
|
||||
return;
|
||||
}
|
||||
|
||||
// If toolbar is in edit mode, this means the entry is expanded and the
|
||||
// tabs button is translated offscreen. Don't trigger tabs counter
|
||||
// If toolbar is in edit mode on a phone, this means the entry is expanded
|
||||
// and the tabs button is translated offscreen. Don't trigger tabs counter
|
||||
// updates until the tabs button is back on screen.
|
||||
// See stopEditing()
|
||||
if (!isEditing()) {
|
||||
if (!isEditing() || HardwareUtils.isTablet()) {
|
||||
mTabsCounter.setCount(count);
|
||||
|
||||
mTabs.setContentDescription((count > 1) ?
|
||||
@ -875,11 +875,11 @@ public class BrowserToolbar extends GeckoRelativeLayout
|
||||
}
|
||||
|
||||
public void updateTabCount(int count) {
|
||||
// If toolbar is in edit mode, this means the entry is expanded and the
|
||||
// tabs button is translated offscreen. Don't trigger tabs counter
|
||||
// If toolbar is in edit mode on a phone, this means the entry is expanded
|
||||
// and the tabs button is translated offscreen. Don't trigger tabs counter
|
||||
// updates until the tabs button is back on screen.
|
||||
// See stopEditing()
|
||||
if (isEditing()) {
|
||||
if (isEditing() && !HardwareUtils.isTablet()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1378,9 +1378,10 @@ public class BrowserToolbar extends GeckoRelativeLayout
|
||||
|
||||
if (HardwareUtils.isTablet() || Build.VERSION.SDK_INT < 11) {
|
||||
hideUrlEditContainer();
|
||||
updateTabCountAndAnimate(Tabs.getInstance().getDisplayCount());
|
||||
|
||||
if (!HardwareUtils.isTablet()) {
|
||||
updateTabCountAndAnimate(Tabs.getInstance().getDisplayCount());
|
||||
|
||||
if (mUrlBarRightEdge != null) {
|
||||
ViewHelper.setTranslationX(mUrlBarRightEdge, 0);
|
||||
}
|
||||
|
@ -2347,7 +2347,10 @@ abstract public class GeckoApp
|
||||
try {
|
||||
obj.put("lac", gcl.getLac());
|
||||
obj.put("cid", gcl.getCid());
|
||||
obj.put("psc", gcl.getPsc());
|
||||
|
||||
int psc = (Build.VERSION.SDK_INT >= 9) ? gcl.getPsc() : -1;
|
||||
obj.put("psc", psc);
|
||||
|
||||
switch(tm.getNetworkType()) {
|
||||
case TelephonyManager.NETWORK_TYPE_GPRS:
|
||||
case TelephonyManager.NETWORK_TYPE_EDGE:
|
||||
|
@ -334,7 +334,6 @@ var BrowserApp = {
|
||||
Reader.init();
|
||||
UserAgentOverrides.init();
|
||||
DesktopUserAgent.init();
|
||||
ExternalApps.init();
|
||||
Distribution.init();
|
||||
Tabs.init();
|
||||
#ifdef ACCESSIBILITY
|
||||
@ -368,6 +367,9 @@ var BrowserApp = {
|
||||
SearchEngines.init();
|
||||
this.initContextMenu();
|
||||
}
|
||||
// The order that context menu items are added is important
|
||||
// Make sure the "Open in App" context menu item appears at the bottom of the list
|
||||
ExternalApps.init();
|
||||
|
||||
// XXX maybe we don't do this if the launch was kicked off from external
|
||||
Services.io.offline = false;
|
||||
|
@ -70,7 +70,7 @@ class LibHandle;
|
||||
namespace mozilla {
|
||||
namespace detail {
|
||||
|
||||
template <> inline void RefCounted<LibHandle, AtomicRefCount>::Release();
|
||||
template <> inline void RefCounted<LibHandle, AtomicRefCount>::Release() const;
|
||||
|
||||
template <> inline RefCounted<LibHandle, AtomicRefCount>::~RefCounted()
|
||||
{
|
||||
@ -215,7 +215,7 @@ private:
|
||||
namespace mozilla {
|
||||
namespace detail {
|
||||
|
||||
template <> inline void RefCounted<LibHandle, AtomicRefCount>::Release() {
|
||||
template <> inline void RefCounted<LibHandle, AtomicRefCount>::Release() const {
|
||||
#ifdef DEBUG
|
||||
if (refCnt > 0x7fff0000)
|
||||
MOZ_ASSERT(refCnt > 0x7fffdead);
|
||||
@ -228,7 +228,7 @@ template <> inline void RefCounted<LibHandle, AtomicRefCount>::Release() {
|
||||
#else
|
||||
refCnt = 1;
|
||||
#endif
|
||||
delete static_cast<LibHandle*>(this);
|
||||
delete static_cast<const LibHandle*>(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -38,7 +38,7 @@
|
||||
<![CDATA[
|
||||
if (!this._remoteWebNavigation) {
|
||||
let jsm = "resource://gre/modules/RemoteWebNavigation.jsm";
|
||||
let RemoteWebNavigation = Components.utils.import(jsm, {}).RemoteWebNavigation;
|
||||
let RemoteWebNavigation = Cu.import(jsm, {}).RemoteWebNavigation;
|
||||
this._remoteWebNavigation = new RemoteWebNavigation(this);
|
||||
}
|
||||
return this._remoteWebNavigation;
|
||||
@ -53,8 +53,9 @@
|
||||
<![CDATA[
|
||||
if (!this._remoteWebProgress) {
|
||||
let jsm = "resource://gre/modules/RemoteWebProgress.jsm";
|
||||
let RemoteWebProgress = Components.utils.import(jsm, {}).RemoteWebProgress;
|
||||
this._remoteWebProgress = new RemoteWebProgress(this);
|
||||
let RemoteWebProgressManager = Cu.import(jsm, {}).RemoteWebProgressManager;
|
||||
this._remoteWebProgress = new RemoteWebProgressManager(this)
|
||||
.topLevelWebProgress;
|
||||
}
|
||||
return this._remoteWebProgress;
|
||||
]]>
|
||||
@ -107,8 +108,6 @@
|
||||
this.messageManager.loadFrameScript("chrome://global/content/select-child.js", true);
|
||||
}
|
||||
|
||||
this.webProgress._init();
|
||||
|
||||
let jsm = "resource://gre/modules/RemoteController.jsm";
|
||||
let RemoteController = Components.utils.import(jsm, {}).RemoteController;
|
||||
this._controller = new RemoteController(this);
|
||||
|
@ -13,36 +13,22 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
function RemoteSecurityUI()
|
||||
{
|
||||
this._state = 0;
|
||||
this._SSLStatus = null;
|
||||
this._state = 0;
|
||||
}
|
||||
|
||||
RemoteSecurityUI.prototype = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsISSLStatusProvider, Ci.nsISecureBrowserUI]),
|
||||
|
||||
// nsISSLStatusProvider
|
||||
get SSLStatus() { return this._SSLStatus; },
|
||||
|
||||
// nsISecureBrowserUI
|
||||
get state() { return this._state; },
|
||||
get tooltipText() { return ""; },
|
||||
|
||||
// nsISSLStatusProvider
|
||||
get SSLStatus() { return this._SSLStatus; },
|
||||
|
||||
_update: function (state, status) {
|
||||
let deserialized = null;
|
||||
if (status) {
|
||||
let helper = Cc["@mozilla.org/network/serialization-helper;1"]
|
||||
.getService(Components.interfaces.nsISerializationHelper);
|
||||
|
||||
deserialized = helper.deserializeObject(status)
|
||||
deserialized.QueryInterface(Ci.nsISSLStatus);
|
||||
}
|
||||
|
||||
// We must check the Extended Validation (EV) state here, on the chrome
|
||||
// process, because NSS is needed for that determination.
|
||||
if (deserialized && deserialized.isExtendedValidation)
|
||||
state |= Ci.nsIWebProgressListener.STATE_IDENTITY_EV_TOPLEVEL;
|
||||
|
||||
this._state = state;
|
||||
this._SSLStatus = deserialized;
|
||||
_update: function (aStatus, aState) {
|
||||
this._SSLStatus = aStatus;
|
||||
this._state = aState;
|
||||
}
|
||||
};
|
||||
|
@ -3,7 +3,7 @@
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["RemoteWebProgress"];
|
||||
this.EXPORTED_SYMBOLS = ["RemoteWebProgressManager"];
|
||||
|
||||
const Ci = Components.interfaces;
|
||||
const Cc = Components.classes;
|
||||
@ -28,14 +28,13 @@ RemoteWebProgressRequest.prototype = {
|
||||
get URI() { return this.uri.clone(); }
|
||||
};
|
||||
|
||||
function RemoteWebProgress(browser)
|
||||
{
|
||||
this._browser = browser;
|
||||
function RemoteWebProgress(aManager, aIsTopLevel) {
|
||||
this._manager = aManager;
|
||||
|
||||
this._isLoadingDocument = false;
|
||||
this._DOMWindow = null;
|
||||
this._isTopLevel = null;
|
||||
this._isTopLevel = aIsTopLevel;
|
||||
this._loadType = 0;
|
||||
this._progressListeners = [];
|
||||
}
|
||||
|
||||
RemoteWebProgress.prototype = {
|
||||
@ -51,101 +50,132 @@ RemoteWebProgress.prototype = {
|
||||
NOTIFY_REFRESH: 0x00000100,
|
||||
NOTIFY_ALL: 0x000001ff,
|
||||
|
||||
_init: function WP_Init() {
|
||||
this._browser.messageManager.addMessageListener("Content:StateChange", this);
|
||||
this._browser.messageManager.addMessageListener("Content:LocationChange", this);
|
||||
this._browser.messageManager.addMessageListener("Content:SecurityChange", this);
|
||||
this._browser.messageManager.addMessageListener("Content:StatusChange", this);
|
||||
},
|
||||
|
||||
_destroy: function WP_Destroy() {
|
||||
this._browser = null;
|
||||
},
|
||||
|
||||
get isLoadingDocument() { return this._isLoadingDocument },
|
||||
get DOMWindow() { return this._DOMWindow; },
|
||||
get DOMWindowID() { return 0; },
|
||||
get isTopLevel() {
|
||||
// When this object is accessed directly, it's usually obtained
|
||||
// through browser.webProgress and thus represents the top-level
|
||||
// document.
|
||||
// However, during message handling it temporarily represents
|
||||
// the webProgress that generated the notification, which may or
|
||||
// may not be a toplevel frame.
|
||||
return this._isTopLevel === null ? true : this._isTopLevel;
|
||||
},
|
||||
get isTopLevel() { return this._isTopLevel },
|
||||
get loadType() { return this._loadType; },
|
||||
|
||||
addProgressListener: function WP_AddProgressListener (aListener) {
|
||||
addProgressListener: function (aListener) {
|
||||
this._manager.addProgressListener(aListener);
|
||||
},
|
||||
|
||||
removeProgressListener: function (aListener) {
|
||||
this._manager.removeProgressListener(aListener);
|
||||
}
|
||||
};
|
||||
|
||||
function RemoteWebProgressManager (aBrowser) {
|
||||
this._browser = aBrowser;
|
||||
this._topLevelWebProgress = new RemoteWebProgress(this, true);
|
||||
this._progressListeners = [];
|
||||
|
||||
this._browser.messageManager.addMessageListener("Content:StateChange", this);
|
||||
this._browser.messageManager.addMessageListener("Content:LocationChange", this);
|
||||
this._browser.messageManager.addMessageListener("Content:SecurityChange", this);
|
||||
this._browser.messageManager.addMessageListener("Content:StatusChange", this);
|
||||
}
|
||||
|
||||
RemoteWebProgressManager.prototype = {
|
||||
get topLevelWebProgress() {
|
||||
return this._topLevelWebProgress;
|
||||
},
|
||||
|
||||
addProgressListener: function (aListener) {
|
||||
let listener = aListener.QueryInterface(Ci.nsIWebProgressListener);
|
||||
this._progressListeners.push(listener);
|
||||
},
|
||||
|
||||
removeProgressListener: function WP_RemoveProgressListener (aListener) {
|
||||
removeProgressListener: function (aListener) {
|
||||
this._progressListeners =
|
||||
this._progressListeners.filter(function (l) l != aListener);
|
||||
this._progressListeners.filter(l => l != aListener);
|
||||
},
|
||||
|
||||
_uriSpec: function (spec) {
|
||||
if (!spec)
|
||||
return null;
|
||||
return new RemoteWebProgressRequest(spec);
|
||||
_fixSSLStatusAndState: function (aStatus, aState) {
|
||||
let deserialized = null;
|
||||
if (aStatus) {
|
||||
let helper = Cc["@mozilla.org/network/serialization-helper;1"]
|
||||
.getService(Components.interfaces.nsISerializationHelper);
|
||||
|
||||
deserialized = helper.deserializeObject(aStatus)
|
||||
deserialized.QueryInterface(Ci.nsISSLStatus);
|
||||
}
|
||||
|
||||
// We must check the Extended Validation (EV) state here, on the chrome
|
||||
// process, because NSS is needed for that determination.
|
||||
if (deserialized && deserialized.isExtendedValidation)
|
||||
aState |= Ci.nsIWebProgressListener.STATE_IDENTITY_EV_TOPLEVEL;
|
||||
|
||||
return [deserialized, aState];
|
||||
},
|
||||
|
||||
receiveMessage: function WP_ReceiveMessage(aMessage) {
|
||||
this._isLoadingDocument = aMessage.json.isLoadingDocument;
|
||||
this._DOMWindow = aMessage.objects.DOMWindow;
|
||||
this._isTopLevel = aMessage.json.isTopLevel;
|
||||
this._loadType = aMessage.json.loadType;
|
||||
receiveMessage: function (aMessage) {
|
||||
let json = aMessage.json;
|
||||
let objects = aMessage.objects;
|
||||
|
||||
this._browser._contentWindow = aMessage.objects.contentWindow;
|
||||
// The top-level WebProgress is always the same, but because we don't
|
||||
// really have a concept of subframes/content we always creat a new object
|
||||
// for those.
|
||||
let webProgress = json.isTopLevel ? this._topLevelWebProgress
|
||||
: new RemoteWebProgress(this, false);
|
||||
|
||||
// The WebProgressRequest object however is always dynamic.
|
||||
let request = json.requestURI ? new RemoteWebProgressRequest(json.requestURI)
|
||||
: null;
|
||||
|
||||
// Update the actual WebProgress fields.
|
||||
webProgress._isLoadingDocument = json.isLoadingDocument;
|
||||
webProgress._DOMWindow = objects.DOMWindow;
|
||||
webProgress._loadType = json.loadType;
|
||||
|
||||
if (json.isTopLevel)
|
||||
this._browser._contentWindow = objects.contentWindow;
|
||||
|
||||
let req = this._uriSpec(aMessage.json.requestURI);
|
||||
switch (aMessage.name) {
|
||||
case "Content:StateChange":
|
||||
for each (let p in this._progressListeners) {
|
||||
p.onStateChange(this, req, aMessage.json.stateFlags, aMessage.json.status);
|
||||
for (let p of this._progressListeners) {
|
||||
p.onStateChange(webProgress, request, json.stateFlags, json.status);
|
||||
}
|
||||
break;
|
||||
|
||||
case "Content:LocationChange":
|
||||
let location = newURI(aMessage.json.location);
|
||||
let location = newURI(json.location);
|
||||
|
||||
if (aMessage.json.isTopLevel) {
|
||||
if (json.isTopLevel) {
|
||||
this._browser.webNavigation._currentURI = location;
|
||||
this._browser.webNavigation.canGoBack = aMessage.json.canGoBack;
|
||||
this._browser.webNavigation.canGoForward = aMessage.json.canGoForward;
|
||||
this._browser._characterSet = aMessage.json.charset;
|
||||
this._browser._documentURI = newURI(aMessage.json.documentURI);
|
||||
this._browser.webNavigation.canGoBack = json.canGoBack;
|
||||
this._browser.webNavigation.canGoForward = json.canGoForward;
|
||||
this._browser._characterSet = json.charset;
|
||||
this._browser._documentURI = newURI(json.documentURI);
|
||||
this._browser._imageDocument = null;
|
||||
}
|
||||
|
||||
for each (let p in this._progressListeners) {
|
||||
p.onLocationChange(this, req, location);
|
||||
for (let p of this._progressListeners) {
|
||||
p.onLocationChange(webProgress, request, location);
|
||||
}
|
||||
break;
|
||||
|
||||
case "Content:SecurityChange":
|
||||
// Invoking this getter triggers the generation of the underlying object,
|
||||
// which we need to access with ._securityUI, because .securityUI returns
|
||||
// a wrapper that makes _update inaccessible.
|
||||
void this._browser.securityUI;
|
||||
this._browser._securityUI._update(aMessage.json.state, aMessage.json.status);
|
||||
let [status, state] = this._fixSSLStatusAndState(json.status, json.state);
|
||||
|
||||
// The state passed might not be correct due to checks performed
|
||||
// on the chrome side. _update fixes that.
|
||||
for each (let p in this._progressListeners) {
|
||||
p.onSecurityChange(this, req, this._browser.securityUI.state);
|
||||
if (json.isTopLevel) {
|
||||
// Invoking this getter triggers the generation of the underlying object,
|
||||
// which we need to access with ._securityUI, because .securityUI returns
|
||||
// a wrapper that makes _update inaccessible.
|
||||
void this._browser.securityUI;
|
||||
this._browser._securityUI._update(status, state);
|
||||
}
|
||||
|
||||
for (let p of this._progressListeners) {
|
||||
p.onSecurityChange(webProgress, request, state);
|
||||
}
|
||||
break;
|
||||
|
||||
case "Content:StatusChange":
|
||||
for each (let p in this._progressListeners) {
|
||||
p.onStatusChange(this, req, aMessage.json.status, aMessage.json.message);
|
||||
for (let p of this._progressListeners) {
|
||||
p.onStatusChange(webProgress, request, json.status, json.message);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
this._isTopLevel = null;
|
||||
}
|
||||
};
|
||||
|
107
widget/windows/winrt/APZController.cpp
Normal file
107
widget/windows/winrt/APZController.cpp
Normal file
@ -0,0 +1,107 @@
|
||||
/* 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 "APZController.h"
|
||||
#include "base/message_loop.h"
|
||||
#include "mozilla/layers/GeckoContentController.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "MetroUtils.h"
|
||||
#include "nsPrintfCString.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace widget {
|
||||
namespace winrt {
|
||||
|
||||
class RequestContentRepaintEvent : public nsRunnable
|
||||
{
|
||||
typedef mozilla::layers::FrameMetrics FrameMetrics;
|
||||
|
||||
public:
|
||||
RequestContentRepaintEvent(const FrameMetrics& aFrameMetrics) : mFrameMetrics(aFrameMetrics)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHOD Run() {
|
||||
// This event shuts down the worker thread and so must be main thread.
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
CSSToScreenScale resolution = mFrameMetrics.mZoom;
|
||||
CSSRect compositedRect = mFrameMetrics.CalculateCompositedRectInCssPixels();
|
||||
|
||||
NS_ConvertASCIItoUTF16 data(nsPrintfCString("{ " \
|
||||
" \"resolution\": %.2f, " \
|
||||
" \"scrollId\": %d, " \
|
||||
" \"compositedRect\": { \"width\": %d, \"height\": %d }, " \
|
||||
" \"displayPort\": { \"x\": %d, \"y\": %d, \"width\": %d, \"height\": %d }, " \
|
||||
" \"scrollTo\": { \"x\": %d, \"y\": %d }" \
|
||||
"}",
|
||||
(float)(resolution.scale / mFrameMetrics.mDevPixelsPerCSSPixel.scale),
|
||||
(int)mFrameMetrics.mScrollId,
|
||||
(int)compositedRect.width,
|
||||
(int)compositedRect.height,
|
||||
(int)mFrameMetrics.mDisplayPort.x,
|
||||
(int)mFrameMetrics.mDisplayPort.y,
|
||||
(int)mFrameMetrics.mDisplayPort.width,
|
||||
(int)mFrameMetrics.mDisplayPort.height,
|
||||
(int)mFrameMetrics.mScrollOffset.x,
|
||||
(int)mFrameMetrics.mScrollOffset.y));
|
||||
|
||||
MetroUtils::FireObserver("apzc-request-content-repaint", data.get());
|
||||
return NS_OK;
|
||||
}
|
||||
protected:
|
||||
const FrameMetrics mFrameMetrics;
|
||||
};
|
||||
|
||||
void
|
||||
APZController::RequestContentRepaint(const FrameMetrics& aFrameMetrics)
|
||||
{
|
||||
// Send the result back to the main thread so that it can shutdown
|
||||
nsCOMPtr<nsIRunnable> r1 = new RequestContentRepaintEvent(aFrameMetrics);
|
||||
if (!NS_IsMainThread()) {
|
||||
NS_DispatchToMainThread(r1);
|
||||
} else {
|
||||
r1->Run();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
APZController::HandleDoubleTap(const CSSIntPoint& aPoint)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
APZController::HandleSingleTap(const CSSIntPoint& aPoint)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
APZController::HandleLongTap(const CSSIntPoint& aPoint)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
APZController::SendAsyncScrollDOMEvent(FrameMetrics::ViewID aScrollId, const CSSRect &aContentRect, const CSSSize &aScrollableSize)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
APZController::PostDelayedTask(Task* aTask, int aDelayMs)
|
||||
{
|
||||
MessageLoop::current()->PostDelayedTask(FROM_HERE, aTask, aDelayMs);
|
||||
}
|
||||
|
||||
void
|
||||
APZController::HandlePanBegin()
|
||||
{
|
||||
MetroUtils::FireObserver("apzc-handle-pan-begin", L"");
|
||||
}
|
||||
|
||||
void
|
||||
APZController::HandlePanEnd()
|
||||
{
|
||||
MetroUtils::FireObserver("apzc-handle-pan-end", L"");
|
||||
}
|
||||
|
||||
} } }
|
32
widget/windows/winrt/APZController.h
Normal file
32
widget/windows/winrt/APZController.h
Normal file
@ -0,0 +1,32 @@
|
||||
/* 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 "mozwrlbase.h"
|
||||
|
||||
#include "mozilla/layers/GeckoContentController.h"
|
||||
#include "FrameMetrics.h"
|
||||
#include "Units.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace widget {
|
||||
namespace winrt {
|
||||
|
||||
class APZController : public mozilla::layers::GeckoContentController
|
||||
{
|
||||
typedef mozilla::layers::FrameMetrics FrameMetrics;
|
||||
|
||||
public:
|
||||
virtual void RequestContentRepaint(const FrameMetrics& aFrameMetrics);
|
||||
virtual void HandleDoubleTap(const mozilla::CSSIntPoint& aPoint);
|
||||
virtual void HandleSingleTap(const mozilla::CSSIntPoint& aPoint);
|
||||
virtual void HandleLongTap(const mozilla::CSSIntPoint& aPoint);
|
||||
virtual void SendAsyncScrollDOMEvent(FrameMetrics::ViewID aScrollId, const mozilla::CSSRect &aContentRect, const mozilla::CSSSize &aScrollableSize);
|
||||
virtual void PostDelayedTask(Task* aTask, int aDelayMs);
|
||||
virtual void HandlePanBegin();
|
||||
virtual void HandlePanEnd();
|
||||
};
|
||||
|
||||
} } }
|
@ -197,7 +197,6 @@ FrameworkView::ShutdownXPCOM()
|
||||
mAutomationProvider = nullptr;
|
||||
|
||||
mMetroInput = nullptr;
|
||||
mD2DWindowSurface = nullptr;
|
||||
delete sSettingsArray;
|
||||
sSettingsArray = nullptr;
|
||||
mWidget = nullptr;
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include "nsGUIEvent.h"
|
||||
#include "MetroWidget.h"
|
||||
#include "MetroInput.h"
|
||||
#include "gfxWindowsPlatform.h"
|
||||
#include "gfxD2DSurface.h"
|
||||
#include "nsDataHashtable.h"
|
||||
@ -176,7 +177,6 @@ private:
|
||||
EventRegistrationToken mPrintManager;
|
||||
|
||||
private:
|
||||
nsRefPtr<gfxD2DSurface> mD2DWindowSurface;
|
||||
nsIntRect mWindowBounds; // in device-pixel coordinates
|
||||
float mDPI;
|
||||
bool mShuttingDown;
|
||||
|
@ -107,6 +107,7 @@ MetroApp::ShutdownXPCOM()
|
||||
void
|
||||
MetroApp::CoreExit()
|
||||
{
|
||||
LogFunction();
|
||||
HRESULT hr;
|
||||
ComPtr<ICoreApplicationExit> coreExit;
|
||||
HStringReference className(RuntimeClass_Windows_ApplicationModel_Core_CoreApplication);
|
||||
|
@ -4,6 +4,7 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// Moz headers (alphabetical)
|
||||
#include "MetroInput.h"
|
||||
#include "MetroUtils.h" // Logging, POINT_CEIL_*, ActivateGenericInstance, etc
|
||||
#include "MetroWidget.h" // MetroInput::mWidget
|
||||
#include "mozilla/dom/Touch.h" // Touch
|
||||
@ -161,8 +162,6 @@ MetroInput::MetroInput(MetroWidget* aWidget,
|
||||
NS_ASSERTION(aWidget, "Attempted to create MetroInput for null widget!");
|
||||
NS_ASSERTION(aWindow, "Attempted to create MetroInput for null window!");
|
||||
|
||||
mWidget->SetMetroInput(this);
|
||||
|
||||
mTokenPointerPressed.value = 0;
|
||||
mTokenPointerReleased.value = 0;
|
||||
mTokenPointerMoved.value = 0;
|
||||
@ -928,27 +927,6 @@ MetroInput::OnRightTapped(UI::Input::IGestureRecognizer* aSender,
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// Used by MetroWidget GeckoContentController callbacks
|
||||
void
|
||||
MetroInput::HandleDoubleTap(const LayoutDeviceIntPoint& aPoint)
|
||||
{
|
||||
#ifdef DEBUG_INPUT
|
||||
LogFunction();
|
||||
#endif
|
||||
nsSimpleGestureEvent* tapEvent =
|
||||
new nsSimpleGestureEvent(true,
|
||||
NS_SIMPLE_GESTURE_TAP,
|
||||
mWidget.Get(),
|
||||
0,
|
||||
0.0);
|
||||
|
||||
tapEvent->inputSource = nsIDOMMouseEvent::MOZ_SOURCE_TOUCH;
|
||||
tapEvent->refPoint = aPoint;
|
||||
tapEvent->clickCount = 2;
|
||||
tapEvent->pressure = 1;
|
||||
DispatchAsyncEventIgnoreStatus(tapEvent);
|
||||
}
|
||||
|
||||
void
|
||||
MetroInput::HandleSingleTap(const LayoutDeviceIntPoint& aPoint)
|
||||
{
|
||||
|
@ -147,8 +147,6 @@ public:
|
||||
HRESULT OnRightTapped(IGestureRecognizer* aSender,
|
||||
IRightTappedEventArgs* aArgs);
|
||||
|
||||
// Used by MetroWidget GeckoContentController callbacks
|
||||
void HandleDoubleTap(const mozilla::LayoutDeviceIntPoint& aPoint);
|
||||
void HandleSingleTap(const mozilla::LayoutDeviceIntPoint& aPoint);
|
||||
void HandleLongTap(const mozilla::LayoutDeviceIntPoint& aPoint);
|
||||
|
||||
|
@ -962,7 +962,8 @@ CompositorParent* MetroWidget::NewCompositorParent(int aSurfaceWidth, int aSurfa
|
||||
|
||||
if (ShouldUseAPZC()) {
|
||||
mRootLayerTreeId = compositor->RootLayerTreeId();
|
||||
CompositorParent::SetControllerForLayerTree(mRootLayerTreeId, this);
|
||||
mController = new APZController();
|
||||
CompositorParent::SetControllerForLayerTree(mRootLayerTreeId, mController);
|
||||
|
||||
MetroWidget::sAPZC = CompositorParent::GetAPZCTreeManager(compositor->RootLayerTreeId());
|
||||
MetroWidget::sAPZC->SetDPI(GetDPI());
|
||||
@ -1474,124 +1475,6 @@ MetroWidget::HasPendingInputEvent()
|
||||
return false;
|
||||
}
|
||||
|
||||
// GeckoContentController interface impl
|
||||
|
||||
class RequestContentRepaintEvent : public nsRunnable
|
||||
{
|
||||
public:
|
||||
RequestContentRepaintEvent(const FrameMetrics& aFrameMetrics) : mFrameMetrics(aFrameMetrics)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHOD Run() {
|
||||
// This event shuts down the worker thread and so must be main thread.
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
CSSToScreenScale resolution = mFrameMetrics.mZoom;
|
||||
CSSRect compositedRect = mFrameMetrics.CalculateCompositedRectInCssPixels();
|
||||
|
||||
NS_ConvertASCIItoUTF16 data(nsPrintfCString("{ " \
|
||||
" \"resolution\": %.2f, " \
|
||||
" \"scrollId\": %d, " \
|
||||
" \"compositedRect\": { \"width\": %d, \"height\": %d }, " \
|
||||
" \"displayPort\": { \"x\": %d, \"y\": %d, \"width\": %d, \"height\": %d }, " \
|
||||
" \"scrollTo\": { \"x\": %d, \"y\": %d }" \
|
||||
"}",
|
||||
(float)(resolution.scale / mFrameMetrics.mDevPixelsPerCSSPixel.scale),
|
||||
(int)mFrameMetrics.mScrollId,
|
||||
(int)compositedRect.width,
|
||||
(int)compositedRect.height,
|
||||
(int)mFrameMetrics.mDisplayPort.x,
|
||||
(int)mFrameMetrics.mDisplayPort.y,
|
||||
(int)mFrameMetrics.mDisplayPort.width,
|
||||
(int)mFrameMetrics.mDisplayPort.height,
|
||||
(int)mFrameMetrics.mScrollOffset.x,
|
||||
(int)mFrameMetrics.mScrollOffset.y));
|
||||
|
||||
MetroUtils::FireObserver("apzc-request-content-repaint", data.get());
|
||||
return NS_OK;
|
||||
}
|
||||
protected:
|
||||
const FrameMetrics mFrameMetrics;
|
||||
};
|
||||
|
||||
void
|
||||
MetroWidget::RequestContentRepaint(const FrameMetrics& aFrameMetrics)
|
||||
{
|
||||
LogFunction();
|
||||
|
||||
// Send the result back to the main thread so that it can shutdown
|
||||
nsCOMPtr<nsIRunnable> r1 = new RequestContentRepaintEvent(aFrameMetrics);
|
||||
if (!NS_IsMainThread()) {
|
||||
NS_DispatchToMainThread(r1);
|
||||
} else {
|
||||
r1->Run();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MetroWidget::HandleDoubleTap(const CSSIntPoint& aPoint)
|
||||
{
|
||||
LogFunction();
|
||||
|
||||
if (!mMetroInput) {
|
||||
return;
|
||||
}
|
||||
|
||||
mMetroInput->HandleDoubleTap(CSSIntPointToLayoutDeviceIntPoint(aPoint));
|
||||
}
|
||||
|
||||
void
|
||||
MetroWidget::HandleSingleTap(const CSSIntPoint& aPoint)
|
||||
{
|
||||
LogFunction();
|
||||
|
||||
if (!mMetroInput) {
|
||||
return;
|
||||
}
|
||||
|
||||
mMetroInput->HandleSingleTap(CSSIntPointToLayoutDeviceIntPoint(aPoint));
|
||||
}
|
||||
|
||||
void
|
||||
MetroWidget::HandleLongTap(const CSSIntPoint& aPoint)
|
||||
{
|
||||
LogFunction();
|
||||
|
||||
if (!mMetroInput) {
|
||||
return;
|
||||
}
|
||||
|
||||
mMetroInput->HandleLongTap(CSSIntPointToLayoutDeviceIntPoint(aPoint));
|
||||
}
|
||||
|
||||
void
|
||||
MetroWidget::SendAsyncScrollDOMEvent(FrameMetrics::ViewID aScrollId, const CSSRect &aContentRect, const CSSSize &aScrollableSize)
|
||||
{
|
||||
LogFunction();
|
||||
}
|
||||
|
||||
void
|
||||
MetroWidget::PostDelayedTask(Task* aTask, int aDelayMs)
|
||||
{
|
||||
LogFunction();
|
||||
MessageLoop::current()->PostDelayedTask(FROM_HERE, aTask, aDelayMs);
|
||||
}
|
||||
|
||||
void
|
||||
MetroWidget::HandlePanBegin()
|
||||
{
|
||||
LogFunction();
|
||||
MetroUtils::FireObserver("apzc-handle-pan-begin", L"");
|
||||
}
|
||||
|
||||
void
|
||||
MetroWidget::HandlePanEnd()
|
||||
{
|
||||
LogFunction();
|
||||
MetroUtils::FireObserver("apzc-handle-pan-end", L"");
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MetroWidget::Observe(nsISupports *subject, const char *topic, const PRUnichar *data)
|
||||
{
|
||||
|
@ -22,11 +22,11 @@
|
||||
#include "mozilla/a11y/Accessible.h"
|
||||
#endif
|
||||
#include "mozilla/layers/CompositorParent.h"
|
||||
#include "mozilla/layers/GeckoContentController.h"
|
||||
#include "mozilla/layers/APZCTreeManager.h"
|
||||
#include "mozilla/layers/LayerManagerComposite.h"
|
||||
#include "Units.h"
|
||||
#include "MetroInput.h"
|
||||
#include "nsDeque.h"
|
||||
#include "APZController.h"
|
||||
|
||||
#include "mozwrlbase.h"
|
||||
|
||||
@ -48,7 +48,6 @@ class FrameworkView;
|
||||
class DispatchMsg;
|
||||
|
||||
class MetroWidget : public nsWindowBase,
|
||||
public mozilla::layers::GeckoContentController,
|
||||
public nsIObserver
|
||||
{
|
||||
typedef mozilla::widget::WindowHook WindowHook;
|
||||
@ -58,7 +57,7 @@ class MetroWidget : public nsWindowBase,
|
||||
typedef ABI::Windows::UI::Core::IKeyEventArgs IKeyEventArgs;
|
||||
typedef ABI::Windows::UI::Core::ICharacterReceivedEventArgs ICharacterReceivedEventArgs;
|
||||
typedef mozilla::widget::winrt::FrameworkView FrameworkView;
|
||||
typedef mozilla::layers::FrameMetrics FrameMetrics;
|
||||
typedef mozilla::widget::winrt::APZController APZController;
|
||||
|
||||
static LRESULT CALLBACK
|
||||
StaticWindowProcedure(HWND aWnd, UINT aMsg, WPARAM aWParan, LPARAM aLParam);
|
||||
@ -200,21 +199,6 @@ public:
|
||||
nsresult RequestContentScroll();
|
||||
void RequestContentRepaintImplMainThread();
|
||||
|
||||
// GeckoContentController interface impl
|
||||
virtual void RequestContentRepaint(const FrameMetrics& aFrameMetrics);
|
||||
virtual void HandleDoubleTap(const mozilla::CSSIntPoint& aPoint);
|
||||
virtual void HandleSingleTap(const mozilla::CSSIntPoint& aPoint);
|
||||
virtual void HandleLongTap(const mozilla::CSSIntPoint& aPoint);
|
||||
virtual void SendAsyncScrollDOMEvent(FrameMetrics::ViewID aScrollId, const mozilla::CSSRect &aContentRect, const mozilla::CSSSize &aScrollableSize);
|
||||
virtual void PostDelayedTask(Task* aTask, int aDelayMs);
|
||||
virtual void HandlePanBegin();
|
||||
virtual void HandlePanEnd();
|
||||
|
||||
void SetMetroInput(mozilla::widget::winrt::MetroInput* aMetroInput)
|
||||
{
|
||||
mMetroInput = aMetroInput;
|
||||
}
|
||||
|
||||
protected:
|
||||
friend class FrameworkView;
|
||||
|
||||
@ -238,6 +222,16 @@ protected:
|
||||
void RemoveSubclass();
|
||||
nsIWidgetListener* GetPaintListener();
|
||||
|
||||
// Async event dispatching
|
||||
void DispatchAsyncScrollEvent(DispatchMsg* aEvent);
|
||||
void DeliverNextScrollEvent();
|
||||
void DeliverNextKeyboardEvent();
|
||||
DispatchMsg* CreateDispatchMsg(UINT aMsg, WPARAM aWParam, LPARAM aLParam);
|
||||
|
||||
public:
|
||||
static nsRefPtr<mozilla::layers::APZCTreeManager> sAPZC;
|
||||
|
||||
protected:
|
||||
OleInitializeWrapper mOleInitializeWrapper;
|
||||
WindowHook mWindowHook;
|
||||
Microsoft::WRL::ComPtr<FrameworkView> mView;
|
||||
@ -248,19 +242,8 @@ protected:
|
||||
static HWND sICoreHwnd;
|
||||
WNDPROC mMetroWndProc;
|
||||
bool mTempBasicLayerInUse;
|
||||
Microsoft::WRL::ComPtr<mozilla::widget::winrt::MetroInput> mMetroInput;
|
||||
mozilla::layers::FrameMetrics mFrameMetrics;
|
||||
uint64_t mRootLayerTreeId;
|
||||
|
||||
// Async event dispatching
|
||||
void DispatchAsyncScrollEvent(DispatchMsg* aEvent);
|
||||
void DeliverNextScrollEvent();
|
||||
void DeliverNextKeyboardEvent();
|
||||
DispatchMsg* CreateDispatchMsg(UINT aMsg, WPARAM aWParam, LPARAM aLParam);
|
||||
|
||||
nsDeque mMsgEventQueue;
|
||||
nsDeque mKeyEventQueue;
|
||||
|
||||
public:
|
||||
static nsRefPtr<mozilla::layers::APZCTreeManager> sAPZC;
|
||||
nsRefPtr<APZController> mController;
|
||||
};
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user