This commit is contained in:
Wes Kocher 2016-06-27 14:09:55 -07:00
Родитель 937776c97d a5dca92e10
Коммит c73d13f1bb
59 изменённых файлов: 646 добавлений и 455 удалений

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

@ -36,31 +36,6 @@ DocumentTimeline::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
return DocumentTimelineBinding::Wrap(aCx, this, aGivenProto);
}
/* static */ already_AddRefed<DocumentTimeline>
DocumentTimeline::Constructor(const GlobalObject& aGlobal,
const DOMHighResTimeStamp& aOriginTime,
ErrorResult& aRv)
{
nsIDocument* doc = AnimationUtils::GetCurrentRealmDocument(aGlobal.Context());
if (!doc) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
TimeDuration originTime = TimeDuration::FromMilliseconds(aOriginTime);
if (originTime == TimeDuration::Forever() ||
originTime == -TimeDuration::Forever()) {
nsAutoString inputOriginTime;
inputOriginTime.AppendFloat(aOriginTime);
aRv.ThrowTypeError<dom::MSG_TIME_VALUE_OUT_OF_RANGE>(
NS_LITERAL_STRING("Origin time"));
return nullptr;
}
RefPtr<DocumentTimeline> timeline = new DocumentTimeline(doc, originTime);
return timeline.forget();
}
Nullable<TimeDuration>
DocumentTimeline::GetCurrentTime() const
{
@ -113,9 +88,7 @@ DocumentTimeline::ToTimelineTime(const TimeStamp& aTimeStamp) const
return result;
}
result.SetValue(aTimeStamp
- timing->GetNavigationStartTimeStamp()
- mOriginTime);
result.SetValue(aTimeStamp - timing->GetNavigationStartTimeStamp());
return result;
}
@ -231,7 +204,7 @@ DocumentTimeline::ToTimeStamp(const TimeDuration& aTimeDuration) const
return result;
}
result = timing->GetNavigationStartTimeStamp() + aTimeDuration + mOriginTime;
result = timing->GetNavigationStartTimeStamp() + aTimeDuration;
return result;
}

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

@ -10,7 +10,6 @@
#include "mozilla/TimeStamp.h"
#include "AnimationTimeline.h"
#include "nsIDocument.h"
#include "nsDOMNavigationTiming.h" // for DOMHighResTimeStamp
#include "nsRefreshDriver.h"
struct JSContext;
@ -29,11 +28,10 @@ class DocumentTimeline final
, public nsARefreshObserver
{
public:
DocumentTimeline(nsIDocument* aDocument, const TimeDuration& aOriginTime)
explicit DocumentTimeline(nsIDocument* aDocument)
: AnimationTimeline(aDocument->GetParentObject())
, mDocument(aDocument)
, mIsObservingRefreshDriver(false)
, mOriginTime(aOriginTime)
{
}
@ -52,11 +50,6 @@ public:
virtual JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
static already_AddRefed<DocumentTimeline>
Constructor(const GlobalObject& aGlobal,
const DOMHighResTimeStamp& aOriginTime,
ErrorResult& aRv);
// AnimationTimeline methods
virtual Nullable<TimeDuration> GetCurrentTime() const override;
@ -91,8 +84,6 @@ protected:
// iframe).
mutable TimeStamp mLastRefreshDriverTime;
bool mIsObservingRefreshDriver;
TimeDuration mOriginTime;
};
} // namespace dom

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

@ -37,7 +37,6 @@ support-files =
document-timeline/file_document-timeline.html
mozilla/file_deferred_start.html
mozilla/file_disabled_properties.html
mozilla/file_document-timeline-origin-time-range.html
mozilla/file_hide_and_show.html
mozilla/file_partial_keyframes.html
style/file_animation-seeking-with-current-time.html
@ -83,7 +82,6 @@ skip-if = buildapp == 'mulet'
[mozilla/test_deferred_start.html]
skip-if = (toolkit == 'gonk' && debug)
[mozilla/test_disabled_properties.html]
[mozilla/test_document-timeline-origin-time-range.html]
[mozilla/test_hide_and_show.html]
[mozilla/test_partial_keyframes.html]
[style/test_animation-seeking-with-current-time.html]

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

@ -1,26 +0,0 @@
<!doctype html>
<meta charset=utf-8>
<script src="../testcommon.js"></script>
<body>
<script>
'use strict';
// If the originTime parameter passed to the DocumentTimeline exceeds
// the range of the internal storage type (a signed 64-bit integer number
// of ticks--a platform-dependent unit) then we should throw.
// Infinity isn't allowed as an origin time value and clamping to just
// inside the allowed range will just mean we overflow elsewhere.
test(function(t) {
assert_throws({name: 'TypeError'},
function() { new DocumentTimeline(Number.MAX_SAFE_INTEGER); });
}, 'Calculated current time is positive infinity');
test(function(t) {
assert_throws({name: 'TypeError'},
function() { new DocumentTimeline(-1 * Number.MAX_SAFE_INTEGER); });
}, 'Calculated current time is negative infinity');
done();
</script>
</body>

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

@ -1,14 +0,0 @@
<!doctype html>
<meta charset=utf-8>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
'use strict';
setup({explicit_done: true});
SpecialPowers.pushPrefEnv(
{ "set": [["dom.animations-api.core.enabled", true]]},
function() {
window.open("file_document-timeline-origin-time-range.html");
});
</script>

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

@ -3241,7 +3241,7 @@ DocumentTimeline*
nsDocument::Timeline()
{
if (!mDocumentTimeline) {
mDocumentTimeline = new DocumentTimeline(this, TimeDuration(0));
mDocumentTimeline = new DocumentTimeline(this);
}
return mDocumentTimeline;

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

@ -2745,7 +2745,7 @@ nsXMLHttpRequest::Send(nsIVariant* aVariant, const Nullable<RequestBody>& aBody)
// Not doing this for system XHR uses since those don't use CORS.
nsCOMPtr<nsILoadInfo> loadInfo = mChannel->GetLoadInfo();
static_cast<LoadInfo*>(loadInfo.get())->SetIncludeCookiesSecFlag();
static_cast<net::LoadInfo*>(loadInfo.get())->SetIncludeCookiesSecFlag();
}
// Blocking gets are common enough out of XHR that we should mark
@ -2851,7 +2851,7 @@ nsXMLHttpRequest::Send(nsIVariant* aVariant, const Nullable<RequestBody>& aBody)
// Because of bug 682305, we can't let listener be the XHR object itself
// because JS wouldn't be able to use it. So create a listener around 'this'.
// Make sure to hold a strong reference so that we don't leak the wrapper.
nsCOMPtr<nsIStreamListener> listener = new nsStreamListenerWrapper(this);
nsCOMPtr<nsIStreamListener> listener = new net::nsStreamListenerWrapper(this);
rv = mChannel->AsyncOpen2(listener);
listener = nullptr;

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

@ -98,5 +98,4 @@ MSG_DEF(MSG_INVALID_EASING_ERROR, 1, JSEXN_TYPEERR, "Invalid easing '{0}'.")
MSG_DEF(MSG_USELESS_SETTIMEOUT, 1, JSEXN_TYPEERR, "Useless {0} call (missing quotes around argument?)")
MSG_DEF(MSG_TOKENLIST_NO_SUPPORTED_TOKENS, 2, JSEXN_TYPEERR, "{0} attribute of <{1}> does not define any supported tokens")
MSG_DEF(MSG_CACHE_STREAM_CLOSED, 0, JSEXN_TYPEERR, "Response body is a cache file stream that has already been closed.")
MSG_DEF(MSG_TIME_VALUE_OUT_OF_RANGE, 1, JSEXN_TYPEERR, "{0} is outside the supported range for time values.")
MSG_DEF(MSG_ONLY_IF_CACHED_WITHOUT_SAME_ORIGIN, 1, JSEXN_TYPEERR, "Request mode '{0}' was used, but request cache mode 'only-if-cached' can only be used with request mode 'same-origin'.")

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

@ -153,6 +153,7 @@ TextTrack::RemoveCue(TextTrackCue& aCue, ErrorResult& aRv)
aCue.SetActive(false);
mCueList->RemoveCue(aCue, aRv);
aCue.SetTrack(nullptr);
if (mTextTrackList) {
HTMLMediaElement* mediaElement = mTextTrackList->GetMediaElement();
if (mediaElement) {

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

@ -909,11 +909,6 @@ AudioContext::Suspend(ErrorResult& aRv)
return promise.forget();
}
if (mAudioContextState == AudioContextState::Suspended) {
promise->MaybeResolve(JS::UndefinedHandleValue);
return promise.forget();
}
Destination()->Suspend();
mPromiseGripArray.AppendElement(promise);
@ -956,11 +951,6 @@ AudioContext::Resume(ErrorResult& aRv)
return promise.forget();
}
if (mAudioContextState == AudioContextState::Running) {
promise->MaybeResolve(JS::UndefinedHandleValue);
return promise.forget();
}
Destination()->Resume();
nsTArray<MediaStream*> streams;

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

@ -198,7 +198,9 @@ MediaStreamAudioSourceNode::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) cons
// Future:
// - mInputStream
size_t amount = AudioNode::SizeOfExcludingThis(aMallocSizeOf);
amount += mInputPort->SizeOfIncludingThis(aMallocSizeOf);
if (mInputPort) {
amount += mInputPort->SizeOfIncludingThis(aMallocSizeOf);
}
return amount;
}

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

@ -10,9 +10,7 @@
<pre id="test">
<script class="testbody" type="text/javascript">
SimpleTest.requestCompleteLog();
function tryToToCreateNodeOnClosedContext(ctx) {
function tryToCreateNodeOnClosedContext(ctx) {
ok(ctx.state, "closed", "The context is in closed state");
[ { name: "createBufferSource" },
@ -307,7 +305,7 @@ function testAudioContext() {
ok(!stateTracker.close.promise && !stateTracker.close.handler,
"Promise should be called before the callback, and only once");
stateTracker.close.promise = true;
tryToToCreateNodeOnClosedContext(ac);
tryToCreateNodeOnClosedContext(ac);
tryLegalOpeerationsOnClosedContext(ac);
});
}
@ -350,7 +348,7 @@ function testOfflineAudioContext() {
previousState = o.state;
o.onstatechange = afterRenderingFinished;
tryToToCreateNodeOnClosedContext(o);
tryToCreateNodeOnClosedContext(o);
tryLegalOpeerationsOnClosedContext(o);
}
@ -365,6 +363,24 @@ function testOfflineAudioContext() {
});
}
function testSuspendResumeEventLoop() {
var ac = new AudioContext();
var source = ac.createBufferSource();
source.buffer = ac.createBuffer(1, 44100, 44100);
source.onended = function() {
ok(true, "The AudioContext did resume.");
finish();
}
ac.onstatechange = function() {
ac.onstatechange = null;
ok(ac.state == "running", "initial state is running");
ac.suspend();
source.start();
ac.resume();
}
}
var remaining = 0;
function finish() {
remaining--;
@ -381,7 +397,8 @@ addLoadEvent(function() {
testOfflineAudioContext,
testScriptProcessNodeSuspended,
testMultiContextOutput,
testMultiContextInput
testMultiContextInput,
testSuspendResumeEventLoop
];
remaining = tests.length;
tests.forEach(function(f) { f() });

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

@ -10,7 +10,8 @@
* liability, trademark and document use rules apply.
*/
[Func="nsDocument::IsWebAnimationsEnabled",
Constructor (DOMHighResTimeStamp originTime)]
// Not yet implemented:
// [Constructor (DOMHighResTimeStamp originTime)]
[Func="nsDocument::IsWebAnimationsEnabled"]
interface DocumentTimeline : AnimationTimeline {
};

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

@ -50,7 +50,6 @@
#include "DrawEventRecorder.h"
#include "Preferences.h"
#include "Logging.h"
#include "mozilla/CheckedInt.h"
@ -154,9 +153,8 @@ HasCPUIDBit(unsigned int level, CPUIDRegister reg, unsigned int bit)
namespace mozilla {
namespace gfx {
int32_t LoggingPrefs::sGfxLogLevel =
PreferenceAccess::RegisterLivePref("gfx.logging.level", &sGfxLogLevel,
LOG_DEFAULT);
// In Gecko, this value is managed by gfx.logging.level in gfxPrefs.
int32_t LoggingPrefs::sGfxLogLevel = LOG_DEFAULT;
#ifdef WIN32
ID3D11Device *Factory::mD3D11Device;

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

@ -22,6 +22,7 @@
#include "Point.h"
#include "BaseRect.h"
#include "Matrix.h"
#include "LoggingConstants.h"
#if defined(MOZ_LOGGING)
extern GFX2D_API mozilla::LogModule* GetGFX2DLog();
@ -30,21 +31,6 @@ extern GFX2D_API mozilla::LogModule* GetGFX2DLog();
namespace mozilla {
namespace gfx {
// Attempting to be consistent with prlog values, but that isn't critical
// (and note that 5 has a special meaning - see the description
// with sGfxLogLevel)
const int LOG_CRITICAL = 1;
const int LOG_WARNING = 2;
const int LOG_DEBUG = 3;
const int LOG_DEBUG_PRLOG = 4;
const int LOG_EVERYTHING = 5; // This needs to be the highest value
#if defined(DEBUG)
const int LOG_DEFAULT = LOG_EVERYTHING;
#else
const int LOG_DEFAULT = LOG_CRITICAL;
#endif
#if defined(MOZ_LOGGING)
inline mozilla::LogLevel PRLogLevelForLevel(int aLevel) {
switch (aLevel) {

30
gfx/2d/LoggingConstants.h Normal file
Просмотреть файл

@ -0,0 +1,30 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef MOZILLA_GFX_LOGGING_CONSTANTS_H_
#define MOZILLA_GFX_LOGGING_CONSTANTS_H_
namespace mozilla {
namespace gfx {
// Attempting to be consistent with prlog values, but that isn't critical
// (and note that 5 has a special meaning - see the description
// with LoggingPrefs::sGfxLogLevel)
const int LOG_CRITICAL = 1;
const int LOG_WARNING = 2;
const int LOG_DEBUG = 3;
const int LOG_DEBUG_PRLOG = 4;
const int LOG_EVERYTHING = 5; // This needs to be the highest value
#if defined(DEBUG)
const int LOG_DEFAULT = LOG_EVERYTHING;
#else
const int LOG_DEFAULT = LOG_CRITICAL;
#endif
} // namespace gfx
} // namespace mozilla
#endif /* MOZILLA_GFX_LOGGING_CONSTANTS_H_ */

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

@ -1,62 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "Preferences.h"
#include "mozilla/Assertions.h"
#include "mozilla/Vector.h"
namespace mozilla {
namespace gfx {
static PreferenceAccess* sAccess = nullptr;
struct Int32Pref
{
const char* name;
int32_t* varPtr;
};
static Vector<Int32Pref>& Int32Prefs()
{
static Vector<Int32Pref>* sInt32Prefs = new Vector<Int32Pref>();
return *sInt32Prefs;
}
/* static */
int32_t
PreferenceAccess::RegisterLivePref(const char* aName, int32_t* aVar,
int32_t aDefault)
{
if (!Int32Prefs().append(Int32Pref{ aName, aVar })) {
MOZ_CRASH("GFX: RegisterLivePref failure");
}
return aDefault;
}
/* static */
void
PreferenceAccess::SetAccess(PreferenceAccess* aAccess)
{
sAccess = aAccess;
if (!sAccess) {
return;
}
#if defined(DEBUG)
static uint32_t sProvideAccessCount;
MOZ_ASSERT(!sProvideAccessCount++,
"ProvideAccess must only be called with non-nullptr once.");
#endif
for (Int32Pref pref : Int32Prefs()) {
sAccess->LivePref(pref.name, pref.varPtr, *pref.varPtr);
}
Int32Prefs().clearAndFree();
}
} // namespace gfx
} // namespace mozilla

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

@ -1,34 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_gfx_Preferences_h
#define mozilla_gfx_Preferences_h
namespace mozilla {
namespace gfx {
class PreferenceAccess
{
public:
virtual ~PreferenceAccess() {};
// This will be called with the derived class, so we will can register the
// callbacks with it.
static void SetAccess(PreferenceAccess* aAccess);
static int32_t RegisterLivePref(const char* aName, int32_t* aVar,
int32_t aDefault);
protected:
// This should connect the variable aVar to be updated whenever a preference
// aName is modified. aDefault would be used if the preference is undefined,
// so that we always get the valid value for aVar.
virtual void LivePref(const char* aName, int32_t* aVar, int32_t aDefault) = 0;
};
} // namespace gfx
} // namespace mozilla
#endif // mozilla_gfx_Preferences_h

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

@ -33,13 +33,13 @@ EXPORTS.mozilla.gfx += [
'JobScheduler_posix.h',
'JobScheduler_win32.h',
'Logging.h',
'LoggingConstants.h',
'Matrix.h',
'MatrixFwd.h',
'NumericTools.h',
'PathHelpers.h',
'PatternHelpers.h',
'Point.h',
'Preferences.h',
'Quaternion.h',
'RecordedEvent.h',
'RecordingTypes.h',
@ -161,7 +161,6 @@ UNIFIED_SOURCES += [
'PathCairo.cpp',
'PathHelpers.cpp',
'PathRecording.cpp',
'Preferences.cpp',
'Quaternion.cpp',
'RecordedEvent.cpp',
'Scale.cpp',

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

@ -4,6 +4,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "GPUChild.h"
#include "gfxPrefs.h"
#include "GPUProcessHost.h"
namespace mozilla {
@ -20,6 +21,28 @@ GPUChild::~GPUChild()
MOZ_COUNT_DTOR(GPUChild);
}
void
GPUChild::Init()
{
// Build a list of prefs the GPU process will need. Note that because we
// limit the GPU process to prefs contained in gfxPrefs, we can simplify
// the message in two ways: one, we only need to send its index in gfxPrefs
// rather than its name, and two, we only need to send prefs that don't
// have their default value.
nsTArray<GfxPrefSetting> prefs;
for (auto pref : gfxPrefs::all()) {
if (pref->HasDefaultValue()) {
return;
}
GfxPrefValue value;
pref->GetCachedValue(&value);
prefs.AppendElement(GfxPrefSetting(pref->Index(), value));
}
SendInit(prefs);
}
void
GPUChild::ActorDestroy(ActorDestroyReason aWhy)
{

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

@ -20,6 +20,8 @@ public:
explicit GPUChild(GPUProcessHost* aHost);
~GPUChild();
void Init();
static void Destroy(UniquePtr<GPUChild>&& aChild);
void ActorDestroy(ActorDestroyReason aWhy) override;

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

@ -5,6 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "GPUParent.h"
#include "gfxConfig.h"
#include "gfxPrefs.h"
#include "GPUProcessHost.h"
#include "mozilla/Assertions.h"
#include "mozilla/ipc/ProcessChild.h"
@ -31,12 +32,28 @@ GPUParent::Init(base::ProcessId aParentPid,
return false;
}
// Ensure gfxPrefs are initialized.
gfxPrefs::GetSingleton();
return true;
}
bool
GPUParent::RecvNothing()
GPUParent::RecvInit(nsTArray<GfxPrefSetting>&& prefs)
{
for (auto setting : prefs) {
gfxPrefs::Pref* pref = gfxPrefs::all()[setting.index()];
pref->SetCachedValue(setting.value());
}
return true;
}
bool
GPUParent::RecvUpdatePref(const GfxPrefSetting& setting)
{
gfxPrefs::Pref* pref = gfxPrefs::all()[setting.index()];
pref->SetCachedValue(setting.value());
return true;
}

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

@ -21,7 +21,8 @@ public:
MessageLoop* aIOLoop,
IPC::Channel* aChannel);
bool RecvNothing() override;
bool RecvInit(nsTArray<GfxPrefSetting>&& prefs) override;
bool RecvUpdatePref(const GfxPrefSetting& pref) override;
void ActorDestroy(ActorDestroyReason aWhy) override;
};

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

@ -122,6 +122,8 @@ GPUProcessHost::InitAfterConnect(bool aSucceeded)
DebugOnly<bool> rv =
mGPUChild->Open(GetChannel(), base::GetProcId(GetChildProcessHandle()));
MOZ_ASSERT(rv);
mGPUChild->Init();
}
if (mListener) {

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

@ -19,13 +19,13 @@ static StaticAutoPtr<GPUProcessManager> sSingleton;
GPUProcessManager*
GPUProcessManager::Get()
{
MOZ_ASSERT(sSingleton);
return sSingleton;
}
void
GPUProcessManager::Initialize()
{
MOZ_ASSERT(XRE_IsParentProcess());
sSingleton = new GPUProcessManager();
}

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

@ -106,6 +106,11 @@ public:
void OnProcessLaunchComplete(GPUProcessHost* aHost) override;
void OnProcessUnexpectedShutdown(GPUProcessHost* aHost) override;
// Returns access to the PGPU protocol if a GPU process is present.
GPUChild* GetGPUChild() {
return mGPUChild;
}
private:
// Called from our xpcom-shutdown observer.
void OnXPCOMShutdown();

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

@ -3,14 +3,31 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
include protocol PContent;
namespace mozilla {
namespace gfx {
union GfxPrefValue {
bool;
int32_t;
uint32_t;
float;
};
struct GfxPrefSetting {
int32_t index;
GfxPrefValue value;
};
sync protocol PGPU
{
parent:
// Sent by the UI process to initiate shutdown.
async Nothing();
// Sent by the UI process to initiate core settings.
async Init(GfxPrefSetting[] prefs);
// Called to update a gfx preference.
async UpdatePref(GfxPrefSetting pref);
};
} // namespace gfx

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

@ -5,33 +5,20 @@
#include "gfxPrefs.h"
#include "mozilla/Preferences.h"
#include "MainThreadUtils.h"
#include "mozilla/gfx/Preferences.h"
#include "nsXULAppAPI.h"
#include "mozilla/Preferences.h"
#include "mozilla/unused.h"
#include "mozilla/gfx/Logging.h"
#include "mozilla/gfx/GPUChild.h"
#include "mozilla/gfx/GPUProcessManager.h"
using namespace mozilla;
nsTArray<gfxPrefs::Pref*>* gfxPrefs::sGfxPrefList = nullptr;
gfxPrefs* gfxPrefs::sInstance = nullptr;
bool gfxPrefs::sInstanceHasBeenDestroyed = false;
class PreferenceAccessImpl : public mozilla::gfx::PreferenceAccess
{
public:
virtual ~PreferenceAccessImpl();
virtual void LivePref(const char* aName, int32_t* aVar, int32_t aDefault) override;
};
PreferenceAccessImpl::~PreferenceAccessImpl()
{
}
void PreferenceAccessImpl::LivePref(const char* aName,
int32_t* aVar,
int32_t aDefault)
{
Preferences::AddIntVarCache(aVar, aName, aDefault);
}
void
gfxPrefs::DestroySingleton()
{
@ -51,20 +38,31 @@ gfxPrefs::SingletonExists()
gfxPrefs::gfxPrefs()
{
// UI, content, and plugin processes use XPCOM and should have prefs
// ready by the time we initialize gfxPrefs.
MOZ_ASSERT_IF(XRE_IsContentProcess() ||
XRE_IsParentProcess() ||
XRE_GetProcessType() == GeckoProcessType_Plugin,
Preferences::IsServiceAvailable());
gfxPrefs::AssertMainThread();
mMoz2DPrefAccess = new PreferenceAccessImpl;
mozilla::gfx::PreferenceAccess::SetAccess(mMoz2DPrefAccess);
}
void
gfxPrefs::Init()
{
// Set up Moz2D prefs.
mPrefGfxLoggingLevel.SetChangeCallback([]() -> void {
mozilla::gfx::LoggingPrefs::sGfxLogLevel = GetSingleton().mPrefGfxLoggingLevel.GetLiveValue();
});
}
gfxPrefs::~gfxPrefs()
{
gfxPrefs::AssertMainThread();
// gfxPrefs is a singleton, we can reset this to null once
// it goes away.
mozilla::gfx::PreferenceAccess::SetAccess(nullptr);
delete mMoz2DPrefAccess;
mMoz2DPrefAccess = nullptr;
mPrefGfxLoggingLevel.SetChangeCallback(nullptr);
delete sGfxPrefList;
sGfxPrefList = nullptr;
}
void gfxPrefs::AssertMainThread()
@ -72,10 +70,67 @@ void gfxPrefs::AssertMainThread()
MOZ_ASSERT(NS_IsMainThread(), "this code must be run on the main thread");
}
void
gfxPrefs::Pref::OnChange()
{
if (auto gpm = gfx::GPUProcessManager::Get()) {
if (gfx::GPUChild* gpu = gpm->GetGPUChild()) {
GfxPrefValue value;
GetCachedValue(&value);
Unused << gpu->SendUpdatePref(gfx::GfxPrefSetting(mIndex, value));
}
}
FireChangeCallback();
}
void
gfxPrefs::Pref::FireChangeCallback()
{
if (mChangeCallback) {
mChangeCallback();
}
}
void
gfxPrefs::Pref::SetChangeCallback(ChangeCallback aCallback)
{
mChangeCallback = aCallback;
if (!IsParentProcess() && IsPrefsServiceAvailable()) {
// If we're in the parent process, we watch prefs by default so we can
// send changes over to the GPU process. Otherwise, we need to add or
// remove a watch for the pref now.
if (aCallback) {
WatchChanges(Name(), this);
} else {
UnwatchChanges(Name(), this);
}
}
// Fire the callback once to make initialization easier for the caller.
FireChangeCallback();
}
// On lightweight processes such as for GMP and GPU, XPCOM is not initialized,
// and therefore we don't have access to Preferences. When XPCOM is not
// available we rely on manual synchronization of gfxPrefs values over IPC.
/* static */ bool
gfxPrefs::IsPrefsServiceAvailable()
{
return Preferences::IsServiceAvailable();
}
/* static */ bool
gfxPrefs::IsParentProcess()
{
return XRE_IsParentProcess();
}
void gfxPrefs::PrefAddVarCache(bool* aVariable,
const char* aPref,
bool aDefault)
{
MOZ_ASSERT(IsPrefsServiceAvailable());
Preferences::AddBoolVarCache(aVariable, aPref, aDefault);
}
@ -83,6 +138,7 @@ void gfxPrefs::PrefAddVarCache(int32_t* aVariable,
const char* aPref,
int32_t aDefault)
{
MOZ_ASSERT(IsPrefsServiceAvailable());
Preferences::AddIntVarCache(aVariable, aPref, aDefault);
}
@ -90,6 +146,7 @@ void gfxPrefs::PrefAddVarCache(uint32_t* aVariable,
const char* aPref,
uint32_t aDefault)
{
MOZ_ASSERT(IsPrefsServiceAvailable());
Preferences::AddUintVarCache(aVariable, aPref, aDefault);
}
@ -97,46 +154,114 @@ void gfxPrefs::PrefAddVarCache(float* aVariable,
const char* aPref,
float aDefault)
{
MOZ_ASSERT(IsPrefsServiceAvailable());
Preferences::AddFloatVarCache(aVariable, aPref, aDefault);
}
bool gfxPrefs::PrefGet(const char* aPref, bool aDefault)
{
MOZ_ASSERT(IsPrefsServiceAvailable());
return Preferences::GetBool(aPref, aDefault);
}
int32_t gfxPrefs::PrefGet(const char* aPref, int32_t aDefault)
{
MOZ_ASSERT(IsPrefsServiceAvailable());
return Preferences::GetInt(aPref, aDefault);
}
uint32_t gfxPrefs::PrefGet(const char* aPref, uint32_t aDefault)
{
MOZ_ASSERT(IsPrefsServiceAvailable());
return Preferences::GetUint(aPref, aDefault);
}
float gfxPrefs::PrefGet(const char* aPref, float aDefault)
{
MOZ_ASSERT(IsPrefsServiceAvailable());
return Preferences::GetFloat(aPref, aDefault);
}
void gfxPrefs::PrefSet(const char* aPref, bool aValue)
{
MOZ_ASSERT(IsPrefsServiceAvailable());
Preferences::SetBool(aPref, aValue);
}
void gfxPrefs::PrefSet(const char* aPref, int32_t aValue)
{
MOZ_ASSERT(IsPrefsServiceAvailable());
Preferences::SetInt(aPref, aValue);
}
void gfxPrefs::PrefSet(const char* aPref, uint32_t aValue)
{
MOZ_ASSERT(IsPrefsServiceAvailable());
Preferences::SetUint(aPref, aValue);
}
void gfxPrefs::PrefSet(const char* aPref, float aValue)
{
MOZ_ASSERT(IsPrefsServiceAvailable());
Preferences::SetFloat(aPref, aValue);
}
static void
OnGfxPrefChanged(const char* aPrefname, void* aClosure)
{
reinterpret_cast<gfxPrefs::Pref*>(aClosure)->OnChange();
}
void gfxPrefs::WatchChanges(const char* aPrefname, Pref* aPref)
{
MOZ_ASSERT(IsPrefsServiceAvailable());
Preferences::RegisterCallback(OnGfxPrefChanged, aPrefname, aPref, Preferences::ExactMatch);
}
void gfxPrefs::UnwatchChanges(const char* aPrefname, Pref* aPref)
{
// The Preferences service can go offline before gfxPrefs is destroyed.
if (IsPrefsServiceAvailable()) {
Preferences::UnregisterCallback(OnGfxPrefChanged, aPrefname, aPref, Preferences::ExactMatch);
}
}
void gfxPrefs::CopyPrefValue(const bool* aValue, GfxPrefValue* aOutValue)
{
*aOutValue = *aValue;
}
void gfxPrefs::CopyPrefValue(const int32_t* aValue, GfxPrefValue* aOutValue)
{
*aOutValue = *aValue;
}
void gfxPrefs::CopyPrefValue(const uint32_t* aValue, GfxPrefValue* aOutValue)
{
*aOutValue = *aValue;
}
void gfxPrefs::CopyPrefValue(const float* aValue, GfxPrefValue* aOutValue)
{
*aOutValue = *aValue;
}
void gfxPrefs::CopyPrefValue(const GfxPrefValue* aValue, bool* aOutValue)
{
*aOutValue = aValue->get_bool();
}
void gfxPrefs::CopyPrefValue(const GfxPrefValue* aValue, int32_t* aOutValue)
{
*aOutValue = aValue->get_int32_t();
}
void gfxPrefs::CopyPrefValue(const GfxPrefValue* aValue, uint32_t* aOutValue)
{
*aOutValue = aValue->get_uint32_t();
}
void gfxPrefs::CopyPrefValue(const GfxPrefValue* aValue, float* aOutValue)
{
*aOutValue = aValue->get_float();
}

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

@ -9,6 +9,9 @@
#include <cmath> // for M_PI
#include <stdint.h>
#include "mozilla/Assertions.h"
#include "mozilla/Function.h"
#include "mozilla/gfx/LoggingConstants.h"
#include "nsTArray.h"
// First time gfxPrefs::GetSingleton() needs to be called on the main thread,
// before any of the methods accessing the values are used, but after
@ -55,25 +58,31 @@
// example, if the accessor is Foo() then calling SetFoo(...) will update
// the preference and also change the return value of subsequent Foo() calls.
// This is true even for 'Once' prefs which otherwise do not change if the
// pref is updated after initialization.
// pref is updated after initialization. Changing gfxPrefs values in content
// processes will not affect the result in other processes. Changing gfxPrefs
// values in the GPU process is not supported at all.
#define DECL_GFX_PREF(Update, Pref, Name, Type, Default) \
#define DECL_GFX_PREF(Update, Prefname, Name, Type, Default) \
public: \
static Type Name() { MOZ_ASSERT(SingletonExists()); return GetSingleton().mPref##Name.mValue; } \
static void Set##Name(Type aVal) { MOZ_ASSERT(SingletonExists()); \
static void Set##Name(Type aVal) { MOZ_ASSERT(SingletonExists()); \
GetSingleton().mPref##Name.Set(UpdatePolicy::Update, Get##Name##PrefName(), aVal); } \
static const char* Get##Name##PrefName() { return Pref; } \
static const char* Get##Name##PrefName() { return Prefname; } \
static Type Get##Name##PrefDefault() { return Default; } \
private: \
static Pref* Get##Name##PrefPtr() { return &GetSingleton().mPref##Name; } \
PrefTemplate<UpdatePolicy::Update, Type, Get##Name##PrefDefault, Get##Name##PrefName> mPref##Name
class PreferenceAccessImpl;
namespace mozilla {
namespace gfx {
class GfxPrefValue; // defined in PGPU.ipdl
} // namespace gfx
} // namespace mozilla
class gfxPrefs;
class gfxPrefs final
{
private:
/// See Logging.h. This lets Moz2D access preference values it owns.
PreferenceAccessImpl* mMoz2DPrefAccess;
typedef mozilla::gfx::GfxPrefValue GfxPrefValue;
private:
// Enums for the update policy.
@ -83,27 +92,81 @@ private:
Live // Evaluate the preference and set callback so it stays current/live
};
public:
class Pref
{
public:
Pref() : mChangeCallback(nullptr)
{
mIndex = sGfxPrefList->Length();
sGfxPrefList->AppendElement(this);
}
size_t Index() const { return mIndex; }
void OnChange();
typedef void (*ChangeCallback)();
void SetChangeCallback(ChangeCallback aCallback);
virtual const char* Name() const = 0;
// Returns true if the value is default, false if changed.
virtual bool HasDefaultValue() const = 0;
// Returns the pref value as a discriminated union.
virtual void GetCachedValue(GfxPrefValue* aOutValue) const = 0;
// Change the cached value. GfxPrefValue must be a compatible type.
virtual void SetCachedValue(const GfxPrefValue& aOutValue) = 0;
protected:
void FireChangeCallback();
private:
size_t mIndex;
ChangeCallback mChangeCallback;
};
static const nsTArray<Pref*>& all() {
return *sGfxPrefList;
}
private:
// Since we cannot use const char*, use a function that returns it.
template <UpdatePolicy Update, class T, T Default(void), const char* Pref(void)>
class PrefTemplate
template <UpdatePolicy Update, class T, T Default(void), const char* Prefname(void)>
class PrefTemplate : public Pref
{
public:
PrefTemplate()
: mValue(Default())
{
Register(Update, Pref());
// If not using the Preferences service, values are synced over IPC, so
// there's no need to register us as a Preferences observer.
if (IsPrefsServiceAvailable()) {
Register(Update, Prefname());
}
// By default we only watch changes in the parent process, to communicate
// changes to the GPU process.
if (IsParentProcess() && Update == UpdatePolicy::Live) {
WatchChanges(Prefname(), this);
}
}
~PrefTemplate() {
if (IsParentProcess() && Update == UpdatePolicy::Live) {
UnwatchChanges(Prefname(), this);
}
}
void Register(UpdatePolicy aUpdate, const char* aPreference)
{
AssertMainThread();
switch(aUpdate) {
switch (aUpdate) {
case UpdatePolicy::Skip:
break;
case UpdatePolicy::Once:
mValue = PrefGet(aPreference, mValue);
break;
case UpdatePolicy::Live:
PrefAddVarCache(&mValue,aPreference, mValue);
PrefAddVarCache(&mValue, aPreference, mValue);
break;
default:
MOZ_CRASH("Incomplete switch");
@ -124,6 +187,36 @@ private:
MOZ_CRASH("Incomplete switch");
}
}
const char *Name() const override {
return Prefname();
}
// When using the Preferences service, the change callback can be triggered
// *before* our cached value is updated, so we expose a method to grab the
// true live value.
T GetLiveValue() const {
if (IsPrefsServiceAvailable()) {
return PrefGet(Prefname(), mValue);
}
return mValue;
}
bool HasDefaultValue() const override {
return mValue == Default();
}
void GetCachedValue(GfxPrefValue* aOutValue) const override {
CopyPrefValue(&mValue, aOutValue);
}
void SetCachedValue(const GfxPrefValue& aOutValue) override {
// This is only used in non-XPCOM processes.
MOZ_ASSERT(!IsPrefsServiceAvailable());
T newValue;
CopyPrefValue(&aOutValue, &newValue);
if (mValue != newValue) {
mValue = newValue;
FireChangeCallback();
}
}
T mValue;
};
@ -261,7 +354,8 @@ private:
DECL_GFX_PREF(Live, "gfx.gralloc.fence-with-readpixels", GrallocFenceWithReadPixels, bool, false);
DECL_GFX_PREF(Live, "gfx.layerscope.enabled", LayerScopeEnabled, bool, false);
DECL_GFX_PREF(Live, "gfx.layerscope.port", LayerScopePort, int32_t, 23456);
// Note that "gfx.logging.level" is defined in Logging.h
// Note that "gfx.logging.level" is defined in Logging.h.
DECL_GFX_PREF(Live, "gfx.logging.level", GfxLoggingLevel, int32_t, mozilla::gfx::LOG_DEFAULT);
DECL_GFX_PREF(Once, "gfx.logging.crash.length", GfxLoggingCrashLength, uint32_t, 16);
DECL_GFX_PREF(Live, "gfx.logging.painted-pixel-count.enabled",GfxLoggingPaintedPixelCountEnabled, bool, false);
// The maximums here are quite conservative, we can tighten them if problems show up.
@ -480,7 +574,9 @@ public:
{
MOZ_ASSERT(!sInstanceHasBeenDestroyed, "Should never recreate a gfxPrefs instance!");
if (!sInstance) {
sGfxPrefList = new nsTArray<Pref*>();
sInstance = new gfxPrefs;
sInstance->Init();
}
MOZ_ASSERT(SingletonExists());
return *sInstance;
@ -491,8 +587,16 @@ public:
private:
static gfxPrefs* sInstance;
static bool sInstanceHasBeenDestroyed;
static nsTArray<Pref*>* sGfxPrefList;
private:
// The constructor cannot access GetSingleton(), since sInstance (necessarily)
// has not been assigned yet. Follow-up initialization that needs GetSingleton()
// must be added to Init().
void Init();
static bool IsPrefsServiceAvailable();
static bool IsParentProcess();
// Creating these to avoid having to include Preferences.h in the .h
static void PrefAddVarCache(bool*, const char*, bool);
static void PrefAddVarCache(int32_t*, const char*, int32_t);
@ -506,6 +610,17 @@ private:
static void PrefSet(const char* aPref, int32_t aValue);
static void PrefSet(const char* aPref, uint32_t aValue);
static void PrefSet(const char* aPref, float aValue);
static void WatchChanges(const char* aPrefname, Pref* aPref);
static void UnwatchChanges(const char* aPrefname, Pref* aPref);
// Creating these to avoid having to include PGPU.h in the .h
static void CopyPrefValue(const bool* aValue, GfxPrefValue* aOutValue);
static void CopyPrefValue(const int32_t* aValue, GfxPrefValue* aOutValue);
static void CopyPrefValue(const uint32_t* aValue, GfxPrefValue* aOutValue);
static void CopyPrefValue(const float* aValue, GfxPrefValue* aOutValue);
static void CopyPrefValue(const GfxPrefValue* aValue, bool* aOutValue);
static void CopyPrefValue(const GfxPrefValue* aValue, int32_t* aOutValue);
static void CopyPrefValue(const GfxPrefValue* aValue, uint32_t* aOutValue);
static void CopyPrefValue(const GfxPrefValue* aValue, float* aOutValue);
static void AssertMainThread();

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

@ -254,6 +254,7 @@ LoadInfoToLoadInfoArgs(nsILoadInfo *aLoadInfo,
aLoadInfo->GetInnerWindowID(),
aLoadInfo->GetOuterWindowID(),
aLoadInfo->GetParentOuterWindowID(),
aLoadInfo->GetFrameOuterWindowID(),
aLoadInfo->GetEnforceSecurity(),
aLoadInfo->GetInitialSecurityCheckDone(),
aLoadInfo->GetIsInThirdPartyContext(),
@ -319,6 +320,7 @@ LoadInfoArgsToLoadInfo(const OptionalLoadInfoArgs& aOptionalLoadInfoArgs,
loadInfoArgs.innerWindowID(),
loadInfoArgs.outerWindowID(),
loadInfoArgs.parentOuterWindowID(),
loadInfoArgs.frameOuterWindowID(),
loadInfoArgs.enforceSecurity(),
loadInfoArgs.initialSecurityCheckDone(),
loadInfoArgs.isInThirdPartyContext(),

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

@ -232,18 +232,20 @@ js::CheckTracedThing(JSTracer* trc, T* thing)
}
/*
* Try to assert that the thing is allocated. This is complicated by the
* fact that allocated things may still contain the poison pattern if that
* part has not been overwritten. Also, background sweeping may be running
* and concurrently modifiying the free list.
* Try to assert that the thing is allocated.
*
* Tracing is done off main thread while compacting and reading the contents
* of the thing in IsThingPoisoned is racy so this check is skipped there.
* We would like to assert that the thing is not in the free list, but this
* check is very slow. Instead we check whether the thing has been poisoned:
* if it has not then we assume it is allocated, but if it has then it is
* either free or uninitialized in which case we check the free list.
*
* Further complications are that background sweeping may be running and
* concurrently modifiying the free list and that tracing is done off main
* thread during compacting GC and reading the contents of the thing by
* IsThingPoisoned would be racy in this case.
*/
MOZ_ASSERT_IF(rt->isHeapBusy() && !zone->isGCCompacting() &&
!rt->gc.isBackgroundSweeping() &&
IsThingPoisoned(thing),
!InFreeList(thing->asTenured().arena(), thing));
MOZ_ASSERT_IF(rt->isHeapBusy() && !zone->isGCCompacting() && !rt->gc.isBackgroundSweeping(),
!IsThingPoisoned(thing) || !InFreeList(thing->asTenured().arena(), thing));
#endif
}

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

@ -120,23 +120,19 @@ void
MacroAssemblerMIPSCompat::convertDoubleToInt32(FloatRegister src, Register dest,
Label* fail, bool negativeZeroCheck)
{
if (negativeZeroCheck) {
moveFromDoubleHi(src, dest);
moveFromDoubleLo(src, ScratchRegister);
as_movn(dest, zero, ScratchRegister);
ma_b(dest, Imm32(INT32_MIN), fail, Assembler::Equal);
}
// Convert double to int, then convert back and check if we have the
// same number.
as_cvtwd(ScratchDoubleReg, src);
as_mfc1(dest, ScratchDoubleReg);
as_cvtdw(ScratchDoubleReg, ScratchDoubleReg);
ma_bc1d(src, ScratchDoubleReg, fail, Assembler::DoubleNotEqualOrUnordered);
if (negativeZeroCheck) {
Label notZero;
ma_b(dest, Imm32(0), &notZero, Assembler::NotEqual, ShortJump);
// Test and bail for -0.0, when integer result is 0
// Move the top word of the double into the output reg, if it is
// non-zero, then the original value was -0.0
moveFromDoubleHi(src, dest);
ma_b(dest, Imm32(INT32_MIN), fail, Assembler::Equal);
bind(&notZero);
}
}
// Checks whether a float32 is representable as a 32-bit integer. If so, the
@ -146,6 +142,11 @@ void
MacroAssemblerMIPSCompat::convertFloat32ToInt32(FloatRegister src, Register dest,
Label* fail, bool negativeZeroCheck)
{
if (negativeZeroCheck) {
moveFromFloat32(src, dest);
ma_b(dest, Imm32(INT32_MIN), fail, Assembler::Equal);
}
// Converting the floating point value to an integer and then converting it
// back to a float32 would not work, as float to int32 conversions are
// clamping (e.g. float(INT32_MAX + 1) would get converted into INT32_MAX
@ -158,17 +159,6 @@ MacroAssemblerMIPSCompat::convertFloat32ToInt32(FloatRegister src, Register dest
// Bail out in the clamped cases.
ma_b(dest, Imm32(INT32_MAX), fail, Assembler::Equal);
if (negativeZeroCheck) {
Label notZero;
ma_b(dest, Imm32(0), &notZero, Assembler::NotEqual, ShortJump);
// Test and bail for -0.0, when integer result is 0
// Move the top word of the double into the output reg,
// if it is non-zero, then the original value was -0.0
moveFromDoubleHi(src, dest);
ma_b(dest, Imm32(INT32_MIN), fail, Assembler::Equal);
bind(&notZero);
}
}
void

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

@ -129,23 +129,18 @@ void
MacroAssemblerMIPS64Compat::convertDoubleToInt32(FloatRegister src, Register dest,
Label* fail, bool negativeZeroCheck)
{
if (negativeZeroCheck) {
moveFromDouble(src, dest);
ma_drol(dest, dest, Imm32(1));
ma_b(dest, Imm32(1), fail, Assembler::Equal);
}
// Convert double to int, then convert back and check if we have the
// same number.
as_cvtwd(ScratchDoubleReg, src);
as_mfc1(dest, ScratchDoubleReg);
as_cvtdw(ScratchDoubleReg, ScratchDoubleReg);
ma_bc1d(src, ScratchDoubleReg, fail, Assembler::DoubleNotEqualOrUnordered);
if (negativeZeroCheck) {
Label notZero;
ma_b(dest, Imm32(0), &notZero, Assembler::NotEqual, ShortJump);
// Test and bail for -0.0, when integer result is 0
// Move the top word of the double into the output reg, if it is
// non-zero, then the original value was -0.0
moveFromDoubleHi(src, dest);
ma_b(dest, Imm32(INT32_MIN), fail, Assembler::Equal);
bind(&notZero);
}
}
// Checks whether a float32 is representable as a 32-bit integer. If so, the
@ -155,6 +150,11 @@ void
MacroAssemblerMIPS64Compat::convertFloat32ToInt32(FloatRegister src, Register dest,
Label* fail, bool negativeZeroCheck)
{
if (negativeZeroCheck) {
moveFromFloat32(src, dest);
ma_b(dest, Imm32(INT32_MIN), fail, Assembler::Equal);
}
// Converting the floating point value to an integer and then converting it
// back to a float32 would not work, as float to int32 conversions are
// clamping (e.g. float(INT32_MAX + 1) would get converted into INT32_MAX
@ -167,17 +167,6 @@ MacroAssemblerMIPS64Compat::convertFloat32ToInt32(FloatRegister src, Register de
// Bail out in the clamped cases.
ma_b(dest, Imm32(INT32_MAX), fail, Assembler::Equal);
if (negativeZeroCheck) {
Label notZero;
ma_b(dest, Imm32(0), &notZero, Assembler::NotEqual, ShortJump);
// Test and bail for -0.0, when integer result is 0
// Move the top word of the double into the output reg,
// if it is non-zero, then the original value was -0.0
moveFromDoubleHi(src, dest);
ma_b(dest, Imm32(INT32_MIN), fail, Assembler::Equal);
bind(&notZero);
}
}
void

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

@ -936,12 +936,7 @@ JSContext::isThrowingDebuggeeWouldRun()
bool
JSContext::currentlyRunning() const
{
for (ActivationIterator iter(runtime()); !iter.done(); ++iter) {
if (iter->cx() == this)
return true;
}
return false;
return !!activation();
}
static bool
@ -1061,7 +1056,7 @@ JSContext::findVersion() const
if (compartment() && compartment()->behaviors().version() != JSVERSION_UNKNOWN)
return compartment()->behaviors().version();
return runtime()->defaultVersion();
return defaultVersion();
}
#ifdef DEBUG

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

@ -318,8 +318,8 @@ struct JSContext : public js::ExclusiveContext,
using ExclusiveContext::staticStrings;
using ExclusiveContext::wellKnownSymbols;
JSRuntime* runtime() const { return runtime_; }
js::PerThreadData& mainThread() const { return runtime()->mainThread; }
JSRuntime* runtime() { return this; }
js::PerThreadData& mainThread() { return this->JSRuntime::mainThread; }
static size_t offsetOfRuntime() {
return offsetof(JSContext, runtime_);

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

@ -21,7 +21,6 @@
namespace js {
#ifdef JS_CRASH_DIAGNOSTICS
class CompartmentChecker
{
JSCompartment* compartment;
@ -135,7 +134,6 @@ class CompartmentChecker
check(desc.value());
}
};
#endif /* JS_CRASH_DIAGNOSTICS */
/*
* Don't perform these checks when called from a finalizer. The checking
@ -146,6 +144,13 @@ class CompartmentChecker
return; \
CompartmentChecker c(cx)
template <class T1> inline void
releaseAssertSameCompartment(ExclusiveContext* cx, const T1& t1)
{
START_ASSERT_SAME_COMPARTMENT();
c.check(t1);
}
template <class T1> inline void
assertSameCompartment(ExclusiveContext* cx, const T1& t1)
{
@ -371,7 +376,7 @@ JSContext::setPendingException(js::Value v)
inline bool
JSContext::runningWithTrustedPrincipals() const
{
return !compartment() || compartment()->principals() == runtime()->trustedPrincipals();
return !compartment() || compartment()->principals() == trustedPrincipals();
}
inline void
@ -439,7 +444,7 @@ JSContext::currentScript(jsbytecode** ppc,
if (ppc)
*ppc = nullptr;
js::Activation* act = runtime()->activation();
js::Activation* act = activation();
while (act && (act->cx() != this || (act->isJit() && !act->asJit()->isActive())))
act = act->prev();

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

@ -1684,7 +1684,7 @@ ScriptSourceObject::create(ExclusiveContext* cx, ScriptSource* source)
ScriptSourceObject::initFromOptions(JSContext* cx, HandleScriptSource source,
const ReadOnlyCompileOptions& options)
{
assertSameCompartment(cx, source);
releaseAssertSameCompartment(cx, source);
MOZ_ASSERT(source->getReservedSlot(ELEMENT_SLOT).isMagic(JS_GENERIC_MAGIC));
MOZ_ASSERT(source->getReservedSlot(ELEMENT_PROPERTY_SLOT).isMagic(JS_GENERIC_MAGIC));
MOZ_ASSERT(source->getReservedSlot(INTRODUCTION_SCRIPT_SLOT).isMagic(JS_GENERIC_MAGIC));

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

@ -1171,7 +1171,7 @@ GlobalHelperThreadState::finishParseTask(JSContext* maybecx, JSRuntime* rt, Pars
return nullptr;
RootedScript script(rt, parseTask->script);
assertSameCompartment(cx, script);
releaseAssertSameCompartment(cx, script);
// Report out of memory errors eagerly, or errors could be malformed.
if (parseTask->outOfMemory) {

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

@ -1109,7 +1109,7 @@ struct JSRuntime : public JS::shadow::Runtime,
/* Gets current default locale. String remains owned by context. */
const char* getDefaultLocale();
JSVersion defaultVersion() { return defaultVersion_; }
JSVersion defaultVersion() const { return defaultVersion_; }
void setDefaultVersion(JSVersion v) { defaultVersion_ = v; }
/* Base address of the native stack for the current thread. */

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

@ -182,6 +182,10 @@ ClearKeyDecryptor::Decrypt(uint8_t* aBuffer, uint32_t aBufferSize,
for (size_t i = 0; i < aMetadata.NumSubsamples(); i++) {
data += aMetadata.mClearBytes[i];
uint32_t cipherBytes = aMetadata.mCipherBytes[i];
if (data + cipherBytes > aBuffer + aBufferSize) {
// Trying to read past the end of the buffer!
return GMPCryptoErr;
}
memcpy(iter, data, cipherBytes);

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

@ -34,6 +34,8 @@ public class SyncAction extends BaseAction {
private static final String KINTO_KEY_ID = "id";
private static final String KINTO_KEY_DELETED = "deleted";
private static final String KINTO_KEY_DATA = "data";
private static final String KINTO_KEY_ATTACHMENT = "attachment";
private static final String KINTO_KEY_ORIGINAL = "original";
private static final String KINTO_PARAMETER_SINCE = "_since";
private static final String KINTO_PARAMETER_FIELDS = "_fields";
@ -73,6 +75,12 @@ public class SyncAction extends BaseAction {
final boolean isDeleted = object.optBoolean(KINTO_KEY_DELETED, false);
if (!isDeleted) {
JSONObject attachment = object.getJSONObject(KINTO_KEY_ATTACHMENT);
if (attachment.isNull(KINTO_KEY_ORIGINAL))
throw new JSONException(String.format("Old Attachment Format"));
}
DownloadContent existingContent = catalog.getContentById(id);
if (isDeleted) {
@ -122,7 +130,7 @@ public class SyncAction extends BaseAction {
}
// Only select the fields we are actually going to read.
builder.appendQueryParameter(KINTO_PARAMETER_FIELDS,
"attachment.location,original.filename,original.hash,attachment.hash,type,kind,original.size,match");
"attachment.location,attachment.original.filename,attachment.original.hash,attachment.hash,type,kind,attachment.original.size,match");
// We want to process items in the order they have been modified. This is to ensure that
// our last_modified values are correct if we processing is interrupted and not all items

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

@ -216,14 +216,13 @@ public class DownloadContentBuilder {
setKind(object.getString(KINTO_KEY_KIND));
setLastModified(object.getLong(KINTO_KEY_LAST_MODIFIED));
JSONObject original = object.getJSONObject(KINTO_KEY_ORIGINAL);
JSONObject attachment = object.getJSONObject(KINTO_KEY_ATTACHMENT);
JSONObject original = attachment.getJSONObject(KINTO_KEY_ORIGINAL);
setFilename(original.getString(KINTO_KEY_FILENAME));
setChecksum(original.getString(KINTO_KEY_HASH));
setSize(original.getLong(KINTO_KEY_SIZE));
JSONObject attachment = object.getJSONObject(KINTO_KEY_ATTACHMENT);
setLocation(attachment.getString(KINTO_KEY_LOCATION));
setDownloadChecksum(attachment.getString(KINTO_KEY_HASH));

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

@ -0,0 +1,23 @@
{
"data":[
{
"kind":"font",
"original": {
"mimetype":"application/x-font-ttf",
"filename":"CharisSILCompact-R.ttf",
"hash":"4ed509317f1bb441b185ea13bf1c9d19d1a0b396962efa3b5dc3190ad88f2067",
"size":1727656
},
"last_modified":1455710632607,
"attachment": {
"mimetype":"application/x-gzip",
"size":548720,
"hash":"960be4fc5a92c1dc488582b215d5d75429fd4ffbee463105d29992cd792a912e",
"location":"/attachments/0d28a72d-a51f-46f8-9e5a-f95c61de904e.gz",
"filename":"CharisSILCompact-R.ttf.gz"
},
"type":"asset-archive",
"id":"c906275c-3747-fe27-426f-6187526a6f06"
}
]
}

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

@ -2,19 +2,19 @@
"data":[
{
"kind":"font",
"original": {
"mimetype":"application/x-font-ttf",
"filename":"CharisSILCompact-R.ttf",
"hash":"4ed509317f1bb441b185ea13bf1c9d19d1a0b396962efa3b5dc3190ad88f2067",
"size":1727656
},
"last_modified":1455710632607,
"attachment": {
"mimetype":"application/x-gzip",
"size":548720,
"hash":"960be4fc5a92c1dc488582b215d5d75429fd4ffbee463105d29992cd792a912e",
"location":"/attachments/0d28a72d-a51f-46f8-9e5a-f95c61de904e.gz",
"filename":"CharisSILCompact-R.ttf.gz"
"filename":"CharisSILCompact-R.ttf.gz",
"original": {
"mimetype":"application/x-font-ttf",
"filename":"CharisSILCompact-R.ttf",
"hash":"4ed509317f1bb441b185ea13bf1c9d19d1a0b396962efa3b5dc3190ad88f2067",
"size":1727656
}
},
"type":"asset-archive",
"id":"c906275c-3747-fe27-426f-6187526a6f06"

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

@ -103,6 +103,28 @@ public class TestSyncAction {
Assert.assertEquals(DownloadContent.STATE_NONE, content.getState());
}
/**
* Scenario: The catalog is using the old format, we want to make sure we abort cleanly.
*/
@Test
public void testUpdatingWithOldCatalog() throws Exception{
SyncAction action = spy(new SyncAction());
doReturn(true).when(action).isSyncEnabledForClient(RuntimeEnvironment.application);
doReturn(fromFile("dlc_sync_old_format.json")).when(action).fetchRawCatalog(anyLong());
DownloadContent existingContent = createTestContent("c906275c-3747-fe27-426f-6187526a6f06");
DownloadContentCatalog catalog = spy(new MockedContentCatalog(existingContent));
action.perform(RuntimeEnvironment.application, catalog);
// make sure nothing was done
verify(action, never()).createContent(anyCatalog(), anyJSONObject());
verify(action, never()).updateContent(anyCatalog(), anyJSONObject(), anyContent());
verify(action, never()).deleteContent(anyCatalog(), anyString());
verify(action, never()).startStudyAction(anyContext());
}
/**
* Scenario: The catalog contains one item and the server returns a new version.
*/

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

@ -433,6 +433,13 @@ Preferences::GetInstanceForService()
return sPreferences;
}
// static
bool
Preferences::IsServiceAvailable()
{
return !!sPreferences;
}
// static
bool
Preferences::InitStaticMembers()

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

@ -51,6 +51,11 @@ public:
nsresult Init();
/**
* Returns true if the Preferences service is available, false otherwise.
*/
static bool IsServiceAvailable();
/**
* Reset loaded user prefs then read them
*/

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

@ -54,6 +54,7 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal,
, mInnerWindowID(0)
, mOuterWindowID(0)
, mParentOuterWindowID(0)
, mFrameOuterWindowID(0)
, mEnforceSecurity(false)
, mInitialSecurityCheckDone(false)
, mIsThirdPartyContext(false)
@ -97,9 +98,12 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal,
nsCOMPtr<nsPIDOMWindowOuter> contextOuter = aLoadingContext->OwnerDoc()->GetWindow();
if (contextOuter) {
ComputeIsThirdPartyContext(contextOuter);
mOuterWindowID = contextOuter->WindowID();
nsCOMPtr<nsPIDOMWindowOuter> parent = contextOuter->GetScriptableParent();
mParentOuterWindowID = parent ? parent->WindowID() : mOuterWindowID;
}
nsCOMPtr<nsPIDOMWindowOuter> outerWindow;
mInnerWindowID = aLoadingContext->OwnerDoc()->InnerWindowID();
// When the element being loaded is a frame, we choose the frame's window
// for the window ID and the frame element's window as the parent
@ -115,19 +119,11 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal,
if (fl) {
nsCOMPtr<nsIDocShell> docShell;
if (NS_SUCCEEDED(fl->GetDocShell(getter_AddRefs(docShell))) && docShell) {
outerWindow = do_GetInterface(docShell);
nsCOMPtr<nsPIDOMWindowOuter> outerWindow = do_GetInterface(docShell);
if (outerWindow) {
mFrameOuterWindowID = outerWindow->WindowID();
}
}
} else {
outerWindow = contextOuter.forget();
}
if (outerWindow) {
nsCOMPtr<nsPIDOMWindowInner> inner = outerWindow->GetCurrentInnerWindow();
mInnerWindowID = inner ? inner->WindowID() : 0;
mOuterWindowID = outerWindow->WindowID();
nsCOMPtr<nsPIDOMWindowOuter> parent = outerWindow->GetScriptableParent();
mParentOuterWindowID = parent->WindowID();
}
// if the document forces all requests to be upgraded from http to https, then
@ -201,6 +197,7 @@ LoadInfo::LoadInfo(nsPIDOMWindowOuter* aOuterWindow,
, mInnerWindowID(0)
, mOuterWindowID(0)
, mParentOuterWindowID(0)
, mFrameOuterWindowID(0)
, mEnforceSecurity(false)
, mInitialSecurityCheckDone(false)
, mIsThirdPartyContext(false) // NB: TYPE_DOCUMENT implies not third-party.
@ -247,6 +244,7 @@ LoadInfo::LoadInfo(const LoadInfo& rhs)
, mInnerWindowID(rhs.mInnerWindowID)
, mOuterWindowID(rhs.mOuterWindowID)
, mParentOuterWindowID(rhs.mParentOuterWindowID)
, mFrameOuterWindowID(rhs.mFrameOuterWindowID)
, mEnforceSecurity(rhs.mEnforceSecurity)
, mInitialSecurityCheckDone(rhs.mInitialSecurityCheckDone)
, mIsThirdPartyContext(rhs.mIsThirdPartyContext)
@ -271,6 +269,7 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal,
uint64_t aInnerWindowID,
uint64_t aOuterWindowID,
uint64_t aParentOuterWindowID,
uint64_t aFrameOuterWindowID,
bool aEnforceSecurity,
bool aInitialSecurityCheckDone,
bool aIsThirdPartyContext,
@ -291,6 +290,7 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal,
, mInnerWindowID(aInnerWindowID)
, mOuterWindowID(aOuterWindowID)
, mParentOuterWindowID(aParentOuterWindowID)
, mFrameOuterWindowID(aFrameOuterWindowID)
, mEnforceSecurity(aEnforceSecurity)
, mInitialSecurityCheckDone(aInitialSecurityCheckDone)
, mIsThirdPartyContext(aIsThirdPartyContext)
@ -587,6 +587,13 @@ LoadInfo::GetParentOuterWindowID(uint64_t* aResult)
return NS_OK;
}
NS_IMETHODIMP
LoadInfo::GetFrameOuterWindowID(uint64_t* aResult)
{
*aResult = mFrameOuterWindowID;
return NS_OK;
}
NS_IMETHODIMP
LoadInfo::GetScriptableOriginAttributes(JSContext* aCx,
JS::MutableHandle<JS::Value> aOriginAttributes)

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

@ -92,6 +92,7 @@ private:
uint64_t aInnerWindowID,
uint64_t aOuterWindowID,
uint64_t aParentOuterWindowID,
uint64_t aFrameOuterWindowID,
bool aEnforceSecurity,
bool aInitialSecurityCheckDone,
bool aIsThirdPartyRequest,
@ -131,6 +132,7 @@ private:
uint64_t mInnerWindowID;
uint64_t mOuterWindowID;
uint64_t mParentOuterWindowID;
uint64_t mFrameOuterWindowID;
bool mEnforceSecurity;
bool mInitialSecurityCheckDone;
bool mIsThirdPartyContext;

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

@ -389,12 +389,9 @@ interface nsILoadInfo : nsISupports
[infallible] attribute boolean enforceSRI;
/**
* Typically these are the window IDs of the window in which the element being
* loaded lives. However, if the element being loaded is <frame
* src="foo.html"> (or, more generally, if the element QIs to
* nsIFrameLoaderOwner) then the window IDs are for the window containing the
* foo.html document. In this case, parentOuterWindowID is the window ID of
* the window containing the <frame> element.
* These are the window IDs of the window in which the element being
* loaded lives. parentOuterWindowID is the window ID of this window's
* parent.
*
* Note that these window IDs can be 0 if the window is not
* available. parentOuterWindowID will be the same as outerWindowID if the
@ -404,6 +401,16 @@ interface nsILoadInfo : nsISupports
[infallible] readonly attribute unsigned long long outerWindowID;
[infallible] readonly attribute unsigned long long parentOuterWindowID;
/**
* Only when the element being loaded is <frame src="foo.html">
* (or, more generally, if the element QIs to nsIFrameLoaderOwner),
* the frameOuterWindowID is the outer window containing the
* foo.html document.
*
* Note: For other cases, frameOuterWindowID is 0.
*/
[infallible] readonly attribute unsigned long long frameOuterWindowID;
/**
* Customized NeckoOriginAttributes within LoadInfo to allow overwriting of the
* default originAttributes from the loadingPrincipal.

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

@ -38,6 +38,7 @@ struct LoadInfoArgs
uint64_t innerWindowID;
uint64_t outerWindowID;
uint64_t parentOuterWindowID;
uint64_t frameOuterWindowID;
bool enforceSecurity;
bool initialSecurityCheckDone;
bool isInThirdPartyContext;

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

@ -36087,12 +36087,10 @@
},
"local_changes": {
"deleted": [
"WebCryptoAPI/generateKey/successes.worker.js",
"WebCryptoAPI/generateKey/failures.worker.js",
"web-animations/interfaces/AnimationTimeline/document-timeline.html",
"WebCryptoAPI/generateKey/test_failures.html",
"WebCryptoAPI/generateKey/test_successes.html",
"web-animations/interfaces/AnimationTimeline/idlharness.html",
"WebCryptoAPI/generateKey/successes.worker.js"
"WebCryptoAPI/generateKey/test_successes.html"
],
"deleted_reftests": {},
"items": {
@ -36374,7 +36372,7 @@
"XMLHttpRequest/xmlhttprequest-sync-not-hang-scriptloader.html": [
{
"path": "XMLHttpRequest/xmlhttprequest-sync-not-hang-scriptloader.html",
"url": "/XMLHttpRequest/xmlhttprequest-sync-not-hang-scriptloader.html"
"url": "/XMLHttpRequest/xmlhttprequest-sync-not-hang-scriptloader.html"
}
],
"editing/run/justifycenter.html": [
@ -36391,24 +36389,6 @@
"url": "/editing/run/multitest.html"
}
],
"web-animations/interfaces/DocumentTimeline/constructor.html": [
{
"path": "web-animations/interfaces/DocumentTimeline/constructor.html",
"url": "/web-animations/interfaces/DocumentTimeline/constructor.html"
}
],
"web-animations/interfaces/DocumentTimeline/idlharness.html": [
{
"path": "web-animations/interfaces/DocumentTimeline/idlharness.html",
"url": "/web-animations/interfaces/DocumentTimeline/idlharness.html"
}
],
"web-animations/timing-model/timelines/default-document-timeline.html": [
{
"path": "web-animations/timing-model/timelines/default-document-timeline.html",
"url": "/web-animations/timing-model/timelines/default-document-timeline.html"
}
],
"webaudio/the-audio-api/the-audioparam-interface/setTargetAtTime-after-event-within-block.html": [
{
"path": "webaudio/the-audio-api/the-audioparam-interface/setTargetAtTime-after-event-within-block.html",

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

@ -1,5 +0,0 @@
[addCue.html]
type: testharness
[TextTrack.addCue(), adding a removed cue to a different track]
expected: FAIL

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

@ -1,8 +0,0 @@
[track.html]
type: testharness
[TextTrackCue.track, script-created cue]
expected: FAIL
[TextTrackCue.track, parsed cue]
expected: FAIL

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

@ -0,0 +1,6 @@
[idlharness.html]
type: testharness
prefs: [dom.animations-api.core.enabled:true]
[AnimationTimeline must be primary interface of document.timeline]
expected: FAIL

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

@ -1,7 +1,6 @@
<!doctype html>
<meta charset=utf-8>
<title>Default document timeline tests</title>
<link rel="help" href="https://w3c.github.io/web-animations/#the-documents-default-timeline">
<title>Web Animations API: DocumentTimeline tests</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
@ -17,9 +16,15 @@ test(function() {
'document.timeline returns a different object for each document');
assert_not_equals(iframe.contentDocument.timeline, null,
'document.timeline on an iframe is not null');
}, 'document.timeline identity tests');
},
'document.timeline identity tests',
{
help: 'http://dev.w3.org/fxtf/web-animations/#the-document-timeline',
assert: [ 'Each document has a timeline called the document timeline' ],
author: 'Brian Birtles'
});
promise_test(function(t) {
async_test(function(t) {
assert_true(document.timeline.currentTime > 0,
'document.timeline.currentTime is positive');
// document.timeline.currentTime should be set even before document
@ -35,14 +40,31 @@ promise_test(function(t) {
// We can't just compare document.timeline.currentTime to
// window.performance.now() because currentTime is only updated on a sample
// so we use requestAnimationFrame instead.
return window.requestAnimationFrame(t.step_func(function(rafTime) {
window.requestAnimationFrame(t.step_func(function(rafTime) {
assert_equals(document.timeline.currentTime, rafTime,
'document.timeline.currentTime matches' +
' requestAnimationFrame time');
t.done();
}));
}, 'document.timeline.currentTime value tests');
},
'document.timeline.currentTime value tests',
{
help: [
'http://dev.w3.org/fxtf/web-animations/#the-global-clock',
'http://dev.w3.org/fxtf/web-animations/#the-document-timeline'
],
assert: [
'The global clock is a source of monotonically increasing time values',
'The time values of the document timeline are calculated as a fixed' +
' offset from the global clock',
'the zero time corresponds to the navigationStart moment',
'the time value of each document timeline must be equal to the time ' +
'passed to animation frame request callbacks for that browsing context'
],
author: 'Brian Birtles'
});
promise_test(function(t) {
async_test(function(t) {
var valueAtStart = document.timeline.currentTime;
var timeAtStart = window.performance.now();
while (window.performance.now() - timeAtStart < 100) {
@ -50,10 +72,18 @@ promise_test(function(t) {
}
assert_equals(document.timeline.currentTime, valueAtStart,
'document.timeline.currentTime does not change within a script block');
return window.requestAnimationFrame(t.step_func(function() {
window.requestAnimationFrame(t.step_func(function() {
assert_true(document.timeline.currentTime > valueAtStart,
'document.timeline.currentTime increases between script blocks');
t.done();
}));
}, 'document.timeline.currentTime liveness tests');
},
'document.timeline.currentTime liveness tests',
{
help: 'http://dev.w3.org/fxtf/web-animations/#script-execution-and-live-updates-to-the-model',
assert: [ 'The value returned by the currentTime attribute of a' +
' document timeline will not change within a script block' ],
author: 'Brian Birtles'
});
</script>

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

@ -6,13 +6,11 @@
<script src="/resources/WebIDLParser.js"></script>
<script src="/resources/idlharness.js"></script>
<div id="log"></div>
<script type="text/plain" id="AnimationTimeline-IDL">
<script type="text/plain" id="DocumentTimeline-IDL">
interface AnimationTimeline {
readonly attribute double? currentTime;
};
</script>
<script type="text/plain" id="DocumentTimeline-IDL">
[Constructor (DOMHighResTimeStamp originTime)]
interface DocumentTimeline : AnimationTimeline {
};
</script>
@ -22,8 +20,6 @@ interface DocumentTimeline : AnimationTimeline {
var idlArray;
test(function() {
idlArray = new IdlArray();
idlArray.add_untested_idls(
document.getElementById('AnimationTimeline-IDL').textContent);
idlArray.add_idls(
document.getElementById('DocumentTimeline-IDL').textContent);
idlArray.add_objects( { DocumentTimeline: ['document.timeline'] } );

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

@ -1,34 +0,0 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title>DocumentTimeline constructor tests</title>
<link rel="help" href="https://w3c.github.io/web-animations/#the-documenttimeline-interface">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../../testcommon.js"></script>
<body>
<div id="log"></div>
<script>
"use strict";
test(function(t) {
var timeline = new DocumentTimeline(0);
assert_times_equal(timeline.currentTime, document.timeline.currentTime);
}, 'zero origin time');
test(function(t) {
var timeline = new DocumentTimeline(10 * MS_PER_SEC);
assert_times_equal(timeline.currentTime,
(document.timeline.currentTime - 10 * MS_PER_SEC));
}, 'positive origin time');
test(function(t) {
var timeline = new DocumentTimeline(-10 * MS_PER_SEC);
assert_times_equal(timeline.currentTime,
(document.timeline.currentTime + 10 * MS_PER_SEC));
}, 'negative origin time');
</script>
</body>

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

@ -534,8 +534,10 @@ HttpObserverManager = {
commonData.originUrl = originPrincipal.URI.spec;
}
Object.assign(commonData, {
windowId: loadInfo.outerWindowID,
parentWindowId: loadInfo.parentOuterWindowID,
windowId: loadInfo.frameOuterWindowID ?
loadInfo.frameOuterWindowID : loadInfo.outerWindowID,
parentWindowId: loadInfo.frameOuterWindowID ?
loadInfo.outerWindowID : loadInfo.parentOuterWindowID,
});
} else {
Object.assign(commonData, {