mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 13:21:05 +00:00
Merge mozilla-central to mozilla-inbound
This commit is contained in:
commit
ceb8695fd3
@ -141,7 +141,6 @@ AboutRedirector::NewChannel(nsIURI* aURI,
|
||||
for (int i = 0; i < kRedirTotal; i++) {
|
||||
if (!strcmp(path.get(), kRedirMap[i].id)) {
|
||||
nsAutoCString url;
|
||||
nsLoadFlags loadFlags = static_cast<nsLoadFlags>(nsIChannel::LOAD_NORMAL);
|
||||
|
||||
if (path.EqualsLiteral("newtab")) {
|
||||
// let the aboutNewTabService decide where to redirect
|
||||
@ -159,7 +158,6 @@ AboutRedirector::NewChannel(nsIURI* aURI,
|
||||
if (remoteEnabled) {
|
||||
NS_ENSURE_ARG_POINTER(aLoadInfo);
|
||||
aLoadInfo->SetVerifySignedContent(true);
|
||||
loadFlags = static_cast<nsLoadFlags>(nsIChannel::LOAD_REPLACE);
|
||||
}
|
||||
}
|
||||
// fall back to the specified url in the map
|
||||
@ -181,7 +179,7 @@ AboutRedirector::NewChannel(nsIURI* aURI,
|
||||
&isUIResource);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
loadFlags = isUIResource
|
||||
nsLoadFlags loadFlags = isUIResource
|
||||
? static_cast<nsLoadFlags>(nsIChannel::LOAD_NORMAL)
|
||||
: static_cast<nsLoadFlags>(nsIChannel::LOAD_REPLACE);
|
||||
|
||||
|
12
devtools/bootstrap.js
vendored
12
devtools/bootstrap.js
vendored
@ -124,6 +124,18 @@ function reload(event) {
|
||||
|
||||
// Then spawn a brand new Loader.jsm instance and start the main module
|
||||
Cu.unload("resource://devtools/shared/Loader.jsm");
|
||||
// Also unload all resources loaded as jsm, hopefully all of them are going
|
||||
// to be converted into regular modules
|
||||
Cu.unload("resource://devtools/client/shared/browser-loader.js");
|
||||
Cu.unload("resource://devtools/client/framework/ToolboxProcess.jsm");
|
||||
Cu.unload("resource://devtools/shared/apps/Devices.jsm");
|
||||
Cu.unload("resource://devtools/client/scratchpad/scratchpad-manager.jsm");
|
||||
Cu.unload("resource://devtools/shared/Parser.jsm");
|
||||
Cu.unload("resource://devtools/client/shared/DOMHelpers.jsm");
|
||||
Cu.unload("resource://devtools/client/shared/widgets/VariablesView.jsm");
|
||||
Cu.unload("resource://devtools/client/responsivedesign/responsivedesign.jsm");
|
||||
Cu.unload("resource://devtools/client/shared/widgets/AbstractTreeItem.jsm");
|
||||
Cu.unload("resource://devtools/shared/deprecated-sync-thenables.js");
|
||||
const {devtools} = Cu.import("resource://devtools/shared/Loader.jsm", {});
|
||||
devtools.require("devtools/client/framework/devtools-browser");
|
||||
|
||||
|
@ -13,7 +13,7 @@ const { BrowserLoader } = Cu.import("resource://devtools/client/shared/browser-l
|
||||
// Module Loader
|
||||
const require = BrowserLoader({
|
||||
baseURI: "resource://devtools/client/dom/",
|
||||
window: this
|
||||
window
|
||||
}).require;
|
||||
|
||||
XPCOMUtils.defineConstant(this, "require", require);
|
||||
|
@ -9,7 +9,7 @@ const BrowserLoaderModule = {};
|
||||
Cu.import("resource://devtools/client/shared/browser-loader.js", BrowserLoaderModule);
|
||||
const { require } = BrowserLoaderModule.BrowserLoader({
|
||||
baseURI: "resource://devtools/client/memory/",
|
||||
window: this
|
||||
window
|
||||
});
|
||||
const { Task } = require("devtools/shared/task");
|
||||
const { createFactory, createElement } = require("devtools/client/shared/vendor/react");
|
||||
|
@ -7,7 +7,7 @@ var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
|
||||
var { BrowserLoader } = Cu.import("resource://devtools/client/shared/browser-loader.js", {});
|
||||
var { require } = BrowserLoader({
|
||||
baseURI: "resource://devtools/client/memory/",
|
||||
window: this
|
||||
window
|
||||
});
|
||||
var { Assert } = require("resource://testing-common/Assert.jsm");
|
||||
var Services = require("Services");
|
||||
|
@ -3,7 +3,7 @@
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
"use strict";
|
||||
|
||||
/* global document, SimpleTest, requestAnimationFrame, is, ok */
|
||||
/* global window, document, SimpleTest, requestAnimationFrame, is, ok */
|
||||
/* exported Cc, Ci, Cu, Cr, Assert, Task, TargetFactory, Toolbox, browserRequire,
|
||||
forceRender, setProps, dumpn, checkOptimizationHeader, checkOptimizationTree */
|
||||
let { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
|
||||
@ -20,7 +20,7 @@ let { Toolbox } = require("devtools/client/framework/toolbox");
|
||||
flags.testing = true;
|
||||
let { require: browserRequire } = BrowserLoader({
|
||||
baseURI: "resource://devtools/client/performance/",
|
||||
window: this
|
||||
window
|
||||
});
|
||||
|
||||
let $ = (selector, scope = document) => scope.querySelector(selector);
|
||||
|
@ -3,7 +3,7 @@
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
"use strict";
|
||||
|
||||
/* globals document, PerformanceView, ToolbarView, RecordingsView, DetailsView */
|
||||
/* globals window, document, PerformanceView, ToolbarView, RecordingsView, DetailsView */
|
||||
|
||||
/* exported Cc, Ci, Cu, Cr, loader */
|
||||
var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
|
||||
@ -11,7 +11,7 @@ var BrowserLoaderModule = {};
|
||||
Cu.import("resource://devtools/client/shared/browser-loader.js", BrowserLoaderModule);
|
||||
var { loader, require } = BrowserLoaderModule.BrowserLoader({
|
||||
baseURI: "resource://devtools/client/performance/",
|
||||
window: this
|
||||
window
|
||||
});
|
||||
var { Task } = require("devtools/shared/task");
|
||||
/* exported Heritage, ViewHelpers, WidgetMethods, setNamedTimeout, clearNamedTimeout */
|
||||
|
@ -11,7 +11,7 @@ const { BrowserLoader } =
|
||||
Cu.import("resource://devtools/client/shared/browser-loader.js", {});
|
||||
const { require } = BrowserLoader({
|
||||
baseURI: "resource://devtools/client/responsive.html/",
|
||||
window: this
|
||||
window
|
||||
});
|
||||
const { Task } = require("devtools/shared/task");
|
||||
const Telemetry = require("devtools/client/shared/telemetry");
|
||||
|
@ -24,7 +24,7 @@ var { Toolbox } = require("devtools/client/framework/toolbox");
|
||||
flags.testing = true;
|
||||
var { require: browserRequire } = BrowserLoader({
|
||||
baseURI: "resource://devtools/client/shared/",
|
||||
window: this
|
||||
window
|
||||
});
|
||||
|
||||
let ReactDOM = browserRequire("devtools/client/shared/vendor/react-dom");
|
||||
|
@ -9,7 +9,7 @@ const { BrowserLoader } = Cu.import("resource://devtools/client/shared/browser-l
|
||||
|
||||
const { require: browserRequire } = BrowserLoader({
|
||||
baseURI: "resource://devtools/client/shared/",
|
||||
window: this
|
||||
window
|
||||
});
|
||||
|
||||
const variableFileContents = browserRequire("raw!devtools/client/themes/variables.css");
|
||||
|
@ -13,7 +13,7 @@ var { utils: Cu } = Components;
|
||||
const rootUrl = "resource://devtools/client/webconsole/net/";
|
||||
const require = BrowserLoader({
|
||||
baseURI: rootUrl,
|
||||
window: this}).require;
|
||||
window}).require;
|
||||
|
||||
const NetRequest = require("./net-request");
|
||||
const { loadSheet } = require("sdk/stylesheet/utils");
|
||||
|
@ -16,7 +16,7 @@ const { BrowserLoader } = Cu.import("resource://devtools/client/shared/browser-l
|
||||
// privileges and runs entirely in content scope.
|
||||
const NewConsoleOutputWrapper = BrowserLoader({
|
||||
baseURI: "resource://devtools/client/webconsole/new-console-output/",
|
||||
window: this}).require("./new-console-output-wrapper");
|
||||
window}).require("./new-console-output-wrapper");
|
||||
|
||||
this.NewConsoleOutput = function (parentNode, jsterm, toolbox, owner) {
|
||||
console.log("Creating NewConsoleOutput", parentNode, NewConsoleOutputWrapper);
|
||||
|
@ -12,5 +12,5 @@ var { Task } = require("devtools/shared/task");
|
||||
|
||||
var { require: browserRequire } = BrowserLoader({
|
||||
baseURI: "resource://devtools/client/webconsole/",
|
||||
window: this
|
||||
window
|
||||
});
|
||||
|
@ -138,18 +138,20 @@ function onExecuteFoo23InFirstCall() {
|
||||
onExecuteFooAndFoo3ChangesInFirstCall));
|
||||
}
|
||||
|
||||
function onExecuteFooAndFoo3ChangesInFirstCall() {
|
||||
var onExecuteFooAndFoo3ChangesInFirstCall = Task.async(function*() {
|
||||
let expected = "abbabug783499";
|
||||
isnot(gWebConsole.outputNode.textContent.indexOf(expected), -1,
|
||||
"|foo + foo3| updated in |firstCall()|");
|
||||
|
||||
is(content.wrappedJSObject.foo, "globalFooBug783499",
|
||||
"|foo| in content window");
|
||||
is(content.wrappedJSObject.foo2, "newFoo", "|foo2| in content window");
|
||||
ok(!content.wrappedJSObject.foo3,
|
||||
"|foo3| was not added to the content window");
|
||||
yield ContentTask.spawn(gBrowser.selectedBrowser, null, function*() {
|
||||
is(content.wrappedJSObject.foo, "globalFooBug783499",
|
||||
"|foo| in content window");
|
||||
is(content.wrappedJSObject.foo2, "newFoo", "|foo2| in content window");
|
||||
ok(!content.wrappedJSObject.foo3,
|
||||
"|foo3| was not added to the content window");
|
||||
});
|
||||
|
||||
gWebConsole = gJSTerm = gDebuggerWin = gThread = gDebuggerController =
|
||||
gStackframes = null;
|
||||
executeSoon(finishTest);
|
||||
}
|
||||
});
|
||||
|
@ -4,8 +4,12 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
const { installHelperSheet,
|
||||
addPseudoClassLock, removePseudoClassLock } = require("./utils/markup");
|
||||
const {
|
||||
installHelperSheet,
|
||||
isNodeValid,
|
||||
addPseudoClassLock,
|
||||
removePseudoClassLock
|
||||
} = require("./utils/markup");
|
||||
|
||||
// SimpleOutlineHighlighter's stylesheet
|
||||
const HIGHLIGHTED_PSEUDO_CLASS = ":-moz-devtools-highlighted";
|
||||
@ -41,7 +45,7 @@ SimpleOutlineHighlighter.prototype = {
|
||||
* @param {DOMNode} node
|
||||
*/
|
||||
show: function (node) {
|
||||
if (!this.currentNode || node !== this.currentNode) {
|
||||
if (isNodeValid(node) && (!this.currentNode || node !== this.currentNode)) {
|
||||
this.hide();
|
||||
this.currentNode = node;
|
||||
installHelperSheet(node.ownerDocument.defaultView, SIMPLE_OUTLINE_SHEET);
|
||||
|
@ -32,7 +32,6 @@ public:
|
||||
void Flush() override;
|
||||
void Drain() override;
|
||||
void Shutdown() override;
|
||||
void ConfigurationChanged(const TrackInfo& aConfig) override { MOZ_ASSERT(false); }
|
||||
|
||||
const char* GetDescriptionName() const override { return "RemoteVideoDecoder"; }
|
||||
|
||||
@ -62,18 +61,22 @@ public:
|
||||
: mWrapped(aWrapped)
|
||||
{}
|
||||
|
||||
virtual nsresult Startup() override;
|
||||
nsresult Startup() override;
|
||||
|
||||
virtual bool SupportsMimeType(const nsACString& aMimeType,
|
||||
DecoderDoctorDiagnostics* aDiagnostics) const override;
|
||||
bool SupportsMimeType(const nsACString& aMimeType,
|
||||
DecoderDoctorDiagnostics* aDiagnostics) const override;
|
||||
|
||||
virtual ConversionRequired DecoderNeedsConversion(const TrackInfo& aConfig) const override;
|
||||
ConversionRequired DecoderNeedsConversion(
|
||||
const TrackInfo& aConfig) const override;
|
||||
|
||||
virtual already_AddRefed<MediaDataDecoder>
|
||||
CreateVideoDecoder(const CreateDecoderParams& aParams) override;
|
||||
already_AddRefed<MediaDataDecoder> CreateVideoDecoder(
|
||||
const CreateDecoderParams& aParams) override;
|
||||
|
||||
virtual already_AddRefed<MediaDataDecoder>
|
||||
CreateAudioDecoder(const CreateDecoderParams& aParams) override { return nullptr; }
|
||||
already_AddRefed<MediaDataDecoder> CreateAudioDecoder(
|
||||
const CreateDecoderParams& aParams) override
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
RefPtr<PlatformDecoderModule> mWrapped;
|
||||
|
@ -258,11 +258,12 @@ MediaSourceDemuxer::GetMozDebugReaderData(nsAString& aString)
|
||||
result += nsPrintfCString("Dumping data for demuxer %p:\n", this);
|
||||
if (mAudioTrack) {
|
||||
result += nsPrintfCString("\tDumping Audio Track Buffer(%s): - mLastAudioTime: %f\n"
|
||||
"\t\tNumSamples:%u Size:%u NextGetSampleIndex:%u NextInsertionIndex:%d\n",
|
||||
"\t\tNumSamples:%u Size:%u Evictable:%u NextGetSampleIndex:%u NextInsertionIndex:%d\n",
|
||||
mAudioTrack->mAudioTracks.mInfo->mMimeType.get(),
|
||||
mAudioTrack->mAudioTracks.mNextSampleTime.ToSeconds(),
|
||||
mAudioTrack->mAudioTracks.mBuffers[0].Length(),
|
||||
mAudioTrack->mAudioTracks.mSizeBuffer,
|
||||
mAudioTrack->Evictable(TrackInfo::kAudioTrack),
|
||||
mAudioTrack->mAudioTracks.mNextGetSampleIndex.valueOr(-1),
|
||||
mAudioTrack->mAudioTracks.mNextInsertionIndex.valueOr(-1));
|
||||
|
||||
@ -271,11 +272,12 @@ MediaSourceDemuxer::GetMozDebugReaderData(nsAString& aString)
|
||||
}
|
||||
if (mVideoTrack) {
|
||||
result += nsPrintfCString("\tDumping Video Track Buffer(%s) - mLastVideoTime: %f\n"
|
||||
"\t\tNumSamples:%u Size:%u NextGetSampleIndex:%u NextInsertionIndex:%d\n",
|
||||
"\t\tNumSamples:%u Size:%u Evictable:%u NextGetSampleIndex:%u NextInsertionIndex:%d\n",
|
||||
mVideoTrack->mVideoTracks.mInfo->mMimeType.get(),
|
||||
mVideoTrack->mVideoTracks.mNextSampleTime.ToSeconds(),
|
||||
mVideoTrack->mVideoTracks.mBuffers[0].Length(),
|
||||
mVideoTrack->mVideoTracks.mSizeBuffer,
|
||||
mVideoTrack->Evictable(TrackInfo::kVideoTrack),
|
||||
mVideoTrack->mVideoTracks.mNextGetSampleIndex.valueOr(-1),
|
||||
mVideoTrack->mVideoTracks.mNextInsertionIndex.valueOr(-1));
|
||||
|
||||
|
@ -274,22 +274,23 @@ TrackBuffersManager::EvictData(const TimeUnit& aPlaybackTime, int64_t aSize)
|
||||
}
|
||||
const int64_t toEvict = GetSize() + aSize - EvictionThreshold();
|
||||
|
||||
MSE_DEBUG("buffered=%lldkb, eviction threshold=%ukb, evict=%lldkb",
|
||||
GetSize() / 1024, EvictionThreshold() / 1024, toEvict / 1024);
|
||||
const uint32_t canEvict =
|
||||
Evictable(HasVideo() ? TrackInfo::kVideoTrack : TrackInfo::kAudioTrack);
|
||||
|
||||
MSE_DEBUG(
|
||||
"buffered=%lldkB, eviction threshold=%ukB, evict=%lldkB canevict=%ukB",
|
||||
GetSize() / 1024, EvictionThreshold() / 1024, toEvict / 1024,
|
||||
canEvict / 1024);
|
||||
|
||||
if (toEvict <= 0) {
|
||||
mEvictionState = EvictionState::NO_EVICTION_NEEDED;
|
||||
return EvictDataResult::NO_DATA_EVICTED;
|
||||
}
|
||||
if (toEvict <= 512*1024) {
|
||||
// Don't bother evicting less than 512KB.
|
||||
mEvictionState = EvictionState::NO_EVICTION_NEEDED;
|
||||
return EvictDataResult::CANT_EVICT;
|
||||
}
|
||||
|
||||
EvictDataResult result;
|
||||
|
||||
if (mBufferFull && mEvictionState == EvictionState::EVICTION_COMPLETED) {
|
||||
if (mBufferFull && mEvictionState == EvictionState::EVICTION_COMPLETED &&
|
||||
canEvict < uint32_t(toEvict)) {
|
||||
// Our buffer is currently full. We will make another eviction attempt.
|
||||
// However, the current appendBuffer will fail as we can't know ahead of
|
||||
// time if the eviction will later succeed.
|
||||
@ -422,7 +423,7 @@ TrackBuffersManager::DoEvictData(const TimeUnit& aPlaybackTime,
|
||||
mEvictionState = EvictionState::EVICTION_COMPLETED;
|
||||
|
||||
// Video is what takes the most space, only evict there if we have video.
|
||||
const auto& track = HasVideo() ? mVideoTracks : mAudioTracks;
|
||||
auto& track = HasVideo() ? mVideoTracks : mAudioTracks;
|
||||
const auto& buffer = track.mBuffers.LastElement();
|
||||
// Remove any data we've already played, or before the next sample to be
|
||||
// demuxed whichever is lowest.
|
||||
@ -1603,7 +1604,7 @@ TrackBuffersManager::CheckNextInsertionIndex(TrackData& aTrackData,
|
||||
TrackBuffer& data = aTrackData.mBuffers.LastElement();
|
||||
|
||||
if (data.IsEmpty() || aSampleTime < aTrackData.mBufferedRanges.GetStart()) {
|
||||
aTrackData.mNextInsertionIndex = Some(size_t(0));
|
||||
aTrackData.mNextInsertionIndex = Some(0u);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1617,7 +1618,7 @@ TrackBuffersManager::CheckNextInsertionIndex(TrackData& aTrackData,
|
||||
}
|
||||
if (target.IsEmpty()) {
|
||||
// No target found, it will be added at the end of the track buffer.
|
||||
aTrackData.mNextInsertionIndex = Some(data.Length());
|
||||
aTrackData.mNextInsertionIndex = Some(uint32_t(data.Length()));
|
||||
return true;
|
||||
}
|
||||
// We now need to find the first frame of the searched interval.
|
||||
@ -1626,7 +1627,7 @@ TrackBuffersManager::CheckNextInsertionIndex(TrackData& aTrackData,
|
||||
const RefPtr<MediaRawData>& sample = data[i];
|
||||
if (sample->mTime >= target.mStart.ToMicroseconds() ||
|
||||
sample->GetEndTime() > target.mStart.ToMicroseconds()) {
|
||||
aTrackData.mNextInsertionIndex = Some(size_t(i));
|
||||
aTrackData.mNextInsertionIndex = Some(i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -1686,7 +1687,7 @@ TrackBuffersManager::InsertFrames(TrackBuffer& aSamples,
|
||||
// to overlap the following frame.
|
||||
trackBuffer.mNextInsertionIndex.reset();
|
||||
}
|
||||
size_t index =
|
||||
uint32_t index =
|
||||
RemoveFrames(aIntervals, trackBuffer, trackBuffer.mNextInsertionIndex.refOr(0));
|
||||
if (index) {
|
||||
trackBuffer.mNextInsertionIndex = Some(index);
|
||||
@ -1706,8 +1707,15 @@ TrackBuffersManager::InsertFrames(TrackBuffer& aSamples,
|
||||
aIntervals.GetEnd() >= trackBuffer.mNextSampleTime) {
|
||||
MSE_DEBUG("Next sample to be played got overwritten");
|
||||
trackBuffer.mNextGetSampleIndex.reset();
|
||||
ResetEvictionIndex(trackBuffer);
|
||||
} else if (trackBuffer.mNextInsertionIndex.ref() <= trackBuffer.mNextGetSampleIndex.ref()) {
|
||||
trackBuffer.mNextGetSampleIndex.ref() += aSamples.Length();
|
||||
// We could adjust the eviction index so that the new data gets added to
|
||||
// the evictable amount (as it is prior currentTime). However, considering
|
||||
// new data is being added prior the current playback, it's likely that
|
||||
// this data will be played next, and as such we probably don't want to
|
||||
// have it evicted too early. So instead reset the eviction index instead.
|
||||
ResetEvictionIndex(trackBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1737,7 +1745,7 @@ TrackBuffersManager::UpdateHighestTimestamp(TrackData& aTrackData,
|
||||
}
|
||||
}
|
||||
|
||||
size_t
|
||||
uint32_t
|
||||
TrackBuffersManager::RemoveFrames(const TimeIntervals& aIntervals,
|
||||
TrackData& aTrackData,
|
||||
uint32_t aStartIndex)
|
||||
@ -1783,6 +1791,7 @@ TrackBuffersManager::RemoveFrames(const TimeIntervals& aIntervals,
|
||||
}
|
||||
|
||||
int64_t maxSampleDuration = 0;
|
||||
uint32_t sizeRemoved = 0;
|
||||
TimeIntervals removedIntervals;
|
||||
for (uint32_t i = firstRemovedIndex.ref(); i <= lastRemovedIndex; i++) {
|
||||
const RefPtr<MediaRawData> sample = data[i];
|
||||
@ -1793,8 +1802,9 @@ TrackBuffersManager::RemoveFrames(const TimeIntervals& aIntervals,
|
||||
if (sample->mDuration > maxSampleDuration) {
|
||||
maxSampleDuration = sample->mDuration;
|
||||
}
|
||||
aTrackData.mSizeBuffer -= sample->ComputedSizeOfIncludingThis();
|
||||
sizeRemoved += sample->ComputedSizeOfIncludingThis();
|
||||
}
|
||||
aTrackData.mSizeBuffer -= sizeRemoved;
|
||||
|
||||
MSE_DEBUG("Removing frames from:%u (frames:%u) ([%f, %f))",
|
||||
firstRemovedIndex.ref(),
|
||||
@ -1807,9 +1817,21 @@ TrackBuffersManager::RemoveFrames(const TimeIntervals& aIntervals,
|
||||
aTrackData.mNextGetSampleIndex.ref() <= lastRemovedIndex) {
|
||||
MSE_DEBUG("Next sample to be played got evicted");
|
||||
aTrackData.mNextGetSampleIndex.reset();
|
||||
ResetEvictionIndex(aTrackData);
|
||||
} else if (aTrackData.mNextGetSampleIndex.ref() > lastRemovedIndex) {
|
||||
aTrackData.mNextGetSampleIndex.ref() -=
|
||||
lastRemovedIndex - firstRemovedIndex.ref() + 1;
|
||||
uint32_t samplesRemoved = lastRemovedIndex - firstRemovedIndex.ref() + 1;
|
||||
aTrackData.mNextGetSampleIndex.ref() -= samplesRemoved;
|
||||
if (aTrackData.mEvictionIndex.mLastIndex > lastRemovedIndex) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(
|
||||
aTrackData.mEvictionIndex.mLastIndex >= samplesRemoved &&
|
||||
aTrackData.mEvictionIndex.mEvictable >= sizeRemoved,
|
||||
"Invalid eviction index");
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
aTrackData.mEvictionIndex.mLastIndex -= samplesRemoved;
|
||||
aTrackData.mEvictionIndex.mEvictable -= sizeRemoved;
|
||||
} else {
|
||||
ResetEvictionIndex(aTrackData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1951,6 +1973,33 @@ TrackBuffersManager::HighestEndTime()
|
||||
return highestEndTime;
|
||||
}
|
||||
|
||||
void
|
||||
TrackBuffersManager::ResetEvictionIndex(TrackData& aTrackData)
|
||||
{
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
aTrackData.mEvictionIndex.Reset();
|
||||
}
|
||||
|
||||
void
|
||||
TrackBuffersManager::UpdateEvictionIndex(TrackData& aTrackData,
|
||||
uint32_t currentIndex)
|
||||
{
|
||||
uint32_t evictable = 0;
|
||||
TrackBuffer& data = aTrackData.mBuffers.LastElement();
|
||||
MOZ_DIAGNOSTIC_ASSERT(currentIndex >= aTrackData.mEvictionIndex.mLastIndex,
|
||||
"Invalid call");
|
||||
MOZ_DIAGNOSTIC_ASSERT(currentIndex == data.Length() ||
|
||||
data[currentIndex]->mKeyframe,"Must stop at keyframe");
|
||||
|
||||
for (uint32_t i = aTrackData.mEvictionIndex.mLastIndex; i < currentIndex;
|
||||
i++) {
|
||||
evictable += data[i]->ComputedSizeOfIncludingThis();
|
||||
}
|
||||
aTrackData.mEvictionIndex.mLastIndex = currentIndex;
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
aTrackData.mEvictionIndex.mEvictable += evictable;
|
||||
}
|
||||
|
||||
const TrackBuffersManager::TrackBuffer&
|
||||
TrackBuffersManager::GetTrackBuffer(TrackInfo::TrackType aTrack)
|
||||
{
|
||||
@ -1989,6 +2038,7 @@ TrackBuffersManager::Seek(TrackInfo::TrackType aTrack,
|
||||
trackBuffer.mNextGetSampleIndex = Some(uint32_t(0));
|
||||
trackBuffer.mNextSampleTimecode = TimeUnit();
|
||||
trackBuffer.mNextSampleTime = TimeUnit();
|
||||
ResetEvictionIndex(trackBuffer);
|
||||
return TimeUnit();
|
||||
}
|
||||
|
||||
@ -2027,13 +2077,16 @@ TrackBuffersManager::Seek(TrackInfo::TrackType aTrack,
|
||||
break;
|
||||
}
|
||||
}
|
||||
MSE_DEBUG("Keyframe %s found at %lld",
|
||||
MSE_DEBUG("Keyframe %s found at %lld @ %u",
|
||||
lastKeyFrameTime.isSome() ? "" : "not",
|
||||
lastKeyFrameTime.refOr(TimeUnit()).ToMicroseconds());
|
||||
lastKeyFrameTime.refOr(TimeUnit()).ToMicroseconds(),
|
||||
lastKeyFrameIndex);
|
||||
|
||||
trackBuffer.mNextGetSampleIndex = Some(lastKeyFrameIndex);
|
||||
trackBuffer.mNextSampleTimecode = lastKeyFrameTimecode;
|
||||
trackBuffer.mNextSampleTime = lastKeyFrameTime.refOr(TimeUnit());
|
||||
ResetEvictionIndex(trackBuffer);
|
||||
UpdateEvictionIndex(trackBuffer, lastKeyFrameIndex);
|
||||
|
||||
return lastKeyFrameTime.refOr(TimeUnit());
|
||||
}
|
||||
@ -2121,12 +2174,17 @@ TrackBuffersManager::SkipToNextRandomAccessPoint(TrackInfo::TrackType aTrack,
|
||||
parsed--;
|
||||
}
|
||||
}
|
||||
|
||||
if (aFound) {
|
||||
UpdateEvictionIndex(trackData, trackData.mNextGetSampleIndex.ref());
|
||||
}
|
||||
|
||||
return parsed;
|
||||
}
|
||||
|
||||
const MediaRawData*
|
||||
TrackBuffersManager::GetSample(TrackInfo::TrackType aTrack,
|
||||
size_t aIndex,
|
||||
uint32_t aIndex,
|
||||
const TimeUnit& aExpectedDts,
|
||||
const TimeUnit& aExpectedPts,
|
||||
const TimeUnit& aFuzz)
|
||||
@ -2193,6 +2251,9 @@ TrackBuffersManager::GetSample(TrackInfo::TrackType aTrack,
|
||||
aResult = MediaResult(NS_ERROR_OUT_OF_MEMORY, __func__);
|
||||
return nullptr;
|
||||
}
|
||||
if (p->mKeyframe) {
|
||||
UpdateEvictionIndex(trackData, trackData.mNextGetSampleIndex.ref());
|
||||
}
|
||||
trackData.mNextGetSampleIndex.ref()++;
|
||||
// Estimate decode timestamp and timestamp of the next sample.
|
||||
TimeUnit nextSampleTimecode =
|
||||
@ -2244,6 +2305,13 @@ TrackBuffersManager::GetSample(TrackInfo::TrackType aTrack,
|
||||
aResult = MediaResult(NS_ERROR_OUT_OF_MEMORY, __func__);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Find the previous keyframe to calculate the evictable amount.
|
||||
int32_t i = pos;
|
||||
for (; !track[i]->mKeyframe; i--) {
|
||||
}
|
||||
UpdateEvictionIndex(trackData, i);
|
||||
|
||||
trackData.mNextGetSampleIndex = Some(uint32_t(pos)+1);
|
||||
trackData.mNextSampleTimecode =
|
||||
TimeUnit::FromMicroseconds(sample->mTimecode + sample->mDuration);
|
||||
@ -2313,6 +2381,13 @@ TrackBuffersManager::FindCurrentPosition(TrackInfo::TrackType aTrack,
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
TrackBuffersManager::Evictable(TrackInfo::TrackType aTrack) const
|
||||
{
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
return GetTracksData(aTrack).mEvictionIndex.mEvictable;
|
||||
}
|
||||
|
||||
TimeUnit
|
||||
TrackBuffersManager::GetNextRandomAccessPoint(TrackInfo::TrackType aTrack,
|
||||
const TimeUnit& aFuzz)
|
||||
|
@ -147,6 +147,7 @@ public:
|
||||
{
|
||||
return mEnded;
|
||||
}
|
||||
uint32_t Evictable(TrackInfo::TrackType aTrack) const;
|
||||
media::TimeUnit Seek(TrackInfo::TrackType aTrack,
|
||||
const media::TimeUnit& aTime,
|
||||
const media::TimeUnit& aFuzz);
|
||||
@ -307,7 +308,7 @@ private:
|
||||
// If set, position where the next contiguous frame will be inserted.
|
||||
// If a discontinuity is detected, it will be unset and recalculated upon
|
||||
// the next insertion.
|
||||
Maybe<size_t> mNextInsertionIndex;
|
||||
Maybe<uint32_t> mNextInsertionIndex;
|
||||
// Samples just demuxed, but not yet parsed.
|
||||
TrackBuffer mQueuedSamples;
|
||||
// We only manage a single track of each type at this time.
|
||||
@ -334,6 +335,26 @@ private:
|
||||
// Approximation of the next sample's presentation timestamp.
|
||||
media::TimeUnit mNextSampleTime;
|
||||
|
||||
struct EvictionIndex
|
||||
{
|
||||
EvictionIndex() { Reset(); }
|
||||
void Reset()
|
||||
{
|
||||
mEvictable = 0;
|
||||
mLastIndex = 0;
|
||||
}
|
||||
uint32_t mEvictable;
|
||||
uint32_t mLastIndex;
|
||||
};
|
||||
// Size of data that can be safely evicted during the next eviction
|
||||
// cycle.
|
||||
// We consider as evictable all frames up to the last keyframe prior to
|
||||
// mNextGetSampleIndex. If mNextGetSampleIndex isn't set, then we assume
|
||||
// that we can't yet evict data.
|
||||
// Protected by global monitor, except when reading on the task queue as it
|
||||
// is only written there.
|
||||
EvictionIndex mEvictionIndex;
|
||||
|
||||
void ResetAppendState()
|
||||
{
|
||||
mLastDecodeTimestamp.reset();
|
||||
@ -360,14 +381,17 @@ private:
|
||||
// Remove all frames and their dependencies contained in aIntervals.
|
||||
// Return the index at which frames were first removed or 0 if no frames
|
||||
// removed.
|
||||
size_t RemoveFrames(const media::TimeIntervals& aIntervals,
|
||||
TrackData& aTrackData,
|
||||
uint32_t aStartIndex);
|
||||
uint32_t RemoveFrames(const media::TimeIntervals& aIntervals,
|
||||
TrackData& aTrackData,
|
||||
uint32_t aStartIndex);
|
||||
// Recalculate track's evictable amount.
|
||||
void ResetEvictionIndex(TrackData& aTrackData);
|
||||
void UpdateEvictionIndex(TrackData& aTrackData, uint32_t aCurrentIndex);
|
||||
// Find index of sample. Return a negative value if not found.
|
||||
uint32_t FindSampleIndex(const TrackBuffer& aTrackBuffer,
|
||||
const media::TimeInterval& aInterval);
|
||||
const MediaRawData* GetSample(TrackInfo::TrackType aTrack,
|
||||
size_t aIndex,
|
||||
uint32_t aIndex,
|
||||
const media::TimeUnit& aExpectedDts,
|
||||
const media::TimeUnit& aExpectedPts,
|
||||
const media::TimeUnit& aFuzz);
|
||||
@ -389,6 +413,16 @@ private:
|
||||
return mAudioTracks;
|
||||
}
|
||||
}
|
||||
const TrackData& GetTracksData(TrackType aTrack) const
|
||||
{
|
||||
switch(aTrack) {
|
||||
case TrackType::kVideoTrack:
|
||||
return mVideoTracks;
|
||||
case TrackType::kAudioTrack:
|
||||
default:
|
||||
return mAudioTracks;
|
||||
}
|
||||
}
|
||||
TrackData mVideoTracks;
|
||||
TrackData mAudioTracks;
|
||||
|
||||
@ -436,7 +470,7 @@ private:
|
||||
};
|
||||
Atomic<EvictionState> mEvictionState;
|
||||
|
||||
// Monitor to protect following objects accessed across multipple threads.
|
||||
// Monitor to protect following objects accessed across multiple threads.
|
||||
mutable Monitor mMonitor;
|
||||
// Stable audio and video track time ranges.
|
||||
media::TimeIntervals mVideoBufferedRanges;
|
||||
|
@ -55,14 +55,16 @@ skip-if = toolkit == 'android' #timeout android bug 1199531
|
||||
skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3
|
||||
[test_DrainOnMissingData_mp4.html]
|
||||
skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3
|
||||
[test_EndOfStream.html]
|
||||
skip-if = (true || toolkit == 'android' || buildapp == 'mulet') #timeout android/mulet only bug 1101187 and bug 1182946
|
||||
[test_EndOfStream_mp4.html]
|
||||
skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android' || buildapp == 'mulet')) # Not supported on xp and android 2.3
|
||||
[test_DurationChange.html]
|
||||
[test_DurationUpdated.html]
|
||||
[test_DurationUpdated_mp4.html]
|
||||
skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3
|
||||
[test_EndOfStream.html]
|
||||
skip-if = (true || toolkit == 'android' || buildapp == 'mulet') #timeout android/mulet only bug 1101187 and bug 1182946
|
||||
[test_EndOfStream_mp4.html]
|
||||
skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android' || buildapp == 'mulet')) # Not supported on xp and android 2.3
|
||||
[test_Eviction_mp4.html]
|
||||
skip-if = (os == "win" && os_version == "5.1") # Not supported on xp.
|
||||
[test_FrameSelection.html]
|
||||
[test_FrameSelection_mp4.html]
|
||||
skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3
|
||||
|
82
dom/media/mediasource/test/test_Eviction_mp4.html
Normal file
82
dom/media/mediasource/test/test_Eviction_mp4.html
Normal file
@ -0,0 +1,82 @@
|
||||
<!DOCTYPE html>
|
||||
<html><head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=windows-1252">
|
||||
<title>MSE: QuotaExceededError when source buffer is full</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="mediasource.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test"><script class="testbody" type="text/javascript">
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
// We fill up the source buffer with audio data until the buffer is full.
|
||||
// We ensure that QuotaExceededError is thrown once the buffer is full.
|
||||
// We then seek to half the content. By that time, another appendBuffer must succeed
|
||||
// as the auto-eviction would succeed (removing all data prior currentTime)
|
||||
|
||||
// Fill up the SourceBuffer by appending data repeatedly via doAppendDataFunc until
|
||||
// an exception is thrown.
|
||||
function fillUpSourceBuffer(sourceBuffer, doAppendDataFunc, onCaughtExceptionCallback) {
|
||||
// We are appending data repeatedly in sequence mode, there should be no gaps.
|
||||
ok(sourceBuffer.buffered.length <= 1, "there should be no gap in buffered ranges.");
|
||||
try {
|
||||
doAppendDataFunc();
|
||||
} catch(ex) {
|
||||
onCaughtExceptionCallback(ex);
|
||||
return;
|
||||
}
|
||||
once(sourceBuffer, 'updateend', () => {
|
||||
fillUpSourceBuffer(sourceBuffer, doAppendDataFunc, onCaughtExceptionCallback);
|
||||
});
|
||||
}
|
||||
|
||||
runWithMSE(function(ms, el) {
|
||||
el.controls = true;
|
||||
once(ms, 'sourceopen').then(function() {
|
||||
ok(true, "Receive a sourceopen event");
|
||||
SpecialPowers.pushPrefEnv({
|
||||
"set": [
|
||||
["media.mediasource.eviction_threshold.audio", 524288],
|
||||
]
|
||||
}, function() {
|
||||
let audiosb = ms.addSourceBuffer("audio/mp4");
|
||||
audiosb.mode = "sequence";
|
||||
fetchAndLoad(audiosb, 'bipbop/bipbop_audio', ['init'], '.mp4')
|
||||
.then(function() {
|
||||
fetchWithXHR('bipbop/bipbop_audio1.m4s', function(audioBuffer) {
|
||||
fillUpSourceBuffer(audiosb,
|
||||
function() { // doAppendDataFunc
|
||||
audiosb.appendBuffer(audioBuffer);
|
||||
},
|
||||
function(ex) { // onCaughtExceptionCallback
|
||||
is(ex.name, 'QuotaExceededError', "QuotaExceededError thrown");
|
||||
is(audiosb.buffered.end(0), el.duration, "Duration is end of buffered range");
|
||||
let seekTime = audiosb.buffered.end(0) / 2;
|
||||
el.currentTime = seekTime;
|
||||
once(el, 'seeked', () => {
|
||||
is(el.currentTime, seekTime, "correctly seeked to " + seekTime);
|
||||
try {
|
||||
audiosb.appendBuffer(audioBuffer);
|
||||
} catch(ex) {
|
||||
ok(false, "Shouldn't throw another time when data can be evicted");
|
||||
el.mozDumpDebugInfo();
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
once(audiosb, 'update', () => {
|
||||
ok(true, "appendBuffer succeeded");
|
||||
SimpleTest.finish();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -266,14 +266,6 @@ public:
|
||||
// after creating. It doesn't need to call Init() before calling this function.
|
||||
virtual bool IsHardwareAccelerated(nsACString& aFailureReason) const { return false; }
|
||||
|
||||
// ConfigurationChanged will be called to inform the video or audio decoder
|
||||
// that the format of the next input sample is about to change.
|
||||
// If video decoder, aConfig will be a VideoInfo object.
|
||||
// If audio decoder, aConfig will be a AudioInfo object.
|
||||
// It is not safe to store a reference to this object and the decoder must
|
||||
// make a copy.
|
||||
virtual void ConfigurationChanged(const TrackInfo& aConfig) {}
|
||||
|
||||
// Return the name of the MediaDataDecoder, only used for decoding.
|
||||
// Only return a static const string, as the information may be accessed
|
||||
// in a non thread-safe fashion.
|
||||
|
@ -209,27 +209,6 @@ WMFMediaDataDecoder::IsHardwareAccelerated(nsACString& aFailureReason) const {
|
||||
return mMFTManager && mMFTManager->IsHardwareAccelerated(aFailureReason);
|
||||
}
|
||||
|
||||
void
|
||||
WMFMediaDataDecoder::ConfigurationChanged(const TrackInfo& aConfig)
|
||||
{
|
||||
MOZ_ASSERT(mCallback->OnReaderTaskQueue());
|
||||
|
||||
nsCOMPtr<nsIRunnable> runnable =
|
||||
NewRunnableMethod<UniquePtr<TrackInfo>&&>(
|
||||
this,
|
||||
&WMFMediaDataDecoder::ProcessConfigurationChanged,
|
||||
aConfig.Clone());
|
||||
mTaskQueue->Dispatch(runnable.forget());
|
||||
}
|
||||
|
||||
void
|
||||
WMFMediaDataDecoder::ProcessConfigurationChanged(UniquePtr<TrackInfo>&& aConfig)
|
||||
{
|
||||
if (mMFTManager) {
|
||||
mMFTManager->ConfigurationChanged(*aConfig);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WMFMediaDataDecoder::SetSeekThreshold(const media::TimeUnit& aTime)
|
||||
{
|
||||
|
@ -57,8 +57,6 @@ public:
|
||||
|
||||
virtual TrackInfo::TrackType GetType() = 0;
|
||||
|
||||
virtual void ConfigurationChanged(const TrackInfo& aConfig) {}
|
||||
|
||||
virtual const char* GetDescriptionName() const = 0;
|
||||
|
||||
virtual void SetSeekThreshold(const media::TimeUnit& aTime) {
|
||||
@ -96,8 +94,6 @@ public:
|
||||
|
||||
bool IsHardwareAccelerated(nsACString& aFailureReason) const override;
|
||||
|
||||
void ConfigurationChanged(const TrackInfo& aConfig) override;
|
||||
|
||||
const char* GetDescriptionName() const override
|
||||
{
|
||||
return mMFTManager ? mMFTManager->GetDescriptionName() : "";
|
||||
@ -125,10 +121,6 @@ private:
|
||||
|
||||
void ProcessShutdown();
|
||||
|
||||
// Called on the task queue. Tell the MFT that the next Input will have a
|
||||
// different configuration (typically resolution change).
|
||||
void ProcessConfigurationChanged(UniquePtr<TrackInfo>&& aConfig);
|
||||
|
||||
const RefPtr<TaskQueue> mTaskQueue;
|
||||
MediaDataDecoderCallback* mCallback;
|
||||
|
||||
|
@ -963,13 +963,4 @@ WMFVideoMFTManager::IsHardwareAccelerated(nsACString& aFailureReason) const
|
||||
return mDecoder && mUseHwAccel;
|
||||
}
|
||||
|
||||
void
|
||||
WMFVideoMFTManager::ConfigurationChanged(const TrackInfo& aConfig)
|
||||
{
|
||||
MOZ_ASSERT(aConfig.GetAsVideoInfo());
|
||||
mVideoInfo = *aConfig.GetAsVideoInfo();
|
||||
mImageSize = mVideoInfo.mImage;
|
||||
ValidateVideoInfo();
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -40,8 +40,6 @@ public:
|
||||
return TrackInfo::kVideoTrack;
|
||||
}
|
||||
|
||||
void ConfigurationChanged(const TrackInfo& aConfig) override;
|
||||
|
||||
const char* GetDescriptionName() const override
|
||||
{
|
||||
nsCString failureReason;
|
||||
|
@ -88,15 +88,6 @@ DecoderFuzzingWrapper::IsHardwareAccelerated(nsACString& aFailureReason) const
|
||||
return mDecoder->IsHardwareAccelerated(aFailureReason);
|
||||
}
|
||||
|
||||
void
|
||||
DecoderFuzzingWrapper::ConfigurationChanged(const TrackInfo& aConfig)
|
||||
{
|
||||
DFW_LOGV("");
|
||||
MOZ_ASSERT(mDecoder);
|
||||
mDecoder->ConfigurationChanged(aConfig);
|
||||
}
|
||||
|
||||
|
||||
DecoderCallbackFuzzingWrapper::DecoderCallbackFuzzingWrapper(MediaDataDecoderCallback* aCallback)
|
||||
: mCallback(aCallback)
|
||||
, mDontDelayInputExhausted(false)
|
||||
|
@ -108,7 +108,6 @@ public:
|
||||
void Drain() override;
|
||||
void Shutdown() override;
|
||||
bool IsHardwareAccelerated(nsACString& aFailureReason) const override;
|
||||
void ConfigurationChanged(const TrackInfo& aConfig) override;
|
||||
const char* GetDescriptionName() const override
|
||||
{
|
||||
return mDecoder->GetDescriptionName();
|
||||
|
@ -18,7 +18,6 @@ namespace mozilla
|
||||
H264Converter::H264Converter(PlatformDecoderModule* aPDM,
|
||||
const CreateDecoderParams& aParams)
|
||||
: mPDM(aPDM)
|
||||
, mOriginalConfig(aParams.VideoConfig())
|
||||
, mCurrentConfig(aParams.VideoConfig())
|
||||
, mLayersBackend(aParams.mLayersBackend)
|
||||
, mImageContainer(aParams.mImageContainer)
|
||||
@ -166,7 +165,7 @@ H264Converter::SetSeekThreshold(const media::TimeUnit& aTime)
|
||||
nsresult
|
||||
H264Converter::CreateDecoder(DecoderDoctorDiagnostics* aDiagnostics)
|
||||
{
|
||||
if (mNeedAVCC && !mp4_demuxer::AnnexB::HasSPS(mCurrentConfig.mExtraData)) {
|
||||
if (!mp4_demuxer::AnnexB::HasSPS(mCurrentConfig.mExtraData)) {
|
||||
// nothing found yet, will try again later
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
@ -183,20 +182,14 @@ H264Converter::CreateDecoder(DecoderDoctorDiagnostics* aDiagnostics)
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
} else if (mNeedAVCC) {
|
||||
} else {
|
||||
// SPS was invalid.
|
||||
mLastError = NS_ERROR_FAILURE;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (!mNeedAVCC) {
|
||||
// When using a decoder handling AnnexB, we get here only once from the
|
||||
// constructor. We do want to get the dimensions extracted from the SPS.
|
||||
mOriginalConfig = mCurrentConfig;
|
||||
}
|
||||
|
||||
mDecoder = mPDM->CreateVideoDecoder({
|
||||
mNeedAVCC ? mCurrentConfig : mOriginalConfig,
|
||||
mCurrentConfig,
|
||||
mTaskQueue,
|
||||
mCallback,
|
||||
aDiagnostics,
|
||||
@ -281,11 +274,6 @@ H264Converter::CheckForSPSChange(MediaRawData* aSample)
|
||||
mCurrentConfig.mExtraData)) {
|
||||
return NS_OK;
|
||||
}
|
||||
if (!mNeedAVCC) {
|
||||
UpdateConfigFromExtraData(extra_data);
|
||||
mDecoder->ConfigurationChanged(mCurrentConfig);
|
||||
return NS_OK;
|
||||
}
|
||||
// The SPS has changed, signal to flush the current decoder and create a
|
||||
// new one.
|
||||
mDecoder->Flush();
|
||||
|
@ -55,7 +55,6 @@ private:
|
||||
void OnDecoderInitFailed(MediaResult aError);
|
||||
|
||||
RefPtr<PlatformDecoderModule> mPDM;
|
||||
VideoInfo mOriginalConfig;
|
||||
VideoInfo mCurrentConfig;
|
||||
layers::LayersBackend mLayersBackend;
|
||||
RefPtr<layers::ImageContainer> mImageContainer;
|
||||
|
2
dom/media/test/external/requirements.txt
vendored
2
dom/media/test/external/requirements.txt
vendored
@ -17,4 +17,4 @@ mozversion==1.4
|
||||
wptserve==1.3.0
|
||||
marionette-client==3.1.0
|
||||
marionette-driver==2.0.0
|
||||
firefox-puppeteer >= 51.0.0, <52.0.0
|
||||
firefox-puppeteer >= 52.0.0, <53.0.0
|
||||
|
@ -1469,12 +1469,12 @@ function getPlayableVideo(candidates) {
|
||||
}
|
||||
|
||||
function getPlayableVideos(candidates) {
|
||||
var v = document.createElement("video");
|
||||
var v = manifestVideo();
|
||||
return candidates.filter(function(x){return /^video/.test(x.type) && v.canPlayType(x.type);});
|
||||
}
|
||||
|
||||
function getPlayableAudio(candidates) {
|
||||
var v = document.createElement("audio");
|
||||
var v = manifestVideo();
|
||||
var resources = candidates.filter(function(x){return /^audio/.test(x.type) && v.canPlayType(x.type);});
|
||||
if (resources.length > 0)
|
||||
return resources[0];
|
||||
|
@ -7,8 +7,6 @@
|
||||
<script type="text/javascript" src="manifest.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<video id="v1"></video>
|
||||
<video id="v2" autoplay></video>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
@ -19,22 +17,29 @@ if (media == null) {
|
||||
todo(false, "No media supported.");
|
||||
SimpleTest.finish();
|
||||
} else {
|
||||
v1.src = media.name;
|
||||
v1.preload = 'metadata';
|
||||
v1.onloadedmetadata = function() {
|
||||
v2.srcObject = v1.mozCaptureStream();
|
||||
v1.play();
|
||||
};
|
||||
var onPlayingEventFired = false;
|
||||
function startTest() {
|
||||
var v1 = document.createElement('video');
|
||||
var v2 = document.createElement('video');
|
||||
v1.preload = 'metadata';
|
||||
v2.autoplay = true;
|
||||
document.body.appendChild(v1);
|
||||
document.body.appendChild(v2);
|
||||
|
||||
v2.onplaying = function() {
|
||||
if(!onPlayingEventFired) {
|
||||
onPlayingEventFired = true;
|
||||
v1.src = media.name;
|
||||
v1.onloadedmetadata = function() {
|
||||
v2.srcObject = v1.mozCaptureStream();
|
||||
v1.play();
|
||||
};
|
||||
|
||||
v2.addEventListener('playing', function() {
|
||||
ok(true, "playback started");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}, {once: true});
|
||||
}
|
||||
|
||||
setMediaTestsPrefs(startTest);
|
||||
}
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
|
@ -105,7 +105,7 @@ skip-if = toolkit == 'gonk' || toolkit == 'android' # B2G emulator is too slow t
|
||||
[test_peerConnection_basicAudioRequireEOC.html]
|
||||
skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g (Bug 1059867)
|
||||
[test_peerConnection_basicAudioPcmaPcmuOnly.html]
|
||||
skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g (Bug 1059867)
|
||||
skip-if = toolkit == 'gonk' || buildapp == 'mulet' || android_version == '18' # b2g (Bug 1059867)
|
||||
[test_peerConnection_basicAudioDynamicPtMissingRtpmap.html]
|
||||
skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g (Bug 1059867)
|
||||
[test_peerConnection_basicAudioVideo.html]
|
||||
|
@ -78,7 +78,7 @@ struct BasePoint {
|
||||
return x * aPoint.x + y * aPoint.y;
|
||||
}
|
||||
|
||||
T Length() const {
|
||||
Coord Length() const {
|
||||
return hypot(x, y);
|
||||
}
|
||||
|
||||
|
@ -79,19 +79,19 @@ static DllBlockInfo sWindowsDllBlocklist[] = {
|
||||
// The DLL name must be in lowercase!
|
||||
// The version field is a maximum, that is, we block anything that is
|
||||
// less-than or equal to that version.
|
||||
|
||||
|
||||
// NPFFAddon - Known malware
|
||||
{ "npffaddon.dll", ALL_VERSIONS},
|
||||
|
||||
// AVG 8 - Antivirus vendor AVG, old version, plugin already blocklisted
|
||||
{"avgrsstx.dll", MAKE_VERSION(8,5,0,401)},
|
||||
|
||||
|
||||
// calc.dll - Suspected malware
|
||||
{"calc.dll", MAKE_VERSION(1,0,0,1)},
|
||||
|
||||
// hook.dll - Suspected malware
|
||||
{"hook.dll", ALL_VERSIONS},
|
||||
|
||||
|
||||
// GoogleDesktopNetwork3.dll - Extremely old, unversioned instances
|
||||
// of this DLL cause crashes
|
||||
{"googledesktopnetwork3.dll", UNVERSIONED},
|
||||
@ -101,7 +101,7 @@ static DllBlockInfo sWindowsDllBlocklist[] = {
|
||||
|
||||
// fgjk4wvb.dll - Suspected malware
|
||||
{"fgjk4wvb.dll", MAKE_VERSION(8,8,8,8)},
|
||||
|
||||
|
||||
// radhslib.dll - Naomi internet filter - unmaintained since 2006
|
||||
{"radhslib.dll", UNVERSIONED},
|
||||
|
||||
@ -219,6 +219,9 @@ static DllBlockInfo sWindowsDllBlocklist[] = {
|
||||
{ "rlls.dll", ALL_VERSIONS },
|
||||
{ "rlls64.dll", ALL_VERSIONS },
|
||||
|
||||
// Vorbis DirectShow filters, bug 1239690.
|
||||
{ "vorbis.acm", MAKE_VERSION(0, 0, 3, 6) },
|
||||
|
||||
{ nullptr, 0 }
|
||||
};
|
||||
|
||||
@ -397,7 +400,7 @@ public:
|
||||
mReentered = mPreviousDllName && !stricmp(mPreviousDllName, dllName);
|
||||
(*sThreadMap)[currentThreadId] = dllName;
|
||||
}
|
||||
|
||||
|
||||
~ReentrancySentinel()
|
||||
{
|
||||
DWORD currentThreadId = GetCurrentThreadId();
|
||||
@ -409,7 +412,7 @@ public:
|
||||
{
|
||||
return mReentered;
|
||||
};
|
||||
|
||||
|
||||
static void InitializeStatics()
|
||||
{
|
||||
InitializeCriticalSection(&sLock);
|
||||
|
@ -198,10 +198,13 @@ def docker_worker_setup(config, test, taskdesc):
|
||||
'--chown', '/home/worker/workspace',
|
||||
]
|
||||
|
||||
# Support vcs checkouts regardless of whether the task runs from
|
||||
# source or not in case it is needed on an interactive loaner.
|
||||
docker_worker_support_vcs_checkout(config, test, taskdesc)
|
||||
|
||||
# If we have a source checkout, run mozharness from it instead of
|
||||
# downloading a zip file with the same content.
|
||||
if test['checkout']:
|
||||
docker_worker_support_vcs_checkout(config, test, taskdesc)
|
||||
command.extend(['--vcs-checkout', '/home/worker/checkouts/gecko'])
|
||||
env['MOZHARNESS_PATH'] = '/home/worker/checkouts/gecko/testing/mozharness'
|
||||
else:
|
||||
|
@ -1,4 +1,4 @@
|
||||
firefox-puppeteer >= 51.0.0, <52.0.0
|
||||
firefox-puppeteer >= 52.0.0, <53.0.0
|
||||
marionette-client >= 2.3.0
|
||||
mozfile >= 1.2
|
||||
mozinfo >= 0.8
|
||||
|
@ -19,7 +19,7 @@ class TestL10n(FirefoxTestCase):
|
||||
FirefoxTestCase.tearDown(self)
|
||||
|
||||
def test_dtd_entity_chrome(self):
|
||||
dtds = ['chrome://global/locale/filepicker.dtd',
|
||||
dtds = ['chrome://global/locale/about.dtd',
|
||||
'chrome://browser/locale/baseMenuOverlay.dtd']
|
||||
|
||||
value = self.l10n.get_entity(dtds, 'helpSafeMode.label')
|
||||
@ -29,7 +29,7 @@ class TestL10n(FirefoxTestCase):
|
||||
self.assertRaises(MarionetteException, self.l10n.get_entity, dtds, 'notExistent')
|
||||
|
||||
def test_dtd_entity_content(self):
|
||||
dtds = ['chrome://global/locale/filepicker.dtd',
|
||||
dtds = ['chrome://global/locale/about.dtd',
|
||||
'chrome://global/locale/aboutSupport.dtd']
|
||||
|
||||
value = self.l10n.get_entity(dtds, 'aboutSupport.pageTitle')
|
||||
|
@ -61,7 +61,7 @@ config = {
|
||||
"exes": {
|
||||
"hg": [
|
||||
"hg", "--config",
|
||||
"hostfingerprints.hg.mozilla.org=af:27:b9:34:47:4e:e5:98:01:f6:83:2b:51:c9:aa:d8:df:fb:1a:27",
|
||||
"hostfingerprints.hg.mozilla.org=73:7F:EF:AB:68:0F:49:3F:88:91:F0:B7:06:69:FD:8F:F2:55:C9:56",
|
||||
],
|
||||
"gittool.py": [sys.executable, os.getcwd() + "/build/tools/buildfarm/utils/gittool.py"],
|
||||
},
|
||||
|
@ -22,7 +22,7 @@ config = {
|
||||
"exes": {
|
||||
"hg": [
|
||||
"hg", "--config",
|
||||
"hostfingerprints.hg.mozilla.org=af:27:b9:34:47:4e:e5:98:01:f6:83:2b:51:c9:aa:d8:df:fb:1a:27",
|
||||
"hostfingerprints.hg.mozilla.org=73:7F:EF:AB:68:0F:49:3F:88:91:F0:B7:06:69:FD:8F:F2:55:C9:56",
|
||||
],
|
||||
}
|
||||
}
|
||||
|
@ -199,7 +199,7 @@ class TestingMixin(VirtualenvMixin, BuildbotMixin, ResourceMonitoringMixin,
|
||||
if symbols_url:
|
||||
self._urlopen(symbols_url, timeout=120)
|
||||
self.symbols_url = symbols_url
|
||||
except (urllib2.URLError, socket.error, socket.timeout):
|
||||
except (urllib2.HTTPError, urllib2.URLError, socket.error, socket.timeout):
|
||||
self.exception("Can't figure out symbols_url from installer_url: %s!" % self.installer_url, level=WARNING)
|
||||
|
||||
# If no symbols URL can be determined let minidump_stackwalk query the symbols.
|
||||
|
@ -2,14 +2,12 @@
|
||||
# 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/.
|
||||
|
||||
import os
|
||||
|
||||
from marionette_driver.marionette import HTMLElement
|
||||
|
||||
from decorators import use_class_as_property
|
||||
|
||||
|
||||
__version__ = '51.0.0'
|
||||
__version__ = '52.0.0'
|
||||
|
||||
|
||||
class Puppeteer(object):
|
||||
|
@ -4,24 +4,22 @@
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
if CONFIG['MOZ_XUL'] and \
|
||||
CONFIG['MOZ_WIDGET_TOOLKIT'] not in ('android', 'cocoa', 'windows'):
|
||||
XPIDL_MODULE = 'filepicker'
|
||||
XPIDL_SOURCES += [
|
||||
'nsIFileView.idl',
|
||||
]
|
||||
SOURCES += [
|
||||
'nsFileView.cpp',
|
||||
]
|
||||
EXTRA_COMPONENTS += [
|
||||
'nsFilePicker.js',
|
||||
]
|
||||
EXTRA_PP_COMPONENTS += [
|
||||
'nsFilePicker.manifest',
|
||||
]
|
||||
XPCSHELL_TESTS_MANIFESTS += [
|
||||
'test/unit/xpcshell.ini',
|
||||
]
|
||||
FINAL_LIBRARY = 'xul'
|
||||
XPIDL_MODULE = 'filepicker'
|
||||
XPIDL_SOURCES += [
|
||||
'nsIFileView.idl',
|
||||
]
|
||||
SOURCES += [
|
||||
'nsFileView.cpp',
|
||||
]
|
||||
EXTRA_COMPONENTS += [
|
||||
'nsFilePicker.js',
|
||||
]
|
||||
EXTRA_PP_COMPONENTS += [
|
||||
'nsFilePicker.manifest',
|
||||
]
|
||||
XPCSHELL_TESTS_MANIFESTS += [
|
||||
'test/unit/xpcshell.ini',
|
||||
]
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
||||
JAR_MANIFESTS += ['jar.mn']
|
||||
|
@ -26,7 +26,6 @@ DIRS += [
|
||||
'downloads',
|
||||
'extensions',
|
||||
'exthelper',
|
||||
'filepicker',
|
||||
'filewatcher',
|
||||
'finalizationwitness',
|
||||
'formautofill',
|
||||
@ -88,6 +87,9 @@ if CONFIG['MOZ_FEEDS']:
|
||||
if CONFIG['MOZ_XUL']:
|
||||
DIRS += ['autocomplete', 'satchel']
|
||||
|
||||
if 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']:
|
||||
DIRS += ['filepicker']
|
||||
|
||||
if CONFIG['MOZ_TOOLKIT_SEARCH']:
|
||||
DIRS += ['search']
|
||||
|
||||
|
@ -223,7 +223,7 @@
|
||||
content.document.documentElement.focus();
|
||||
});
|
||||
|
||||
gFindBar.close();
|
||||
gFindBar.close(true);
|
||||
yield new Promise(resolve => setTimeout(resolve, kIteratorTimeout));
|
||||
}
|
||||
]]></script>
|
||||
|
@ -369,9 +369,11 @@
|
||||
this._remoteWebNavigationImpl = this._remoteWebNavigation.wrappedJSObject;
|
||||
this._remoteWebNavigationImpl.swapBrowser(this);
|
||||
|
||||
// Initialize to the null principal
|
||||
let Services = Components.utils.import("resource://gre/modules/Services.jsm", {}).Services
|
||||
this._contentPrincipal = Services.scriptSecurityManager.createNullPrincipal({});
|
||||
// Initialize contentPrincipal to the about:blank principal for this loadcontext
|
||||
let {Services} = Components.utils.import("resource://gre/modules/Services.jsm", {});
|
||||
let aboutBlank = Services.io.newURI("about:blank", null, null);
|
||||
let ssm = Services.scriptSecurityManager;
|
||||
this._contentPrincipal = ssm.getLoadContextCodebasePrincipal(aboutBlank, this.loadContext);
|
||||
|
||||
this.messageManager.addMessageListener("Browser:Init", this);
|
||||
this.messageManager.addMessageListener("DOMTitleChanged", this);
|
||||
|
@ -46,7 +46,9 @@
|
||||
locale/@AB_CD@/global/extensions.properties (%chrome/global/extensions.properties)
|
||||
locale/@AB_CD@/global/fallbackMenubar.properties (%chrome/global/fallbackMenubar.properties)
|
||||
locale/@AB_CD@/global/filefield.properties (%chrome/global/filefield.properties)
|
||||
#ifdef MOZ_GTK
|
||||
locale/@AB_CD@/global/filepicker.dtd (%chrome/global/filepicker.dtd)
|
||||
#endif
|
||||
locale/@AB_CD@/global/filepicker.properties (%chrome/global/filepicker.properties)
|
||||
#ifndef MOZ_FENNEC
|
||||
locale/@AB_CD@/global/findbar.dtd (%chrome/global/findbar.dtd)
|
||||
|
@ -7,4 +7,7 @@
|
||||
if CONFIG['MOZ_BUILD_APP'] == 'mobile/android':
|
||||
DEFINES['MOZ_FENNEC'] = True
|
||||
|
||||
if 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']:
|
||||
DEFINES['MOZ_GTK'] = True
|
||||
|
||||
JAR_MANIFESTS += ['jar.mn']
|
||||
|
@ -233,12 +233,12 @@ FinderHighlighter.prototype = {
|
||||
this._found = true;
|
||||
},
|
||||
|
||||
onIteratorReset() {
|
||||
onIteratorReset() {},
|
||||
|
||||
onIteratorRestart() {
|
||||
this.clear(this.finder._getWindow());
|
||||
},
|
||||
|
||||
onIteratorRestart() {},
|
||||
|
||||
onIteratorStart(params) {
|
||||
let window = this.finder._getWindow();
|
||||
let dict = this.getForWindow(window);
|
||||
@ -511,8 +511,11 @@ FinderHighlighter.prototype = {
|
||||
onHighlightAllChange(highlightAll) {
|
||||
this._highlightAll = highlightAll;
|
||||
if (!highlightAll) {
|
||||
this.clear();
|
||||
this._scheduleRepaintOfMask(this.finder._getWindow());
|
||||
let window = this.finder._getWindow();
|
||||
if (!this._modal)
|
||||
this.hide(window);
|
||||
this.clear(window);
|
||||
this._scheduleRepaintOfMask(window);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -358,7 +358,7 @@ add_task(function* testHighlightAllToggle() {
|
||||
|
||||
// For posterity, let's switch back.
|
||||
expectedResult = {
|
||||
rectCount: 2,
|
||||
rectCount: 1,
|
||||
insertCalls: [1, 3],
|
||||
removeCalls: [0, 1]
|
||||
};
|
||||
|
@ -1,40 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
@import url("chrome://global/skin/");
|
||||
|
||||
@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
|
||||
|
||||
/* ::::: column widths ::::: */
|
||||
|
||||
#FilenameColumn,
|
||||
#ContentLengthColumn,
|
||||
#LastModifiedDateColumn {
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
/* ::::: file/directory items ::::: */
|
||||
|
||||
treechildren::-moz-tree-image(treecolAutoCompleteValue, directory),
|
||||
treechildren::-moz-tree-image(FilenameColumn, directory) {
|
||||
margin-right: 2px;
|
||||
list-style-image: url("chrome://global/skin/filepicker/dir-closed.gif");
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-image(treecolAutoCompleteValue, file),
|
||||
treechildren::-moz-tree-image(FilenameColumn, file) {
|
||||
list-style-image: url("chrome://global/skin/filepicker/blank.gif");
|
||||
}
|
||||
|
||||
/* ::::: button items ::::: */
|
||||
|
||||
.up-button {
|
||||
list-style-image: url("chrome://global/skin/filepicker/folder-up.gif");
|
||||
max-width: 36px;
|
||||
}
|
||||
|
||||
.home-button {
|
||||
list-style-image: url("chrome://global/skin/filepicker/folder-home.gif");
|
||||
max-width: 36px;
|
||||
}
|
@ -17,7 +17,6 @@ toolkit.jar:
|
||||
skin/classic/global/dialog.css
|
||||
skin/classic/global/dropmarker.css
|
||||
skin/classic/global/filefield.css
|
||||
skin/classic/global/filepicker.css
|
||||
skin/classic/global/filters.svg
|
||||
* skin/classic/global/findBar.css
|
||||
* skin/classic/global/global.css
|
||||
|
@ -1,77 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* ===== filepicker.css =================================================
|
||||
== Styles used by the File Picker dialog.
|
||||
======================================================================= */
|
||||
|
||||
@import url("chrome://global/skin/");
|
||||
|
||||
@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
|
||||
|
||||
/* ::::: column widths ::::: */
|
||||
|
||||
#FilenameColumn,
|
||||
#ContentLengthColumn,
|
||||
#LastModifiedDateColumn {
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
/* ::::: file/directory items ::::: */
|
||||
|
||||
treechildren::-moz-tree-image(treecolAutoCompleteValue, directory),
|
||||
treechildren::-moz-tree-image(FilenameColumn, directory) {
|
||||
list-style-image: url("chrome://global/skin/icons/folder-item.png");
|
||||
-moz-image-region: rect(0px, 32px, 16px, 16px);
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-image(treecolAutoCompleteValue, file),
|
||||
treechildren::-moz-tree-image(FilenameColumn, file) {
|
||||
list-style-image: url("chrome://global/skin/icons/folder-item.png");
|
||||
-moz-image-region: rect(16px, 16px, 32px, 0px);
|
||||
}
|
||||
|
||||
/* ::::: button items ::::: */
|
||||
|
||||
/* up-button */
|
||||
|
||||
.up-button {
|
||||
list-style-image: url("chrome://global/skin/Filepicker.png");
|
||||
-moz-image-region: rect(0px 24px 24px 0px);
|
||||
max-width: 36px;
|
||||
}
|
||||
|
||||
.up-button:hover {
|
||||
list-style-image: url("chrome://global/skin/Filepicker.png");
|
||||
-moz-image-region: rect(24px 24px 48px 0px);
|
||||
max-width: 36px;
|
||||
}
|
||||
|
||||
/* home-button */
|
||||
|
||||
.home-button {
|
||||
list-style-image: url("chrome://global/skin/Filepicker.png");
|
||||
-moz-image-region: rect(0px 48px 24px 24px);
|
||||
max-width: 36px;
|
||||
}
|
||||
|
||||
.home-button:hover {
|
||||
list-style-image: url("chrome://global/skin/Filepicker.png");
|
||||
-moz-image-region: rect(24px 48px 48px 24px);
|
||||
max-width: 36px;
|
||||
}
|
||||
|
||||
/* new-dir-button */
|
||||
|
||||
.new-dir-button {
|
||||
list-style-image: url("chrome://global/skin/Filepicker.png");
|
||||
-moz-image-region: rect(0px 72px 24px 48px);
|
||||
max-width: 36px;
|
||||
}
|
||||
|
||||
.new-dir-button:hover {
|
||||
list-style-image: url("chrome://global/skin/Filepicker.png");
|
||||
-moz-image-region: rect(24px 72px 48px 48px);
|
||||
max-width: 36px;
|
||||
}
|
Binary file not shown.
Before Width: | Height: | Size: 8.5 KiB |
@ -20,8 +20,6 @@ toolkit.jar:
|
||||
#endif
|
||||
skin/classic/global/colorpicker.css
|
||||
skin/classic/global/commonDialog.css
|
||||
skin/classic/global/filepicker.css
|
||||
skin/classic/global/Filepicker.png (filepicker/Filepicker.png)
|
||||
skin/classic/global/findBar.css
|
||||
* skin/classic/global/global.css
|
||||
skin/classic/global/listbox.css
|
||||
|
@ -1190,6 +1190,7 @@ VirtualKey::FillKbdState(PBYTE aKbdState,
|
||||
*****************************************************************************/
|
||||
|
||||
uint8_t NativeKey::sDispatchedKeyOfAppCommand = 0;
|
||||
NativeKey* NativeKey::sLatestInstance = nullptr;
|
||||
|
||||
LazyLogModule sNativeKeyLogger("NativeKeyWidgets");
|
||||
|
||||
@ -1198,7 +1199,10 @@ NativeKey::NativeKey(nsWindowBase* aWidget,
|
||||
const ModifierKeyState& aModKeyState,
|
||||
HKL aOverrideKeyboardLayout,
|
||||
nsTArray<FakeCharMsg>* aFakeCharMsgs)
|
||||
: mWidget(aWidget)
|
||||
: mLastInstance(sLatestInstance)
|
||||
, mRemovingMsg(EmptyMSG())
|
||||
, mReceivedMsg(EmptyMSG())
|
||||
, mWidget(aWidget)
|
||||
, mDispatcher(aWidget->GetTextEventDispatcher())
|
||||
, mMsg(aMessage)
|
||||
, mFocusedWndBeforeDispatch(::GetFocus())
|
||||
@ -1218,12 +1222,13 @@ NativeKey::NativeKey(nsWindowBase* aWidget,
|
||||
{
|
||||
MOZ_LOG(sNativeKeyLogger, LogLevel::Info,
|
||||
("%p NativeKey::NativeKey(aWidget=0x%p { GetWindowHandle()=0x%p }, "
|
||||
"aMessage=%s, aModKeyState=%s)",
|
||||
"aMessage=%s, aModKeyState=%s), sLatestInstance=0x%p",
|
||||
this, aWidget, aWidget->GetWindowHandle(), ToString(aMessage).get(),
|
||||
ToString(aModKeyState).get()));
|
||||
ToString(aModKeyState).get(), sLatestInstance));
|
||||
|
||||
MOZ_ASSERT(aWidget);
|
||||
MOZ_ASSERT(mDispatcher);
|
||||
sLatestInstance = this;
|
||||
KeyboardLayout* keyboardLayout = KeyboardLayout::GetInstance();
|
||||
mKeyboardLayout = keyboardLayout->GetLayout();
|
||||
if (aOverrideKeyboardLayout && mKeyboardLayout != aOverrideKeyboardLayout) {
|
||||
@ -1427,6 +1432,22 @@ NativeKey::InitWithKeyChar()
|
||||
case WM_CHAR:
|
||||
case WM_UNICHAR:
|
||||
case WM_SYSCHAR:
|
||||
// If there is another instance and it is trying to remove a char message
|
||||
// from the queue, this message should be handled in the old instance.
|
||||
if (IsAnotherInstanceRemovingCharMessage()) {
|
||||
// XXX Do we need to make mReceivedMsg an array?
|
||||
MOZ_ASSERT(IsEmptyMSG(mLastInstance->mReceivedMsg));
|
||||
MOZ_LOG(sNativeKeyLogger, LogLevel::Warning,
|
||||
("%p NativeKey::InitWithKeyChar(), WARNING, detecting another "
|
||||
"instance is trying to remove a char message, so, this instance "
|
||||
"should do nothing, mLastInstance=0x%p, mRemovingMsg=%s, "
|
||||
"mReceivedMsg=%s",
|
||||
this, mLastInstance, ToString(mLastInstance->mRemovingMsg).get(),
|
||||
ToString(mLastInstance->mReceivedMsg).get()));
|
||||
mLastInstance->mReceivedMsg = mMsg;
|
||||
return;
|
||||
}
|
||||
|
||||
// NOTE: If other applications like a11y tools sends WM_*CHAR without
|
||||
// scancode, we cannot compute virtual keycode. I.e., with such
|
||||
// applications, we cannot generate proper KeyboardEvent.code value.
|
||||
@ -1515,6 +1536,7 @@ NativeKey::~NativeKey()
|
||||
KeyboardLayout* keyboardLayout = KeyboardLayout::GetInstance();
|
||||
keyboardLayout->RestoreLayout();
|
||||
}
|
||||
sLatestInstance = mLastInstance;
|
||||
}
|
||||
|
||||
void
|
||||
@ -2458,6 +2480,15 @@ NativeKey::HandleCharMessage(const MSG& aCharMsg,
|
||||
*aEventDispatched = false;
|
||||
}
|
||||
|
||||
if (IsPrintableCharMessage(mMsg) && IsAnotherInstanceRemovingCharMessage()) {
|
||||
MOZ_LOG(sNativeKeyLogger, LogLevel::Warning,
|
||||
("%p NativeKey::HandleCharMessage(), WARNING, does nothing because "
|
||||
"the message should be handled in another instance removing this "
|
||||
"message", this));
|
||||
// Consume this for now because it will be handled by another instance.
|
||||
return true;
|
||||
}
|
||||
|
||||
// Alt+Space key is handled by OS, we shouldn't touch it.
|
||||
if (mModKeyState.IsAlt() && !mModKeyState.IsControl() &&
|
||||
mVirtualKeyCode == VK_SPACE) {
|
||||
@ -2813,7 +2844,7 @@ NativeKey::MayBeSameCharMessage(const MSG& aCharMsg1,
|
||||
}
|
||||
|
||||
bool
|
||||
NativeKey::GetFollowingCharMessage(MSG& aCharMsg) const
|
||||
NativeKey::GetFollowingCharMessage(MSG& aCharMsg)
|
||||
{
|
||||
MOZ_ASSERT(IsKeyDownMessage());
|
||||
MOZ_ASSERT(!IsKeyMessageOnPlugin());
|
||||
@ -2852,6 +2883,12 @@ NativeKey::GetFollowingCharMessage(MSG& aCharMsg) const
|
||||
return false;
|
||||
}
|
||||
|
||||
AutoRestore<MSG> saveLastRemovingMsg(mRemovingMsg);
|
||||
mRemovingMsg = nextKeyMsg;
|
||||
|
||||
mReceivedMsg = EmptyMSG();
|
||||
AutoRestore<MSG> ensureToClearRecivedMsg(mReceivedMsg);
|
||||
|
||||
// On Metrofox, PeekMessage() sometimes returns WM_NULL even if we specify
|
||||
// the message range. So, if it returns WM_NULL, we should retry to get
|
||||
// the following char message it was found above.
|
||||
@ -2864,6 +2901,46 @@ NativeKey::GetFollowingCharMessage(MSG& aCharMsg) const
|
||||
// We meets unexpected case. We should collect the message queue state
|
||||
// and crash for reporting the bug.
|
||||
doCrash = true;
|
||||
|
||||
// If another instance was created for the removing message during trying
|
||||
// to remove a char message, the instance didn't handle it for preventing
|
||||
// recursive handling. So, let's handle it in this instance.
|
||||
if (!IsEmptyMSG(mReceivedMsg)) {
|
||||
// If focus is moved to different window, we shouldn't handle it on
|
||||
// the widget. Let's discard it for now.
|
||||
if (mReceivedMsg.hwnd != nextKeyMsg.hwnd) {
|
||||
MOZ_LOG(sNativeKeyLogger, LogLevel::Warning,
|
||||
("%p NativeKey::GetFollowingCharMessage(), WARNING, received a "
|
||||
"char message during removing it from the queue, but it's for "
|
||||
"different window, mReceivedMsg=%s, nextKeyMsg=%s",
|
||||
this, ToString(mReceivedMsg).get(), ToString(nextKeyMsg).get()));
|
||||
// There might still exist char messages, the loop of calling
|
||||
// this method should be continued.
|
||||
aCharMsg.message = WM_NULL;
|
||||
return true;
|
||||
}
|
||||
// Even if the received message is different from what we tried to
|
||||
// remove from the queue, let's take the received message as a part of
|
||||
// the result of this key sequence.
|
||||
if (mReceivedMsg.message != nextKeyMsg.message ||
|
||||
mReceivedMsg.wParam != nextKeyMsg.wParam ||
|
||||
mReceivedMsg.lParam != nextKeyMsg.lParam) {
|
||||
MOZ_LOG(sNativeKeyLogger, LogLevel::Warning,
|
||||
("%p NativeKey::GetFollowingCharMessage(), WARNING, received a "
|
||||
"char message during removing it from the queue, but it's "
|
||||
"differnt from what trying to remove from the queue, "
|
||||
"aCharMsg=%s, nextKeyMsg=%s",
|
||||
this, ToString(mReceivedMsg).get(), ToString(nextKeyMsg).get()));
|
||||
} else {
|
||||
MOZ_LOG(sNativeKeyLogger, LogLevel::Verbose,
|
||||
("%p NativeKey::GetFollowingCharMessage(), succeeded to retrieve "
|
||||
"next char message via another instance, aCharMsg=%s",
|
||||
this, ToString(mReceivedMsg).get()));
|
||||
}
|
||||
aCharMsg = mReceivedMsg;
|
||||
return true;
|
||||
}
|
||||
|
||||
// The char message is redirected to different thread's window by focus
|
||||
// move or something or just cancelled by external application.
|
||||
if (!WinUtils::PeekMessage(&nextKeyMsgInAllWindows, 0,
|
||||
|
@ -259,6 +259,13 @@ public:
|
||||
static bool IsControlChar(char16_t aChar);
|
||||
|
||||
private:
|
||||
NativeKey* mLastInstance;
|
||||
// mRemovingMsg is set at removing a char message from
|
||||
// GetFollowingCharMessage().
|
||||
MSG mRemovingMsg;
|
||||
// mReceivedMsg is set when another instance starts to handle the message
|
||||
// unexpectedly.
|
||||
MSG mReceivedMsg;
|
||||
RefPtr<nsWindowBase> mWidget;
|
||||
RefPtr<TextEventDispatcher> mDispatcher;
|
||||
HKL mKeyboardLayout;
|
||||
@ -455,7 +462,7 @@ private:
|
||||
* WARNING: Even if this returns true, aCharMsg may be WM_NULL or its
|
||||
* hwnd may be different window.
|
||||
*/
|
||||
bool GetFollowingCharMessage(MSG& aCharMsg) const;
|
||||
bool GetFollowingCharMessage(MSG& aCharMsg);
|
||||
|
||||
/**
|
||||
* Whether the key event can compute virtual keycode from the scancode value.
|
||||
@ -543,6 +550,36 @@ private:
|
||||
{
|
||||
return mFocusedWndBeforeDispatch != ::GetFocus();
|
||||
}
|
||||
|
||||
// Calls of PeekMessage() from NativeKey might cause nested message handling
|
||||
// due to (perhaps) odd API hook. NativeKey should do nothing if given
|
||||
// message is tried to be retrieved by another instance.
|
||||
|
||||
/**
|
||||
* sLatestInstacne is a pointer to the newest instance of NativeKey which is
|
||||
* handling a key or char message(s).
|
||||
*/
|
||||
static NativeKey* sLatestInstance;
|
||||
|
||||
static const MSG EmptyMSG()
|
||||
{
|
||||
static bool sInitialized = false;
|
||||
static MSG sEmptyMSG;
|
||||
if (!sInitialized) {
|
||||
memset(&sEmptyMSG, 0, sizeof(sEmptyMSG));
|
||||
sInitialized = true;
|
||||
}
|
||||
return sEmptyMSG;
|
||||
}
|
||||
static bool IsEmptyMSG(const MSG& aMSG)
|
||||
{
|
||||
return !memcmp(&aMSG, &EmptyMSG(), sizeof(MSG));
|
||||
}
|
||||
|
||||
bool IsAnotherInstanceRemovingCharMessage() const
|
||||
{
|
||||
return mLastInstance && !IsEmptyMSG(mLastInstance->mRemovingMsg);
|
||||
}
|
||||
};
|
||||
|
||||
class KeyboardLayout
|
||||
|
@ -87,14 +87,12 @@ static nsresult
|
||||
DumpReport(nsIFileOutputStream* aOStream, const nsCString& aProcess,
|
||||
const nsCString& aName, const nsCString& aDescription)
|
||||
{
|
||||
int pid;
|
||||
if (aProcess.IsEmpty()) {
|
||||
pid = getpid();
|
||||
int pid = getpid();
|
||||
nsPrintfCString pidStr("PID %u", pid);
|
||||
DUMP(aOStream, "\n {\n \"Process\": \"");
|
||||
DUMP(aOStream, pidStr.get());
|
||||
} else {
|
||||
pid = 0;
|
||||
DUMP(aOStream, "\n { \"Unknown Process\": \"");
|
||||
}
|
||||
|
||||
|
@ -1436,10 +1436,8 @@ nsLocalFile::GetParent(nsIFile** aParent)
|
||||
|
||||
// <brendan, after jband> I promise to play nice
|
||||
char* buffer = mPath.BeginWriting();
|
||||
char* slashp = buffer;
|
||||
|
||||
// find the last significant slash in buffer
|
||||
slashp = strrchr(buffer, '/');
|
||||
char* slashp = strrchr(buffer, '/');
|
||||
NS_ASSERTION(slashp, "non-canonical path?");
|
||||
if (!slashp) {
|
||||
return NS_ERROR_FILE_INVALID_PATH;
|
||||
|
Loading…
Reference in New Issue
Block a user