Merge mozilla-central to mozilla-inbound

This commit is contained in:
Carsten "Tomcat" Book 2016-09-27 11:26:17 +02:00
commit ceb8695fd3
60 changed files with 488 additions and 336 deletions

View File

@ -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
View File

@ -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");

View File

@ -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);

View File

@ -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");

View File

@ -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");

View File

@ -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);

View File

@ -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 */

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -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);

View File

@ -12,5 +12,5 @@ var { Task } = require("devtools/shared/task");
var { require: browserRequire } = BrowserLoader({
baseURI: "resource://devtools/client/webconsole/",
window: this
window
});

View File

@ -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);
}
});

View File

@ -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);

View File

@ -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;

View File

@ -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));

View File

@ -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)

View File

@ -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;

View File

@ -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

View 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>

View File

@ -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.

View File

@ -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)
{

View File

@ -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;

View File

@ -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

View File

@ -40,8 +40,6 @@ public:
return TrackInfo::kVideoTrack;
}
void ConfigurationChanged(const TrackInfo& aConfig) override;
const char* GetDescriptionName() const override
{
nsCString failureReason;

View File

@ -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)

View File

@ -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();

View File

@ -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();

View File

@ -55,7 +55,6 @@ private:
void OnDecoderInitFailed(MediaResult aError);
RefPtr<PlatformDecoderModule> mPDM;
VideoInfo mOriginalConfig;
VideoInfo mCurrentConfig;
layers::LayersBackend mLayersBackend;
RefPtr<layers::ImageContainer> mImageContainer;

View File

@ -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

View File

@ -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];

View File

@ -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>

View File

@ -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]

View File

@ -78,7 +78,7 @@ struct BasePoint {
return x * aPoint.x + y * aPoint.y;
}
T Length() const {
Coord Length() const {
return hypot(x, y);
}

View File

@ -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);

View File

@ -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:

View File

@ -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

View File

@ -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')

View File

@ -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"],
},

View File

@ -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",
],
}
}

View File

@ -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.

View File

@ -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):

View File

@ -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']

View File

@ -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']

View File

@ -223,7 +223,7 @@
content.document.documentElement.focus();
});
gFindBar.close();
gFindBar.close(true);
yield new Promise(resolve => setTimeout(resolve, kIteratorTimeout));
}
]]></script>

View File

@ -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);

View File

@ -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)

View File

@ -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']

View File

@ -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);
}
},

View File

@ -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]
};

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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

View File

@ -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\": \"");
}

View File

@ -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;