summaryrefslogtreecommitdiffstats
path: root/dom
diff options
context:
space:
mode:
Diffstat (limited to 'dom')
-rw-r--r--dom/animation/AnimationEffectReadOnly.cpp1
-rw-r--r--dom/animation/AnimationTimeline.cpp1
-rw-r--r--dom/base/Attr.cpp2
-rw-r--r--dom/base/CustomElementRegistry.cpp1
-rw-r--r--dom/base/DOMException.cpp1
-rw-r--r--dom/base/DOMIntersectionObserver.cpp140
-rw-r--r--dom/base/DOMIntersectionObserver.h25
-rw-r--r--dom/base/Element.cpp71
-rw-r--r--dom/base/Element.h8
-rwxr-xr-xdom/base/File.cpp1
-rw-r--r--dom/base/FormData.cpp1
-rw-r--r--dom/base/FragmentOrElement.cpp10
-rw-r--r--dom/base/FragmentOrElement.h3
-rw-r--r--dom/base/Location.cpp36
-rw-r--r--dom/base/Navigator.cpp81
-rw-r--r--dom/base/Navigator.h7
-rw-r--r--dom/base/Pose.cpp1
-rw-r--r--dom/base/ProcessGlobal.cpp1
-rw-r--r--dom/base/nsAttrAndChildArray.cpp9
-rw-r--r--dom/base/nsCCUncollectableMarker.cpp40
-rw-r--r--dom/base/nsContentList.cpp1
-rw-r--r--dom/base/nsContentUtils.cpp71
-rw-r--r--dom/base/nsContentUtils.h19
-rw-r--r--dom/base/nsDOMAttributeMap.cpp1
-rw-r--r--dom/base/nsDOMClassInfo.cpp4
-rw-r--r--dom/base/nsDOMMutationObserver.cpp1
-rw-r--r--dom/base/nsDOMNavigationTiming.cpp7
-rw-r--r--dom/base/nsDOMWindowUtils.cpp2
-rw-r--r--dom/base/nsDocument.cpp214
-rw-r--r--dom/base/nsDocument.h15
-rw-r--r--dom/base/nsFrameLoader.cpp3
-rw-r--r--dom/base/nsFrameMessageManager.cpp15
-rw-r--r--dom/base/nsGenericDOMDataNode.cpp4
-rw-r--r--dom/base/nsGlobalWindow.cpp110
-rw-r--r--dom/base/nsGlobalWindow.h29
-rw-r--r--dom/base/nsIDocument.h18
-rw-r--r--dom/base/nsINode.cpp49
-rw-r--r--dom/base/nsJSEnvironment.cpp34
-rw-r--r--dom/base/nsJSTimeoutHandler.cpp1
-rw-r--r--dom/base/nsMappedAttributes.h11
-rw-r--r--dom/base/nsNodeInfoManager.cpp3
-rw-r--r--dom/base/nsNodeUtils.cpp10
-rw-r--r--dom/base/nsObjectLoadingContent.cpp10
-rw-r--r--dom/base/nsRange.cpp1
-rw-r--r--dom/base/nsScriptLoader.cpp13
-rw-r--r--dom/base/nsWrapperCache.cpp2
-rw-r--r--dom/base/nsWrapperCache.h5
-rw-r--r--dom/bindings/BindingUtils.cpp10
-rw-r--r--dom/bindings/BindingUtils.h103
-rw-r--r--dom/bindings/CallbackObject.cpp1
-rw-r--r--dom/bindings/Codegen.py341
-rw-r--r--dom/bindings/Configuration.py2
-rw-r--r--dom/bindings/Exceptions.cpp1
-rw-r--r--dom/bindings/MozMap.h121
-rw-r--r--dom/bindings/Record.h91
-rw-r--r--dom/bindings/SimpleGlobalObject.cpp2
-rw-r--r--dom/bindings/moz.build2
-rw-r--r--dom/bindings/parser/WebIDL.py152
-rw-r--r--dom/browser-element/BrowserElementParent.js13
-rw-r--r--dom/canvas/CanvasRenderingContext2D.cpp38
-rw-r--r--dom/canvas/CanvasRenderingContext2D.h12
-rw-r--r--dom/canvas/CanvasRenderingContextHelper.cpp14
-rw-r--r--dom/canvas/ImageBitmap.cpp101
-rw-r--r--dom/canvas/ImageBitmap.h12
-rw-r--r--dom/canvas/ImageBitmapRenderingContext.cpp5
-rw-r--r--dom/canvas/ImageData.cpp1
-rw-r--r--dom/canvas/WebGL1Context.cpp3
-rw-r--r--dom/canvas/WebGLContext.cpp103
-rw-r--r--dom/canvas/WebGLContext.h6
-rw-r--r--dom/canvas/WebGLTextureUpload.cpp22
-rw-r--r--dom/canvas/test/test_imagebitmap.html23
-rwxr-xr-xdom/console/Console.cpp1
-rw-r--r--dom/crypto/WebCryptoTask.cpp46
-rw-r--r--dom/events/DOMEventTargetHelper.cpp1
-rw-r--r--dom/events/DataTransfer.cpp1
-rwxr-xr-xdom/events/Event.cpp1
-rw-r--r--dom/events/EventDispatcher.cpp48
-rw-r--r--dom/events/EventStateManager.cpp6
-rw-r--r--dom/events/EventStateManager.h3
-rw-r--r--dom/events/JSEventHandler.cpp1
-rw-r--r--dom/fetch/Fetch.cpp7
-rw-r--r--dom/fetch/FetchConsumer.cpp10
-rw-r--r--dom/fetch/FetchDriver.cpp13
-rw-r--r--dom/fetch/Headers.cpp14
-rw-r--r--dom/fetch/Headers.h12
-rw-r--r--dom/fetch/InternalHeaders.cpp11
-rw-r--r--dom/fetch/InternalHeaders.h4
-rw-r--r--dom/filesystem/Directory.cpp1
-rw-r--r--dom/gamepad/GamepadManager.cpp18
-rw-r--r--dom/gamepad/GamepadManager.h6
-rw-r--r--dom/gamepad/GamepadServiceTest.cpp1
-rw-r--r--dom/gamepad/ipc/GamepadServiceType.h4
-rw-r--r--dom/geolocation/nsGeolocation.cpp70
-rw-r--r--dom/geolocation/nsGeolocation.h6
-rw-r--r--dom/html/HTMLCanvasElement.cpp43
-rw-r--r--dom/html/HTMLCanvasElement.h8
-rw-r--r--dom/html/HTMLFormControlsCollection.cpp1
-rw-r--r--dom/html/HTMLFormElement.cpp11
-rw-r--r--dom/html/HTMLImageElement.cpp2
-rw-r--r--dom/html/HTMLInputElement.cpp10
-rw-r--r--dom/html/HTMLMediaElement.cpp361
-rw-r--r--dom/html/HTMLMediaElement.h84
-rw-r--r--dom/html/HTMLOptionsCollection.cpp51
-rw-r--r--dom/html/HTMLOptionsCollection.h9
-rw-r--r--dom/html/HTMLSelectElement.cpp5
-rw-r--r--dom/html/HTMLSelectElement.h2
-rw-r--r--dom/html/HTMLTableElement.cpp15
-rw-r--r--dom/html/HTMLTableSectionElement.cpp2
-rw-r--r--dom/html/ImageDocument.cpp17
-rw-r--r--dom/html/ImageDocument.h3
-rw-r--r--dom/html/TextTrackManager.cpp37
-rw-r--r--dom/html/TextTrackManager.h15
-rw-r--r--dom/html/nsDOMStringMap.cpp1
-rw-r--r--dom/html/nsGenericHTMLElement.h7
-rw-r--r--dom/html/nsTextEditorState.cpp19
-rw-r--r--dom/indexedDB/ActorsChild.cpp4
-rw-r--r--dom/indexedDB/ActorsParent.cpp178
-rw-r--r--dom/indexedDB/FileManager.h3
-rw-r--r--dom/indexedDB/IDBCursor.cpp1
-rw-r--r--dom/indexedDB/IDBFactory.cpp19
-rw-r--r--dom/indexedDB/IDBIndex.cpp1
-rw-r--r--dom/indexedDB/IDBKeyRange.cpp1
-rw-r--r--dom/indexedDB/IDBObjectStore.cpp1
-rw-r--r--dom/indexedDB/IDBRequest.cpp2
-rw-r--r--dom/indexedDB/IDBWrapperCache.cpp2
-rw-r--r--dom/indexedDB/KeyPath.cpp77
-rw-r--r--dom/interfaces/html/nsIDOMHTMLElement.idl1
-rw-r--r--dom/ipc/ContentChild.cpp9
-rw-r--r--dom/ipc/ContentChild.h2
-rw-r--r--dom/ipc/ContentParent.cpp37
-rw-r--r--dom/ipc/ContentParent.h7
-rw-r--r--dom/ipc/PContent.ipdl13
-rw-r--r--dom/ipc/TabChild.cpp4
-rw-r--r--dom/locales/en-US/chrome/security/security.properties2
-rw-r--r--dom/media/AudioStream.cpp6
-rw-r--r--dom/media/Benchmark.cpp2
-rw-r--r--dom/media/CubebUtils.cpp33
-rw-r--r--dom/media/CubebUtils.h2
-rw-r--r--dom/media/DecoderTraits.cpp115
-rw-r--r--dom/media/GraphDriver.cpp21
-rw-r--r--dom/media/GraphDriver.h6
-rw-r--r--dom/media/MP3FrameParser.cpp591
-rw-r--r--dom/media/MP3FrameParser.h219
-rw-r--r--dom/media/MediaData.h3
-rw-r--r--dom/media/MediaDecoder.cpp52
-rw-r--r--dom/media/MediaDecoder.h8
-rw-r--r--dom/media/MediaDecoderStateMachine.cpp53
-rw-r--r--dom/media/MediaFormatReader.cpp4
-rw-r--r--dom/media/MediaManager.cpp54
-rw-r--r--dom/media/MediaPrefs.h6
-rw-r--r--dom/media/MediaStreamGraph.cpp3
-rw-r--r--dom/media/ThreadPoolCOMListener.h4
-rw-r--r--dom/media/VideoFrameContainer.cpp12
-rw-r--r--dom/media/VideoUtils.cpp56
-rw-r--r--dom/media/VideoUtils.h5
-rw-r--r--dom/media/WebVTTListener.h1
-rw-r--r--dom/media/android/AndroidMediaDecoder.cpp25
-rw-r--r--dom/media/android/AndroidMediaDecoder.h28
-rw-r--r--dom/media/android/AndroidMediaPluginHost.cpp305
-rw-r--r--dom/media/android/AndroidMediaPluginHost.h41
-rw-r--r--dom/media/android/AndroidMediaReader.cpp449
-rw-r--r--dom/media/android/AndroidMediaReader.h75
-rw-r--r--dom/media/android/AndroidMediaResourceServer.cpp503
-rw-r--r--dom/media/android/AndroidMediaResourceServer.h96
-rw-r--r--dom/media/android/MPAPI.h165
-rw-r--r--dom/media/android/moz.build27
-rw-r--r--dom/media/directshow/AudioSinkFilter.cpp285
-rw-r--r--dom/media/directshow/AudioSinkFilter.h95
-rw-r--r--dom/media/directshow/AudioSinkInputPin.cpp195
-rw-r--r--dom/media/directshow/AudioSinkInputPin.h76
-rw-r--r--dom/media/directshow/DirectShowDecoder.cpp65
-rw-r--r--dom/media/directshow/DirectShowDecoder.h45
-rw-r--r--dom/media/directshow/DirectShowReader.cpp360
-rw-r--r--dom/media/directshow/DirectShowReader.h110
-rw-r--r--dom/media/directshow/DirectShowUtils.cpp369
-rw-r--r--dom/media/directshow/DirectShowUtils.h125
-rw-r--r--dom/media/directshow/SampleSink.cpp159
-rw-r--r--dom/media/directshow/SampleSink.h67
-rw-r--r--dom/media/directshow/SourceFilter.cpp683
-rw-r--r--dom/media/directshow/SourceFilter.h75
-rw-r--r--dom/media/directshow/moz.build41
-rw-r--r--dom/media/eme/DetailedPromise.cpp3
-rw-r--r--dom/media/eme/MediaKeySession.cpp3
-rw-r--r--dom/media/eme/MediaKeys.cpp2
-rw-r--r--dom/media/fmp4/MP4Decoder.cpp12
-rw-r--r--dom/media/fmp4/MP4Demuxer.cpp64
-rw-r--r--dom/media/fmp4/MP4Stream.cpp3
-rw-r--r--dom/media/fmp4/moz.build3
-rw-r--r--dom/media/gmp/GMPParent.cpp3
-rw-r--r--dom/media/gmp/widevine-adapter/WidevineAdapter.cpp10
-rw-r--r--dom/media/gmp/widevine-adapter/WidevineDecryptor.cpp101
-rw-r--r--dom/media/gmp/widevine-adapter/WidevineDecryptor.h24
-rw-r--r--dom/media/gmp/widevine-adapter/WidevineUtils.cpp4
-rw-r--r--dom/media/gmp/widevine-adapter/WidevineUtils.h10
-rw-r--r--dom/media/gmp/widevine-adapter/WidevineVideoDecoder.h2
-rw-r--r--dom/media/gmp/widevine-adapter/content_decryption_module.h289
-rw-r--r--dom/media/gmp/widevine-adapter/content_decryption_module_export.h22
-rw-r--r--dom/media/gmp/widevine-adapter/content_decryption_module_ext.h64
-rw-r--r--dom/media/gtest/Cargo.toml7
-rw-r--r--dom/media/gtest/TestMP3Demuxer.cpp1
-rw-r--r--dom/media/gtest/TestMP4Reader.cpp217
-rw-r--r--dom/media/gtest/TestRust.cpp9
-rw-r--r--dom/media/gtest/hello.rs6
-rw-r--r--dom/media/gtest/moz.build1
-rw-r--r--dom/media/mediasource/MediaSource.cpp2
-rw-r--r--dom/media/mediasource/moz.build3
-rw-r--r--dom/media/moz.build18
-rw-r--r--dom/media/mp3/MP3Decoder.cpp (renamed from dom/media/MP3Decoder.cpp)2
-rw-r--r--dom/media/mp3/MP3Decoder.h (renamed from dom/media/MP3Decoder.h)0
-rw-r--r--dom/media/mp3/MP3Demuxer.cpp (renamed from dom/media/MP3Demuxer.cpp)2
-rw-r--r--dom/media/mp3/MP3Demuxer.h (renamed from dom/media/MP3Demuxer.h)2
-rw-r--r--dom/media/mp3/moz.build17
-rw-r--r--dom/media/ogg/OggDemuxer.cpp2
-rw-r--r--dom/media/platforms/MediaTelemetryConstants.h22
-rw-r--r--dom/media/platforms/PDMFactory.cpp9
-rw-r--r--dom/media/platforms/agnostic/AOMDecoder.cpp332
-rw-r--r--dom/media/platforms/agnostic/AOMDecoder.h62
-rw-r--r--dom/media/platforms/agnostic/AgnosticDecoderModule.cpp19
-rw-r--r--dom/media/platforms/agnostic/VPXDecoder.cpp53
-rw-r--r--dom/media/platforms/agnostic/VPXDecoder.h12
-rw-r--r--dom/media/platforms/ffmpeg/FFmpegDataDecoder.cpp18
-rw-r--r--dom/media/platforms/ffmpeg/FFmpegLibWrapper.cpp3
-rw-r--r--dom/media/platforms/ffmpeg/FFmpegLibWrapper.h7
-rw-r--r--dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp75
-rw-r--r--dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h1
-rw-r--r--dom/media/platforms/ffmpeg/ffvpx/moz.build2
-rw-r--r--dom/media/platforms/moz.build9
-rw-r--r--dom/media/platforms/omx/OmxPlatformLayer.cpp23
-rw-r--r--dom/media/platforms/wmf/DXVA2Manager.cpp8
-rw-r--r--dom/media/platforms/wmf/WMFAudioMFTManager.cpp1
-rw-r--r--dom/media/platforms/wmf/WMFDecoderModule.h6
-rw-r--r--dom/media/platforms/wmf/WMFMediaDataDecoder.cpp46
-rw-r--r--dom/media/platforms/wmf/WMFMediaDataDecoder.h6
-rw-r--r--dom/media/platforms/wmf/WMFVideoMFTManager.cpp4
-rw-r--r--dom/media/systemservices/LoadManager.cpp18
-rw-r--r--dom/media/test/bug1377278.webm (renamed from dom/media/test/bug580982.webm)bin215594 -> 215594 bytes
-rw-r--r--dom/media/test/bug1377278.webm^headers^ (renamed from dom/media/test/bug580982.webm^headers^)0
-rw-r--r--dom/media/test/crashtests/1228484.html13
-rw-r--r--dom/media/test/crashtests/crashtests.list2
-rw-r--r--dom/media/test/manifest.js8
-rw-r--r--dom/media/test/mochitest.ini4
-rw-r--r--dom/media/test/test_can_play_type_mpeg.html3
-rw-r--r--dom/media/webaudio/AudioBuffer.cpp1
-rwxr-xr-xdom/media/webaudio/AudioContext.cpp12
-rw-r--r--dom/media/webaudio/AudioContext.h6
-rw-r--r--dom/media/webaudio/AudioParam.cpp1
-rw-r--r--dom/media/webaudio/MediaBufferDecoder.cpp3
-rw-r--r--dom/media/webaudio/WaveShaperNode.cpp1
-rw-r--r--dom/media/webm/WebMDecoder.cpp9
-rw-r--r--dom/media/webm/WebMDemuxer.cpp166
-rw-r--r--dom/media/webm/WebMDemuxer.h18
-rw-r--r--dom/media/webrtc/RTCCertificate.cpp2
-rw-r--r--dom/moz.build1
-rw-r--r--dom/network/TCPSocketChild.cpp1
-rw-r--r--dom/notification/Notification.cpp212
-rw-r--r--dom/notification/Notification.h34
-rw-r--r--dom/performance/PerformanceMainThread.cpp1
-rw-r--r--dom/performance/PerformanceObserver.cpp1
-rw-r--r--dom/plugins/base/nptypes.h12
-rw-r--r--dom/plugins/base/nsPluginHost.cpp9
-rw-r--r--dom/plugins/base/nsPluginsDirUnix.cpp22
-rw-r--r--dom/plugins/ipc/PluginAsyncSurrogate.cpp2
-rw-r--r--dom/plugins/ipc/PluginHangUIParent.cpp9
-rw-r--r--dom/plugins/ipc/PluginInstanceParent.cpp13
-rwxr-xr-xdom/plugins/ipc/PluginModuleParent.cpp80
-rw-r--r--dom/plugins/ipc/PluginModuleParent.h3
-rw-r--r--dom/presentation/provider/PresentationControlService.js1
-rw-r--r--dom/promise/Promise.cpp2
-rw-r--r--dom/promise/PromiseCallback.cpp4
-rw-r--r--dom/push/PushSubscriptionOptions.cpp1
-rw-r--r--dom/security/nsContentSecurityManager.cpp56
-rw-r--r--dom/security/nsContentSecurityManager.h1
-rw-r--r--dom/security/nsMixedContentBlocker.cpp54
-rw-r--r--dom/security/nsMixedContentBlocker.h3
-rw-r--r--dom/security/test/cors/test_CrossSiteXHR.html2
-rw-r--r--dom/smil/nsSMILAnimationController.cpp2
-rw-r--r--dom/storage/DOMStorageCache.cpp60
-rw-r--r--dom/storage/DOMStorageCache.h6
-rw-r--r--dom/storage/DOMStorageDBThread.cpp2
-rw-r--r--dom/svg/DOMSVGLength.cpp1
-rw-r--r--dom/svg/DOMSVGLengthList.cpp1
-rw-r--r--dom/svg/DOMSVGNumber.cpp1
-rw-r--r--dom/svg/DOMSVGNumberList.cpp1
-rw-r--r--dom/svg/DOMSVGPathSeg.cpp1
-rw-r--r--dom/svg/DOMSVGPathSegList.cpp1
-rw-r--r--dom/svg/DOMSVGPointList.cpp1
-rw-r--r--dom/svg/DOMSVGTransformList.cpp1
-rw-r--r--dom/svg/SVGTransform.cpp1
-rw-r--r--dom/svg/SVGUseElement.cpp9
-rw-r--r--dom/svg/nsISVGPoint.cpp1
-rw-r--r--dom/svg/nsSVGElement.h1
-rw-r--r--dom/svg/test/reftest_viewport_noninteger.html175
-rw-r--r--dom/system/mac/CoreLocationLocationProvider.mm3
-rw-r--r--dom/system/windows/WindowsLocationProvider.cpp4
-rw-r--r--dom/url/URLSearchParams.cpp51
-rw-r--r--dom/url/URLSearchParams.h19
-rw-r--r--dom/vr/VRDisplay.cpp802
-rw-r--r--dom/vr/VRDisplay.h362
-rw-r--r--dom/vr/VREventObserver.cpp79
-rw-r--r--dom/vr/VREventObserver.h33
-rw-r--r--dom/vr/moz.build22
-rw-r--r--dom/webidl/AddonEvent.webidl12
-rw-r--r--dom/webidl/AddonManager.webidl91
-rw-r--r--dom/webidl/AudioContext.webidl1
-rw-r--r--dom/webidl/CommandEvent.webidl6
-rw-r--r--dom/webidl/CompositionEvent.webidl10
-rw-r--r--dom/webidl/CustomEvent.webidl6
-rw-r--r--dom/webidl/DeviceMotionEvent.webidl12
-rw-r--r--dom/webidl/DeviceOrientationEvent.webidl12
-rw-r--r--dom/webidl/DragEvent.webidl30
-rw-r--r--dom/webidl/Element.webidl6
-rw-r--r--dom/webidl/Event.webidl4
-rw-r--r--dom/webidl/HashChangeEvent.webidl8
-rw-r--r--dom/webidl/Headers.webidl2
-rw-r--r--dom/webidl/InstallTrigger.webidl2
-rw-r--r--dom/webidl/IntersectionObserver.webidl6
-rw-r--r--dom/webidl/KeyEvent.webidl18
-rw-r--r--dom/webidl/MessageEvent.webidl12
-rw-r--r--dom/webidl/MouseEvent.webidl64
-rw-r--r--dom/webidl/MouseScrollEvent.webidl30
-rw-r--r--dom/webidl/MutationEvent.webidl14
-rw-r--r--dom/webidl/Navigator.webidl8
-rw-r--r--dom/webidl/ScrollAreaEvent.webidl16
-rw-r--r--dom/webidl/SimpleGestureEvent.webidl36
-rw-r--r--dom/webidl/StorageEvent.webidl14
-rw-r--r--dom/webidl/TestInterfaceJS.webidl2
-rw-r--r--dom/webidl/TimeEvent.webidl4
-rw-r--r--dom/webidl/TouchEvent.webidl22
-rw-r--r--dom/webidl/UIEvent.webidl8
-rw-r--r--dom/webidl/URLSearchParams.webidl3
-rw-r--r--dom/webidl/VRDisplay.webidl286
-rw-r--r--dom/webidl/XULCommandEvent.webidl18
-rw-r--r--dom/webidl/moz.build7
-rw-r--r--dom/workers/RuntimeService.cpp14
-rw-r--r--dom/workers/ServiceWorkerClient.cpp2
-rw-r--r--dom/workers/ServiceWorkerClients.cpp8
-rw-r--r--dom/workers/ServiceWorkerEvents.cpp20
-rw-r--r--dom/workers/ServiceWorkerManager.cpp3
-rw-r--r--dom/workers/ServiceWorkerPrivate.cpp15
-rw-r--r--dom/workers/ServiceWorkerRegistrar.cpp3
-rw-r--r--dom/workers/ServiceWorkerRegistration.cpp8
-rw-r--r--dom/workers/ServiceWorkerUpdateJob.cpp2
-rw-r--r--dom/workers/ServiceWorkerWindowClient.cpp4
-rw-r--r--dom/workers/SharedWorker.cpp3
-rw-r--r--dom/workers/WorkerPrivate.cpp10
-rw-r--r--dom/workers/WorkerRunnable.cpp25
-rw-r--r--dom/workers/WorkerScope.cpp2
-rw-r--r--dom/worklet/WorkletGlobalScope.cpp2
-rw-r--r--dom/xbl/nsXBLBinding.cpp3
-rw-r--r--dom/xbl/nsXBLDocumentInfo.cpp2
-rw-r--r--dom/xbl/nsXBLProtoImpl.cpp12
-rw-r--r--dom/xhr/XMLHttpRequestMainThread.cpp11
-rw-r--r--dom/xhr/XMLHttpRequestWorker.cpp2
-rw-r--r--dom/xslt/xpath/XPathResult.cpp1
-rw-r--r--dom/xslt/xpath/txUnaryExpr.cpp9
-rw-r--r--dom/xslt/xslt/txMozillaStylesheetCompiler.cpp4
-rw-r--r--dom/xul/nsXULElement.cpp1
-rw-r--r--dom/xul/nsXULPrototypeCache.cpp6
358 files changed, 2967 insertions, 11376 deletions
diff --git a/dom/animation/AnimationEffectReadOnly.cpp b/dom/animation/AnimationEffectReadOnly.cpp
index bf2e2197d..63d633c2f 100644
--- a/dom/animation/AnimationEffectReadOnly.cpp
+++ b/dom/animation/AnimationEffectReadOnly.cpp
@@ -23,7 +23,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(AnimationEffectReadOnly)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocument, mTiming, mAnimation)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(AnimationEffectReadOnly)
diff --git a/dom/animation/AnimationTimeline.cpp b/dom/animation/AnimationTimeline.cpp
index 643106807..f4a1ecc9a 100644
--- a/dom/animation/AnimationTimeline.cpp
+++ b/dom/animation/AnimationTimeline.cpp
@@ -21,7 +21,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(AnimationTimeline)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindow, mAnimations)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(AnimationTimeline)
diff --git a/dom/base/Attr.cpp b/dom/base/Attr.cpp
index 6eb3b49fd..71b559392 100644
--- a/dom/base/Attr.cpp
+++ b/dom/base/Attr.cpp
@@ -59,8 +59,6 @@ Attr::Attr(nsDOMAttributeMap *aAttrMap,
NS_IMPL_CYCLE_COLLECTION_CLASS(Attr)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Attr)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
-
if (!nsINode::Traverse(tmp, cb)) {
return NS_SUCCESS_INTERRUPTED_TRAVERSE;
}
diff --git a/dom/base/CustomElementRegistry.cpp b/dom/base/CustomElementRegistry.cpp
index 00ee3d42f..3f202d33b 100644
--- a/dom/base/CustomElementRegistry.cpp
+++ b/dom/base/CustomElementRegistry.cpp
@@ -138,7 +138,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(CustomElementRegistry)
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWhenDefinedPromiseMap)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindow)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(CustomElementRegistry)
diff --git a/dom/base/DOMException.cpp b/dom/base/DOMException.cpp
index dfda47316..9fbb2f242 100644
--- a/dom/base/DOMException.cpp
+++ b/dom/base/DOMException.cpp
@@ -165,7 +165,6 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(Exception)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Exception)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLocation)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mData)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(Exception)
diff --git a/dom/base/DOMIntersectionObserver.cpp b/dom/base/DOMIntersectionObserver.cpp
index e39abf1a6..389b93071 100644
--- a/dom/base/DOMIntersectionObserver.cpp
+++ b/dom/base/DOMIntersectionObserver.cpp
@@ -43,16 +43,17 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DOMIntersectionObserver)
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
+ tmp->Disconnect();
NS_IMPL_CYCLE_COLLECTION_UNLINK(mOwner)
+ NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocument)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mCallback)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mRoot)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mQueuedEntries)
- tmp->Disconnect();
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(DOMIntersectionObserver)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOwner)
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocument)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCallback)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRoot)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mQueuedEntries)
@@ -153,30 +154,34 @@ DOMIntersectionObserver::Observe(Element& aTarget)
return;
}
aTarget.RegisterIntersectionObserver(this);
- mObservationTargets.PutEntry(&aTarget);
+ mObservationTargets.AppendElement(&aTarget);
Connect();
}
void
DOMIntersectionObserver::Unobserve(Element& aTarget)
{
- if (UnlinkTarget(aTarget)) {
- aTarget.UnregisterIntersectionObserver(this);
+ if (!mObservationTargets.Contains(&aTarget)) {
+ // You're not on the list, buddy!
+ return;
}
+
+ if (mObservationTargets.Length() == 1) {
+ Disconnect();
+ return;
+ }
+
+ mObservationTargets.RemoveElement(&aTarget);
+ aTarget.UnregisterIntersectionObserver(this);
}
-bool
+void
DOMIntersectionObserver::UnlinkTarget(Element& aTarget)
{
- if (!mObservationTargets.Contains(&aTarget)) {
- return false;
- }
- if (mObservationTargets.Count() == 1) {
- Disconnect();
- return false;
- }
- mObservationTargets.RemoveEntry(&aTarget);
- return true;
+ mObservationTargets.RemoveElement(&aTarget);
+ if (mObservationTargets.Length() == 0) {
+ Disconnect();
+ }
}
void
@@ -185,10 +190,11 @@ DOMIntersectionObserver::Connect()
if (mConnected) {
return;
}
+
mConnected = true;
-
- nsIDocument* document = mOwner->GetExtantDoc();
- document->AddIntersectionObserver(this);
+ if (mDocument) {
+ mDocument->AddIntersectionObserver(this);
+ }
}
void
@@ -197,18 +203,17 @@ DOMIntersectionObserver::Disconnect()
if (!mConnected) {
return;
}
- for (auto iter = mObservationTargets.Iter(); !iter.Done(); iter.Next()) {
- Element* target = iter.Get()->GetKey();
+
+ mConnected = false;
+
+ for (size_t i = 0; i < mObservationTargets.Length(); ++i) {
+ Element* target = mObservationTargets.ElementAt(i);
target->UnregisterIntersectionObserver(this);
}
mObservationTargets.Clear();
- if (mOwner) {
- nsIDocument* document = mOwner->GetExtantDoc();
- if (document) {
- document->RemoveIntersectionObserver(this);
- }
+ if (mDocument) {
+ mDocument->RemoveIntersectionObserver(this);
}
- mConnected = false;
}
void
@@ -269,17 +274,21 @@ DOMIntersectionObserver::Update(nsIDocument* aDocument, DOMHighResTimeStamp time
root = mRoot;
rootFrame = root->GetPrimaryFrame();
if (rootFrame) {
+ nsRect rootRectRelativeToRootFrame;
if (rootFrame->GetType() == nsGkAtoms::scrollFrame) {
+ // rootRectRelativeToRootFrame should be the content rect of rootFrame, not including the scrollbars.
nsIScrollableFrame* scrollFrame = do_QueryFrame(rootFrame);
- rootRect = nsLayoutUtils::TransformFrameRectToAncestor(
- rootFrame,
- rootFrame->GetContentRectRelativeToSelf(),
- scrollFrame->GetScrolledFrame());
+ rootRectRelativeToRootFrame = scrollFrame->GetScrollPortRect();
} else {
- rootRect = nsLayoutUtils::GetAllInFlowRectsUnion(rootFrame,
- nsLayoutUtils::GetContainingBlockForClientRect(rootFrame),
- nsLayoutUtils::RECTS_ACCOUNT_FOR_TRANSFORMS);
+ // rootRectRelativeToRootFrame should be the border rect of rootFrame.
+ rootRectRelativeToRootFrame = rootFrame->GetRectRelativeToSelf();
}
+ nsIFrame* containingBlock =
+ nsLayoutUtils::GetContainingBlockForClientRect(rootFrame);
+ rootRect =
+ nsLayoutUtils::TransformFrameRectToAncestor(rootFrame,
+ rootRectRelativeToRootFrame,
+ containingBlock);
}
} else {
nsCOMPtr<nsIPresShell> presShell = aDocument->GetShell();
@@ -288,12 +297,25 @@ DOMIntersectionObserver::Update(nsIDocument* aDocument, DOMHighResTimeStamp time
if (rootFrame) {
nsPresContext* presContext = rootFrame->PresContext();
while (!presContext->IsRootContentDocument()) {
- presContext = rootFrame->PresContext()->GetParentPresContext();
- rootFrame = presContext->PresShell()->GetRootScrollFrame();
+ // Walk up the tree
+ presContext = presContext->GetParentPresContext();
+ if (!presContext) {
+ break;
+ }
+ nsIFrame* rootScrollFrame = presContext->PresShell()->GetRootScrollFrame();
+ if (rootScrollFrame) {
+ rootFrame = rootScrollFrame;
+ } else {
+ break;
+ }
}
root = rootFrame->GetContent()->AsElement();
nsIScrollableFrame* scrollFrame = do_QueryFrame(rootFrame);
- rootRect = scrollFrame->GetScrollPortRect();
+ // If we end up with a null root frame for some reason, we'll proceed
+ // with an empty root intersection rect.
+ if (scrollFrame) {
+ rootRect = scrollFrame->GetScrollPortRect();
+ }
}
}
}
@@ -314,11 +336,12 @@ DOMIntersectionObserver::Update(nsIDocument* aDocument, DOMHighResTimeStamp time
rootMargin.Side(side) = nsLayoutUtils::ComputeCBDependentValue(basis, coord);
}
- for (auto iter = mObservationTargets.Iter(); !iter.Done(); iter.Next()) {
- Element* target = iter.Get()->GetKey();
+ for (size_t i = 0; i < mObservationTargets.Length(); ++i) {
+ Element* target = mObservationTargets.ElementAt(i);
nsIFrame* targetFrame = target->GetPrimaryFrame();
nsRect targetRect;
Maybe<nsRect> intersectionRect;
+ bool isSameDoc = root && root->GetComposedDoc() == target->GetComposedDoc();
if (rootFrame && targetFrame) {
// If mRoot is set we are testing intersection with a container element
@@ -327,7 +350,7 @@ DOMIntersectionObserver::Update(nsIDocument* aDocument, DOMHighResTimeStamp time
// Skip further processing of this target if it is not in the same
// Document as the intersection root, e.g. if root is an element of
// the main document and target an element from an embedded iframe.
- if (target->GetComposedDoc() != root->GetComposedDoc()) {
+ if (!isSameDoc) {
continue;
}
// Skip further processing of this target if is not a descendant of the
@@ -344,7 +367,7 @@ DOMIntersectionObserver::Update(nsIDocument* aDocument, DOMHighResTimeStamp time
nsLayoutUtils::GetContainingBlockForClientRect(targetFrame),
nsLayoutUtils::RECTS_ACCOUNT_FOR_TRANSFORMS
);
- intersectionRect = Some(targetFrame->GetVisualOverflowRect());
+ intersectionRect = Some(targetFrame->GetRectRelativeToSelf());
nsIFrame* containerFrame = nsLayoutUtils::GetCrossDocParentFrame(targetFrame);
while (containerFrame && containerFrame != rootFrame) {
@@ -399,29 +422,37 @@ DOMIntersectionObserver::Update(nsIDocument* aDocument, DOMHighResTimeStamp time
intersectionRectRelativeToRoot,
rootIntersectionRect
);
- if (intersectionRect.isSome()) {
- intersectionRect = Some(nsLayoutUtils::TransformFrameRectToAncestor(
- nsLayoutUtils::GetContainingBlockForClientRect(rootFrame),
- intersectionRect.value(),
- targetFrame->PresContext()->PresShell()->GetRootScrollFrame()
- ));
+ if (intersectionRect.isSome() && !isSameDoc) {
+ nsRect rect = intersectionRect.value();
+ nsPresContext* presContext = targetFrame->PresContext();
+ nsLayoutUtils::TransformRect(rootFrame,
+ presContext->PresShell()->GetRootScrollFrame(), rect);
+ intersectionRect = Some(rect);
}
}
- double targetArea = targetRect.width * targetRect.height;
- double intersectionArea = !intersectionRect ?
- 0 : intersectionRect->width * intersectionRect->height;
- double intersectionRatio = targetArea > 0.0 ? intersectionArea / targetArea : 0.0;
+ int64_t targetArea =
+ (int64_t) targetRect.Width() * (int64_t) targetRect.Height();
+ int64_t intersectionArea = !intersectionRect ? 0 :
+ (int64_t) intersectionRect->Width() *
+ (int64_t) intersectionRect->Height();
+
+ double intersectionRatio;
+ if (targetArea > 0.0) {
+ intersectionRatio = (double) intersectionArea / (double) targetArea;
+ } else {
+ intersectionRatio = intersectionRect.isSome() ? 1.0 : 0.0;
+ }
- size_t threshold = -1;
+ int32_t threshold = -1;
if (intersectionRatio > 0.0) {
if (intersectionRatio >= 1.0) {
intersectionRatio = 1.0;
- threshold = mThresholds.Length();
+ threshold = (int32_t)mThresholds.Length();
} else {
for (size_t k = 0; k < mThresholds.Length(); ++k) {
if (mThresholds[k] <= intersectionRatio) {
- threshold = k + 1;
+ threshold = (int32_t)k + 1;
} else {
break;
}
@@ -468,6 +499,7 @@ DOMIntersectionObserver::QueueIntersectionObserverEntry(Element* aTarget,
rootBounds.forget(),
boundingClientRect.forget(),
intersectionRect.forget(),
+ aIntersectionRect.isSome(),
aTarget, aIntersectionRatio);
mQueuedEntries.AppendElement(entry.forget());
}
@@ -480,7 +512,7 @@ DOMIntersectionObserver::Notify()
}
mozilla::dom::Sequence<mozilla::OwningNonNull<DOMIntersectionObserverEntry>> entries;
if (entries.SetCapacity(mQueuedEntries.Length(), mozilla::fallible)) {
- for (uint32_t i = 0; i < mQueuedEntries.Length(); ++i) {
+ for (size_t i = 0; i < mQueuedEntries.Length(); ++i) {
RefPtr<DOMIntersectionObserverEntry> next = mQueuedEntries[i];
*entries.AppendElement(mozilla::fallible) = next;
}
diff --git a/dom/base/DOMIntersectionObserver.h b/dom/base/DOMIntersectionObserver.h
index 8144fc5c5..8674fe25d 100644
--- a/dom/base/DOMIntersectionObserver.h
+++ b/dom/base/DOMIntersectionObserver.h
@@ -30,6 +30,7 @@ public:
RefPtr<DOMRect> aRootBounds,
RefPtr<DOMRect> aBoundingClientRect,
RefPtr<DOMRect> aIntersectionRect,
+ bool aIsIntersecting,
Element* aTarget,
double aIntersectionRatio)
: mOwner(aOwner),
@@ -37,6 +38,7 @@ public:
mRootBounds(aRootBounds),
mBoundingClientRect(aBoundingClientRect),
mIntersectionRect(aIntersectionRect),
+ mIsIntersecting(aIsIntersecting),
mTarget(aTarget),
mIntersectionRatio(aIntersectionRatio)
{
@@ -74,6 +76,11 @@ public:
return mIntersectionRect;
}
+ bool IsIntersecting()
+ {
+ return mIsIntersecting;
+ }
+
double IntersectionRatio()
{
return mIntersectionRatio;
@@ -90,6 +97,7 @@ protected:
RefPtr<DOMRect> mRootBounds;
RefPtr<DOMRect> mBoundingClientRect;
RefPtr<DOMRect> mIntersectionRect;
+ bool mIsIntersecting;
RefPtr<Element> mTarget;
double mIntersectionRatio;
};
@@ -101,12 +109,17 @@ protected:
class DOMIntersectionObserver final : public nsISupports,
public nsWrapperCache
{
- virtual ~DOMIntersectionObserver() { }
+ virtual ~DOMIntersectionObserver() {
+ Disconnect();
+ }
public:
DOMIntersectionObserver(already_AddRefed<nsPIDOMWindowInner>&& aOwner,
mozilla::dom::IntersectionCallback& aCb)
- : mOwner(aOwner), mCallback(&aCb), mConnected(false)
+ : mOwner(aOwner)
+ , mDocument(mOwner->GetExtantDoc())
+ , mCallback(&aCb)
+ , mConnected(false)
{
}
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
@@ -142,7 +155,7 @@ public:
void Observe(Element& aTarget);
void Unobserve(Element& aTarget);
- bool UnlinkTarget(Element& aTarget);
+ void UnlinkTarget(Element& aTarget);
void Disconnect();
void TakeRecords(nsTArray<RefPtr<DOMIntersectionObserverEntry>>& aRetVal);
@@ -164,11 +177,15 @@ protected:
double aIntersectionRatio);
nsCOMPtr<nsPIDOMWindowInner> mOwner;
+ RefPtr<nsIDocument> mDocument;
RefPtr<mozilla::dom::IntersectionCallback> mCallback;
RefPtr<Element> mRoot;
nsCSSRect mRootMargin;
nsTArray<double> mThresholds;
- nsTHashtable<nsPtrHashKey<Element>> mObservationTargets;
+
+ // Holds raw pointers which are explicitly cleared by UnlinkTarget().
+ nsTArray<Element*> mObservationTargets;
+
nsTArray<RefPtr<DOMIntersectionObserverEntry>> mQueuedEntries;
bool mConnected;
};
diff --git a/dom/base/Element.cpp b/dom/base/Element.cpp
index 79b36a314..5c3277e84 100644
--- a/dom/base/Element.cpp
+++ b/dom/base/Element.cpp
@@ -145,7 +145,6 @@
#include "mozilla/dom/KeyframeEffectBinding.h"
#include "mozilla/dom/WindowBinding.h"
#include "mozilla/dom/ElementBinding.h"
-#include "mozilla/dom/VRDisplay.h"
#include "mozilla/IntegerPrintfMacros.h"
#include "mozilla/Preferences.h"
#include "nsComputedDOMStyle.h"
@@ -688,19 +687,23 @@ Element::GetScrollFrame(nsIFrame **aStyledFrame, bool aFlushLayout)
}
void
-Element::ScrollIntoView()
+Element::ScrollIntoView(const BooleanOrScrollIntoViewOptions& aObject)
{
- ScrollIntoView(ScrollIntoViewOptions());
-}
+ if (aObject.IsScrollIntoViewOptions()) {
+ return ScrollIntoView(aObject.GetAsScrollIntoViewOptions());
+ }
+
+ MOZ_DIAGNOSTIC_ASSERT(aObject.IsBoolean());
-void
-Element::ScrollIntoView(bool aTop)
-{
ScrollIntoViewOptions options;
- if (!aTop) {
+ if (aObject.GetAsBoolean()) {
+ options.mBlock = ScrollLogicalPosition::Start;
+ options.mInline = ScrollLogicalPosition::Nearest;
+ } else {
options.mBlock = ScrollLogicalPosition::End;
+ options.mInline = ScrollLogicalPosition::Nearest;
}
- ScrollIntoView(options);
+ return ScrollIntoView(options);
}
void
@@ -717,9 +720,41 @@ Element::ScrollIntoView(const ScrollIntoViewOptions &aOptions)
return;
}
- int16_t vpercent = (aOptions.mBlock == ScrollLogicalPosition::Start)
- ? nsIPresShell::SCROLL_TOP
- : nsIPresShell::SCROLL_BOTTOM;
+ int16_t vpercent = nsIPresShell::SCROLL_CENTER;
+ switch (aOptions.mBlock) {
+ case ScrollLogicalPosition::Start:
+ vpercent = nsIPresShell::SCROLL_TOP;
+ break;
+ case ScrollLogicalPosition::Center:
+ vpercent = nsIPresShell::SCROLL_CENTER;
+ break;
+ case ScrollLogicalPosition::End:
+ vpercent = nsIPresShell::SCROLL_BOTTOM;
+ break;
+ case ScrollLogicalPosition::Nearest:
+ vpercent = nsIPresShell::SCROLL_MINIMUM;
+ break;
+ default:
+ MOZ_ASSERT_UNREACHABLE("Unexpected ScrollLogicalPosition value");
+ }
+
+ int16_t hpercent = nsIPresShell::SCROLL_CENTER;
+ switch (aOptions.mInline) {
+ case ScrollLogicalPosition::Start:
+ hpercent = nsIPresShell::SCROLL_LEFT;
+ break;
+ case ScrollLogicalPosition::Center:
+ hpercent = nsIPresShell::SCROLL_CENTER;
+ break;
+ case ScrollLogicalPosition::End:
+ hpercent = nsIPresShell::SCROLL_RIGHT;
+ break;
+ case ScrollLogicalPosition::Nearest:
+ hpercent = nsIPresShell::SCROLL_MINIMUM;
+ break;
+ default:
+ MOZ_ASSERT_UNREACHABLE("Unexpected ScrollLogicalPosition value");
+ }
uint32_t flags = nsIPresShell::SCROLL_OVERFLOW_HIDDEN;
if (aOptions.mBehavior == ScrollBehavior::Smooth) {
@@ -732,7 +767,9 @@ Element::ScrollIntoView(const ScrollIntoViewOptions &aOptions)
nsIPresShell::ScrollAxis(
vpercent,
nsIPresShell::SCROLL_ALWAYS),
- nsIPresShell::ScrollAxis(),
+ nsIPresShell::ScrollAxis(
+ hpercent,
+ nsIPresShell::SCROLL_ALWAYS),
flags);
}
@@ -3948,7 +3985,7 @@ Element::ClearDataset()
slots->mDataset = nullptr;
}
-nsDataHashtable<nsPtrHashKey<DOMIntersectionObserver>, int32_t>*
+nsDataHashtable<nsRefPtrHashKey<DOMIntersectionObserver>, int32_t>*
Element::RegisteredIntersectionObservers()
{
nsDOMSlots* slots = DOMSlots();
@@ -3963,7 +4000,7 @@ enum nsPreviousIntersectionThreshold {
void
Element::RegisterIntersectionObserver(DOMIntersectionObserver* aObserver)
{
- nsDataHashtable<nsPtrHashKey<DOMIntersectionObserver>, int32_t>* observers =
+ nsDataHashtable<nsRefPtrHashKey<DOMIntersectionObserver>, int32_t>* observers =
RegisteredIntersectionObservers();
if (observers->Contains(aObserver)) {
return;
@@ -3980,7 +4017,7 @@ Element::RegisterIntersectionObserver(DOMIntersectionObserver* aObserver)
void
Element::UnregisterIntersectionObserver(DOMIntersectionObserver* aObserver)
{
- nsDataHashtable<nsPtrHashKey<DOMIntersectionObserver>, int32_t>* observers =
+ nsDataHashtable<nsRefPtrHashKey<DOMIntersectionObserver>, int32_t>* observers =
RegisteredIntersectionObservers();
observers->Remove(aObserver);
}
@@ -3988,7 +4025,7 @@ Element::UnregisterIntersectionObserver(DOMIntersectionObserver* aObserver)
bool
Element::UpdateIntersectionObservation(DOMIntersectionObserver* aObserver, int32_t aThreshold)
{
- nsDataHashtable<nsPtrHashKey<DOMIntersectionObserver>, int32_t>* observers =
+ nsDataHashtable<nsRefPtrHashKey<DOMIntersectionObserver>, int32_t>* observers =
RegisteredIntersectionObservers();
if (!observers->Contains(aObserver)) {
return false;
diff --git a/dom/base/Element.h b/dom/base/Element.h
index c269ab14a..ce84b74fb 100644
--- a/dom/base/Element.h
+++ b/dom/base/Element.h
@@ -818,9 +818,10 @@ public:
return slots ? slots->mShadowRoot.get() : nullptr;
}
- void ScrollIntoView();
- void ScrollIntoView(bool aTop);
+private:
void ScrollIntoView(const ScrollIntoViewOptions &aOptions);
+public:
+ void ScrollIntoView(const BooleanOrScrollIntoViewOptions& aObject);
void Scroll(double aXScroll, double aYScroll);
void Scroll(const ScrollToOptions& aOptions);
void ScrollTo(double aXScroll, double aYScroll);
@@ -1382,7 +1383,8 @@ protected:
nsDOMTokenList* GetTokenList(nsIAtom* aAtom,
const DOMTokenListSupportedTokenArray aSupportedTokens = nullptr);
- nsDataHashtable<nsPtrHashKey<DOMIntersectionObserver>, int32_t>* RegisteredIntersectionObservers();
+ nsDataHashtable<nsRefPtrHashKey<DOMIntersectionObserver>, int32_t>*
+ RegisteredIntersectionObservers();
private:
/**
diff --git a/dom/base/File.cpp b/dom/base/File.cpp
index 7d86dfe8a..1d5ab73e7 100755
--- a/dom/base/File.cpp
+++ b/dom/base/File.cpp
@@ -138,7 +138,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Blob)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(Blob)
diff --git a/dom/base/FormData.cpp b/dom/base/FormData.cpp
index 6095286be..52bdd9210 100644
--- a/dom/base/FormData.cpp
+++ b/dom/base/FormData.cpp
@@ -84,7 +84,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(FormData)
"mFormData[i].GetAsBlob()", 0);
}
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(FormData)
diff --git a/dom/base/FragmentOrElement.cpp b/dom/base/FragmentOrElement.cpp
index fde983e7c..9106778df 100644
--- a/dom/base/FragmentOrElement.cpp
+++ b/dom/base/FragmentOrElement.cpp
@@ -585,6 +585,12 @@ FragmentOrElement::nsDOMSlots::Traverse(nsCycleCollectionTraversalCallback &cb,
mCustomElementData->mCallbackQueue[i]->Traverse(cb);
}
}
+
+ for (auto iter = mRegisteredIntersectionObservers.Iter(); !iter.Done(); iter.Next()) {
+ DOMIntersectionObserver* observer = iter.Key();
+ NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mRegisteredIntersectionObservers[i]");
+ cb.NoteXPCOMChild(observer);
+ }
}
void
@@ -1872,10 +1878,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(FragmentOrElement)
NS_IMPL_CYCLE_COLLECTION_DESCRIBE(FragmentOrElement, tmp->mRefCnt.get())
}
- // Always need to traverse script objects, so do that before we check
- // if we're uncollectable.
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
-
if (!nsINode::Traverse(tmp, cb)) {
return NS_SUCCESS_INTERRUPTED_TRAVERSE;
}
diff --git a/dom/base/FragmentOrElement.h b/dom/base/FragmentOrElement.h
index 7c74e9cd4..f0cc29f22 100644
--- a/dom/base/FragmentOrElement.h
+++ b/dom/base/FragmentOrElement.h
@@ -354,7 +354,8 @@ public:
/**
* Registered Intersection Observers on the element.
*/
- nsDataHashtable<nsPtrHashKey<DOMIntersectionObserver>, int32_t> mRegisteredIntersectionObservers;
+ nsDataHashtable<nsRefPtrHashKey<DOMIntersectionObserver>, int32_t>
+ mRegisteredIntersectionObservers;
};
protected:
diff --git a/dom/base/Location.cpp b/dom/base/Location.cpp
index 7b3722f09..1483c32f9 100644
--- a/dom/base/Location.cpp
+++ b/dom/base/Location.cpp
@@ -33,6 +33,7 @@
#include "nsCycleCollectionParticipant.h"
#include "nsNullPrincipal.h"
#include "ScriptSettings.h"
+#include "mozilla/Unused.h"
#include "mozilla/dom/LocationBinding.h"
namespace mozilla {
@@ -79,7 +80,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Location)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mInnerWindow)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(Location)
@@ -716,9 +716,15 @@ Location::SetProtocol(const nsAString& aProtocol)
return rv;
}
- rv = uri->SetScheme(NS_ConvertUTF16toUTF8(aProtocol));
+ nsAString::const_iterator start, end;
+ aProtocol.BeginReading(start);
+ aProtocol.EndReading(end);
+ nsAString::const_iterator iter(start);
+ Unused << FindCharInReadable(':', iter, end);
+
+ rv = uri->SetScheme(NS_ConvertUTF16toUTF8(Substring(start, iter)));
if (NS_WARN_IF(NS_FAILED(rv))) {
- return rv;
+ return NS_ERROR_DOM_SYNTAX_ERR;
}
nsAutoCString newSpec;
rv = uri->GetSpec(newSpec);
@@ -728,9 +734,29 @@ Location::SetProtocol(const nsAString& aProtocol)
// We may want a new URI class for the new URI, so recreate it:
rv = NS_NewURI(getter_AddRefs(uri), newSpec);
if (NS_FAILED(rv)) {
+ if (rv == NS_ERROR_MALFORMED_URI) {
+ rv = NS_ERROR_DOM_SYNTAX_ERR;
+ }
+ return rv;
+ }
+
+ bool isHttp;
+ rv = uri->SchemeIs("http", &isHttp);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+
+ bool isHttps;
+ rv = uri->SchemeIs("https", &isHttps);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
+ if (!isHttp && !isHttps) {
+ // No-op, per spec.
+ return NS_OK;
+ }
+
return SetURI(uri);
}
@@ -763,10 +789,6 @@ Location::GetSearch(nsAString& aSearch)
NS_IMETHODIMP
Location::SetSearch(const nsAString& aSearch)
{
- if (aSearch.IsEmpty()) {
- return NS_OK; // Ignore empty string
- }
-
nsresult rv = SetSearchInternal(aSearch);
if (NS_FAILED(rv)) {
return rv;
diff --git a/dom/base/Navigator.cpp b/dom/base/Navigator.cpp
index ed96ee23b..fdf151b6c 100644
--- a/dom/base/Navigator.cpp
+++ b/dom/base/Navigator.cpp
@@ -44,7 +44,6 @@
#include "mozilla/dom/ServiceWorkerContainer.h"
#include "mozilla/dom/StorageManager.h"
#include "mozilla/dom/TCPSocket.h"
-#include "mozilla/dom/VRDisplay.h"
#include "mozilla/dom/workers/RuntimeService.h"
#include "mozilla/Hal.h"
#include "nsISiteSpecificUserAgent.h"
@@ -224,7 +223,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Navigator)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGamepadServiceTest)
#endif
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mVRGetDisplaysPromises)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(Navigator)
@@ -684,8 +682,6 @@ Navigator::GetDoNotTrack(nsAString &aResult)
bool
Navigator::JavaEnabled(ErrorResult& aRv)
{
- Telemetry::AutoTimer<Telemetry::CHECK_JAVA_ENABLED> telemetryTimer;
-
// Return true if we have a handler for the java mime
nsAdoptingString javaMIME = Preferences::GetString("plugin.java.mime");
NS_ENSURE_TRUE(!javaMIME.IsEmpty(), false);
@@ -1473,83 +1469,6 @@ Navigator::RequestGamepadServiceTest()
}
#endif
-already_AddRefed<Promise>
-Navigator::GetVRDisplays(ErrorResult& aRv)
-{
- if (!mWindow || !mWindow->GetDocShell()) {
- aRv.Throw(NS_ERROR_UNEXPECTED);
- return nullptr;
- }
-
- nsGlobalWindow* win = nsGlobalWindow::Cast(mWindow);
- win->NotifyVREventListenerAdded();
-
- nsCOMPtr<nsIGlobalObject> go = do_QueryInterface(mWindow);
- RefPtr<Promise> p = Promise::Create(go, aRv);
- if (aRv.Failed()) {
- return nullptr;
- }
-
- // We pass mWindow's id to RefreshVRDisplays, so NotifyVRDisplaysUpdated will
- // be called asynchronously, resolving the promises in mVRGetDisplaysPromises.
- if (!VRDisplay::RefreshVRDisplays(win->WindowID())) {
- p->MaybeReject(NS_ERROR_FAILURE);
- return p.forget();
- }
-
- mVRGetDisplaysPromises.AppendElement(p);
- return p.forget();
-}
-
-void
-Navigator::GetActiveVRDisplays(nsTArray<RefPtr<VRDisplay>>& aDisplays) const
-{
- /**
- * Get only the active VR displays.
- * Callers do not wish to VRDisplay::RefreshVRDisplays, as the enumeration may
- * activate hardware that is not yet intended to be used.
- */
- if (!mWindow || !mWindow->GetDocShell()) {
- return;
- }
- nsGlobalWindow* win = nsGlobalWindow::Cast(mWindow);
- win->NotifyVREventListenerAdded();
- nsTArray<RefPtr<VRDisplay>> displays;
- if (win->UpdateVRDisplays(displays)) {
- for (auto display : displays) {
- if (display->IsPresenting()) {
- aDisplays.AppendElement(display);
- }
- }
- }
-}
-
-void
-Navigator::NotifyVRDisplaysUpdated()
-{
- // Synchronize the VR devices and resolve the promises in
- // mVRGetDisplaysPromises
- nsGlobalWindow* win = nsGlobalWindow::Cast(mWindow);
-
- nsTArray<RefPtr<VRDisplay>> vrDisplays;
- if (win->UpdateVRDisplays(vrDisplays)) {
- for (auto p : mVRGetDisplaysPromises) {
- p->MaybeResolve(vrDisplays);
- }
- } else {
- for (auto p : mVRGetDisplaysPromises) {
- p->MaybeReject(NS_ERROR_FAILURE);
- }
- }
- mVRGetDisplaysPromises.Clear();
-}
-
-void
-Navigator::NotifyActiveVRDisplaysChanged()
-{
- NavigatorBinding::ClearCachedActiveVRDisplaysValue(this);
-}
-
//*****************************************************************************
// Navigator::nsIMozNavigatorNetwork
//*****************************************************************************
diff --git a/dom/base/Navigator.h b/dom/base/Navigator.h
index d47a80bc1..91b7fc15c 100644
--- a/dom/base/Navigator.h
+++ b/dom/base/Navigator.h
@@ -76,7 +76,6 @@ class Connection;
class PowerManager;
class Presentation;
class LegacyMozTCPSocket;
-class VRDisplay;
class StorageManager;
namespace time {
@@ -204,8 +203,6 @@ public:
void GetGamepads(nsTArray<RefPtr<Gamepad> >& aGamepads, ErrorResult& aRv);
GamepadServiceTest* RequestGamepadServiceTest();
#endif // MOZ_GAMEPAD
- already_AddRefed<Promise> GetVRDisplays(ErrorResult& aRv);
- void GetActiveVRDisplays(nsTArray<RefPtr<VRDisplay>>& aDisplays) const;
#ifdef MOZ_TIME_MANAGER
time::TimeManager* GetMozTime(ErrorResult& aRv);
#endif // MOZ_TIME_MANAGER
@@ -269,10 +266,6 @@ private:
RefPtr<MediaKeySystemAccessManager> mMediaKeySystemAccessManager;
#endif
-public:
- void NotifyVRDisplaysUpdated();
- void NotifyActiveVRDisplaysChanged();
-
private:
virtual ~Navigator();
diff --git a/dom/base/Pose.cpp b/dom/base/Pose.cpp
index 1eab4c173..5bc4ca6de 100644
--- a/dom/base/Pose.cpp
+++ b/dom/base/Pose.cpp
@@ -26,7 +26,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Pose)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(Pose)
diff --git a/dom/base/ProcessGlobal.cpp b/dom/base/ProcessGlobal.cpp
index 641f49f98..6cd29ab7c 100644
--- a/dom/base/ProcessGlobal.cpp
+++ b/dom/base/ProcessGlobal.cpp
@@ -52,7 +52,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(ProcessGlobal)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMessageManager)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGlobal)
tmp->TraverseHostObjectURIs(cb);
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(ProcessGlobal)
diff --git a/dom/base/nsAttrAndChildArray.cpp b/dom/base/nsAttrAndChildArray.cpp
index b285ee003..9fd27262b 100644
--- a/dom/base/nsAttrAndChildArray.cpp
+++ b/dom/base/nsAttrAndChildArray.cpp
@@ -78,15 +78,8 @@ GetIndexFromCache(const nsAttrAndChildArray* aArray)
}
-/**
- * Due to a compiler bug in VisualAge C++ for AIX, we need to return the
- * address of the first index into mBuffer here, instead of simply returning
- * mBuffer itself.
- *
- * See Bug 231104 for more information.
- */
#define ATTRS(_impl) \
- reinterpret_cast<InternalAttr*>(&((_impl)->mBuffer[0]))
+ reinterpret_cast<InternalAttr*>((_impl)->mBuffer)
#define NS_IMPL_EXTRA_SIZE \
diff --git a/dom/base/nsCCUncollectableMarker.cpp b/dom/base/nsCCUncollectableMarker.cpp
index 861cda521..db4d0d351 100644
--- a/dom/base/nsCCUncollectableMarker.cpp
+++ b/dom/base/nsCCUncollectableMarker.cpp
@@ -188,23 +188,20 @@ MarkMessageManagers()
}
void
-MarkContentViewer(nsIContentViewer* aViewer, bool aCleanupJS,
- bool aPrepareForCC)
+MarkDocument(nsIDocument* aDoc, bool aCleanupJS, bool aPrepareForCC)
{
- if (!aViewer) {
+ if (!aDoc) {
return;
}
- nsIDocument *doc = aViewer->GetDocument();
- if (doc &&
- doc->GetMarkedCCGeneration() != nsCCUncollectableMarker::sGeneration) {
- doc->MarkUncollectableForCCGeneration(nsCCUncollectableMarker::sGeneration);
+ if (aDoc->GetMarkedCCGeneration() != nsCCUncollectableMarker::sGeneration) {
+ aDoc->MarkUncollectableForCCGeneration(nsCCUncollectableMarker::sGeneration);
if (aCleanupJS) {
- EventListenerManager* elm = doc->GetExistingListenerManager();
+ EventListenerManager* elm = aDoc->GetExistingListenerManager();
if (elm) {
elm->MarkForCC();
}
- nsCOMPtr<EventTarget> win = do_QueryInterface(doc->GetInnerWindow());
+ nsCOMPtr<EventTarget> win = do_QueryInterface(aDoc->GetInnerWindow());
if (win) {
elm = win->GetExistingListenerManager();
if (elm) {
@@ -215,18 +212,27 @@ MarkContentViewer(nsIContentViewer* aViewer, bool aCleanupJS,
} else if (aPrepareForCC) {
// Unfortunately we need to still mark user data just before running CC so
// that it has the right generation.
- doc->PropertyTable(DOM_USER_DATA)->
+ aDoc->PropertyTable(DOM_USER_DATA)->
EnumerateAll(MarkUserData, &nsCCUncollectableMarker::sGeneration);
}
}
- if (doc) {
- if (nsPIDOMWindowInner* inner = doc->GetInnerWindow()) {
- inner->MarkUncollectableForCCGeneration(nsCCUncollectableMarker::sGeneration);
- }
- if (nsPIDOMWindowOuter* outer = doc->GetWindow()) {
- outer->MarkUncollectableForCCGeneration(nsCCUncollectableMarker::sGeneration);
- }
+ if (nsPIDOMWindowInner* inner = aDoc->GetInnerWindow()) {
+ inner->MarkUncollectableForCCGeneration(nsCCUncollectableMarker::sGeneration);
+ }
+ if (nsPIDOMWindowOuter* outer = aDoc->GetWindow()) {
+ outer->MarkUncollectableForCCGeneration(nsCCUncollectableMarker::sGeneration);
+ }
+}
+
+void
+MarkContentViewer(nsIContentViewer* aViewer, bool aCleanupJS,
+ bool aPrepareForCC)
+{
+ if (!aViewer) {
+ return;
}
+
+ MarkDocument(aViewer->GetDocument(), aCleanupJS, aPrepareForCC);
}
void MarkDocShell(nsIDocShellTreeItem* aNode, bool aCleanupJS,
diff --git a/dom/base/nsContentList.cpp b/dom/base/nsContentList.cpp
index 43e65777d..c98859ee3 100644
--- a/dom/base/nsContentList.cpp
+++ b/dom/base/nsContentList.cpp
@@ -54,7 +54,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsBaseContentList)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsBaseContentList)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mElements)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(nsBaseContentList)
diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp
index 34c7d23b8..3696195dd 100644
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -7597,6 +7597,24 @@ nsContentUtils::IsFileImage(nsIFile* aFile, nsACString& aType)
}
nsresult
+nsContentUtils::CalculateBufferSizeForImage(const uint32_t& aStride,
+ const IntSize& aImageSize,
+ const SurfaceFormat& aFormat,
+ size_t* aMaxBufferSize,
+ size_t* aUsedBufferSize)
+{
+ CheckedInt32 requiredBytes =
+ CheckedInt32(aStride) * CheckedInt32(aImageSize.height);
+ if (!requiredBytes.isValid()) {
+ return NS_ERROR_FAILURE;
+ }
+ *aMaxBufferSize = requiredBytes.value();
+ *aUsedBufferSize = *aMaxBufferSize - aStride +
+ (aImageSize.width * BytesPerPixel(aFormat));
+ return NS_OK;
+}
+
+nsresult
nsContentUtils::DataTransferItemToImage(const IPCDataTransferItem& aItem,
imgIContainer** aContainer)
{
@@ -7611,6 +7629,22 @@ nsContentUtils::DataTransferItemToImage(const IPCDataTransferItem& aItem,
Shmem data = aItem.data().get_Shmem();
+ // Validate shared memory buffer size
+ size_t imageBufLen = 0;
+ size_t maxBufLen = 0;
+ nsresult rv = CalculateBufferSizeForImage(imageDetails.stride(),
+ size,
+ static_cast<SurfaceFormat>(
+ imageDetails.format()),
+ &maxBufLen,
+ &imageBufLen);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ if (imageBufLen > data.Size<uint8_t>()) {
+ return NS_ERROR_FAILURE;
+ }
+
RefPtr<DataSourceSurface> image =
CreateDataSourceSurfaceFromData(size,
static_cast<SurfaceFormat>(imageDetails.format()),
@@ -7950,20 +7984,19 @@ GetSurfaceDataImpl(mozilla::gfx::DataSourceSurface* aSurface,
return GetSurfaceDataContext::NullValue();
}
- mozilla::gfx::IntSize size = aSurface->GetSize();
- mozilla::CheckedInt32 requiredBytes =
- mozilla::CheckedInt32(map.mStride) * mozilla::CheckedInt32(size.height);
- if (!requiredBytes.isValid()) {
+ size_t bufLen = 0;
+ size_t maxBufLen = 0;
+ nsresult rv = nsContentUtils::CalculateBufferSizeForImage(map.mStride,
+ aSurface->GetSize(),
+ aSurface->GetFormat(),
+ &maxBufLen,
+ &bufLen);
+ if (NS_FAILED(rv)) {
+ // Release mapped memory
+ aSurface->Unmap();
return GetSurfaceDataContext::NullValue();
}
- size_t maxBufLen = requiredBytes.value();
- mozilla::gfx::SurfaceFormat format = aSurface->GetFormat();
-
- // Surface data handling is totally nuts. This is the magic one needs to
- // know to access the data.
- size_t bufLen = maxBufLen - map.mStride + (size.width * BytesPerPixel(format));
-
// nsDependentCString wants null-terminated string.
typename GetSurfaceDataContext::ReturnType surfaceData = aContext.Allocate(maxBufLen + 1);
if (GetSurfaceDataContext::GetBuffer(surfaceData)) {
@@ -9787,3 +9820,19 @@ nsContentUtils::AttemptLargeAllocationLoad(nsIHttpChannel* aChannel)
return reloadSucceeded;
}
+
+/* static */ bool
+nsContentUtils::IsLocalRefURL(const nsString& aString)
+{
+ // Find the first non-"C0 controls + space" character.
+ const char16_t* current = aString.get();
+ for (; *current != '\0'; current++) {
+ if (*current > 0x20) {
+ // if the first non-"C0 controls + space" character is '#', this is a
+ // local-ref URL.
+ return *current == '#';
+ }
+ }
+
+ return false;
+} \ No newline at end of file
diff --git a/dom/base/nsContentUtils.h b/dom/base/nsContentUtils.h
index 9ae6d2155..299a8e859 100644
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -13,10 +13,6 @@
#include <float.h>
#endif
-#if defined(SOLARIS)
-#include <ieeefp.h>
-#endif
-
#include "js/TypeDecls.h"
#include "js/Value.h"
#include "js/RootingAPI.h"
@@ -975,11 +971,17 @@ public:
static bool PrefetchEnabled(nsIDocShell* aDocShell);
+ static nsresult CalculateBufferSizeForImage(const uint32_t& aStride,
+ const mozilla::gfx::IntSize& aImageSize,
+ const mozilla::gfx::SurfaceFormat& aFormat,
+ size_t* aMaxBufferSize,
+ size_t* aUsedBufferSize);
+
+private:
/**
* Fill (with the parameters given) the localized string named |aKey| in
* properties file |aFile|.
*/
-private:
static nsresult FormatLocalizedString(PropertiesFile aFile,
const char* aKey,
const char16_t** aParams,
@@ -2730,6 +2732,13 @@ public:
static bool AttemptLargeAllocationLoad(nsIHttpChannel* aChannel);
+ /**
+ * Detect whether a string is a (CSS) local-url.
+ * https://drafts.csswg.org/css-values/#local-urls
+ */
+ static bool
+ IsLocalRefURL(const nsString& aString);
+
private:
static bool InitializeEventTable();
diff --git a/dom/base/nsDOMAttributeMap.cpp b/dom/base/nsDOMAttributeMap.cpp
index 381f267cd..2a90df7e4 100644
--- a/dom/base/nsDOMAttributeMap.cpp
+++ b/dom/base/nsDOMAttributeMap.cpp
@@ -65,7 +65,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDOMAttributeMap)
for (auto iter = tmp->mAttributeCache.Iter(); !iter.Done(); iter.Next()) {
cb.NoteXPCOMChild(static_cast<nsINode*>(iter.Data().get()));
}
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mContent)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
diff --git a/dom/base/nsDOMClassInfo.cpp b/dom/base/nsDOMClassInfo.cpp
index d125e5ad1..1cfde6e1b 100644
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -49,7 +49,6 @@
#include "nsContentUtils.h"
#include "nsIDOMGlobalPropertyInitializer.h"
#include "mozilla/Attributes.h"
-#include "mozilla/Telemetry.h"
// Window scriptable helper includes
#include "nsScriptNameSpaceManager.h"
@@ -1903,9 +1902,6 @@ LookupComponentsShim(JSContext *cx, JS::Handle<JSObject*> global,
nsPIDOMWindowInner *win,
JS::MutableHandle<JS::PropertyDescriptor> desc)
{
- // Keep track of how often this happens.
- Telemetry::Accumulate(Telemetry::COMPONENTS_SHIM_ACCESSED_BY_CONTENT, true);
-
// Warn once.
nsCOMPtr<nsIDocument> doc = win->GetExtantDoc();
if (doc) {
diff --git a/dom/base/nsDOMMutationObserver.cpp b/dom/base/nsDOMMutationObserver.cpp
index 024ce5e2e..858a30ce5 100644
--- a/dom/base/nsDOMMutationObserver.cpp
+++ b/dom/base/nsDOMMutationObserver.cpp
@@ -506,7 +506,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDOMMutationObserver)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDOMMutationObserver)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOwner)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mReceivers)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFirstPendingMutation)
diff --git a/dom/base/nsDOMNavigationTiming.cpp b/dom/base/nsDOMNavigationTiming.cpp
index 32ce8a8cb..9c732f2d8 100644
--- a/dom/base/nsDOMNavigationTiming.cpp
+++ b/dom/base/nsDOMNavigationTiming.cpp
@@ -15,7 +15,6 @@
#include "nsPrintfCString.h"
#include "mozilla/dom/PerformanceNavigation.h"
#include "mozilla/TimeStamp.h"
-#include "mozilla/Telemetry.h"
using namespace mozilla;
@@ -203,12 +202,6 @@ nsDOMNavigationTiming::NotifyNonBlankPaintForRootContentDocument()
mDocShellHasBeenActiveSinceNavigationStart ? "foreground tab" : "this tab was inactive some of the time between navigation start and first non-blank paint");
PROFILER_MARKER(marker.get());
}
-
- if (mDocShellHasBeenActiveSinceNavigationStart) {
- Telemetry::AccumulateTimeDelta(Telemetry::TIME_TO_NON_BLANK_PAINT_MS,
- mNavigationStart,
- mNonBlankPaint);
- }
}
void
diff --git a/dom/base/nsDOMWindowUtils.cpp b/dom/base/nsDOMWindowUtils.cpp
index 291df5f27..2ab5937ac 100644
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -4033,8 +4033,6 @@ nsDOMWindowUtils::ForceUseCounterFlush(nsIDOMNode *aNode)
if (nsCOMPtr<nsIDocument> doc = do_QueryInterface(aNode)) {
mozilla::css::ImageLoader* loader = doc->StyleImageLoader();
loader->FlushUseCounters();
-
- static_cast<nsDocument*>(doc.get())->ReportUseCounters();
return NS_OK;
}
diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp
index 8acfd901a..a6ed419df 100644
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -25,7 +25,6 @@
#include "plstr.h"
#include "mozilla/Sprintf.h"
-#include "mozilla/Telemetry.h"
#include "nsIInterfaceRequestor.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsILoadContext.h"
@@ -1396,63 +1395,6 @@ nsDocument::~nsDocument()
NS_ASSERTION(!mIsShowing, "Destroying a currently-showing document");
- if (IsTopLevelContentDocument()) {
- //don't report for about: pages
- if (!IsAboutPage()) {
- // Record the page load
- uint32_t pageLoaded = 1;
- Accumulate(Telemetry::MIXED_CONTENT_UNBLOCK_COUNTER, pageLoaded);
- // Record the mixed content status of the docshell in Telemetry
- enum {
- NO_MIXED_CONTENT = 0, // There is no Mixed Content on the page
- MIXED_DISPLAY_CONTENT = 1, // The page attempted to load Mixed Display Content
- MIXED_ACTIVE_CONTENT = 2, // The page attempted to load Mixed Active Content
- MIXED_DISPLAY_AND_ACTIVE_CONTENT = 3 // The page attempted to load Mixed Display & Mixed Active Content
- };
-
- bool mixedActiveLoaded = GetHasMixedActiveContentLoaded();
- bool mixedActiveBlocked = GetHasMixedActiveContentBlocked();
-
- bool mixedDisplayLoaded = GetHasMixedDisplayContentLoaded();
- bool mixedDisplayBlocked = GetHasMixedDisplayContentBlocked();
-
- bool hasMixedDisplay = (mixedDisplayBlocked || mixedDisplayLoaded);
- bool hasMixedActive = (mixedActiveBlocked || mixedActiveLoaded);
-
- uint32_t mixedContentLevel = NO_MIXED_CONTENT;
- if (hasMixedDisplay && hasMixedActive) {
- mixedContentLevel = MIXED_DISPLAY_AND_ACTIVE_CONTENT;
- } else if (hasMixedActive){
- mixedContentLevel = MIXED_ACTIVE_CONTENT;
- } else if (hasMixedDisplay) {
- mixedContentLevel = MIXED_DISPLAY_CONTENT;
- }
- Accumulate(Telemetry::MIXED_CONTENT_PAGE_LOAD, mixedContentLevel);
-
- // record mixed object subrequest telemetry
- if (mHasMixedContentObjectSubrequest) {
- /* mixed object subrequest loaded on page*/
- Accumulate(Telemetry::MIXED_CONTENT_OBJECT_SUBREQUEST, 1);
- } else {
- /* no mixed object subrequests loaded on page*/
- Accumulate(Telemetry::MIXED_CONTENT_OBJECT_SUBREQUEST, 0);
- }
-
- // record CSP telemetry on this document
- if (mHasCSP) {
- Accumulate(Telemetry::CSP_DOCUMENTS_COUNT, 1);
- }
- if (mHasUnsafeInlineCSP) {
- Accumulate(Telemetry::CSP_UNSAFE_INLINE_DOCUMENTS_COUNT, 1);
- }
- if (mHasUnsafeEvalCSP) {
- Accumulate(Telemetry::CSP_UNSAFE_EVAL_DOCUMENTS_COUNT, 1);
- }
- }
- }
-
- ReportUseCounters();
-
mInDestructor = true;
mInUnlinkOrDeletion = true;
@@ -1648,10 +1590,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsDocument)
NS_IMPL_CYCLE_COLLECTION_DESCRIBE(nsDocument, tmp->mRefCnt.get())
}
- // Always need to traverse script objects, so do that before we check
- // if we're uncollectable.
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
-
if (!nsINode::Traverse(tmp, cb)) {
return NS_SUCCESS_INTERRUPTED_TRAVERSE;
}
@@ -1737,8 +1675,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsDocument)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOnDemandBuiltInUASheets)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPreloadingImages)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIntersectionObservers)
-
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSubImportLinks)
for (uint32_t i = 0; i < tmp->mFrameRequestCallbacks.Length(); ++i) {
@@ -12356,134 +12292,27 @@ nsIDocument::InlineScriptAllowedByCSP()
return allowsInlineScript;
}
-static bool
-MightBeAboutOrChromeScheme(nsIURI* aURI)
-{
- MOZ_ASSERT(aURI);
- bool isAbout = true;
- bool isChrome = true;
- aURI->SchemeIs("about", &isAbout);
- aURI->SchemeIs("chrome", &isChrome);
- return isAbout || isChrome;
-}
-
-void
-nsDocument::ReportUseCounters()
-{
- static const bool sDebugUseCounters = false;
- if (mReportedUseCounters) {
- return;
- }
-
- mReportedUseCounters = true;
-
- if (Telemetry::HistogramUseCounterCount > 0 &&
- (IsContentDocument() || IsResourceDoc())) {
- nsCOMPtr<nsIURI> uri;
- NodePrincipal()->GetURI(getter_AddRefs(uri));
- if (!uri || MightBeAboutOrChromeScheme(uri)) {
- return;
- }
-
- if (sDebugUseCounters) {
- nsCString spec = uri->GetSpecOrDefault();
-
- // URIs can be rather long for data documents, so truncate them to
- // some reasonable length.
- spec.Truncate(std::min(128U, spec.Length()));
- printf("-- Use counters for %s --\n", spec.get());
- }
-
- // We keep separate counts for individual documents and top-level
- // pages to more accurately track how many web pages might break if
- // certain features were removed. Consider the case of a single
- // HTML document with several SVG images and/or iframes with
- // sub-documents of their own. If we maintained a single set of use
- // counters and all the sub-documents use a particular feature, then
- // telemetry would indicate that we would be breaking N documents if
- // that feature were removed. Whereas with a document/top-level
- // page split, we can see that N documents would be affected, but
- // only a single web page would be affected.
-
- // The difference between the values of these two histograms and the
- // related use counters below tell us how many pages did *not* use
- // the feature in question. For instance, if we see that a given
- // session has destroyed 30 content documents, but a particular use
- // counter shows only a count of 5, we can infer that the use
- // counter was *not* used in 25 of those 30 documents.
- //
- // We do things this way, rather than accumulating a boolean flag
- // for each use counter, to avoid sending histograms for features
- // that don't get widely used. Doing things in this fashion means
- // smaller telemetry payloads and faster processing on the server
- // side.
- Telemetry::Accumulate(Telemetry::CONTENT_DOCUMENTS_DESTROYED, 1);
- if (IsTopLevelContentDocument()) {
- Telemetry::Accumulate(Telemetry::TOP_LEVEL_CONTENT_DOCUMENTS_DESTROYED, 1);
- }
-
- for (int32_t c = 0;
- c < eUseCounter_Count; ++c) {
- UseCounter uc = static_cast<UseCounter>(c);
-
- Telemetry::ID id =
- static_cast<Telemetry::ID>(Telemetry::HistogramFirstUseCounter + uc * 2);
- bool value = GetUseCounter(uc);
-
- if (value) {
- if (sDebugUseCounters) {
- const char* name = Telemetry::GetHistogramName(id);
- if (name) {
- printf(" %s", name);
- } else {
- printf(" #%d", id);
- }
- printf(": %d\n", value);
- }
-
- Telemetry::Accumulate(id, 1);
- }
-
- if (IsTopLevelContentDocument()) {
- id = static_cast<Telemetry::ID>(Telemetry::HistogramFirstUseCounter +
- uc * 2 + 1);
- value = GetUseCounter(uc) || GetChildDocumentUseCounter(uc);
-
- if (value) {
- if (sDebugUseCounters) {
- const char* name = Telemetry::GetHistogramName(id);
- if (name) {
- printf(" %s", name);
- } else {
- printf(" #%d", id);
- }
- printf(": %d\n", value);
- }
-
- Telemetry::Accumulate(id, 1);
- }
- }
- }
- }
-}
-
void
nsDocument::AddIntersectionObserver(DOMIntersectionObserver* aObserver)
{
- NS_ASSERTION(mIntersectionObservers.IndexOf(aObserver) == nsTArray<int>::NoIndex,
- "Intersection observer already in the list");
- mIntersectionObservers.AppendElement(aObserver);
+ MOZ_ASSERT(!mIntersectionObservers.Contains(aObserver),
+ "Intersection observer already in the list");
+ mIntersectionObservers.PutEntry(aObserver);
}
void
nsDocument::RemoveIntersectionObserver(DOMIntersectionObserver* aObserver)
{
- mIntersectionObservers.RemoveElement(aObserver);
+ mIntersectionObservers.RemoveEntry(aObserver);
}
void
nsDocument::UpdateIntersectionObservations()
{
+ if (mIntersectionObservers.IsEmpty()) {
+ return;
+ }
+
DOMHighResTimeStamp time = 0;
if (nsPIDOMWindowInner* window = GetInnerWindow()) {
Performance* perf = window->GetPerformance();
@@ -12491,25 +12320,42 @@ nsDocument::UpdateIntersectionObservations()
time = perf->Now();
}
}
- for (const auto& observer : mIntersectionObservers) {
- observer->Update(this, time);
+ nsTArray<RefPtr<DOMIntersectionObserver>> observers(mIntersectionObservers.Count());
+ for (auto iter = mIntersectionObservers.Iter(); !iter.Done(); iter.Next()) {
+ DOMIntersectionObserver* observer = iter.Get()->GetKey();
+ observers.AppendElement(observer);
+ }
+ for (const auto& observer : observers) {
+ if (observer) {
+ observer->Update(this, time);
+ }
}
}
void
nsDocument::ScheduleIntersectionObserverNotification()
{
+ if (mIntersectionObservers.IsEmpty()) {
+ return;
+ }
+
nsCOMPtr<nsIRunnable> notification = NewRunnableMethod(this,
&nsDocument::NotifyIntersectionObservers);
- NS_DispatchToCurrentThread(notification);
+ NS_DispatchToCurrentThread(notification.forget());
}
void
nsDocument::NotifyIntersectionObservers()
{
- nsTArray<RefPtr<DOMIntersectionObserver>> observers(mIntersectionObservers);
+ nsTArray<RefPtr<DOMIntersectionObserver>> observers(mIntersectionObservers.Count());
+ for (auto iter = mIntersectionObservers.Iter(); !iter.Done(); iter.Next()) {
+ DOMIntersectionObserver* observer = iter.Get()->GetKey();
+ observers.AppendElement(observer);
+ }
for (const auto& observer : observers) {
- observer->Notify();
+ if (observer) {
+ observer->Notify();
+ }
}
}
diff --git a/dom/base/nsDocument.h b/dom/base/nsDocument.h
index 3725b3c18..95fd57545 100644
--- a/dom/base/nsDocument.h
+++ b/dom/base/nsDocument.h
@@ -774,8 +774,6 @@ public:
virtual nsViewportInfo GetViewportInfo(const mozilla::ScreenIntSize& aDisplaySize) override;
- void ReportUseCounters();
-
virtual void AddIntersectionObserver(
mozilla::dom::DOMIntersectionObserver* aObserver) override;
virtual void RemoveIntersectionObserver(
@@ -1341,8 +1339,9 @@ protected:
// Array of observers
nsTObserverArray<nsIDocumentObserver*> mObservers;
- // Array of intersection observers
- nsTArray<RefPtr<mozilla::dom::DOMIntersectionObserver>> mIntersectionObservers;
+ // Hashtable of intersection observers
+ nsTHashtable<nsPtrHashKey<mozilla::dom::DOMIntersectionObserver>>
+ mIntersectionObservers;
// Tracker for animations that are waiting to start.
// nullptr until GetOrCreatePendingAnimationTracker is called.
@@ -1448,14 +1447,6 @@ public:
// 'style-sheet-applicable-state-changed' notification.
bool mSSApplicableStateNotificationPending:1;
- // Whether we have reported use counters for this document with Telemetry yet.
- // Normally this is only done at document destruction time, but for image
- // documents (SVG documents) that are not guaranteed to be destroyed, we
- // report use counters when the image cache no longer has any imgRequestProxys
- // pointing to them. We track whether we ever reported use counters so
- // that we only report them once for the document.
- bool mReportedUseCounters:1;
-
// Whether we have filled our pres shell's style set with the document's
// additional sheets and sheets from the nsStyleSheetService.
bool mStyleSetFilled:1;
diff --git a/dom/base/nsFrameLoader.cpp b/dom/base/nsFrameLoader.cpp
index 23067becd..2804f2d4c 100644
--- a/dom/base/nsFrameLoader.cpp
+++ b/dom/base/nsFrameLoader.cpp
@@ -588,6 +588,9 @@ nsFrameLoader::ReallyStartLoadingInternal()
flags = nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP |
nsIWebNavigation::LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL;
}
+
+ // Notify that this load resulted from attribute changes.
+ loadInfo->SetIsFromProcessingFrameAttributes(true);
// Kick off the load...
bool tmpState = mNeedsAsyncDestroy;
diff --git a/dom/base/nsFrameMessageManager.cpp b/dom/base/nsFrameMessageManager.cpp
index 6fffd376b..bba4232aa 100644
--- a/dom/base/nsFrameMessageManager.cpp
+++ b/dom/base/nsFrameMessageManager.cpp
@@ -32,7 +32,6 @@
#include "mozilla/CycleCollectedJSContext.h"
#include "mozilla/IntentionalCrash.h"
#include "mozilla/Preferences.h"
-#include "mozilla/Telemetry.h"
#include "mozilla/dom/File.h"
#include "mozilla/dom/MessagePort.h"
#include "mozilla/dom/nsIContentParent.h"
@@ -133,7 +132,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsFrameMessageManager)
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChildManagers)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParentManager)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsFrameMessageManager)
@@ -707,18 +705,9 @@ nsFrameMessageManager::SendRpcMessage(const nsAString& aMessageName,
static bool
AllowMessage(size_t aDataLength, const nsAString& aMessageName)
{
- static const size_t kMinTelemetryMessageSize = 8192;
-
- if (aDataLength < kMinTelemetryMessageSize) {
- return true;
- }
-
NS_ConvertUTF16toUTF8 messageName(aMessageName);
messageName.StripChars("0123456789");
- Telemetry::Accumulate(Telemetry::MESSAGE_MANAGER_MESSAGE_SIZE2, messageName,
- aDataLength);
-
// A message includes more than structured clone data, so subtract
// 20KB to make it more likely that a message within this bound won't
// result in an overly large IPC message.
@@ -727,9 +716,6 @@ AllowMessage(size_t aDataLength, const nsAString& aMessageName)
return true;
}
- Telemetry::Accumulate(Telemetry::REJECTED_MESSAGE_MANAGER_MESSAGE,
- messageName);
-
return false;
}
@@ -2248,7 +2234,6 @@ nsSameProcessAsyncMessageBase::Init(const nsAString& aMessage,
nsIPrincipal* aPrincipal)
{
if (!mData.Copy(aData)) {
- Telemetry::Accumulate(Telemetry::IPC_SAME_PROCESS_MESSAGE_COPY_OOM_KB, aData.DataLength());
return NS_ERROR_OUT_OF_MEMORY;
}
diff --git a/dom/base/nsGenericDOMDataNode.cpp b/dom/base/nsGenericDOMDataNode.cpp
index 9688588e0..0ae15e09e 100644
--- a/dom/base/nsGenericDOMDataNode.cpp
+++ b/dom/base/nsGenericDOMDataNode.cpp
@@ -98,10 +98,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsGenericDOMDataNode)
NS_IMPL_CYCLE_COLLECTION_DESCRIBE(nsGenericDOMDataNode, tmp->mRefCnt.get())
}
- // Always need to traverse script objects, so do that before we check
- // if we're uncollectable.
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
-
if (!nsINode::Traverse(tmp, cb)) {
return NS_SUCCESS_INTERRUPTED_TRAVERSE;
}
diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp
index 884ad69ca..ac85e34c0 100644
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -202,16 +202,12 @@
#include "mozilla/dom/GamepadManager.h"
#endif
-#include "mozilla/dom/VRDisplay.h"
-#include "mozilla/dom/VREventObserver.h"
-
#include "nsRefreshDriver.h"
#include "Layers.h"
#include "mozilla/AddonPathService.h"
#include "mozilla/BasePrincipal.h"
#include "mozilla/Services.h"
-#include "mozilla/Telemetry.h"
#include "mozilla/dom/Location.h"
#include "nsHTMLDocument.h"
#include "nsWrapperCacheInlines.h"
@@ -292,7 +288,6 @@ static bool gMouseDown = false;
static bool gDragServiceDisabled = false;
static FILE *gDumpFile = nullptr;
static uint32_t gSerialCounter = 0;
-static TimeStamp gLastRecordedRecentTimeouts;
#define STATISTICS_INTERVAL (30 * PR_MSEC_PER_SEC)
#ifdef DEBUG_jst
@@ -1522,7 +1517,6 @@ nsGlobalWindow::nsGlobalWindow(nsGlobalWindow *aOuterWindow)
mIsPopupSpam(false),
mBlockScriptedClosingFlag(false),
mWasOffline(false),
- mHasHadSlowScript(false),
mNotifyIdleObserversIdleOnThaw(false),
mNotifyIdleObserversActiveOnThaw(false),
mCreatingInnerWindow(false),
@@ -1533,7 +1527,6 @@ nsGlobalWindow::nsGlobalWindow(nsGlobalWindow *aOuterWindow)
mShowFocusRingForContent(false),
mFocusByKeyOccurred(false),
mHasGamepad(false),
- mHasVREvents(false),
#ifdef MOZ_GAMEPAD
mHasSeenGamepadInput(false),
#endif
@@ -1759,9 +1752,6 @@ nsGlobalWindow::~nsGlobalWindow()
DropOuterWindowDocs();
} else {
- Telemetry::Accumulate(Telemetry::INNERWINDOWS_WITH_MUTATION_LISTENERS,
- mMutationBits ? 1 : 0);
-
if (mListenerManager) {
mListenerManager->Disconnect();
mListenerManager = nullptr;
@@ -1971,12 +1961,9 @@ nsGlobalWindow::CleanUp()
if (IsInnerWindow()) {
DisableGamepadUpdates();
mHasGamepad = false;
- DisableVRUpdates();
- mHasVREvents = false;
DisableIdleCallbackRequests();
} else {
MOZ_ASSERT(!mHasGamepad);
- MOZ_ASSERT(!mHasVREvents);
}
if (mCleanMessageManager) {
@@ -2027,7 +2014,7 @@ nsGlobalWindow::ClearControllers()
}
void
-nsGlobalWindow::FreeInnerObjects()
+nsGlobalWindow::FreeInnerObjects(bool aForDocumentOpen)
{
NS_ASSERTION(IsInnerWindow(), "Don't free inner objects on an outer window");
@@ -2086,8 +2073,10 @@ nsGlobalWindow::FreeInnerObjects()
mDocumentURI = mDoc->GetDocumentURI();
mDocBaseURI = mDoc->GetDocBaseURI();
- while (mDoc->EventHandlingSuppressed()) {
- mDoc->UnsuppressEventHandlingAndFireEvents(nsIDocument::eEvents, false);
+ if (!aForDocumentOpen) {
+ while (mDoc->EventHandlingSuppressed()) {
+ mDoc->UnsuppressEventHandlingAndFireEvents(nsIDocument::eEvents, false);
+ }
}
// Note: we don't have to worry about eAnimationsOnly suppressions because
@@ -2120,9 +2109,6 @@ nsGlobalWindow::FreeInnerObjects()
mHasGamepad = false;
mGamepads.Clear();
#endif
- DisableVRUpdates();
- mHasVREvents = false;
- mVRDisplays.Clear();
}
//*****************************************************************************
@@ -2277,7 +2263,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsGlobalWindow)
#endif
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCacheStorage)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mVRDisplays)
// Traverse stuff from nsPIDOMWindow
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChromeEventHandler)
@@ -2299,7 +2284,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsGlobalWindow)
tmp->TraverseHostObjectURIs(cb);
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGlobalWindow)
@@ -2354,7 +2338,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGlobalWindow)
#endif
NS_IMPL_CYCLE_COLLECTION_UNLINK(mCacheStorage)
- NS_IMPL_CYCLE_COLLECTION_UNLINK(mVRDisplays)
// Unlink stuff from nsPIDOMWindow
NS_IMPL_CYCLE_COLLECTION_UNLINK(mChromeEventHandler)
@@ -2695,7 +2678,6 @@ TreatAsRemoteXUL(nsIPrincipal* aPrincipal)
static bool
EnablePrivilege(JSContext* cx, unsigned argc, JS::Value* vp)
{
- Telemetry::Accumulate(Telemetry::ENABLE_PRIVILEGE_EVER_CALLED, true);
return xpc::EnableUniversalXPConnect(cx);
}
@@ -3005,6 +2987,8 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
nsCOMPtr<WindowStateHolder> wsh = do_QueryInterface(aState);
NS_ASSERTION(!aState || wsh, "What kind of weird state are you giving me here?");
+ bool handleDocumentOpen = false;
+
JS::Rooted<JSObject*> newInnerGlobal(cx);
if (reUseInnerWindow) {
// We're reusing the current inner window.
@@ -3096,6 +3080,7 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
if (currentInner && currentInner->GetWrapperPreserveColor()) {
if (oldDoc == aDocument) {
+ handleDocumentOpen = true;
// Move the navigator from the old inner window to the new one since
// this is a document.write. This is safe from a same-origin point of
// view because document.write can only be used by the same origin.
@@ -3120,7 +3105,7 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
// Don't free objects on our current inner window if it's going to be
// held in the bfcache.
if (!currentInner->IsFrozen()) {
- currentInner->FreeInnerObjects();
+ currentInner->FreeInnerObjects(handleDocumentOpen);
}
}
@@ -3389,9 +3374,6 @@ nsGlobalWindow::InnerSetNewDocument(JSContext* aCx, nsIDocument* aDocument)
mLastOpenedURI = aDocument->GetDocumentURI();
#endif
- Telemetry::Accumulate(Telemetry::INNERWINDOWS_WITH_MUTATION_LISTENERS,
- mMutationBits ? 1 : 0);
-
// Clear our mutation bitfield.
mMutationBits = 0;
}
@@ -6848,8 +6830,6 @@ FullscreenTransitionTask::Run()
Preferences::GetUint("full-screen-api.transition.timeout", 1000);
mTimer->Init(observer, timeout, nsITimer::TYPE_ONE_SHOT);
} else if (stage == eAfterToggle) {
- Telemetry::AccumulateTimeDelta(Telemetry::FULLSCREEN_TRANSITION_BLACK_MS,
- mFullscreenChangeStartTime);
mWidget->PerformFullscreenTransition(nsIWidget::eAfterFullscreenToggle,
mDuration.mFadeOut, mTransitionData,
this);
@@ -10513,24 +10493,6 @@ nsGlobalWindow::DisableGamepadUpdates()
}
void
-nsGlobalWindow::EnableVRUpdates()
-{
- MOZ_ASSERT(IsInnerWindow());
-
- if (mHasVREvents && !mVREventObserver) {
- mVREventObserver = new VREventObserver(this);
- }
-}
-
-void
-nsGlobalWindow::DisableVRUpdates()
-{
- MOZ_ASSERT(IsInnerWindow());
-
- mVREventObserver = nullptr;
-}
-
-void
nsGlobalWindow::SetChromeEventHandler(EventTarget* aChromeEventHandler)
{
MOZ_ASSERT(IsOuterWindow());
@@ -11577,13 +11539,6 @@ nsGlobalWindow::ShowSlowScriptDialog()
unsigned lineno;
bool hasFrame = JS::DescribeScriptedCaller(cx, &filename, &lineno);
- // Record the slow script event if we haven't done so already for this inner window
- // (which represents a particular page to the user).
- if (!mHasHadSlowScript) {
- Telemetry::Accumulate(Telemetry::SLOW_SCRIPT_PAGE_COUNT, 1);
- }
- mHasHadSlowScript = true;
-
if (XRE_IsContentProcess() &&
ProcessHangMonitor::Get()) {
ProcessHangMonitor::SlowScriptAction action;
@@ -11613,10 +11568,6 @@ nsGlobalWindow::ShowSlowScriptDialog()
return ContinueSlowScriptAndKeepNotifying;
}
- // Reached only on non-e10s - once per slow script dialog.
- // On e10s - we probe once at ProcessHangsMonitor.jsm
- Telemetry::Accumulate(Telemetry::SLOW_SCRIPT_NOTICE_COUNT, 1);
-
// Get the nsIPrompt interface from the docshell
nsCOMPtr<nsIDocShell> ds = GetDocShell();
NS_ENSURE_TRUE(ds, KillSlowScript);
@@ -12224,7 +12175,6 @@ nsGlobalWindow::Suspend()
ac->RemoveWindowListener(mEnabledSensors[i], this);
}
DisableGamepadUpdates();
- DisableVRUpdates();
mozilla::dom::workers::SuspendWorkersForWindow(AsInner());
@@ -12288,7 +12238,6 @@ nsGlobalWindow::Resume()
ac->AddWindowListener(mEnabledSensors[i], this);
}
EnableGamepadUpdates();
- EnableVRUpdates();
// Resume all of the AudioContexts for this window
for (uint32_t i = 0; i < mAudioContexts.Length(); ++i) {
@@ -13445,13 +13394,6 @@ nsGlobalWindow::RunTimeout(Timeout* aTimeout)
return;
}
- // Record telemetry information about timers set recently.
- TimeDuration recordingInterval = TimeDuration::FromMilliseconds(STATISTICS_INTERVAL);
- if (gLastRecordedRecentTimeouts.IsNull() ||
- now - gLastRecordedRecentTimeouts > recordingInterval) {
- gLastRecordedRecentTimeouts = now;
- }
-
// Insert a dummy timeout into the list of timeouts between the
// portion of the list that we are about to process now and those
// timeouts that will be processed in a future call to
@@ -14044,19 +13986,6 @@ nsGlobalWindow::SetHasGamepadEventListener(bool aHasGamepad/* = true*/)
void
nsGlobalWindow::EventListenerAdded(nsIAtom* aType)
{
- if (aType == nsGkAtoms::onvrdisplayconnect ||
- aType == nsGkAtoms::onvrdisplaydisconnect ||
- aType == nsGkAtoms::onvrdisplaypresentchange) {
- NotifyVREventListenerAdded();
- }
-}
-
-void
-nsGlobalWindow::NotifyVREventListenerAdded()
-{
- MOZ_ASSERT(IsInnerWindow());
- mHasVREvents = true;
- EnableVRUpdates();
}
void
@@ -14201,27 +14130,6 @@ nsGlobalWindow::SyncGamepadState()
}
#endif // MOZ_GAMEPAD
-bool
-nsGlobalWindow::UpdateVRDisplays(nsTArray<RefPtr<mozilla::dom::VRDisplay>>& aDevices)
-{
- FORWARD_TO_INNER(UpdateVRDisplays, (aDevices), false);
-
- VRDisplay::UpdateVRDisplays(mVRDisplays, AsInner());
- aDevices = mVRDisplays;
- return true;
-}
-
-void
-nsGlobalWindow::NotifyActiveVRDisplaysChanged()
-{
- MOZ_ASSERT(IsInnerWindow());
-
- if (mNavigator) {
- mNavigator->NotifyActiveVRDisplaysChanged();
- }
-}
-
-
// nsGlobalChromeWindow implementation
NS_IMPL_CYCLE_COLLECTION_CLASS(nsGlobalChromeWindow)
diff --git a/dom/base/nsGlobalWindow.h b/dom/base/nsGlobalWindow.h
index 467bc6796..1f420895c 100644
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -135,8 +135,6 @@ class SpeechSynthesis;
class TabGroup;
class Timeout;
class U2F;
-class VRDisplay;
-class VREventObserver;
class WakeLock;
#if defined(MOZ_WIDGET_ANDROID)
class WindowOrientationObserver;
@@ -745,18 +743,6 @@ public:
void EnableGamepadUpdates();
void DisableGamepadUpdates();
- // Inner windows only.
- // Enable/disable updates for VR
- void EnableVRUpdates();
- void DisableVRUpdates();
-
- // Update the VR displays for this window
- bool UpdateVRDisplays(nsTArray<RefPtr<mozilla::dom::VRDisplay>>& aDisplays);
-
- // Inner windows only.
- // Called to inform that the set of active VR displays has changed.
- void NotifyActiveVRDisplaysChanged();
-
#define EVENT(name_, id_, type_, struct_) \
mozilla::dom::EventHandlerNonNull* GetOn##name_() \
{ \
@@ -1380,7 +1366,7 @@ protected:
}
}
- void FreeInnerObjects();
+ void FreeInnerObjects(bool aForDocumentOpen = false);
nsGlobalWindow *CallerInnerWindow();
// Only to be called on an inner window.
@@ -1794,11 +1780,6 @@ protected:
// Window offline status. Checked to see if we need to fire offline event
bool mWasOffline : 1;
- // Represents whether the inner window's page has had a slow script notice.
- // Only used by inner windows; will always be false for outer windows.
- // This is used to implement Telemetry measures such as SLOW_SCRIPT_PAGE_COUNT.
- bool mHasHadSlowScript : 1;
-
// Track what sorts of events we need to fire when thawed
bool mNotifyIdleObserversIdleOnThaw : 1;
bool mNotifyIdleObserversActiveOnThaw : 1;
@@ -1832,9 +1813,6 @@ protected:
// Indicates whether this window wants gamepad input events
bool mHasGamepad : 1;
- // Inner windows only.
- // Indicates whether this window wants VR events
- bool mHasVREvents : 1;
#ifdef MOZ_GAMEPAD
nsCheapSet<nsUint32HashKey> mGamepadIndexSet;
nsRefPtrHashtable<nsUint32HashKey, mozilla::dom::Gamepad> mGamepads;
@@ -1989,11 +1967,6 @@ protected:
// This is the CC generation the last time we called CanSkip.
uint32_t mCanSkipCCGeneration;
- // The VR Displays for this window
- nsTArray<RefPtr<mozilla::dom::VRDisplay>> mVRDisplays;
-
- nsAutoPtr<mozilla::dom::VREventObserver> mVREventObserver;
-
friend class nsDOMScriptableHelper;
friend class nsDOMWindowUtils;
friend class mozilla::dom::PostMessageEvent;
diff --git a/dom/base/nsIDocument.h b/dom/base/nsIDocument.h
index 7a73fae71..e5d12ab8f 100644
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -3439,13 +3439,29 @@ nsINode::OwnerDocAsNode() const
return OwnerDoc();
}
+// ShouldUseXBLScope is defined here as a template so that we can get the faster
+// version of IsInAnonymousSubtree if we're statically known to be an
+// nsIContent. we could try defining ShouldUseXBLScope separately on nsINode
+// and nsIContent, but then we couldn't put its nsINode implementation here
+// (because this header does not include nsIContent) and we can't put it in
+// nsIContent.h, because the definition of nsIContent::IsInAnonymousSubtree is
+// in nsIContentInlines.h. And then we get include hell from people trying to
+// call nsINode::GetParentObject but not including nsIContentInlines.h and with
+// no really good way to include it.
+template<typename T>
+inline bool ShouldUseXBLScope(const T* aNode)
+{
+ return aNode->IsInAnonymousSubtree() &&
+ !aNode->IsAnonymousContentInSVGUseSubtree();
+}
+
inline mozilla::dom::ParentObject
nsINode::GetParentObject() const
{
mozilla::dom::ParentObject p(OwnerDoc());
// Note that mUseXBLScope is a no-op for chrome, and other places where we
// don't use XBL scopes.
- p.mUseXBLScope = IsInAnonymousSubtree() && !IsAnonymousContentInSVGUseSubtree();
+ p.mUseXBLScope = ShouldUseXBLScope(this);
return p;
}
diff --git a/dom/base/nsINode.cpp b/dom/base/nsINode.cpp
index 09e848710..ca507a5fc 100644
--- a/dom/base/nsINode.cpp
+++ b/dom/base/nsINode.cpp
@@ -27,6 +27,7 @@
#include "mozilla/dom/Element.h"
#include "mozilla/dom/Event.h"
#include "mozilla/dom/ShadowRoot.h"
+#include "mozilla/dom/ScriptSettings.h"
#include "nsAttrValueOrString.h"
#include "nsBindingManager.h"
#include "nsCCUncollectableMarker.h"
@@ -1569,6 +1570,48 @@ CheckForOutdatedParent(nsINode* aParent, nsINode* aNode)
return NS_OK;
}
+static nsresult
+ReparentWrappersInSubtree(nsIContent* aRoot)
+{
+ MOZ_ASSERT(ShouldUseXBLScope(aRoot));
+ // Start off with no global so we don't fire any error events on failure.
+ AutoJSAPI jsapi;
+ jsapi.Init();
+
+ JSContext* cx = jsapi.cx();
+
+ nsIGlobalObject* docGlobal = aRoot->OwnerDoc()->GetScopeObject();
+ if (NS_WARN_IF(!docGlobal)) {
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ JS::Rooted<JSObject*> rootedGlobal(cx, docGlobal->GetGlobalJSObject());
+ if (NS_WARN_IF(!rootedGlobal)) {
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ rootedGlobal = xpc::GetXBLScope(cx, rootedGlobal);
+
+ nsresult rv;
+ JS::Rooted<JSObject*> reflector(cx);
+ for (nsIContent* cur = aRoot; cur; cur = cur->GetNextNode(aRoot)) {
+ if ((reflector = cur->GetWrapper())) {
+ JSAutoCompartment ac(cx, reflector);
+ rv = ReparentWrapper(cx, reflector);
+ if NS_FAILED(rv) {
+ // We _could_ consider BlastSubtreeToPieces here, but it's not really
+ // needed. Having some nodes in here accessible to content while others
+ // are not is probably OK. We just need to fail out of the actual
+ // insertion, so they're not in the DOM. Returning a failure here will
+ // do that.
+ return rv;
+ }
+ }
+ }
+
+ return NS_OK;
+}
+
nsresult
nsINode::doInsertChildAt(nsIContent* aKid, uint32_t aIndex,
bool aNotify, nsAttrAndChildArray& aChildArray)
@@ -1606,9 +1649,15 @@ nsINode::doInsertChildAt(nsIContent* aKid, uint32_t aIndex,
nsIContent* parent =
IsNodeOfType(eDOCUMENT) ? nullptr : static_cast<nsIContent*>(this);
+ bool wasInXBLScope = ShouldUseXBLScope(aKid);
rv = aKid->BindToTree(doc, parent,
parent ? parent->GetBindingParent() : nullptr,
true);
+ if (NS_SUCCEEDED(rv) && !wasInXBLScope && ShouldUseXBLScope(aKid)) {
+ MOZ_ASSERT(ShouldUseXBLScope(this),
+ "Why does the kid need to use an XBL scope?");
+ rv = ReparentWrappersInSubtree(aKid);
+ }
if (NS_FAILED(rv)) {
if (GetFirstChild() == aKid) {
mFirstChild = aKid->GetNextSibling();
diff --git a/dom/base/nsJSEnvironment.cpp b/dom/base/nsJSEnvironment.cpp
index 3be1a6d2f..dfd380fc2 100644
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -70,7 +70,6 @@
#include "prthread.h"
#include "mozilla/Preferences.h"
-#include "mozilla/Telemetry.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/Attributes.h"
#include "mozilla/dom/asmjscache/AsmJSCache.h"
@@ -626,7 +625,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsJSContext)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsJSContext)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGlobalObjectRef)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsJSContext)
@@ -1357,9 +1355,20 @@ nsJSContext::RunCycleCollectorSlice()
TimeStamp now = TimeStamp::Now();
// Only run a limited slice if we're within the max running time.
- if (TimeBetween(gCCStats.mBeginTime, now) < kMaxICCDuration) {
- float sliceMultiplier = std::max(TimeBetween(gCCStats.mEndSliceTime, now) / (float)kICCIntersliceDelay, 1.0f);
- budget = js::SliceBudget(js::TimeBudget(kICCSliceBudget * sliceMultiplier));
+ uint32_t runningTime = TimeBetween(gCCStats.mBeginTime, now);
+ if (runningTime < kMaxICCDuration) {
+ // Try to make up for a delay in running this slice.
+ float sliceDelayMultiplier = TimeBetween(gCCStats.mEndSliceTime, now) / (float)kICCIntersliceDelay;
+ float delaySliceBudget = kICCSliceBudget * sliceDelayMultiplier;
+
+ // Increase slice budgets up to |maxLaterSlice| as we approach
+ // half way through the ICC, to avoid large sync CCs.
+ float percentToHalfDone = std::min(2.0f * runningTime / kMaxICCDuration, 1.0f);
+ const float maxLaterSlice = 40.0f;
+ float laterSliceBudget = maxLaterSlice * percentToHalfDone;
+
+ budget = js::SliceBudget(js::TimeBudget(std::max({delaySliceBudget,
+ laterSliceBudget, (float)kICCSliceBudget})));
}
}
}
@@ -1477,22 +1486,8 @@ nsJSContext::EndCycleCollectionCallback(CycleCollectorResults &aResults)
NS_GC_DELAY - std::min(ccNowDuration, kMaxICCDuration));
}
- // Log information about the CC via telemetry, JSON and the console.
- Telemetry::Accumulate(Telemetry::CYCLE_COLLECTOR_FINISH_IGC, gCCStats.mAnyLockedOut);
- Telemetry::Accumulate(Telemetry::CYCLE_COLLECTOR_SYNC_SKIPPABLE, gCCStats.mRanSyncForgetSkippable);
- Telemetry::Accumulate(Telemetry::CYCLE_COLLECTOR_FULL, ccNowDuration);
- Telemetry::Accumulate(Telemetry::CYCLE_COLLECTOR_MAX_PAUSE, gCCStats.mMaxSliceTime);
-
- if (!sLastCCEndTime.IsNull()) {
- // TimeBetween returns milliseconds, but we want to report seconds.
- uint32_t timeBetween = TimeBetween(sLastCCEndTime, gCCStats.mBeginTime) / 1000;
- Telemetry::Accumulate(Telemetry::CYCLE_COLLECTOR_TIME_BETWEEN, timeBetween);
- }
sLastCCEndTime = endCCTimeStamp;
- Telemetry::Accumulate(Telemetry::FORGET_SKIPPABLE_MAX,
- sMaxForgetSkippableTime / PR_USEC_PER_MSEC);
-
PRTime delta = GetCollectionTimeDelta();
uint32_t cleanups = sForgetSkippableBeforeCC ? sForgetSkippableBeforeCC : 1;
@@ -2633,7 +2628,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsJSArgArray)
tmp->ReleaseJSObjects();
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsJSArgArray)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsJSArgArray)
diff --git a/dom/base/nsJSTimeoutHandler.cpp b/dom/base/nsJSTimeoutHandler.cpp
index 8736cd1dd..ce5d58385 100644
--- a/dom/base/nsJSTimeoutHandler.cpp
+++ b/dom/base/nsJSTimeoutHandler.cpp
@@ -151,7 +151,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsJSScriptTimeoutHandler)
if (tmp->mFunction) {
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFunction)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
diff --git a/dom/base/nsMappedAttributes.h b/dom/base/nsMappedAttributes.h
index 9fa7572dd..f00b888b9 100644
--- a/dom/base/nsMappedAttributes.h
+++ b/dom/base/nsMappedAttributes.h
@@ -93,20 +93,13 @@ private:
nsAttrValue mValue;
};
- /**
- * Due to a compiler bug in VisualAge C++ for AIX, we need to return the
- * address of the first index into mAttrs here, instead of simply
- * returning mAttrs itself.
- *
- * See Bug 231104 for more information.
- */
const InternalAttr* Attrs() const
{
- return reinterpret_cast<const InternalAttr*>(&(mAttrs[0]));
+ return reinterpret_cast<const InternalAttr*>(mAttrs);
}
InternalAttr* Attrs()
{
- return reinterpret_cast<InternalAttr*>(&(mAttrs[0]));
+ return reinterpret_cast<InternalAttr*>(mAttrs);
}
uint16_t mAttrCount;
diff --git a/dom/base/nsNodeInfoManager.cpp b/dom/base/nsNodeInfoManager.cpp
index 66c8c84cf..80f0aa786 100644
--- a/dom/base/nsNodeInfoManager.cpp
+++ b/dom/base/nsNodeInfoManager.cpp
@@ -392,9 +392,6 @@ nsNodeInfoManager::SetDocumentPrincipal(nsIPrincipal *aPrincipal)
NS_ASSERTION(aPrincipal, "Must have principal by this point!");
MOZ_DIAGNOSTIC_ASSERT(!nsContentUtils::IsExpandedPrincipal(aPrincipal),
"Documents shouldn't have an expanded principal");
- if (nsContentUtils::IsExpandedPrincipal(aPrincipal)) {
- Telemetry::Accumulate(Telemetry::DOCUMENT_WITH_EXPANDED_PRINCIPAL, 1);
- }
mPrincipal = aPrincipal;
}
diff --git a/dom/base/nsNodeUtils.cpp b/dom/base/nsNodeUtils.cpp
index ecea95dc1..75d408151 100644
--- a/dom/base/nsNodeUtils.cpp
+++ b/dom/base/nsNodeUtils.cpp
@@ -297,6 +297,16 @@ nsNodeUtils::LastRelease(nsINode* aNode)
NodeWillBeDestroyed, (aNode));
}
+ if (aNode->IsElement()) {
+ Element* elem = aNode->AsElement();
+ FragmentOrElement::nsDOMSlots* domSlots =
+ static_cast<FragmentOrElement::nsDOMSlots*>(slots);
+ for (auto iter = domSlots->mRegisteredIntersectionObservers.Iter(); !iter.Done(); iter.Next()) {
+ DOMIntersectionObserver* observer = iter.Key();
+ observer->UnlinkTarget(*elem);
+ }
+ }
+
delete slots;
aNode->mSlots = nullptr;
}
diff --git a/dom/base/nsObjectLoadingContent.cpp b/dom/base/nsObjectLoadingContent.cpp
index 9e9dacf01..c1b732258 100644
--- a/dom/base/nsObjectLoadingContent.cpp
+++ b/dom/base/nsObjectLoadingContent.cpp
@@ -85,7 +85,6 @@
#include "mozilla/AsyncEventDispatcher.h"
#include "mozilla/EventDispatcher.h"
#include "mozilla/EventStates.h"
-#include "mozilla/Telemetry.h"
#include "mozilla/dom/HTMLObjectElementBinding.h"
#include "mozilla/dom/HTMLSharedObjectElement.h"
#include "nsChannelClassifier.h"
@@ -1149,7 +1148,6 @@ nsObjectLoadingContent::OnStartRequest(nsIRequest *aRequest,
NS_LITERAL_STRING(" since it was found on an internal Firefox blocklist.");
console->LogStringMessage(message.get());
}
- Telemetry::Accumulate(Telemetry::PLUGIN_BLOCKED_FOR_STABILITY, 1);
mContentBlockingEnabled = true;
return NS_ERROR_FAILURE;
} else if (status == NS_ERROR_TRACKING_URI) {
@@ -1565,7 +1563,6 @@ nsObjectLoadingContent::MaybeRewriteYoutubeEmbed(nsIURI* aURI, nsIURI* aBaseURI,
}
if (uri.Find("enablejsapi=1", true, 0, -1) != kNotFound) {
- Telemetry::Accumulate(Telemetry::YOUTUBE_NONREWRITABLE_EMBED_SEEN, 1);
return;
}
@@ -1585,11 +1582,6 @@ nsObjectLoadingContent::MaybeRewriteYoutubeEmbed(nsIURI* aURI, nsIURI* aBaseURI,
}
}
- // If we've made it this far, we've got a rewritable embed. Log it in
- // telemetry.
- Telemetry::Accumulate(Telemetry::YOUTUBE_REWRITABLE_EMBED_SEEN, 1);
-
- // If we're pref'd off, return after telemetry has been logged.
if (!Preferences::GetBool(kPrefYoutubeRewrite)) {
return;
}
@@ -3800,8 +3792,6 @@ nsObjectLoadingContent::LegacyCall(JSContext* aCx,
aRv.Throw(NS_ERROR_FAILURE);
return;
}
-
- Telemetry::Accumulate(Telemetry::PLUGIN_CALLED_DIRECTLY, true);
}
void
diff --git a/dom/base/nsRange.cpp b/dom/base/nsRange.cpp
index 4b4ce7885..d45a2c975 100644
--- a/dom/base/nsRange.cpp
+++ b/dom/base/nsRange.cpp
@@ -351,7 +351,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsRange)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEndParent)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRoot)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSelection)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsRange)
diff --git a/dom/base/nsScriptLoader.cpp b/dom/base/nsScriptLoader.cpp
index a6d20e363..1e23d6c5f 100644
--- a/dom/base/nsScriptLoader.cpp
+++ b/dom/base/nsScriptLoader.cpp
@@ -81,11 +81,19 @@ ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsScriptLoadRequest)
NS_INTERFACE_MAP_END
-NS_IMPL_CYCLE_COLLECTION_0(nsScriptLoadRequest)
-
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsScriptLoadRequest)
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsScriptLoadRequest)
+NS_IMPL_CYCLE_COLLECTION_CLASS(nsScriptLoadRequest)
+
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsScriptLoadRequest)
+ NS_IMPL_CYCLE_COLLECTION_UNLINK(mElement)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsScriptLoadRequest)
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mElement)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
nsScriptLoadRequest::~nsScriptLoadRequest()
{
js_free(mScriptTextBuf);
@@ -345,7 +353,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsModuleScript)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLoader)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsModuleScript)
diff --git a/dom/base/nsWrapperCache.cpp b/dom/base/nsWrapperCache.cpp
index b91d86598..c5993fe7b 100644
--- a/dom/base/nsWrapperCache.cpp
+++ b/dom/base/nsWrapperCache.cpp
@@ -133,7 +133,7 @@ nsWrapperCache::CheckCCWrapperTraversal(void* aScriptObjectHolder,
// see through the COM layer, so we use a suppression to help it.
JS::AutoSuppressGCAnalysis suppress;
- aTracer->Traverse(aScriptObjectHolder, callback);
+ aTracer->TraverseNativeAndJS(aScriptObjectHolder, callback);
MOZ_ASSERT(callback.mFound,
"Cycle collection participant didn't traverse to preserved "
"wrapper! This will probably crash.");
diff --git a/dom/base/nsWrapperCache.h b/dom/base/nsWrapperCache.h
index 3c69a7ec4..56cae89ed 100644
--- a/dom/base/nsWrapperCache.h
+++ b/dom/base/nsWrapperCache.h
@@ -331,8 +331,7 @@ private:
* causes between the native object and the JS object, so it is important that
* any native object that supports preserving of its wrapper
* traces/traverses/unlinks the cached JS object (see
- * NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER,
- * NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS and
+ * NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER and
* NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER).
*/
enum { WRAPPER_BIT_PRESERVED = 1 << 0 };
@@ -383,7 +382,6 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsWrapperCache, NS_WRAPPERCACHE_IID)
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER \
NS_IMPL_CYCLE_COLLECTION_UNLINK_END \
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_class) \
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS \
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END \
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(_class)
@@ -395,7 +393,6 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsWrapperCache, NS_WRAPPERCACHE_IID)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END \
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_class) \
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(__VA_ARGS__) \
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS \
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END \
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(_class)
diff --git a/dom/bindings/BindingUtils.cpp b/dom/bindings/BindingUtils.cpp
index 323feca52..8d2bdaac6 100644
--- a/dom/bindings/BindingUtils.cpp
+++ b/dom/bindings/BindingUtils.cpp
@@ -2558,7 +2558,7 @@ NonVoidByteStringToJsval(JSContext *cx, const nsACString &str,
template<typename T> static void
-NormalizeUSVStringInternal(JSContext* aCx, T& aString)
+NormalizeUSVStringInternal(T& aString)
{
char16_t* start = aString.BeginWriting();
// Must use const here because we can't pass char** to UTF16CharEnumerator as
@@ -2575,15 +2575,15 @@ NormalizeUSVStringInternal(JSContext* aCx, T& aString)
}
void
-NormalizeUSVString(JSContext* aCx, nsAString& aString)
+NormalizeUSVString(nsAString& aString)
{
- NormalizeUSVStringInternal(aCx, aString);
+ NormalizeUSVStringInternal(aString);
}
void
-NormalizeUSVString(JSContext* aCx, binding_detail::FakeString& aString)
+NormalizeUSVString(binding_detail::FakeString& aString)
{
- NormalizeUSVStringInternal(aCx, aString);
+ NormalizeUSVStringInternal(aString);
}
bool
diff --git a/dom/bindings/BindingUtils.h b/dom/bindings/BindingUtils.h
index 3e58390c9..a3ec70f47 100644
--- a/dom/bindings/BindingUtils.h
+++ b/dom/bindings/BindingUtils.h
@@ -49,7 +49,7 @@ namespace mozilla {
enum UseCounter : int16_t;
namespace dom {
-template<typename DataType> class MozMap;
+template<typename KeyType, typename ValueType> class Record;
nsresult
UnwrapArgImpl(JS::Handle<JSObject*> src, const nsIID& iid, void** ppArg);
@@ -515,7 +515,7 @@ class ProtoAndIfaceCache
{
public:
PageTableCache() {
- memset(&mPages, 0, sizeof(mPages));
+ memset(mPages.begin(), 0, sizeof(mPages));
}
~PageTableCache() {
@@ -2127,11 +2127,30 @@ ConvertJSValueToString(JSContext* cx, JS::Handle<JS::Value> v,
return AssignJSString(cx, result, s);
}
+template<typename T>
+static inline bool
+ConvertJSValueToString(JSContext* cx, JS::Handle<JS::Value> v, T& result)
+{
+ return ConvertJSValueToString(cx, v, eStringify, eStringify, result);
+}
+
void
-NormalizeUSVString(JSContext* aCx, nsAString& aString);
+NormalizeUSVString(nsAString& aString);
void
-NormalizeUSVString(JSContext* aCx, binding_detail::FakeString& aString);
+NormalizeUSVString(binding_detail::FakeString& aString);
+
+template<typename T>
+static inline bool
+ConvertJSValueToUSVString(JSContext* cx, JS::Handle<JS::Value> v, T& result)
+{
+ if (!ConvertJSValueToString(cx, v, eStringify, eStringify, result)) {
+ return false;
+ }
+
+ NormalizeUSVString(result);
+ return true;
+}
template<typename T>
inline bool
@@ -2158,6 +2177,13 @@ bool
ConvertJSValueToByteString(JSContext* cx, JS::Handle<JS::Value> v,
bool nullable, nsACString& result);
+inline bool
+ConvertJSValueToByteString(JSContext* cx, JS::Handle<JS::Value> v,
+ nsACString& result)
+{
+ return ConvertJSValueToByteString(cx, v, false, result);
+}
+
template<typename T>
void DoTraceSequence(JSTracer* trc, FallibleTArray<T>& seq);
template<typename T>
@@ -2293,31 +2319,26 @@ public:
}
};
-template<typename T>
-static void
-TraceMozMapValue(T* aValue, void* aClosure)
-{
- JSTracer* trc = static_cast<JSTracer*>(aClosure);
- // Act like it's a one-element sequence to leverage all that infrastructure.
- SequenceTracer<T>::TraceSequence(trc, aValue, aValue + 1);
-}
-
-template<typename T>
-void TraceMozMap(JSTracer* trc, MozMap<T>& map)
+template<typename K, typename V>
+void TraceRecord(JSTracer* trc, Record<K, V>& record)
{
- map.EnumerateValues(TraceMozMapValue<T>, trc);
+ for (auto& entry : record.Entries()) {
+ // Act like it's a one-element sequence to leverage all that infrastructure.
+ SequenceTracer<V>::TraceSequence(trc, &entry.mValue, &entry.mValue + 1);
+ }
}
-// sequence<MozMap>
-template<typename T>
-class SequenceTracer<MozMap<T>, false, false, false>
+// sequence<record>
+template<typename K, typename V>
+class SequenceTracer<Record<K, V>, false, false, false>
{
explicit SequenceTracer() = delete; // Should never be instantiated
public:
- static void TraceSequence(JSTracer* trc, MozMap<T>* seqp, MozMap<T>* end) {
+ static void TraceSequence(JSTracer* trc, Record<K, V>* seqp,
+ Record<K, V>* end) {
for (; seqp != end; ++seqp) {
- seqp->EnumerateValues(TraceMozMapValue<T>, trc);
+ TraceRecord(trc, *seqp);
}
}
};
@@ -2395,51 +2416,51 @@ public:
SequenceType mSequenceType;
};
-// Rooter class for MozMap; this is what we mostly use in the codegen.
-template<typename T>
-class MOZ_RAII MozMapRooter final : private JS::CustomAutoRooter
+// Rooter class for Record; this is what we mostly use in the codegen.
+template<typename K, typename V>
+class MOZ_RAII RecordRooter final : private JS::CustomAutoRooter
{
public:
- MozMapRooter(JSContext *aCx, MozMap<T>* aMozMap
+ RecordRooter(JSContext *aCx, Record<K, V>* aRecord
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
: JS::CustomAutoRooter(aCx MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT),
- mMozMap(aMozMap),
- mMozMapType(eMozMap)
+ mRecord(aRecord),
+ mRecordType(eRecord)
{
}
- MozMapRooter(JSContext *aCx, Nullable<MozMap<T>>* aMozMap
+ RecordRooter(JSContext *aCx, Nullable<Record<K, V>>* aRecord
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
: JS::CustomAutoRooter(aCx MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT),
- mNullableMozMap(aMozMap),
- mMozMapType(eNullableMozMap)
+ mNullableRecord(aRecord),
+ mRecordType(eNullableRecord)
{
}
private:
- enum MozMapType {
- eMozMap,
- eNullableMozMap
+ enum RecordType {
+ eRecord,
+ eNullableRecord
};
virtual void trace(JSTracer *trc) override
{
- if (mMozMapType == eMozMap) {
- TraceMozMap(trc, *mMozMap);
+ if (mRecordType == eRecord) {
+ TraceRecord(trc, *mRecord);
} else {
- MOZ_ASSERT(mMozMapType == eNullableMozMap);
- if (!mNullableMozMap->IsNull()) {
- TraceMozMap(trc, mNullableMozMap->Value());
+ MOZ_ASSERT(mRecordType == eNullableRecord);
+ if (!mNullableRecord->IsNull()) {
+ TraceRecord(trc, mNullableRecord->Value());
}
}
}
union {
- MozMap<T>* mMozMap;
- Nullable<MozMap<T>>* mNullableMozMap;
+ Record<K, V>* mRecord;
+ Nullable<Record<K, V>>* mNullableRecord;
};
- MozMapType mMozMapType;
+ RecordType mRecordType;
};
template<typename T>
diff --git a/dom/bindings/CallbackObject.cpp b/dom/bindings/CallbackObject.cpp
index 7c7d2c6b4..bb01c804c 100644
--- a/dom/bindings/CallbackObject.cpp
+++ b/dom/bindings/CallbackObject.cpp
@@ -37,7 +37,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(CallbackObject)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mIncumbentGlobal)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(CallbackObject)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIncumbentGlobal)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(CallbackObject)
diff --git a/dom/bindings/Codegen.py b/dom/bindings/Codegen.py
index 7a6668687..74acb5918 100644
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -84,7 +84,7 @@ def idlTypeNeedsCycleCollection(type):
return True
elif type.isUnion():
return any(idlTypeNeedsCycleCollection(t) for t in type.flatMemberTypes)
- elif type.isMozMap():
+ elif type.isRecord():
if idlTypeNeedsCycleCollection(type.inner):
raise TypeError("Cycle collection for type %s is not supported" % type)
return False
@@ -996,6 +996,8 @@ class CGElseChain(CGThing):
class CGTemplatedType(CGWrapper):
def __init__(self, templateName, child, isConst=False, isReference=False):
+ if isinstance(child, list):
+ child = CGList(child, ", ")
const = "const " if isConst else ""
pre = "%s%s<" % (const, templateName)
ref = "&" if isReference else ""
@@ -1171,12 +1173,12 @@ class CGHeaders(CGWrapper):
declareIncludes.add(filename)
elif unrolled.isPrimitive():
bindingHeaders.add("mozilla/dom/PrimitiveConversions.h")
- elif unrolled.isMozMap():
+ elif unrolled.isRecord():
if dictionary or jsImplementedDescriptors:
- declareIncludes.add("mozilla/dom/MozMap.h")
+ declareIncludes.add("mozilla/dom/Record.h")
else:
- bindingHeaders.add("mozilla/dom/MozMap.h")
- # Also add headers for the type the MozMap is
+ bindingHeaders.add("mozilla/dom/Record.h")
+ # Also add headers for the type the record is
# parametrized over, if needed.
addHeadersForType((t.inner, dictionary))
@@ -1388,8 +1390,8 @@ def UnionTypes(unionTypes, config):
# the right header to be able to Release() in our inlined
# code.
headers.add(CGHeaders.getDeclarationFilename(f.callback))
- elif f.isMozMap():
- headers.add("mozilla/dom/MozMap.h")
+ elif f.isRecord():
+ headers.add("mozilla/dom/Record.h")
# And add headers for the type we're parametrized over
addHeadersForType(f.inner)
@@ -1448,9 +1450,9 @@ def UnionConversions(unionTypes, config):
headers.add(CGHeaders.getDeclarationFilename(f.inner))
elif f.isPrimitive():
headers.add("mozilla/dom/PrimitiveConversions.h")
- elif f.isMozMap():
- headers.add("mozilla/dom/MozMap.h")
- # And the internal type of the MozMap
+ elif f.isRecord():
+ headers.add("mozilla/dom/Record.h")
+ # And the internal type of the record
addHeadersForType(f.inner)
# We plan to include UnionTypes.h no matter what, so it's
@@ -4290,6 +4292,9 @@ class JSToNativeConversionInfo():
for whether we have a JS::Value. Only used when
defaultValue is not None or when True is passed for
checkForValue to instantiateJSToNativeConversion.
+ This expression may not be already-parenthesized, so if
+ you use it with && or || make sure to put parens
+ around it.
${passedToJSImpl} replaced by an expression that evaluates to a boolean
for whether this value is being passed to a JS-
implemented interface.
@@ -4355,7 +4360,9 @@ def handleDefaultStringValue(defaultValue, method):
passing as the second argument of handleDefault; in particular it does not
end with a ';'
"""
- assert defaultValue.type.isDOMString() or defaultValue.type.isByteString()
+ assert (defaultValue.type.isDOMString() or
+ defaultValue.type.isUSVString() or
+ defaultValue.type.isByteString())
return ("static const %(char_t)s data[] = { %(data)s };\n"
"%(method)s(data, ArrayLength(data) - 1)") % {
'char_t': "char" if defaultValue.type.isByteString() else "char16_t",
@@ -4365,6 +4372,17 @@ def handleDefaultStringValue(defaultValue, method):
}
+def recordKeyType(recordType):
+ assert recordType.keyType.isString()
+ if recordType.keyType.isByteString():
+ return "nsCString"
+ return "nsString"
+
+
+def recordKeyDeclType(recordType):
+ return CGGeneric(recordKeyType(recordType))
+
+
# If this function is modified, modify CGNativeMember.getArg and
# CGNativeMember.getRetvalInfo accordingly. The latter cares about the decltype
# and holdertype we end up using, because it needs to be able to return the code
@@ -4559,7 +4577,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
declArgs = "cx"
else:
assert (isMember in
- ("Sequence", "Variadic", "Dictionary", "OwningUnion", "MozMap"))
+ ("Sequence", "Variadic", "Dictionary", "OwningUnion", "Record"))
# We'll get traced by the sequence or dictionary or union tracer
declType = CGGeneric("JSObject*")
declArgs = None
@@ -4725,39 +4743,41 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
dealWithOptional=isOptional,
holderArgs=holderArgs)
- if type.isMozMap():
+ if type.isRecord():
assert not isEnforceRange and not isClamp
if failureCode is None:
- notMozMap = ('ThrowErrorMessage(cx, MSG_NOT_OBJECT, "%s");\n'
+ notRecord = ('ThrowErrorMessage(cx, MSG_NOT_OBJECT, "%s");\n'
"%s" % (firstCap(sourceDescription), exceptionCode))
else:
- notMozMap = failureCode
+ notRecord = failureCode
nullable = type.nullable()
# Be very careful not to change "type": we need it later
if nullable:
- valueType = type.inner.inner
+ recordType = type.inner
else:
- valueType = type.inner
+ recordType = type
+ valueType = recordType.inner
valueInfo = getJSToNativeConversionInfo(
- valueType, descriptorProvider, isMember="MozMap",
+ valueType, descriptorProvider, isMember="Record",
exceptionCode=exceptionCode, lenientFloatCode=lenientFloatCode,
isCallbackReturnValue=isCallbackReturnValue,
sourceDescription="value in %s" % sourceDescription,
nestingLevel=incrementNestingLevel())
if valueInfo.dealWithOptional:
- raise TypeError("Shouldn't have optional things in MozMap")
+ raise TypeError("Shouldn't have optional things in record")
if valueInfo.holderType is not None:
- raise TypeError("Shouldn't need holders for MozMap")
+ raise TypeError("Shouldn't need holders for record")
- typeName = CGTemplatedType("MozMap", valueInfo.declType)
- mozMapType = typeName.define()
+ declType = CGTemplatedType("Record", [recordKeyDeclType(recordType),
+ valueInfo.declType])
+ typeName = declType.define()
if nullable:
- typeName = CGTemplatedType("Nullable", typeName)
- mozMapRef = "${declName}.SetValue()"
+ declType = CGTemplatedType("Nullable", declType)
+ recordRef = "${declName}.SetValue()"
else:
- mozMapRef = "${declName}"
+ recordRef = "${declName}"
valueConversion = string.Template(valueInfo.template).substitute({
"val": "temp",
@@ -4770,68 +4790,122 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
"passedToJSImpl": "${passedToJSImpl}"
})
+ keyType = recordKeyType(recordType)
+ if recordType.keyType.isByteString():
+ keyConversionFunction = "ConvertJSValueToByteString"
+ hashKeyType = "nsCStringHashKey"
+ else:
+ hashKeyType = "nsStringHashKey"
+ if recordType.keyType.isDOMString():
+ keyConversionFunction = "ConvertJSValueToString"
+ else:
+ assert recordType.keyType.isUSVString()
+ keyConversionFunction = "ConvertJSValueToUSVString"
+
templateBody = fill(
"""
- ${mozMapType} &mozMap = ${mozMapRef};
+ auto& recordEntries = ${recordRef}.Entries();
- JS::Rooted<JSObject*> mozMapObj(cx, &$${val}.toObject());
- JS::Rooted<JS::IdVector> ids(cx, JS::IdVector(cx));
- if (!JS_Enumerate(cx, mozMapObj, &ids)) {
+ JS::Rooted<JSObject*> recordObj(cx, &$${val}.toObject());
+ JS::AutoIdVector ids(cx);
+ if (!js::GetPropertyKeys(cx, recordObj,
+ JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS, &ids)) {
+ $*{exceptionCode}
+ }
+ if (!recordEntries.SetCapacity(ids.length(), mozilla::fallible)) {
+ JS_ReportOutOfMemory(cx);
$*{exceptionCode}
}
JS::Rooted<JS::Value> propNameValue(cx);
JS::Rooted<JS::Value> temp(cx);
JS::Rooted<jsid> curId(cx);
+ JS::Rooted<JS::Value> idVal(cx);
+ // Use a hashset to keep track of ids seen, to avoid
+ // introducing nasty O(N^2) behavior scanning for them all the
+ // time. Ideally we'd use a data structure with O(1) lookup
+ // _and_ ordering for the MozMap, but we don't have one lying
+ // around.
+ nsTHashtable<${hashKeyType}> idsSeen;
for (size_t i = 0; i < ids.length(); ++i) {
- // Make sure we get the value before converting the name, since
- // getting the value can trigger GC but our name is a dependent
- // string.
curId = ids[i];
- binding_detail::FakeString propName;
- bool isSymbol;
- if (!ConvertIdToString(cx, curId, propName, isSymbol) ||
- (!isSymbol && !JS_GetPropertyById(cx, mozMapObj, curId, &temp))) {
+
+ JS::Rooted<JS::PropertyDescriptor> desc(cx);
+ if (!JS_GetOwnPropertyDescriptorById(cx, recordObj, curId,
+ &desc)) {
$*{exceptionCode}
}
- if (isSymbol) {
+
+ if (!desc.object() /* == undefined in spec terms */ ||
+ !desc.enumerable()) {
continue;
}
- ${valueType}* slotPtr = mozMap.AddEntry(propName);
- if (!slotPtr) {
- JS_ReportOutOfMemory(cx);
+ idVal = js::IdToValue(curId);
+ ${keyType} propName;
+ // This will just throw if idVal is a Symbol, like the spec says
+ // to do.
+ if (!${keyConversionFunction}(cx, idVal, propName)) {
$*{exceptionCode}
}
- ${valueType}& slot = *slotPtr;
+
+ if (!JS_GetPropertyById(cx, recordObj, curId, &temp)) {
+ $*{exceptionCode}
+ }
+
+ ${typeName}::EntryType* entry;
+ if (idsSeen.Contains(propName)) {
+ // Find the existing entry.
+ auto idx = recordEntries.IndexOf(propName);
+ MOZ_ASSERT(idx != recordEntries.NoIndex,
+ "Why is it not found?");
+ // Now blow it away to make it look like it was just added
+ // to the array, because it's not obvious that it's
+ // safe to write to its already-initialized mValue via our
+ // normal codegen conversions. For example, the value
+ // could be a union and this would change its type, but
+ // codegen assumes we won't do that.
+ entry = recordEntries.ReconstructElementAt(idx);
+ } else {
+ // Safe to do an infallible append here, because we did a
+ // SetCapacity above to the right capacity.
+ entry = recordEntries.AppendElement();
+ idsSeen.PutEntry(propName);
+ }
+ entry->mKey = propName;
+ ${valueType}& slot = entry->mValue;
$*{valueConversion}
}
""",
exceptionCode=exceptionCode,
- mozMapType=mozMapType,
- mozMapRef=mozMapRef,
+ recordRef=recordRef,
+ hashKeyType=hashKeyType,
+ keyType=keyType,
+ keyConversionFunction=keyConversionFunction,
+ typeName=typeName,
valueType=valueInfo.declType.define(),
valueConversion=valueConversion)
templateBody = wrapObjectTemplate(templateBody, type,
"${declName}.SetNull();\n",
- notMozMap)
+ notRecord)
- declType = typeName
declArgs = None
holderType = None
holderArgs = None
- # MozMap arguments that might contain traceable things need
+ # record arguments that might contain traceable things need
# to get traced
if not isMember and isCallbackReturnValue:
# Go ahead and just convert directly into our actual return value
declType = CGWrapper(declType, post="&")
declArgs = "aRetVal"
elif not isMember and typeNeedsRooting(valueType):
- holderType = CGTemplatedType("MozMapRooter", valueInfo.declType)
- # If our MozMap is nullable, this will set the Nullable to be
+ holderType = CGTemplatedType("RecordRooter",
+ [recordKeyDeclType(recordType),
+ valueInfo.declType])
+ # If our record is nullable, this will set the Nullable to be
# not-null, but that's ok because we make an explicit SetNull() call
# on it as needed if our JS value is actually null.
- holderArgs = "cx, &%s" % mozMapRef
+ holderArgs = "cx, &%s" % recordRef
return JSToNativeConversionInfo(templateBody, declType=declType,
declArgs=declArgs,
@@ -4914,16 +4988,16 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
else:
setDictionary = None
- mozMapMemberTypes = filter(lambda t: t.isMozMap(), memberTypes)
- if len(mozMapMemberTypes) > 0:
- assert len(mozMapMemberTypes) == 1
- name = getUnionMemberName(mozMapMemberTypes[0])
- mozMapObject = CGGeneric(
+ recordMemberTypes = filter(lambda t: t.isRecord(), memberTypes)
+ if len(recordMemberTypes) > 0:
+ assert len(recordMemberTypes) == 1
+ name = getUnionMemberName(recordMemberTypes[0])
+ recordObject = CGGeneric(
"done = (failed = !%s.TrySetTo%s(cx, ${val}, tryNext, ${passedToJSImpl})) || !tryNext;\n" %
(unionArgumentObj, name))
names.append(name)
else:
- mozMapObject = None
+ recordObject = None
objectMemberTypes = filter(lambda t: t.isObject(), memberTypes)
if len(objectMemberTypes) > 0:
@@ -4939,10 +5013,10 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
else:
object = None
- hasObjectTypes = interfaceObject or sequenceObject or dateObject or callbackObject or object or mozMapObject
+ hasObjectTypes = interfaceObject or sequenceObject or dateObject or callbackObject or object or recordObject
if hasObjectTypes:
# "object" is not distinguishable from other types
- assert not object or not (interfaceObject or sequenceObject or dateObject or callbackObject or mozMapObject)
+ assert not object or not (interfaceObject or sequenceObject or dateObject or callbackObject or recordObject)
if sequenceObject or dateObject or callbackObject:
# An object can be both an sequence object and a callback or
# dictionary, but we shouldn't have both in the union's members
@@ -4962,9 +5036,9 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
if dateObject:
templateBody.prepend(CGGeneric("JS::Rooted<JSObject*> argObj(cx, &${val}.toObject());\n"))
- if mozMapObject:
+ if recordObject:
templateBody = CGList([templateBody,
- CGIfWrapper(mozMapObject, "!done")])
+ CGIfWrapper(recordObject, "!done")])
templateBody = CGIfWrapper(templateBody, "${val}.isObject()")
else:
@@ -5144,7 +5218,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
if isinstance(defaultValue, IDLNullValue):
extraConditionForNull = "!(${haveValue}) || "
else:
- extraConditionForNull = "${haveValue} && "
+ extraConditionForNull = "(${haveValue}) && "
else:
extraConditionForNull = ""
templateBody = handleNull(templateBody, declLoc,
@@ -5525,7 +5599,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
def getConversionCode(varName):
normalizeCode = ""
if type.isUSVString():
- normalizeCode = "NormalizeUSVString(cx, %s);\n" % varName
+ normalizeCode = "NormalizeUSVString(%s);\n" % varName
conversionCode = fill("""
if (!ConvertJSValueToString(cx, $${val}, ${nullBehavior}, ${undefinedBehavior}, ${varName})) {
@@ -5688,7 +5762,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
haveCallable = "${val}.isObject() && " + haveCallable
if defaultValue is not None:
assert(isinstance(defaultValue, IDLNullValue))
- haveCallable = "${haveValue} && " + haveCallable
+ haveCallable = "(${haveValue}) && " + haveCallable
template = (
("if (%s) {\n" % haveCallable) +
conversion +
@@ -5700,7 +5774,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
haveObject = "${val}.isObject()"
if defaultValue is not None:
assert(isinstance(defaultValue, IDLNullValue))
- haveObject = "${haveValue} && " + haveObject
+ haveObject = "(${haveValue}) && " + haveObject
template = CGIfElseWrapper(haveObject,
CGGeneric(conversion),
CGGeneric("${declName} = nullptr;\n")).define()
@@ -5724,7 +5798,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
assert not isEnforceRange and not isClamp
declArgs = None
- if isMember in ("Variadic", "Sequence", "Dictionary", "MozMap"):
+ if isMember in ("Variadic", "Sequence", "Dictionary", "Record"):
# Rooting is handled by the sequence and dictionary tracers.
declType = "JS::Value"
else:
@@ -5768,8 +5842,9 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
return handleJSObjectType(type, isMember, failureCode, exceptionCode, sourceDescription)
if type.isDictionary():
- # There are no nullable dictionaries
- assert not type.nullable() or isCallbackReturnValue
+ # There are no nullable dictionary arguments or dictionary members
+ assert(not type.nullable() or isCallbackReturnValue or
+ (isMember and isMember != "Dictionary"))
# All optional dictionaries always have default values, so we
# should be able to assume not isOptional here.
assert not isOptional
@@ -6256,7 +6331,7 @@ def getMaybeWrapValueFuncForType(type):
sequenceWrapLevel = 0
-mozMapWrapLevel = 0
+recordWrapLevel = 0
def getWrapTemplateForType(type, descriptorProvider, result, successCode,
@@ -6361,7 +6436,7 @@ def getWrapTemplateForType(type, descriptorProvider, result, successCode,
if type is None or type.isVoid():
return (setUndefined(), True)
- if (type.isSequence() or type.isMozMap()) and type.nullable():
+ if (type.isSequence() or type.isRecord()) and type.nullable():
# These are both wrapped in Nullable<>
recTemplate, recInfall = getWrapTemplateForType(type.inner, descriptorProvider,
"%s.Value()" % result, successCode,
@@ -6434,14 +6509,14 @@ def getWrapTemplateForType(type, descriptorProvider, result, successCode,
return (code, False)
- if type.isMozMap():
- # Now do non-nullable MozMap. Our success code is just to break to
+ if type.isRecord():
+ # Now do non-nullable record. Our success code is just to break to
# where we define the property on the object. Note that we bump the
- # mozMapWrapLevel around this call so that nested MozMap conversions
+ # recordWrapLevel around this call so that nested record conversions
# will use different temp value names.
- global mozMapWrapLevel
- valueName = "mozMapValue%d" % mozMapWrapLevel
- mozMapWrapLevel += 1
+ global recordWrapLevel
+ valueName = "recordValue%d" % recordWrapLevel
+ recordWrapLevel += 1
innerTemplate = wrapForType(
type.inner, descriptorProvider,
{
@@ -6454,12 +6529,22 @@ def getWrapTemplateForType(type, descriptorProvider, result, successCode,
'obj': "returnObj",
'typedArraysAreStructs': typedArraysAreStructs
})
- mozMapWrapLevel -= 1
+ recordWrapLevel -= 1
+ if type.keyType.isByteString():
+ # There is no length-taking JS_DefineProperty. So to keep
+ # things sane with embedded nulls, we want to byte-inflate
+ # to an nsAString. The only byte-inflation function we
+ # have around is AppendASCIItoUTF16, which luckily doesn't
+ # assert anything about the input being ASCII.
+ expandedKeyDecl = "NS_ConvertASCIItoUTF16 expandedKey(entry.mKey);\n"
+ keyName = "expandedKey"
+ else:
+ expandedKeyDecl = ""
+ keyName = "entry.mKey"
+
code = fill(
"""
- nsTArray<nsString> keys;
- ${result}.GetKeys(keys);
JS::Rooted<JSObject*> returnObj(cx, JS_NewPlainObject(cx));
if (!returnObj) {
$*{exceptionCode}
@@ -6467,15 +6552,17 @@ def getWrapTemplateForType(type, descriptorProvider, result, successCode,
// Scope for 'tmp'
{
JS::Rooted<JS::Value> tmp(cx);
- for (size_t idx = 0; idx < keys.Length(); ++idx) {
- auto& ${valueName} = ${result}.Get(keys[idx]);
+ for (auto& entry : ${result}.Entries()) {
+ auto& ${valueName} = entry.mValue;
// Control block to let us common up the JS_DefineUCProperty calls when there
// are different ways to succeed at wrapping the value.
do {
$*{innerTemplate}
} while (0);
- if (!JS_DefineUCProperty(cx, returnObj, keys[idx].get(),
- keys[idx].Length(), tmp,
+ $*{expandedKeyDecl}
+ if (!JS_DefineUCProperty(cx, returnObj,
+ ${keyName}.BeginReading(),
+ ${keyName}.Length(), tmp,
JSPROP_ENUMERATE)) {
$*{exceptionCode}
}
@@ -6487,6 +6574,8 @@ def getWrapTemplateForType(type, descriptorProvider, result, successCode,
exceptionCode=exceptionCode,
valueName=valueName,
innerTemplate=innerTemplate,
+ expandedKeyDecl=expandedKeyDecl,
+ keyName=keyName,
set=setObject("*returnObj"))
return (code, False)
@@ -6770,7 +6859,7 @@ def typeMatchesLambda(type, func):
return False
if type.nullable():
return typeMatchesLambda(type.inner, func)
- if type.isSequence() or type.isMozMap():
+ if type.isSequence() or type.isRecord():
return typeMatchesLambda(type.inner, func)
if type.isUnion():
return any(typeMatchesLambda(t, func) for t in
@@ -6866,20 +6955,21 @@ def getRetvalDeclarationForType(returnType, descriptorProvider,
if nullable:
result = CGTemplatedType("Nullable", result)
return result, "ref", rooter, None, None
- if returnType.isMozMap():
+ if returnType.isRecord():
nullable = returnType.nullable()
if nullable:
returnType = returnType.inner
result, _, _, _, _ = getRetvalDeclarationForType(returnType.inner,
descriptorProvider,
- isMember="MozMap")
+ isMember="Record")
# While we have our inner type, set up our rooter, if needed
if not isMember and typeNeedsRooting(returnType):
- rooter = CGGeneric("MozMapRooter<%s> resultRooter(cx, &result);\n" %
- result.define())
+ rooter = CGGeneric("RecordRooter<%s> resultRooter(cx, &result);\n" %
+ ("nsString, " + result.define()))
else:
rooter = None
- result = CGTemplatedType("MozMap", result)
+ result = CGTemplatedType("Record", [recordKeyDeclType(returnType),
+ result])
if nullable:
result = CGTemplatedType("Nullable", result)
return result, "ref", rooter, None, None
@@ -6976,7 +7066,7 @@ class CGCallGenerator(CGThing):
return True
if a.type.isSequence():
return True
- if a.type.isMozMap():
+ if a.type.isRecord():
return True
# isObject() types are always a JS::Rooted, whether
# nullable or not, and it turns out a const JS::Rooted
@@ -7138,7 +7228,7 @@ class MethodNotNewObjectError(Exception):
# nested sequences we don't use the same variable name to iterate over
# different sequences.
sequenceWrapLevel = 0
-mapWrapLevel = 0
+recordWrapLevel = 0
def wrapTypeIntoCurrentCompartment(type, value, isMember=True):
@@ -7199,29 +7289,27 @@ def wrapTypeIntoCurrentCompartment(type, value, isMember=True):
wrapCode = CGIfWrapper(wrapCode, "!%s.IsNull()" % origValue)
return wrapCode
- if type.isMozMap():
- origValue = value
+ if type.isRecord():
origType = type
if type.nullable():
type = type.inner
- value = "%s.Value()" % value
- global mapWrapLevel
- key = "mapName%d" % mapWrapLevel
- mapWrapLevel += 1
+ recordRef = "%s.Value()" % value
+ else:
+ recordRef = value
+ global recordWrapLevel
+ entryRef = "mapEntry%d" % recordWrapLevel
+ recordWrapLevel += 1
wrapElement = wrapTypeIntoCurrentCompartment(type.inner,
- "%s.Get(%sKeys[%sIndex])" % (value, key, key))
- mapWrapLevel -= 1
+ "%s.mValue" % entryRef)
+ recordWrapLevel -= 1
if not wrapElement:
return None
wrapCode = CGWrapper(CGIndenter(wrapElement),
- pre=("""
- nsTArray<nsString> %sKeys;
- %s.GetKeys(%sKeys);
- for (uint32_t %sIndex = 0; %sIndex < %sKeys.Length(); ++%sIndex) {
- """ % (key, value, key, key, key, key, key)),
+ pre=("for (auto& %s : %s.Entries()) {\n" %
+ (entryRef, recordRef)),
post="}\n")
if origType.nullable():
- wrapCode = CGIfWrapper(wrapCode, "!%s.IsNull()" % origValue)
+ wrapCode = CGIfWrapper(wrapCode, "!%s.IsNull()" % value)
return wrapCode
if type.isDictionary():
@@ -8110,11 +8198,11 @@ class CGMethodCall(CGThing):
if distinguishingType(s).isSequence())
# Now append all the overloads that take a dictionary or callback
- # interface or MozMap. There should be only one of these!
+ # interface or record. There should be only one of these!
genericObjectSigs = [
s for s in possibleSignatures
if (distinguishingType(s).isDictionary() or
- distinguishingType(s).isMozMap() or
+ distinguishingType(s).isRecord() or
distinguishingType(s).isCallbackInterface())]
assert len(genericObjectSigs) <= 1
objectSigs.extend(genericObjectSigs)
@@ -9408,7 +9496,7 @@ class CGMemberJITInfo(CGThing):
return "JSVAL_TYPE_UNDEFINED"
if t.isSequence():
return "JSVAL_TYPE_OBJECT"
- if t.isMozMap():
+ if t.isRecord():
return "JSVAL_TYPE_OBJECT"
if t.isGeckoInterface():
return "JSVAL_TYPE_OBJECT"
@@ -9669,17 +9757,22 @@ def getUnionAccessorSignatureType(type, descriptorProvider):
# Flat member types have already unwrapped nullables.
assert not type.nullable()
- if type.isSequence() or type.isMozMap():
+ if type.isSequence() or type.isRecord():
if type.isSequence():
wrapperType = "Sequence"
else:
- wrapperType = "MozMap"
+ wrapperType = "Record"
# We don't use the returned template here, so it's OK to just pass no
# sourceDescription.
elementInfo = getJSToNativeConversionInfo(type.inner,
descriptorProvider,
isMember=wrapperType)
- return CGTemplatedType(wrapperType, elementInfo.declType,
+ if wrapperType == "Sequence":
+ innerType = elementInfo.declType
+ else:
+ innerType = [recordKeyDeclType(type), elementInfo.declType]
+
+ return CGTemplatedType(wrapperType, innerType,
isConst=True, isReference=True)
# Nested unions are unwrapped automatically into our flatMemberTypes.
@@ -10040,10 +10133,10 @@ class CGUnionStruct(CGThing):
CGCase("e" + vars["name"],
CGGeneric("DoTraceSequence(trc, mValue.m%s.Value());\n" %
vars["name"])))
- elif t.isMozMap():
+ elif t.isRecord():
traceCases.append(
CGCase("e" + vars["name"],
- CGGeneric("TraceMozMap(trc, mValue.m%s.Value());\n" %
+ CGGeneric("TraceRecord(trc, mValue.m%s.Value());\n" %
vars["name"])))
else:
assert t.isSpiderMonkeyInterface()
@@ -13172,8 +13265,8 @@ class CGDictionary(CGThing):
trace = CGGeneric('%s.TraceSelf(trc);\n' % memberData)
if type.nullable():
trace = CGIfWrapper(trace, "!%s.IsNull()" % memberNullable)
- elif type.isMozMap():
- # If you implement this, add a MozMap<object> to
+ elif type.isRecord():
+ # If you implement this, add a record<DOMString, object> to
# TestInterfaceJSDictionary and test it in test_bug1036214.html
# to make sure we end up with the correct security properties.
assert False
@@ -13583,7 +13676,7 @@ class ForwardDeclarationBuilder:
# since we don't know which one we might want
self.addInMozillaDom(CGUnionStruct.unionTypeName(t, False))
self.addInMozillaDom(CGUnionStruct.unionTypeName(t, True))
- elif t.isMozMap():
+ elif t.isRecord():
self.forwardDeclareForType(t.inner, config)
# Don't need to do anything for void, primitive, string, any or object.
# There may be some other cases we are missing.
@@ -14089,9 +14182,9 @@ class CGNativeMember(ClassMethod):
else:
returnCode = "aRetVal.SwapElements(${declName});\n"
return "void", "", returnCode
- if type.isMozMap():
- # If we want to handle MozMap-of-MozMap return values, we're
- # going to need to fix example codegen to not produce MozMap<void>
+ if type.isRecord():
+ # If we want to handle record-of-record return values, we're
+ # going to need to fix example codegen to not produce record<void>
# for the relevant argument...
assert not isMember
# In this case we convert directly into our outparam to start with
@@ -14139,13 +14232,14 @@ class CGNativeMember(ClassMethod):
if nullable:
type = CGTemplatedType("Nullable", type)
args.append(Argument("%s&" % type.define(), "aRetVal"))
- elif returnType.isMozMap():
+ elif returnType.isRecord():
nullable = returnType.nullable()
if nullable:
returnType = returnType.inner
# And now the actual underlying type
elementDecl = self.getReturnType(returnType.inner, True)
- type = CGTemplatedType("MozMap", CGGeneric(elementDecl))
+ type = CGTemplatedType("Record", [recordKeyDeclType(returnType),
+ CGGeneric(elementDecl)])
if nullable:
type = CGTemplatedType("Nullable", type)
args.append(Argument("%s&" % type.define(), "aRetVal"))
@@ -14206,7 +14300,7 @@ class CGNativeMember(ClassMethod):
Nullable as needed.
isMember can be false or one of the strings "Sequence", "Variadic",
- "MozMap"
+ "Record"
"""
if type.isSequence():
nullable = type.nullable()
@@ -14217,13 +14311,13 @@ class CGNativeMember(ClassMethod):
decl = CGTemplatedType("Sequence", argType)
return decl.define(), True, True
- if type.isMozMap():
+ if type.isRecord():
nullable = type.nullable()
if nullable:
type = type.inner
elementType = type.inner
- argType = self.getArgType(elementType, False, "MozMap")[0]
- decl = CGTemplatedType("MozMap", argType)
+ argType = self.getArgType(elementType, False, "Record")[0]
+ decl = CGTemplatedType("Record", [recordKeyDeclType(type), argType])
return decl.define(), True, True
if type.isUnion():
@@ -14994,7 +15088,6 @@ class CGJSImplClass(CGBindingImplClass):
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(${ifaceName})
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mImpl)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(${ifaceName})
NS_IMPL_CYCLE_COLLECTING_ADDREF(${ifaceName})
diff --git a/dom/bindings/Configuration.py b/dom/bindings/Configuration.py
index 5c96580a1..f80c19c33 100644
--- a/dom/bindings/Configuration.py
+++ b/dom/bindings/Configuration.py
@@ -115,7 +115,7 @@ class Configuration(DescriptorProvider):
for (t, _) in getAllTypes(self.descriptors, self.dictionaries, self.callbacks):
while True:
- if t.isMozMap():
+ if t.isRecord():
t = t.inner
elif t.unroll() != t:
t = t.unroll()
diff --git a/dom/bindings/Exceptions.cpp b/dom/bindings/Exceptions.cpp
index a3f807688..8ace37051 100644
--- a/dom/bindings/Exceptions.cpp
+++ b/dom/bindings/Exceptions.cpp
@@ -305,7 +305,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(JSStackFrame)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCaller)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAsyncCaller)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(JSStackFrame)
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mStack)
diff --git a/dom/bindings/MozMap.h b/dom/bindings/MozMap.h
deleted file mode 100644
index 1e920c098..000000000
--- a/dom/bindings/MozMap.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/**
- * Class for representing MozMap arguments. This is an nsTHashtable
- * under the hood, but we don't want to leak that implementation
- * detail.
- */
-
-#ifndef mozilla_dom_MozMap_h
-#define mozilla_dom_MozMap_h
-
-#include "nsTHashtable.h"
-#include "nsHashKeys.h"
-#include "nsStringGlue.h"
-#include "nsTArray.h"
-#include "mozilla/Attributes.h"
-#include "mozilla/Move.h"
-
-namespace mozilla {
-namespace dom {
-
-namespace binding_detail {
-template<typename DataType>
-class MozMapEntry : public nsStringHashKey
-{
-public:
- explicit MozMapEntry(const nsAString* aKeyTypePointer)
- : nsStringHashKey(aKeyTypePointer)
- {
- }
-
- // Move constructor so we can do MozMaps of MozMaps.
- MozMapEntry(MozMapEntry<DataType>&& aOther)
- : nsStringHashKey(aOther),
- mData(Move(aOther.mData))
- {
- }
-
- DataType mData;
-};
-
-} // namespace binding_detail
-
-template<typename DataType>
-class MozMap : protected nsTHashtable<binding_detail::MozMapEntry<DataType>>
-{
-public:
- typedef typename binding_detail::MozMapEntry<DataType> EntryType;
- typedef nsTHashtable<EntryType> Base;
- typedef MozMap<DataType> SelfType;
-
- MozMap()
- {
- }
-
- // Move constructor so we can do MozMap of MozMap.
- MozMap(SelfType&& aOther) :
- Base(Move(aOther))
- {
- }
-
- // The return value is only safe to use until an AddEntry call.
- const DataType& Get(const nsAString& aKey) const
- {
- const EntryType* ent = this->GetEntry(aKey);
- MOZ_ASSERT(ent, "Why are you using a key we didn't claim to have?");
- return ent->mData;
- }
-
- DataType& Get(const nsAString& aKey)
- {
- EntryType* ent = this->GetEntry(aKey);
- MOZ_ASSERT(ent, "Why are you using a key we didn't claim to have?");
- return ent->mData;
- }
-
- // The return value is only safe to use until an AddEntry call.
- const DataType* GetIfExists(const nsAString& aKey) const
- {
- const EntryType* ent = this->GetEntry(aKey);
- if (!ent) {
- return nullptr;
- }
- return &ent->mData;
- }
-
- void GetKeys(nsTArray<nsString>& aKeys) const {
- for (auto iter = this->ConstIter(); !iter.Done(); iter.Next()) {
- aKeys.AppendElement(iter.Get()->GetKey());
- }
- }
-
- // XXXbz we expose this generic enumerator for tracing. Otherwise we'd end up
- // with a dependency on BindingUtils.h here for the SequenceTracer bits.
- typedef void (* Enumerator)(DataType* aValue, void* aClosure);
- void EnumerateValues(Enumerator aEnumerator, void *aClosure)
- {
- for (auto iter = this->Iter(); !iter.Done(); iter.Next()) {
- aEnumerator(&iter.Get()->mData, aClosure);
- }
- }
-
- MOZ_MUST_USE
- DataType* AddEntry(const nsAString& aKey)
- {
- EntryType* ent = this->PutEntry(aKey, fallible);
- if (!ent) {
- return nullptr;
- }
- return &ent->mData;
- }
-};
-
-} // namespace dom
-} // namespace mozilla
-
-#endif // mozilla_dom_MozMap_h
diff --git a/dom/bindings/Record.h b/dom/bindings/Record.h
new file mode 100644
index 000000000..d6ab31699
--- /dev/null
+++ b/dom/bindings/Record.h
@@ -0,0 +1,91 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/**
+ * Class for representing record arguments. Basically an array under the hood.
+ */
+
+#ifndef mozilla_dom_Record_h
+#define mozilla_dom_Record_h
+
+#include "nsTHashtable.h"
+#include "nsHashKeys.h"
+#include "nsStringGlue.h"
+#include "nsTArray.h"
+#include "mozilla/Attributes.h"
+#include "mozilla/Move.h"
+
+namespace mozilla {
+namespace dom {
+
+namespace binding_detail {
+template<typename KeyType, typename ValueType>
+class RecordEntry
+{
+public:
+ RecordEntry()
+ {
+ }
+
+ // Move constructor so we can do Records of Records.
+ RecordEntry(RecordEntry<KeyType, ValueType>&& aOther)
+ : mKey(Move(aOther.mKey)),
+ mValue(Move(aOther.mValue))
+ {
+ }
+
+ KeyType mKey;
+ ValueType mValue;
+};
+
+} // namespace binding_detail
+
+template<typename KeyType, typename ValueType>
+class Record
+{
+public:
+ typedef typename binding_detail::RecordEntry<KeyType, ValueType> EntryType;
+ typedef Record<KeyType, ValueType> SelfType;
+
+ Record()
+ {
+ }
+
+ // Move constructor so we can do Record of Record.
+ Record(SelfType&& aOther) :
+ mEntries(Move(aOther.mEntries))
+ {
+ }
+
+ const nsTArray<EntryType>& Entries() const
+ {
+ return mEntries;
+ }
+
+ nsTArray<EntryType>& Entries()
+ {
+ return mEntries;
+ }
+
+private:
+ nsTArray<EntryType> mEntries;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+template<typename K, typename V>
+class nsDefaultComparator<mozilla::dom::binding_detail::RecordEntry<K, V>, K>
+{
+public:
+ bool Equals(const mozilla::dom::binding_detail::RecordEntry<K, V>& aEntry,
+ const K& aKey) const
+ {
+ return aEntry.mKey == aKey;
+ }
+};
+
+#endif // mozilla_dom_Record_h
diff --git a/dom/bindings/SimpleGlobalObject.cpp b/dom/bindings/SimpleGlobalObject.cpp
index 6ac397019..88710f7d9 100644
--- a/dom/bindings/SimpleGlobalObject.cpp
+++ b/dom/bindings/SimpleGlobalObject.cpp
@@ -29,8 +29,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(SimpleGlobalObject)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(SimpleGlobalObject)
-
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
tmp->TraverseHostObjectURIs(cb);
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
diff --git a/dom/bindings/moz.build b/dom/bindings/moz.build
index f1ce9e276..7e1358e9c 100644
--- a/dom/bindings/moz.build
+++ b/dom/bindings/moz.build
@@ -32,10 +32,10 @@ EXPORTS.mozilla.dom += [
'FakeString.h',
'IterableIterator.h',
'JSSlots.h',
- 'MozMap.h',
'NonRefcountedDOMObject.h',
'Nullable.h',
'PrimitiveConversions.h',
+ 'Record.h',
'RootedDictionary.h',
'SimpleGlobalObject.h',
'StructuredClone.h',
diff --git a/dom/bindings/parser/WebIDL.py b/dom/bindings/parser/WebIDL.py
index f668d7d62..8c32a8738 100644
--- a/dom/bindings/parser/WebIDL.py
+++ b/dom/bindings/parser/WebIDL.py
@@ -1867,7 +1867,7 @@ class IDLDictionary(IDLObjectWithScope):
if (memberType.nullable() or
memberType.isSequence() or
- memberType.isMozMap()):
+ memberType.isRecord()):
return typeContainsDictionary(memberType.inner, dictionary)
if memberType.isDictionary():
@@ -1988,7 +1988,7 @@ class IDLType(IDLObject):
'callback',
'union',
'sequence',
- 'mozmap'
+ 'record'
)
def __init__(self, location, name):
@@ -2038,7 +2038,7 @@ class IDLType(IDLObject):
def isSequence(self):
return False
- def isMozMap(self):
+ def isRecord(self):
return False
def isArrayBuffer(self):
@@ -2263,8 +2263,8 @@ class IDLNullableType(IDLParameterizedType):
def isSequence(self):
return self.inner.isSequence()
- def isMozMap(self):
- return self.inner.isMozMap()
+ def isRecord(self):
+ return self.inner.isRecord()
def isArrayBuffer(self):
return self.inner.isArrayBuffer()
@@ -2321,8 +2321,10 @@ class IDLNullableType(IDLParameterizedType):
return self
def isDistinguishableFrom(self, other):
- if (other.nullable() or (other.isUnion() and other.hasNullableType) or
- other.isDictionary()):
+ if (other.nullable() or
+ other.isDictionary() or
+ (other.isUnion() and
+ (other.hasNullableType or other.hasDictionaryType()))):
# Can't tell which type null should become
return False
return self.inner.isDistinguishableFrom(other)
@@ -2397,34 +2399,38 @@ class IDLSequenceType(IDLParameterizedType):
return (other.isPrimitive() or other.isString() or other.isEnum() or
other.isDate() or other.isInterface() or
other.isDictionary() or
- other.isCallback() or other.isMozMap())
+ other.isCallback() or other.isRecord())
-class IDLMozMapType(IDLParameterizedType):
- def __init__(self, location, parameterType):
- assert not parameterType.isVoid()
+class IDLRecordType(IDLParameterizedType):
+ def __init__(self, location, keyType, valueType):
+ assert keyType.isString()
+ assert keyType.isComplete()
+ assert not valueType.isVoid()
+
+ IDLParameterizedType.__init__(self, location, valueType.name, valueType)
+ self.keyType = keyType
- IDLParameterizedType.__init__(self, location, parameterType.name, parameterType)
# Need to set self.name up front if our inner type is already complete,
# since in that case our .complete() won't be called.
if self.inner.isComplete():
- self.name = self.inner.name + "MozMap"
+ self.name = self.keyType.name + self.inner.name + "Record"
def __eq__(self, other):
- return isinstance(other, IDLMozMapType) and self.inner == other.inner
+ return isinstance(other, IDLRecordType) and self.inner == other.inner
def __str__(self):
- return self.inner.__str__() + "MozMap"
+ return self.keyType.__str__() + self.inner.__str__() + "Record"
- def isMozMap(self):
+ def isRecord(self):
return True
def tag(self):
- return IDLType.Tags.mozmap
+ return IDLType.Tags.record
def complete(self, scope):
self.inner = self.inner.complete(scope)
- self.name = self.inner.name + "MozMap"
+ self.name = self.keyType.name + self.inner.name + "Record"
return self
def unroll(self):
@@ -2614,8 +2620,8 @@ class IDLTypedefType(IDLType):
def isSequence(self):
return self.inner.isSequence()
- def isMozMap(self):
- return self.inner.isMozMap()
+ def isRecord(self):
+ return self.inner.isRecord()
def isDictionary(self):
return self.inner.isDictionary()
@@ -2798,7 +2804,7 @@ class IDLWrapperType(IDLType):
if self.isEnum():
return (other.isPrimitive() or other.isInterface() or other.isObject() or
other.isCallback() or other.isDictionary() or
- other.isSequence() or other.isMozMap() or other.isDate())
+ other.isSequence() or other.isRecord() or other.isDate())
if self.isDictionary() and other.nullable():
return False
if (other.isPrimitive() or other.isString() or other.isEnum() or
@@ -2820,7 +2826,7 @@ class IDLWrapperType(IDLType):
(self.isNonCallbackInterface() or
other.isNonCallbackInterface()))
if (other.isDictionary() or other.isCallback() or
- other.isMozMap()):
+ other.isRecord()):
return self.isNonCallbackInterface()
# Not much else |other| can be
@@ -3030,17 +3036,17 @@ class IDLBuiltinType(IDLType):
return (other.isNumeric() or other.isString() or other.isEnum() or
other.isInterface() or other.isObject() or
other.isCallback() or other.isDictionary() or
- other.isSequence() or other.isMozMap() or other.isDate())
+ other.isSequence() or other.isRecord() or other.isDate())
if self.isNumeric():
return (other.isBoolean() or other.isString() or other.isEnum() or
other.isInterface() or other.isObject() or
other.isCallback() or other.isDictionary() or
- other.isSequence() or other.isMozMap() or other.isDate())
+ other.isSequence() or other.isRecord() or other.isDate())
if self.isString():
return (other.isPrimitive() or other.isInterface() or
other.isObject() or
other.isCallback() or other.isDictionary() or
- other.isSequence() or other.isMozMap() or other.isDate())
+ other.isSequence() or other.isRecord() or other.isDate())
if self.isAny():
# Can't tell "any" apart from anything
return False
@@ -3050,7 +3056,7 @@ class IDLBuiltinType(IDLType):
return (other.isPrimitive() or other.isString() or other.isEnum() or
other.isInterface() or other.isCallback() or
other.isDictionary() or other.isSequence() or
- other.isMozMap())
+ other.isRecord())
if self.isVoid():
return not other.isVoid()
# Not much else we could be!
@@ -3058,7 +3064,7 @@ class IDLBuiltinType(IDLType):
# Like interfaces, but we know we're not a callback
return (other.isPrimitive() or other.isString() or other.isEnum() or
other.isCallback() or other.isDictionary() or
- other.isSequence() or other.isMozMap() or other.isDate() or
+ other.isSequence() or other.isRecord() or other.isDate() or
(other.isInterface() and (
# ArrayBuffer is distinguishable from everything
# that's not an ArrayBuffer or a callback interface
@@ -3843,6 +3849,9 @@ class IDLConst(IDLInterfaceMember):
if type.isDictionary():
raise WebIDLError("A constant cannot be of a dictionary type",
[self.location])
+ if type.isRecord():
+ raise WebIDLError("A constant cannot be of a record type",
+ [self.location])
self.type = type
self.value = value
@@ -3954,8 +3963,8 @@ class IDLAttribute(IDLInterfaceMember):
if self.type.isSequence() and not self.getExtendedAttribute("Cached"):
raise WebIDLError("A non-cached attribute cannot be of a sequence "
"type", [self.location])
- if self.type.isMozMap() and not self.getExtendedAttribute("Cached"):
- raise WebIDLError("A non-cached attribute cannot be of a MozMap "
+ if self.type.isRecord() and not self.getExtendedAttribute("Cached"):
+ raise WebIDLError("A non-cached attribute cannot be of a record "
"type", [self.location])
if self.type.isUnion():
for f in self.type.unroll().flatMemberTypes:
@@ -3971,11 +3980,11 @@ class IDLAttribute(IDLInterfaceMember):
"one of its member types's member "
"types, and so on) is a sequence "
"type", [self.location, f.location])
- if f.isMozMap():
+ if f.isRecord():
raise WebIDLError("An attribute cannot be of a union "
"type if one of its member types (or "
"one of its member types's member "
- "types, and so on) is a MozMap "
+ "types, and so on) is a record "
"type", [self.location, f.location])
if not self.type.isInterface() and self.getExtendedAttribute("PutForwards"):
raise WebIDLError("An attribute with [PutForwards] must have an "
@@ -3989,7 +3998,7 @@ class IDLAttribute(IDLInterfaceMember):
def typeContainsChromeOnlyDictionaryMember(type):
if (type.nullable() or
type.isSequence() or
- type.isMozMap()):
+ type.isRecord()):
return typeContainsChromeOnlyDictionaryMember(type.inner)
if type.isUnion():
@@ -4035,10 +4044,10 @@ class IDLAttribute(IDLInterfaceMember):
[self.location, location])
if self.getExtendedAttribute("Frozen"):
if (not self.type.isSequence() and not self.type.isDictionary() and
- not self.type.isMozMap()):
+ not self.type.isRecord()):
raise WebIDLError("[Frozen] is only allowed on "
"sequence-valued, dictionary-valued, and "
- "MozMap-valued attributes",
+ "record-valued attributes",
[self.location])
if not self.type.unroll().isExposedInAllOf(self.exposureSet):
raise WebIDLError("Attribute returns a type that is not exposed "
@@ -5147,7 +5156,7 @@ class Tokenizer(object):
"Promise": "PROMISE",
"required": "REQUIRED",
"sequence": "SEQUENCE",
- "MozMap": "MOZMAP",
+ "record": "RECORD",
"short": "SHORT",
"unsigned": "UNSIGNED",
"void": "VOID",
@@ -6276,7 +6285,7 @@ class Parser(Tokenizer):
| OCTET
| OPTIONAL
| SEQUENCE
- | MOZMAP
+ | RECORD
| SETTER
| SHORT
| STATIC
@@ -6355,7 +6364,7 @@ class Parser(Tokenizer):
def p_NonAnyType(self, p):
"""
- NonAnyType : PrimitiveOrStringType Null
+ NonAnyType : PrimitiveType Null
| ARRAYBUFFER Null
| SHAREDARRAYBUFFER Null
| OBJECT Null
@@ -6371,6 +6380,12 @@ class Parser(Tokenizer):
p[0] = self.handleNullable(type, p[2])
+ def p_NonAnyTypeStringType(self, p):
+ """
+ NonAnyType : StringType Null
+ """
+ p[0] = self.handleNullable(p[1], p[2])
+
def p_NonAnyTypeSequenceType(self, p):
"""
NonAnyType : SEQUENCE LT Type GT Null
@@ -6391,13 +6406,14 @@ class Parser(Tokenizer):
type = IDLUnresolvedType(self.getLocation(p, 1), promiseIdent, p[3])
p[0] = self.handleNullable(type, p[5])
- def p_NonAnyTypeMozMapType(self, p):
+ def p_NonAnyTypeRecordType(self, p):
"""
- NonAnyType : MOZMAP LT Type GT Null
+ NonAnyType : RECORD LT StringType COMMA Type GT Null
"""
- innerType = p[3]
- type = IDLMozMapType(self.getLocation(p, 1), innerType)
- p[0] = self.handleNullable(type, p[5])
+ keyType = p[3]
+ valueType = p[5]
+ type = IDLRecordType(self.getLocation(p, 1), keyType, valueType)
+ p[0] = self.handleNullable(type, p[7])
def p_NonAnyTypeScopedName(self, p):
"""
@@ -6440,7 +6456,7 @@ class Parser(Tokenizer):
def p_ConstType(self, p):
"""
- ConstType : PrimitiveOrStringType Null
+ ConstType : PrimitiveType Null
"""
type = BuiltinTypes[p[1]]
p[0] = self.handleNullable(type, p[2])
@@ -6454,69 +6470,75 @@ class Parser(Tokenizer):
type = IDLUnresolvedType(self.getLocation(p, 1), identifier)
p[0] = self.handleNullable(type, p[2])
- def p_PrimitiveOrStringTypeUint(self, p):
+ def p_PrimitiveTypeUint(self, p):
"""
- PrimitiveOrStringType : UnsignedIntegerType
+ PrimitiveType : UnsignedIntegerType
"""
p[0] = p[1]
- def p_PrimitiveOrStringTypeBoolean(self, p):
+ def p_PrimitiveTypeBoolean(self, p):
"""
- PrimitiveOrStringType : BOOLEAN
+ PrimitiveType : BOOLEAN
"""
p[0] = IDLBuiltinType.Types.boolean
- def p_PrimitiveOrStringTypeByte(self, p):
+ def p_PrimitiveTypeByte(self, p):
"""
- PrimitiveOrStringType : BYTE
+ PrimitiveType : BYTE
"""
p[0] = IDLBuiltinType.Types.byte
- def p_PrimitiveOrStringTypeOctet(self, p):
+ def p_PrimitiveTypeOctet(self, p):
"""
- PrimitiveOrStringType : OCTET
+ PrimitiveType : OCTET
"""
p[0] = IDLBuiltinType.Types.octet
- def p_PrimitiveOrStringTypeFloat(self, p):
+ def p_PrimitiveTypeFloat(self, p):
"""
- PrimitiveOrStringType : FLOAT
+ PrimitiveType : FLOAT
"""
p[0] = IDLBuiltinType.Types.float
- def p_PrimitiveOrStringTypeUnrestictedFloat(self, p):
+ def p_PrimitiveTypeUnrestictedFloat(self, p):
"""
- PrimitiveOrStringType : UNRESTRICTED FLOAT
+ PrimitiveType : UNRESTRICTED FLOAT
"""
p[0] = IDLBuiltinType.Types.unrestricted_float
- def p_PrimitiveOrStringTypeDouble(self, p):
+ def p_PrimitiveTypeDouble(self, p):
"""
- PrimitiveOrStringType : DOUBLE
+ PrimitiveType : DOUBLE
"""
p[0] = IDLBuiltinType.Types.double
- def p_PrimitiveOrStringTypeUnrestictedDouble(self, p):
+ def p_PrimitiveTypeUnrestictedDouble(self, p):
"""
- PrimitiveOrStringType : UNRESTRICTED DOUBLE
+ PrimitiveType : UNRESTRICTED DOUBLE
"""
p[0] = IDLBuiltinType.Types.unrestricted_double
- def p_PrimitiveOrStringTypeDOMString(self, p):
+ def p_StringType(self, p):
+ """
+ StringType : BuiltinStringType
+ """
+ p[0] = BuiltinTypes[p[1]]
+
+ def p_BuiltinStringTypeDOMString(self, p):
"""
- PrimitiveOrStringType : DOMSTRING
+ BuiltinStringType : DOMSTRING
"""
p[0] = IDLBuiltinType.Types.domstring
- def p_PrimitiveOrStringTypeBytestring(self, p):
+ def p_BuiltinStringTypeBytestring(self, p):
"""
- PrimitiveOrStringType : BYTESTRING
+ BuiltinStringType : BYTESTRING
"""
p[0] = IDLBuiltinType.Types.bytestring
- def p_PrimitiveOrStringTypeUSVString(self, p):
+ def p_BuiltinStringTypeUSVString(self, p):
"""
- PrimitiveOrStringType : USVSTRING
+ BuiltinStringType : USVSTRING
"""
p[0] = IDLBuiltinType.Types.usvstring
diff --git a/dom/browser-element/BrowserElementParent.js b/dom/browser-element/BrowserElementParent.js
index 67d05f0ab..8e4475bfa 100644
--- a/dom/browser-element/BrowserElementParent.js
+++ b/dom/browser-element/BrowserElementParent.js
@@ -23,15 +23,6 @@ function debug(msg) {
//dump("BrowserElementParent - " + msg + "\n");
}
-function getIntPref(prefName, def) {
- try {
- return Services.prefs.getIntPref(prefName);
- }
- catch(err) {
- return def;
- }
-}
-
function handleWindowEvent(e) {
if (this._browserElementParents) {
let beps = ThreadSafeChromeUtils.nondeterministicGetWeakMapKeys(this._browserElementParents);
@@ -856,8 +847,8 @@ BrowserElementParent.prototype = {
*/
zoom: defineNoReturnMethod(function(zoom) {
zoom *= 100;
- zoom = Math.min(getIntPref("zoom.maxPercent", 300), zoom);
- zoom = Math.max(getIntPref("zoom.minPercent", 50), zoom);
+ zoom = Math.min(Services.prefs.getIntPref("zoom.maxPercent", 300), zoom);
+ zoom = Math.max(Services.prefs.getIntPref("zoom.minPercent", 50), zoom);
this._sendAsyncMsg('zoom', {zoom: zoom / 100.0});
}),
diff --git a/dom/canvas/CanvasRenderingContext2D.cpp b/dom/canvas/CanvasRenderingContext2D.cpp
index 18af28e9f..4849fda57 100644
--- a/dom/canvas/CanvasRenderingContext2D.cpp
+++ b/dom/canvas/CanvasRenderingContext2D.cpp
@@ -783,6 +783,15 @@ public:
: mCanvas(aCanvas)
{}
+ void OnShutdown() {
+ if(!mCanvas) {
+ return;
+ }
+
+ mCanvas = nullptr;
+ nsContentUtils::UnregisterShutdownObserver(this);
+ }
+
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
private:
@@ -800,7 +809,7 @@ CanvasShutdownObserver::Observe(nsISupports* aSubject,
{
if (mCanvas && strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0) {
mCanvas->OnShutdown();
- nsContentUtils::UnregisterShutdownObserver(this);
+ OnShutdown();
}
return NS_OK;
@@ -1038,7 +1047,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(CanvasRenderingContext2D)
ImplCycleCollectionTraverse(cb, info.mElement, "Hit region fallback element");
}
}
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(CanvasRenderingContext2D)
@@ -1097,6 +1105,7 @@ CanvasRenderingContext2D::CanvasRenderingContext2D(layers::LayersBackend aCompos
, mIsCapturedFrameInvalid(false)
, mPathTransformWillUpdate(false)
, mInvalidateCount(0)
+ , mWriteOnly(false) // == !origin-clean
{
sNumLivingContexts++;
@@ -1218,7 +1227,7 @@ void
CanvasRenderingContext2D::RemoveShutdownObserver()
{
if (mShutdownObserver) {
- nsContentUtils::UnregisterShutdownObserver(mShutdownObserver);
+ mShutdownObserver->OnShutdown();
mShutdownObserver = nullptr;
}
}
@@ -2554,7 +2563,8 @@ CanvasRenderingContext2D::CreatePattern(const CanvasImageSource& aSource,
// nullptr and set CORSUsed to true for passing the security check in
// CanvasUtils::DoDrawImageSecurityCheck().
RefPtr<CanvasPattern> pat =
- new CanvasPattern(this, srcSurf, repeatMode, nullptr, false, true);
+ new CanvasPattern(this, srcSurf, repeatMode, nullptr,
+ imgBitmap.IsWriteOnly(), true);
return pat.forget();
}
@@ -4944,6 +4954,10 @@ CanvasRenderingContext2D::DrawImage(const CanvasImageSource& aImage,
aError.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return;
}
+
+ if (canvas->IsWriteOnly()) {
+ SetWriteOnly();
+ }
} else if (aImage.IsImageBitmap()) {
ImageBitmap& imageBitmap = aImage.GetAsImageBitmap();
srcSurf = imageBitmap.PrepareForDrawTarget(mTarget);
@@ -4952,6 +4966,10 @@ CanvasRenderingContext2D::DrawImage(const CanvasImageSource& aImage,
return;
}
+ if (imageBitmap.IsWriteOnly()) {
+ SetWriteOnly();
+ }
+
imgSize = gfx::IntSize(imageBitmap.Width(), imageBitmap.Height());
}
else {
@@ -5666,9 +5684,8 @@ CanvasRenderingContext2D::GetImageData(JSContext* aCx, double aSx,
// Check only if we have a canvas element; if we were created with a docshell,
// then it's special internal use.
- if (mCanvasElement && mCanvasElement->IsWriteOnly() &&
- !nsContentUtils::IsCallerChrome())
- {
+ if (IsWriteOnly() ||
+ (mCanvasElement && mCanvasElement->IsWriteOnly() && !nsContentUtils::IsCallerChrome())) {
// XXX ERRMSG we need to report an error to developers here! (bug 329026)
aError.Throw(NS_ERROR_DOM_SECURITY_ERR);
return nullptr;
@@ -6312,6 +6329,13 @@ CanvasRenderingContext2D::ShouldForceInactiveLayer(LayerManager* aManager)
return !aManager->CanUseCanvasLayerForSize(GetSize());
}
+void CanvasRenderingContext2D::SetWriteOnly() {
+ mWriteOnly = true;
+ if (mCanvasElement) {
+ mCanvasElement->SetWriteOnly();
+ }
+}
+
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(CanvasPath, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(CanvasPath, Release)
diff --git a/dom/canvas/CanvasRenderingContext2D.h b/dom/canvas/CanvasRenderingContext2D.h
index 848b3ee08..d4f295a03 100644
--- a/dom/canvas/CanvasRenderingContext2D.h
+++ b/dom/canvas/CanvasRenderingContext2D.h
@@ -40,6 +40,7 @@ class SourceSurface;
namespace dom {
class HTMLImageElementOrSVGImageElementOrHTMLCanvasElementOrHTMLVideoElementOrImageBitmap;
typedef HTMLImageElementOrSVGImageElementOrHTMLCanvasElementOrHTMLVideoElementOrImageBitmap CanvasImageSource;
+class ImageBitmap;
class ImageData;
class StringOrCanvasGradientOrCanvasPattern;
class OwningStringOrCanvasGradientOrCanvasPattern;
@@ -1151,6 +1152,17 @@ protected:
friend struct CanvasBidiProcessor;
friend class CanvasDrawObserver;
+ friend class ImageBitmap;
+
+ // For the origin-clean algorithm (mWriteOnly == !origin-clean)
+ // See https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html
+ void SetWriteOnly();
+
+ bool IsWriteOnly() const {
+ return mWriteOnly;
+ }
+
+ bool mWriteOnly;
};
} // namespace dom
diff --git a/dom/canvas/CanvasRenderingContextHelper.cpp b/dom/canvas/CanvasRenderingContextHelper.cpp
index 3000e59bd..61317fb51 100644
--- a/dom/canvas/CanvasRenderingContextHelper.cpp
+++ b/dom/canvas/CanvasRenderingContextHelper.cpp
@@ -7,7 +7,6 @@
#include "ImageBitmapRenderingContext.h"
#include "ImageEncoder.h"
#include "mozilla/dom/CanvasRenderingContext2D.h"
-#include "mozilla/Telemetry.h"
#include "mozilla/UniquePtr.h"
#include "nsContentUtils.h"
#include "nsDOMJSUtils.h"
@@ -138,13 +137,10 @@ CanvasRenderingContextHelper::CreateContextHelper(CanvasContextType aContextType
break;
case CanvasContextType::Canvas2D:
- Telemetry::Accumulate(Telemetry::CANVAS_2D_USED, 1);
ret = new CanvasRenderingContext2D(aCompositorBackend);
break;
case CanvasContextType::WebGL1:
- Telemetry::Accumulate(Telemetry::CANVAS_WEBGL_USED, 1);
-
ret = WebGL1Context::Create();
if (!ret)
return nullptr;
@@ -152,8 +148,6 @@ CanvasRenderingContextHelper::CreateContextHelper(CanvasContextType aContextType
break;
case CanvasContextType::WebGL2:
- Telemetry::Accumulate(Telemetry::CANVAS_WEBGL_USED, 1);
-
ret = WebGL2Context::Create();
if (!ret)
return nullptr;
@@ -205,16 +199,8 @@ CanvasRenderingContextHelper::GetContext(JSContext* aCx,
// See bug 645792 and bug 1215072.
// We want to throw only if dictionary initialization fails,
// so only in case aRv has been set to some error value.
- if (contextType == CanvasContextType::WebGL1)
- Telemetry::Accumulate(Telemetry::CANVAS_WEBGL_SUCCESS, 0);
- else if (contextType == CanvasContextType::WebGL2)
- Telemetry::Accumulate(Telemetry::CANVAS_WEBGL2_SUCCESS, 0);
return nullptr;
}
- if (contextType == CanvasContextType::WebGL1)
- Telemetry::Accumulate(Telemetry::CANVAS_WEBGL_SUCCESS, 1);
- else if (contextType == CanvasContextType::WebGL2)
- Telemetry::Accumulate(Telemetry::CANVAS_WEBGL2_SUCCESS, 1);
} else {
// We already have a context of some type.
if (contextType != mCurrentContextType)
diff --git a/dom/canvas/ImageBitmap.cpp b/dom/canvas/ImageBitmap.cpp
index e45cdfc6f..6efe1b318 100644
--- a/dom/canvas/ImageBitmap.cpp
+++ b/dom/canvas/ImageBitmap.cpp
@@ -351,29 +351,27 @@ CheckSecurityForHTMLElements(const nsLayoutUtils::SurfaceFromElementResult& aRes
*/
template<class HTMLElementType>
static already_AddRefed<SourceSurface>
-GetSurfaceFromElement(nsIGlobalObject* aGlobal, HTMLElementType& aElement, ErrorResult& aRv)
+GetSurfaceFromElement(nsIGlobalObject* aGlobal, HTMLElementType& aElement,
+ bool* aWriteOnly, ErrorResult& aRv)
{
nsLayoutUtils::SurfaceFromElementResult res =
nsLayoutUtils::SurfaceFromElement(&aElement, nsLayoutUtils::SFE_WANT_FIRST_FRAME);
- // check origin-clean
- if (!CheckSecurityForHTMLElements(res)) {
- aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
- return nullptr;
- }
-
RefPtr<SourceSurface> surface = res.GetSourceSurface();
if (NS_WARN_IF(!surface)) {
- aRv.Throw(NS_ERROR_NOT_AVAILABLE);
+ aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return nullptr;
}
+
+ // Check origin-clean and pass back
+ *aWriteOnly = !CheckSecurityForHTMLElements(res);
return surface.forget();
}
/*
- * The specification doesn't allow to create an ImegeBitmap from a vector image.
+ * The specification doesn't allow to create an ImageBitmap from a vector image.
* This function is used to check if the given HTMLImageElement contains a
* raster image.
*/
@@ -398,7 +396,7 @@ HasRasterImage(HTMLImageElement& aImageEl)
}
ImageBitmap::ImageBitmap(nsIGlobalObject* aGlobal, layers::Image* aData,
- bool aIsPremultipliedAlpha /* = true */)
+ bool aWriteOnly, bool aIsPremultipliedAlpha /* = true */)
: mParent(aGlobal)
, mData(aData)
, mSurface(nullptr)
@@ -406,6 +404,7 @@ ImageBitmap::ImageBitmap(nsIGlobalObject* aGlobal, layers::Image* aData,
, mPictureRect(0, 0, aData->GetSize().width, aData->GetSize().height)
, mIsPremultipliedAlpha(aIsPremultipliedAlpha)
, mIsCroppingAreaOutSideOfSourceImage(false)
+ , mWriteOnly(aWriteOnly)
{
MOZ_ASSERT(aData, "aData is null in ImageBitmap constructor.");
}
@@ -698,6 +697,7 @@ ImageBitmap::ToCloneData() const
RefPtr<SourceSurface> surface = mData->GetAsSourceSurface();
result->mSurface = surface->GetDataSurface();
MOZ_ASSERT(result->mSurface);
+ result->mWriteOnly = mWriteOnly;
return Move(result);
}
@@ -708,7 +708,7 @@ ImageBitmap::CreateFromCloneData(nsIGlobalObject* aGlobal,
{
RefPtr<layers::Image> data = CreateImageFromSurface(aData->mSurface);
- RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data,
+ RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data, aData->mWriteOnly,
aData->mIsPremultipliedAlpha);
ret->mIsCroppingAreaOutSideOfSourceImage =
@@ -724,11 +724,8 @@ ImageBitmap::CreateFromOffscreenCanvas(nsIGlobalObject* aGlobal,
OffscreenCanvas& aOffscreenCanvas,
ErrorResult& aRv)
{
- // Check origin-clean.
- if (aOffscreenCanvas.IsWriteOnly()) {
- aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
- return nullptr;
- }
+ // Check origin-clean
+ bool writeOnly = aOffscreenCanvas.IsWriteOnly();
nsLayoutUtils::SurfaceFromElementResult res =
nsLayoutUtils::SurfaceFromOffscreenCanvas(&aOffscreenCanvas,
@@ -744,7 +741,7 @@ ImageBitmap::CreateFromOffscreenCanvas(nsIGlobalObject* aGlobal,
RefPtr<layers::Image> data =
CreateImageFromSurface(surface);
- RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data);
+ RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data, writeOnly);
return ret.forget();
}
@@ -757,16 +754,19 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, HTMLImageElement& aImageEl
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return nullptr;
}
-
+
// Check if the image element is a bitmap (e.g. it's a vector graphic) or not.
if (!HasRasterImage(aImageEl)) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return nullptr;
}
+ bool writeOnly = true;
+
// Get the SourceSurface out from the image element and then do security
// checking.
- RefPtr<SourceSurface> surface = GetSurfaceFromElement(aGlobal, aImageEl, aRv);
+ RefPtr<SourceSurface> surface = GetSurfaceFromElement(aGlobal, aImageEl,
+ &writeOnly, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
@@ -780,7 +780,7 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, HTMLImageElement& aImageEl
return nullptr;
}
- RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data);
+ RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data, writeOnly);
// Set the picture rectangle.
if (ret && aCropRect.isSome()) {
@@ -812,13 +812,13 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, HTMLVideoElement& aVideoEl
return nullptr;
}
+ bool writeOnly = true;
+
// Check security.
nsCOMPtr<nsIPrincipal> principal = aVideoEl.GetCurrentVideoPrincipal();
bool CORSUsed = aVideoEl.GetCORSMode() != CORS_NONE;
- if (!CheckSecurityForHTMLElements(false, CORSUsed, principal)) {
- aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
- return nullptr;
- }
+
+ writeOnly = !CheckSecurityForHTMLElements(false, CORSUsed, principal);
// Create ImageBitmap.
ImageContainer *container = aVideoEl.GetImageContainer();
@@ -834,7 +834,7 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, HTMLVideoElement& aVideoEl
aRv.Throw(NS_ERROR_NOT_AVAILABLE);
return nullptr;
}
- RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data);
+ RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data, writeOnly);
// Set the picture rectangle.
if (ret && aCropRect.isSome()) {
@@ -856,12 +856,18 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, HTMLCanvasElement& aCanvas
return nullptr;
}
- RefPtr<SourceSurface> surface = GetSurfaceFromElement(aGlobal, aCanvasEl, aRv);
+ bool writeOnly = true;
+
+ RefPtr<SourceSurface> surface = GetSurfaceFromElement(aGlobal, aCanvasEl, &writeOnly, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
+ if (!writeOnly) {
+ writeOnly = aCanvasEl.IsWriteOnly();
+ }
+
// Crop the source surface if needed.
RefPtr<SourceSurface> croppedSurface;
IntRect cropRect = aCropRect.valueOr(IntRect());
@@ -874,8 +880,7 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, HTMLCanvasElement& aCanvas
aCropRect.isSome()) {
// The _surface_ must be a DataSourceSurface.
MOZ_ASSERT(surface->GetType() == SurfaceType::DATA,
- "The snapshot SourceSurface from WebGL rendering contest is not \
- DataSourceSurface.");
+ "The snapshot SourceSurface from WebGL rendering contest is not DataSourceSurface.");
RefPtr<DataSourceSurface> dataSurface = surface->GetDataSurface();
croppedSurface = CropAndCopyDataSourceSurface(dataSurface, cropRect);
cropRect.MoveTo(0, 0);
@@ -897,7 +902,7 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, HTMLCanvasElement& aCanvas
return nullptr;
}
- RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data);
+ RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data, writeOnly);
// Set the picture rectangle.
if (ret && aCropRect.isSome()) {
@@ -958,9 +963,12 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, ImageData& aImageData,
return nullptr;
}
- // Create an ImageBimtap.
+ // Create an ImageBitmap.
// ImageData's underlying data is not alpha-premultiplied.
- RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data, false);
+ RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal,
+ data,
+ false /* write-only */,
+ false /* alpha-premult */);
// The cropping information has been handled in the CreateImageFromRawData()
// function.
@@ -975,11 +983,8 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, ImageData& aImageData,
ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, CanvasRenderingContext2D& aCanvasCtx,
const Maybe<IntRect>& aCropRect, ErrorResult& aRv)
{
- // Check origin-clean.
- if (aCanvasCtx.GetCanvas()->IsWriteOnly()) {
- aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
- return nullptr;
- }
+ // Check origin-clean
+ bool writeOnly = aCanvasCtx.GetCanvas()->IsWriteOnly() || aCanvasCtx.IsWriteOnly();
RefPtr<SourceSurface> surface = aCanvasCtx.GetSurfaceSnapshot();
@@ -1001,7 +1006,7 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, CanvasRenderingContext2D&
return nullptr;
}
- RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data);
+ RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data, writeOnly);
// Set the picture rectangle.
if (ret && aCropRect.isSome()) {
@@ -1024,7 +1029,10 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, ImageBitmap& aImageBitmap,
}
RefPtr<layers::Image> data = aImageBitmap.mData;
- RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data, aImageBitmap.mIsPremultipliedAlpha);
+ RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal,
+ data,
+ aImageBitmap.mWriteOnly,
+ aImageBitmap.mIsPremultipliedAlpha);
// Set the picture rectangle.
if (ret && aCropRect.isSome()) {
@@ -1295,7 +1303,7 @@ private:
}
// Create ImageBitmap object.
- RefPtr<ImageBitmap> imageBitmap = new ImageBitmap(mGlobalObject, data);
+ RefPtr<ImageBitmap> imageBitmap = new ImageBitmap(mGlobalObject, data, false /* write-only */);
// Set mIsCroppingAreaOutSideOfSourceImage.
imageBitmap->SetIsCroppingAreaOutSideOfSourceImage(sourceSize, originalCropRect);
@@ -1391,7 +1399,7 @@ private:
}
// Create ImageBitmap object.
- RefPtr<ImageBitmap> imageBitmap = new ImageBitmap(mGlobalObject, data);
+ RefPtr<ImageBitmap> imageBitmap = new ImageBitmap(mGlobalObject, data, false /* write-only */);
// Set mIsCroppingAreaOutSideOfSourceImage.
imageBitmap->SetIsCroppingAreaOutSideOfSourceImage(sourceSize, originalCropRect);
@@ -1486,14 +1494,19 @@ ImageBitmap::ReadStructuredClone(JSContext* aCx,
uint32_t picRectHeight_;
uint32_t isPremultipliedAlpha_;
uint32_t isCroppingAreaOutSideOfSourceImage_;
+ uint32_t writeOnly;
+ uint32_t dummy;
if (!JS_ReadUint32Pair(aReader, &picRectX_, &picRectY_) ||
!JS_ReadUint32Pair(aReader, &picRectWidth_, &picRectHeight_) ||
!JS_ReadUint32Pair(aReader, &isPremultipliedAlpha_,
- &isCroppingAreaOutSideOfSourceImage_)) {
+ &isCroppingAreaOutSideOfSourceImage_) ||
+ !JS_ReadUint32Pair(aReader, &writeOnly, &dummy)) {
return nullptr;
}
+ MOZ_ASSERT(dummy == 0);
+
int32_t picRectX = BitwiseCast<int32_t>(picRectX_);
int32_t picRectY = BitwiseCast<int32_t>(picRectY_);
int32_t picRectWidth = BitwiseCast<int32_t>(picRectWidth_);
@@ -1512,7 +1525,7 @@ ImageBitmap::ReadStructuredClone(JSContext* aCx,
{
RefPtr<layers::Image> img = CreateImageFromSurface(aClonedSurfaces[aIndex]);
RefPtr<ImageBitmap> imageBitmap =
- new ImageBitmap(aParent, img, isPremultipliedAlpha_);
+ new ImageBitmap(aParent, img, !!writeOnly, isPremultipliedAlpha_);
imageBitmap->mIsCroppingAreaOutSideOfSourceImage =
isCroppingAreaOutSideOfSourceImage_;
@@ -1547,6 +1560,7 @@ ImageBitmap::WriteStructuredClone(JSStructuredCloneWriter* aWriter,
const uint32_t picRectHeight = BitwiseCast<uint32_t>(aImageBitmap->mPictureRect.height);
const uint32_t isPremultipliedAlpha = aImageBitmap->mIsPremultipliedAlpha ? 1 : 0;
const uint32_t isCroppingAreaOutSideOfSourceImage = aImageBitmap->mIsCroppingAreaOutSideOfSourceImage ? 1 : 0;
+ const uint32_t isWriteOnly = aImageBitmap->mWriteOnly ? 1 : 0;
// Indexing the cloned surfaces and send the index to the receiver.
uint32_t index = aClonedSurfaces.Length();
@@ -1555,7 +1569,8 @@ ImageBitmap::WriteStructuredClone(JSStructuredCloneWriter* aWriter,
NS_WARN_IF(!JS_WriteUint32Pair(aWriter, picRectX, picRectY)) ||
NS_WARN_IF(!JS_WriteUint32Pair(aWriter, picRectWidth, picRectHeight)) ||
NS_WARN_IF(!JS_WriteUint32Pair(aWriter, isPremultipliedAlpha,
- isCroppingAreaOutSideOfSourceImage))) {
+ isCroppingAreaOutSideOfSourceImage)) ||
+ NS_WARN_IF(!JS_WriteUint32Pair(aWriter, isWriteOnly, 0))) {
return false;
}
diff --git a/dom/canvas/ImageBitmap.h b/dom/canvas/ImageBitmap.h
index 2119c6bda..25084b6ac 100644
--- a/dom/canvas/ImageBitmap.h
+++ b/dom/canvas/ImageBitmap.h
@@ -65,6 +65,7 @@ struct ImageBitmapCloneData final
gfx::IntRect mPictureRect;
bool mIsPremultipliedAlpha;
bool mIsCroppingAreaOutSideOfSourceImage;
+ bool mWriteOnly;
};
/*
@@ -161,6 +162,10 @@ public:
template<typename T>
friend class MapDataIntoBufferSource;
+ bool IsWriteOnly() const {
+ return mWriteOnly;
+ }
+
// Mozilla Extensions
ImageBitmapFormat
FindOptimalFormat(const Optional<Sequence<ImageBitmapFormat>>& aPossibleFormats,
@@ -197,6 +202,7 @@ protected:
* CreateInternal(from ImageData) method.
*/
ImageBitmap(nsIGlobalObject* aGlobal, layers::Image* aData,
+ bool aWriteOnly,
bool aIsPremultipliedAlpha = true);
virtual ~ImageBitmap();
@@ -280,6 +286,12 @@ protected:
*/
bool mIsCroppingAreaOutSideOfSourceImage;
+ /*
+ * Write-Only flag is set to true if this image has been generated from a
+ * cross-origin source. This is the opposite of what is called 'origin-clean'
+ * in the spec.
+ */
+ bool mWriteOnly;
};
} // namespace dom
diff --git a/dom/canvas/ImageBitmapRenderingContext.cpp b/dom/canvas/ImageBitmapRenderingContext.cpp
index 8f5074554..ad313906a 100644
--- a/dom/canvas/ImageBitmapRenderingContext.cpp
+++ b/dom/canvas/ImageBitmapRenderingContext.cpp
@@ -63,6 +63,11 @@ ImageBitmapRenderingContext::TransferFromImageBitmap(ImageBitmap& aImageBitmap)
if (!mImage) {
return;
}
+
+ // Check if ImageBitmap is tainted, and if so flag the canvas tainted too.
+ if (aImageBitmap.IsWriteOnly() && mCanvasElement) {
+ mCanvasElement->SetWriteOnly();
+ }
Redraw(gfxRect(0, 0, mWidth, mHeight));
}
diff --git a/dom/canvas/ImageData.cpp b/dom/canvas/ImageData.cpp
index b201fa279..d24fbca95 100644
--- a/dom/canvas/ImageData.cpp
+++ b/dom/canvas/ImageData.cpp
@@ -29,7 +29,6 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(ImageData)
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(ImageData)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ImageData)
diff --git a/dom/canvas/WebGL1Context.cpp b/dom/canvas/WebGL1Context.cpp
index c1818a3f9..e82cafbe5 100644
--- a/dom/canvas/WebGL1Context.cpp
+++ b/dom/canvas/WebGL1Context.cpp
@@ -6,7 +6,6 @@
#include "WebGL1Context.h"
#include "mozilla/dom/WebGLRenderingContextBinding.h"
-#include "mozilla/Telemetry.h"
#include "WebGLFormats.h"
namespace mozilla {
@@ -43,8 +42,6 @@ WebGL1Context::WrapObject(JSContext* cx, JS::Handle<JSObject*> givenProto)
nsresult
NS_NewCanvasRenderingContextWebGL(nsIDOMWebGLRenderingContext** out_result)
{
- mozilla::Telemetry::Accumulate(mozilla::Telemetry::CANVAS_WEBGL_USED, 1);
-
nsIDOMWebGLRenderingContext* ctx = mozilla::WebGL1Context::Create();
NS_ADDREF(*out_result = ctx);
diff --git a/dom/canvas/WebGLContext.cpp b/dom/canvas/WebGLContext.cpp
index 32eed6354..e2e05e5fd 100644
--- a/dom/canvas/WebGLContext.cpp
+++ b/dom/canvas/WebGLContext.cpp
@@ -47,7 +47,6 @@
#include "nsSVGEffects.h"
#include "prenv.h"
#include "ScopedGLHelpers.h"
-#include "VRManagerChild.h"
#include "mozilla/layers/TextureClientSharedSurface.h"
// Local
@@ -825,10 +824,6 @@ NS_IMETHODIMP
WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight)
{
if (signedWidth < 0 || signedHeight < 0) {
- if (!gl) {
- Telemetry::Accumulate(Telemetry::CANVAS_WEBGL_FAILURE_ID,
- NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBGL_SIZE"));
- }
GenerateWarning("Canvas size is too large (seems like a negative value wrapped)");
return NS_ERROR_OUT_OF_MEMORY;
}
@@ -884,12 +879,6 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight)
return NS_OK;
}
- nsCString failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBGL_UNKOWN");
- auto autoTelemetry = mozilla::MakeScopeExit([&] {
- Telemetry::Accumulate(Telemetry::CANVAS_WEBGL_FAILURE_ID,
- failureId);
- });
-
// End of early return cases.
// At this point we know that we're not just resizing an existing context,
// we are initializing a new context.
@@ -911,7 +900,6 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight)
// resource handles created from older context generations.
if (!(mGeneration + 1).isValid()) {
// exit without changing the value of mGeneration
- failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBGL_TOO_MANY");
const nsLiteralCString text("Too many WebGL contexts created this run.");
ThrowEvent_WebGLContextCreationError(text);
return NS_ERROR_FAILURE;
@@ -928,11 +916,6 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight)
disabled |= gfxPlatform::InSafeMode();
if (disabled) {
- if (gfxPlatform::InSafeMode()) {
- failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBGL_SAFEMODE");
- } else {
- failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBGL_DISABLED");
- }
const nsLiteralCString text("WebGL is currently disabled.");
ThrowEvent_WebGLContextCreationError(text);
return NS_ERROR_FAILURE;
@@ -945,7 +928,6 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight)
if (mOptions.failIfMajorPerformanceCaveat) {
nsCOMPtr<nsIGfxInfo> gfxInfo = services::GetGfxInfo();
if (!HasAcceleratedLayers(gfxInfo)) {
- failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBGL_PERF_CAVEAT");
const nsLiteralCString text("failIfMajorPerformanceCaveat: Compositor is not"
" hardware-accelerated.");
ThrowEvent_WebGLContextCreationError(text);
@@ -961,12 +943,9 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight)
if (!CreateAndInitGL(forceEnabled, &failReasons)) {
nsCString text("WebGL creation failed: ");
for (const auto& cur : failReasons) {
- Telemetry::Accumulate(Telemetry::CANVAS_WEBGL_FAILURE_ID, cur.key);
-
text.AppendASCII("\n* ");
text.Append(cur.info);
}
- failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_REASON");
ThrowEvent_WebGLContextCreationError(text);
return NS_ERROR_FAILURE;
}
@@ -978,7 +957,6 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight)
DestroyResourcesAndContext();
MOZ_ASSERT(!gl);
- failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBGL_PERF_WARP");
const nsLiteralCString text("failIfMajorPerformanceCaveat: Driver is not"
" hardware-accelerated.");
ThrowEvent_WebGLContextCreationError(text);
@@ -992,7 +970,6 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight)
DestroyResourcesAndContext();
MOZ_ASSERT(!gl);
- failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBGL_DXGL_INTEROP2");
const nsLiteralCString text("Caveat: WGL without DXGLInterop2.");
ThrowEvent_WebGLContextCreationError(text);
return NS_ERROR_FAILURE;
@@ -1001,7 +978,6 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight)
}
if (!ResizeBackbuffer(width, height)) {
- failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBGL_BACKBUFFER");
const nsLiteralCString text("Initializing WebGL backbuffer failed.");
ThrowEvent_WebGLContextCreationError(text);
return NS_ERROR_FAILURE;
@@ -1085,7 +1061,6 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight)
//////
- failureId = NS_LITERAL_CSTRING("SUCCESS");
return NS_OK;
}
@@ -2263,84 +2238,6 @@ WebGLContext::GetUnpackSize(bool isFunc3D, uint32_t width, uint32_t height,
return totalBytes;
}
-already_AddRefed<layers::SharedSurfaceTextureClient>
-WebGLContext::GetVRFrame()
-{
- if (!mLayerIsMirror) {
- /**
- * Do not allow VR frame submission until a mirroring canvas layer has
- * been returned by GetCanvasLayer
- */
- return nullptr;
- }
-
- VRManagerChild* vrmc = VRManagerChild::Get();
- if (!vrmc) {
- return nullptr;
- }
-
- /**
- * Swap buffers as though composition has occurred.
- * We will then share the resulting front buffer to be submitted to the VR
- * compositor.
- */
- BeginComposition();
- EndComposition();
-
- gl::GLScreenBuffer* screen = gl->Screen();
- if (!screen) {
- return nullptr;
- }
-
- RefPtr<SharedSurfaceTextureClient> sharedSurface = screen->Front();
- if (!sharedSurface) {
- return nullptr;
- }
-
- if (sharedSurface && sharedSurface->GetAllocator() != vrmc) {
- RefPtr<SharedSurfaceTextureClient> dest =
- screen->Factory()->NewTexClient(sharedSurface->GetSize());
- if (!dest) {
- return nullptr;
- }
- gl::SharedSurface* destSurf = dest->Surf();
- destSurf->ProducerAcquire();
- SharedSurface::ProdCopy(sharedSurface->Surf(), dest->Surf(),
- screen->Factory());
- destSurf->ProducerRelease();
-
- return dest.forget();
- }
-
- return sharedSurface.forget();
-}
-
-bool
-WebGLContext::StartVRPresentation()
-{
- VRManagerChild* vrmc = VRManagerChild::Get();
- if (!vrmc) {
- return false;
- }
- gl::GLScreenBuffer* screen = gl->Screen();
- if (!screen) {
- return false;
- }
- gl::SurfaceCaps caps = screen->mCaps;
-
- UniquePtr<gl::SurfaceFactory> factory =
- gl::GLScreenBuffer::CreateFactory(gl,
- caps,
- vrmc,
- vrmc->GetBackendType(),
- TextureFlags::ORIGIN_BOTTOM_LEFT);
-
- if (factory) {
- screen->Morph(Move(factory));
- }
- return true;
-}
-
////////////////////////////////////////////////////////////////////////////////
static inline size_t
diff --git a/dom/canvas/WebGLContext.h b/dom/canvas/WebGLContext.h
index b4d416a33..8a20237ff 100644
--- a/dom/canvas/WebGLContext.h
+++ b/dom/canvas/WebGLContext.h
@@ -275,8 +275,9 @@ struct TexImageSourceAdapter final : public TexImageSource
mPboOffset = pboOffset;
}
- TexImageSourceAdapter(const dom::ImageBitmap* imageBitmap, ErrorResult*) {
+ TexImageSourceAdapter(const dom::ImageBitmap* imageBitmap, ErrorResult* out_error) {
mImageBitmap = imageBitmap;
+ mOut_error = out_error;
}
TexImageSourceAdapter(const dom::ImageData* imageData, ErrorResult*) {
@@ -656,9 +657,6 @@ public:
void PixelStorei(GLenum pname, GLint param);
void PolygonOffset(GLfloat factor, GLfloat units);
- already_AddRefed<layers::SharedSurfaceTextureClient> GetVRFrame();
- bool StartVRPresentation();
-
////
webgl::PackingInfo
diff --git a/dom/canvas/WebGLTextureUpload.cpp b/dom/canvas/WebGLTextureUpload.cpp
index 612d5889d..3839b5d5e 100644
--- a/dom/canvas/WebGLTextureUpload.cpp
+++ b/dom/canvas/WebGLTextureUpload.cpp
@@ -12,6 +12,7 @@
#include "GLBlitHelper.h"
#include "GLContext.h"
#include "mozilla/gfx/2D.h"
+#include "mozilla/dom/HTMLCanvasElement.h"
#include "mozilla/dom/HTMLVideoElement.h"
#include "mozilla/dom/ImageBitmap.h"
#include "mozilla/dom/ImageData.h"
@@ -214,9 +215,18 @@ FromPboOffset(WebGLContext* webgl, const char* funcName, TexImageTarget target,
static UniquePtr<webgl::TexUnpackBlob>
FromImageBitmap(WebGLContext* webgl, const char* funcName, TexImageTarget target,
uint32_t width, uint32_t height, uint32_t depth,
- const dom::ImageBitmap& imageBitmap)
+ const dom::ImageBitmap& imageBitmap, ErrorResult* aRv)
{
+ if (imageBitmap.IsWriteOnly()) {
+ aRv->Throw(NS_ERROR_DOM_SECURITY_ERR);
+ return nullptr;
+ }
+
UniquePtr<dom::ImageBitmapCloneData> cloneData = Move(imageBitmap.ToCloneData());
+ if (!cloneData) {
+ return nullptr;
+ }
+
const RefPtr<gfx::DataSourceSurface> surf = cloneData->mSurface;
////
@@ -293,6 +303,14 @@ WebGLContext::FromDomElem(const char* funcName, TexImageTarget target, uint32_t
uint32_t height, uint32_t depth, const dom::Element& elem,
ErrorResult* const out_error)
{
+ if (elem.IsHTMLElement(nsGkAtoms::canvas)) {
+ const dom::HTMLCanvasElement* canvas = static_cast<const dom::HTMLCanvasElement*>(&elem);
+ if (canvas->IsWriteOnly()) {
+ out_error->Throw(NS_ERROR_DOM_SECURITY_ERR);
+ return nullptr;
+ }
+ }
+
uint32_t flags = nsLayoutUtils::SFE_WANT_IMAGE_SURFACE |
nsLayoutUtils::SFE_USE_ELEMENT_SIZE_IF_VECTOR;
@@ -412,7 +430,7 @@ WebGLContext::From(const char* funcName, TexImageTarget target, GLsizei rawWidth
if (src.mImageBitmap) {
return FromImageBitmap(this, funcName, target, width, height, depth,
- *(src.mImageBitmap));
+ *(src.mImageBitmap), src.mOut_error);
}
if (src.mImageData) {
diff --git a/dom/canvas/test/test_imagebitmap.html b/dom/canvas/test/test_imagebitmap.html
index b3d3c08ad..3b74970ac 100644
--- a/dom/canvas/test/test_imagebitmap.html
+++ b/dom/canvas/test/test_imagebitmap.html
@@ -270,13 +270,22 @@ function testSecurityErrors() {
}
function checkPromiseFailedWithSecurityError(p) {
- return p.then( function(reason) { ok(false, "Did not get SecurityError with unclean source. ImageBitmap was created successfully."); },
- function(reason) { if (reason == "SecurityError: The operation is insecure.") {
- ok(true, reason);
- }
- else {
- ok(false, "Did not get SecurityError with unclean source. Error Message: " + reason);
- }});
+ return p.then(imageBitmap => {
+ ok(!!imageBitmap, "ImageBitmaps are always created");
+ const context = document.createElement("canvas").getContext("2d");
+ context.drawImage(imageBitmap, 0, 0);
+ try {
+ context.getImageData(0, 0, 1, 1);
+ ok(false, "Did not get SecurityError with unclean source. ImageBitmap was created successfully.");
+ } catch (ex) {
+ if (ex == "SecurityError: The operation is insecure.") {
+ ok(true, ex);
+ }
+ else {
+ ok(false, "Did not get SecurityError with unclean source. Error Message: " + ex);
+ }
+ }
+ });
}
return Promise.all([
diff --git a/dom/console/Console.cpp b/dom/console/Console.cpp
index ff5a92167..b174172e0 100755
--- a/dom/console/Console.cpp
+++ b/dom/console/Console.cpp
@@ -797,7 +797,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Console)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindow)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mConsoleEventNotifier)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(Console)
diff --git a/dom/crypto/WebCryptoTask.cpp b/dom/crypto/WebCryptoTask.cpp
index f5fc7b5bc..e5f5882e9 100644
--- a/dom/crypto/WebCryptoTask.cpp
+++ b/dom/crypto/WebCryptoTask.cpp
@@ -452,7 +452,6 @@ void
WebCryptoTask::FailWithError(nsresult aRv)
{
MOZ_ASSERT(IsOnOriginalThread());
- Telemetry::Accumulate(Telemetry::WEBCRYPTO_RESOLVED, false);
// Blindly convert nsresult to DOMException
// Individual tasks must ensure they pass the right values
@@ -491,7 +490,6 @@ WebCryptoTask::CallCallback(nsresult rv)
}
Resolve();
- Telemetry::Accumulate(Telemetry::WEBCRYPTO_RESOLVED, true);
// Manually release mResultPromise while we're on the main thread
mResultPromise = nullptr;
@@ -586,7 +584,7 @@ public:
mMechanism = CKM_AES_CBC_PAD;
telemetryAlg = TA_AES_CBC;
- AesCbcParams params;
+ RootedDictionary<AesCbcParams> params(aCx);
nsresult rv = Coerce(aCx, params, aAlgorithm);
if (NS_FAILED(rv)) {
mEarlyRv = NS_ERROR_DOM_INVALID_ACCESS_ERR;
@@ -603,7 +601,7 @@ public:
mMechanism = CKM_AES_CTR;
telemetryAlg = TA_AES_CTR;
- AesCtrParams params;
+ RootedDictionary<AesCtrParams> params(aCx);
nsresult rv = Coerce(aCx, params, aAlgorithm);
if (NS_FAILED(rv)) {
mEarlyRv = NS_ERROR_DOM_SYNTAX_ERR;
@@ -622,7 +620,7 @@ public:
mMechanism = CKM_AES_GCM;
telemetryAlg = TA_AES_GCM;
- AesGcmParams params;
+ RootedDictionary<AesGcmParams> params(aCx);
nsresult rv = Coerce(aCx, params, aAlgorithm);
if (NS_FAILED(rv)) {
mEarlyRv = NS_ERROR_DOM_SYNTAX_ERR;
@@ -650,7 +648,6 @@ public:
mEarlyRv = NS_ERROR_DOM_NOT_SUPPORTED_ERR;
return;
}
- Telemetry::Accumulate(Telemetry::WEBCRYPTO_ALG, telemetryAlg);
}
private:
@@ -794,7 +791,6 @@ public:
return;
}
- Telemetry::Accumulate(Telemetry::WEBCRYPTO_ALG, TA_AES_KW);
}
private:
@@ -908,8 +904,6 @@ public:
void Init(JSContext* aCx, const ObjectOrString& aAlgorithm,
CryptoKey& aKey, bool aEncrypt)
{
- Telemetry::Accumulate(Telemetry::WEBCRYPTO_ALG, TA_RSA_OAEP);
-
CHECK_KEY_ALGORITHM(aKey.Algorithm(), WEBCRYPTO_ALG_RSA_OAEP);
if (mEncrypt) {
@@ -1049,7 +1043,6 @@ public:
case CKM_SHA512_HMAC: telemetryAlg = TA_HMAC_SHA_512; break;
default: telemetryAlg = TA_UNKNOWN;
}
- Telemetry::Accumulate(Telemetry::WEBCRYPTO_ALG, telemetryAlg);
}
private:
@@ -1158,12 +1151,10 @@ public:
if (algName.EqualsLiteral(WEBCRYPTO_ALG_RSASSA_PKCS1)) {
mAlgorithm = Algorithm::RSA_PKCS1;
- Telemetry::Accumulate(Telemetry::WEBCRYPTO_ALG, TA_RSASSA_PKCS1);
CHECK_KEY_ALGORITHM(aKey.Algorithm(), WEBCRYPTO_ALG_RSASSA_PKCS1);
hashAlgName = aKey.Algorithm().mRsa.mHash.mName;
} else if (algName.EqualsLiteral(WEBCRYPTO_ALG_RSA_PSS)) {
mAlgorithm = Algorithm::RSA_PSS;
- Telemetry::Accumulate(Telemetry::WEBCRYPTO_ALG, TA_RSA_PSS);
CHECK_KEY_ALGORITHM(aKey.Algorithm(), WEBCRYPTO_ALG_RSA_PSS);
KeyAlgorithm& hashAlg = aKey.Algorithm().mRsa.mHash;
@@ -1188,7 +1179,6 @@ public:
mSaltLength = params.mSaltLength;
} else if (algName.EqualsLiteral(WEBCRYPTO_ALG_ECDSA)) {
mAlgorithm = Algorithm::ECDSA;
- Telemetry::Accumulate(Telemetry::WEBCRYPTO_ALG, TA_ECDSA);
CHECK_KEY_ALGORITHM(aKey.Algorithm(), WEBCRYPTO_ALG_ECDSA);
// For ECDSA, the hash name comes from the algorithm parameter
@@ -1356,7 +1346,6 @@ public:
mEarlyRv = NS_ERROR_DOM_SYNTAX_ERR;
return;
}
- Telemetry::Accumulate(Telemetry::WEBCRYPTO_ALG, telemetryAlg);
mOidTag = MapHashAlgorithmNameToOID(algName);
}
@@ -2656,7 +2645,6 @@ public:
void Init(JSContext* aCx, const ObjectOrString& aAlgorithm, CryptoKey& aKey,
uint32_t aLength)
{
- Telemetry::Accumulate(Telemetry::WEBCRYPTO_ALG, TA_HKDF);
CHECK_KEY_ALGORITHM(aKey.Algorithm(), WEBCRYPTO_ALG_HKDF);
// Check that we have a key.
@@ -2806,7 +2794,6 @@ public:
void Init(JSContext* aCx, const ObjectOrString& aAlgorithm, CryptoKey& aKey,
uint32_t aLength)
{
- Telemetry::Accumulate(Telemetry::WEBCRYPTO_ALG, TA_PBKDF2);
CHECK_KEY_ALGORITHM(aKey.Algorithm(), WEBCRYPTO_ALG_PBKDF2);
// Check that we got a symmetric key
@@ -2981,7 +2968,6 @@ public:
void Init(JSContext* aCx, const ObjectOrString& aAlgorithm, CryptoKey& aKey)
{
- Telemetry::Accumulate(Telemetry::WEBCRYPTO_ALG, TA_ECDH);
CHECK_KEY_ALGORITHM(aKey.Algorithm(), WEBCRYPTO_ALG_ECDH);
// Check that we have a private key.
@@ -3277,10 +3263,6 @@ WebCryptoTask::CreateEncryptDecryptTask(JSContext* aCx,
const CryptoOperationData& aData,
bool aEncrypt)
{
- TelemetryMethod method = (aEncrypt)? TM_ENCRYPT : TM_DECRYPT;
- Telemetry::Accumulate(Telemetry::WEBCRYPTO_METHOD, method);
- Telemetry::Accumulate(Telemetry::WEBCRYPTO_EXTRACTABLE_ENC, aKey.Extractable());
-
// Ensure key is usable for this operation
if ((aEncrypt && !aKey.HasUsage(CryptoKey::ENCRYPT)) ||
(!aEncrypt && !aKey.HasUsage(CryptoKey::DECRYPT))) {
@@ -3312,10 +3294,6 @@ WebCryptoTask::CreateSignVerifyTask(JSContext* aCx,
const CryptoOperationData& aData,
bool aSign)
{
- TelemetryMethod method = (aSign)? TM_SIGN : TM_VERIFY;
- Telemetry::Accumulate(Telemetry::WEBCRYPTO_METHOD, method);
- Telemetry::Accumulate(Telemetry::WEBCRYPTO_EXTRACTABLE_SIG, aKey.Extractable());
-
// Ensure key is usable for this operation
if ((aSign && !aKey.HasUsage(CryptoKey::SIGN)) ||
(!aSign && !aKey.HasUsage(CryptoKey::VERIFY))) {
@@ -3345,8 +3323,6 @@ WebCryptoTask::CreateDigestTask(JSContext* aCx,
const ObjectOrString& aAlgorithm,
const CryptoOperationData& aData)
{
- Telemetry::Accumulate(Telemetry::WEBCRYPTO_METHOD, TM_DIGEST);
-
nsString algName;
nsresult rv = GetAlgorithmName(aCx, aAlgorithm, algName);
if (NS_FAILED(rv)) {
@@ -3372,9 +3348,6 @@ WebCryptoTask::CreateImportKeyTask(nsIGlobalObject* aGlobal,
bool aExtractable,
const Sequence<nsString>& aKeyUsages)
{
- Telemetry::Accumulate(Telemetry::WEBCRYPTO_METHOD, TM_IMPORTKEY);
- Telemetry::Accumulate(Telemetry::WEBCRYPTO_EXTRACTABLE_IMPORT, aExtractable);
-
// Verify that the format is recognized
if (!aFormat.EqualsLiteral(WEBCRYPTO_KEY_FORMAT_RAW) &&
!aFormat.EqualsLiteral(WEBCRYPTO_KEY_FORMAT_SPKI) &&
@@ -3426,8 +3399,6 @@ WebCryptoTask*
WebCryptoTask::CreateExportKeyTask(const nsAString& aFormat,
CryptoKey& aKey)
{
- Telemetry::Accumulate(Telemetry::WEBCRYPTO_METHOD, TM_EXPORTKEY);
-
// Verify that the format is recognized
if (!aFormat.EqualsLiteral(WEBCRYPTO_KEY_FORMAT_RAW) &&
!aFormat.EqualsLiteral(WEBCRYPTO_KEY_FORMAT_SPKI) &&
@@ -3470,9 +3441,6 @@ WebCryptoTask::CreateGenerateKeyTask(nsIGlobalObject* aGlobal,
bool aExtractable,
const Sequence<nsString>& aKeyUsages)
{
- Telemetry::Accumulate(Telemetry::WEBCRYPTO_METHOD, TM_GENERATEKEY);
- Telemetry::Accumulate(Telemetry::WEBCRYPTO_EXTRACTABLE_GENERATE, aExtractable);
-
// Verify that aKeyUsages does not contain an unrecognized value
// SPEC-BUG: Spec says that this should be InvalidAccessError, but that
// is inconsistent with other analogous points in the spec
@@ -3515,8 +3483,6 @@ WebCryptoTask::CreateDeriveKeyTask(nsIGlobalObject* aGlobal,
bool aExtractable,
const Sequence<nsString>& aKeyUsages)
{
- Telemetry::Accumulate(Telemetry::WEBCRYPTO_METHOD, TM_DERIVEKEY);
-
// Ensure baseKey is usable for this operation
if (!aBaseKey.HasUsage(CryptoKey::DERIVEKEY)) {
return new FailureTask(NS_ERROR_DOM_INVALID_ACCESS_ERR);
@@ -3560,8 +3526,6 @@ WebCryptoTask::CreateDeriveBitsTask(JSContext* aCx,
CryptoKey& aKey,
uint32_t aLength)
{
- Telemetry::Accumulate(Telemetry::WEBCRYPTO_METHOD, TM_DERIVEBITS);
-
// Ensure baseKey is usable for this operation
if (!aKey.HasUsage(CryptoKey::DERIVEBITS)) {
return new FailureTask(NS_ERROR_DOM_INVALID_ACCESS_ERR);
@@ -3599,8 +3563,6 @@ WebCryptoTask::CreateWrapKeyTask(JSContext* aCx,
CryptoKey& aWrappingKey,
const ObjectOrString& aWrapAlgorithm)
{
- Telemetry::Accumulate(Telemetry::WEBCRYPTO_METHOD, TM_WRAPKEY);
-
// Verify that the format is recognized
if (!aFormat.EqualsLiteral(WEBCRYPTO_KEY_FORMAT_RAW) &&
!aFormat.EqualsLiteral(WEBCRYPTO_KEY_FORMAT_SPKI) &&
@@ -3652,8 +3614,6 @@ WebCryptoTask::CreateUnwrapKeyTask(nsIGlobalObject* aGlobal,
bool aExtractable,
const Sequence<nsString>& aKeyUsages)
{
- Telemetry::Accumulate(Telemetry::WEBCRYPTO_METHOD, TM_UNWRAPKEY);
-
// Ensure key is usable for this operation
if (!aUnwrappingKey.HasUsage(CryptoKey::UNWRAPKEY)) {
return new FailureTask(NS_ERROR_DOM_INVALID_ACCESS_ERR);
diff --git a/dom/events/DOMEventTargetHelper.cpp b/dom/events/DOMEventTargetHelper.cpp
index f8a5227d6..dd9a01d8d 100644
--- a/dom/events/DOMEventTargetHelper.cpp
+++ b/dom/events/DOMEventTargetHelper.cpp
@@ -43,7 +43,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_DESCRIBE(DOMEventTargetHelper, tmp->mRefCnt.get())
}
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mListenerManager)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
diff --git a/dom/events/DataTransfer.cpp b/dom/events/DataTransfer.cpp
index 45c72e662..40a0f42e6 100644
--- a/dom/events/DataTransfer.cpp
+++ b/dom/events/DataTransfer.cpp
@@ -57,7 +57,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(DataTransfer)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mItems)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDragTarget)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDragImage)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(DataTransfer)
diff --git a/dom/events/Event.cpp b/dom/events/Event.cpp
index f33bfa5a8..280e40ad5 100755
--- a/dom/events/Event.cpp
+++ b/dom/events/Event.cpp
@@ -231,7 +231,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Event)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPresContext)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mExplicitOriginalTarget)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOwner)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
diff --git a/dom/events/EventDispatcher.cpp b/dom/events/EventDispatcher.cpp
index 65f01844b..1d4dfd7d9 100644
--- a/dom/events/EventDispatcher.cpp
+++ b/dom/events/EventDispatcher.cpp
@@ -858,63 +858,46 @@ EventDispatcher::CreateEvent(EventTarget* aOwner,
// And if we didn't get an event, check the type argument.
-#define LOG_EVENT_CREATION(name) mozilla::Telemetry::Accumulate( \
- mozilla::Telemetry::CREATE_EVENT_##name, true);
-
if (aEventType.LowerCaseEqualsLiteral("mouseevent")) {
- LOG_EVENT_CREATION(MOUSEEVENT);
return NS_NewDOMMouseEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("mouseevents")) {
- LOG_EVENT_CREATION(MOUSEEVENTS);
return NS_NewDOMMouseEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("popupevents")) {
- LOG_EVENT_CREATION(POPUPEVENTS);
return NS_NewDOMMouseEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("mousescrollevents")) {
- LOG_EVENT_CREATION(MOUSESCROLLEVENTS);
return NS_NewDOMMouseScrollEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("dragevent")) {
- LOG_EVENT_CREATION(DRAGEVENT);
return NS_NewDOMDragEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("dragevents")) {
- LOG_EVENT_CREATION(DRAGEVENTS);
return NS_NewDOMDragEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("keyboardevent")) {
- LOG_EVENT_CREATION(KEYBOARDEVENT);
return NS_NewDOMKeyboardEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("keyevents")) {
- LOG_EVENT_CREATION(KEYEVENTS);
return NS_NewDOMKeyboardEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("compositionevent")) {
- LOG_EVENT_CREATION(COMPOSITIONEVENT);
return NS_NewDOMCompositionEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("textevent")) {
- LOG_EVENT_CREATION(TEXTEVENT);
return NS_NewDOMCompositionEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("textevents")) {
- LOG_EVENT_CREATION(TEXTEVENTS);
return NS_NewDOMCompositionEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("mutationevent")) {
- LOG_EVENT_CREATION(MUTATIONEVENT);
return NS_NewDOMMutationEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("mutationevents")) {
- LOG_EVENT_CREATION(MUTATIONEVENTS);
return NS_NewDOMMutationEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("deviceorientationevent")) {
- LOG_EVENT_CREATION(DEVICEORIENTATIONEVENT);
DeviceOrientationEventInit init;
RefPtr<Event> event =
DeviceOrientationEvent::Constructor(aOwner, EmptyString(), init);
@@ -922,97 +905,74 @@ EventDispatcher::CreateEvent(EventTarget* aOwner,
return event.forget();
}
if (aEventType.LowerCaseEqualsLiteral("devicemotionevent")) {
- LOG_EVENT_CREATION(DEVICEMOTIONEVENT);
return NS_NewDOMDeviceMotionEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("uievent")) {
- LOG_EVENT_CREATION(UIEVENT);
return NS_NewDOMUIEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("uievents")) {
- LOG_EVENT_CREATION(UIEVENTS);
return NS_NewDOMUIEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("event")) {
- LOG_EVENT_CREATION(EVENT);
return NS_NewDOMEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("events")) {
- LOG_EVENT_CREATION(EVENTS);
return NS_NewDOMEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("htmlevents")) {
- LOG_EVENT_CREATION(HTMLEVENTS);
return NS_NewDOMEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("svgevent")) {
- LOG_EVENT_CREATION(SVGEVENT);
return NS_NewDOMEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("svgevents")) {
- LOG_EVENT_CREATION(SVGEVENTS);
return NS_NewDOMEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("svgzoomevent")) {
- LOG_EVENT_CREATION(SVGZOOMEVENT);
return NS_NewDOMSVGZoomEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("svgzoomevents")) {
- LOG_EVENT_CREATION(SVGZOOMEVENTS);
return NS_NewDOMSVGZoomEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("timeevent")) {
- LOG_EVENT_CREATION(TIMEEVENT);
return NS_NewDOMTimeEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("timeevents")) {
- LOG_EVENT_CREATION(TIMEEVENTS);
return NS_NewDOMTimeEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("xulcommandevent")) {
- LOG_EVENT_CREATION(XULCOMMANDEVENT);
return NS_NewDOMXULCommandEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("xulcommandevents")) {
- LOG_EVENT_CREATION(XULCOMMANDEVENTS);
return NS_NewDOMXULCommandEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("commandevent")) {
- LOG_EVENT_CREATION(COMMANDEVENT);
return NS_NewDOMCommandEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("commandevents")) {
- LOG_EVENT_CREATION(COMMANDEVENTS);
return NS_NewDOMCommandEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("datacontainerevent")) {
- LOG_EVENT_CREATION(DATACONTAINEREVENT);
return NS_NewDOMDataContainerEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("datacontainerevents")) {
- LOG_EVENT_CREATION(DATACONTAINEREVENTS);
return NS_NewDOMDataContainerEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("messageevent")) {
- LOG_EVENT_CREATION(MESSAGEEVENT);
RefPtr<Event> event = new MessageEvent(aOwner, aPresContext, nullptr);
return event.forget();
}
if (aEventType.LowerCaseEqualsLiteral("notifypaintevent")) {
- LOG_EVENT_CREATION(NOTIFYPAINTEVENT);
return NS_NewDOMNotifyPaintEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("simplegestureevent")) {
- LOG_EVENT_CREATION(SIMPLEGESTUREEVENT);
return NS_NewDOMSimpleGestureEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("beforeunloadevent")) {
- LOG_EVENT_CREATION(BEFOREUNLOADEVENT);
return NS_NewDOMBeforeUnloadEvent(aOwner, aPresContext, nullptr);
}
// XXXkhuey this is broken
if (aEventType.LowerCaseEqualsLiteral("pagetransition")) {
- LOG_EVENT_CREATION(PAGETRANSITION);
PageTransitionEventInit init;
RefPtr<Event> event =
PageTransitionEvent::Constructor(aOwner, EmptyString(), init);
@@ -1020,14 +980,12 @@ EventDispatcher::CreateEvent(EventTarget* aOwner,
return event.forget();
}
if (aEventType.LowerCaseEqualsLiteral("scrollareaevent")) {
- LOG_EVENT_CREATION(SCROLLAREAEVENT);
return NS_NewDOMScrollAreaEvent(aOwner, aPresContext, nullptr);
}
// XXXkhuey Chrome supports popstateevent here, even though it provides no
// initPopStateEvent method. This is nuts ... but copying it is unlikely to
// break the web.
if (aEventType.LowerCaseEqualsLiteral("popstateevent")) {
- LOG_EVENT_CREATION(POPSTATEEVENT);
AutoJSContext cx;
RootedDictionary<PopStateEventInit> init(cx);
RefPtr<Event> event =
@@ -1037,11 +995,9 @@ EventDispatcher::CreateEvent(EventTarget* aOwner,
}
if (aEventType.LowerCaseEqualsLiteral("touchevent") &&
TouchEvent::PrefEnabled(nsContentUtils::GetDocShellForEventTarget(aOwner))) {
- LOG_EVENT_CREATION(TOUCHEVENT);
return NS_NewDOMTouchEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("hashchangeevent")) {
- LOG_EVENT_CREATION(HASHCHANGEEVENT);
HashChangeEventInit init;
RefPtr<Event> event =
HashChangeEvent::Constructor(aOwner, EmptyString(), init);
@@ -1049,11 +1005,9 @@ EventDispatcher::CreateEvent(EventTarget* aOwner,
return event.forget();
}
if (aEventType.LowerCaseEqualsLiteral("customevent")) {
- LOG_EVENT_CREATION(CUSTOMEVENT);
return NS_NewDOMCustomEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("storageevent")) {
- LOG_EVENT_CREATION(STORAGEEVENT);
return NS_NewDOMStorageEvent(aOwner);
}
if (aEventType.LowerCaseEqualsLiteral("focusevent")) {
@@ -1062,8 +1016,6 @@ EventDispatcher::CreateEvent(EventTarget* aOwner,
return event.forget();
}
-#undef LOG_EVENT_CREATION
-
// NEW EVENT TYPES SHOULD NOT BE ADDED HERE; THEY SHOULD USE ONLY EVENT
// CONSTRUCTORS
diff --git a/dom/events/EventStateManager.cpp b/dom/events/EventStateManager.cpp
index 7bbfe21b7..e16d68c81 100644
--- a/dom/events/EventStateManager.cpp
+++ b/dom/events/EventStateManager.cpp
@@ -3240,6 +3240,12 @@ EventStateManager::PostHandleEvent(nsPresContext* aPresContext,
action = WheelPrefs::GetInstance()->ComputeActionFor(wheelEvent);
}
switch (action) {
+ case WheelPrefs::ACTION_HSCROLL: {
+ // Swap axes and fall through
+ double deltaX = wheelEvent->mDeltaX;
+ wheelEvent->mDeltaX = wheelEvent->mDeltaY;
+ wheelEvent->mDeltaY = deltaX;
+ }
case WheelPrefs::ACTION_SCROLL: {
// For scrolling of default action, we should honor the mouse wheel
// transaction.
diff --git a/dom/events/EventStateManager.h b/dom/events/EventStateManager.h
index d0461e7fa..95ce9a907 100644
--- a/dom/events/EventStateManager.h
+++ b/dom/events/EventStateManager.h
@@ -513,7 +513,8 @@ protected:
ACTION_SCROLL,
ACTION_HISTORY,
ACTION_ZOOM,
- ACTION_LAST = ACTION_ZOOM,
+ ACTION_HSCROLL,
+ ACTION_LAST = ACTION_HSCROLL,
// Following actions are used only by internal processing. So, cannot
// specified by prefs.
ACTION_SEND_TO_PLUGIN
diff --git a/dom/events/JSEventHandler.cpp b/dom/events/JSEventHandler.cpp
index 4b1b33313..b9e7c4d84 100644
--- a/dom/events/JSEventHandler.cpp
+++ b/dom/events/JSEventHandler.cpp
@@ -63,7 +63,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(JSEventHandler)
NS_IMPL_CYCLE_COLLECTION_DESCRIBE(JSEventHandler, tmp->mRefCnt.get())
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_RAWPTR(mTypedHandler.Ptr())
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(JSEventHandler)
diff --git a/dom/fetch/Fetch.cpp b/dom/fetch/Fetch.cpp
index 5c05f3602..f944352e3 100644
--- a/dom/fetch/Fetch.cpp
+++ b/dom/fetch/Fetch.cpp
@@ -38,7 +38,6 @@
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/dom/URLSearchParams.h"
#include "mozilla/dom/workers/ServiceWorkerManager.h"
-#include "mozilla/Telemetry.h"
#include "InternalRequest.h"
#include "InternalResponse.h"
@@ -237,8 +236,6 @@ FetchRequest(nsIGlobalObject* aGlobal, const RequestOrUSVString& aInput,
}
}
- Telemetry::Accumulate(Telemetry::FETCH_IS_MAINTHREAD, 1);
-
RefPtr<MainThreadFetchResolver> resolver = new MainThreadFetchResolver(p);
RefPtr<FetchDriver> fetch = new FetchDriver(r, principal, loadGroup);
fetch->SetDocument(doc);
@@ -251,8 +248,6 @@ FetchRequest(nsIGlobalObject* aGlobal, const RequestOrUSVString& aInput,
WorkerPrivate* worker = GetCurrentThreadWorkerPrivate();
MOZ_ASSERT(worker);
- Telemetry::Accumulate(Telemetry::FETCH_IS_MAINTHREAD, 0);
-
if (worker->IsServiceWorker()) {
r->SetSkipServiceWorker();
}
@@ -265,7 +260,7 @@ FetchRequest(nsIGlobalObject* aGlobal, const RequestOrUSVString& aInput,
}
RefPtr<MainThreadFetchRunnable> run = new MainThreadFetchRunnable(resolver, r);
- worker->DispatchToMainThread(run.forget());
+ MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(run));
}
return p.forget();
diff --git a/dom/fetch/FetchConsumer.cpp b/dom/fetch/FetchConsumer.cpp
index 42dfcbaba..e82e5ec51 100644
--- a/dom/fetch/FetchConsumer.cpp
+++ b/dom/fetch/FetchConsumer.cpp
@@ -339,11 +339,7 @@ FetchBodyConsumer<Derived>::Create(nsIGlobalObject* aGlobal,
nsCOMPtr<nsIRunnable> r = new BeginConsumeBodyRunnable<Derived>(consumer);
- if (workerPrivate) {
- aRv = workerPrivate->DispatchToMainThread(r.forget());
- } else {
- aRv = NS_DispatchToMainThread(r.forget());
- }
+ aRv = NS_DispatchToMainThread(r.forget());
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
@@ -655,9 +651,7 @@ FetchBodyConsumer<Derived>::ShutDownMainThreadConsuming()
nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(
[self] () { self->ShutDownMainThreadConsuming(); });
- WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
- MOZ_ASSERT(workerPrivate);
- workerPrivate->DispatchToMainThread(r.forget());
+ MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(r.forget()));
return;
}
diff --git a/dom/fetch/FetchDriver.cpp b/dom/fetch/FetchDriver.cpp
index aac79b829..6294b0dc5 100644
--- a/dom/fetch/FetchDriver.cpp
+++ b/dom/fetch/FetchDriver.cpp
@@ -77,9 +77,6 @@ FetchDriver::Fetch(FetchDriverObserver* aObserver)
mObserver = aObserver;
- Telemetry::Accumulate(Telemetry::SERVICE_WORKER_REQUEST_PASSTHROUGH,
- mRequest->WasCreatedByFetchEvent());
-
// FIXME(nsm): Deal with HSTS.
MOZ_RELEASE_ASSERT(!mRequest->IsSynchronous(),
@@ -906,11 +903,7 @@ FetchDriver::SetRequestHeaders(nsIHttpChannel* aChannel) const
AutoTArray<InternalHeaders::Entry, 5> headers;
mRequest->Headers()->GetEntries(headers);
- bool hasAccept = false;
for (uint32_t i = 0; i < headers.Length(); ++i) {
- if (!hasAccept && headers[i].mName.EqualsLiteral("accept")) {
- hasAccept = true;
- }
if (headers[i].mValue.IsEmpty()) {
aChannel->SetEmptyRequestHeader(headers[i].mName);
} else {
@@ -918,12 +911,6 @@ FetchDriver::SetRequestHeaders(nsIHttpChannel* aChannel) const
}
}
- if (!hasAccept) {
- aChannel->SetRequestHeader(NS_LITERAL_CSTRING("accept"),
- NS_LITERAL_CSTRING("*/*"),
- false /* merge */);
- }
-
if (mRequest->ForceOriginHeader()) {
nsAutoString origin;
if (NS_SUCCEEDED(nsContentUtils::GetUTFOrigin(mPrincipal, origin))) {
diff --git a/dom/fetch/Headers.cpp b/dom/fetch/Headers.cpp
index 1e1a46c62..ca5aa57a6 100644
--- a/dom/fetch/Headers.cpp
+++ b/dom/fetch/Headers.cpp
@@ -25,7 +25,7 @@ NS_INTERFACE_MAP_END
// static
already_AddRefed<Headers>
Headers::Constructor(const GlobalObject& aGlobal,
- const Optional<HeadersOrByteStringSequenceSequenceOrByteStringMozMap>& aInit,
+ const Optional<HeadersOrByteStringSequenceSequenceOrByteStringByteStringRecord>& aInit,
ErrorResult& aRv)
{
RefPtr<InternalHeaders> ih = new InternalHeaders();
@@ -39,8 +39,8 @@ Headers::Constructor(const GlobalObject& aGlobal,
ih->Fill(*aInit.Value().GetAsHeaders().mInternalHeaders, aRv);
} else if (aInit.Value().IsByteStringSequenceSequence()) {
ih->Fill(aInit.Value().GetAsByteStringSequenceSequence(), aRv);
- } else if (aInit.Value().IsByteStringMozMap()) {
- ih->Fill(aInit.Value().GetAsByteStringMozMap(), aRv);
+ } else if (aInit.Value().IsByteStringByteStringRecord()) {
+ ih->Fill(aInit.Value().GetAsByteStringByteStringRecord(), aRv);
}
if (aRv.Failed()) {
@@ -53,7 +53,7 @@ Headers::Constructor(const GlobalObject& aGlobal,
// static
already_AddRefed<Headers>
Headers::Constructor(const GlobalObject& aGlobal,
- const OwningHeadersOrByteStringSequenceSequenceOrByteStringMozMap& aInit,
+ const OwningHeadersOrByteStringSequenceSequenceOrByteStringByteStringRecord& aInit,
ErrorResult& aRv)
{
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
@@ -62,7 +62,7 @@ Headers::Constructor(const GlobalObject& aGlobal,
/* static */ already_AddRefed<Headers>
Headers::Create(nsIGlobalObject* aGlobal,
- const OwningHeadersOrByteStringSequenceSequenceOrByteStringMozMap& aInit,
+ const OwningHeadersOrByteStringSequenceSequenceOrByteStringByteStringRecord& aInit,
ErrorResult& aRv)
{
RefPtr<InternalHeaders> ih = new InternalHeaders();
@@ -72,8 +72,8 @@ Headers::Create(nsIGlobalObject* aGlobal,
ih->Fill(*(aInit.GetAsHeaders().get()->mInternalHeaders), aRv);
} else if (aInit.IsByteStringSequenceSequence()) {
ih->Fill(aInit.GetAsByteStringSequenceSequence(), aRv);
- } else if (aInit.IsByteStringMozMap()) {
- ih->Fill(aInit.GetAsByteStringMozMap(), aRv);
+ } else if (aInit.IsByteStringByteStringRecord()) {
+ ih->Fill(aInit.GetAsByteStringByteStringRecord(), aRv);
}
if (NS_WARN_IF(aRv.Failed())) {
diff --git a/dom/fetch/Headers.h b/dom/fetch/Headers.h
index b603dc836..1dd92f779 100644
--- a/dom/fetch/Headers.h
+++ b/dom/fetch/Headers.h
@@ -20,9 +20,9 @@ class ErrorResult;
namespace dom {
-template<typename T> class MozMap;
-class HeadersOrByteStringSequenceSequenceOrByteStringMozMap;
-class OwningHeadersOrByteStringSequenceSequenceOrByteStringMozMap;
+template<typename K, typename V> class Record;
+class HeadersOrByteStringSequenceSequenceOrByteStringByteStringRecord;
+class OwningHeadersOrByteStringSequenceSequenceOrByteStringByteStringRecord;
/**
* This Headers class is only used to represent the content facing Headers
@@ -57,17 +57,17 @@ public:
static already_AddRefed<Headers>
Constructor(const GlobalObject& aGlobal,
- const Optional<HeadersOrByteStringSequenceSequenceOrByteStringMozMap>& aInit,
+ const Optional<HeadersOrByteStringSequenceSequenceOrByteStringByteStringRecord>& aInit,
ErrorResult& aRv);
static already_AddRefed<Headers>
Constructor(const GlobalObject& aGlobal,
- const OwningHeadersOrByteStringSequenceSequenceOrByteStringMozMap& aInit,
+ const OwningHeadersOrByteStringSequenceSequenceOrByteStringByteStringRecord& aInit,
ErrorResult& aRv);
static already_AddRefed<Headers>
Create(nsIGlobalObject* aGlobalObject,
- const OwningHeadersOrByteStringSequenceSequenceOrByteStringMozMap& aInit,
+ const OwningHeadersOrByteStringSequenceSequenceOrByteStringByteStringRecord& aInit,
ErrorResult& aRv);
void Append(const nsACString& aName, const nsACString& aValue,
diff --git a/dom/fetch/InternalHeaders.cpp b/dom/fetch/InternalHeaders.cpp
index 11585615e..f66221d42 100644
--- a/dom/fetch/InternalHeaders.cpp
+++ b/dom/fetch/InternalHeaders.cpp
@@ -314,12 +314,13 @@ InternalHeaders::Fill(const Sequence<Sequence<nsCString>>& aInit, ErrorResult& a
}
void
-InternalHeaders::Fill(const MozMap<nsCString>& aInit, ErrorResult& aRv)
+InternalHeaders::Fill(const Record<nsCString, nsCString>& aInit, ErrorResult& aRv)
{
- nsTArray<nsString> keys;
- aInit.GetKeys(keys);
- for (uint32_t i = 0; i < keys.Length() && !aRv.Failed(); ++i) {
- Append(NS_ConvertUTF16toUTF8(keys[i]), aInit.Get(keys[i]), aRv);
+ for (auto& entry : aInit.Entries()) {
+ Append(entry.mKey, entry.mValue, aRv);
+ if (aRv.Failed()) {
+ return;
+ }
}
}
diff --git a/dom/fetch/InternalHeaders.h b/dom/fetch/InternalHeaders.h
index 9a6d6dae7..98046f0ef 100644
--- a/dom/fetch/InternalHeaders.h
+++ b/dom/fetch/InternalHeaders.h
@@ -20,7 +20,7 @@ class ErrorResult;
namespace dom {
-template<typename T> class MozMap;
+template<typename K, typename V> class Record;
class HeadersEntry;
class InternalHeaders final
@@ -113,7 +113,7 @@ public:
void Fill(const InternalHeaders& aInit, ErrorResult& aRv);
void Fill(const Sequence<Sequence<nsCString>>& aInit, ErrorResult& aRv);
- void Fill(const MozMap<nsCString>& aInit, ErrorResult& aRv);
+ void Fill(const Record<nsCString, nsCString>& aInit, ErrorResult& aRv);
bool HasOnlySimpleHeaders() const;
diff --git a/dom/filesystem/Directory.cpp b/dom/filesystem/Directory.cpp
index 59c78fb2c..5e8a4a745 100644
--- a/dom/filesystem/Directory.cpp
+++ b/dom/filesystem/Directory.cpp
@@ -36,7 +36,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Directory)
tmp->mFileSystem->Traverse(cb);
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(Directory)
diff --git a/dom/gamepad/GamepadManager.cpp b/dom/gamepad/GamepadManager.cpp
index dde71dd0a..e17829652 100644
--- a/dom/gamepad/GamepadManager.cpp
+++ b/dom/gamepad/GamepadManager.cpp
@@ -28,7 +28,6 @@
#include "nsIObserverService.h"
#include "nsIServiceManager.h"
#include "nsThreadUtils.h"
-#include "VRManagerChild.h"
#include "mozilla/Services.h"
#include "mozilla/Unused.h"
@@ -110,11 +109,6 @@ GamepadManager::StopMonitoring()
}
mChannelChildren.Clear();
mGamepads.Clear();
-
-#if defined(XP_WIN) || defined(XP_MACOSX) || defined(XP_LINUX)
- mVRChannelChild = gfx::VRManagerChild::Get();
- mVRChannelChild->SendControllerListenerRemoved();
-#endif
}
void
@@ -211,11 +205,6 @@ uint32_t GamepadManager::GetGamepadIndexWithServiceType(uint32_t aIndex,
newIndex = aIndex;
break;
}
- case GamepadServiceType::VR:
- {
- newIndex = aIndex + VR_GAMEPAD_IDX_OFFSET;
- break;
- }
default:
MOZ_ASSERT(false);
break;
@@ -679,13 +668,6 @@ GamepadManager::ActorCreated(PBackgroundChild *aActor)
MOZ_ASSERT(initedChild == child);
child->SendGamepadListenerAdded();
mChannelChildren.AppendElement(child);
-
-#if defined(XP_WIN) || defined(XP_MACOSX) || defined(XP_LINUX)
- // Construct VRManagerChannel and ask adding the connected
- // VR controllers to GamepadManager
- mVRChannelChild = gfx::VRManagerChild::Get();
- mVRChannelChild->SendControllerListenerAdded();
-#endif
}
//Override nsIIPCBackgroundChildCreateCallback
diff --git a/dom/gamepad/GamepadManager.h b/dom/gamepad/GamepadManager.h
index 1bb437d8f..a772221ca 100644
--- a/dom/gamepad/GamepadManager.h
+++ b/dom/gamepad/GamepadManager.h
@@ -16,9 +16,6 @@
class nsGlobalWindow;
namespace mozilla {
-namespace gfx {
-class VRManagerChild;
-} // namespace gfx
namespace dom {
class EventTarget;
@@ -123,7 +120,6 @@ class GamepadManager final : public nsIObserver,
// will be destroyed during the IPDL shutdown chain, so we
// don't need to refcount it here.
nsTArray<GamepadEventChannelChild *> mChannelChildren;
- gfx::VRManagerChild* mVRChannelChild;
private:
@@ -138,8 +134,6 @@ class GamepadManager final : public nsIObserver,
// Indicate that a window has received data from a gamepad.
void SetWindowHasSeenGamepad(nsGlobalWindow* aWindow, uint32_t aIndex,
bool aHasSeen = true);
- // Our gamepad index has VR_GAMEPAD_IDX_OFFSET while GamepadChannelType
- // is from VRManager.
uint32_t GetGamepadIndexWithServiceType(uint32_t aIndex, GamepadServiceType aServiceType);
// Gamepads connected to the system. Copies of these are handed out
diff --git a/dom/gamepad/GamepadServiceTest.cpp b/dom/gamepad/GamepadServiceTest.cpp
index a6fde58f0..89429b52a 100644
--- a/dom/gamepad/GamepadServiceTest.cpp
+++ b/dom/gamepad/GamepadServiceTest.cpp
@@ -35,7 +35,6 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(GamepadServiceTest)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(GamepadServiceTest,
DOMEventTargetHelper)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindow)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
diff --git a/dom/gamepad/ipc/GamepadServiceType.h b/dom/gamepad/ipc/GamepadServiceType.h
index acc0967d1..6200cdfa9 100644
--- a/dom/gamepad/ipc/GamepadServiceType.h
+++ b/dom/gamepad/ipc/GamepadServiceType.h
@@ -6,11 +6,9 @@ namespace mozilla{
namespace dom{
// Standard channel is used for managing gamepads that
-// are from GamepadPlatformService. VR channel
-// is for gamepads that are from VRManagerChild.
+// are from GamepadPlatformService.
enum class GamepadServiceType : uint16_t {
Standard,
- VR,
NumGamepadServiceType
};
diff --git a/dom/geolocation/nsGeolocation.cpp b/dom/geolocation/nsGeolocation.cpp
index 2d84a3e11..846e7fff4 100644
--- a/dom/geolocation/nsGeolocation.cpp
+++ b/dom/geolocation/nsGeolocation.cpp
@@ -7,7 +7,6 @@
#include "nsXULAppAPI.h"
#include "mozilla/dom/ContentChild.h"
-#include "mozilla/Telemetry.h"
#include "mozilla/UniquePtr.h"
#include "nsGeolocation.h"
@@ -70,7 +69,6 @@ class nsGeolocationRequest final
GeoPositionCallback aCallback,
GeoPositionErrorCallback aErrorCallback,
UniquePtr<PositionOptions>&& aOptions,
- uint8_t aProtocolType,
bool aWatchPositionRequest = false,
int32_t aWatchId = 0);
@@ -119,7 +117,6 @@ class nsGeolocationRequest final
int32_t mWatchId;
bool mShutdown;
nsCOMPtr<nsIContentPermissionRequester> mRequester;
- uint8_t mProtocolType;
};
static UniquePtr<PositionOptions>
@@ -287,7 +284,6 @@ nsGeolocationRequest::nsGeolocationRequest(Geolocation* aLocator,
GeoPositionCallback aCallback,
GeoPositionErrorCallback aErrorCallback,
UniquePtr<PositionOptions>&& aOptions,
- uint8_t aProtocolType,
bool aWatchPositionRequest,
int32_t aWatchId)
: mIsWatchPositionRequest(aWatchPositionRequest),
@@ -296,8 +292,7 @@ nsGeolocationRequest::nsGeolocationRequest(Geolocation* aLocator,
mOptions(Move(aOptions)),
mLocator(aLocator),
mWatchId(aWatchId),
- mShutdown(false),
- mProtocolType(aProtocolType)
+ mShutdown(false)
{
if (nsCOMPtr<nsPIDOMWindowInner> win =
do_QueryReferent(mLocator->GetOwner())) {
@@ -382,13 +377,6 @@ nsGeolocationRequest::GetElement(nsIDOMElement * *aRequestingElement)
NS_IMETHODIMP
nsGeolocationRequest::Cancel()
{
- if (mRequester) {
- // Record the number of denied requests for regular web content.
- // This method is only called when the user explicitly denies the request,
- // and is not called when the page is simply unloaded, or similar.
- Telemetry::Accumulate(Telemetry::GEOLOCATION_REQUEST_GRANTED, mProtocolType);
- }
-
if (mLocator->ClearPendingRequest(this)) {
return NS_OK;
}
@@ -402,27 +390,6 @@ nsGeolocationRequest::Allow(JS::HandleValue aChoices)
{
MOZ_ASSERT(aChoices.isUndefined());
- if (mRequester) {
- // Record the number of granted requests for regular web content.
- Telemetry::Accumulate(Telemetry::GEOLOCATION_REQUEST_GRANTED, mProtocolType + 10);
-
- // Record whether a location callback is fulfilled while the owner window
- // is not visible.
- bool isVisible = false;
- nsCOMPtr<nsPIDOMWindowInner> window = mLocator->GetParentObject();
-
- if (window) {
- nsCOMPtr<nsIDocument> doc = window->GetDoc();
- isVisible = doc && !doc->Hidden();
- }
-
- if (IsWatch()) {
- mozilla::Telemetry::Accumulate(mozilla::Telemetry::GEOLOCATION_WATCHPOSITION_VISIBLE, isVisible);
- } else {
- mozilla::Telemetry::Accumulate(mozilla::Telemetry::GEOLOCATION_GETCURRENTPOSITION_VISIBLE, isVisible);
- }
- }
-
if (mLocator->ClearPendingRequest(this)) {
return NS_OK;
}
@@ -977,8 +944,7 @@ NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(Geolocation,
mPendingRequests)
Geolocation::Geolocation()
-: mProtocolType(ProtocolType::OTHER)
-, mLastWatchId(0)
+: mLastWatchId(0)
{
}
@@ -1010,23 +976,6 @@ Geolocation::Init(nsPIDOMWindowInner* aContentDom)
nsCOMPtr<nsIURI> uri;
nsresult rv = mPrincipal->GetURI(getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, rv);
-
- if (uri) {
- bool isHttp;
- rv = uri->SchemeIs("http", &isHttp);
- NS_ENSURE_SUCCESS(rv, rv);
-
- bool isHttps;
- rv = uri->SchemeIs("https", &isHttps);
- NS_ENSURE_SUCCESS(rv, rv);
-
- // Store the protocol to send via telemetry later.
- if (isHttp) {
- mProtocolType = ProtocolType::HTTP;
- } else if (isHttps) {
- mProtocolType = ProtocolType::HTTPS;
- }
- }
}
// If no aContentDom was passed into us, we are being used
@@ -1110,7 +1059,6 @@ Geolocation::Update(nsIDOMGeoPosition *aSomewhere)
if (coords) {
double accuracy = -1;
coords->GetAccuracy(&accuracy);
- mozilla::Telemetry::Accumulate(mozilla::Telemetry::GEOLOCATION_ACCURACY_EXPONENTIAL, accuracy);
}
}
@@ -1135,8 +1083,6 @@ Geolocation::NotifyError(uint16_t aErrorCode)
return NS_OK;
}
- mozilla::Telemetry::Accumulate(mozilla::Telemetry::GEOLOCATION_ERROR, true);
-
for (uint32_t i = mPendingCallbacks.Length(); i > 0; i--) {
mPendingCallbacks[i-1]->NotifyErrorAndShutdown(aErrorCode);
//NotifyErrorAndShutdown() removes the request from the array
@@ -1214,13 +1160,9 @@ Geolocation::GetCurrentPosition(GeoPositionCallback callback,
// After this we hand over ownership of options to our nsGeolocationRequest.
- // Count the number of requests per protocol/scheme.
- Telemetry::Accumulate(Telemetry::GEOLOCATION_GETCURRENTPOSITION_SECURE_ORIGIN,
- static_cast<uint8_t>(mProtocolType));
-
RefPtr<nsGeolocationRequest> request =
new nsGeolocationRequest(this, Move(callback), Move(errorCallback),
- Move(options), static_cast<uint8_t>(mProtocolType),
+ Move(options),
false);
if (!sGeoEnabled) {
@@ -1292,17 +1234,13 @@ Geolocation::WatchPosition(GeoPositionCallback aCallback,
return NS_ERROR_NOT_AVAILABLE;
}
- // Count the number of requests per protocol/scheme.
- Telemetry::Accumulate(Telemetry::GEOLOCATION_WATCHPOSITION_SECURE_ORIGIN,
- static_cast<uint8_t>(mProtocolType));
-
// The watch ID:
*aRv = mLastWatchId++;
RefPtr<nsGeolocationRequest> request =
new nsGeolocationRequest(this, Move(aCallback), Move(aErrorCallback),
Move(aOptions),
- static_cast<uint8_t>(mProtocolType), true, *aRv);
+ true, *aRv);
if (!sGeoEnabled) {
nsCOMPtr<nsIRunnable> ev = new RequestAllowEvent(false, request);
diff --git a/dom/geolocation/nsGeolocation.h b/dom/geolocation/nsGeolocation.h
index 0bc527e34..0bcc587e4 100644
--- a/dom/geolocation/nsGeolocation.h
+++ b/dom/geolocation/nsGeolocation.h
@@ -202,12 +202,6 @@ private:
// where the content was loaded from
nsCOMPtr<nsIPrincipal> mPrincipal;
- // the protocols we want to measure
- enum class ProtocolType: uint8_t { OTHER, HTTP, HTTPS };
-
- // the protocol used to load the content
- ProtocolType mProtocolType;
-
// owning back pointer.
RefPtr<nsGeolocationService> mService;
diff --git a/dom/html/HTMLCanvasElement.cpp b/dom/html/HTMLCanvasElement.cpp
index 88b41bce0..a01795d9e 100644
--- a/dom/html/HTMLCanvasElement.cpp
+++ b/dom/html/HTMLCanvasElement.cpp
@@ -42,7 +42,6 @@
#include "nsRefreshDriver.h"
#include "nsStreamUtils.h"
#include "ActiveLayerTracker.h"
-#include "VRManagerChild.h"
#include "WebGL1Context.h"
#include "WebGL2Context.h"
@@ -358,7 +357,6 @@ NS_IMPL_ISUPPORTS(HTMLCanvasElementObserver, nsIObserver)
HTMLCanvasElement::HTMLCanvasElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
: nsGenericHTMLElement(aNodeInfo),
mResetLayer(true) ,
- mVRPresentationActive(false),
mWriteOnly(false)
{}
@@ -1002,7 +1000,7 @@ HTMLCanvasElement::GetSize()
}
bool
-HTMLCanvasElement::IsWriteOnly()
+HTMLCanvasElement::IsWriteOnly() const
{
return mWriteOnly;
}
@@ -1111,7 +1109,7 @@ HTMLCanvasElement::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
static uint8_t sOffscreenCanvasLayerUserDataDummy = 0;
if (mCurrentContext) {
- return mCurrentContext->GetCanvasLayer(aBuilder, aOldLayer, aManager, mVRPresentationActive);
+ return mCurrentContext->GetCanvasLayer(aBuilder, aOldLayer, aManager);
}
if (mOffscreenCanvas) {
@@ -1441,42 +1439,5 @@ HTMLCanvasElement::InvalidateFromAsyncCanvasRenderer(AsyncCanvasRenderer *aRende
element->InvalidateCanvasContent(nullptr);
}
-void
-HTMLCanvasElement::StartVRPresentation()
-{
- WebGLContext* webgl = static_cast<WebGLContext*>(GetContextAtIndex(0));
- if (!webgl) {
- return;
- }
-
- if (!webgl->StartVRPresentation()) {
- return;
- }
-
- mVRPresentationActive = true;
-}
-
-void
-HTMLCanvasElement::StopVRPresentation()
-{
- mVRPresentationActive = false;
-}
-
-already_AddRefed<layers::SharedSurfaceTextureClient>
-HTMLCanvasElement::GetVRFrame()
-{
- if (GetCurrentContextType() != CanvasContextType::WebGL1 &&
- GetCurrentContextType() != CanvasContextType::WebGL2) {
- return nullptr;
- }
-
- WebGLContext* webgl = static_cast<WebGLContext*>(GetContextAtIndex(0));
- if (!webgl) {
- return nullptr;
- }
-
- return webgl->GetVRFrame();
-}
-
} // namespace dom
} // namespace mozilla
diff --git a/dom/html/HTMLCanvasElement.h b/dom/html/HTMLCanvasElement.h
index 81c141d3c..e77db6ff1 100644
--- a/dom/html/HTMLCanvasElement.h
+++ b/dom/html/HTMLCanvasElement.h
@@ -224,9 +224,9 @@ public:
nsIntSize GetSize();
/**
- * Determine whether the canvas is write-only.
+ * Determine whether the canvas is write-only (tainted).
*/
- bool IsWriteOnly();
+ bool IsWriteOnly() const;
/**
* Force the canvas to be write-only.
@@ -350,10 +350,6 @@ public:
static void SetAttrFromAsyncCanvasRenderer(AsyncCanvasRenderer *aRenderer);
static void InvalidateFromAsyncCanvasRenderer(AsyncCanvasRenderer *aRenderer);
- void StartVRPresentation();
- void StopVRPresentation();
- already_AddRefed<layers::SharedSurfaceTextureClient> GetVRFrame();
-
protected:
virtual ~HTMLCanvasElement();
diff --git a/dom/html/HTMLFormControlsCollection.cpp b/dom/html/HTMLFormControlsCollection.cpp
index d91a6b5de..77fafae99 100644
--- a/dom/html/HTMLFormControlsCollection.cpp
+++ b/dom/html/HTMLFormControlsCollection.cpp
@@ -134,7 +134,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(HTMLFormControlsCollection)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(HTMLFormControlsCollection)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mNameLookupTable)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(HTMLFormControlsCollection)
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
diff --git a/dom/html/HTMLFormElement.cpp b/dom/html/HTMLFormElement.cpp
index 5164391f8..6bea19a2b 100644
--- a/dom/html/HTMLFormElement.cpp
+++ b/dom/html/HTMLFormElement.cpp
@@ -38,7 +38,6 @@
// form submission
#include "HTMLFormSubmissionConstants.h"
#include "mozilla/dom/FormData.h"
-#include "mozilla/Telemetry.h"
#include "nsIFormSubmitObserver.h"
#include "nsIObserverService.h"
#include "nsICategoryManager.h"
@@ -52,7 +51,6 @@
#include "nsIWebProgress.h"
#include "nsIDocShell.h"
#include "nsIPrompt.h"
-#include "nsISecurityUITelemetry.h"
#include "nsIStringBundle.h"
// radio buttons
@@ -955,15 +953,6 @@ HTMLFormElement::DoSecureToInsecureSubmitCheck(nsIURI* aActionURL,
return rv;
}
*aCancelSubmit = (buttonPressed == 1);
- uint32_t telemetryBucket =
- nsISecurityUITelemetry::WARNING_CONFIRM_POST_TO_INSECURE_FROM_SECURE;
- mozilla::Telemetry::Accumulate(mozilla::Telemetry::SECURITY_UI,
- telemetryBucket);
- if (!*aCancelSubmit) {
- // The user opted to continue, so note that in the next telemetry bucket.
- mozilla::Telemetry::Accumulate(mozilla::Telemetry::SECURITY_UI,
- telemetryBucket + 1);
- }
return NS_OK;
}
diff --git a/dom/html/HTMLImageElement.cpp b/dom/html/HTMLImageElement.cpp
index 4b2e7a07b..fab1cdef4 100644
--- a/dom/html/HTMLImageElement.cpp
+++ b/dom/html/HTMLImageElement.cpp
@@ -1345,8 +1345,6 @@ HTMLImageElement::FlushUseCounters()
nsCOMPtr<imgIContainer> container;
request->GetImage(getter_AddRefs(container));
-
- static_cast<image::Image*>(container.get())->ReportUseCounters();
}
} // namespace dom
diff --git a/dom/html/HTMLInputElement.cpp b/dom/html/HTMLInputElement.cpp
index e9086933b..0b879bb9b 100644
--- a/dom/html/HTMLInputElement.cpp
+++ b/dom/html/HTMLInputElement.cpp
@@ -24,7 +24,6 @@
#include "nsIPhonetic.h"
#include "HTMLFormSubmissionConstants.h"
-#include "mozilla/Telemetry.h"
#include "nsIControllers.h"
#include "nsIStringBundle.h"
#include "nsFocusManager.h"
@@ -1275,10 +1274,6 @@ HTMLInputElement::BeforeSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
container->RadioRequiredWillChange(name, !!aValue);
}
}
-
- if (aName == nsGkAtoms::webkitdirectory) {
- Telemetry::Accumulate(Telemetry::WEBKIT_DIRECTORY_USED, true);
- }
}
return nsGenericHTMLFormElementWithState::BeforeSetAttr(aNameSpaceID, aName,
@@ -4989,10 +4984,6 @@ HTMLInputElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
true);
dispatcher->PostDOMEvent();
}
-
-#ifdef EARLY_BETA_OR_EARLIER
- Telemetry::Accumulate(Telemetry::PWMGR_PASSWORD_INPUT_IN_FORM, !!mForm);
-#endif
}
return rv;
@@ -8863,7 +8854,6 @@ HTMLInputElement::UpdateEntries(const nsTArray<OwningFileOrDirectory>& aFilesOrD
void
HTMLInputElement::GetWebkitEntries(nsTArray<RefPtr<FileSystemEntry>>& aSequence)
{
- Telemetry::Accumulate(Telemetry::BLINK_FILESYSTEM_USED, true);
aSequence.AppendElements(mEntries);
}
diff --git a/dom/html/HTMLMediaElement.cpp b/dom/html/HTMLMediaElement.cpp
index 3954e6208..050d1ac69 100644
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -92,7 +92,6 @@
#include "mozilla/dom/VideoTrackList.h"
#include "mozilla/dom/TextTrack.h"
#include "nsIContentPolicy.h"
-#include "mozilla/Telemetry.h"
#include "DecoderDoctorDiagnostics.h"
#include "DecoderTraits.h"
#include "MediaContentType.h"
@@ -1038,14 +1037,6 @@ void HTMLMediaElement::ShutdownDecoder()
void HTMLMediaElement::AbortExistingLoads()
{
-#ifdef MOZ_EME
- // If there is no existing decoder then we don't have anything to
- // report. This prevents reporting the initial load from an
- // empty video element as a failed EME load.
- if (mDecoder) {
- ReportEMETelemetry();
- }
-#endif
// Abort any already-running instance of the resource selection algorithm.
mLoadWaitStatus = NOT_WAITING;
@@ -1901,8 +1892,6 @@ NS_IMETHODIMP HTMLMediaElement::GetCurrentTime(double* aCurrentTime)
void
HTMLMediaElement::FastSeek(double aTime, ErrorResult& aRv)
{
- LOG(LogLevel::Debug, ("Reporting telemetry VIDEO_FASTSEEK_USED"));
- Telemetry::Accumulate(Telemetry::VIDEO_FASTSEEK_USED, 1);
RefPtr<Promise> tobeDropped = Seek(aTime, SeekTarget::PrevSyncPoint, aRv);
}
@@ -3156,10 +3145,6 @@ HTMLMediaElement::~HTMLMediaElement()
if (mProgressTimer) {
StopProgress();
}
- if (mVideoDecodeSuspendTimer) {
- mVideoDecodeSuspendTimer->Cancel();
- mVideoDecodeSuspendTimer = nullptr;
- }
if (mSrcStream) {
EndSrcMediaStreamPlayback();
}
@@ -3650,228 +3635,6 @@ nsresult HTMLMediaElement::BindToTree(nsIDocument* aDocument, nsIContent* aParen
return rv;
}
-/* static */
-void HTMLMediaElement::VideoDecodeSuspendTimerCallback(nsITimer* aTimer, void* aClosure)
-{
- MOZ_ASSERT(NS_IsMainThread());
- auto element = static_cast<HTMLMediaElement*>(aClosure);
- element->mVideoDecodeSuspendTime.Start();
- element->mVideoDecodeSuspendTimer = nullptr;
-}
-
-void HTMLMediaElement::HiddenVideoStart()
-{
- MOZ_ASSERT(NS_IsMainThread());
- mHiddenPlayTime.Start();
- if (mVideoDecodeSuspendTimer) {
- // Already started, just keep it running.
- return;
- }
- mVideoDecodeSuspendTimer = do_CreateInstance("@mozilla.org/timer;1");
- mVideoDecodeSuspendTimer->InitWithNamedFuncCallback(
- VideoDecodeSuspendTimerCallback, this,
- MediaPrefs::MDSMSuspendBackgroundVideoDelay(), nsITimer::TYPE_ONE_SHOT,
- "HTMLMediaElement::VideoDecodeSuspendTimerCallback");
-}
-
-void HTMLMediaElement::HiddenVideoStop()
-{
- MOZ_ASSERT(NS_IsMainThread());
- mHiddenPlayTime.Pause();
- mVideoDecodeSuspendTime.Pause();
- if (!mVideoDecodeSuspendTimer) {
- return;
- }
- mVideoDecodeSuspendTimer->Cancel();
- mVideoDecodeSuspendTimer = nullptr;
-}
-
-#ifdef MOZ_EME
-void
-HTMLMediaElement::ReportEMETelemetry()
-{
- // Report telemetry for EME videos when a page is unloaded.
- NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
- if (mIsEncrypted && Preferences::GetBool("media.eme.enabled")) {
- Telemetry::Accumulate(Telemetry::VIDEO_EME_PLAY_SUCCESS, mLoadedDataFired);
- LOG(LogLevel::Debug, ("%p VIDEO_EME_PLAY_SUCCESS = %s",
- this, mLoadedDataFired ? "true" : "false"));
- }
-}
-#endif
-
-void
-HTMLMediaElement::ReportTelemetry()
-{
- // Report telemetry for videos when a page is unloaded. We
- // want to know data on what state the video is at when
- // the user has exited.
- enum UnloadedState {
- ENDED = 0,
- PAUSED = 1,
- STALLED = 2,
- SEEKING = 3,
- OTHER = 4
- };
-
- UnloadedState state = OTHER;
- if (Seeking()) {
- state = SEEKING;
- }
- else if (Ended()) {
- state = ENDED;
- }
- else if (Paused()) {
- state = PAUSED;
- }
- else {
- // For buffering we check if the current playback position is at the end
- // of a buffered range, within a margin of error. We also consider to be
- // buffering if the last frame status was buffering and the ready state is
- // HAVE_CURRENT_DATA to account for times where we are in a buffering state
- // regardless of what actual data we have buffered.
- bool stalled = false;
- RefPtr<TimeRanges> ranges = Buffered();
- const double errorMargin = 0.05;
- double t = CurrentTime();
- TimeRanges::index_type index = ranges->Find(t, errorMargin);
- ErrorResult ignore;
- stalled = index != TimeRanges::NoIndex &&
- (ranges->End(index, ignore) - t) < errorMargin;
- stalled |= mDecoder && NextFrameStatus() == MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE_BUFFERING &&
- mReadyState == HTMLMediaElement::HAVE_CURRENT_DATA;
- if (stalled) {
- state = STALLED;
- }
- }
-
- Telemetry::Accumulate(Telemetry::VIDEO_UNLOAD_STATE, state);
- LOG(LogLevel::Debug, ("%p VIDEO_UNLOAD_STATE = %d", this, state));
-
- FrameStatisticsData data;
-
- if (HTMLVideoElement* vid = HTMLVideoElement::FromContentOrNull(this)) {
- FrameStatistics* stats = vid->GetFrameStatistics();
- if (stats) {
- data = stats->GetFrameStatisticsData();
- if (data.mParsedFrames) {
- MOZ_ASSERT(data.mDroppedFrames <= data.mParsedFrames);
- // Dropped frames <= total frames, so 'percentage' cannot be higher than
- // 100 and therefore can fit in a uint32_t (that Telemetry takes).
- uint32_t percentage = 100 * data.mDroppedFrames / data.mParsedFrames;
- LOG(LogLevel::Debug,
- ("Reporting telemetry DROPPED_FRAMES_IN_VIDEO_PLAYBACK"));
- Telemetry::Accumulate(Telemetry::VIDEO_DROPPED_FRAMES_PROPORTION,
- percentage);
- }
- }
- }
-
- if (mMediaInfo.HasVideo() &&
- mMediaInfo.mVideo.mImage.height > 0) {
- // We have a valid video.
- double playTime = mPlayTime.Total();
- double hiddenPlayTime = mHiddenPlayTime.Total();
- double videoDecodeSuspendTime = mVideoDecodeSuspendTime.Total();
-
- Telemetry::Accumulate(Telemetry::VIDEO_PLAY_TIME_MS, SECONDS_TO_MS(playTime));
- LOG(LogLevel::Debug, ("%p VIDEO_PLAY_TIME_MS = %f", this, playTime));
-
- Telemetry::Accumulate(Telemetry::VIDEO_HIDDEN_PLAY_TIME_MS, SECONDS_TO_MS(hiddenPlayTime));
- LOG(LogLevel::Debug, ("%p VIDEO_HIDDEN_PLAY_TIME_MS = %f", this, hiddenPlayTime));
-
- if (playTime > 0.0) {
- // We have actually played something -> Report some valid-video telemetry.
-
- // Keyed by audio+video or video alone, and by a resolution range.
- nsCString key(mMediaInfo.HasAudio() ? "AV," : "V,");
- static const struct { int32_t mH; const char* mRes; } sResolutions[] = {
- { 240, "0<h<=240" },
- { 480, "240<h<=480" },
- { 576, "480<h<=576" },
- { 720, "576<h<=720" },
- { 1080, "720<h<=1080" },
- { 2160, "1080<h<=2160" }
- };
- const char* resolution = "h>2160";
- int32_t height = mMediaInfo.mVideo.mImage.height;
- for (const auto& res : sResolutions) {
- if (height <= res.mH) {
- resolution = res.mRes;
- break;
- }
- }
- key.AppendASCII(resolution);
-
- uint32_t hiddenPercentage = uint32_t(hiddenPlayTime / playTime * 100.0 + 0.5);
- Telemetry::Accumulate(Telemetry::VIDEO_HIDDEN_PLAY_TIME_PERCENTAGE,
- key,
- hiddenPercentage);
- // Also accumulate all percentages in an "All" key.
- Telemetry::Accumulate(Telemetry::VIDEO_HIDDEN_PLAY_TIME_PERCENTAGE,
- NS_LITERAL_CSTRING("All"),
- hiddenPercentage);
- LOG(LogLevel::Debug, ("%p VIDEO_HIDDEN_PLAY_TIME_PERCENTAGE = %u, keys: '%s' and 'All'",
- this, hiddenPercentage, key.get()));
-
- uint32_t videoDecodeSuspendPercentage =
- uint32_t(videoDecodeSuspendTime / playTime * 100.0 + 0.5);
- Telemetry::Accumulate(Telemetry::VIDEO_INFERRED_DECODE_SUSPEND_PERCENTAGE,
- key,
- videoDecodeSuspendPercentage);
- Telemetry::Accumulate(Telemetry::VIDEO_INFERRED_DECODE_SUSPEND_PERCENTAGE,
- NS_LITERAL_CSTRING("All"),
- videoDecodeSuspendPercentage);
- LOG(LogLevel::Debug, ("%p VIDEO_INFERRED_DECODE_SUSPEND_PERCENTAGE = %u, keys: '%s' and 'All'",
- this, videoDecodeSuspendPercentage, key.get()));
-
- if (data.mInterKeyframeCount != 0) {
- uint32_t average_ms =
- uint32_t(std::min<uint64_t>(double(data.mInterKeyframeSum_us)
- / double(data.mInterKeyframeCount)
- / 1000.0
- + 0.5,
- UINT32_MAX));
- Telemetry::Accumulate(Telemetry::VIDEO_INTER_KEYFRAME_AVERAGE_MS,
- key,
- average_ms);
- Telemetry::Accumulate(Telemetry::VIDEO_INTER_KEYFRAME_AVERAGE_MS,
- NS_LITERAL_CSTRING("All"),
- average_ms);
- LOG(LogLevel::Debug, ("%p VIDEO_INTER_KEYFRAME_AVERAGE_MS = %u, keys: '%s' and 'All'",
- this, average_ms, key.get()));
-
- uint32_t max_ms =
- uint32_t(std::min<uint64_t>((data.mInterKeyFrameMax_us + 500) / 1000,
- UINT32_MAX));
- Telemetry::Accumulate(Telemetry::VIDEO_INTER_KEYFRAME_MAX_MS,
- key,
- max_ms);
- Telemetry::Accumulate(Telemetry::VIDEO_INTER_KEYFRAME_MAX_MS,
- NS_LITERAL_CSTRING("All"),
- max_ms);
- LOG(LogLevel::Debug, ("%p VIDEO_INTER_KEYFRAME_MAX_MS = %u, keys: '%s' and 'All'",
- this, max_ms, key.get()));
- } else {
- // Here, we have played *some* of the video, but didn't get more than 1
- // keyframe. Report '0' if we have played for longer than the video-
- // decode-suspend delay (showing recovery would be difficult).
- uint32_t suspendDelay_ms = MediaPrefs::MDSMSuspendBackgroundVideoDelay();
- if (uint32_t(playTime * 1000.0) > suspendDelay_ms) {
- Telemetry::Accumulate(Telemetry::VIDEO_INTER_KEYFRAME_MAX_MS,
- key,
- 0);
- Telemetry::Accumulate(Telemetry::VIDEO_INTER_KEYFRAME_MAX_MS,
- NS_LITERAL_CSTRING("All"),
- 0);
- LOG(LogLevel::Debug, ("%p VIDEO_INTER_KEYFRAME_MAX_MS = 0 (only 1 keyframe), keys: '%s' and 'All'",
- this, key.get()));
- }
- }
- }
- }
-}
-
void HTMLMediaElement::UnbindFromTree(bool aDeep,
bool aNullParent)
{
@@ -5351,19 +5114,6 @@ nsresult HTMLMediaElement::DispatchAsyncEvent(const nsAString& aName)
nsCOMPtr<nsIRunnable> event = new nsAsyncEventRunner(aName, this);
NS_DispatchToMainThread(event);
- if ((aName.EqualsLiteral("play") || aName.EqualsLiteral("playing"))) {
- mPlayTime.Start();
- if (IsHidden()) {
- HiddenVideoStart();
- }
- } else if (aName.EqualsLiteral("waiting")) {
- mPlayTime.Pause();
- HiddenVideoStop();
- } else if (aName.EqualsLiteral("pause")) {
- mPlayTime.Pause();
- HiddenVideoStop();
- }
-
return NS_OK;
}
@@ -5489,11 +5239,6 @@ void HTMLMediaElement::SuspendOrResumeElement(bool aPauseElement, bool aSuspendE
UpdateSrcMediaStreamPlaying();
UpdateAudioChannelPlayingState();
if (aPauseElement) {
- ReportTelemetry();
-#ifdef MOZ_EME
- ReportEMETelemetry();
-#endif
-
#ifdef MOZ_EME
// For EME content, we may force destruction of the CDM client (and CDM
// instance if this is the last client for that CDM instance) and
@@ -5545,13 +5290,6 @@ bool HTMLMediaElement::IsBeingDestroyed()
void HTMLMediaElement::NotifyOwnerDocumentActivityChanged()
{
bool visible = !IsHidden();
- if (visible) {
- // Visible -> Just pause hidden play time (no-op if already paused).
- HiddenVideoStop();
- } else if (mPlayTime.IsStarted()) {
- // Not visible, play time is running -> Start hidden play time if needed.
- HiddenVideoStart();
- }
if (mDecoder && !IsBeingDestroyed()) {
mDecoder->NotifyOwnerActivityChanged(visible);
@@ -6327,18 +6065,10 @@ HTMLMediaElement::OnVisibilityChange(Visibility aNewVisibility)
break;
}
case Visibility::APPROXIMATELY_NONVISIBLE: {
- if (mPlayTime.IsStarted()) {
- // Not visible, play time is running -> Start hidden play time if needed.
- HiddenVideoStart();
- }
-
mDecoder->NotifyOwnerActivityChanged(false);
break;
}
case Visibility::APPROXIMATELY_VISIBLE: {
- // Visible -> Just pause hidden play time (no-op if already paused).
- HiddenVideoStop();
-
mDecoder->NotifyOwnerActivityChanged(true);
break;
}
@@ -6860,97 +6590,6 @@ HTMLMediaElement::MarkAsContentSource(CallerAPI aAPI)
{
const bool isVisible = mVisibilityState != Visibility::APPROXIMATELY_NONVISIBLE;
- if (isVisible) {
- // 0 = ALL_VISIBLE
- Telemetry::Accumulate(Telemetry::VIDEO_AS_CONTENT_SOURCE, 0);
- } else {
- // 1 = ALL_INVISIBLE
- Telemetry::Accumulate(Telemetry::VIDEO_AS_CONTENT_SOURCE, 1);
-
- if (IsInUncomposedDoc()) {
- // 0 = ALL_IN_TREE
- Telemetry::Accumulate(Telemetry::VIDEO_AS_CONTENT_SOURCE_IN_TREE_OR_NOT, 0);
- } else {
- // 1 = ALL_NOT_IN_TREE
- Telemetry::Accumulate(Telemetry::VIDEO_AS_CONTENT_SOURCE_IN_TREE_OR_NOT, 1);
- }
- }
-
- switch (aAPI) {
- case CallerAPI::DRAW_IMAGE: {
- if (isVisible) {
- // 2 = drawImage_VISIBLE
- Telemetry::Accumulate(Telemetry::VIDEO_AS_CONTENT_SOURCE, 2);
- } else {
- // 3 = drawImage_INVISIBLE
- Telemetry::Accumulate(Telemetry::VIDEO_AS_CONTENT_SOURCE, 3);
-
- if (IsInUncomposedDoc()) {
- // 2 = drawImage_IN_TREE
- Telemetry::Accumulate(Telemetry::VIDEO_AS_CONTENT_SOURCE_IN_TREE_OR_NOT, 2);
- } else {
- // 3 = drawImage_NOT_IN_TREE
- Telemetry::Accumulate(Telemetry::VIDEO_AS_CONTENT_SOURCE_IN_TREE_OR_NOT, 3);
- }
- }
- break;
- }
- case CallerAPI::CREATE_PATTERN: {
- if (isVisible) {
- // 4 = createPattern_VISIBLE
- Telemetry::Accumulate(Telemetry::VIDEO_AS_CONTENT_SOURCE, 4);
- } else {
- // 5 = createPattern_INVISIBLE
- Telemetry::Accumulate(Telemetry::VIDEO_AS_CONTENT_SOURCE, 5);
-
- if (IsInUncomposedDoc()) {
- // 4 = createPattern_IN_TREE
- Telemetry::Accumulate(Telemetry::VIDEO_AS_CONTENT_SOURCE_IN_TREE_OR_NOT, 4);
- } else {
- // 5 = createPattern_NOT_IN_TREE
- Telemetry::Accumulate(Telemetry::VIDEO_AS_CONTENT_SOURCE_IN_TREE_OR_NOT, 5);
- }
- }
- break;
- }
- case CallerAPI::CREATE_IMAGEBITMAP: {
- if (isVisible) {
- // 6 = createImageBitmap_VISIBLE
- Telemetry::Accumulate(Telemetry::VIDEO_AS_CONTENT_SOURCE, 6);
- } else {
- // 7 = createImageBitmap_INVISIBLE
- Telemetry::Accumulate(Telemetry::VIDEO_AS_CONTENT_SOURCE, 7);
-
- if (IsInUncomposedDoc()) {
- // 6 = createImageBitmap_IN_TREE
- Telemetry::Accumulate(Telemetry::VIDEO_AS_CONTENT_SOURCE_IN_TREE_OR_NOT, 6);
- } else {
- // 7 = createImageBitmap_NOT_IN_TREE
- Telemetry::Accumulate(Telemetry::VIDEO_AS_CONTENT_SOURCE_IN_TREE_OR_NOT, 7);
- }
- }
- break;
- }
- case CallerAPI::CAPTURE_STREAM: {
- if (isVisible) {
- // 8 = captureStream_VISIBLE
- Telemetry::Accumulate(Telemetry::VIDEO_AS_CONTENT_SOURCE, 8);
- } else {
- // 9 = captureStream_INVISIBLE
- Telemetry::Accumulate(Telemetry::VIDEO_AS_CONTENT_SOURCE, 9);
-
- if (IsInUncomposedDoc()) {
- // 8 = captureStream_IN_TREE
- Telemetry::Accumulate(Telemetry::VIDEO_AS_CONTENT_SOURCE_IN_TREE_OR_NOT, 8);
- } else {
- // 9 = captureStream_NOT_IN_TREE
- Telemetry::Accumulate(Telemetry::VIDEO_AS_CONTENT_SOURCE_IN_TREE_OR_NOT, 9);
- }
- }
- break;
- }
- }
-
LOG(LogLevel::Debug,
("%p Log VIDEO_AS_CONTENT_SOURCE: visibility = %u, API: '%d' and 'All'",
this, isVisible, aAPI));
diff --git a/dom/html/HTMLMediaElement.h b/dom/html/HTMLMediaElement.h
index af944a318..899e8449a 100644
--- a/dom/html/HTMLMediaElement.h
+++ b/dom/html/HTMLMediaElement.h
@@ -1195,29 +1195,6 @@ protected:
return isPaused;
}
- /**
- * Video has been playing while hidden and, if feature was enabled, would
- * trigger suspending decoder.
- * Used to track hidden-video-decode-suspend telemetry.
- */
- static void VideoDecodeSuspendTimerCallback(nsITimer* aTimer, void* aClosure);
- /**
- * Video is now both: playing and hidden.
- * Used to track hidden-video telemetry.
- */
- void HiddenVideoStart();
- /**
- * Video is not playing anymore and/or has become visible.
- * Used to track hidden-video telemetry.
- */
- void HiddenVideoStop();
-
-#ifdef MOZ_EME
- void ReportEMETelemetry();
-#endif
-
- void ReportTelemetry();
-
// Check the permissions for audiochannel.
bool CheckAudioChannelPermissions(const nsAString& aType);
@@ -1484,9 +1461,6 @@ protected:
// Timer used for updating progress events.
nsCOMPtr<nsITimer> mProgressTimer;
- // Timer used to simulate video-suspend.
- nsCOMPtr<nsITimer> mVideoDecodeSuspendTimer;
-
#ifdef MOZ_EME
// Encrypted Media Extension media keys.
RefPtr<MediaKeys> mMediaKeys;
@@ -1688,65 +1662,7 @@ protected:
// before attaching to the DOM tree.
bool mUnboundFromTree = false;
-public:
- // Helper class to measure times for MSE telemetry stats
- class TimeDurationAccumulator
- {
- public:
- TimeDurationAccumulator()
- : mCount(0)
- {}
- void Start()
- {
- if (IsStarted()) {
- return;
- }
- mStartTime = TimeStamp::Now();
- }
- void Pause()
- {
- if (!IsStarted()) {
- return;
- }
- mSum += (TimeStamp::Now() - mStartTime);
- mCount++;
- mStartTime = TimeStamp();
- }
- bool IsStarted() const
- {
- return !mStartTime.IsNull();
- }
- double Total() const
- {
- if (!IsStarted()) {
- return mSum.ToSeconds();
- }
- // Add current running time until now, but keep it running.
- return (mSum + (TimeStamp::Now() - mStartTime)).ToSeconds();
- }
- uint32_t Count() const
- {
- if (!IsStarted()) {
- return mCount;
- }
- // Count current run in this report, without increasing the stored count.
- return mCount + 1;
- }
- private:
- TimeStamp mStartTime;
- TimeDuration mSum;
- uint32_t mCount;
- };
private:
- // Total time a video has spent playing.
- TimeDurationAccumulator mPlayTime;
-
- // Total time a video has spent playing while hidden.
- TimeDurationAccumulator mHiddenPlayTime;
-
- // Total time a video has (or would have) spent in video-decode-suspend mode.
- TimeDurationAccumulator mVideoDecodeSuspendTime;
-
// Indicates if user has interacted with the element.
// Used to block autoplay when disabled.
bool mHasUserInteraction;
diff --git a/dom/html/HTMLOptionsCollection.cpp b/dom/html/HTMLOptionsCollection.cpp
index 294493c0c..67de97fc4 100644
--- a/dom/html/HTMLOptionsCollection.cpp
+++ b/dom/html/HTMLOptionsCollection.cpp
@@ -35,23 +35,8 @@ namespace mozilla {
namespace dom {
HTMLOptionsCollection::HTMLOptionsCollection(HTMLSelectElement* aSelect)
-{
- // Do not maintain a reference counted reference. When
- // the select goes away, it will let us know.
- mSelect = aSelect;
-}
-
-HTMLOptionsCollection::~HTMLOptionsCollection()
-{
- DropReference();
-}
-
-void
-HTMLOptionsCollection::DropReference()
-{
- // Drop our (non ref-counted) reference
- mSelect = nullptr;
-}
+ : mSelect(aSelect)
+{}
nsresult
HTMLOptionsCollection::GetOptionIndex(Element* aOption,
@@ -88,7 +73,9 @@ HTMLOptionsCollection::GetOptionIndex(Element* aOption,
}
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(HTMLOptionsCollection, mElements)
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(HTMLOptionsCollection,
+ mElements,
+ mSelect)
// nsISupports
@@ -124,10 +111,6 @@ HTMLOptionsCollection::GetLength(uint32_t* aLength)
NS_IMETHODIMP
HTMLOptionsCollection::SetLength(uint32_t aLength)
{
- if (!mSelect) {
- return NS_ERROR_UNEXPECTED;
- }
-
return mSelect->SetLength(aLength);
}
@@ -135,10 +118,6 @@ NS_IMETHODIMP
HTMLOptionsCollection::SetOption(uint32_t aIndex,
nsIDOMHTMLOptionElement* aOption)
{
- if (!mSelect) {
- return NS_OK;
- }
-
// if the new option is null, just remove this option. Note that it's safe
// to pass a too-large aIndex in here.
if (!aOption) {
@@ -187,11 +166,6 @@ HTMLOptionsCollection::SetOption(uint32_t aIndex,
int32_t
HTMLOptionsCollection::GetSelectedIndex(ErrorResult& aError)
{
- if (!mSelect) {
- aError.Throw(NS_ERROR_UNEXPECTED);
- return 0;
- }
-
int32_t selectedIndex;
aError = mSelect->GetSelectedIndex(&selectedIndex);
return selectedIndex;
@@ -209,11 +183,6 @@ void
HTMLOptionsCollection::SetSelectedIndex(int32_t aSelectedIndex,
ErrorResult& aError)
{
- if (!mSelect) {
- aError.Throw(NS_ERROR_UNEXPECTED);
- return;
- }
-
aError = mSelect->SetSelectedIndex(aSelectedIndex);
}
@@ -339,22 +308,12 @@ HTMLOptionsCollection::Add(const HTMLOptionOrOptGroupElement& aElement,
const Nullable<HTMLElementOrLong>& aBefore,
ErrorResult& aError)
{
- if (!mSelect) {
- aError.Throw(NS_ERROR_NOT_INITIALIZED);
- return;
- }
-
mSelect->Add(aElement, aBefore, aError);
}
void
HTMLOptionsCollection::Remove(int32_t aIndex, ErrorResult& aError)
{
- if (!mSelect) {
- aError.Throw(NS_ERROR_UNEXPECTED);
- return;
- }
-
uint32_t len = 0;
mSelect->GetLength(&len);
if (aIndex < 0 || (uint32_t)aIndex >= len)
diff --git a/dom/html/HTMLOptionsCollection.h b/dom/html/HTMLOptionsCollection.h
index 21123b3d2..496919555 100644
--- a/dom/html/HTMLOptionsCollection.h
+++ b/dom/html/HTMLOptionsCollection.h
@@ -46,7 +46,7 @@ public:
using nsWrapperCache::GetWrapper;
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
protected:
- virtual ~HTMLOptionsCollection();
+ virtual ~HTMLOptionsCollection() = default;
virtual JSObject* GetWrapperPreserveColorInternal() override
{
@@ -113,11 +113,6 @@ public:
}
/**
- * Drop the reference to the select. Called during select destruction.
- */
- void DropReference();
-
- /**
* Finds the index of a given option element.
* If the option isn't part of the collection, return NS_ERROR_FAILURE
* without setting aIndex.
@@ -161,7 +156,7 @@ private:
* various members such as InsertOptionAt are also infallible. */
nsTArray<RefPtr<mozilla::dom::HTMLOptionElement> > mElements;
/** The select element that contains this array */
- HTMLSelectElement* mSelect;
+ RefPtr<HTMLSelectElement> mSelect;
};
} // namespace dom
diff --git a/dom/html/HTMLSelectElement.cpp b/dom/html/HTMLSelectElement.cpp
index 53f42317a..9ba0a1efe 100644
--- a/dom/html/HTMLSelectElement.cpp
+++ b/dom/html/HTMLSelectElement.cpp
@@ -130,11 +130,6 @@ HTMLSelectElement::HTMLSelectElement(already_AddRefed<mozilla::dom::NodeInfo>& a
NS_EVENT_STATE_VALID);
}
-HTMLSelectElement::~HTMLSelectElement()
-{
- mOptions->DropReference();
-}
-
// ISupports
NS_IMPL_CYCLE_COLLECTION_CLASS(HTMLSelectElement)
diff --git a/dom/html/HTMLSelectElement.h b/dom/html/HTMLSelectElement.h
index 8a25385de..dc1075cd7 100644
--- a/dom/html/HTMLSelectElement.h
+++ b/dom/html/HTMLSelectElement.h
@@ -436,7 +436,7 @@ public:
void SetOpenInParentProcess(bool aVal);
protected:
- virtual ~HTMLSelectElement();
+ virtual ~HTMLSelectElement() = default;
friend class SafeOptionListMutation;
diff --git a/dom/html/HTMLTableElement.cpp b/dom/html/HTMLTableElement.cpp
index ec1b7cecb..c5b7696cf 100644
--- a/dom/html/HTMLTableElement.cpp
+++ b/dom/html/HTMLTableElement.cpp
@@ -421,11 +421,10 @@ HTMLTableElement::CreateTHead()
void
HTMLTableElement::DeleteTHead()
{
- HTMLTableSectionElement* tHead = GetTHead();
+ RefPtr<HTMLTableSectionElement> tHead = GetTHead();
if (tHead) {
- mozilla::ErrorResult rv;
+ mozilla::IgnoredErrorResult rv;
nsINode::RemoveChild(*tHead, rv);
- MOZ_ASSERT(!rv.Failed());
}
}
@@ -452,11 +451,10 @@ HTMLTableElement::CreateTFoot()
void
HTMLTableElement::DeleteTFoot()
{
- HTMLTableSectionElement* tFoot = GetTFoot();
+ RefPtr<HTMLTableSectionElement> tFoot = GetTFoot();
if (tFoot) {
- mozilla::ErrorResult rv;
+ mozilla::IgnoredErrorResult rv;
nsINode::RemoveChild(*tFoot, rv);
- MOZ_ASSERT(!rv.Failed());
}
}
@@ -483,11 +481,10 @@ HTMLTableElement::CreateCaption()
void
HTMLTableElement::DeleteCaption()
{
- HTMLTableCaptionElement* caption = GetCaption();
+ RefPtr<HTMLTableCaptionElement> caption = GetCaption();
if (caption) {
- mozilla::ErrorResult rv;
+ mozilla::IgnoredErrorResult rv;
nsINode::RemoveChild(*caption, rv);
- MOZ_ASSERT(!rv.Failed());
}
}
diff --git a/dom/html/HTMLTableSectionElement.cpp b/dom/html/HTMLTableSectionElement.cpp
index c7b0665dd..e99597636 100644
--- a/dom/html/HTMLTableSectionElement.cpp
+++ b/dom/html/HTMLTableSectionElement.cpp
@@ -122,7 +122,7 @@ HTMLTableSectionElement::DeleteRow(int32_t aValue, ErrorResult& aError)
refIndex = (uint32_t)aValue;
}
- nsINode* row = rows->Item(refIndex);
+ nsCOMPtr<nsINode> row = rows->Item(refIndex);
if (!row) {
aError.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
return;
diff --git a/dom/html/ImageDocument.cpp b/dom/html/ImageDocument.cpp
index 200bb5d46..f83a804be 100644
--- a/dom/html/ImageDocument.cpp
+++ b/dom/html/ImageDocument.cpp
@@ -40,12 +40,14 @@
#include "nsThreadUtils.h"
#include "nsIScrollableFrame.h"
#include "nsContentUtils.h"
+#include "nsCSSParser.h" // for CSS colors on the background
#include "mozilla/dom/Element.h"
#include "mozilla/Preferences.h"
#include <algorithm>
#define AUTOMATIC_IMAGE_RESIZING_PREF "browser.enable_automatic_image_resizing"
#define CLICK_IMAGE_RESIZING_PREF "browser.enable_click_image_resizing"
+#define STANDALONE_IMAGE_BACKGROUND_COLOR_PREF "browser.display.standalone_images.background_color"
//XXX A hack needed for Firefox's site specific zoom.
#define SITE_SPECIFIC_ZOOM "browser.zoom.siteSpecific"
@@ -170,6 +172,8 @@ ImageDocument::Init()
mClickResizingEnabled = Preferences::GetBool(CLICK_IMAGE_RESIZING_PREF);
mShouldResize = mResizeImageByDefault;
mFirstResize = true;
+
+ mBackgroundColor = Preferences::GetString(STANDALONE_IMAGE_BACKGROUND_COLOR_PREF);
return NS_OK;
}
@@ -682,9 +686,22 @@ ImageDocument::CreateSyntheticDocument()
mImageContent->SetAttr(kNameSpaceID_None, nsGkAtoms::src, srcString, false);
mImageContent->SetAttr(kNameSpaceID_None, nsGkAtoms::alt, srcString, false);
+ // Implement mechanism for custom background color from pref.
+ if (!mBackgroundColor.IsEmpty()) {
+ nsCSSValue color;
+ nsCSSParser parser;
+ if (parser.ParseColorString(mBackgroundColor, nullptr, 0, color)) {
+ nsAutoString styleAttr(NS_LITERAL_STRING("background-color: "));
+ styleAttr.Append(mBackgroundColor);
+ body->SetAttr(kNameSpaceID_None, nsGkAtoms::style, styleAttr, false);
+ }
+ }
+
body->AppendChildTo(mImageContent, false);
imageLoader->SetLoadingEnabled(true);
+ UpdateTitleAndCharset();
+
return NS_OK;
}
diff --git a/dom/html/ImageDocument.h b/dom/html/ImageDocument.h
index fdf2a00a8..945317314 100644
--- a/dom/html/ImageDocument.h
+++ b/dom/html/ImageDocument.h
@@ -112,6 +112,9 @@ protected:
float mVisibleHeight;
int32_t mImageWidth;
int32_t mImageHeight;
+
+ // Holds the custom background color for stand-alone images
+ nsAutoString mBackgroundColor;
bool mResizeImageByDefault;
bool mClickResizingEnabled;
diff --git a/dom/html/TextTrackManager.cpp b/dom/html/TextTrackManager.cpp
index 8110dab29..7f9d32794 100644
--- a/dom/html/TextTrackManager.cpp
+++ b/dom/html/TextTrackManager.cpp
@@ -12,7 +12,6 @@
#include "mozilla/dom/TextTrackCue.h"
#include "mozilla/dom/Event.h"
#include "mozilla/ClearOnShutdown.h"
-#include "mozilla/Telemetry.h"
#include "nsComponentManagerUtils.h"
#include "nsVariant.h"
#include "nsVideoFrame.h"
@@ -30,6 +29,13 @@ namespace dom {
NS_IMPL_ISUPPORTS(TextTrackManager::ShutdownObserverProxy, nsIObserver);
+void
+TextTrackManager::ShutdownObserverProxy::Unregister()
+{
+ nsContentUtils::UnregisterShutdownObserver(this);
+ mManager = nullptr;
+}
+
CompareTextTracks::CompareTextTracks(HTMLMediaElement* aMediaElement)
{
mMediaElement = aMediaElement;
@@ -112,7 +118,6 @@ TextTrackManager::TextTrackManager(HTMLMediaElement *aMediaElement)
, mTimeMarchesOnDispatched(false)
, mUpdateCueDisplayDispatched(false)
, performedTrackSelection(false)
- , mCueTelemetryReported(false)
, mShutdown(false)
{
nsISupports* parentObject =
@@ -138,7 +143,7 @@ TextTrackManager::TextTrackManager(HTMLMediaElement *aMediaElement)
TextTrackManager::~TextTrackManager()
{
WEBVTT_LOG("%p ~TextTrackManager",this);
- nsContentUtils::UnregisterShutdownObserver(mShutdownProxy);
+ mShutdownProxy->Unregister();
}
TextTrackList*
@@ -164,7 +169,6 @@ TextTrackManager::AddTextTrack(TextTrackKind aKind, const nsAString& aLabel,
mTextTracks->AddTextTrack(aKind, aLabel, aLanguage, aMode, aReadyState,
aTextTrackSource, CompareTextTracks(mMediaElement));
AddCues(track);
- ReportTelemetryForTrack(track);
if (aTextTrackSource == TextTrackSource::Track) {
RefPtr<nsIRunnable> task =
@@ -184,7 +188,6 @@ TextTrackManager::AddTextTrack(TextTrack* aTextTrack)
WEBVTT_LOG("%p AddTextTrack TextTrack %p",this, aTextTrack);
mTextTracks->AddTextTrack(aTextTrack, CompareTextTracks(mMediaElement));
AddCues(aTextTrack);
- ReportTelemetryForTrack(aTextTrack);
if (aTextTrack->GetTextTrackSource() == TextTrackSource::Track) {
RefPtr<nsIRunnable> task =
@@ -303,7 +306,6 @@ TextTrackManager::NotifyCueAdded(TextTrackCue& aCue)
mNewCues->AddCue(aCue);
}
DispatchTimeMarchesOn();
- ReportTelemetryForCue();
}
void
@@ -821,28 +823,5 @@ TextTrackManager::NotifyReset()
mLastTimeMarchesOnCalled = 0.0;
}
-void
-TextTrackManager::ReportTelemetryForTrack(TextTrack* aTextTrack) const
-{
- MOZ_ASSERT(NS_IsMainThread());
- MOZ_ASSERT(aTextTrack);
- MOZ_ASSERT(mTextTracks->Length() > 0);
-
- TextTrackKind kind = aTextTrack->Kind();
- Telemetry::Accumulate(Telemetry::WEBVTT_TRACK_KINDS, uint32_t(kind));
-}
-
-void
-TextTrackManager::ReportTelemetryForCue()
-{
- MOZ_ASSERT(NS_IsMainThread());
- MOZ_ASSERT(!mNewCues->IsEmpty() || !mLastActiveCues->IsEmpty());
-
- if (!mCueTelemetryReported) {
- Telemetry::Accumulate(Telemetry::WEBVTT_USED_VTT_CUES, 1);
- mCueTelemetryReported = true;
- }
-}
-
} // namespace dom
} // namespace mozilla
diff --git a/dom/html/TextTrackManager.h b/dom/html/TextTrackManager.h
index d20707346..2375aa4bb 100644
--- a/dom/html/TextTrackManager.h
+++ b/dom/html/TextTrackManager.h
@@ -148,13 +148,6 @@ private:
nsTArray<TextTrack*>& aTextTracks);
bool TrackIsDefault(TextTrack* aTextTrack);
- void ReportTelemetryForTrack(TextTrack* aTextTrack) const;
- void ReportTelemetryForCue();
-
- // If there is at least one cue has been added to the cue list once, we would
- // report the usage of cue to Telemetry.
- bool mCueTelemetryReported;
-
class ShutdownObserverProxy final : public nsIObserver
{
NS_DECL_ISUPPORTS
@@ -170,11 +163,15 @@ private:
{
MOZ_ASSERT(NS_IsMainThread());
if (strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0) {
- nsContentUtils::UnregisterShutdownObserver(this);
- mManager->NotifyShutdown();
+ if (mManager) {
+ mManager->NotifyShutdown();
+ }
+ Unregister();
}
return NS_OK;
}
+
+ void Unregister();
private:
~ShutdownObserverProxy() {};
diff --git a/dom/html/nsDOMStringMap.cpp b/dom/html/nsDOMStringMap.cpp
index 42725bc6f..6d2bc424d 100644
--- a/dom/html/nsDOMStringMap.cpp
+++ b/dom/html/nsDOMStringMap.cpp
@@ -19,7 +19,6 @@ using namespace mozilla::dom;
NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMStringMap)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDOMStringMap)
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mElement)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
diff --git a/dom/html/nsGenericHTMLElement.h b/dom/html/nsGenericHTMLElement.h
index 0635c27e1..24a7a3652 100644
--- a/dom/html/nsGenericHTMLElement.h
+++ b/dom/html/nsGenericHTMLElement.h
@@ -396,13 +396,6 @@ public:
}
NS_IMETHOD InsertAdjacentHTML(const nsAString& position,
const nsAString& text) final override;
- NS_IMETHOD ScrollIntoView(bool top, uint8_t _argc) final override {
- if (!_argc) {
- top = true;
- }
- mozilla::dom::Element::ScrollIntoView(top);
- return NS_OK;
- }
NS_IMETHOD GetOffsetParent(nsIDOMElement** aOffsetParent)
final override {
mozilla::dom::Element* offsetParent = GetOffsetParent();
diff --git a/dom/html/nsTextEditorState.cpp b/dom/html/nsTextEditorState.cpp
index 187afb66d..25be6016c 100644
--- a/dom/html/nsTextEditorState.cpp
+++ b/dom/html/nsTextEditorState.cpp
@@ -47,7 +47,6 @@
#include "mozilla/dom/HTMLInputElement.h"
#include "nsNumberControlFrame.h"
#include "nsFrameSelection.h"
-#include "mozilla/Telemetry.h"
#include "mozilla/layers/ScrollInputMethods.h"
using namespace mozilla;
@@ -585,9 +584,6 @@ nsTextInputSelectionImpl::CompleteScroll(bool aForward)
if (!mScrollFrame)
return NS_ERROR_NOT_INITIALIZED;
- mozilla::Telemetry::Accumulate(mozilla::Telemetry::SCROLL_INPUT_METHODS,
- (uint32_t) ScrollInputMethod::MainThreadCompleteScroll);
-
mScrollFrame->ScrollBy(nsIntPoint(0, aForward ? 1 : -1),
nsIScrollableFrame::WHOLE,
nsIScrollableFrame::INSTANT);
@@ -640,9 +636,6 @@ nsTextInputSelectionImpl::ScrollPage(bool aForward)
if (!mScrollFrame)
return NS_ERROR_NOT_INITIALIZED;
- mozilla::Telemetry::Accumulate(mozilla::Telemetry::SCROLL_INPUT_METHODS,
- (uint32_t) ScrollInputMethod::MainThreadScrollPage);
-
mScrollFrame->ScrollBy(nsIntPoint(0, aForward ? 1 : -1),
nsIScrollableFrame::PAGES,
nsIScrollableFrame::SMOOTH);
@@ -655,9 +648,6 @@ nsTextInputSelectionImpl::ScrollLine(bool aForward)
if (!mScrollFrame)
return NS_ERROR_NOT_INITIALIZED;
- mozilla::Telemetry::Accumulate(mozilla::Telemetry::SCROLL_INPUT_METHODS,
- (uint32_t) ScrollInputMethod::MainThreadScrollLine);
-
mScrollFrame->ScrollBy(nsIntPoint(0, aForward ? 1 : -1),
nsIScrollableFrame::LINES,
nsIScrollableFrame::SMOOTH);
@@ -670,9 +660,6 @@ nsTextInputSelectionImpl::ScrollCharacter(bool aRight)
if (!mScrollFrame)
return NS_ERROR_NOT_INITIALIZED;
- mozilla::Telemetry::Accumulate(mozilla::Telemetry::SCROLL_INPUT_METHODS,
- (uint32_t) ScrollInputMethod::MainThreadScrollCharacter);
-
mScrollFrame->ScrollBy(nsIntPoint(aRight ? 1 : -1, 0),
nsIScrollableFrame::LINES,
nsIScrollableFrame::SMOOTH);
@@ -2268,7 +2255,11 @@ nsTextEditorState::UpdatePlaceholderText(bool aNotify)
nsCOMPtr<nsIContent> content = do_QueryInterface(mTextCtrlElement);
content->GetAttr(kNameSpaceID_None, nsGkAtoms::placeholder, placeholderValue);
- nsContentUtils::RemoveNewlines(placeholderValue);
+ if (mTextCtrlElement->IsTextArea()) { // <textarea>s preserve newlines...
+ nsContentUtils::PlatformToDOMLineBreaks(placeholderValue);
+ } else { // ...<input>s don't
+ nsContentUtils::RemoveNewlines(placeholderValue);
+ }
NS_ASSERTION(mPlaceholderDiv->GetFirstChild(), "placeholder div has no child");
mPlaceholderDiv->GetFirstChild()->SetText(placeholderValue, aNotify);
}
diff --git a/dom/indexedDB/ActorsChild.cpp b/dom/indexedDB/ActorsChild.cpp
index 3e8f97348..c4fcceb90 100644
--- a/dom/indexedDB/ActorsChild.cpp
+++ b/dom/indexedDB/ActorsChild.cpp
@@ -3456,6 +3456,8 @@ BackgroundCursorChild::RecvResponse(const CursorResponse& aResponse)
RefPtr<IDBCursor> cursor;
mStrongCursor.swap(cursor);
+
+ RefPtr<IDBTransaction> transaction = mTransaction;
switch (aResponse.type()) {
case CursorResponse::Tnsresult:
@@ -3486,7 +3488,7 @@ BackgroundCursorChild::RecvResponse(const CursorResponse& aResponse)
MOZ_CRASH("Should never get here!");
}
- mTransaction->OnRequestFinished(/* aActorDestroyedNormally */ true);
+ transaction->OnRequestFinished(/* aActorDestroyedNormally */ true);
return true;
}
diff --git a/dom/indexedDB/ActorsParent.cpp b/dom/indexedDB/ActorsParent.cpp
index e6fe9e2a8..38621cee3 100644
--- a/dom/indexedDB/ActorsParent.cpp
+++ b/dom/indexedDB/ActorsParent.cpp
@@ -23,6 +23,7 @@
#include "mozilla/AppProcessChecker.h"
#include "mozilla/AutoRestore.h"
#include "mozilla/Casting.h"
+#include "mozilla/CheckedInt.h"
#include "mozilla/EndianUtils.h"
#include "mozilla/ErrorNames.h"
#include "mozilla/LazyIdleThread.h"
@@ -249,8 +250,6 @@ const char kSQLiteJournalSuffix[] = ".sqlite-journal";
const char kSQLiteSHMSuffix[] = ".sqlite-shm";
const char kSQLiteWALSuffix[] = ".sqlite-wal";
-const char kPrefIndexedDBEnabled[] = "dom.indexedDB.enabled";
-
const char kPrefFileHandleEnabled[] = "dom.fileHandle.enabled";
#define IDB_PREFIX "indexedDB"
@@ -784,29 +783,25 @@ MakeCompressedIndexDataValues(
MOZ_ASSERT(!keyBuffer.IsEmpty());
- // Don't let |infoLength| overflow.
- if (NS_WARN_IF(UINT32_MAX - keyBuffer.Length() <
- CompressedByteCountForIndexId(info.mIndexId) +
- CompressedByteCountForNumber(keyBufferLength) +
- CompressedByteCountForNumber(sortKeyBufferLength))) {
- IDB_REPORT_INTERNAL_ERR();
- return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
- }
-
- const uint32_t infoLength =
- CompressedByteCountForIndexId(info.mIndexId) +
+ const CheckedUint32 infoLength =
+ CheckedUint32(CompressedByteCountForIndexId(info.mIndexId)) +
CompressedByteCountForNumber(keyBufferLength) +
CompressedByteCountForNumber(sortKeyBufferLength) +
keyBufferLength +
sortKeyBufferLength;
+ // Don't let |infoLength| overflow.
+ if (NS_WARN_IF(!infoLength.isValid())) {
+ IDB_REPORT_INTERNAL_ERR();
+ return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
+ }
// Don't let |blobDataLength| overflow.
- if (NS_WARN_IF(UINT32_MAX - infoLength < blobDataLength)) {
+ if (NS_WARN_IF(UINT32_MAX - infoLength.value() < blobDataLength)) {
IDB_REPORT_INTERNAL_ERR();
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
- blobDataLength += infoLength;
+ blobDataLength += infoLength.value();
}
UniqueFreePtr<uint8_t> blobData(
@@ -4134,7 +4129,6 @@ GetDatabaseFileURL(nsIFile* aDatabaseFile,
PersistenceType aPersistenceType,
const nsACString& aGroup,
const nsACString& aOrigin,
- uint32_t aTelemetryId,
nsIFileURL** aResult)
{
MOZ_ASSERT(aDatabaseFile);
@@ -4166,18 +4160,10 @@ GetDatabaseFileURL(nsIFile* aDatabaseFile,
nsAutoCString type;
PersistenceTypeToText(aPersistenceType, type);
- nsAutoCString telemetryFilenameClause;
- if (aTelemetryId) {
- telemetryFilenameClause.AssignLiteral("&telemetryFilename=indexedDB-");
- telemetryFilenameClause.AppendInt(aTelemetryId);
- telemetryFilenameClause.AppendLiteral(".sqlite");
- }
-
rv = fileUrl->SetQuery(NS_LITERAL_CSTRING("persistenceType=") + type +
NS_LITERAL_CSTRING("&group=") + aGroup +
NS_LITERAL_CSTRING("&origin=") + aOrigin +
- NS_LITERAL_CSTRING("&cache=private") +
- telemetryFilenameClause);
+ NS_LITERAL_CSTRING("&cache=private"));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@@ -4427,7 +4413,6 @@ CreateStorageConnection(nsIFile* aDBFile,
PersistenceType aPersistenceType,
const nsACString& aGroup,
const nsACString& aOrigin,
- uint32_t aTelemetryId,
mozIStorageConnection** aConnection)
{
AssertIsOnIOThread();
@@ -4459,7 +4444,6 @@ CreateStorageConnection(nsIFile* aDBFile,
aPersistenceType,
aGroup,
aOrigin,
- aTelemetryId,
getter_AddRefs(dbFileUrl));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
@@ -4895,7 +4879,6 @@ GetStorageConnection(nsIFile* aDatabaseFile,
PersistenceType aPersistenceType,
const nsACString& aGroup,
const nsACString& aOrigin,
- uint32_t aTelemetryId,
mozIStorageConnection** aConnection)
{
MOZ_ASSERT(!NS_IsMainThread());
@@ -4923,7 +4906,6 @@ GetStorageConnection(nsIFile* aDatabaseFile,
aPersistenceType,
aGroup,
aOrigin,
- aTelemetryId,
getter_AddRefs(dbFileUrl));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
@@ -4960,7 +4942,6 @@ GetStorageConnection(const nsAString& aDatabaseFilePath,
PersistenceType aPersistenceType,
const nsACString& aGroup,
const nsACString& aOrigin,
- uint32_t aTelemetryId,
mozIStorageConnection** aConnection)
{
MOZ_ASSERT(!NS_IsMainThread());
@@ -4979,7 +4960,6 @@ GetStorageConnection(const nsAString& aDatabaseFilePath,
aPersistenceType,
aGroup,
aOrigin,
- aTelemetryId,
aConnection);
}
@@ -6301,7 +6281,6 @@ private:
const nsCString mId;
const nsString mFilePath;
uint32_t mActiveMutableFileCount;
- const uint32_t mTelemetryId;
const PersistenceType mPersistenceType;
const bool mFileHandleDisabled;
const bool mChromeWriteAccessAllowed;
@@ -6318,7 +6297,6 @@ public:
const Maybe<ContentParentId>& aOptionalContentParentId,
const nsACString& aGroup,
const nsACString& aOrigin,
- uint32_t aTelemetryId,
FullDatabaseMetadata* aMetadata,
FileManager* aFileManager,
already_AddRefed<DirectoryLock> aDirectoryLock,
@@ -6377,12 +6355,6 @@ public:
return mId;
}
- uint32_t
- TelemetryId() const
- {
- return mTelemetryId;
- }
-
PersistenceType
Type() const
{
@@ -7678,8 +7650,6 @@ class OpenDatabaseOp final
// cycles.
VersionChangeOp* mVersionChangeOp;
- uint32_t mTelemetryId;
-
public:
OpenDatabaseOp(Factory* aFactory,
already_AddRefed<ContentParent> aContentParent,
@@ -10307,13 +10277,6 @@ typedef nsDataHashtable<nsIDHashKey, DatabaseLoggingInfo*>
StaticAutoPtr<DatabaseLoggingInfoHashtable> gLoggingInfoHashtable;
-typedef nsDataHashtable<nsUint32HashKey, uint32_t> TelemetryIdHashtable;
-
-StaticAutoPtr<TelemetryIdHashtable> gTelemetryIdHashtable;
-
-// Protects all reads and writes to gTelemetryIdHashtable.
-StaticAutoPtr<Mutex> gTelemetryIdMutex;
-
#ifdef DEBUG
StaticRefPtr<DEBUGThreadSlower> gDEBUGThreadSlower;
@@ -10409,88 +10372,6 @@ DecreaseBusyCount()
}
}
-uint32_t
-TelemetryIdForFile(nsIFile* aFile)
-{
- // May be called on any thread!
-
- MOZ_ASSERT(aFile);
- MOZ_ASSERT(gTelemetryIdMutex);
-
- // The storage directory is structured like this:
- //
- // <profile>/storage/<persistence>/<origin>/idb/<filename>.sqlite
- //
- // For the purposes of this function we're only concerned with the
- // <persistence>, <origin>, and <filename> pieces.
-
- nsString filename;
- MOZ_ALWAYS_SUCCEEDS(aFile->GetLeafName(filename));
-
- // Make sure we were given a database file.
- NS_NAMED_LITERAL_STRING(sqliteExtension, ".sqlite");
-
- MOZ_ASSERT(StringEndsWith(filename, sqliteExtension));
-
- filename.Truncate(filename.Length() - sqliteExtension.Length());
-
- // Get the "idb" directory.
- nsCOMPtr<nsIFile> idbDirectory;
- MOZ_ALWAYS_SUCCEEDS(aFile->GetParent(getter_AddRefs(idbDirectory)));
-
- DebugOnly<nsString> idbLeafName;
- MOZ_ASSERT(NS_SUCCEEDED(idbDirectory->GetLeafName(idbLeafName)));
- MOZ_ASSERT(static_cast<nsString&>(idbLeafName).EqualsLiteral("idb"));
-
- // Get the <origin> directory.
- nsCOMPtr<nsIFile> originDirectory;
- MOZ_ALWAYS_SUCCEEDS(
- idbDirectory->GetParent(getter_AddRefs(originDirectory)));
-
- nsString origin;
- MOZ_ALWAYS_SUCCEEDS(originDirectory->GetLeafName(origin));
-
- // Any databases in these directories are owned by the application and should
- // not have their filenames masked. Hopefully they also appear in the
- // Telemetry.cpp whitelist.
- if (origin.EqualsLiteral("chrome") ||
- origin.EqualsLiteral("moz-safe-about+home")) {
- return 0;
- }
-
- // Get the <persistence> directory.
- nsCOMPtr<nsIFile> persistenceDirectory;
- MOZ_ALWAYS_SUCCEEDS(
- originDirectory->GetParent(getter_AddRefs(persistenceDirectory)));
-
- nsString persistence;
- MOZ_ALWAYS_SUCCEEDS(persistenceDirectory->GetLeafName(persistence));
-
- NS_NAMED_LITERAL_STRING(separator, "*");
-
- uint32_t hashValue = HashString(persistence + separator +
- origin + separator +
- filename);
-
- MutexAutoLock lock(*gTelemetryIdMutex);
-
- if (!gTelemetryIdHashtable) {
- gTelemetryIdHashtable = new TelemetryIdHashtable();
- }
-
- uint32_t id;
- if (!gTelemetryIdHashtable->Get(hashValue, &id)) {
- static uint32_t sNextId = 1;
-
- // We're locked, no need for atomics.
- id = sNextId++;
-
- gTelemetryIdHashtable->Put(hashValue, id);
- }
-
- return id;
-}
-
} // namespace
/*******************************************************************************
@@ -12270,7 +12151,6 @@ ConnectionPool::GetOrCreateConnection(const Database* aDatabase,
aDatabase->Type(),
aDatabase->Group(),
aDatabase->Origin(),
- aDatabase->TelemetryId(),
getter_AddRefs(storageConnection));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
@@ -14139,7 +14019,6 @@ Database::Database(Factory* aFactory,
const Maybe<ContentParentId>& aOptionalContentParentId,
const nsACString& aGroup,
const nsACString& aOrigin,
- uint32_t aTelemetryId,
FullDatabaseMetadata* aMetadata,
FileManager* aFileManager,
already_AddRefed<DirectoryLock> aDirectoryLock,
@@ -14156,7 +14035,6 @@ Database::Database(Factory* aFactory,
, mId(aMetadata->mDatabaseId)
, mFilePath(aMetadata->mFilePath)
, mActiveMutableFileCount(0)
- , mTelemetryId(aTelemetryId)
, mPersistenceType(aMetadata->mCommonMetadata.persistenceType())
, mFileHandleDisabled(aFileHandleDisabled)
, mChromeWriteAccessAllowed(aChromeWriteAccessAllowed)
@@ -17396,8 +17274,7 @@ FileManager::InitDirectory(nsIFile* aDirectory,
nsIFile* aDatabaseFile,
PersistenceType aPersistenceType,
const nsACString& aGroup,
- const nsACString& aOrigin,
- uint32_t aTelemetryId)
+ const nsACString& aOrigin)
{
AssertIsOnIOThread();
MOZ_ASSERT(aDirectory);
@@ -17469,7 +17346,6 @@ FileManager::InitDirectory(nsIFile* aDirectory,
aPersistenceType,
aGroup,
aOrigin,
- aTelemetryId,
getter_AddRefs(connection));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
@@ -17653,11 +17529,6 @@ QuotaClient::QuotaClient()
{
AssertIsOnBackgroundThread();
MOZ_ASSERT(!sInstance, "We expect this to be a singleton!");
- MOZ_ASSERT(!gTelemetryIdMutex);
-
- // Always create this so that later access to gTelemetryIdHashtable can be
- // properly synchronized.
- gTelemetryIdMutex = new Mutex("IndexedDB gTelemetryIdMutex");
sInstance = this;
}
@@ -17666,14 +17537,8 @@ QuotaClient::~QuotaClient()
{
AssertIsOnBackgroundThread();
MOZ_ASSERT(sInstance == this, "We expect this to be a singleton!");
- MOZ_ASSERT(gTelemetryIdMutex);
MOZ_ASSERT(!mMaintenanceThreadPool);
- // No one else should be able to touch gTelemetryIdHashtable now that the
- // QuotaClient has gone away.
- gTelemetryIdHashtable = nullptr;
- gTelemetryIdMutex = nullptr;
-
sInstance = nullptr;
}
@@ -17947,8 +17812,7 @@ QuotaClient::InitOrigin(PersistenceType aPersistenceType,
initInfo.mDatabaseFile,
aPersistenceType,
aGroup,
- aOrigin,
- TelemetryIdForFile(initInfo.mDatabaseFile));
+ aOrigin);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@@ -19041,7 +18905,6 @@ DatabaseMaintenance::PerformMaintenanceOnDatabase()
mPersistenceType,
mGroup,
mOrigin,
- TelemetryIdForFile(databaseFile),
getter_AddRefs(connection));
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
@@ -21172,16 +21035,6 @@ FactoryOp::CheckPermission(ContentParent* aContentParent,
return NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR;
}
- if (NS_WARN_IF(!Preferences::GetBool(kPrefIndexedDBEnabled, false))) {
- if (aContentParent) {
- // The DOM in the other process should have kept us from receiving any
- // indexedDB messages so assume that the child is misbehaving.
- aContentParent->KillHard("IndexedDB CheckPermission 1");
- }
-
- return NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR;
- }
-
const ContentPrincipalInfo& contentPrincipalInfo =
principalInfo.get_ContentPrincipalInfo();
if (contentPrincipalInfo.attrs().mPrivateBrowsingId != 0) {
@@ -21668,7 +21521,6 @@ OpenDatabaseOp::OpenDatabaseOp(Factory* aFactory,
, mMetadata(new FullDatabaseMetadata(aParams.metadata()))
, mRequestedVersion(aParams.metadata().version())
, mVersionChangeOp(nullptr)
- , mTelemetryId(0)
{
if (mContentParent) {
// This is a little scary but it looks safe to call this off the main thread
@@ -21777,8 +21629,6 @@ OpenDatabaseOp::DoDatabaseWork()
return rv;
}
- mTelemetryId = TelemetryIdForFile(dbFile);
-
#ifdef DEBUG
nsString databaseFilePath;
rv = dbFile->GetPath(databaseFilePath);
@@ -21809,7 +21659,6 @@ OpenDatabaseOp::DoDatabaseWork()
persistenceType,
mGroup,
mOrigin,
- mTelemetryId,
getter_AddRefs(connection));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
@@ -22692,7 +22541,6 @@ OpenDatabaseOp::EnsureDatabaseActor()
mOptionalContentParentId,
mGroup,
mOrigin,
- mTelemetryId,
mMetadata,
mFileManager,
mDirectoryLock.forget(),
diff --git a/dom/indexedDB/FileManager.h b/dom/indexedDB/FileManager.h
index da917f431..0fba46ec0 100644
--- a/dom/indexedDB/FileManager.h
+++ b/dom/indexedDB/FileManager.h
@@ -58,8 +58,7 @@ public:
nsIFile* aDatabaseFile,
PersistenceType aPersistenceType,
const nsACString& aGroup,
- const nsACString& aOrigin,
- uint32_t aTelemetryId);
+ const nsACString& aOrigin);
static nsresult
GetUsage(nsIFile* aDirectory, uint64_t* aUsage);
diff --git a/dom/indexedDB/IDBCursor.cpp b/dom/indexedDB/IDBCursor.cpp
index 7ae35e981..af88742f0 100644
--- a/dom/indexedDB/IDBCursor.cpp
+++ b/dom/indexedDB/IDBCursor.cpp
@@ -948,7 +948,6 @@ NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTION_CLASS(IDBCursor)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(IDBCursor)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRequest)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSourceObjectStore)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSourceIndex)
diff --git a/dom/indexedDB/IDBFactory.cpp b/dom/indexedDB/IDBFactory.cpp
index 663828978..c1ef6353d 100644
--- a/dom/indexedDB/IDBFactory.cpp
+++ b/dom/indexedDB/IDBFactory.cpp
@@ -47,12 +47,6 @@ namespace dom {
using namespace mozilla::dom::quota;
using namespace mozilla::ipc;
-namespace {
-
-const char kPrefIndexedDBEnabled[] = "dom.indexedDB.enabled";
-
-} // namespace
-
class IDBFactory::BackgroundCreateCallback final
: public nsIIPCBackgroundChildCreateCallback
{
@@ -130,12 +124,6 @@ IDBFactory::CreateForWindow(nsPIDOMWindowInner* aWindow,
nsCOMPtr<nsIPrincipal> principal;
nsresult rv = AllowedForWindowInternal(aWindow, getter_AddRefs(principal));
- if (!(NS_SUCCEEDED(rv) && nsContentUtils::IsSystemPrincipal(principal)) &&
- NS_WARN_IF(!Preferences::GetBool(kPrefIndexedDBEnabled, false))) {
- *aFactory = nullptr;
- return NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR;
- }
-
if (rv == NS_ERROR_DOM_NOT_SUPPORTED_ERR) {
NS_WARNING("IndexedDB is not permitted in a third-party window.");
*aFactory = nullptr;
@@ -246,12 +234,6 @@ IDBFactory::CreateForMainThreadJSInternal(
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aPrincipalInfo);
- if (aPrincipalInfo->type() != PrincipalInfo::TSystemPrincipalInfo &&
- NS_WARN_IF(!Preferences::GetBool(kPrefIndexedDBEnabled, false))) {
- *aFactory = nullptr;
- return NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR;
- }
-
IndexedDatabaseManager* mgr = IndexedDatabaseManager::GetOrCreate();
if (NS_WARN_IF(!mgr)) {
IDB_REPORT_INTERNAL_ERR();
@@ -883,7 +865,6 @@ NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTION_CLASS(IDBFactory)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(IDBFactory)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindow)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
diff --git a/dom/indexedDB/IDBIndex.cpp b/dom/indexedDB/IDBIndex.cpp
index 657e744c9..af50926e6 100644
--- a/dom/indexedDB/IDBIndex.cpp
+++ b/dom/indexedDB/IDBIndex.cpp
@@ -652,7 +652,6 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(IDBIndex)
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(IDBIndex)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mObjectStore)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
diff --git a/dom/indexedDB/IDBKeyRange.cpp b/dom/indexedDB/IDBKeyRange.cpp
index 2de48a70c..e61c80617 100644
--- a/dom/indexedDB/IDBKeyRange.cpp
+++ b/dom/indexedDB/IDBKeyRange.cpp
@@ -239,7 +239,6 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(IDBKeyRange)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(IDBKeyRange)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGlobal)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(IDBKeyRange)
diff --git a/dom/indexedDB/IDBObjectStore.cpp b/dom/indexedDB/IDBObjectStore.cpp
index 8a0b292ad..756792741 100644
--- a/dom/indexedDB/IDBObjectStore.cpp
+++ b/dom/indexedDB/IDBObjectStore.cpp
@@ -1758,7 +1758,6 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(IDBObjectStore)
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(IDBObjectStore)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTransaction)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIndexes)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDeletedIndexes)
diff --git a/dom/indexedDB/IDBRequest.cpp b/dom/indexedDB/IDBRequest.cpp
index 919d3adc7..e0e318059 100644
--- a/dom/indexedDB/IDBRequest.cpp
+++ b/dom/indexedDB/IDBRequest.cpp
@@ -417,8 +417,6 @@ IDBRequest::GetError(ErrorResult& aRv)
NS_IMPL_CYCLE_COLLECTION_CLASS(IDBRequest)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBRequest, IDBWrapperCache)
- // Don't need NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS because
- // DOMEventTargetHelper does it for us.
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSourceAsObjectStore)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSourceAsIndex)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSourceAsCursor)
diff --git a/dom/indexedDB/IDBWrapperCache.cpp b/dom/indexedDB/IDBWrapperCache.cpp
index df62514c8..ccc2bb43e 100644
--- a/dom/indexedDB/IDBWrapperCache.cpp
+++ b/dom/indexedDB/IDBWrapperCache.cpp
@@ -18,8 +18,6 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(IDBWrapperCache)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBWrapperCache,
DOMEventTargetHelper)
- // Don't need NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS because
- // DOMEventTargetHelper does it for us.
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBWrapperCache,
diff --git a/dom/indexedDB/KeyPath.cpp b/dom/indexedDB/KeyPath.cpp
index dc8d10668..30edd8cd7 100644
--- a/dom/indexedDB/KeyPath.cpp
+++ b/dom/indexedDB/KeyPath.cpp
@@ -14,6 +14,7 @@
#include "xpcpublic.h"
#include "mozilla/dom/BindingDeclarations.h"
+#include "mozilla/dom/BlobBinding.h"
#include "mozilla/dom/IDBObjectStoreBinding.h"
namespace mozilla {
@@ -100,7 +101,6 @@ GetJSValFromKeyPathString(JSContext* aCx,
const char16_t* keyPathChars = token.BeginReading();
const size_t keyPathLen = token.Length();
- bool hasProp;
if (!targetObject) {
// We're still walking the chain of existing objects
// http://w3c.github.io/IndexedDB/#dfn-evaluate-a-key-path-on-a-value
@@ -116,16 +116,77 @@ GetJSValFromKeyPathString(JSContext* aCx,
}
obj = &currentVal.toObject();
- bool ok = JS_HasUCProperty(aCx, obj, keyPathChars, keyPathLen,
- &hasProp);
+ // We call JS_GetOwnUCPropertyDescriptor on purpose (as opposed to
+ // JS_GetUCPropertyDescriptor) to avoid searching the prototype chain.
+ JS::Rooted<JS::PropertyDescriptor> desc(aCx);
+ bool ok = JS_GetOwnUCPropertyDescriptor(aCx, obj, keyPathChars,
+ keyPathLen, &desc);
IDB_ENSURE_TRUE(ok, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
- if (hasProp) {
- // Get if the property exists...
- JS::Rooted<JS::Value> intermediate(aCx);
- bool ok = JS_GetUCProperty(aCx, obj, keyPathChars, keyPathLen, &intermediate);
- IDB_ENSURE_TRUE(ok, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+ JS::Rooted<JS::Value> intermediate(aCx);
+ bool hasProp = false;
+
+ if (desc.object()) {
+ intermediate = desc.value();
+ hasProp = true;
+ } else {
+ // If we get here it means the object doesn't have the property or the
+ // property is available throuch a getter. We don't want to call any
+ // getters to avoid potential re-entrancy.
+ // The blob object is special since its properties are available
+ // only through getters but we still want to support them for key
+ // extraction. So they need to be handled manually.
+ Blob* blob;
+ if (NS_SUCCEEDED(UNWRAP_OBJECT(Blob, &obj, blob))) {
+ if (token.EqualsLiteral("size")) {
+ ErrorResult rv;
+ uint64_t size = blob->GetSize(rv);
+ MOZ_ALWAYS_TRUE(!rv.Failed());
+
+ intermediate = JS_NumberValue(size);
+ hasProp = true;
+ } else if (token.EqualsLiteral("type")) {
+ nsString type;
+ blob->GetType(type);
+
+ JSString* string =
+ JS_NewUCStringCopyN(aCx, type.get(), type.Length());
+
+ intermediate = JS::StringValue(string);
+ hasProp = true;
+ } else {
+ RefPtr<File> file = blob->ToFile();
+ if (file) {
+ if (token.EqualsLiteral("name")) {
+ nsString name;
+ file->GetName(name);
+
+ JSString* string =
+ JS_NewUCStringCopyN(aCx, name.get(), name.Length());
+
+ intermediate = JS::StringValue(string);
+ hasProp = true;
+ } else if (token.EqualsLiteral("lastModified")) {
+ ErrorResult rv;
+ int64_t lastModifiedDate = file->GetLastModified(rv);
+ MOZ_ALWAYS_TRUE(!rv.Failed());
+
+ intermediate = JS_NumberValue(lastModifiedDate);
+ hasProp = true;
+ } else if (token.EqualsLiteral("lastModifiedDate")) {
+ ErrorResult rv;
+ Date lastModifiedDate = file->GetLastModifiedDate(rv);
+ MOZ_ALWAYS_TRUE(!rv.Failed());
+
+ lastModifiedDate.ToDateObject(aCx, &intermediate);
+ hasProp = true;
+ }
+ }
+ }
+ }
+ }
+ if (hasProp) {
// Treat explicitly undefined as an error.
if (intermediate.isUndefined()) {
return NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
diff --git a/dom/interfaces/html/nsIDOMHTMLElement.idl b/dom/interfaces/html/nsIDOMHTMLElement.idl
index 63a1f9572..686475f04 100644
--- a/dom/interfaces/html/nsIDOMHTMLElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLElement.idl
@@ -58,7 +58,6 @@ interface nsIDOMHTMLElement : nsIDOMElement
// CSSOM View
- [optional_argc] void scrollIntoView([optional] in boolean top);
readonly attribute nsIDOMElement offsetParent;
readonly attribute long offsetTop;
readonly attribute long offsetLeft;
diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp
index fc288e2c5..fdf0fcf3e 100644
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -171,7 +171,6 @@
#include "GMPServiceChild.h"
#include "gfxPlatform.h"
#include "nscore.h" // for NS_FREE_PERMANENT_DATA
-#include "VRManagerChild.h"
using namespace mozilla;
using namespace mozilla::docshell;
@@ -1148,7 +1147,6 @@ ContentChild::RecvGMPsChanged(nsTArray<GMPCapabilityData>&& capabilities)
bool
ContentChild::RecvInitRendering(Endpoint<PCompositorBridgeChild>&& aCompositor,
Endpoint<PImageBridgeChild>&& aImageBridge,
- Endpoint<PVRManagerChild>&& aVRBridge,
Endpoint<PVideoDecoderManagerChild>&& aVideoManager)
{
if (!CompositorBridgeChild::InitForContent(Move(aCompositor))) {
@@ -1157,9 +1155,6 @@ ContentChild::RecvInitRendering(Endpoint<PCompositorBridgeChild>&& aCompositor,
if (!ImageBridgeChild::InitForContent(Move(aImageBridge))) {
return false;
}
- if (!gfx::VRManagerChild::InitForContent(Move(aVRBridge))) {
- return false;
- }
VideoDecoderManagerChild::InitForContent(Move(aVideoManager));
return true;
}
@@ -1167,7 +1162,6 @@ ContentChild::RecvInitRendering(Endpoint<PCompositorBridgeChild>&& aCompositor,
bool
ContentChild::RecvReinitRendering(Endpoint<PCompositorBridgeChild>&& aCompositor,
Endpoint<PImageBridgeChild>&& aImageBridge,
- Endpoint<PVRManagerChild>&& aVRBridge,
Endpoint<PVideoDecoderManagerChild>&& aVideoManager)
{
nsTArray<RefPtr<TabChild>> tabs = TabChild::GetAll();
@@ -1186,9 +1180,6 @@ ContentChild::RecvReinitRendering(Endpoint<PCompositorBridgeChild>&& aCompositor
if (!ImageBridgeChild::ReinitForContent(Move(aImageBridge))) {
return false;
}
- if (!gfx::VRManagerChild::ReinitForContent(Move(aVRBridge))) {
- return false;
- }
// Establish new PLayerTransactions.
for (const auto& tabChild : tabs) {
diff --git a/dom/ipc/ContentChild.h b/dom/ipc/ContentChild.h
index ba590b58e..4c8f15cc0 100644
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -152,14 +152,12 @@ public:
RecvInitRendering(
Endpoint<PCompositorBridgeChild>&& aCompositor,
Endpoint<PImageBridgeChild>&& aImageBridge,
- Endpoint<PVRManagerChild>&& aVRBridge,
Endpoint<PVideoDecoderManagerChild>&& aVideoManager) override;
bool
RecvReinitRendering(
Endpoint<PCompositorBridgeChild>&& aCompositor,
Endpoint<PImageBridgeChild>&& aImageBridge,
- Endpoint<PVRManagerChild>&& aVRBridge,
Endpoint<PVideoDecoderManagerChild>&& aVideoManager) override;
PProcessHangMonitorChild*
diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp
index 0a07147bf..79446151c 100644
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -84,7 +84,6 @@
#include "mozilla/ScopeExit.h"
#include "mozilla/Services.h"
#include "mozilla/StaticPtr.h"
-#include "mozilla/Telemetry.h"
#include "mozilla/WebBrowserPersistDocumentParent.h"
#include "mozilla/Unused.h"
#include "nsAnonymousTemporaryFile.h"
@@ -1718,9 +1717,6 @@ ContentParent::ActorDestroy(ActorDestroyReason why)
props->SetPropertyAsUint64(NS_LITERAL_STRING("childID"), mChildID);
if (AbnormalShutdown == why) {
- Telemetry::Accumulate(Telemetry::SUBPROCESS_ABNORMAL_ABORT,
- NS_LITERAL_CSTRING("content"), 1);
-
props->SetPropertyAsBool(NS_LITERAL_STRING("abnormal"), true);
}
nsAutoString cpId;
@@ -2076,21 +2072,18 @@ ContentParent::InitInternal(ProcessPriority aInitialPriority,
Endpoint<PCompositorBridgeChild> compositor;
Endpoint<PImageBridgeChild> imageBridge;
- Endpoint<PVRManagerChild> vrBridge;
Endpoint<PVideoDecoderManagerChild> videoManager;
DebugOnly<bool> opened = gpm->CreateContentBridges(
OtherPid(),
&compositor,
&imageBridge,
- &vrBridge,
&videoManager);
MOZ_ASSERT(opened);
Unused << SendInitRendering(
Move(compositor),
Move(imageBridge),
- Move(vrBridge),
Move(videoManager));
gpm->AddListener(this);
@@ -2204,21 +2197,18 @@ ContentParent::OnCompositorUnexpectedShutdown()
Endpoint<PCompositorBridgeChild> compositor;
Endpoint<PImageBridgeChild> imageBridge;
- Endpoint<PVRManagerChild> vrBridge;
Endpoint<PVideoDecoderManagerChild> videoManager;
DebugOnly<bool> opened = gpm->CreateContentBridges(
OtherPid(),
&compositor,
&imageBridge,
- &vrBridge,
&videoManager);
MOZ_ASSERT(opened);
Unused << SendReinitRendering(
Move(compositor),
Move(imageBridge),
- Move(vrBridge),
Move(videoManager));
}
@@ -3373,17 +3363,6 @@ ContentParent::RecvIsSecureURI(const uint32_t& type,
}
bool
-ContentParent::RecvAccumulateMixedContentHSTS(const URIParams& aURI, const bool& aActive)
-{
- nsCOMPtr<nsIURI> ourURI = DeserializeURI(aURI);
- if (!ourURI) {
- return false;
- }
- nsMixedContentBlocker::AccumulateMixedContentHSTS(ourURI, aActive);
- return true;
-}
-
-bool
ContentParent::RecvLoadURIExternal(const URIParams& uri,
PBrowserParent* windowContext)
{
@@ -4773,19 +4752,3 @@ ContentParent::ForceTabPaint(TabParent* aTabParent, uint64_t aLayerObserverEpoch
}
ProcessHangMonitor::ForcePaint(mHangMonitorActor, aTabParent, aLayerObserverEpoch);
}
-
-bool
-ContentParent::RecvAccumulateChildHistogram(
- InfallibleTArray<Accumulation>&& aAccumulations)
-{
- Telemetry::AccumulateChild(GeckoProcessType_Content, aAccumulations);
- return true;
-}
-
-bool
-ContentParent::RecvAccumulateChildKeyedHistogram(
- InfallibleTArray<KeyedAccumulation>&& aAccumulations)
-{
- Telemetry::AccumulateChildKeyed(GeckoProcessType_Content, aAccumulations);
- return true;
-}
diff --git a/dom/ipc/ContentParent.h b/dom/ipc/ContentParent.h
index abcea0b65..26b5c44ac 100644
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -741,9 +741,6 @@ private:
virtual bool RecvIsSecureURI(const uint32_t& aType, const URIParams& aURI,
const uint32_t& aFlags, bool* aIsSecureURI) override;
- virtual bool RecvAccumulateMixedContentHSTS(const URIParams& aURI,
- const bool& aActive) override;
-
virtual bool DeallocPHalParent(PHalParent*) override;
virtual bool
@@ -1044,10 +1041,6 @@ private:
virtual bool RecvDeleteGetFilesRequest(const nsID& aID) override;
- virtual bool RecvAccumulateChildHistogram(
- InfallibleTArray<Accumulation>&& aAccumulations) override;
- virtual bool RecvAccumulateChildKeyedHistogram(
- InfallibleTArray<KeyedAccumulation>&& aAccumulations) override;
public:
void SendGetFilesResponseAndForget(const nsID& aID,
const GetFilesResponseResult& aResult);
diff --git a/dom/ipc/PContent.ipdl b/dom/ipc/PContent.ipdl
index c01ad59c1..e8fb25aec 100644
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -44,7 +44,6 @@ include protocol PRemoteSpellcheckEngine;
include protocol PWebBrowserPersistDocument;
include protocol PWebrtcGlobal;
include protocol PPresentation;
-include protocol PVRManager;
include protocol PVideoDecoderManager;
include protocol PFlyWebPublishedServer;
include DOMTypes;
@@ -90,8 +89,6 @@ using mozilla::DataStorageType from "ipc/DataStorageIPCUtils.h";
using mozilla::DocShellOriginAttributes from "mozilla/ipc/BackgroundUtils.h";
using struct mozilla::layers::TextureFactoryIdentifier from "mozilla/layers/CompositorTypes.h";
using struct mozilla::dom::FlyWebPublishOptions from "mozilla/dom/FlyWebPublishOptionsIPCSerializer.h";
-using mozilla::Telemetry::Accumulation from "mozilla/TelemetryComms.h";
-using mozilla::Telemetry::KeyedAccumulation from "mozilla/TelemetryComms.h";
union ChromeRegistryItem
{
@@ -311,7 +308,6 @@ child:
async InitRendering(
Endpoint<PCompositorBridgeChild> compositor,
Endpoint<PImageBridgeChild> imageBridge,
- Endpoint<PVRManagerChild> vr,
Endpoint<PVideoDecoderManagerChild> video);
// Re-create the rendering stack using the given endpoints. This is sent
@@ -320,7 +316,6 @@ child:
async ReinitRendering(
Endpoint<PCompositorBridgeChild> compositor,
Endpoint<PImageBridgeChild> bridge,
- Endpoint<PVRManagerChild> vr,
Endpoint<PVideoDecoderManagerChild> video);
/**
@@ -661,8 +656,6 @@ parent:
sync IsSecureURI(uint32_t type, URIParams uri, uint32_t flags)
returns (bool isSecureURI);
- async AccumulateMixedContentHSTS(URIParams uri, bool active);
-
sync GetLookAndFeelCache()
returns (LookAndFeelInt[] lookAndFeelIntCache);
@@ -1025,12 +1018,6 @@ parent:
async UnstoreAndBroadcastBlobURLUnregistration(nsCString url);
- /**
- * Messages for communicating child Telemetry to the parent process
- */
- async AccumulateChildHistogram(Accumulation[] accumulations);
- async AccumulateChildKeyedHistogram(KeyedAccumulation[] accumulations);
-
sync GetA11yContentId() returns (uint32_t aContentId);
both:
diff --git a/dom/ipc/TabChild.cpp b/dom/ipc/TabChild.cpp
index 705799c54..e1355adee 100644
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -107,7 +107,6 @@
#include "nsDeviceContext.h"
#include "nsSandboxFlags.h"
#include "FrameLayerBuilder.h"
-#include "VRManagerChild.h"
#include "nsICommandParams.h"
#include "nsISHistory.h"
#include "nsQueryObject.h"
@@ -177,7 +176,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(TabChildBase)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTabChildGlobal)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGlobal)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWebBrowserChrome)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
@@ -2395,7 +2393,6 @@ TabChild::RecvSetDocShellIsActive(const bool& aIsActive,
root->SchedulePaint();
}
- Telemetry::AutoTimer<Telemetry::TABCHILD_PAINT_TIME> timer;
// If we need to repaint, let's do that right away. No sense waiting until
// we get back to the event loop again. We suppress the display port so that
// we only paint what's visible. This ensures that the tab we're switching
@@ -2566,7 +2563,6 @@ TabChild::InitRenderingState(const TextureFactoryIdentifier& aTextureFactoryIden
lf->SetShadowManager(shadowManager);
lf->IdentifyTextureHost(mTextureFactoryIdentifier);
ImageBridgeChild::IdentifyCompositorTextureHost(mTextureFactoryIdentifier);
- gfx::VRManagerChild::IdentifyTextureHost(mTextureFactoryIdentifier);
}
mRemoteFrame = remoteFrame;
diff --git a/dom/locales/en-US/chrome/security/security.properties b/dom/locales/en-US/chrome/security/security.properties
index 8efdb0a6d..2be56fb9d 100644
--- a/dom/locales/en-US/chrome/security/security.properties
+++ b/dom/locales/en-US/chrome/security/security.properties
@@ -85,3 +85,5 @@ BlockScriptWithWrongMimeType=Script from “%1$S” was blocked because of a dis
# LOCALIZATION NOTE: Do not translate "data: URI".
BlockTopLevelDataURINavigation=Navigation to toplevel data: URI not allowed (Blocked loading of: “%1$S”)
+
+BlockSubresourceFTP=Loading FTP subresource within http(s) page not allowed (Blocked loading of: “%1$S”)
diff --git a/dom/media/AudioStream.cpp b/dom/media/AudioStream.cpp
index 54cf7b965..4b1d82c37 100644
--- a/dom/media/AudioStream.cpp
+++ b/dom/media/AudioStream.cpp
@@ -14,7 +14,6 @@
#include "mozilla/Mutex.h"
#include "mozilla/Sprintf.h"
#include <algorithm>
-#include "mozilla/Telemetry.h"
#include "CubebUtils.h"
#include "nsPrintfCString.h"
#include "gfxPrefs.h"
@@ -346,7 +345,6 @@ AudioStream::Init(uint32_t aNumChannels, uint32_t aRate,
cubeb* cubebContext = CubebUtils::GetCubebContext();
if (!cubebContext) {
NS_WARNING("Can't get cubeb context!");
- CubebUtils::ReportCubebStreamInitFailure(true);
return NS_ERROR_DOM_MEDIA_CUBEB_INITIALIZATION_ERR;
}
@@ -368,18 +366,14 @@ AudioStream::OpenCubeb(cubeb* aContext, cubeb_stream_params& aParams,
latency_frames,
DataCallback_S, StateCallback_S, this) == CUBEB_OK) {
mCubebStream.reset(stream);
- CubebUtils::ReportCubebBackendUsed();
} else {
NS_WARNING(nsPrintfCString("AudioStream::OpenCubeb() %p failed to init cubeb", this).get());
- CubebUtils::ReportCubebStreamInitFailure(aIsFirst);
return NS_ERROR_FAILURE;
}
TimeDuration timeDelta = TimeStamp::Now() - aStartTime;
LOG("creation time %sfirst: %u ms", aIsFirst ? "" : "not ",
(uint32_t) timeDelta.ToMilliseconds());
- Telemetry::Accumulate(aIsFirst ? Telemetry::AUDIOSTREAM_FIRST_OPEN_MS :
- Telemetry::AUDIOSTREAM_LATER_OPEN_MS, timeDelta.ToMilliseconds());
return NS_OK;
}
diff --git a/dom/media/Benchmark.cpp b/dom/media/Benchmark.cpp
index fdbedeca5..7394f8036 100644
--- a/dom/media/Benchmark.cpp
+++ b/dom/media/Benchmark.cpp
@@ -11,7 +11,6 @@
#include "PDMFactory.h"
#include "WebMDemuxer.h"
#include "mozilla/Preferences.h"
-#include "mozilla/Telemetry.h"
#include "mozilla/dom/ContentChild.h"
#ifndef MOZ_WIDGET_ANDROID
@@ -68,7 +67,6 @@ VP9Benchmark::IsVP9DecodeFast()
Preferences::SetUint(sBenchmarkFpsPref, aDecodeFps);
Preferences::SetUint(sBenchmarkFpsVersionCheck, sBenchmarkVersionID);
}
- Telemetry::Accumulate(Telemetry::ID::VIDEO_VP9_BENCHMARK_FPS, aDecodeFps);
},
[]() { });
}
diff --git a/dom/media/CubebUtils.cpp b/dom/media/CubebUtils.cpp
index fe94264ee..0f0167d9c 100644
--- a/dom/media/CubebUtils.cpp
+++ b/dom/media/CubebUtils.cpp
@@ -239,39 +239,6 @@ cubeb* GetCubebContextUnlocked()
return sCubebContext;
}
-void ReportCubebBackendUsed()
-{
- StaticMutexAutoLock lock(sMutex);
-
- sAudioStreamInitEverSucceeded = true;
-
- bool foundBackend = false;
- for (uint32_t i = 0; i < ArrayLength(AUDIOSTREAM_BACKEND_ID_STR); i++) {
- if (!strcmp(cubeb_get_backend_id(sCubebContext), AUDIOSTREAM_BACKEND_ID_STR[i])) {
- Telemetry::Accumulate(Telemetry::AUDIOSTREAM_BACKEND_USED, i);
- foundBackend = true;
- }
- }
- if (!foundBackend) {
- Telemetry::Accumulate(Telemetry::AUDIOSTREAM_BACKEND_USED,
- CUBEB_BACKEND_UNKNOWN);
- }
-}
-
-void ReportCubebStreamInitFailure(bool aIsFirst)
-{
- StaticMutexAutoLock lock(sMutex);
- if (!aIsFirst && !sAudioStreamInitEverSucceeded) {
- // This machine has no audio hardware, or it's in really bad shape, don't
- // send this info, since we want CUBEB_BACKEND_INIT_FAILURE_OTHER to detect
- // failures to open multiple streams in a process over time.
- return;
- }
- Telemetry::Accumulate(Telemetry::AUDIOSTREAM_BACKEND_USED,
- aIsFirst ? CUBEB_BACKEND_INIT_FAILURE_FIRST
- : CUBEB_BACKEND_INIT_FAILURE_OTHER);
-}
-
uint32_t GetCubebPlaybackLatencyInMilliseconds()
{
StaticMutexAutoLock lock(sMutex);
diff --git a/dom/media/CubebUtils.h b/dom/media/CubebUtils.h
index fa5fc2294..f43492374 100644
--- a/dom/media/CubebUtils.h
+++ b/dom/media/CubebUtils.h
@@ -35,8 +35,6 @@ double GetVolumeScale();
bool GetFirstStream();
cubeb* GetCubebContext();
cubeb* GetCubebContextUnlocked();
-void ReportCubebStreamInitFailure(bool aIsFirstStream);
-void ReportCubebBackendUsed();
uint32_t GetCubebPlaybackLatencyInMilliseconds();
Maybe<uint32_t> GetCubebMSGLatencyInFrames();
bool CubebLatencyPrefSet();
diff --git a/dom/media/DecoderTraits.cpp b/dom/media/DecoderTraits.cpp
index ddd35fe0d..6aa44f3e5 100644
--- a/dom/media/DecoderTraits.cpp
+++ b/dom/media/DecoderTraits.cpp
@@ -10,7 +10,6 @@
#include "nsCharSeparatedTokenizer.h"
#include "nsMimeTypes.h"
#include "mozilla/Preferences.h"
-#include "mozilla/Telemetry.h"
#include "OggDecoder.h"
#include "OggDemuxer.h"
@@ -18,15 +17,6 @@
#include "WebMDecoder.h"
#include "WebMDemuxer.h"
-#ifdef MOZ_ANDROID_OMX
-#include "AndroidMediaDecoder.h"
-#include "AndroidMediaReader.h"
-#include "AndroidMediaPluginHost.h"
-#endif
-#ifdef MOZ_DIRECTSHOW
-#include "DirectShowDecoder.h"
-#include "DirectShowReader.h"
-#endif
#ifdef MOZ_FMP4
#include "MP4Decoder.h"
#include "MP4Demuxer.h"
@@ -94,45 +84,6 @@ DecoderTraits::IsWebMAudioType(const nsACString& aType)
return aType.EqualsASCII("audio/webm");
}
-static char const *const gHttpLiveStreamingTypes[] = {
- // For m3u8.
- // https://tools.ietf.org/html/draft-pantos-http-live-streaming-19#section-10
- "application/vnd.apple.mpegurl",
- // Some sites serve these as the informal m3u type.
- "application/x-mpegurl",
- "audio/x-mpegurl",
- nullptr
-};
-
-static bool
-IsHttpLiveStreamingType(const nsACString& aType)
-{
- return CodecListContains(gHttpLiveStreamingTypes, aType);
-}
-
-#ifdef MOZ_ANDROID_OMX
-static bool
-IsAndroidMediaType(const nsACString& aType)
-{
- if (!MediaDecoder::IsAndroidMediaPluginEnabled()) {
- return false;
- }
-
- static const char* supportedTypes[] = {
- "audio/mpeg", "audio/mp4", "video/mp4", "video/x-m4v", nullptr
- };
- return CodecListContains(supportedTypes, aType);
-}
-#endif
-
-#ifdef MOZ_DIRECTSHOW
-static bool
-IsDirectShowSupportedType(const nsACString& aType)
-{
- return DirectShowDecoder::GetSupportedCodecs(aType, nullptr);
-}
-#endif
-
#ifdef MOZ_FMP4
static bool
IsMP4SupportedType(const MediaContentType& aParsedType,
@@ -247,14 +198,6 @@ CanHandleCodecsType(const MediaContentType& aType,
if (IsFlacSupportedType(aType.GetMIMEType(), aType.GetCodecs())) {
return CANPLAY_YES;
}
-#ifdef MOZ_DIRECTSHOW
- DirectShowDecoder::GetSupportedCodecs(aType.GetMIMEType(), &codecList);
-#endif
-#ifdef MOZ_ANDROID_OMX
- if (MediaDecoder::IsAndroidMediaPluginEnabled()) {
- EnsureAndroidMediaPluginHost()->FindDecoder(aType.GetMIMEType(), &codecList);
- }
-#endif
if (!codecList) {
return CANPLAY_MAYBE;
}
@@ -287,10 +230,6 @@ CanHandleMediaType(const MediaContentType& aType,
{
MOZ_ASSERT(NS_IsMainThread());
- if (IsHttpLiveStreamingType(aType.GetMIMEType())) {
- Telemetry::Accumulate(Telemetry::MEDIA_HLS_CANPLAY_REQUESTED, true);
- }
-
if (aType.HaveCodecs()) {
CanPlayStatus result = CanHandleCodecsType(aType, aDiagnostics);
if (result == CANPLAY_NO || result == CANPLAY_YES) {
@@ -320,17 +259,6 @@ CanHandleMediaType(const MediaContentType& aType,
if (IsFlacSupportedType(aType.GetMIMEType())) {
return CANPLAY_MAYBE;
}
-#ifdef MOZ_DIRECTSHOW
- if (DirectShowDecoder::GetSupportedCodecs(aType.GetMIMEType(), nullptr)) {
- return CANPLAY_MAYBE;
- }
-#endif
-#ifdef MOZ_ANDROID_OMX
- if (MediaDecoder::IsAndroidMediaPluginEnabled() &&
- EnsureAndroidMediaPluginHost()->FindDecoder(aType.GetMIMEType(), nullptr)) {
- return CANPLAY_MAYBE;
- }
-#endif
return CANPLAY_NO;
}
@@ -411,33 +339,12 @@ InstantiateDecoder(const nsACString& aType,
decoder = new FlacDecoder(aOwner);
return decoder.forget();
}
-#ifdef MOZ_ANDROID_OMX
- if (MediaDecoder::IsAndroidMediaPluginEnabled() &&
- EnsureAndroidMediaPluginHost()->FindDecoder(aType, nullptr)) {
- decoder = new AndroidMediaDecoder(aOwner, aType);
- return decoder.forget();
- }
-#endif
if (IsWebMSupportedType(aType)) {
decoder = new WebMDecoder(aOwner);
return decoder.forget();
}
-#ifdef MOZ_DIRECTSHOW
- // Note: DirectShow should come before WMF, so that we prefer DirectShow's
- // MP3 support over WMF's.
- if (IsDirectShowSupportedType(aType)) {
- decoder = new DirectShowDecoder(aOwner);
- return decoder.forget();
- }
-#endif
-
- if (IsHttpLiveStreamingType(aType)) {
- // We don't have an HLS decoder.
- Telemetry::Accumulate(Telemetry::MEDIA_HLS_DECODER_SUCCESS, false);
- }
-
return nullptr;
}
@@ -466,7 +373,7 @@ MediaDecoderReader* DecoderTraits::CreateReader(const nsACString& aType, Abstrac
} else
#endif
if (IsMP3SupportedType(aType)) {
- decoderReader = new MediaFormatReader(aDecoder, new mp3::MP3Demuxer(aDecoder->GetResource()));
+ decoderReader = new MediaFormatReader(aDecoder, new MP3Demuxer(aDecoder->GetResource()));
} else
if (IsAACSupportedType(aType)) {
decoderReader = new MediaFormatReader(aDecoder, new ADTSDemuxer(aDecoder->GetResource()));
@@ -480,22 +387,10 @@ MediaDecoderReader* DecoderTraits::CreateReader(const nsACString& aType, Abstrac
if (IsOggSupportedType(aType)) {
decoderReader = new MediaFormatReader(aDecoder, new OggDemuxer(aDecoder->GetResource()));
} else
-#ifdef MOZ_ANDROID_OMX
- if (MediaDecoder::IsAndroidMediaPluginEnabled() &&
- EnsureAndroidMediaPluginHost()->FindDecoder(aType, nullptr)) {
- decoderReader = new AndroidMediaReader(aDecoder, aType);
- } else
-#endif
if (IsWebMSupportedType(aType)) {
decoderReader =
new MediaFormatReader(aDecoder, new WebMDemuxer(aDecoder->GetResource()));
- } else
-#ifdef MOZ_DIRECTSHOW
- if (IsDirectShowSupportedType(aType)) {
- decoderReader = new DirectShowReader(aDecoder);
- } else
-#endif
- if (false) {} // dummy if to take care of the dangling else
+ }
return decoderReader;
}
@@ -514,18 +409,12 @@ bool DecoderTraits::IsSupportedInVideoDocument(const nsACString& aType)
return
IsOggSupportedType(aType) ||
IsWebMSupportedType(aType) ||
-#ifdef MOZ_ANDROID_OMX
- (MediaDecoder::IsAndroidMediaPluginEnabled() && IsAndroidMediaType(aType)) ||
-#endif
#ifdef MOZ_FMP4
IsMP4SupportedType(aType, /* DecoderDoctorDiagnostics* */ nullptr) ||
#endif
IsMP3SupportedType(aType) ||
IsAACSupportedType(aType) ||
IsFlacSupportedType(aType) ||
-#ifdef MOZ_DIRECTSHOW
- IsDirectShowSupportedType(aType) ||
-#endif
false;
}
diff --git a/dom/media/GraphDriver.cpp b/dom/media/GraphDriver.cpp
index cae15eb8c..37c692a4b 100644
--- a/dom/media/GraphDriver.cpp
+++ b/dom/media/GraphDriver.cpp
@@ -200,7 +200,7 @@ public:
STREAM_LOG(LogLevel::Debug, ("Starting system thread"));
profiler_register_thread("MediaStreamGraph", &aLocal);
LIFECYCLE_LOG("Starting a new system driver for graph %p\n",
- mDriver->mGraphImpl);
+ mDriver->mGraphImpl.get());
RefPtr<GraphDriver> previousDriver;
{
@@ -236,7 +236,7 @@ private:
void
ThreadedDriver::Start()
{
- LIFECYCLE_LOG("Starting thread for a SystemClockDriver %p\n", mGraphImpl);
+ LIFECYCLE_LOG("Starting thread for a SystemClockDriver %p\n", mGraphImpl.get());
Unused << NS_WARN_IF(mThread);
if (!mThread) { // Ensure we haven't already started it
nsCOMPtr<nsIRunnable> event = new MediaStreamGraphInitThreadRunnable(this);
@@ -623,16 +623,12 @@ AudioCallbackDriver::Init()
cubeb* cubebContext = CubebUtils::GetCubebContext();
if (!cubebContext) {
NS_WARNING("Could not get cubeb context.");
- if (!mFromFallback) {
- CubebUtils::ReportCubebStreamInitFailure(true);
- }
return;
}
cubeb_stream_params output;
cubeb_stream_params input;
uint32_t latency_frames;
- bool firstStream = CubebUtils::GetFirstStream();
MOZ_ASSERT(!NS_IsMainThread(),
"This is blocking and should never run on the main thread.");
@@ -710,18 +706,11 @@ AudioCallbackDriver::Init()
NS_WARNING_ASSERTION(
rv == CUBEB_OK,
"Could not set the audio stream volume in GraphDriver.cpp");
- CubebUtils::ReportCubebBackendUsed();
} else {
#ifdef MOZ_WEBRTC
StaticMutexAutoUnlock unlock(AudioInputCubeb::Mutex());
#endif
NS_WARNING("Could not create a cubeb stream for MediaStreamGraph, falling back to a SystemClockDriver");
- // Only report failures when we're not coming from a driver that was
- // created itself as a fallback driver because of a previous audio driver
- // failure.
- if (!mFromFallback) {
- CubebUtils::ReportCubebStreamInitFailure(firstStream);
- }
// Fall back to a driver using a normal thread. If needed,
// the graph will try to re-open an audio stream later.
MonitorAutoLock lock(GraphImpl()->GetMonitor());
@@ -761,7 +750,7 @@ AudioCallbackDriver::Destroy()
void
AudioCallbackDriver::Resume()
{
- STREAM_LOG(LogLevel::Debug, ("Resuming audio threads for MediaStreamGraph %p", mGraphImpl));
+ STREAM_LOG(LogLevel::Debug, ("Resuming audio threads for MediaStreamGraph %p", mGraphImpl.get()));
if (cubeb_stream_start(mAudioStream) != CUBEB_OK) {
NS_WARNING("Could not start cubeb stream for MSG.");
}
@@ -830,7 +819,9 @@ AudioCallbackDriver::Revive()
mGraphImpl->SetCurrentDriver(NextDriver());
NextDriver()->Start();
} else {
- STREAM_LOG(LogLevel::Debug, ("Starting audio threads for MediaStreamGraph %p from a new thread.", mGraphImpl));
+ STREAM_LOG(LogLevel::Debug,
+ ("Starting audio threads for MediaStreamGraph %p from a new thread.",
+ mGraphImpl.get()));
RefPtr<AsyncCubebTask> initEvent =
new AsyncCubebTask(this, AsyncCubebOperation::INIT);
initEvent->Dispatch();
diff --git a/dom/media/GraphDriver.h b/dom/media/GraphDriver.h
index 411e175d3..bb4f2689b 100644
--- a/dom/media/GraphDriver.h
+++ b/dom/media/GraphDriver.h
@@ -210,10 +210,8 @@ protected:
// Time of the end of this graph iteration. This must be accessed while having
// the monitor.
GraphTime mIterationEnd;
- // The MediaStreamGraphImpl that owns this driver. This has a lifetime longer
- // than the driver, and will never be null. Hence, it can be accesed without
- // monitor.
- MediaStreamGraphImpl* mGraphImpl;
+ // The MediaStreamGraphImpl associated with this driver.
+ const RefPtr<MediaStreamGraphImpl> mGraphImpl;
// This enum specifies the wait state of the driver.
enum WaitState {
diff --git a/dom/media/MP3FrameParser.cpp b/dom/media/MP3FrameParser.cpp
deleted file mode 100644
index 242e3df00..000000000
--- a/dom/media/MP3FrameParser.cpp
+++ /dev/null
@@ -1,591 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include <algorithm>
-
-#include "nsMemory.h"
-#include "MP3FrameParser.h"
-#include "VideoUtils.h"
-
-
-#define FROM_BIG_ENDIAN(X) ((uint32_t)((uint8_t)(X)[0] << 24 | (uint8_t)(X)[1] << 16 | \
- (uint8_t)(X)[2] << 8 | (uint8_t)(X)[3]))
-
-
-namespace mozilla {
-
-/*
- * Following code taken from http://www.hydrogenaudio.org/forums/index.php?showtopic=85125
- * with permission from the author, Nick Wallette <sirnickity@gmail.com>.
- */
-
-/* BEGIN shameless copy and paste */
-
-// Bitrates - use [version][layer][bitrate]
-const uint16_t mpeg_bitrates[4][4][16] = {
- { // Version 2.5
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Reserved
- { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0 }, // Layer 3
- { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0 }, // Layer 2
- { 0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 0 } // Layer 1
- },
- { // Reserved
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Invalid
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Invalid
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Invalid
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } // Invalid
- },
- { // Version 2
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Reserved
- { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0 }, // Layer 3
- { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0 }, // Layer 2
- { 0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 0 } // Layer 1
- },
- { // Version 1
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Reserved
- { 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0 }, // Layer 3
- { 0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 0 }, // Layer 2
- { 0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 0 }, // Layer 1
- }
-};
-
-// Sample rates - use [version][srate]
-const uint16_t mpeg_srates[4][4] = {
- { 11025, 12000, 8000, 0 }, // MPEG 2.5
- { 0, 0, 0, 0 }, // Reserved
- { 22050, 24000, 16000, 0 }, // MPEG 2
- { 44100, 48000, 32000, 0 } // MPEG 1
-};
-
-// Samples per frame - use [version][layer]
-const uint16_t mpeg_frame_samples[4][4] = {
-// Rsvd 3 2 1 < Layer v Version
- { 0, 576, 1152, 384 }, // 2.5
- { 0, 0, 0, 0 }, // Reserved
- { 0, 576, 1152, 384 }, // 2
- { 0, 1152, 1152, 384 } // 1
-};
-
-// Slot size (MPEG unit of measurement) - use [layer]
-const uint8_t mpeg_slot_size[4] = { 0, 1, 1, 4 }; // Rsvd, 3, 2, 1
-
-uint16_t
-MP3Frame::CalculateLength()
-{
- // Lookup real values of these fields
- uint32_t bitrate = mpeg_bitrates[mVersion][mLayer][mBitrate] * 1000;
- uint32_t samprate = mpeg_srates[mVersion][mSampleRate];
- uint16_t samples = mpeg_frame_samples[mVersion][mLayer];
- uint8_t slot_size = mpeg_slot_size[mLayer];
-
- // In-between calculations
- float bps = (float)samples / 8.0;
- float fsize = ( (bps * (float)bitrate) / (float)samprate )
- + ( (mPad) ? slot_size : 0 );
-
- // Frame sizes are truncated integers
- return (uint16_t)fsize;
-}
-
-/* END shameless copy and paste */
-
-
-/** MP3Parser methods **/
-
-MP3Parser::MP3Parser()
- : mCurrentChar(0)
-{ }
-
-void
-MP3Parser::Reset()
-{
- mCurrentChar = 0;
-}
-
-uint16_t
-MP3Parser::ParseFrameLength(uint8_t ch)
-{
- mData.mRaw[mCurrentChar] = ch;
-
- MP3Frame &frame = mData.mFrame;
-
- // Validate MP3 header as we read. We can't mistake the start of an MP3 frame
- // for the middle of another frame due to the sync byte at the beginning
- // of the frame.
-
- // The only valid position for an all-high byte is the sync byte at the
- // beginning of the frame.
- if (ch == 0xff) {
- mCurrentChar = 0;
- }
-
- // Make sure the current byte is valid in context. If not, reset the parser.
- if (mCurrentChar == 2) {
- if (frame.mBitrate == 0x0f) {
- goto fail;
- }
- } else if (mCurrentChar == 1) {
- if (frame.mSync2 != 0x07
- || frame.mVersion == 0x01
- || frame.mLayer == 0x00) {
- goto fail;
- }
- }
-
- // The only valid character at the beginning of the header is 0xff. Fail if
- // it's different.
- if (mCurrentChar == 0 && frame.mSync1 != 0xff) {
- // Couldn't find the sync byte. Fail.
- return 0;
- }
-
- mCurrentChar++;
- MOZ_ASSERT(mCurrentChar <= sizeof(MP3Frame));
-
- // Don't have a full header yet.
- if (mCurrentChar < sizeof(MP3Frame)) {
- return 0;
- }
-
- // Woo, valid header. Return the length.
- mCurrentChar = 0;
- return frame.CalculateLength();
-
-fail:
- Reset();
- return 0;
-}
-
-uint32_t
-MP3Parser::GetSampleRate()
-{
- MP3Frame &frame = mData.mFrame;
- return mpeg_srates[frame.mVersion][frame.mSampleRate];
-}
-
-uint32_t
-MP3Parser::GetSamplesPerFrame()
-{
- MP3Frame &frame = mData.mFrame;
- return mpeg_frame_samples[frame.mVersion][frame.mLayer];
-}
-
-
-/** ID3Parser methods **/
-
-const char sID3Head[3] = { 'I', 'D', '3' };
-const uint32_t ID3_HEADER_LENGTH = 10;
-const uint32_t ID3_FOOTER_LENGTH = 10;
-const uint8_t ID3_FOOTER_PRESENT = 0x10;
-
-ID3Parser::ID3Parser()
- : mCurrentChar(0)
- , mVersion(0)
- , mFlags(0)
- , mHeaderLength(0)
-{ }
-
-void
-ID3Parser::Reset()
-{
- mCurrentChar = mVersion = mFlags = mHeaderLength = 0;
-}
-
-bool
-ID3Parser::ParseChar(char ch)
-{
- switch (mCurrentChar) {
- // The first three bytes of an ID3v2 header must match the string "ID3".
- case 0: case 1: case 2:
- if (ch != sID3Head[mCurrentChar]) {
- goto fail;
- }
- break;
- // The fourth and fifth bytes give the version, between 2 and 4.
- case 3:
- if (ch < '\2' || ch > '\4') {
- goto fail;
- }
- mVersion = uint8_t(ch);
- break;
- case 4:
- if (ch != '\0') {
- goto fail;
- }
- break;
- // The sixth byte gives the flags; valid flags depend on the version.
- case 5:
- if ((ch & (0xff >> mVersion)) != '\0') {
- goto fail;
- }
- mFlags = uint8_t(ch);
- break;
- // Bytes seven through ten give the sum of the byte length of the extended
- // header, the padding and the frames after unsynchronisation.
- // These bytes form a 28-bit integer, with the high bit of each byte unset.
- case 6: case 7: case 8: case 9:
- if (ch & 0x80) {
- goto fail;
- }
- mHeaderLength <<= 7;
- mHeaderLength |= ch;
- if (mCurrentChar == 9) {
- mHeaderLength += ID3_HEADER_LENGTH;
- mHeaderLength += (mFlags & ID3_FOOTER_PRESENT) ? ID3_FOOTER_LENGTH : 0;
- }
- break;
- default:
- MOZ_CRASH("Header already fully parsed!");
- }
-
- mCurrentChar++;
-
- return IsParsed();
-
-fail:
- if (mCurrentChar) {
- Reset();
- return ParseChar(ch);
- }
- Reset();
- return false;
-}
-
-bool
-ID3Parser::IsParsed() const
-{
- return mCurrentChar >= ID3_HEADER_LENGTH;
-}
-
-uint32_t
-ID3Parser::GetHeaderLength() const
-{
- MOZ_ASSERT(IsParsed(),
- "Queried length of ID3 header before parsing finished.");
- return mHeaderLength;
-}
-
-
-/** VBR header helper stuff **/
-
-// Helper function to find a VBR header in an MP3 frame.
-// Based on information from
-// http://www.codeproject.com/Articles/8295/MPEG-Audio-Frame-Header
-
-const uint32_t VBRI_TAG = FROM_BIG_ENDIAN("VBRI");
-const uint32_t VBRI_OFFSET = 32 - sizeof(MP3Frame);
-const uint32_t VBRI_FRAME_COUNT_OFFSET = VBRI_OFFSET + 14;
-const uint32_t VBRI_MIN_FRAME_SIZE = VBRI_OFFSET + 26;
-
-const uint32_t XING_TAG = FROM_BIG_ENDIAN("Xing");
-enum XingFlags {
- XING_HAS_NUM_FRAMES = 0x01,
- XING_HAS_NUM_BYTES = 0x02,
- XING_HAS_TOC = 0x04,
- XING_HAS_VBR_SCALE = 0x08
-};
-
-static int64_t
-ParseXing(const char *aBuffer)
-{
- uint32_t flags = FROM_BIG_ENDIAN(aBuffer + 4);
-
- if (!(flags & XING_HAS_NUM_FRAMES)) {
- NS_WARNING("VBR file without frame count. Duration estimation likely to "
- "be totally wrong.");
- return -1;
- }
-
- int64_t numFrames = -1;
- if (flags & XING_HAS_NUM_FRAMES) {
- numFrames = FROM_BIG_ENDIAN(aBuffer + 8);
- }
-
- return numFrames;
-}
-
-static int64_t
-FindNumVBRFrames(const nsCString& aFrame)
-{
- const char *buffer = aFrame.get();
- const char *bufferEnd = aFrame.get() + aFrame.Length();
-
- // VBRI header is nice and well-defined; let's try to find that first.
- if (aFrame.Length() > VBRI_MIN_FRAME_SIZE &&
- FROM_BIG_ENDIAN(buffer + VBRI_OFFSET) == VBRI_TAG) {
- return FROM_BIG_ENDIAN(buffer + VBRI_FRAME_COUNT_OFFSET);
- }
-
- // We have to search for the Xing header as its position can change.
- for (; buffer + sizeof(XING_TAG) < bufferEnd; buffer++) {
- if (FROM_BIG_ENDIAN(buffer) == XING_TAG) {
- return ParseXing(buffer);
- }
- }
-
- return -1;
-}
-
-
-/** MP3FrameParser methods **/
-
-// Some MP3's have large ID3v2 tags, up to 150KB, so we allow lots of
-// skipped bytes to be read, just in case, before we give up and assume
-// we're not parsing an MP3 stream.
-static const uint32_t MAX_SKIPPED_BYTES = 4096;
-
-enum {
- MP3_HEADER_LENGTH = 4,
-};
-
-MP3FrameParser::MP3FrameParser(int64_t aLength)
-: mLock("MP3FrameParser.mLock"),
- mTotalID3Size(0),
- mTotalFrameSize(0),
- mFrameCount(0),
- mOffset(0),
- mLength(aLength),
- mMP3Offset(-1),
- mSamplesPerSecond(0),
- mFirstFrameEnd(-1),
- mIsMP3(MAYBE_MP3)
-{ }
-
-nsresult MP3FrameParser::ParseBuffer(const uint8_t* aBuffer,
- uint32_t aLength,
- int64_t aStreamOffset,
- uint32_t* aOutBytesRead)
-{
- // Iterate forwards over the buffer, looking for ID3 tag, or MP3
- // Frame headers.
- const uint8_t *buffer = aBuffer;
- const uint8_t *bufferEnd = aBuffer + aLength;
-
- // If we haven't found any MP3 frame data yet, there might be ID3 headers
- // we can skip over.
- if (mMP3Offset < 0) {
- for (const uint8_t *ch = buffer; ch < bufferEnd; ch++) {
- if (mID3Parser.ParseChar(*ch)) {
- // Found an ID3 header. We don't care about the body of the header, so
- // just skip past.
- buffer = ch + mID3Parser.GetHeaderLength() - (ID3_HEADER_LENGTH - 1);
-
- if (buffer <= ch) {
- return NS_ERROR_FAILURE;
- }
-
- ch = buffer;
-
- mTotalID3Size += mID3Parser.GetHeaderLength();
-
- // Yes, this is an MP3!
- mIsMP3 = DEFINITELY_MP3;
-
- mID3Parser.Reset();
- }
- }
- }
-
- // The first MP3 frame in a variable bitrate stream can contain metadata
- // for duration estimation and seeking, so we buffer that first frame here.
- if (aStreamOffset < mFirstFrameEnd) {
- uint64_t copyLen = std::min((int64_t)aLength, mFirstFrameEnd - aStreamOffset);
- mFirstFrame.Append((const char *)buffer, copyLen);
- buffer += copyLen;
- }
-
- while (buffer < bufferEnd) {
- uint16_t frameLen = mMP3Parser.ParseFrameLength(*buffer);
-
- if (frameLen) {
- // We've found an MP3 frame!
- // This is the first frame (and the only one we'll bother parsing), so:
- // * Mark this stream as MP3;
- // * Store the offset at which the MP3 data started; and
- // * Start buffering the frame, as it might contain handy metadata.
-
- // We're now sure this is an MP3 stream.
- mIsMP3 = DEFINITELY_MP3;
-
- // We need to know these to convert the number of frames in the stream
- // to the length of the stream in seconds.
- mSamplesPerSecond = mMP3Parser.GetSampleRate();
- mSamplesPerFrame = mMP3Parser.GetSamplesPerFrame();
-
- // If the stream has a constant bitrate, we should only need the length
- // of the first frame and the length (in bytes) of the stream to
- // estimate the length (in seconds).
- mTotalFrameSize += frameLen;
- mFrameCount++;
-
- // If |mMP3Offset| isn't set then this is the first MP3 frame we have
- // seen in the stream, which is useful for duration estimation.
- if (mMP3Offset > -1) {
- uint16_t skip = frameLen - sizeof(MP3Frame);
- buffer += skip ? skip : 1;
- continue;
- }
-
- // Remember the offset of the MP3 stream.
- // We're at the last byte of an MP3Frame, so MP3 data started
- // sizeof(MP3Frame) - 1 bytes ago.
- mMP3Offset = aStreamOffset
- + (buffer - aBuffer)
- - (sizeof(MP3Frame) - 1);
-
- buffer++;
-
- // If the stream has a variable bitrate, the first frame has metadata
- // we need for duration estimation and seeking. Start buffering it so we
- // can parse it later.
- mFirstFrameEnd = mMP3Offset + frameLen;
- uint64_t currOffset = buffer - aBuffer + aStreamOffset;
- uint64_t copyLen = std::min(mFirstFrameEnd - currOffset,
- (uint64_t)(bufferEnd - buffer));
- mFirstFrame.Append((const char *)buffer, copyLen);
-
- buffer += copyLen;
-
- } else {
- // Nothing to see here. Move along.
- buffer++;
- }
- }
-
- *aOutBytesRead = buffer - aBuffer;
-
- if (mFirstFrameEnd > -1 && mFirstFrameEnd <= aStreamOffset + buffer - aBuffer) {
- // We have our whole first frame. Try to find a VBR header.
- mNumFrames = FindNumVBRFrames(mFirstFrame);
- mFirstFrameEnd = -1;
- }
-
- return NS_OK;
-}
-
-void MP3FrameParser::Parse(const uint8_t* aBuffer, uint32_t aLength, uint64_t aOffset)
-{
- MutexAutoLock mon(mLock);
-
- if (HasExactDuration()) {
- // We know the duration; nothing to do here.
- return;
- }
-
- const uint8_t* buffer = aBuffer;
- int32_t length = aLength;
- uint64_t offset = aOffset;
-
- // Got some data we have seen already. Skip forward to what we need.
- if (aOffset < mOffset) {
- buffer += mOffset - aOffset;
- length -= mOffset - aOffset;
- offset = mOffset;
-
- if (length <= 0) {
- return;
- }
- }
-
- // If there is a discontinuity in the input stream, reset the state of the
- // parsers so we don't get any partial headers.
- if (mOffset < aOffset) {
- if (!mID3Parser.IsParsed()) {
- // Only reset this if it hasn't finished yet.
- mID3Parser.Reset();
- }
-
- if (mFirstFrameEnd > -1) {
- NS_WARNING("Discontinuity in input while buffering first frame.");
- mFirstFrameEnd = -1;
- }
-
- mMP3Parser.Reset();
- }
-
- uint32_t bytesRead = 0;
- if (NS_FAILED(ParseBuffer(buffer,
- length,
- offset,
- &bytesRead))) {
- return;
- }
-
- MOZ_ASSERT(length <= (int)bytesRead, "All bytes should have been consumed");
-
- // Update next data offset
- mOffset = offset + bytesRead;
-
- // If we've parsed lots of data and we still have nothing, just give up.
- // We don't count ID3 headers towards the skipped bytes count, as MP3 files
- // can have massive ID3 sections.
- if (!mID3Parser.IsParsed() && mMP3Offset < 0 &&
- mOffset - mTotalID3Size > MAX_SKIPPED_BYTES) {
- mIsMP3 = NOT_MP3;
- }
-}
-
-int64_t MP3FrameParser::GetDuration()
-{
- MutexAutoLock mon(mLock);
-
- if (!ParsedHeaders() || !mSamplesPerSecond) {
- // Not a single frame decoded yet.
- return -1;
- }
-
- MOZ_ASSERT(mFrameCount > 0 && mTotalFrameSize > 0,
- "Frame parser should have seen at least one MP3 frame of positive length.");
-
- if (!mFrameCount || !mTotalFrameSize) {
- // This should never happen.
- return -1;
- }
-
- double frames;
- if (mNumFrames < 0) {
- // Estimate the number of frames in the stream based on the average frame
- // size and the length of the MP3 file.
- double frameSize = (double)mTotalFrameSize / mFrameCount;
- frames = (double)(mLength - mMP3Offset) / frameSize;
- } else {
- // We know the exact number of frames from the VBR header.
- frames = mNumFrames;
- }
-
- // The duration of each frame is constant over a given stream.
- double usPerFrame = USECS_PER_S * mSamplesPerFrame / mSamplesPerSecond;
-
- return frames * usPerFrame;
-}
-
-int64_t MP3FrameParser::GetMP3Offset()
-{
- MutexAutoLock mon(mLock);
- return mMP3Offset;
-}
-
-bool MP3FrameParser::ParsedHeaders()
-{
- // We have seen both the beginning and the end of the first MP3 frame in the
- // stream.
- return mMP3Offset > -1 && mFirstFrameEnd < 0;
-}
-
-bool MP3FrameParser::HasExactDuration()
-{
- return ParsedHeaders() && mNumFrames > -1;
-}
-
-bool MP3FrameParser::NeedsData()
-{
- // If we don't know the duration exactly then either:
- // - we're still waiting for a VBR header; or
- // - we look at all frames to constantly update our duration estimate.
- return IsMP3() && !HasExactDuration();
-}
-
-} // namespace mozilla
diff --git a/dom/media/MP3FrameParser.h b/dom/media/MP3FrameParser.h
deleted file mode 100644
index d2ba791fd..000000000
--- a/dom/media/MP3FrameParser.h
+++ /dev/null
@@ -1,219 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef MP3FrameParser_h
-#define MP3FrameParser_h
-
-#include <stdint.h>
-
-#include "mozilla/Mutex.h"
-#include "nsString.h"
-#include "Intervals.h"
-
-namespace mozilla {
-
-// Simple parser to tell whether we've found an ID3 header and how long it is,
-// so that we can skip it.
-// XXX maybe actually parse this stuff?
-class ID3Parser
-{
-public:
- ID3Parser();
-
- void Reset();
- bool ParseChar(char ch);
- bool IsParsed() const;
- uint32_t GetHeaderLength() const;
-
-private:
- uint32_t mCurrentChar;
- uint8_t mVersion;
- uint8_t mFlags;
- uint32_t mHeaderLength;
-};
-
-struct MP3Frame {
- uint16_t mSync1 : 8; // Always all set
- uint16_t mProtected : 1; // Ignored
- uint16_t mLayer : 2;
- uint16_t mVersion : 2;
- uint16_t mSync2 : 3; // Always all set
- uint16_t mPrivate : 1; // Ignored
- uint16_t mPad : 1;
- uint16_t mSampleRate : 2; // Index into mpeg_srates above
- uint16_t mBitrate : 4; // Index into mpeg_bitrates above
-
- uint16_t CalculateLength();
-};
-
-// Buffering parser for MP3 frames.
-class MP3Parser
-{
-public:
- MP3Parser();
-
- // Forget all data the parser has seen so far.
- void Reset();
-
- // Parse the given byte. If we have found a frame header, return the length of
- // the frame.
- uint16_t ParseFrameLength(uint8_t ch);
-
- // Get the sample rate from the current header.
- uint32_t GetSampleRate();
-
- // Get the number of samples per frame.
- uint32_t GetSamplesPerFrame();
-
-private:
- uint32_t mCurrentChar;
- union {
- uint8_t mRaw[3];
- MP3Frame mFrame;
- } mData;
-};
-
-
-// A description of the MP3 format and its extensions is available at
-//
-// http://www.codeproject.com/Articles/8295/MPEG-Audio-Frame-Header
-//
-// The data in MP3 streams is split into small frames, with each frame
-// containing a fixed number of samples. The duration of a frame depends
-// on the frame's bit rate and sample rate. Both values can vary among
-// frames, so it is necessary to examine each individual frame of an MP3
-// stream to calculate the stream's overall duration.
-//
-// The MP3 frame parser extracts information from an MP3 data stream. It
-// accepts a range of frames of an MP3 stream as input, and parses all
-// frames for their duration. Callers can query the stream's overall
-// duration from the parser.
-//
-// Call the methods NotifyDataArrived or Parse to add new data. If you added
-// information for a certain stream position, you cannot go back to previous
-// positions. The parser will simply ignore the input. If you skip stream
-// positions, the duration of the related MP3 frames will be estimated from
-// the stream's average.
-//
-// The method GetDuration returns calculated duration of the stream, including
-// estimates for skipped ranges.
-//
-// All public methods are thread-safe.
-
-class MP3FrameParser
-{
-public:
- explicit MP3FrameParser(int64_t aLength=-1);
-
- bool IsMP3() {
- MutexAutoLock mon(mLock);
- return mIsMP3 != NOT_MP3;
- }
-
- void Parse(const uint8_t* aBuffer, uint32_t aLength, uint64_t aStreamOffset);
-
- // Returns the duration, in microseconds. If the entire stream has not
- // been parsed yet, this is an estimate based on the bitrate of the
- // frames parsed so far.
- int64_t GetDuration();
-
- // Returns the offset of the first MP3 frame in the stream, or -1 of
- // no MP3 frame has been detected yet.
- int64_t GetMP3Offset();
-
- // Returns true if we've seen the whole first frame of the MP3 stream, and
- // therefore can make an estimate on the stream duration.
- // Otherwise, returns false.
- bool ParsedHeaders();
-
- // Returns true if we know the exact duration of the MP3 stream;
- // false otherwise.
- bool HasExactDuration();
-
- // Returns true if the parser needs more data for duration estimation.
- bool NeedsData();
- // Assign the total lenght of this mp3 stream
- void SetLength(int64_t aLength) {
- MutexAutoLock mon(mLock);
- mLength = aLength;
- }
-private:
-
- // Parses aBuffer, starting at offset 0. Returns the number of bytes
- // parsed, relative to the start of the buffer. Note this may be
- // greater than aLength if the headers in the buffer indicate that
- // the frame or ID3 tag extends outside of aBuffer. Returns failure
- // if too many non-MP3 bytes are parsed.
- nsresult ParseBuffer(const uint8_t* aBuffer,
- uint32_t aLength,
- int64_t aStreamOffset,
- uint32_t* aOutBytesRead);
-
- // A low-contention lock for protecting the parser results
- Mutex mLock;
-
- // ID3 header parser. Keeps state between reads in case the header falls
- // in between.
- ID3Parser mID3Parser;
-
- // MP3 frame header parser.
- MP3Parser mMP3Parser;
-
- // If we read |MAX_SKIPPED_BYTES| from the stream without finding any MP3
- // frames, we give up and report |NOT_MP3|. Here we track the cumulative size
- // of any ID3 headers we've seen so big ID3 sections aren't counted towards
- // skipped bytes.
- uint32_t mTotalID3Size;
-
- // All fields below are protected by mLock
-
- // We keep stats on the size of all the frames we've seen, as well as how many
- // so that we can estimate the duration of the rest of the stream.
- uint64_t mTotalFrameSize;
- uint64_t mFrameCount;
-
- // Offset of the last data parsed. This is the end offset of the last data
- // block parsed, so it's the start offset we expect to get on the next
- // call to Parse().
- uint64_t mOffset;
-
- // Total length of the stream in bytes.
- int64_t mLength;
-
- // Offset of first MP3 frame in the bitstream. Has value -1 until the
- // first MP3 frame is found.
- int64_t mMP3Offset;
-
- // The exact number of frames in this stream, if we know it. -1 otherwise.
- int64_t mNumFrames;
-
- // Number of audio samples per second and per frame. Fixed through the whole
- // file. If we know these variables as well as the number of frames in the
- // file, we can get an exact duration for the stream.
- uint16_t mSamplesPerSecond;
- uint16_t mSamplesPerFrame;
-
- // If the MP3 has a variable bitrate, then there *should* be metadata about
- // the encoding in the first frame. We buffer the first frame here.
- nsCString mFirstFrame;
-
- // While we are reading the first frame, this is the stream offset of the
- // last byte of that frame. -1 at all other times.
- int64_t mFirstFrameEnd;
-
- enum eIsMP3 {
- MAYBE_MP3, // We're giving the stream the benefit of the doubt...
- DEFINITELY_MP3, // We've hit at least one ID3 tag or MP3 frame.
- NOT_MP3 // Not found any evidence of the stream being MP3.
- };
-
- eIsMP3 mIsMP3;
-
-};
-
-} // namespace mozilla
-
-#endif
diff --git a/dom/media/MediaData.h b/dom/media/MediaData.h
index a79aac6ed..905b4c1d9 100644
--- a/dom/media/MediaData.h
+++ b/dom/media/MediaData.h
@@ -14,6 +14,7 @@
#include "nsIMemoryReporter.h"
#include "SharedBuffer.h"
#include "mozilla/RefPtr.h"
+#include "mozilla/Span.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/UniquePtrExtensions.h"
#include "nsTArray.h"
@@ -631,6 +632,8 @@ public:
{
return sizeof(*this) + mBuffer.ComputedSizeOfExcludingThis();
}
+ // Access the buffer as a Span.
+ operator Span<const uint8_t>() { return MakeSpan(Data(), Size()); }
const CryptoSample& mCrypto;
RefPtr<MediaByteBuffer> mExtraData;
diff --git a/dom/media/MediaDecoder.cpp b/dom/media/MediaDecoder.cpp
index 9334d1bcb..223c59c3b 100644
--- a/dom/media/MediaDecoder.cpp
+++ b/dom/media/MediaDecoder.cpp
@@ -30,15 +30,10 @@
#include "mozilla/dom/VideoTrack.h"
#include "mozilla/dom/VideoTrackList.h"
#include "nsPrintfCString.h"
-#include "mozilla/Telemetry.h"
#include "GMPService.h"
#include "Layers.h"
#include "mozilla/layers/ShadowLayers.h"
-#ifdef MOZ_ANDROID_OMX
-#include "AndroidBridge.h"
-#endif
-
using namespace mozilla::dom;
using namespace mozilla::layers;
using namespace mozilla::media;
@@ -425,7 +420,6 @@ MediaDecoder::MediaDecoder(MediaDecoderOwner* aOwner)
, INIT_CANONICAL(mPlaybackRateReliable, true)
, INIT_CANONICAL(mDecoderPosition, 0)
, INIT_CANONICAL(mIsVisible, !aOwner->IsHidden())
- , mTelemetryReported(false)
{
MOZ_COUNT_CTOR(MediaDecoder);
MOZ_ASSERT(NS_IsMainThread());
@@ -845,42 +839,6 @@ MediaDecoder::MetadataLoaded(nsAutoPtr<MediaInfo> aInfo,
// So we call Invalidate() after calling mOwner->MetadataLoaded to ensure
// the media element has the latest dimensions.
Invalidate();
-
- EnsureTelemetryReported();
-}
-
-void
-MediaDecoder::EnsureTelemetryReported()
-{
- MOZ_ASSERT(NS_IsMainThread());
-
- if (mTelemetryReported || !mInfo) {
- // Note: sometimes we get multiple MetadataLoaded calls (for example
- // for chained ogg). So we ensure we don't report duplicate results for
- // these resources.
- return;
- }
-
- nsTArray<nsCString> codecs;
- if (mInfo->HasAudio() && !mInfo->mAudio.GetAsAudioInfo()->mMimeType.IsEmpty()) {
- codecs.AppendElement(mInfo->mAudio.GetAsAudioInfo()->mMimeType);
- }
- if (mInfo->HasVideo() && !mInfo->mVideo.GetAsVideoInfo()->mMimeType.IsEmpty()) {
- codecs.AppendElement(mInfo->mVideo.GetAsVideoInfo()->mMimeType);
- }
- if (codecs.IsEmpty()) {
- if (mResource->GetContentType().IsEmpty()) {
- NS_WARNING("Somehow the resource's content type is empty");
- return;
- }
- codecs.AppendElement(nsPrintfCString("resource; %s", mResource->GetContentType().get()));
- }
- for (const nsCString& codec : codecs) {
- DECODER_LOG("Telemetry MEDIA_CODEC_USED= '%s'", codec.get());
- Telemetry::Accumulate(Telemetry::ID::MEDIA_CODEC_USED, codec);
- }
-
- mTelemetryReported = true;
}
const char*
@@ -1618,16 +1576,6 @@ MediaDecoder::IsWebMEnabled()
return Preferences::GetBool("media.webm.enabled");
}
-#ifdef MOZ_ANDROID_OMX
-bool
-MediaDecoder::IsAndroidMediaPluginEnabled()
-{
- return AndroidBridge::Bridge() &&
- AndroidBridge::Bridge()->GetAPIVersion() < 16 &&
- Preferences::GetBool("media.plugins.enabled");
-}
-#endif
-
NS_IMETHODIMP
MediaMemoryTracker::CollectReports(nsIHandleReportCallback* aHandleReport,
nsISupports* aData, bool aAnonymize)
diff --git a/dom/media/MediaDecoder.h b/dom/media/MediaDecoder.h
index a4edcbe72..05e88db8b 100644
--- a/dom/media/MediaDecoder.h
+++ b/dom/media/MediaDecoder.h
@@ -440,17 +440,11 @@ private:
void SetCDMProxy(CDMProxy* aProxy);
- void EnsureTelemetryReported();
-
static bool IsOggEnabled();
static bool IsOpusEnabled();
static bool IsWaveEnabled();
static bool IsWebMEnabled();
-#ifdef MOZ_ANDROID_OMX
- static bool IsAndroidMediaPluginEnabled();
-#endif
-
#ifdef MOZ_WMF
static bool IsWMFEnabled();
#endif
@@ -856,8 +850,6 @@ private:
// download has ended. Called on the main thread only. aStatus is
// the result from OnStopRequest.
void NotifyDownloadEnded(nsresult aStatus);
-
- bool mTelemetryReported;
};
} // namespace mozilla
diff --git a/dom/media/MediaDecoderStateMachine.cpp b/dom/media/MediaDecoderStateMachine.cpp
index c586139ad..2ed1956c9 100644
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -1173,60 +1173,12 @@ StateObject::HandleShutdown()
return SetState<ShutdownState>();
}
-static void
-ReportRecoveryTelemetry(const TimeStamp& aRecoveryStart,
- const MediaInfo& aMediaInfo,
- bool aIsHardwareAccelerated)
-{
- MOZ_ASSERT(NS_IsMainThread());
- if (!aMediaInfo.HasVideo()) {
- return;
- }
-
- // Keyed by audio+video or video alone, hardware acceleration,
- // and by a resolution range.
- nsCString key(aMediaInfo.HasAudio() ? "AV" : "V");
- key.AppendASCII(aIsHardwareAccelerated ? "(hw)," : ",");
- static const struct { int32_t mH; const char* mRes; } sResolutions[] = {
- { 240, "0-240" },
- { 480, "241-480" },
- { 720, "481-720" },
- { 1080, "721-1080" },
- { 2160, "1081-2160" }
- };
- const char* resolution = "2161+";
- int32_t height = aMediaInfo.mVideo.mImage.height;
- for (const auto& res : sResolutions) {
- if (height <= res.mH) {
- resolution = res.mRes;
- break;
- }
- }
- key.AppendASCII(resolution);
-
- TimeDuration duration = TimeStamp::Now() - aRecoveryStart;
- double duration_ms = duration.ToMilliseconds();
- Telemetry::Accumulate(Telemetry::VIDEO_SUSPEND_RECOVERY_TIME_MS,
- key,
- uint32_t(duration_ms + 0.5));
- Telemetry::Accumulate(Telemetry::VIDEO_SUSPEND_RECOVERY_TIME_MS,
- NS_LITERAL_CSTRING("All"),
- uint32_t(duration_ms + 0.5));
-}
-
void
MediaDecoderStateMachine::
StateObject::HandleResumeVideoDecoding()
{
MOZ_ASSERT(mMaster->mVideoDecodeSuspended);
- // Start counting recovery time from right now.
- TimeStamp start = TimeStamp::Now();
-
- // Local reference to mInfo, so that it will be copied in the lambda below.
- auto& info = Info();
- bool hw = Reader()->VideoIsHardwareAccelerated();
-
// Start video-only seek to the current time.
SeekJob seekJob;
@@ -1238,10 +1190,7 @@ StateObject::HandleResumeVideoDecoding()
type,
true /* aVideoOnly */);
- SetState<SeekingState>(Move(seekJob), EventVisibility::Suppressed)->Then(
- AbstractThread::MainThread(), __func__,
- [start, info, hw](){ ReportRecoveryTelemetry(start, info, hw); },
- [](){});
+ SetState<SeekingState>(Move(seekJob), EventVisibility::Suppressed);
}
void
diff --git a/dom/media/MediaFormatReader.cpp b/dom/media/MediaFormatReader.cpp
index 06e8b963b..773434710 100644
--- a/dom/media/MediaFormatReader.cpp
+++ b/dom/media/MediaFormatReader.cpp
@@ -32,6 +32,10 @@ using mozilla::layers::Image;
using mozilla::layers::LayerManager;
using mozilla::layers::LayersBackend;
+// avoid redefined macro warning in unified builds
+#undef LOG
+#undef LOGV
+
static mozilla::LazyLogModule sFormatDecoderLog("MediaFormatReader");
mozilla::LazyLogModule gMediaDemuxerLog("MediaDemuxer");
diff --git a/dom/media/MediaManager.cpp b/dom/media/MediaManager.cpp
index ba6b4cd47..979cb64c7 100644
--- a/dom/media/MediaManager.cpp
+++ b/dom/media/MediaManager.cpp
@@ -32,7 +32,6 @@
#include "nsAppDirectoryServiceDefs.h"
#include "nsIInputStream.h"
#include "nsILineInputStream.h"
-#include "mozilla/Telemetry.h"
#include "mozilla/Types.h"
#include "mozilla/PeerIdentity.h"
#include "mozilla/dom/ContentChild.h"
@@ -2034,7 +2033,6 @@ MediaManager::GetUserMedia(nsPIDOMWindowInner* aWindow,
}
// Determine permissions early (while we still have a stack).
-
nsIURI* docURI = aWindow->GetDocumentURI();
if (!docURI) {
return NS_ERROR_UNEXPECTED;
@@ -2044,48 +2042,23 @@ MediaManager::GetUserMedia(nsPIDOMWindowInner* aWindow,
Preferences::GetBool("media.navigator.permission.disabled", false);
bool isHTTPS = false;
docURI->SchemeIs("https", &isHTTPS);
- nsCString host;
- nsresult rv = docURI->GetHost(host);
- // Test for some other schemes that ServiceWorker recognizes
- bool isFile;
- docURI->SchemeIs("file", &isFile);
- bool isApp;
- docURI->SchemeIs("app", &isApp);
- // Same localhost check as ServiceWorkers uses
- // (see IsOriginPotentiallyTrustworthy())
- bool isLocalhost = NS_SUCCEEDED(rv) &&
- (host.LowerCaseEqualsLiteral("localhost") ||
- host.LowerCaseEqualsLiteral("127.0.0.1") ||
- host.LowerCaseEqualsLiteral("::1"));
-
- // Record telemetry about whether the source of the call was secure, i.e.,
- // privileged or HTTPS. We may handle other cases
-if (privileged) {
- Telemetry::Accumulate(Telemetry::WEBRTC_GET_USER_MEDIA_SECURE_ORIGIN,
- (uint32_t) GetUserMediaSecurityState::Privileged);
- } else if (isHTTPS) {
- Telemetry::Accumulate(Telemetry::WEBRTC_GET_USER_MEDIA_SECURE_ORIGIN,
- (uint32_t) GetUserMediaSecurityState::HTTPS);
- } else if (isFile) {
- Telemetry::Accumulate(Telemetry::WEBRTC_GET_USER_MEDIA_SECURE_ORIGIN,
- (uint32_t) GetUserMediaSecurityState::File);
- } else if (isApp) {
- Telemetry::Accumulate(Telemetry::WEBRTC_GET_USER_MEDIA_SECURE_ORIGIN,
- (uint32_t) GetUserMediaSecurityState::App);
- } else if (isLocalhost) {
- Telemetry::Accumulate(Telemetry::WEBRTC_GET_USER_MEDIA_SECURE_ORIGIN,
- (uint32_t) GetUserMediaSecurityState::Localhost);
- } else {
- Telemetry::Accumulate(Telemetry::WEBRTC_GET_USER_MEDIA_SECURE_ORIGIN,
- (uint32_t) GetUserMediaSecurityState::Other);
- }
nsCString origin;
- rv = nsPrincipal::GetOriginForURI(docURI, origin);
+ nsresult rv = nsPrincipal::GetOriginForURI(docURI, origin);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
+ // Disallow access to null principal pages
+ nsCOMPtr<nsIPrincipal> principal = aWindow->GetExtantDoc()->NodePrincipal();
+ if (principal->GetIsNullPrincipal()) {
+ RefPtr<MediaStreamError> error =
+ new MediaStreamError(aWindow,
+ NS_LITERAL_STRING("NotAllowedError"));
+ onFailure->OnError(error);
+ return NS_OK;
+ }
+
if (!Preferences::GetBool("media.navigator.video.enabled", true)) {
c.mVideo.SetAsBoolean() = false;
}
@@ -2098,8 +2071,6 @@ if (privileged) {
videoType = StringToEnum(dom::MediaSourceEnumValues::strings,
vc.mMediaSource,
MediaSourceEnum::Other);
- Telemetry::Accumulate(Telemetry::WEBRTC_GET_USER_MEDIA_TYPE,
- (uint32_t) videoType);
switch (videoType) {
case MediaSourceEnum::Camera:
break;
@@ -2182,8 +2153,6 @@ if (privileged) {
ac.mMediaSource.AssignASCII(EnumToASCII(dom::MediaSourceEnumValues::strings,
audioType));
}
- Telemetry::Accumulate(Telemetry::WEBRTC_GET_USER_MEDIA_TYPE,
- (uint32_t) audioType);
switch (audioType) {
case MediaSourceEnum::Microphone:
@@ -2229,7 +2198,6 @@ if (privileged) {
StreamListeners* listeners = AddWindowID(windowID);
// Create a disabled listener to act as a placeholder
- nsIPrincipal* principal = aWindow->GetExtantDoc()->NodePrincipal();
RefPtr<GetUserMediaCallbackMediaStreamListener> listener =
new GetUserMediaCallbackMediaStreamListener(mMediaThread, windowID,
MakePrincipalHandle(principal));
diff --git a/dom/media/MediaPrefs.h b/dom/media/MediaPrefs.h
index b237ecd3d..c67a89989 100644
--- a/dom/media/MediaPrefs.h
+++ b/dom/media/MediaPrefs.h
@@ -105,9 +105,6 @@ private:
DECL_MEDIA_PREF("media.eme.enabled", EMEEnabled, bool, false);
DECL_MEDIA_PREF("media.use-blank-decoder", PDMUseBlankDecoder, bool, false);
DECL_MEDIA_PREF("media.gpu-process-decoder", PDMUseGPUDecoder, bool, false);
-#ifdef MOZ_GONK_MEDIACODEC
- DECL_MEDIA_PREF("media.gonk.enabled", PDMGonkDecoderEnabled, bool, true);
-#endif
#ifdef MOZ_WIDGET_ANDROID
DECL_MEDIA_PREF("media.android-media-codec.enabled", PDMAndroidMediaCodecEnabled, bool, false);
DECL_MEDIA_PREF("media.android-media-codec.preferred", PDMAndroidMediaCodecPreferred, bool, false);
@@ -120,6 +117,9 @@ private:
#ifdef MOZ_FFVPX
DECL_MEDIA_PREF("media.ffvpx.enabled", PDMFFVPXEnabled, bool, true);
#endif
+#ifdef MOZ_AV1
+ DECL_MEDIA_PREF("media.av1.enabled", AV1Enabled, bool, false);
+#endif
#ifdef XP_WIN
DECL_MEDIA_PREF("media.wmf.enabled", PDMWMFEnabled, bool, true);
DECL_MEDIA_PREF("media.wmf.skip-blacklist", PDMWMFSkipBlacklist, bool, false);
diff --git a/dom/media/MediaStreamGraph.cpp b/dom/media/MediaStreamGraph.cpp
index e2934cbb2..1b9e4f674 100644
--- a/dom/media/MediaStreamGraph.cpp
+++ b/dom/media/MediaStreamGraph.cpp
@@ -3371,7 +3371,8 @@ MediaStreamGraphImpl::Destroy()
// First unregister from memory reporting.
UnregisterWeakMemoryReporter(this);
- // Clear the self reference which will destroy this instance.
+ // Clear the self reference which will destroy this instance if all
+ // associated GraphDrivers are destroyed.
mSelfRef = nullptr;
}
diff --git a/dom/media/ThreadPoolCOMListener.h b/dom/media/ThreadPoolCOMListener.h
index 881013a78..424ca65d2 100644
--- a/dom/media/ThreadPoolCOMListener.h
+++ b/dom/media/ThreadPoolCOMListener.h
@@ -13,8 +13,8 @@
namespace mozilla {
// Thread pool listener which ensures that MSCOM is initialized and
-// deinitialized on the thread pool thread. We may call into WMF or
-// DirectShow on this thread, so we need MSCOM working.
+// deinitialized on the thread pool thread. We may call into WMF on
+// this thread, so we need MSCOM working.
class MSCOMInitThreadPoolListener final : public nsIThreadPoolListener {
~MSCOMInitThreadPoolListener() {}
public:
diff --git a/dom/media/VideoFrameContainer.cpp b/dom/media/VideoFrameContainer.cpp
index 2b1965766..56aea9d27 100644
--- a/dom/media/VideoFrameContainer.cpp
+++ b/dom/media/VideoFrameContainer.cpp
@@ -61,7 +61,7 @@ void VideoFrameContainer::UpdatePrincipalHandleForFrameIDLocked(const PrincipalH
mFrameIDForPendingPrincipalHandle = aFrameID;
}
-static void
+static bool
SetImageToBlackPixel(PlanarYCbCrImage* aImage)
{
uint8_t blackPixel[] = { 0x10, 0x80, 0x80 };
@@ -72,7 +72,7 @@ SetImageToBlackPixel(PlanarYCbCrImage* aImage)
data.mCrChannel = blackPixel + 2;
data.mYStride = data.mCbCrStride = 1;
data.mPicSize = data.mYSize = data.mCbCrSize = gfx::IntSize(1, 1);
- aImage->CopyData(data);
+ return aImage->CopyData(data);
}
class VideoFrameContainerInvalidateRunnable : public Runnable {
@@ -122,11 +122,13 @@ void VideoFrameContainer::SetCurrentFrames(const VideoSegment& aSegment)
if (frame->GetForceBlack()) {
if (!mBlackImage) {
- mBlackImage = GetImageContainer()->CreatePlanarYCbCrImage();
- if (mBlackImage) {
+ RefPtr<Image> blackImage = GetImageContainer()->CreatePlanarYCbCrImage();
+ if (blackImage) {
// Sets the image to a single black pixel, which will be scaled to
// fill the rendered size.
- SetImageToBlackPixel(mBlackImage->AsPlanarYCbCrImage());
+ if (SetImageToBlackPixel(blackImage->AsPlanarYCbCrImage())) {
+ mBlackImage = blackImage;
+ }
}
}
if (mBlackImage) {
diff --git a/dom/media/VideoUtils.cpp b/dom/media/VideoUtils.cpp
index 5c00e54bc..c06ba9070 100644
--- a/dom/media/VideoUtils.cpp
+++ b/dom/media/VideoUtils.cpp
@@ -6,7 +6,6 @@
#include "mozilla/Base64.h"
#include "mozilla/TaskQueue.h"
-#include "mozilla/Telemetry.h"
#include "mozilla/Function.h"
#include "MediaContentType.h"
@@ -208,8 +207,20 @@ already_AddRefed<SharedThreadPool> GetMediaThreadPool(MediaThreadType aType)
name = "MediaPlayback";
break;
}
- return SharedThreadPool::
+ RefPtr<SharedThreadPool> pool = SharedThreadPool::
Get(nsDependentCString(name), MediaPrefs::MediaThreadPoolDefaultCount());
+
+ // Ensure a larger stack for platform decoder threads
+ if (aType == MediaThreadType::PLATFORM_DECODER) {
+ const uint32_t minStackSize = 512*1024;
+ uint32_t stackSize;
+ MOZ_ALWAYS_SUCCEEDS(pool->GetThreadStackSize(&stackSize));
+ if (stackSize < minStackSize) {
+ MOZ_ALWAYS_SUCCEEDS(pool->SetThreadStackSize(minStackSize));
+ }
+ }
+
+ return pool.forget();
}
bool
@@ -248,24 +259,6 @@ ExtractH264CodecDetails(const nsAString& aCodec,
aLevel *= 10;
}
- // Capture the constraint_set flag value for the purpose of Telemetry.
- // We don't NS_ENSURE_SUCCESS here because ExtractH264CodecDetails doesn't
- // care about this, but we make sure constraints is above 4 (constraint_set5_flag)
- // otherwise collect 0 for unknown.
- uint8_t constraints = PromiseFlatString(Substring(aCodec, 7, 2)).ToInteger(&rv, 16);
- Telemetry::Accumulate(Telemetry::VIDEO_CANPLAYTYPE_H264_CONSTRAINT_SET_FLAG,
- constraints >= 4 ? constraints : 0);
-
- // 244 is the highest meaningful profile value (High 4:4:4 Intra Profile)
- // that can be represented as single hex byte, otherwise collect 0 for unknown.
- Telemetry::Accumulate(Telemetry::VIDEO_CANPLAYTYPE_H264_PROFILE,
- aProfile <= 244 ? aProfile : 0);
-
- // Make sure aLevel represents a value between levels 1 and 5.2,
- // otherwise collect 0 for unknown.
- Telemetry::Accumulate(Telemetry::VIDEO_CANPLAYTYPE_H264_LEVEL,
- (aLevel >= 10 && aLevel <= 52) ? aLevel : 0);
-
return true;
}
@@ -445,6 +438,16 @@ ParseMIMETypeString(const nsAString& aMIMEType,
return ParseCodecsString(codecsStr, aOutCodecs);
}
+template <int N>
+static bool
+StartsWith(const nsACString& string, const char (&prefix)[N])
+{
+ if (N - 1 > string.Length()) {
+ return false;
+ }
+ return memcmp(string.Data(), prefix, N - 1) == 0;
+}
+
bool
IsH264CodecString(const nsAString& aCodec)
{
@@ -477,15 +480,14 @@ IsVP9CodecString(const nsAString& aCodec)
aCodec.EqualsLiteral("vp9.0");
}
-template <int N>
-static bool
-StartsWith(const nsACString& string, const char (&prefix)[N])
+#ifdef MOZ_AV1
+bool
+IsAV1CodecString(const nsAString& aCodec)
{
- if (N - 1 > string.Length()) {
- return false;
- }
- return memcmp(string.Data(), prefix, N - 1) == 0;
+ return aCodec.EqualsLiteral("av1") ||
+ StartsWith(NS_ConvertUTF16toUTF8(aCodec), "av01");
}
+#endif
UniquePtr<TrackInfo>
CreateTrackInfoWithMIMEType(const nsACString& aCodecMIMEType)
diff --git a/dom/media/VideoUtils.h b/dom/media/VideoUtils.h
index 441b63792..aaf0e9903 100644
--- a/dom/media/VideoUtils.h
+++ b/dom/media/VideoUtils.h
@@ -345,6 +345,11 @@ IsVP8CodecString(const nsAString& aCodec);
bool
IsVP9CodecString(const nsAString& aCodec);
+#ifdef MOZ_AV1
+bool
+IsAV1CodecString(const nsAString& aCodec);
+#endif
+
// Try and create a TrackInfo with a given codec MIME type.
UniquePtr<TrackInfo>
CreateTrackInfoWithMIMEType(const nsACString& aCodecMIMEType);
diff --git a/dom/media/WebVTTListener.h b/dom/media/WebVTTListener.h
index 67271664a..461d7f00d 100644
--- a/dom/media/WebVTTListener.h
+++ b/dom/media/WebVTTListener.h
@@ -10,6 +10,7 @@
#include "nsIStreamListener.h"
#include "nsIChannelEventSink.h"
#include "nsIInterfaceRequestor.h"
+#include "nsCOMPtr.h"
#include "nsCycleCollectionParticipant.h"
class nsIWebVTTParserWrapper;
diff --git a/dom/media/android/AndroidMediaDecoder.cpp b/dom/media/android/AndroidMediaDecoder.cpp
deleted file mode 100644
index 41ef3fcb0..000000000
--- a/dom/media/android/AndroidMediaDecoder.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "MediaDecoderStateMachine.h"
-#include "AndroidMediaDecoder.h"
-#include "AndroidMediaReader.h"
-
-namespace mozilla {
-
-AndroidMediaDecoder::AndroidMediaDecoder(MediaDecoderOwner* aOwner,
- const nsACString& aType)
- : MediaDecoder(aOwner), mType(aType)
-{
-}
-
-MediaDecoderStateMachine* AndroidMediaDecoder::CreateStateMachine()
-{
- return new MediaDecoderStateMachine(this, new AndroidMediaReader(this, mType));
-}
-
-} // namespace mozilla
-
diff --git a/dom/media/android/AndroidMediaDecoder.h b/dom/media/android/AndroidMediaDecoder.h
deleted file mode 100644
index 88b5a243f..000000000
--- a/dom/media/android/AndroidMediaDecoder.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-#if !defined(AndroidMediaDecoder_h_)
-#define AndroidMediaDecoder_h_
-
-#include "MediaDecoder.h"
-#include "AndroidMediaDecoder.h"
-
-namespace mozilla {
-
-class AndroidMediaDecoder : public MediaDecoder
-{
- nsCString mType;
-public:
- AndroidMediaDecoder(MediaDecoderOwner* aOwner, const nsACString& aType);
-
- MediaDecoder* Clone(MediaDecoderOwner* aOwner) override {
- return new AndroidMediaDecoder(aOwner, mType);
- }
- MediaDecoderStateMachine* CreateStateMachine() override;
-};
-
-} // namespace mozilla
-
-#endif
diff --git a/dom/media/android/AndroidMediaPluginHost.cpp b/dom/media/android/AndroidMediaPluginHost.cpp
deleted file mode 100644
index d4c4fc59e..000000000
--- a/dom/media/android/AndroidMediaPluginHost.cpp
+++ /dev/null
@@ -1,305 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-#include "mozilla/Preferences.h"
-#include "MediaResource.h"
-#include "mozilla/dom/HTMLMediaElement.h"
-#include "mozilla/Services.h"
-#include "AndroidMediaPluginHost.h"
-#include "nsAutoPtr.h"
-#include "nsXPCOMStrings.h"
-#include "nsISeekableStream.h"
-#include "nsIGfxInfo.h"
-#include "prmem.h"
-#include "prlink.h"
-#include "AndroidMediaResourceServer.h"
-#include "nsServiceManagerUtils.h"
-
-#include "MPAPI.h"
-
-#include "nsIPropertyBag2.h"
-
-#if defined(ANDROID)
-#include "android/log.h"
-#define ALOG(args...) __android_log_print(ANDROID_LOG_INFO, "AndroidMediaPluginHost" , ## args)
-#else
-#define ALOG(args...) /* do nothing */
-#endif
-
-using namespace MPAPI;
-
-Decoder::Decoder() :
- mResource(nullptr), mPrivate(nullptr)
-{
-}
-
-namespace mozilla {
-
-static char* GetResource(Decoder *aDecoder)
-{
- return static_cast<char*>(aDecoder->mResource);
-}
-
-class GetIntPrefEvent : public Runnable {
-public:
- GetIntPrefEvent(const char* aPref, int32_t* aResult)
- : mPref(aPref), mResult(aResult) {}
- NS_IMETHOD Run() override {
- return Preferences::GetInt(mPref, mResult);
- }
-private:
- const char* mPref;
- int32_t* mResult;
-};
-
-static bool GetIntPref(const char* aPref, int32_t* aResult)
-{
- // GetIntPref() is called on the decoder thread, but the Preferences API
- // can only be called on the main thread. Post a runnable and wait.
- NS_ENSURE_TRUE(aPref, false);
- NS_ENSURE_TRUE(aResult, false);
- nsCOMPtr<nsIRunnable> event = new GetIntPrefEvent(aPref, aResult);
- return NS_SUCCEEDED(NS_DispatchToMainThread(event, NS_DISPATCH_SYNC));
-}
-
-static bool
-GetSystemInfoString(const char *aKey, char *aResult, size_t aResultLength)
-{
- NS_ENSURE_TRUE(aKey, false);
- NS_ENSURE_TRUE(aResult, false);
-
- nsCOMPtr<nsIPropertyBag2> infoService = do_GetService("@mozilla.org/system-info;1");
- NS_ASSERTION(infoService, "Could not find a system info service");
-
- nsAutoCString key(aKey);
- nsAutoCString info;
- nsresult rv = infoService->GetPropertyAsACString(NS_ConvertUTF8toUTF16(key),
- info);
-
- NS_ENSURE_SUCCESS(rv, false);
-
- strncpy(aResult, info.get(), aResultLength);
-
- return true;
-}
-
-static PluginHost sPluginHost = {
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- GetIntPref,
- GetSystemInfoString
-};
-
-// Return true if Omx decoding is supported on the device. This checks the
-// built in whitelist/blacklist and preferences to see if that is overridden.
-static bool IsOmxSupported()
-{
- bool forceEnabled =
- Preferences::GetBool("stagefright.force-enabled", false);
- bool disabled =
- Preferences::GetBool("stagefright.disabled", false);
-
- if (disabled) {
- NS_WARNING("XXX stagefright disabled\n");
- return false;
- }
-
- if (!forceEnabled) {
- nsCOMPtr<nsIGfxInfo> gfxInfo = services::GetGfxInfo();
- if (gfxInfo) {
- int32_t status;
- nsCString discardFailure;
- if (NS_SUCCEEDED(gfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_STAGEFRIGHT, discardFailure, &status))) {
- if (status != nsIGfxInfo::FEATURE_STATUS_OK) {
- NS_WARNING("XXX stagefright blacklisted\n");
- return false;
- }
- }
- }
- }
-
- return true;
-}
-
-// Return the name of the shared library that implements Omx based decoding. This varies
-// depending on libstagefright version installed on the device and whether it is B2G vs Android.
-// nullptr is returned if Omx decoding is not supported on the device,
-static const char* GetOmxLibraryName()
-{
-#if defined(ANDROID)
- nsCOMPtr<nsIPropertyBag2> infoService = do_GetService("@mozilla.org/system-info;1");
- NS_ASSERTION(infoService, "Could not find a system info service");
-
- int32_t version;
- nsresult rv = infoService->GetPropertyAsInt32(NS_LITERAL_STRING("version"), &version);
- if (NS_SUCCEEDED(rv)) {
- ALOG("Android Version is: %d", version);
- }
-
- nsAutoString release_version;
- rv = infoService->GetPropertyAsAString(NS_LITERAL_STRING("release_version"), release_version);
- if (NS_SUCCEEDED(rv)) {
- ALOG("Android Release Version is: %s", NS_LossyConvertUTF16toASCII(release_version).get());
- }
-
- nsAutoString device;
- rv = infoService->GetPropertyAsAString(NS_LITERAL_STRING("device"), device);
- if (NS_SUCCEEDED(rv)) {
- ALOG("Android Device is: %s", NS_LossyConvertUTF16toASCII(device).get());
- }
-
- nsAutoString manufacturer;
- rv = infoService->GetPropertyAsAString(NS_LITERAL_STRING("manufacturer"), manufacturer);
- if (NS_SUCCEEDED(rv)) {
- ALOG("Android Manufacturer is: %s", NS_LossyConvertUTF16toASCII(manufacturer).get());
- }
-
- nsAutoString hardware;
- rv = infoService->GetPropertyAsAString(NS_LITERAL_STRING("hardware"), hardware);
- if (NS_SUCCEEDED(rv)) {
- ALOG("Android Hardware is: %s", NS_LossyConvertUTF16toASCII(hardware).get());
- }
-#endif
-
- if (!IsOmxSupported())
- return nullptr;
-
-#if defined(ANDROID)
- if (version >= 17) {
- return "libomxpluginkk.so";
- }
-
- // Ice Cream Sandwich and Jellybean
- return "libomxplugin.so";
-
-#else
- return nullptr;
-#endif
-}
-
-AndroidMediaPluginHost::AndroidMediaPluginHost() {
- MOZ_COUNT_CTOR(AndroidMediaPluginHost);
- MOZ_ASSERT(NS_IsMainThread());
-
- mResourceServer = AndroidMediaResourceServer::Start();
-
- const char* name = GetOmxLibraryName();
- ALOG("Loading OMX Plugin: %s", name ? name : "nullptr");
- if (name) {
- char *path = PR_GetLibraryFilePathname("libxul.so", (PRFuncPtr) GetOmxLibraryName);
- PRLibrary *lib = nullptr;
- if (path) {
- nsAutoCString libpath(path);
- PR_Free(path);
- int32_t slash = libpath.RFindChar('/');
- if (slash != kNotFound) {
- libpath.Truncate(slash + 1);
- libpath.Append(name);
- lib = PR_LoadLibrary(libpath.get());
- }
- }
- if (!lib)
- lib = PR_LoadLibrary(name);
-
- if (lib) {
- Manifest *manifest = static_cast<Manifest *>(PR_FindSymbol(lib, "MPAPI_MANIFEST"));
- if (manifest) {
- mPlugins.AppendElement(manifest);
- ALOG("OMX plugin successfully loaded");
- }
- }
- }
-}
-
-AndroidMediaPluginHost::~AndroidMediaPluginHost() {
- mResourceServer->Stop();
- MOZ_COUNT_DTOR(AndroidMediaPluginHost);
-}
-
-bool AndroidMediaPluginHost::FindDecoder(const nsACString& aMimeType, const char* const** aCodecs)
-{
- const char *chars;
- size_t len = NS_CStringGetData(aMimeType, &chars, nullptr);
- for (size_t n = 0; n < mPlugins.Length(); ++n) {
- Manifest *plugin = mPlugins[n];
- const char* const *codecs;
- if (plugin->CanDecode(chars, len, &codecs)) {
- if (aCodecs)
- *aCodecs = codecs;
- return true;
- }
- }
- return false;
-}
-
-MPAPI::Decoder *AndroidMediaPluginHost::CreateDecoder(MediaResource *aResource, const nsACString& aMimeType)
-{
- NS_ENSURE_TRUE(aResource, nullptr);
-
- nsAutoPtr<Decoder> decoder(new Decoder());
- if (!decoder) {
- return nullptr;
- }
-
- const char *chars;
- size_t len = NS_CStringGetData(aMimeType, &chars, nullptr);
- for (size_t n = 0; n < mPlugins.Length(); ++n) {
- Manifest *plugin = mPlugins[n];
- const char* const *codecs;
- if (!plugin->CanDecode(chars, len, &codecs)) {
- continue;
- }
-
- nsCString url;
- nsresult rv = mResourceServer->AddResource(aResource, url);
- if (NS_FAILED (rv)) continue;
-
- decoder->mResource = strdup(url.get());
- if (plugin->CreateDecoder(&sPluginHost, decoder, chars, len)) {
- return decoder.forget();
- }
- }
-
- return nullptr;
-}
-
-void AndroidMediaPluginHost::DestroyDecoder(Decoder *aDecoder)
-{
- aDecoder->DestroyDecoder(aDecoder);
- char* resource = GetResource(aDecoder);
- if (resource) {
- // resource *shouldn't* be null, but check anyway just in case the plugin
- // decoder does something stupid.
- mResourceServer->RemoveResource(nsCString(resource));
- free(resource);
- }
- delete aDecoder;
-}
-
-AndroidMediaPluginHost *sAndroidMediaPluginHost = nullptr;
-AndroidMediaPluginHost *EnsureAndroidMediaPluginHost()
-{
- MOZ_DIAGNOSTIC_ASSERT(NS_IsMainThread());
- if (!sAndroidMediaPluginHost) {
- sAndroidMediaPluginHost = new AndroidMediaPluginHost();
- }
- return sAndroidMediaPluginHost;
-}
-
-AndroidMediaPluginHost *GetAndroidMediaPluginHost()
-{
- MOZ_ASSERT(sAndroidMediaPluginHost);
- return sAndroidMediaPluginHost;
-}
-
-void AndroidMediaPluginHost::Shutdown()
-{
- delete sAndroidMediaPluginHost;
- sAndroidMediaPluginHost = nullptr;
-}
-
-} // namespace mozilla
diff --git a/dom/media/android/AndroidMediaPluginHost.h b/dom/media/android/AndroidMediaPluginHost.h
deleted file mode 100644
index 854b7f21e..000000000
--- a/dom/media/android/AndroidMediaPluginHost.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-#if !defined(AndroidMediaPluginHost_h_)
-#define AndroidMediaPluginHost_h_
-
-#include "nsTArray.h"
-#include "MediaResource.h"
-#include "MPAPI.h"
-#include "AndroidMediaResourceServer.h"
-
-namespace mozilla {
-
-class AndroidMediaPluginHost {
- RefPtr<AndroidMediaResourceServer> mResourceServer;
- nsTArray<MPAPI::Manifest *> mPlugins;
-
- MPAPI::Manifest *FindPlugin(const nsACString& aMimeType);
-public:
- AndroidMediaPluginHost();
- ~AndroidMediaPluginHost();
-
- static void Shutdown();
-
- bool FindDecoder(const nsACString& aMimeType, const char* const** aCodecs);
- MPAPI::Decoder *CreateDecoder(mozilla::MediaResource *aResource, const nsACString& aMimeType);
- void DestroyDecoder(MPAPI::Decoder *aDecoder);
-};
-
-// Must be called on the main thread. Creates the plugin host if it doesn't
-// already exist.
-AndroidMediaPluginHost *EnsureAndroidMediaPluginHost();
-
-// May be called on any thread after EnsureAndroidMediaPluginHost has been called.
-AndroidMediaPluginHost *GetAndroidMediaPluginHost();
-
-} // namespace mozilla
-
-#endif
diff --git a/dom/media/android/AndroidMediaReader.cpp b/dom/media/android/AndroidMediaReader.cpp
deleted file mode 100644
index 12afacbc9..000000000
--- a/dom/media/android/AndroidMediaReader.cpp
+++ /dev/null
@@ -1,449 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-#include "AndroidMediaReader.h"
-#include "mozilla/TimeStamp.h"
-#include "mozilla/gfx/Point.h"
-#include "MediaResource.h"
-#include "VideoUtils.h"
-#include "AndroidMediaDecoder.h"
-#include "AndroidMediaPluginHost.h"
-#include "MediaDecoderStateMachine.h"
-#include "ImageContainer.h"
-#include "AbstractMediaDecoder.h"
-#include "gfx2DGlue.h"
-#include "VideoFrameContainer.h"
-#include "mozilla/CheckedInt.h"
-
-namespace mozilla {
-
-using namespace mozilla::gfx;
-using namespace mozilla::media;
-
-typedef mozilla::layers::Image Image;
-typedef mozilla::layers::PlanarYCbCrImage PlanarYCbCrImage;
-
-AndroidMediaReader::AndroidMediaReader(AbstractMediaDecoder *aDecoder,
- const nsACString& aContentType) :
- MediaDecoderReader(aDecoder),
- mType(aContentType),
- mPlugin(nullptr),
- mHasAudio(false),
- mHasVideo(false),
- mVideoSeekTimeUs(-1),
- mAudioSeekTimeUs(-1)
-{
-}
-
-nsresult AndroidMediaReader::ReadMetadata(MediaInfo* aInfo,
- MetadataTags** aTags)
-{
- MOZ_ASSERT(OnTaskQueue());
-
- if (!mPlugin) {
- mPlugin = GetAndroidMediaPluginHost()->CreateDecoder(mDecoder->GetResource(), mType);
- if (!mPlugin) {
- return NS_ERROR_FAILURE;
- }
- }
-
- // Set the total duration (the max of the audio and video track).
- int64_t durationUs;
- mPlugin->GetDuration(mPlugin, &durationUs);
- if (durationUs) {
- mInfo.mMetadataDuration.emplace(TimeUnit::FromMicroseconds(durationUs));
- }
-
- if (mPlugin->HasVideo(mPlugin)) {
- int32_t width, height;
- mPlugin->GetVideoParameters(mPlugin, &width, &height);
- nsIntRect pictureRect(0, 0, width, height);
-
- // Validate the container-reported frame and pictureRect sizes. This ensures
- // that our video frame creation code doesn't overflow.
- nsIntSize displaySize(width, height);
- nsIntSize frameSize(width, height);
- if (!IsValidVideoRegion(frameSize, pictureRect, displaySize)) {
- return NS_ERROR_FAILURE;
- }
-
- // Video track's frame sizes will not overflow. Activate the video track.
- mHasVideo = true;
- mInfo.mVideo.mDisplay = displaySize;
- mPicture = pictureRect;
- mInitialFrame = frameSize;
- VideoFrameContainer* container = mDecoder->GetVideoFrameContainer();
- if (container) {
- container->ClearCurrentFrame(IntSize(displaySize.width, displaySize.height));
- }
- }
-
- if (mPlugin->HasAudio(mPlugin)) {
- int32_t numChannels, sampleRate;
- mPlugin->GetAudioParameters(mPlugin, &numChannels, &sampleRate);
- mHasAudio = true;
- mInfo.mAudio.mChannels = numChannels;
- mInfo.mAudio.mRate = sampleRate;
- }
-
- *aInfo = mInfo;
- *aTags = nullptr;
- return NS_OK;
-}
-
-RefPtr<ShutdownPromise>
-AndroidMediaReader::Shutdown()
-{
- ResetDecode();
- if (mPlugin) {
- GetAndroidMediaPluginHost()->DestroyDecoder(mPlugin);
- mPlugin = nullptr;
- }
-
- return MediaDecoderReader::Shutdown();
-}
-
-// Resets all state related to decoding, emptying all buffers etc.
-nsresult AndroidMediaReader::ResetDecode(TrackSet aTracks)
-{
- if (mLastVideoFrame) {
- mLastVideoFrame = nullptr;
- }
- mSeekRequest.DisconnectIfExists();
- mSeekPromise.RejectIfExists(NS_OK, __func__);
- return MediaDecoderReader::ResetDecode(aTracks);
-}
-
-bool AndroidMediaReader::DecodeVideoFrame(bool &aKeyframeSkip,
- int64_t aTimeThreshold)
-{
- // Record number of frames decoded and parsed. Automatically update the
- // stats counters using the AutoNotifyDecoded stack-based class.
- AbstractMediaDecoder::AutoNotifyDecoded a(mDecoder);
-
- // Throw away the currently buffered frame if we are seeking.
- if (mLastVideoFrame && mVideoSeekTimeUs != -1) {
- mLastVideoFrame = nullptr;
- }
-
- ImageBufferCallback bufferCallback(mDecoder->GetImageContainer());
- RefPtr<Image> currentImage;
-
- // Read next frame
- while (true) {
- MPAPI::VideoFrame frame;
- if (!mPlugin->ReadVideo(mPlugin, &frame, mVideoSeekTimeUs, &bufferCallback)) {
- // We reached the end of the video stream. If we have a buffered
- // video frame, push it the video queue using the total duration
- // of the video as the end time.
- if (mLastVideoFrame) {
- int64_t durationUs;
- mPlugin->GetDuration(mPlugin, &durationUs);
- durationUs = std::max<int64_t>(durationUs - mLastVideoFrame->mTime, 0);
- RefPtr<VideoData> data = VideoData::ShallowCopyUpdateDuration(mLastVideoFrame,
- durationUs);
- mVideoQueue.Push(data);
- mLastVideoFrame = nullptr;
- }
- return false;
- }
- mVideoSeekTimeUs = -1;
-
- if (aKeyframeSkip) {
- // Disable keyframe skipping for now as
- // stagefright doesn't seem to be telling us
- // when a frame is a keyframe.
-#if 0
- if (!frame.mKeyFrame) {
- ++a.mStats.mParsedFrames;
- ++a.mStats.mDroppedFrames;
- continue;
- }
-#endif
- aKeyframeSkip = false;
- }
-
- if (frame.mSize == 0)
- return true;
-
- currentImage = bufferCallback.GetImage();
- int64_t pos = mDecoder->GetResource()->Tell();
- IntRect picture = mPicture;
-
- RefPtr<VideoData> v;
- if (currentImage) {
- gfx::IntSize frameSize = currentImage->GetSize();
- if (frameSize.width != mInitialFrame.width ||
- frameSize.height != mInitialFrame.height) {
- // Frame size is different from what the container reports. This is legal,
- // and we will preserve the ratio of the crop rectangle as it
- // was reported relative to the picture size reported by the container.
- picture.x = (mPicture.x * frameSize.width) / mInitialFrame.width;
- picture.y = (mPicture.y * frameSize.height) / mInitialFrame.height;
- picture.width = (frameSize.width * mPicture.width) / mInitialFrame.width;
- picture.height = (frameSize.height * mPicture.height) / mInitialFrame.height;
- }
-
- v = VideoData::CreateFromImage(mInfo.mVideo,
- pos,
- frame.mTimeUs,
- 1, // We don't know the duration yet.
- currentImage,
- frame.mKeyFrame,
- -1,
- picture);
- } else {
- // Assume YUV
- VideoData::YCbCrBuffer b;
- b.mPlanes[0].mData = static_cast<uint8_t *>(frame.Y.mData);
- b.mPlanes[0].mStride = frame.Y.mStride;
- b.mPlanes[0].mHeight = frame.Y.mHeight;
- b.mPlanes[0].mWidth = frame.Y.mWidth;
- b.mPlanes[0].mOffset = frame.Y.mOffset;
- b.mPlanes[0].mSkip = frame.Y.mSkip;
-
- b.mPlanes[1].mData = static_cast<uint8_t *>(frame.Cb.mData);
- b.mPlanes[1].mStride = frame.Cb.mStride;
- b.mPlanes[1].mHeight = frame.Cb.mHeight;
- b.mPlanes[1].mWidth = frame.Cb.mWidth;
- b.mPlanes[1].mOffset = frame.Cb.mOffset;
- b.mPlanes[1].mSkip = frame.Cb.mSkip;
-
- b.mPlanes[2].mData = static_cast<uint8_t *>(frame.Cr.mData);
- b.mPlanes[2].mStride = frame.Cr.mStride;
- b.mPlanes[2].mHeight = frame.Cr.mHeight;
- b.mPlanes[2].mWidth = frame.Cr.mWidth;
- b.mPlanes[2].mOffset = frame.Cr.mOffset;
- b.mPlanes[2].mSkip = frame.Cr.mSkip;
-
- if (frame.Y.mWidth != mInitialFrame.width ||
- frame.Y.mHeight != mInitialFrame.height) {
-
- // Frame size is different from what the container reports. This is legal,
- // and we will preserve the ratio of the crop rectangle as it
- // was reported relative to the picture size reported by the container.
- picture.x = (mPicture.x * frame.Y.mWidth) / mInitialFrame.width;
- picture.y = (mPicture.y * frame.Y.mHeight) / mInitialFrame.height;
- picture.width = (frame.Y.mWidth * mPicture.width) / mInitialFrame.width;
- picture.height = (frame.Y.mHeight * mPicture.height) / mInitialFrame.height;
- }
-
- // This is the approximate byte position in the stream.
- v = VideoData::CreateAndCopyData(mInfo.mVideo,
- mDecoder->GetImageContainer(),
- pos,
- frame.mTimeUs,
- 1, // We don't know the duration yet.
- b,
- frame.mKeyFrame,
- -1,
- picture);
- }
-
- if (!v) {
- return false;
- }
- a.mStats.mParsedFrames++;
- a.mStats.mDecodedFrames++;
- NS_ASSERTION(a.mStats.mDecodedFrames <= a.mStats.mParsedFrames, "Expect to decode fewer frames than parsed in AndroidMedia...");
-
- // Since MPAPI doesn't give us the end time of frames, we keep one frame
- // buffered in AndroidMediaReader and push it into the queue as soon
- // we read the following frame so we can use that frame's start time as
- // the end time of the buffered frame.
- if (!mLastVideoFrame) {
- mLastVideoFrame = v;
- continue;
- }
-
- // Calculate the duration as the timestamp of the current frame minus the
- // timestamp of the previous frame. We can then return the previously
- // decoded frame, and it will have a valid timestamp.
- int64_t duration = v->mTime - mLastVideoFrame->mTime;
- mLastVideoFrame = VideoData::ShallowCopyUpdateDuration(mLastVideoFrame, duration);
-
- // We have the start time of the next frame, so we can push the previous
- // frame into the queue, except if the end time is below the threshold,
- // in which case it wouldn't be displayed anyway.
- if (mLastVideoFrame->GetEndTime() < aTimeThreshold) {
- mLastVideoFrame = nullptr;
- continue;
- }
-
- // Buffer the current frame we just decoded.
- mVideoQueue.Push(mLastVideoFrame);
- mLastVideoFrame = v;
-
- break;
- }
-
- return true;
-}
-
-bool AndroidMediaReader::DecodeAudioData()
-{
- MOZ_ASSERT(OnTaskQueue());
-
- // This is the approximate byte position in the stream.
- int64_t pos = mDecoder->GetResource()->Tell();
-
- // Read next frame
- MPAPI::AudioFrame source;
- if (!mPlugin->ReadAudio(mPlugin, &source, mAudioSeekTimeUs)) {
- return false;
- }
- mAudioSeekTimeUs = -1;
-
- // Ignore empty buffers which stagefright media read will sporadically return
- if (source.mSize == 0)
- return true;
-
- uint32_t frames = source.mSize / (source.mAudioChannels *
- sizeof(AudioDataValue));
-
- typedef AudioCompactor::NativeCopy MPCopy;
- return mAudioCompactor.Push(pos,
- source.mTimeUs,
- source.mAudioSampleRate,
- frames,
- source.mAudioChannels,
- MPCopy(static_cast<uint8_t *>(source.mData),
- source.mSize,
- source.mAudioChannels));
-}
-
-RefPtr<MediaDecoderReader::SeekPromise>
-AndroidMediaReader::Seek(SeekTarget aTarget, int64_t aEndTime)
-{
- MOZ_ASSERT(OnTaskQueue());
-
- RefPtr<SeekPromise> p = mSeekPromise.Ensure(__func__);
- if (mHasAudio && mHasVideo) {
- // The decoder seeks/demuxes audio and video streams separately. So if
- // we seek both audio and video to aTarget, the audio stream can typically
- // seek closer to the seek target, since typically every audio block is
- // a sync point, whereas for video there are only keyframes once every few
- // seconds. So if we have both audio and video, we must seek the video
- // stream to the preceeding keyframe first, get the stream time, and then
- // seek the audio stream to match the video stream's time. Otherwise, the
- // audio and video streams won't be in sync after the seek.
- mVideoSeekTimeUs = aTarget.GetTime().ToMicroseconds();
-
- RefPtr<AndroidMediaReader> self = this;
- mSeekRequest.Begin(DecodeToFirstVideoData()->Then(OwnerThread(), __func__, [self] (MediaData* v) {
- self->mSeekRequest.Complete();
- self->mAudioSeekTimeUs = v->mTime;
- self->mSeekPromise.Resolve(media::TimeUnit::FromMicroseconds(self->mAudioSeekTimeUs), __func__);
- }, [self, aTarget] () {
- self->mSeekRequest.Complete();
- self->mAudioSeekTimeUs = aTarget.GetTime().ToMicroseconds();
- self->mSeekPromise.Resolve(aTarget.GetTime(), __func__);
- }));
- } else {
- mAudioSeekTimeUs = mVideoSeekTimeUs = aTarget.GetTime().ToMicroseconds();
- mSeekPromise.Resolve(aTarget.GetTime(), __func__);
- }
-
- return p;
-}
-
-AndroidMediaReader::ImageBufferCallback::ImageBufferCallback(mozilla::layers::ImageContainer *aImageContainer) :
- mImageContainer(aImageContainer)
-{
-}
-
-void *
-AndroidMediaReader::ImageBufferCallback::operator()(size_t aWidth, size_t aHeight,
- MPAPI::ColorFormat aColorFormat)
-{
- if (!mImageContainer) {
- NS_WARNING("No image container to construct an image");
- return nullptr;
- }
-
- RefPtr<Image> image;
- switch(aColorFormat) {
- case MPAPI::RGB565:
- image = mozilla::layers::CreateSharedRGBImage(mImageContainer,
- nsIntSize(aWidth, aHeight),
- SurfaceFormat::R5G6B5_UINT16);
- if (!image) {
- NS_WARNING("Could not create rgb image");
- return nullptr;
- }
-
- mImage = image;
- return image->GetBuffer();
- case MPAPI::I420:
- return CreateI420Image(aWidth, aHeight);
- default:
- NS_NOTREACHED("Color format not supported");
- return nullptr;
- }
-}
-
-uint8_t *
-AndroidMediaReader::ImageBufferCallback::CreateI420Image(size_t aWidth,
- size_t aHeight)
-{
- RefPtr<PlanarYCbCrImage> yuvImage = mImageContainer->CreatePlanarYCbCrImage();
- mImage = yuvImage;
-
- if (!yuvImage) {
- NS_WARNING("Could not create I420 image");
- return nullptr;
- }
-
- // Use uint32_t throughout to match AllocateAndGetNewBuffer's param
- const auto checkedFrameSize =
- CheckedInt<uint32_t>(aWidth) * aHeight;
-
- // Allocate enough for one full resolution Y plane
- // and two quarter resolution Cb/Cr planes.
- const auto checkedBufferSize =
- checkedFrameSize + checkedFrameSize / 2;
-
- if (!checkedBufferSize.isValid()) { // checks checkedFrameSize too
- NS_WARNING("Could not create I420 image");
- return nullptr;
- }
-
- const auto frameSize = checkedFrameSize.value();
-
- uint8_t *buffer =
- yuvImage->AllocateAndGetNewBuffer(checkedBufferSize.value());
-
- mozilla::layers::PlanarYCbCrData frameDesc;
-
- frameDesc.mYChannel = buffer;
- frameDesc.mCbChannel = buffer + frameSize;
- frameDesc.mCrChannel = frameDesc.mCbChannel + frameSize / 4;
-
- frameDesc.mYSize = IntSize(aWidth, aHeight);
- frameDesc.mCbCrSize = IntSize(aWidth / 2, aHeight / 2);
-
- frameDesc.mYStride = aWidth;
- frameDesc.mCbCrStride = aWidth / 2;
-
- frameDesc.mYSkip = 0;
- frameDesc.mCbSkip = 0;
- frameDesc.mCrSkip = 0;
-
- frameDesc.mPicX = 0;
- frameDesc.mPicY = 0;
- frameDesc.mPicSize = IntSize(aWidth, aHeight);
-
- yuvImage->AdoptData(frameDesc);
-
- return buffer;
-}
-
-already_AddRefed<Image>
-AndroidMediaReader::ImageBufferCallback::GetImage()
-{
- return mImage.forget();
-}
-
-} // namespace mozilla
diff --git a/dom/media/android/AndroidMediaReader.h b/dom/media/android/AndroidMediaReader.h
deleted file mode 100644
index def85a343..000000000
--- a/dom/media/android/AndroidMediaReader.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-#if !defined(AndroidMediaReader_h_)
-#define AndroidMediaReader_h_
-
-#include "mozilla/Attributes.h"
-#include "MediaResource.h"
-#include "MediaDecoderReader.h"
-#include "ImageContainer.h"
-#include "mozilla/layers/SharedRGBImage.h"
-
-#include "MPAPI.h"
-
-class nsACString;
-
-namespace mozilla {
-
-class AbstractMediaDecoder;
-
-namespace layers {
-class ImageContainer;
-}
-
-class AndroidMediaReader : public MediaDecoderReader
-{
- nsCString mType;
- MPAPI::Decoder *mPlugin;
- bool mHasAudio;
- bool mHasVideo;
- nsIntRect mPicture;
- nsIntSize mInitialFrame;
- int64_t mVideoSeekTimeUs;
- int64_t mAudioSeekTimeUs;
- RefPtr<VideoData> mLastVideoFrame;
- MozPromiseHolder<MediaDecoderReader::SeekPromise> mSeekPromise;
- MozPromiseRequestHolder<MediaDecoderReader::MediaDataPromise> mSeekRequest;
-public:
- AndroidMediaReader(AbstractMediaDecoder* aDecoder,
- const nsACString& aContentType);
-
- nsresult ResetDecode(TrackSet aTracks = TrackSet(TrackInfo::kAudioTrack,
- TrackInfo::kVideoTrack)) override;
-
- bool DecodeAudioData() override;
- bool DecodeVideoFrame(bool &aKeyframeSkip, int64_t aTimeThreshold) override;
-
- nsresult ReadMetadata(MediaInfo* aInfo, MetadataTags** aTags) override;
- RefPtr<SeekPromise> Seek(SeekTarget aTarget, int64_t aEndTime) override;
-
- RefPtr<ShutdownPromise> Shutdown() override;
-
- class ImageBufferCallback : public MPAPI::BufferCallback {
- typedef mozilla::layers::Image Image;
-
- public:
- ImageBufferCallback(mozilla::layers::ImageContainer *aImageContainer);
- void *operator()(size_t aWidth, size_t aHeight,
- MPAPI::ColorFormat aColorFormat) override;
- already_AddRefed<Image> GetImage();
-
- private:
- uint8_t *CreateI420Image(size_t aWidth, size_t aHeight);
-
- mozilla::layers::ImageContainer *mImageContainer;
- RefPtr<Image> mImage;
- };
-
-};
-
-} // namespace mozilla
-
-#endif
diff --git a/dom/media/android/AndroidMediaResourceServer.cpp b/dom/media/android/AndroidMediaResourceServer.cpp
deleted file mode 100644
index bd76a8c68..000000000
--- a/dom/media/android/AndroidMediaResourceServer.cpp
+++ /dev/null
@@ -1,503 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-#include "mozilla/Assertions.h"
-#include "mozilla/Base64.h"
-#include "mozilla/IntegerPrintfMacros.h"
-#include "mozilla/UniquePtr.h"
-#include "nsThreadUtils.h"
-#include "nsIServiceManager.h"
-#include "nsISocketTransport.h"
-#include "nsIOutputStream.h"
-#include "nsIInputStream.h"
-#include "nsIRandomGenerator.h"
-#include "nsReadLine.h"
-#include "nsNetCID.h"
-#include "VideoUtils.h"
-#include "MediaResource.h"
-#include "AndroidMediaResourceServer.h"
-
-#if defined(_MSC_VER)
-#define strtoll _strtoi64
-#endif
-
-using namespace mozilla;
-
-/*
- ReadCRLF is a variant of NS_ReadLine from nsReadLine.h that deals
- with the carriage return/line feed requirements of HTTP requests.
-*/
-template<typename CharT, class StreamType, class StringType>
-nsresult
-ReadCRLF (StreamType* aStream, nsLineBuffer<CharT> * aBuffer,
- StringType & aLine, bool *aMore)
-{
- // eollast is true if the last character in the buffer is a '\r',
- // signaling a potential '\r\n' sequence split between reads.
- bool eollast = false;
-
- aLine.Truncate();
-
- while (1) { // will be returning out of this loop on eol or eof
- if (aBuffer->start == aBuffer->end) { // buffer is empty. Read into it.
- uint32_t bytesRead;
- nsresult rv = aStream->Read(aBuffer->buf, kLineBufferSize, &bytesRead);
- if (NS_FAILED(rv) || bytesRead == 0) {
- *aMore = false;
- return rv;
- }
- aBuffer->start = aBuffer->buf;
- aBuffer->end = aBuffer->buf + bytesRead;
- *(aBuffer->end) = '\0';
- }
-
- /*
- * Walk the buffer looking for an end-of-line.
- * There are 4 cases to consider:
- * 1. the CR char is the last char in the buffer
- * 2. the CRLF sequence are the last characters in the buffer
- * 3. the CRLF sequence + one or more chars at the end of the buffer
- * we need at least one char after the first CRLF sequence to
- * set |aMore| correctly.
- * 4. The LF character is the first char in the buffer when eollast is
- * true.
- */
- CharT* current = aBuffer->start;
- if (eollast) { // Case 4
- if (*current == '\n') {
- aBuffer->start = ++current;
- *aMore = true;
- return NS_OK;
- }
- else {
- eollast = false;
- aLine.Append('\r');
- }
- }
- // Cases 2 and 3
- for ( ; current < aBuffer->end-1; ++current) {
- if (*current == '\r' && *(current+1) == '\n') {
- *current++ = '\0';
- *current++ = '\0';
- aLine.Append(aBuffer->start);
- aBuffer->start = current;
- *aMore = true;
- return NS_OK;
- }
- }
- // Case 1
- if (*current == '\r') {
- eollast = true;
- *current++ = '\0';
- }
-
- aLine.Append(aBuffer->start);
- aBuffer->start = aBuffer->end; // mark the buffer empty
- }
-}
-
-// Each client HTTP request results in a thread being spawned to process it.
-// That thread has a single event dispatched to it which handles the HTTP
-// protocol. It parses the headers and forwards data from the MediaResource
-// associated with the URL back to client. When the request is complete it will
-// shutdown the thread.
-class ServeResourceEvent : public Runnable {
-private:
- // Reading from this reads the data sent from the client.
- nsCOMPtr<nsIInputStream> mInput;
-
- // Writing to this sends data to the client.
- nsCOMPtr<nsIOutputStream> mOutput;
-
- // The AndroidMediaResourceServer that owns the MediaResource instances
- // served. This is used to lookup the MediaResource from the URL.
- RefPtr<AndroidMediaResourceServer> mServer;
-
- // Write 'aBufferLength' bytes from 'aBuffer' to 'mOutput'. This
- // method ensures all the data is written by checking the number
- // of bytes returned from the output streams 'Write' method and
- // looping until done.
- nsresult WriteAll(char const* aBuffer, int32_t aBufferLength);
-
-public:
- ServeResourceEvent(nsIInputStream* aInput, nsIOutputStream* aOutput,
- AndroidMediaResourceServer* aServer)
- : mInput(aInput), mOutput(aOutput), mServer(aServer) {}
-
- // This method runs on the thread and exits when it has completed the
- // HTTP request.
- NS_IMETHOD Run();
-
- // Given the first line of an HTTP request, parse the URL requested and
- // return the MediaResource for that URL.
- already_AddRefed<MediaResource> GetMediaResource(nsCString const& aHTTPRequest);
-
- // Gracefully shutdown the thread and cleanup resources
- void Shutdown();
-};
-
-nsresult
-ServeResourceEvent::WriteAll(char const* aBuffer, int32_t aBufferLength)
-{
- while (aBufferLength > 0) {
- uint32_t written = 0;
- nsresult rv = mOutput->Write(aBuffer, aBufferLength, &written);
- if (NS_FAILED (rv)) return rv;
-
- aBufferLength -= written;
- aBuffer += written;
- }
-
- return NS_OK;
-}
-
-already_AddRefed<MediaResource>
-ServeResourceEvent::GetMediaResource(nsCString const& aHTTPRequest)
-{
- // Check that the HTTP method is GET
- const char* HTTP_METHOD = "GET ";
- if (strncmp(aHTTPRequest.get(), HTTP_METHOD, strlen(HTTP_METHOD)) != 0) {
- return nullptr;
- }
-
- const char* url_start = strchr(aHTTPRequest.get(), ' ');
- if (!url_start) {
- return nullptr;
- }
-
- const char* url_end = strrchr(++url_start, ' ');
- if (!url_end) {
- return nullptr;
- }
-
- // The path extracted from the HTTP request is used as a key in hash
- // table. It is not related to retrieving data from the filesystem so
- // we don't need to do any sanity checking on ".." paths and similar
- // exploits.
- nsCString relative(url_start, url_end - url_start);
- RefPtr<MediaResource> resource =
- mServer->GetResource(mServer->GetURLPrefix() + relative);
- return resource.forget();
-}
-
-NS_IMETHODIMP
-ServeResourceEvent::Run() {
- bool more = false; // Are there HTTP headers to read after the first line
- nsCString line; // Contains the current line read from input stream
- nsLineBuffer<char>* buffer = new nsLineBuffer<char>();
- nsresult rv = ReadCRLF(mInput.get(), buffer, line, &more);
- if (NS_FAILED(rv)) { Shutdown(); return rv; }
-
- // First line contains the HTTP GET request. Extract the URL and obtain
- // the MediaResource for it.
- RefPtr<MediaResource> resource = GetMediaResource(line);
- if (!resource) {
- const char* response_404 = "HTTP/1.1 404 Not Found\r\n"
- "Content-Length: 0\r\n\r\n";
- rv = WriteAll(response_404, strlen(response_404));
- Shutdown();
- return rv;
- }
-
- // Offset in bytes to start reading from resource.
- // This is zero by default but can be set to another starting value if
- // this HTTP request includes a byte range request header.
- int64_t start = 0;
-
- // Keep reading lines until we get a zero length line, which is the HTTP
- // protocol's way of signifying the end of headers and start of body, or
- // until we have no more data to read.
- while (more && line.Length() > 0) {
- rv = ReadCRLF(mInput.get(), buffer, line, &more);
- if (NS_FAILED(rv)) { Shutdown(); return rv; }
-
- // Look for a byte range request header. If there is one, set the
- // media resource offset to start from to that requested. Here we
- // only check for the range request format used by Android rather
- // than implementing all possibilities in the HTTP specification.
- // That is, the range request is of the form:
- // Range: bytes=nnnn-
- // Were 'nnnn' is an integer number.
- // The end of the range is not checked, instead we return up to
- // the end of the resource and the client is informed of this via
- // the content-range header.
- NS_NAMED_LITERAL_CSTRING(byteRange, "Range: bytes=");
- const char* s = strstr(line.get(), byteRange.get());
- if (s) {
- start = strtoll(s+byteRange.Length(), nullptr, 10);
-
- // Clamp 'start' to be between 0 and the resource length.
- start = std::max(int64_t(0), std::min(resource->GetLength(), start));
- }
- }
-
- // HTTP response to use if this is a non byte range request
- const char* response_normal = "HTTP/1.1 200 OK\r\n";
-
- // HTTP response to use if this is a byte range request
- const char* response_range = "HTTP/1.1 206 Partial Content\r\n";
-
- // End of HTTP reponse headers is indicated by an empty line.
- const char* response_end = "\r\n";
-
- // If the request was a byte range request, we need to read from the
- // requested offset. If the resource is non-seekable, or the seek
- // fails, then the start offset is set back to zero. This results in all
- // HTTP response data being as if the byte range request was not made.
- if (start > 0 && !resource->IsTransportSeekable()) {
- start = 0;
- }
-
- const char* response_line = start > 0 ?
- response_range :
- response_normal;
- rv = WriteAll(response_line, strlen(response_line));
- if (NS_FAILED(rv)) { Shutdown(); return NS_OK; }
-
- // Buffer used for reading from the input stream and writing to
- // the output stream. The buffer size should be big enough for the
- // HTTP response headers sent below. A static_assert ensures
- // this where the buffer is used.
- const int buffer_size = 32768;
- auto b = MakeUnique<char[]>(buffer_size);
-
- // If we know the length of the resource, send a Content-Length header.
- int64_t contentlength = resource->GetLength() - start;
- if (contentlength > 0) {
- static_assert (buffer_size > 1024,
- "buffer_size must be large enough "
- "to hold response headers");
- snprintf(b.get(), buffer_size, "Content-Length: %" PRId64 "\r\n", contentlength);
- rv = WriteAll(b.get(), strlen(b.get()));
- if (NS_FAILED(rv)) { Shutdown(); return NS_OK; }
- }
-
- // If the request was a byte range request, respond with a Content-Range
- // header which details the extent of the data returned.
- if (start > 0) {
- static_assert (buffer_size > 1024,
- "buffer_size must be large enough "
- "to hold response headers");
- snprintf(b.get(), buffer_size, "Content-Range: "
- "bytes %" PRId64 "-%" PRId64 "/%" PRId64 "\r\n",
- start, resource->GetLength() - 1, resource->GetLength());
- rv = WriteAll(b.get(), strlen(b.get()));
- if (NS_FAILED(rv)) { Shutdown(); return NS_OK; }
- }
-
- rv = WriteAll(response_end, strlen(response_end));
- if (NS_FAILED(rv)) { Shutdown(); return NS_OK; }
-
- rv = mOutput->Flush();
- if (NS_FAILED(rv)) { Shutdown(); return NS_OK; }
-
- // Read data from media resource
- uint32_t bytesRead = 0; // Number of bytes read/written to streams
- rv = resource->ReadAt(start, b.get(), buffer_size, &bytesRead);
- while (NS_SUCCEEDED(rv) && bytesRead != 0) {
- // Keep track of what we think the starting position for the next read
- // is. This is used in subsequent ReadAt calls to ensure we are reading
- // from the correct offset in the case where another thread is reading
- // from th same MediaResource.
- start += bytesRead;
-
- // Write data obtained from media resource to output stream
- rv = WriteAll(b.get(), bytesRead);
- if (NS_FAILED (rv)) break;
-
- rv = resource->ReadAt(start, b.get(), 32768, &bytesRead);
- }
-
- Shutdown();
- return NS_OK;
-}
-
-void
-ServeResourceEvent::Shutdown()
-{
- // Cleanup resources and exit.
- mInput->Close();
- mOutput->Close();
-
- // To shutdown the current thread we need to first exit this event.
- // The Shutdown event below is posted to the main thread to do this.
- nsCOMPtr<nsIRunnable> event = new ShutdownThreadEvent(NS_GetCurrentThread());
- NS_DispatchToMainThread(event);
-}
-
-/*
- This is the listener attached to the server socket. When an HTTP
- request is made by the client the OnSocketAccepted method is
- called. This method will spawn a thread to process the request.
- The thread receives a single event which does the parsing of
- the HTTP request and forwarding the data from the MediaResource
- to the output stream of the request.
-
- The MediaResource used for providing the request data is obtained
- from the AndroidMediaResourceServer that created this listener, using the
- URL the client requested.
-*/
-class ResourceSocketListener : public nsIServerSocketListener
-{
-public:
- // The AndroidMediaResourceServer used to look up the MediaResource
- // on requests.
- RefPtr<AndroidMediaResourceServer> mServer;
-
- NS_DECL_THREADSAFE_ISUPPORTS
- NS_DECL_NSISERVERSOCKETLISTENER
-
- ResourceSocketListener(AndroidMediaResourceServer* aServer) :
- mServer(aServer)
- {
- }
-
-private:
- virtual ~ResourceSocketListener() { }
-};
-
-NS_IMPL_ISUPPORTS(ResourceSocketListener, nsIServerSocketListener)
-
-NS_IMETHODIMP
-ResourceSocketListener::OnSocketAccepted(nsIServerSocket* aServ,
- nsISocketTransport* aTrans)
-{
- nsCOMPtr<nsIInputStream> input;
- nsCOMPtr<nsIOutputStream> output;
- nsresult rv;
-
- rv = aTrans->OpenInputStream(nsITransport::OPEN_BLOCKING, 0, 0, getter_AddRefs(input));
- if (NS_FAILED(rv)) return rv;
-
- rv = aTrans->OpenOutputStream(nsITransport::OPEN_BLOCKING, 0, 0, getter_AddRefs(output));
- if (NS_FAILED(rv)) return rv;
-
- nsCOMPtr<nsIThread> thread;
- rv = NS_NewThread(getter_AddRefs(thread));
- if (NS_FAILED(rv)) return rv;
-
- nsCOMPtr<nsIRunnable> event = new ServeResourceEvent(input.get(), output.get(), mServer);
- return thread->Dispatch(event, NS_DISPATCH_NORMAL);
-}
-
-NS_IMETHODIMP
-ResourceSocketListener::OnStopListening(nsIServerSocket* aServ, nsresult aStatus)
-{
- return NS_OK;
-}
-
-AndroidMediaResourceServer::AndroidMediaResourceServer() :
- mMutex("AndroidMediaResourceServer")
-{
-}
-
-NS_IMETHODIMP
-AndroidMediaResourceServer::Run()
-{
- MOZ_DIAGNOSTIC_ASSERT(NS_IsMainThread());
- MutexAutoLock lock(mMutex);
-
- nsresult rv;
- mSocket = do_CreateInstance(NS_SERVERSOCKET_CONTRACTID, &rv);
- if (NS_FAILED(rv)) return rv;
-
- rv = mSocket->InitSpecialConnection(-1,
- nsIServerSocket::LoopbackOnly
- | nsIServerSocket::KeepWhenOffline,
- -1);
- if (NS_FAILED(rv)) return rv;
-
- rv = mSocket->AsyncListen(new ResourceSocketListener(this));
- if (NS_FAILED(rv)) return rv;
-
- return NS_OK;
-}
-
-/* static */
-already_AddRefed<AndroidMediaResourceServer>
-AndroidMediaResourceServer::Start()
-{
- MOZ_ASSERT(NS_IsMainThread());
- RefPtr<AndroidMediaResourceServer> server = new AndroidMediaResourceServer();
- server->Run();
- return server.forget();
-}
-
-void
-AndroidMediaResourceServer::Stop()
-{
- MutexAutoLock lock(mMutex);
- mSocket->Close();
- mSocket = nullptr;
-}
-
-nsresult
-AndroidMediaResourceServer::AppendRandomPath(nsCString& aUrl)
-{
- // Use a cryptographic quality PRNG to generate raw random bytes
- // and convert that to a base64 string for use as an URL path. This
- // is based on code from nsExternalAppHandler::SetUpTempFile.
- nsresult rv;
- nsAutoCString salt;
- rv = GenerateRandomPathName(salt, 16);
- if (NS_FAILED(rv)) return rv;
- aUrl += "/";
- aUrl += salt;
- return NS_OK;
-}
-
-nsresult
-AndroidMediaResourceServer::AddResource(mozilla::MediaResource* aResource, nsCString& aUrl)
-{
- nsCString url = GetURLPrefix();
- nsresult rv = AppendRandomPath(url);
- if (NS_FAILED (rv)) return rv;
-
- {
- MutexAutoLock lock(mMutex);
-
- // Adding a resource URL that already exists is considered an error.
- if (mResources.find(url) != mResources.end()) return NS_ERROR_FAILURE;
- mResources[url] = aResource;
- }
-
- aUrl = url;
-
- return NS_OK;
-}
-
-void
-AndroidMediaResourceServer::RemoveResource(nsCString const& aUrl)
-{
- MutexAutoLock lock(mMutex);
- mResources.erase(aUrl);
-}
-
-nsCString
-AndroidMediaResourceServer::GetURLPrefix()
-{
- MutexAutoLock lock(mMutex);
-
- int32_t port = 0;
- nsresult rv = mSocket->GetPort(&port);
- if (NS_FAILED (rv) || port < 0) {
- return nsCString("");
- }
-
- char buffer[256];
- snprintf(buffer, sizeof(buffer), "http://127.0.0.1:%d", port >= 0 ? port : 0);
- return nsCString(buffer);
-}
-
-already_AddRefed<MediaResource>
-AndroidMediaResourceServer::GetResource(nsCString const& aUrl)
-{
- MutexAutoLock lock(mMutex);
- ResourceMap::const_iterator it = mResources.find(aUrl);
- if (it == mResources.end()) return nullptr;
-
- RefPtr<MediaResource> resource = it->second;
- return resource.forget();
-}
diff --git a/dom/media/android/AndroidMediaResourceServer.h b/dom/media/android/AndroidMediaResourceServer.h
deleted file mode 100644
index 68200f9c0..000000000
--- a/dom/media/android/AndroidMediaResourceServer.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-#if !defined(AndroidMediaResourceServer_h_)
-#define AndroidMediaResourceServer_h_
-
-#include <map>
-#include "nsIServerSocket.h"
-#include "MediaResource.h"
-
-namespace mozilla {
-
-class MediaResource;
-
-/*
- AndroidMediaResourceServer instantiates a socket server that understands
- HTTP requests for MediaResource instances. The server runs on an
- automatically selected port and MediaResource instances are registered.
- The registration returns a string URL than can be used to fetch the
- resource. That URL contains a randomly generated path to make it
- difficult for other local applications on the device to guess it.
-
- The HTTP protocol is limited in that it supports only what the
- Android DataSource implementation uses to fetch media. It
- understands HTTP GET and byte range requests.
-
- The intent of this class is to be used in Media backends that
- have a system component that does its own network requests. These
- requests are made against this server which then uses standard
- Gecko network requests and media cache usage.
-
- The AndroidMediaResourceServer can be instantiated on any thread and
- its methods are threadsafe - they can be called on any thread.
- The server socket itself is always run on the main thread and
- this is done by the Start() static method by synchronously
- dispatching to the main thread.
-*/
-class AndroidMediaResourceServer : public Runnable
-{
-private:
- // Mutex protecting private members of AndroidMediaResourceServer.
- // All member variables below this point in the class definition
- // must acquire the mutex before access.
- mozilla::Mutex mMutex;
-
- // Server socket used to listen for incoming connections
- nsCOMPtr<nsIServerSocket> mSocket;
-
- // Mapping between MediaResource URL's to the MediaResource
- // object served at that URL.
- typedef std::map<nsCString,
- RefPtr<mozilla::MediaResource> > ResourceMap;
- ResourceMap mResources;
-
- // Create a AndroidMediaResourceServer that will listen on an automatically
- // selected port when started. This is private as it should only be
- // called internally from the public 'Start' method.
- AndroidMediaResourceServer();
- NS_IMETHOD Run();
-
- // Append a random URL path to a string. This is used for creating a
- // unique URl for a resource which helps prevent malicious software
- // running on the same machine as the server from guessing the URL
- // and accessing video data.
- nsresult AppendRandomPath(nsCString& aURL);
-
-public:
- // Create a AndroidMediaResourceServer and start it listening. This call will
- // perform a synchronous request on the main thread.
- static already_AddRefed<AndroidMediaResourceServer> Start();
-
- // Stops the server from listening and accepting further connections.
- void Stop();
-
- // Add a MediaResource to be served by this server. Stores the
- // absolute URL that can be used to access the resource in 'aUrl'.
- nsresult AddResource(mozilla::MediaResource* aResource, nsCString& aUrl);
-
- // Remove a MediaResource so it is no longer served by this server.
- // The URL provided must match exactly that provided by a previous
- // call to "AddResource".
- void RemoveResource(nsCString const& aUrl);
-
- // Returns the prefix for HTTP requests to the server. This plus
- // the result of AddResource results in an Absolute URL.
- nsCString GetURLPrefix();
-
- // Returns the resource asociated with a given URL
- already_AddRefed<mozilla::MediaResource> GetResource(nsCString const& aUrl);
-};
-
-} // namespace mozilla
-
-#endif
diff --git a/dom/media/android/MPAPI.h b/dom/media/android/MPAPI.h
deleted file mode 100644
index 9b289ca09..000000000
--- a/dom/media/android/MPAPI.h
+++ /dev/null
@@ -1,165 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-#if !defined(MPAPI_h_)
-#define MPAPI_h_
-
-#include <stdint.h>
-
-namespace MPAPI {
-
-enum ColorFormat {
- I420,
- RGB565
-};
-
-/*
- * A callback for the plugin to use to request a buffer owned by gecko. This can
- * save us a copy or two down the line.
- */
-class BufferCallback {
-public:
- virtual void *operator()(size_t aWidth, size_t aHeight,
- ColorFormat aColorFormat) = 0;
-};
-
-struct VideoPlane {
- VideoPlane() :
- mData(0),
- mStride(0),
- mWidth(0),
- mHeight(0),
- mOffset(0),
- mSkip(0)
- {}
-
- void *mData;
- int32_t mStride;
- int32_t mWidth;
- int32_t mHeight;
- int32_t mOffset;
- int32_t mSkip;
-};
-
-struct VideoFrame {
- int64_t mTimeUs;
- bool mKeyFrame;
- void *mData;
- size_t mSize;
- int32_t mStride;
- int32_t mSliceHeight;
- int32_t mRotation;
- VideoPlane Y;
- VideoPlane Cb;
- VideoPlane Cr;
-
- VideoFrame() :
- mTimeUs(0),
- mKeyFrame(false),
- mData(0),
- mSize(0),
- mStride(0),
- mSliceHeight(0),
- mRotation(0)
- {}
-
- void Set(int64_t aTimeUs, bool aKeyFrame,
- void *aData, size_t aSize, int32_t aStride, int32_t aSliceHeight, int32_t aRotation,
- void *aYData, int32_t aYStride, int32_t aYWidth, int32_t aYHeight, int32_t aYOffset, int32_t aYSkip,
- void *aCbData, int32_t aCbStride, int32_t aCbWidth, int32_t aCbHeight, int32_t aCbOffset, int32_t aCbSkip,
- void *aCrData, int32_t aCrStride, int32_t aCrWidth, int32_t aCrHeight, int32_t aCrOffset, int32_t aCrSkip)
- {
- mTimeUs = aTimeUs;
- mKeyFrame = aKeyFrame;
- mData = aData;
- mSize = aSize;
- mStride = aStride;
- mSliceHeight = aSliceHeight;
- mRotation = aRotation;
- Y.mData = aYData;
- Y.mStride = aYStride;
- Y.mWidth = aYWidth;
- Y.mHeight = aYHeight;
- Y.mOffset = aYOffset;
- Y.mSkip = aYSkip;
- Cb.mData = aCbData;
- Cb.mStride = aCbStride;
- Cb.mWidth = aCbWidth;
- Cb.mHeight = aCbHeight;
- Cb.mOffset = aCbOffset;
- Cb.mSkip = aCbSkip;
- Cr.mData = aCrData;
- Cr.mStride = aCrStride;
- Cr.mWidth = aCrWidth;
- Cr.mHeight = aCrHeight;
- Cr.mOffset = aCrOffset;
- Cr.mSkip = aCrSkip;
- }
-};
-
-struct AudioFrame {
- int64_t mTimeUs;
- void *mData; // 16PCM interleaved
- size_t mSize; // Size of mData in bytes
- int32_t mAudioChannels;
- int32_t mAudioSampleRate;
-
- AudioFrame() :
- mTimeUs(0),
- mData(0),
- mSize(0),
- mAudioChannels(0),
- mAudioSampleRate(0)
- {
- }
-
- void Set(int64_t aTimeUs,
- void *aData, size_t aSize,
- int32_t aAudioChannels, int32_t aAudioSampleRate)
- {
- mTimeUs = aTimeUs;
- mData = aData;
- mSize = aSize;
- mAudioChannels = aAudioChannels;
- mAudioSampleRate = aAudioSampleRate;
- }
-};
-
-struct Decoder;
-
-struct PluginHost {
- bool (*Read)(Decoder *aDecoder, char *aBuffer, int64_t aOffset, uint32_t aCount, uint32_t* aBytes);
- uint64_t (*GetLength)(Decoder *aDecoder);
- void (*SetMetaDataReadMode)(Decoder *aDecoder);
- void (*SetPlaybackReadMode)(Decoder *aDecoder);
- bool (*GetIntPref)(const char *aPref, int32_t *aResult);
- bool (*GetSystemInfoString)(const char *aKey, char *aResult, size_t aResultLen);
-};
-
-struct Decoder {
- void *mResource;
- void *mPrivate;
-
- Decoder();
-
- void (*GetDuration)(Decoder *aDecoder, int64_t *durationUs);
- void (*GetVideoParameters)(Decoder *aDecoder, int32_t *aWidth, int32_t *aHeight);
- void (*GetAudioParameters)(Decoder *aDecoder, int32_t *aNumChannels, int32_t *aSampleRate);
- bool (*HasVideo)(Decoder *aDecoder);
- bool (*HasAudio)(Decoder *aDecoder);
- bool (*ReadVideo)(Decoder *aDecoder, VideoFrame *aFrame, int64_t aSeekTimeUs, BufferCallback *aBufferCallback);
- bool (*ReadAudio)(Decoder *aDecoder, AudioFrame *aFrame, int64_t aSeekTimeUs);
- void (*DestroyDecoder)(Decoder *);
-};
-
-struct Manifest {
- bool (*CanDecode)(const char *aMimeChars, size_t aMimeLen, const char* const**aCodecs);
- bool (*CreateDecoder)(PluginHost *aPluginHost, Decoder *aDecoder,
- const char *aMimeChars, size_t aMimeLen);
-};
-
-}
-
-#endif
diff --git a/dom/media/android/moz.build b/dom/media/android/moz.build
deleted file mode 100644
index 3ad43cd50..000000000
--- a/dom/media/android/moz.build
+++ /dev/null
@@ -1,27 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-EXPORTS += [
- 'AndroidMediaDecoder.h',
- 'AndroidMediaPluginHost.h',
- 'AndroidMediaReader.h',
- 'AndroidMediaResourceServer.h',
- 'MPAPI.h',
-]
-
-UNIFIED_SOURCES += [
- 'AndroidMediaDecoder.cpp',
- 'AndroidMediaPluginHost.cpp',
- 'AndroidMediaReader.cpp',
- 'AndroidMediaResourceServer.cpp',
-]
-
-LOCAL_INCLUDES += [
- '/dom/base',
- '/dom/html',
-]
-
-FINAL_LIBRARY = 'xul'
diff --git a/dom/media/directshow/AudioSinkFilter.cpp b/dom/media/directshow/AudioSinkFilter.cpp
deleted file mode 100644
index 9f23c0e00..000000000
--- a/dom/media/directshow/AudioSinkFilter.cpp
+++ /dev/null
@@ -1,285 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "SampleSink.h"
-#include "AudioSinkFilter.h"
-#include "AudioSinkInputPin.h"
-#include "VideoUtils.h"
-#include "mozilla/Logging.h"
-
-
-#include <initguid.h>
-#include <wmsdkidl.h>
-
-#define DELETE_RESET(p) { delete (p) ; (p) = nullptr ;}
-
-DEFINE_GUID(CLSID_MozAudioSinkFilter, 0x1872d8c8, 0xea8d, 0x4c34, 0xae, 0x96, 0x69, 0xde,
- 0xf1, 0x33, 0x7b, 0x33);
-
-using namespace mozilla::media;
-
-namespace mozilla {
-
-static LazyLogModule gDirectShowLog("DirectShowDecoder");
-#define LOG(...) MOZ_LOG(gDirectShowLog, mozilla::LogLevel::Debug, (__VA_ARGS__))
-
-AudioSinkFilter::AudioSinkFilter(const wchar_t* aObjectName, HRESULT* aOutResult)
- : BaseFilter(aObjectName, CLSID_MozAudioSinkFilter),
- mFilterCritSec("AudioSinkFilter::mFilterCritSec")
-{
- (*aOutResult) = S_OK;
- mInputPin = new AudioSinkInputPin(L"AudioSinkInputPin",
- this,
- &mFilterCritSec,
- aOutResult);
-}
-
-AudioSinkFilter::~AudioSinkFilter()
-{
-}
-
-int
-AudioSinkFilter::GetPinCount()
-{
- return 1;
-}
-
-BasePin*
-AudioSinkFilter::GetPin(int aIndex)
-{
- CriticalSectionAutoEnter lockFilter(mFilterCritSec);
- return (aIndex == 0) ? static_cast<BasePin*>(mInputPin) : nullptr;
-}
-
-HRESULT
-AudioSinkFilter::Pause()
-{
- CriticalSectionAutoEnter lockFilter(mFilterCritSec);
- if (mState == State_Stopped) {
- // Change the state, THEN activate the input pin.
- mState = State_Paused;
- if (mInputPin && mInputPin->IsConnected()) {
- mInputPin->Active();
- }
- } else if (mState == State_Running) {
- mState = State_Paused;
- }
- return S_OK;
-}
-
-HRESULT
-AudioSinkFilter::Stop()
-{
- CriticalSectionAutoEnter lockFilter(mFilterCritSec);
- mState = State_Stopped;
- if (mInputPin) {
- mInputPin->Inactive();
- }
-
- GetSampleSink()->Flush();
-
- return S_OK;
-}
-
-HRESULT
-AudioSinkFilter::Run(REFERENCE_TIME tStart)
-{
- LOG("AudioSinkFilter::Run(%lld) [%4.2lf]",
- RefTimeToUsecs(tStart),
- double(RefTimeToUsecs(tStart)) / USECS_PER_S);
- return media::BaseFilter::Run(tStart);
-}
-
-HRESULT
-AudioSinkFilter::GetClassID( OUT CLSID * pCLSID )
-{
- (* pCLSID) = CLSID_MozAudioSinkFilter;
- return S_OK;
-}
-
-HRESULT
-AudioSinkFilter::QueryInterface(REFIID aIId, void **aInterface)
-{
- if (aIId == IID_IMediaSeeking) {
- *aInterface = static_cast<IMediaSeeking*>(this);
- AddRef();
- return S_OK;
- }
- return mozilla::media::BaseFilter::QueryInterface(aIId, aInterface);
-}
-
-ULONG
-AudioSinkFilter::AddRef()
-{
- return ::InterlockedIncrement(&mRefCnt);
-}
-
-ULONG
-AudioSinkFilter::Release()
-{
- unsigned long newRefCnt = ::InterlockedDecrement(&mRefCnt);
- if (!newRefCnt) {
- delete this;
- }
- return newRefCnt;
-}
-
-SampleSink*
-AudioSinkFilter::GetSampleSink()
-{
- return mInputPin->GetSampleSink();
-}
-
-
-// IMediaSeeking implementation.
-//
-// Calls to IMediaSeeking are forwarded to the output pin that the
-// AudioSinkInputPin is connected to, i.e. upstream towards the parser and
-// source filters, which actually implement seeking.
-#define ENSURE_CONNECTED_PIN_SEEKING \
- if (!mInputPin) { \
- return E_NOTIMPL; \
- } \
- RefPtr<IMediaSeeking> pinSeeking = mInputPin->GetConnectedPinSeeking(); \
- if (!pinSeeking) { \
- return E_NOTIMPL; \
- }
-
-HRESULT
-AudioSinkFilter::GetCapabilities(DWORD* aCapabilities)
-{
- ENSURE_CONNECTED_PIN_SEEKING
- return pinSeeking->GetCapabilities(aCapabilities);
-}
-
-HRESULT
-AudioSinkFilter::CheckCapabilities(DWORD* aCapabilities)
-{
- ENSURE_CONNECTED_PIN_SEEKING
- return pinSeeking->CheckCapabilities(aCapabilities);
-}
-
-HRESULT
-AudioSinkFilter::IsFormatSupported(const GUID* aFormat)
-{
- ENSURE_CONNECTED_PIN_SEEKING
- return pinSeeking->IsFormatSupported(aFormat);
-}
-
-HRESULT
-AudioSinkFilter::QueryPreferredFormat(GUID* aFormat)
-{
- ENSURE_CONNECTED_PIN_SEEKING
- return pinSeeking->QueryPreferredFormat(aFormat);
-}
-
-HRESULT
-AudioSinkFilter::GetTimeFormat(GUID* aFormat)
-{
- ENSURE_CONNECTED_PIN_SEEKING
- return pinSeeking->GetTimeFormat(aFormat);
-}
-
-HRESULT
-AudioSinkFilter::IsUsingTimeFormat(const GUID* aFormat)
-{
- ENSURE_CONNECTED_PIN_SEEKING
- return pinSeeking->IsUsingTimeFormat(aFormat);
-}
-
-HRESULT
-AudioSinkFilter::SetTimeFormat(const GUID* aFormat)
-{
- ENSURE_CONNECTED_PIN_SEEKING
- return pinSeeking->SetTimeFormat(aFormat);
-}
-
-HRESULT
-AudioSinkFilter::GetDuration(LONGLONG* aDuration)
-{
- ENSURE_CONNECTED_PIN_SEEKING
- return pinSeeking->GetDuration(aDuration);
-}
-
-HRESULT
-AudioSinkFilter::GetStopPosition(LONGLONG* aStop)
-{
- ENSURE_CONNECTED_PIN_SEEKING
- return pinSeeking->GetStopPosition(aStop);
-}
-
-HRESULT
-AudioSinkFilter::GetCurrentPosition(LONGLONG* aCurrent)
-{
- ENSURE_CONNECTED_PIN_SEEKING
- return pinSeeking->GetCurrentPosition(aCurrent);
-}
-
-HRESULT
-AudioSinkFilter::ConvertTimeFormat(LONGLONG* aTarget,
- const GUID* aTargetFormat,
- LONGLONG aSource,
- const GUID* aSourceFormat)
-{
- ENSURE_CONNECTED_PIN_SEEKING
- return pinSeeking->ConvertTimeFormat(aTarget,
- aTargetFormat,
- aSource,
- aSourceFormat);
-}
-
-HRESULT
-AudioSinkFilter::SetPositions(LONGLONG* aCurrent,
- DWORD aCurrentFlags,
- LONGLONG* aStop,
- DWORD aStopFlags)
-{
- ENSURE_CONNECTED_PIN_SEEKING
- return pinSeeking->SetPositions(aCurrent,
- aCurrentFlags,
- aStop,
- aStopFlags);
-}
-
-HRESULT
-AudioSinkFilter::GetPositions(LONGLONG* aCurrent,
- LONGLONG* aStop)
-{
- ENSURE_CONNECTED_PIN_SEEKING
- return pinSeeking->GetPositions(aCurrent, aStop);
-}
-
-HRESULT
-AudioSinkFilter::GetAvailable(LONGLONG* aEarliest,
- LONGLONG* aLatest)
-{
- ENSURE_CONNECTED_PIN_SEEKING
- return pinSeeking->GetAvailable(aEarliest, aLatest);
-}
-
-HRESULT
-AudioSinkFilter::SetRate(double aRate)
-{
- ENSURE_CONNECTED_PIN_SEEKING
- return pinSeeking->SetRate(aRate);
-}
-
-HRESULT
-AudioSinkFilter::GetRate(double* aRate)
-{
- ENSURE_CONNECTED_PIN_SEEKING
- return pinSeeking->GetRate(aRate);
-}
-
-HRESULT
-AudioSinkFilter::GetPreroll(LONGLONG* aPreroll)
-{
- ENSURE_CONNECTED_PIN_SEEKING
- return pinSeeking->GetPreroll(aPreroll);
-}
-
-} // namespace mozilla
-
diff --git a/dom/media/directshow/AudioSinkFilter.h b/dom/media/directshow/AudioSinkFilter.h
deleted file mode 100644
index 85abdfccf..000000000
--- a/dom/media/directshow/AudioSinkFilter.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#if !defined(AudioSinkFilter_h_)
-#define AudioSinkFilter_h_
-
-#include "BaseFilter.h"
-#include "DirectShowUtils.h"
-#include "nsAutoPtr.h"
-#include "mozilla/RefPtr.h"
-
-namespace mozilla {
-
-class AudioSinkInputPin;
-class SampleSink;
-
-// Filter that acts as the end of the graph. Audio samples input into
-// this filter block the calling thread, and the calling thread is
-// unblocked when the decode thread extracts the sample. The samples
-// input into this filter are stored in the SampleSink, where the blocking
-// is implemented. The input pin owns the SampleSink.
-class AudioSinkFilter: public mozilla::media::BaseFilter,
- public IMediaSeeking
-{
-
-public:
- AudioSinkFilter(const wchar_t* aObjectName, HRESULT* aOutResult);
- virtual ~AudioSinkFilter();
-
- // Gets the input pin's sample sink.
- SampleSink* GetSampleSink();
-
- // IUnknown implementation.
- STDMETHODIMP QueryInterface(REFIID aIId, void **aInterface);
- STDMETHODIMP_(ULONG) AddRef();
- STDMETHODIMP_(ULONG) Release();
-
- // --------------------------------------------------------------------
- // CBaseFilter methods
- int GetPinCount ();
- mozilla::media::BasePin* GetPin ( IN int Index);
- STDMETHODIMP Pause ();
- STDMETHODIMP Stop ();
- STDMETHODIMP GetClassID ( OUT CLSID * pCLSID);
- STDMETHODIMP Run(REFERENCE_TIME tStart);
- // IMediaSeeking Methods...
-
- // We defer to SourceFilter, but we must expose the interface on
- // the output pins. Seeking commands come upstream from the renderers,
- // but they must be actioned at the source filters.
- STDMETHODIMP GetCapabilities(DWORD* aCapabilities);
- STDMETHODIMP CheckCapabilities(DWORD* aCapabilities);
- STDMETHODIMP IsFormatSupported(const GUID* aFormat);
- STDMETHODIMP QueryPreferredFormat(GUID* aFormat);
- STDMETHODIMP GetTimeFormat(GUID* aFormat);
- STDMETHODIMP IsUsingTimeFormat(const GUID* aFormat);
- STDMETHODIMP SetTimeFormat(const GUID* aFormat);
- STDMETHODIMP GetDuration(LONGLONG* pDuration);
- STDMETHODIMP GetStopPosition(LONGLONG* pStop);
- STDMETHODIMP GetCurrentPosition(LONGLONG* aCurrent);
- STDMETHODIMP ConvertTimeFormat(LONGLONG* aTarget,
- const GUID* aTargetFormat,
- LONGLONG aSource,
- const GUID* aSourceFormat);
- STDMETHODIMP SetPositions(LONGLONG* aCurrent,
- DWORD aCurrentFlags,
- LONGLONG* aStop,
- DWORD aStopFlags);
- STDMETHODIMP GetPositions(LONGLONG* aCurrent,
- LONGLONG* aStop);
- STDMETHODIMP GetAvailable(LONGLONG* aEarliest,
- LONGLONG* aLatest);
- STDMETHODIMP SetRate(double aRate);
- STDMETHODIMP GetRate(double* aRate);
- STDMETHODIMP GetPreroll(LONGLONG* aPreroll);
-
- // --------------------------------------------------------------------
- // class factory calls this
- static IUnknown * CreateInstance (IN LPUNKNOWN punk, OUT HRESULT * phr);
-
-private:
- CriticalSection mFilterCritSec;
-
- // Note: The input pin defers its refcounting to the sink filter, so when
- // the input pin is addrefed, what actually happens is the sink filter is
- // addrefed.
- nsAutoPtr<AudioSinkInputPin> mInputPin;
-};
-
-} // namespace mozilla
-
-#endif // AudioSinkFilter_h_
diff --git a/dom/media/directshow/AudioSinkInputPin.cpp b/dom/media/directshow/AudioSinkInputPin.cpp
deleted file mode 100644
index 85a6e3da3..000000000
--- a/dom/media/directshow/AudioSinkInputPin.cpp
+++ /dev/null
@@ -1,195 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "AudioSinkInputPin.h"
-#include "AudioSinkFilter.h"
-#include "SampleSink.h"
-#include "mozilla/Logging.h"
-
-#include <wmsdkidl.h>
-
-using namespace mozilla::media;
-
-namespace mozilla {
-
-static LazyLogModule gDirectShowLog("DirectShowDecoder");
-#define LOG(...) MOZ_LOG(gDirectShowLog, mozilla::LogLevel::Debug, (__VA_ARGS__))
-
-AudioSinkInputPin::AudioSinkInputPin(wchar_t* aObjectName,
- AudioSinkFilter* aFilter,
- mozilla::CriticalSection* aLock,
- HRESULT* aOutResult)
- : BaseInputPin(aObjectName, aFilter, aLock, aOutResult, aObjectName),
- mSegmentStartTime(0)
-{
- MOZ_COUNT_CTOR(AudioSinkInputPin);
- mSampleSink = new SampleSink();
-}
-
-AudioSinkInputPin::~AudioSinkInputPin()
-{
- MOZ_COUNT_DTOR(AudioSinkInputPin);
-}
-
-HRESULT
-AudioSinkInputPin::GetMediaType(int aPosition, MediaType* aOutMediaType)
-{
- NS_ENSURE_TRUE(aPosition >= 0, E_INVALIDARG);
- NS_ENSURE_TRUE(aOutMediaType, E_POINTER);
-
- if (aPosition > 0) {
- return S_FALSE;
- }
-
- // Note: We set output as PCM, as IEEE_FLOAT only works when using the
- // MP3 decoder as an MFT, and we can't do that while using DirectShow.
- aOutMediaType->SetType(&MEDIATYPE_Audio);
- aOutMediaType->SetSubtype(&MEDIASUBTYPE_PCM);
- aOutMediaType->SetType(&FORMAT_WaveFormatEx);
- aOutMediaType->SetTemporalCompression(FALSE);
-
- return S_OK;
-}
-
-HRESULT
-AudioSinkInputPin::CheckMediaType(const MediaType* aMediaType)
-{
- if (!aMediaType) {
- return E_INVALIDARG;
- }
-
- GUID majorType = *aMediaType->Type();
- if (majorType != MEDIATYPE_Audio && majorType != WMMEDIATYPE_Audio) {
- return E_INVALIDARG;
- }
-
- if (*aMediaType->Subtype() != MEDIASUBTYPE_PCM) {
- return E_INVALIDARG;
- }
-
- if (*aMediaType->FormatType() != FORMAT_WaveFormatEx) {
- return E_INVALIDARG;
- }
-
- // We accept the media type, stash its layout format!
- WAVEFORMATEX* wfx = (WAVEFORMATEX*)(aMediaType->pbFormat);
- GetSampleSink()->SetAudioFormat(wfx);
-
- return S_OK;
-}
-
-AudioSinkFilter*
-AudioSinkInputPin::GetAudioSinkFilter()
-{
- return reinterpret_cast<AudioSinkFilter*>(mFilter);
-}
-
-SampleSink*
-AudioSinkInputPin::GetSampleSink()
-{
- return mSampleSink;
-}
-
-HRESULT
-AudioSinkInputPin::SetAbsoluteMediaTime(IMediaSample* aSample)
-{
- HRESULT hr;
- REFERENCE_TIME start = 0, end = 0;
- hr = aSample->GetTime(&start, &end);
- NS_ENSURE_TRUE(SUCCEEDED(hr), E_FAIL);
- {
- CriticalSectionAutoEnter lock(*mLock);
- start += mSegmentStartTime;
- end += mSegmentStartTime;
- }
- hr = aSample->SetMediaTime(&start, &end);
- NS_ENSURE_TRUE(SUCCEEDED(hr), E_FAIL);
- return S_OK;
-}
-
-HRESULT
-AudioSinkInputPin::Receive(IMediaSample* aSample )
-{
- HRESULT hr;
- NS_ENSURE_TRUE(aSample, E_POINTER);
-
- hr = BaseInputPin::Receive(aSample);
- if (SUCCEEDED(hr) && hr != S_FALSE) { // S_FALSE == flushing
- // Set the timestamp of the sample after being adjusted for
- // seeking/segments in the "media time" attribute. When we seek,
- // DirectShow starts a new "segment", and starts labeling samples
- // from time=0 again, so we need to correct for this to get the
- // actual timestamps after seeking.
- hr = SetAbsoluteMediaTime(aSample);
- NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
- hr = GetSampleSink()->Receive(aSample);
- NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
- }
- return S_OK;
-}
-
-already_AddRefed<IMediaSeeking>
-AudioSinkInputPin::GetConnectedPinSeeking()
-{
- RefPtr<IPin> peer = GetConnected();
- if (!peer)
- return nullptr;
- RefPtr<IMediaSeeking> seeking;
- peer->QueryInterface(static_cast<IMediaSeeking**>(getter_AddRefs(seeking)));
- return seeking.forget();
-}
-
-HRESULT
-AudioSinkInputPin::BeginFlush()
-{
- HRESULT hr = media::BaseInputPin::BeginFlush();
- NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
-
- GetSampleSink()->Flush();
-
- return S_OK;
-}
-
-HRESULT
-AudioSinkInputPin::EndFlush()
-{
- HRESULT hr = media::BaseInputPin::EndFlush();
- NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
-
- // Reset the EOS flag, so that if we're called after a seek we still work.
- GetSampleSink()->Reset();
-
- return S_OK;
-}
-
-HRESULT
-AudioSinkInputPin::EndOfStream(void)
-{
- HRESULT hr = media::BaseInputPin::EndOfStream();
- if (FAILED(hr) || hr == S_FALSE) {
- // Pin is stil flushing.
- return hr;
- }
- GetSampleSink()->SetEOS();
-
- return S_OK;
-}
-
-
-HRESULT
-AudioSinkInputPin::NewSegment(REFERENCE_TIME tStart,
- REFERENCE_TIME tStop,
- double dRate)
-{
- CriticalSectionAutoEnter lock(*mLock);
- // Record the start time of the new segment, so that we can store the
- // correct absolute timestamp in the "media time" each incoming sample.
- mSegmentStartTime = tStart;
- return S_OK;
-}
-
-} // namespace mozilla
-
diff --git a/dom/media/directshow/AudioSinkInputPin.h b/dom/media/directshow/AudioSinkInputPin.h
deleted file mode 100644
index 80503c641..000000000
--- a/dom/media/directshow/AudioSinkInputPin.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#if !defined(AudioSinkInputPin_h_)
-#define AudioSinkInputPin_h_
-
-#include "BaseInputPin.h"
-#include "DirectShowUtils.h"
-#include "mozilla/RefPtr.h"
-#include "nsAutoPtr.h"
-
-namespace mozilla {
-
-namespace media {
- class MediaType;
-}
-
-class AudioSinkFilter;
-class SampleSink;
-
-
-// Input pin for capturing audio output of a DirectShow filter graph.
-// This is the input pin for the AudioSinkFilter.
-class AudioSinkInputPin: public mozilla::media::BaseInputPin
-{
-public:
- AudioSinkInputPin(wchar_t* aObjectName,
- AudioSinkFilter* aFilter,
- mozilla::CriticalSection* aLock,
- HRESULT* aOutResult);
- virtual ~AudioSinkInputPin();
-
- HRESULT GetMediaType (IN int iPos, OUT mozilla::media::MediaType * pmt);
- HRESULT CheckMediaType (IN const mozilla::media::MediaType * pmt);
- STDMETHODIMP Receive (IN IMediaSample *);
- STDMETHODIMP BeginFlush() override;
- STDMETHODIMP EndFlush() override;
-
- // Called when we start decoding a new segment, that happens directly after
- // a seek. This captures the segment's start time. Samples decoded by the
- // MP3 decoder have their timestamps offset from the segment start time.
- // Storing the segment start time enables us to set each sample's MediaTime
- // as an offset in the stream relative to the start of the stream, rather
- // than the start of the segment, i.e. its absolute time in the stream.
- STDMETHODIMP NewSegment(REFERENCE_TIME tStart,
- REFERENCE_TIME tStop,
- double dRate) override;
-
- STDMETHODIMP EndOfStream() override;
-
- // Returns the IMediaSeeking interface of the connected output pin.
- // We forward seeking requests upstream from the sink to the source
- // filters.
- already_AddRefed<IMediaSeeking> GetConnectedPinSeeking();
-
- SampleSink* GetSampleSink();
-
-private:
- AudioSinkFilter* GetAudioSinkFilter();
-
- // Sets the media time on the media sample, relative to the segment
- // start time.
- HRESULT SetAbsoluteMediaTime(IMediaSample* aSample);
-
- nsAutoPtr<SampleSink> mSampleSink;
-
- // Synchronized by the filter lock; BaseInputPin::mLock.
- REFERENCE_TIME mSegmentStartTime;
-};
-
-} // namespace mozilla
-
-#endif // AudioSinkInputPin_h_
diff --git a/dom/media/directshow/DirectShowDecoder.cpp b/dom/media/directshow/DirectShowDecoder.cpp
deleted file mode 100644
index da68b4daa..000000000
--- a/dom/media/directshow/DirectShowDecoder.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "DirectShowDecoder.h"
-#include "DirectShowReader.h"
-#include "DirectShowUtils.h"
-#include "MediaDecoderStateMachine.h"
-#include "mozilla/Preferences.h"
-#include "mozilla/WindowsVersion.h"
-
-namespace mozilla {
-
-MediaDecoderStateMachine* DirectShowDecoder::CreateStateMachine()
-{
- return new MediaDecoderStateMachine(this, new DirectShowReader(this));
-}
-
-/* static */
-bool
-DirectShowDecoder::GetSupportedCodecs(const nsACString& aType,
- char const *const ** aCodecList)
-{
- if (!IsEnabled()) {
- return false;
- }
-
- static char const *const mp3AudioCodecs[] = {
- "mp3",
- nullptr
- };
- if (aType.EqualsASCII("audio/mpeg") ||
- aType.EqualsASCII("audio/mp3")) {
- if (aCodecList) {
- *aCodecList = mp3AudioCodecs;
- }
- return true;
- }
-
- return false;
-}
-
-/* static */
-bool
-DirectShowDecoder::IsEnabled()
-{
- return CanDecodeMP3UsingDirectShow() &&
- Preferences::GetBool("media.directshow.enabled");
-}
-
-DirectShowDecoder::DirectShowDecoder(MediaDecoderOwner* aOwner)
- : MediaDecoder(aOwner)
-{
- MOZ_COUNT_CTOR(DirectShowDecoder);
-}
-
-DirectShowDecoder::~DirectShowDecoder()
-{
- MOZ_COUNT_DTOR(DirectShowDecoder);
-}
-
-} // namespace mozilla
-
diff --git a/dom/media/directshow/DirectShowDecoder.h b/dom/media/directshow/DirectShowDecoder.h
deleted file mode 100644
index c4d371fbf..000000000
--- a/dom/media/directshow/DirectShowDecoder.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#if !defined(DirectShowDecoder_h_)
-#define DirectShowDecoder_h_
-
-#include "MediaDecoder.h"
-
-namespace mozilla {
-
-// Decoder that uses DirectShow to playback MP3 files only.
-class DirectShowDecoder : public MediaDecoder
-{
-public:
-
- explicit DirectShowDecoder(MediaDecoderOwner* aOwner);
- virtual ~DirectShowDecoder();
-
- MediaDecoder* Clone(MediaDecoderOwner* aOwner) override {
- if (!IsEnabled()) {
- return nullptr;
- }
- return new DirectShowDecoder(aOwner);
- }
-
- MediaDecoderStateMachine* CreateStateMachine() override;
-
- // Returns true if aType is a MIME type that we render with the
- // DirectShow backend. If aCodecList is non null,
- // it is filled with a (static const) null-terminated list of strings
- // denoting the codecs we'll playback. Note that playback is strictly
- // limited to MP3 only.
- static bool GetSupportedCodecs(const nsACString& aType,
- char const *const ** aCodecList);
-
- // Returns true if the DirectShow backend is preffed on.
- static bool IsEnabled();
-};
-
-} // namespace mozilla
-
-#endif
diff --git a/dom/media/directshow/DirectShowReader.cpp b/dom/media/directshow/DirectShowReader.cpp
deleted file mode 100644
index cacf6f8de..000000000
--- a/dom/media/directshow/DirectShowReader.cpp
+++ /dev/null
@@ -1,360 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "DirectShowReader.h"
-#include "MediaDecoderReader.h"
-#include "mozilla/RefPtr.h"
-#include "DirectShowUtils.h"
-#include "AudioSinkFilter.h"
-#include "SourceFilter.h"
-#include "SampleSink.h"
-#include "VideoUtils.h"
-
-using namespace mozilla::media;
-
-namespace mozilla {
-
-// Windows XP's MP3 decoder filter. This is available on XP only, on Vista
-// and later we can use the DMO Wrapper filter and MP3 decoder DMO.
-const GUID DirectShowReader::CLSID_MPEG_LAYER_3_DECODER_FILTER =
-{ 0x38BE3000, 0xDBF4, 0x11D0, {0x86, 0x0E, 0x00, 0xA0, 0x24, 0xCF, 0xEF, 0x6D} };
-
-
-static LazyLogModule gDirectShowLog("DirectShowDecoder");
-#define LOG(...) MOZ_LOG(gDirectShowLog, mozilla::LogLevel::Debug, (__VA_ARGS__))
-
-DirectShowReader::DirectShowReader(AbstractMediaDecoder* aDecoder)
- : MediaDecoderReader(aDecoder),
- mMP3FrameParser(aDecoder->GetResource()->GetLength()),
-#ifdef DIRECTSHOW_REGISTER_GRAPH
- mRotRegister(0),
-#endif
- mNumChannels(0),
- mAudioRate(0),
- mBytesPerSample(0)
-{
- MOZ_ASSERT(NS_IsMainThread(), "Must be on main thread.");
- MOZ_COUNT_CTOR(DirectShowReader);
-}
-
-DirectShowReader::~DirectShowReader()
-{
- MOZ_ASSERT(NS_IsMainThread(), "Must be on main thread.");
- MOZ_COUNT_DTOR(DirectShowReader);
-#ifdef DIRECTSHOW_REGISTER_GRAPH
- if (mRotRegister) {
- RemoveGraphFromRunningObjectTable(mRotRegister);
- }
-#endif
-}
-
-// Try to parse the MP3 stream to make sure this is indeed an MP3, get the
-// estimated duration of the stream, and find the offset of the actual MP3
-// frames in the stream, as DirectShow doesn't like large ID3 sections.
-static nsresult
-ParseMP3Headers(MP3FrameParser *aParser, MediaResource *aResource)
-{
- const uint32_t MAX_READ_SIZE = 4096;
-
- uint64_t offset = 0;
- while (aParser->NeedsData() && !aParser->ParsedHeaders()) {
- uint32_t bytesRead;
- char buffer[MAX_READ_SIZE];
- nsresult rv = aResource->ReadAt(offset, buffer,
- MAX_READ_SIZE, &bytesRead);
- NS_ENSURE_SUCCESS(rv, rv);
-
- if (!bytesRead) {
- // End of stream.
- return NS_ERROR_FAILURE;
- }
-
- aParser->Parse(reinterpret_cast<uint8_t*>(buffer), bytesRead, offset);
- offset += bytesRead;
- }
-
- return aParser->IsMP3() ? NS_OK : NS_ERROR_FAILURE;
-}
-
-nsresult
-DirectShowReader::ReadMetadata(MediaInfo* aInfo,
- MetadataTags** aTags)
-{
- MOZ_ASSERT(OnTaskQueue());
- HRESULT hr;
- nsresult rv;
-
- // Create the filter graph, reference it by the GraphBuilder interface,
- // to make graph building more convenient.
- hr = CoCreateInstance(CLSID_FilterGraph,
- nullptr,
- CLSCTX_INPROC_SERVER,
- IID_IGraphBuilder,
- reinterpret_cast<void**>(static_cast<IGraphBuilder**>(getter_AddRefs(mGraph))));
- NS_ENSURE_TRUE(SUCCEEDED(hr) && mGraph, NS_ERROR_FAILURE);
-
- rv = ParseMP3Headers(&mMP3FrameParser, mDecoder->GetResource());
- NS_ENSURE_SUCCESS(rv, rv);
-
- #ifdef DIRECTSHOW_REGISTER_GRAPH
- hr = AddGraphToRunningObjectTable(mGraph, &mRotRegister);
- NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
- #endif
-
- // Extract the interface pointers we'll need from the filter graph.
- hr = mGraph->QueryInterface(static_cast<IMediaControl**>(getter_AddRefs(mControl)));
- NS_ENSURE_TRUE(SUCCEEDED(hr) && mControl, NS_ERROR_FAILURE);
-
- hr = mGraph->QueryInterface(static_cast<IMediaSeeking**>(getter_AddRefs(mMediaSeeking)));
- NS_ENSURE_TRUE(SUCCEEDED(hr) && mMediaSeeking, NS_ERROR_FAILURE);
-
- // Build the graph. Create the filters we need, and connect them. We
- // build the entire graph ourselves to prevent other decoders installed
- // on the system being created and used.
-
- // Our source filters, wraps the MediaResource.
- mSourceFilter = new SourceFilter(MEDIATYPE_Stream, MEDIASUBTYPE_MPEG1Audio);
- NS_ENSURE_TRUE(mSourceFilter, NS_ERROR_FAILURE);
-
- rv = mSourceFilter->Init(mDecoder->GetResource(), mMP3FrameParser.GetMP3Offset());
- NS_ENSURE_SUCCESS(rv, rv);
-
- hr = mGraph->AddFilter(mSourceFilter, L"MozillaDirectShowSource");
- NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
-
- // The MPEG demuxer.
- RefPtr<IBaseFilter> demuxer;
- hr = CreateAndAddFilter(mGraph,
- CLSID_MPEG1Splitter,
- L"MPEG1Splitter",
- getter_AddRefs(demuxer));
- NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
-
- // Platform MP3 decoder.
- RefPtr<IBaseFilter> decoder;
- // Firstly try to create the MP3 decoder filter that ships with WinXP
- // directly. This filter doesn't normally exist on later versions of
- // Windows.
- hr = CreateAndAddFilter(mGraph,
- CLSID_MPEG_LAYER_3_DECODER_FILTER,
- L"MPEG Layer 3 Decoder",
- getter_AddRefs(decoder));
- if (FAILED(hr)) {
- // Failed to create MP3 decoder filter. Try to instantiate
- // the MP3 decoder DMO.
- hr = AddMP3DMOWrapperFilter(mGraph, getter_AddRefs(decoder));
- NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
- }
-
- // Sink, captures audio samples and inserts them into our pipeline.
- static const wchar_t* AudioSinkFilterName = L"MozAudioSinkFilter";
- mAudioSinkFilter = new AudioSinkFilter(AudioSinkFilterName, &hr);
- NS_ENSURE_TRUE(mAudioSinkFilter && SUCCEEDED(hr), NS_ERROR_FAILURE);
- hr = mGraph->AddFilter(mAudioSinkFilter, AudioSinkFilterName);
- NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
-
- // Join the filters.
- hr = ConnectFilters(mGraph, mSourceFilter, demuxer);
- NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
-
- hr = ConnectFilters(mGraph, demuxer, decoder);
- NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
-
- hr = ConnectFilters(mGraph, decoder, mAudioSinkFilter);
- NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
-
- WAVEFORMATEX format;
- mAudioSinkFilter->GetSampleSink()->GetAudioFormat(&format);
- NS_ENSURE_TRUE(format.wFormatTag == WAVE_FORMAT_PCM, NS_ERROR_FAILURE);
-
- mInfo.mAudio.mChannels = mNumChannels = format.nChannels;
- mInfo.mAudio.mRate = mAudioRate = format.nSamplesPerSec;
- mInfo.mAudio.mBitDepth = format.wBitsPerSample;
- mBytesPerSample = format.wBitsPerSample / 8;
-
- // Begin decoding!
- hr = mControl->Run();
- NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
-
- DWORD seekCaps = 0;
- hr = mMediaSeeking->GetCapabilities(&seekCaps);
- mInfo.mMediaSeekable = SUCCEEDED(hr) && (AM_SEEKING_CanSeekAbsolute & seekCaps);
-
- int64_t duration = mMP3FrameParser.GetDuration();
- if (SUCCEEDED(hr)) {
- mInfo.mMetadataDuration.emplace(TimeUnit::FromMicroseconds(duration));
- }
-
- LOG("Successfully initialized DirectShow MP3 decoder.");
- LOG("Channels=%u Hz=%u duration=%lld bytesPerSample=%d",
- mInfo.mAudio.mChannels,
- mInfo.mAudio.mRate,
- RefTimeToUsecs(duration),
- mBytesPerSample);
-
- *aInfo = mInfo;
- // Note: The SourceFilter strips ID3v2 tags out of the stream.
- *aTags = nullptr;
-
- return NS_OK;
-}
-
-inline float
-UnsignedByteToAudioSample(uint8_t aValue)
-{
- return aValue * (2.0f / UINT8_MAX) - 1.0f;
-}
-
-bool
-DirectShowReader::Finish(HRESULT aStatus)
-{
- MOZ_ASSERT(OnTaskQueue());
-
- LOG("DirectShowReader::Finish(0x%x)", aStatus);
- // Notify the filter graph of end of stream.
- RefPtr<IMediaEventSink> eventSink;
- HRESULT hr = mGraph->QueryInterface(static_cast<IMediaEventSink**>(getter_AddRefs(eventSink)));
- if (SUCCEEDED(hr) && eventSink) {
- eventSink->Notify(EC_COMPLETE, aStatus, 0);
- }
- return false;
-}
-
-class DirectShowCopy
-{
-public:
- DirectShowCopy(uint8_t *aSource, uint32_t aBytesPerSample,
- uint32_t aSamples, uint32_t aChannels)
- : mSource(aSource)
- , mBytesPerSample(aBytesPerSample)
- , mSamples(aSamples)
- , mChannels(aChannels)
- , mNextSample(0)
- { }
-
- uint32_t operator()(AudioDataValue *aBuffer, uint32_t aSamples)
- {
- uint32_t maxSamples = std::min(aSamples, mSamples - mNextSample);
- uint32_t frames = maxSamples / mChannels;
- size_t byteOffset = mNextSample * mBytesPerSample;
- if (mBytesPerSample == 1) {
- for (uint32_t i = 0; i < maxSamples; ++i) {
- uint8_t *sample = mSource + byteOffset;
- aBuffer[i] = UnsignedByteToAudioSample(*sample);
- byteOffset += mBytesPerSample;
- }
- } else if (mBytesPerSample == 2) {
- for (uint32_t i = 0; i < maxSamples; ++i) {
- int16_t *sample = reinterpret_cast<int16_t *>(mSource + byteOffset);
- aBuffer[i] = AudioSampleToFloat(*sample);
- byteOffset += mBytesPerSample;
- }
- }
- mNextSample += maxSamples;
- return frames;
- }
-
-private:
- uint8_t * const mSource;
- const uint32_t mBytesPerSample;
- const uint32_t mSamples;
- const uint32_t mChannels;
- uint32_t mNextSample;
-};
-
-bool
-DirectShowReader::DecodeAudioData()
-{
- MOZ_ASSERT(OnTaskQueue());
- HRESULT hr;
-
- SampleSink* sink = mAudioSinkFilter->GetSampleSink();
- if (sink->AtEOS()) {
- // End of stream.
- return Finish(S_OK);
- }
-
- // Get the next chunk of audio samples. This blocks until the sample
- // arrives, or an error occurs (like the stream is shutdown).
- RefPtr<IMediaSample> sample;
- hr = sink->Extract(sample);
- if (FAILED(hr) || hr == S_FALSE) {
- return Finish(hr);
- }
-
- int64_t start = 0, end = 0;
- sample->GetMediaTime(&start, &end);
- LOG("DirectShowReader::DecodeAudioData [%4.2lf-%4.2lf]",
- RefTimeToSeconds(start),
- RefTimeToSeconds(end));
-
- LONG length = sample->GetActualDataLength();
- LONG numSamples = length / mBytesPerSample;
- LONG numFrames = length / mBytesPerSample / mNumChannels;
-
- BYTE* data = nullptr;
- hr = sample->GetPointer(&data);
- NS_ENSURE_TRUE(SUCCEEDED(hr), Finish(hr));
-
- mAudioCompactor.Push(mDecoder->GetResource()->Tell(),
- RefTimeToUsecs(start),
- mInfo.mAudio.mRate,
- numFrames,
- mNumChannels,
- DirectShowCopy(reinterpret_cast<uint8_t *>(data),
- mBytesPerSample,
- numSamples,
- mNumChannels));
- return true;
-}
-
-bool
-DirectShowReader::DecodeVideoFrame(bool &aKeyframeSkip,
- int64_t aTimeThreshold)
-{
- MOZ_ASSERT(OnTaskQueue());
- return false;
-}
-
-RefPtr<MediaDecoderReader::SeekPromise>
-DirectShowReader::Seek(SeekTarget aTarget, int64_t aEndTime)
-{
- nsresult res = SeekInternal(aTarget.GetTime().ToMicroseconds());
- if (NS_FAILED(res)) {
- return SeekPromise::CreateAndReject(res, __func__);
- } else {
- return SeekPromise::CreateAndResolve(aTarget.GetTime(), __func__);
- }
-}
-
-nsresult
-DirectShowReader::SeekInternal(int64_t aTargetUs)
-{
- HRESULT hr;
- MOZ_ASSERT(OnTaskQueue());
-
- LOG("DirectShowReader::Seek() target=%lld", aTargetUs);
-
- hr = mControl->Pause();
- NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
-
- nsresult rv = ResetDecode();
- NS_ENSURE_SUCCESS(rv, rv);
-
- LONGLONG seekPosition = UsecsToRefTime(aTargetUs);
- hr = mMediaSeeking->SetPositions(&seekPosition,
- AM_SEEKING_AbsolutePositioning,
- nullptr,
- AM_SEEKING_NoPositioning);
- NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
-
- hr = mControl->Run();
- NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
-
- return NS_OK;
-}
-
-} // namespace mozilla
diff --git a/dom/media/directshow/DirectShowReader.h b/dom/media/directshow/DirectShowReader.h
deleted file mode 100644
index e1326d416..000000000
--- a/dom/media/directshow/DirectShowReader.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#if !defined(DirectShowReader_h_)
-#define DirectShowReader_h_
-
-#include "windows.h" // HRESULT, DWORD
-#include "MediaDecoderReader.h"
-#include "MediaResource.h"
-#include "mozilla/RefPtr.h"
-#include "MP3FrameParser.h"
-
-// Add the graph to the Running Object Table so that we can connect
-// to this graph with GraphEdit/GraphStudio. Note: on Vista and up you must
-// also regsvr32 proppage.dll from the Windows SDK.
-// See: http://msdn.microsoft.com/en-us/library/ms787252(VS.85).aspx
-// #define DIRECTSHOW_REGISTER_GRAPH
-
-struct IGraphBuilder;
-struct IMediaControl;
-struct IMediaSeeking;
-
-namespace mozilla {
-
-class AudioSinkFilter;
-class SourceFilter;
-
-// Decoder backend for decoding MP3 using DirectShow. DirectShow operates as
-// a filter graph. The basic design of the DirectShowReader is that we have
-// a SourceFilter that wraps the MediaResource that connects to the
-// MP3 decoder filter. The MP3 decoder filter "pulls" data as it requires it
-// downstream on its own thread. When the MP3 decoder has produced a block of
-// decoded samples, its thread calls downstream into our AudioSinkFilter,
-// passing the decoded buffer in. The AudioSinkFilter inserts the samples into
-// a SampleSink object. The SampleSink blocks the MP3 decoder's thread until
-// the decode thread calls DecodeAudioData(), whereupon the SampleSink
-// releases the decoded samples to the decode thread, and unblocks the MP3
-// decoder's thread. The MP3 decoder can then request more data from the
-// SourceFilter, and decode more data. If the decode thread calls
-// DecodeAudioData() and there's no decoded samples waiting to be extracted
-// in the SampleSink, the SampleSink blocks the decode thread until the MP3
-// decoder produces a decoded sample.
-class DirectShowReader : public MediaDecoderReader
-{
-public:
- DirectShowReader(AbstractMediaDecoder* aDecoder);
-
- virtual ~DirectShowReader();
-
- bool DecodeAudioData() override;
- bool DecodeVideoFrame(bool &aKeyframeSkip,
- int64_t aTimeThreshold) override;
-
- nsresult ReadMetadata(MediaInfo* aInfo,
- MetadataTags** aTags) override;
-
- RefPtr<SeekPromise>
- Seek(SeekTarget aTarget, int64_t aEndTime) override;
-
- static const GUID CLSID_MPEG_LAYER_3_DECODER_FILTER;
-
-private:
- // Notifies the filter graph that playback is complete. aStatus is
- // the code to send to the filter graph. Always returns false, so
- // that we can just "return Finish()" from DecodeAudioData().
- bool Finish(HRESULT aStatus);
-
- nsresult SeekInternal(int64_t aTime);
-
- // DirectShow filter graph, and associated playback and seeking
- // control interfaces.
- RefPtr<IGraphBuilder> mGraph;
- RefPtr<IMediaControl> mControl;
- RefPtr<IMediaSeeking> mMediaSeeking;
-
- // Wraps the MediaResource, and feeds undecoded data into the filter graph.
- RefPtr<SourceFilter> mSourceFilter;
-
- // Sits at the end of the graph, removing decoded samples from the graph.
- // The graph will block while this is blocked, i.e. it will pause decoding.
- RefPtr<AudioSinkFilter> mAudioSinkFilter;
-
- // Some MP3s are variable bitrate, so DirectShow's duration estimation
- // can make its duration estimation based on the wrong bitrate. So we parse
- // the MP3 frames to get a more accuate estimate of the duration.
- MP3FrameParser mMP3FrameParser;
-
-#ifdef DIRECTSHOW_REGISTER_GRAPH
- // Used to add/remove the filter graph to the Running Object Table. You can
- // connect GraphEdit/GraphStudio to the graph to observe and/or debug its
- // topology and state.
- DWORD mRotRegister;
-#endif
-
- // Number of channels in the audio stream.
- uint32_t mNumChannels;
-
- // Samples per second in the audio stream.
- uint32_t mAudioRate;
-
- // Number of bytes per sample. Can be either 1 or 2.
- uint32_t mBytesPerSample;
-};
-
-} // namespace mozilla
-
-#endif
diff --git a/dom/media/directshow/DirectShowUtils.cpp b/dom/media/directshow/DirectShowUtils.cpp
deleted file mode 100644
index b2afa7528..000000000
--- a/dom/media/directshow/DirectShowUtils.cpp
+++ /dev/null
@@ -1,369 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "DirectShowUtils.h"
-#include "dmodshow.h"
-#include "wmcodecdsp.h"
-#include "dmoreg.h"
-#include "mozilla/ArrayUtils.h"
-#include "mozilla/RefPtr.h"
-#include "nsPrintfCString.h"
-
-#define WARN(...) NS_WARNING(nsPrintfCString(__VA_ARGS__).get())
-
-namespace mozilla {
-
-// Create a table which maps GUIDs to a string representation of the GUID.
-// This is useful for debugging purposes, for logging the GUIDs of media types.
-// This is only available when logging is enabled, i.e. not in release builds.
-struct GuidToName {
- const char* name;
- const GUID guid;
-};
-
-#pragma push_macro("OUR_GUID_ENTRY")
-#undef OUR_GUID_ENTRY
-#define OUR_GUID_ENTRY(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
- { #name, {l, w1, w2, {b1, b2, b3, b4, b5, b6, b7, b8}} },
-
-static const GuidToName GuidToNameTable[] = {
-#include <uuids.h>
-};
-
-#pragma pop_macro("OUR_GUID_ENTRY")
-
-const char*
-GetDirectShowGuidName(const GUID& aGuid)
-{
- const size_t len = ArrayLength(GuidToNameTable);
- for (unsigned i = 0; i < len; i++) {
- if (IsEqualGUID(aGuid, GuidToNameTable[i].guid)) {
- return GuidToNameTable[i].name;
- }
- }
- return "Unknown";
-}
-
-void
-RemoveGraphFromRunningObjectTable(DWORD aRotRegister)
-{
- RefPtr<IRunningObjectTable> runningObjectTable;
- if (SUCCEEDED(GetRunningObjectTable(0, getter_AddRefs(runningObjectTable)))) {
- runningObjectTable->Revoke(aRotRegister);
- }
-}
-
-HRESULT
-AddGraphToRunningObjectTable(IUnknown *aUnkGraph, DWORD *aOutRotRegister)
-{
- HRESULT hr;
-
- RefPtr<IMoniker> moniker;
- RefPtr<IRunningObjectTable> runningObjectTable;
-
- hr = GetRunningObjectTable(0, getter_AddRefs(runningObjectTable));
- NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
-
- const size_t STRING_LENGTH = 256;
- WCHAR wsz[STRING_LENGTH];
-
- StringCchPrintfW(wsz,
- STRING_LENGTH,
- L"FilterGraph %08x pid %08x",
- (DWORD_PTR)aUnkGraph,
- GetCurrentProcessId());
-
- hr = CreateItemMoniker(L"!", wsz, getter_AddRefs(moniker));
- NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
-
- hr = runningObjectTable->Register(ROTFLAGS_REGISTRATIONKEEPSALIVE,
- aUnkGraph,
- moniker,
- aOutRotRegister);
- NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
-
- return S_OK;
-}
-
-const char*
-GetGraphNotifyString(long evCode)
-{
-#define CASE(x) case x: return #x
- switch(evCode) {
- CASE(EC_ACTIVATE); // A video window is being activated or deactivated.
- CASE(EC_BANDWIDTHCHANGE); // Not supported.
- CASE(EC_BUFFERING_DATA); // The graph is buffering data, or has stopped buffering data.
- CASE(EC_BUILT); // Send by the Video Control when a graph has been built. Not forwarded to applications.
- CASE(EC_CLOCK_CHANGED); // The reference clock has changed.
- CASE(EC_CLOCK_UNSET); // The clock provider was disconnected.
- CASE(EC_CODECAPI_EVENT); // Sent by an encoder to signal an encoding event.
- CASE(EC_COMPLETE); // All data from a particular stream has been rendered.
- CASE(EC_CONTENTPROPERTY_CHANGED); // Not supported.
- CASE(EC_DEVICE_LOST); // A Plug and Play device was removed or has become available again.
- CASE(EC_DISPLAY_CHANGED); // The display mode has changed.
- CASE(EC_END_OF_SEGMENT); // The end of a segment has been reached.
- CASE(EC_EOS_SOON); // Not supported.
- CASE(EC_ERROR_STILLPLAYING); // An asynchronous command to run the graph has failed.
- CASE(EC_ERRORABORT); // An operation was aborted because of an error.
- CASE(EC_ERRORABORTEX); // An operation was aborted because of an error.
- CASE(EC_EXTDEVICE_MODE_CHANGE); // Not supported.
- CASE(EC_FILE_CLOSED); // The source file was closed because of an unexpected event.
- CASE(EC_FULLSCREEN_LOST); // The video renderer is switching out of full-screen mode.
- CASE(EC_GRAPH_CHANGED); // The filter graph has changed.
- CASE(EC_LENGTH_CHANGED); // The length of a source has changed.
- CASE(EC_LOADSTATUS); // Notifies the application of progress when opening a network file.
- CASE(EC_MARKER_HIT); // Not supported.
- CASE(EC_NEED_RESTART); // A filter is requesting that the graph be restarted.
- CASE(EC_NEW_PIN); // Not supported.
- CASE(EC_NOTIFY_WINDOW); // Notifies a filter of the video renderer's window.
- CASE(EC_OLE_EVENT); // A filter is passing a text string to the application.
- CASE(EC_OPENING_FILE); // The graph is opening a file, or has finished opening a file.
- CASE(EC_PALETTE_CHANGED); // The video palette has changed.
- CASE(EC_PAUSED); // A pause request has completed.
- CASE(EC_PLEASE_REOPEN); // The source file has changed.
- CASE(EC_PREPROCESS_COMPLETE); // Sent by the WM ASF Writer filter when it completes the pre-processing for multipass encoding.
- CASE(EC_PROCESSING_LATENCY); // Indicates the amount of time that a component is taking to process each sample.
- CASE(EC_QUALITY_CHANGE); // The graph is dropping samples, for quality control.
- //CASE(EC_RENDER_FINISHED); // Not supported.
- CASE(EC_REPAINT); // A video renderer requires a repaint.
- CASE(EC_SAMPLE_LATENCY); // Specifies how far behind schedule a component is for processing samples.
- //CASE(EC_SAMPLE_NEEDED); // Requests a new input sample from the Enhanced Video Renderer (EVR) filter.
- CASE(EC_SCRUB_TIME); // Specifies the time stamp for the most recent frame step.
- CASE(EC_SEGMENT_STARTED); // A new segment has started.
- CASE(EC_SHUTTING_DOWN); // The filter graph is shutting down, prior to being destroyed.
- CASE(EC_SNDDEV_IN_ERROR); // A device error has occurred in an audio capture filter.
- CASE(EC_SNDDEV_OUT_ERROR); // A device error has occurred in an audio renderer filter.
- CASE(EC_STARVATION); // A filter is not receiving enough data.
- CASE(EC_STATE_CHANGE); // The filter graph has changed state.
- CASE(EC_STATUS); // Contains two arbitrary status strings.
- CASE(EC_STEP_COMPLETE); // A filter performing frame stepping has stepped the specified number of frames.
- CASE(EC_STREAM_CONTROL_STARTED); // A stream-control start command has taken effect.
- CASE(EC_STREAM_CONTROL_STOPPED); // A stream-control stop command has taken effect.
- CASE(EC_STREAM_ERROR_STILLPLAYING); // An error has occurred in a stream. The stream is still playing.
- CASE(EC_STREAM_ERROR_STOPPED); // A stream has stopped because of an error.
- CASE(EC_TIMECODE_AVAILABLE); // Not supported.
- CASE(EC_UNBUILT); // Send by the Video Control when a graph has been torn down. Not forwarded to applications.
- CASE(EC_USERABORT); // The user has terminated playback.
- CASE(EC_VIDEO_SIZE_CHANGED); // The native video size has changed.
- CASE(EC_VIDEOFRAMEREADY); // A video frame is ready for display.
- CASE(EC_VMR_RECONNECTION_FAILED); // Sent by the VMR-7 and the VMR-9 when it was unable to accept a dynamic format change request from the upstream decoder.
- CASE(EC_VMR_RENDERDEVICE_SET); // Sent when the VMR has selected its rendering mechanism.
- CASE(EC_VMR_SURFACE_FLIPPED); // Sent when the VMR-7's allocator presenter has called the DirectDraw Flip method on the surface being presented.
- CASE(EC_WINDOW_DESTROYED); // The video renderer was destroyed or removed from the graph.
- CASE(EC_WMT_EVENT); // Sent by the WM ASF Reader filter when it reads ASF files protected by digital rights management (DRM).
- CASE(EC_WMT_INDEX_EVENT); // Sent when an application uses the WM ASF Writer to index Windows Media Video files.
- CASE(S_OK); // Success.
- CASE(VFW_S_AUDIO_NOT_RENDERED); // Partial success; the audio was not rendered.
- CASE(VFW_S_DUPLICATE_NAME); // Success; the Filter Graph Manager modified a filter name to avoid duplication.
- CASE(VFW_S_PARTIAL_RENDER); // Partial success; some of the streams in this movie are in an unsupported format.
- CASE(VFW_S_VIDEO_NOT_RENDERED); // Partial success; the video was not rendered.
- CASE(E_ABORT); // Operation aborted.
- CASE(E_OUTOFMEMORY); // Insufficient memory.
- CASE(E_POINTER); // Null pointer argument.
- CASE(VFW_E_CANNOT_CONNECT); // No combination of intermediate filters could be found to make the connection.
- CASE(VFW_E_CANNOT_RENDER); // No combination of filters could be found to render the stream.
- CASE(VFW_E_NO_ACCEPTABLE_TYPES); // There is no common media type between these pins.
- CASE(VFW_E_NOT_IN_GRAPH);
-
- default:
- return "Unknown Code";
- };
-#undef CASE
-}
-
-HRESULT
-CreateAndAddFilter(IGraphBuilder* aGraph,
- REFGUID aFilterClsId,
- LPCWSTR aFilterName,
- IBaseFilter **aOutFilter)
-{
- NS_ENSURE_TRUE(aGraph, E_POINTER);
- NS_ENSURE_TRUE(aOutFilter, E_POINTER);
- HRESULT hr;
-
- RefPtr<IBaseFilter> filter;
- hr = CoCreateInstance(aFilterClsId,
- nullptr,
- CLSCTX_INPROC_SERVER,
- IID_IBaseFilter,
- getter_AddRefs(filter));
- if (FAILED(hr)) {
- // Object probably not available on this system.
- WARN("CoCreateInstance failed, hr=%x", hr);
- return hr;
- }
-
- hr = aGraph->AddFilter(filter, aFilterName);
- if (FAILED(hr)) {
- WARN("AddFilter failed, hr=%x", hr);
- return hr;
- }
-
- filter.forget(aOutFilter);
-
- return S_OK;
-}
-
-HRESULT
-CreateMP3DMOWrapperFilter(IBaseFilter **aOutFilter)
-{
- NS_ENSURE_TRUE(aOutFilter, E_POINTER);
- HRESULT hr;
-
- // Create the wrapper filter.
- RefPtr<IBaseFilter> filter;
- hr = CoCreateInstance(CLSID_DMOWrapperFilter,
- nullptr,
- CLSCTX_INPROC_SERVER,
- IID_IBaseFilter,
- getter_AddRefs(filter));
- if (FAILED(hr)) {
- WARN("CoCreateInstance failed, hr=%x", hr);
- return hr;
- }
-
- // Query for IDMOWrapperFilter.
- RefPtr<IDMOWrapperFilter> dmoWrapper;
- hr = filter->QueryInterface(IID_IDMOWrapperFilter,
- getter_AddRefs(dmoWrapper));
- if (FAILED(hr)) {
- WARN("QueryInterface failed, hr=%x", hr);
- return hr;
- }
-
- hr = dmoWrapper->Init(CLSID_CMP3DecMediaObject, DMOCATEGORY_AUDIO_DECODER);
- if (FAILED(hr)) {
- // Can't instantiate MP3 DMO. It doesn't exist on Windows XP, we're
- // probably hitting that. Don't log warning to console, this is an
- // expected error.
- WARN("dmoWrapper Init failed, hr=%x", hr);
- return hr;
- }
-
- filter.forget(aOutFilter);
-
- return S_OK;
-}
-
-HRESULT
-AddMP3DMOWrapperFilter(IGraphBuilder* aGraph,
- IBaseFilter **aOutFilter)
-{
- NS_ENSURE_TRUE(aGraph, E_POINTER);
- NS_ENSURE_TRUE(aOutFilter, E_POINTER);
- HRESULT hr;
-
- // Create the wrapper filter.
- RefPtr<IBaseFilter> filter;
- hr = CreateMP3DMOWrapperFilter(getter_AddRefs(filter));
- NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
-
- // Add the wrapper filter to graph.
- hr = aGraph->AddFilter(filter, L"MP3 Decoder DMO");
- if (FAILED(hr)) {
- WARN("AddFilter failed, hr=%x", hr);
- return hr;
- }
-
- filter.forget(aOutFilter);
-
- return S_OK;
-}
-
-bool
-CanDecodeMP3UsingDirectShow()
-{
- RefPtr<IBaseFilter> filter;
-
- // Can we create the MP3 demuxer filter?
- if (FAILED(CoCreateInstance(CLSID_MPEG1Splitter,
- nullptr,
- CLSCTX_INPROC_SERVER,
- IID_IBaseFilter,
- getter_AddRefs(filter)))) {
- return false;
- }
-
- // Can we create either the WinXP MP3 decoder filter or the MP3 DMO decoder?
- if (FAILED(CoCreateInstance(DirectShowReader::CLSID_MPEG_LAYER_3_DECODER_FILTER,
- nullptr,
- CLSCTX_INPROC_SERVER,
- IID_IBaseFilter,
- getter_AddRefs(filter))) &&
- FAILED(CreateMP3DMOWrapperFilter(getter_AddRefs(filter)))) {
- return false;
- }
-
- // Else, we can create all of the components we need. Assume
- // DirectShow is going to work...
- return true;
-}
-
-// Match a pin by pin direction and connection state.
-HRESULT
-MatchUnconnectedPin(IPin* aPin,
- PIN_DIRECTION aPinDir,
- bool *aOutMatches)
-{
- NS_ENSURE_TRUE(aPin, E_POINTER);
- NS_ENSURE_TRUE(aOutMatches, E_POINTER);
-
- // Ensure the pin is unconnected.
- RefPtr<IPin> peer;
- HRESULT hr = aPin->ConnectedTo(getter_AddRefs(peer));
- if (hr != VFW_E_NOT_CONNECTED) {
- *aOutMatches = false;
- return hr;
- }
-
- // Ensure the pin is of the specified direction.
- PIN_DIRECTION pinDir;
- hr = aPin->QueryDirection(&pinDir);
- NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
-
- *aOutMatches = (pinDir == aPinDir);
- return S_OK;
-}
-
-// Return the first unconnected input pin or output pin.
-already_AddRefed<IPin>
-GetUnconnectedPin(IBaseFilter* aFilter, PIN_DIRECTION aPinDir)
-{
- RefPtr<IEnumPins> enumPins;
-
- HRESULT hr = aFilter->EnumPins(getter_AddRefs(enumPins));
- NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr);
-
- // Test each pin to see if it matches the direction we're looking for.
- RefPtr<IPin> pin;
- while (S_OK == enumPins->Next(1, getter_AddRefs(pin), nullptr)) {
- bool matches = FALSE;
- if (SUCCEEDED(MatchUnconnectedPin(pin, aPinDir, &matches)) &&
- matches) {
- return pin.forget();
- }
- }
-
- return nullptr;
-}
-
-HRESULT
-ConnectFilters(IGraphBuilder* aGraph,
- IBaseFilter* aOutputFilter,
- IBaseFilter* aInputFilter)
-{
- RefPtr<IPin> output = GetUnconnectedPin(aOutputFilter, PINDIR_OUTPUT);
- NS_ENSURE_TRUE(output, E_FAIL);
-
- RefPtr<IPin> input = GetUnconnectedPin(aInputFilter, PINDIR_INPUT);
- NS_ENSURE_TRUE(output, E_FAIL);
-
- return aGraph->Connect(output, input);
-}
-
-} // namespace mozilla
-
-// avoid redefined macro in unified build
-#undef WARN
diff --git a/dom/media/directshow/DirectShowUtils.h b/dom/media/directshow/DirectShowUtils.h
deleted file mode 100644
index 3bbc122fc..000000000
--- a/dom/media/directshow/DirectShowUtils.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef _DirectShowUtils_h_
-#define _DirectShowUtils_h_
-
-#include <stdint.h>
-#include "dshow.h"
-
-// XXXbz windowsx.h defines GetFirstChild, GetNextSibling,
-// GetPrevSibling are macros, apparently... Eeevil. We have functions
-// called that on some classes, so undef them.
-#undef GetFirstChild
-#undef GetNextSibling
-#undef GetPrevSibling
-
-#include "DShowTools.h"
-#include "mozilla/Logging.h"
-
-namespace mozilla {
-
-// Win32 "Event" wrapper. Must be paired with a CriticalSection to create a
-// Java-style "monitor".
-class Signal {
-public:
-
- Signal(CriticalSection* aLock)
- : mLock(aLock)
- {
- CriticalSectionAutoEnter lock(*mLock);
- mEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr);
- }
-
- ~Signal() {
- CriticalSectionAutoEnter lock(*mLock);
- CloseHandle(mEvent);
- }
-
- // Lock must be held.
- void Notify() {
- SetEvent(mEvent);
- }
-
- // Lock must be held. Check the wait condition before waiting!
- HRESULT Wait() {
- mLock->Leave();
- DWORD result = WaitForSingleObject(mEvent, INFINITE);
- mLock->Enter();
- return result == WAIT_OBJECT_0 ? S_OK : E_FAIL;
- }
-
-private:
- CriticalSection* mLock;
- HANDLE mEvent;
-};
-
-HRESULT
-AddGraphToRunningObjectTable(IUnknown *aUnkGraph, DWORD *aOutRotRegister);
-
-void
-RemoveGraphFromRunningObjectTable(DWORD aRotRegister);
-
-const char*
-GetGraphNotifyString(long evCode);
-
-// Creates a filter and adds it to a graph.
-HRESULT
-CreateAndAddFilter(IGraphBuilder* aGraph,
- REFGUID aFilterClsId,
- LPCWSTR aFilterName,
- IBaseFilter **aOutFilter);
-
-HRESULT
-AddMP3DMOWrapperFilter(IGraphBuilder* aGraph,
- IBaseFilter **aOutFilter);
-
-// Connects the output pin on aOutputFilter to an input pin on
-// aInputFilter, in aGraph.
-HRESULT
-ConnectFilters(IGraphBuilder* aGraph,
- IBaseFilter* aOutputFilter,
- IBaseFilter* aInputFilter);
-
-HRESULT
-MatchUnconnectedPin(IPin* aPin,
- PIN_DIRECTION aPinDir,
- bool *aOutMatches);
-
-// Converts from microseconds to DirectShow "Reference Time"
-// (hundreds of nanoseconds).
-inline int64_t
-UsecsToRefTime(const int64_t aUsecs)
-{
- return aUsecs * 10;
-}
-
-// Converts from DirectShow "Reference Time" (hundreds of nanoseconds)
-// to microseconds.
-inline int64_t
-RefTimeToUsecs(const int64_t hRefTime)
-{
- return hRefTime / 10;
-}
-
-// Converts from DirectShow "Reference Time" (hundreds of nanoseconds)
-// to seconds.
-inline double
-RefTimeToSeconds(const REFERENCE_TIME aRefTime)
-{
- return double(aRefTime) / 10000000;
-}
-
-const char*
-GetDirectShowGuidName(const GUID& aGuid);
-
-// Returns true if we can instantiate an MP3 demuxer and decoder filters.
-// Use this to detect whether MP3 support is installed.
-bool
-CanDecodeMP3UsingDirectShow();
-
-} // namespace mozilla
-
-#endif
diff --git a/dom/media/directshow/SampleSink.cpp b/dom/media/directshow/SampleSink.cpp
deleted file mode 100644
index fa5dc8d19..000000000
--- a/dom/media/directshow/SampleSink.cpp
+++ /dev/null
@@ -1,159 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "SampleSink.h"
-#include "AudioSinkFilter.h"
-#include "AudioSinkInputPin.h"
-#include "VideoUtils.h"
-#include "mozilla/Logging.h"
-
-using namespace mozilla::media;
-
-namespace mozilla {
-
-static LazyLogModule gDirectShowLog("DirectShowDecoder");
-#define LOG(...) MOZ_LOG(gDirectShowLog, mozilla::LogLevel::Debug, (__VA_ARGS__))
-
-SampleSink::SampleSink()
- : mMonitor("SampleSink"),
- mIsFlushing(false),
- mAtEOS(false)
-{
- MOZ_COUNT_CTOR(SampleSink);
-}
-
-SampleSink::~SampleSink()
-{
- MOZ_COUNT_DTOR(SampleSink);
-}
-
-void
-SampleSink::SetAudioFormat(const WAVEFORMATEX* aInFormat)
-{
- NS_ENSURE_TRUE(aInFormat, );
- ReentrantMonitorAutoEnter mon(mMonitor);
- memcpy(&mAudioFormat, aInFormat, sizeof(WAVEFORMATEX));
-}
-
-void
-SampleSink::GetAudioFormat(WAVEFORMATEX* aOutFormat)
-{
- MOZ_ASSERT(aOutFormat);
- ReentrantMonitorAutoEnter mon(mMonitor);
- memcpy(aOutFormat, &mAudioFormat, sizeof(WAVEFORMATEX));
-}
-
-HRESULT
-SampleSink::Receive(IMediaSample* aSample)
-{
- ReentrantMonitorAutoEnter mon(mMonitor);
-
- while (true) {
- if (mIsFlushing) {
- return S_FALSE;
- }
- if (!mSample) {
- break;
- }
- if (mAtEOS) {
- return E_UNEXPECTED;
- }
- // Wait until the consumer thread consumes the sample.
- mon.Wait();
- }
-
- if (MOZ_LOG_TEST(gDirectShowLog, LogLevel::Debug)) {
- REFERENCE_TIME start = 0, end = 0;
- HRESULT hr = aSample->GetMediaTime(&start, &end);
- LOG("SampleSink::Receive() [%4.2lf-%4.2lf]",
- (double)RefTimeToUsecs(start) / USECS_PER_S,
- (double)RefTimeToUsecs(end) / USECS_PER_S);
- }
-
- mSample = aSample;
- // Notify the signal, to awaken the consumer thread in WaitForSample()
- // if necessary.
- mon.NotifyAll();
- return S_OK;
-}
-
-HRESULT
-SampleSink::Extract(RefPtr<IMediaSample>& aOutSample)
-{
- ReentrantMonitorAutoEnter mon(mMonitor);
- // Loop until we have a sample, or we should abort.
- while (true) {
- if (mIsFlushing) {
- return S_FALSE;
- }
- if (mSample) {
- break;
- }
- if (mAtEOS) {
- // Order is important here, if we have a sample, we should return it
- // before reporting EOS.
- return E_UNEXPECTED;
- }
- // Wait until the producer thread gives us a sample.
- mon.Wait();
- }
- aOutSample = mSample;
-
- if (MOZ_LOG_TEST(gDirectShowLog, LogLevel::Debug)) {
- int64_t start = 0, end = 0;
- mSample->GetMediaTime(&start, &end);
- LOG("SampleSink::Extract() [%4.2lf-%4.2lf]",
- (double)RefTimeToUsecs(start) / USECS_PER_S,
- (double)RefTimeToUsecs(end) / USECS_PER_S);
- }
-
- mSample = nullptr;
- // Notify the signal, to awaken the producer thread in Receive()
- // if necessary.
- mon.NotifyAll();
- return S_OK;
-}
-
-void
-SampleSink::Flush()
-{
- LOG("SampleSink::Flush()");
- ReentrantMonitorAutoEnter mon(mMonitor);
- mIsFlushing = true;
- mSample = nullptr;
- mon.NotifyAll();
-}
-
-void
-SampleSink::Reset()
-{
- LOG("SampleSink::Reset()");
- ReentrantMonitorAutoEnter mon(mMonitor);
- mIsFlushing = false;
- mAtEOS = false;
-}
-
-void
-SampleSink::SetEOS()
-{
- LOG("SampleSink::SetEOS()");
- ReentrantMonitorAutoEnter mon(mMonitor);
- mAtEOS = true;
- // Notify to unblock any threads waiting for samples in
- // Extract() or Receive(). Now that we're at EOS, no more samples
- // will come!
- mon.NotifyAll();
-}
-
-bool
-SampleSink::AtEOS()
-{
- ReentrantMonitorAutoEnter mon(mMonitor);
- return mAtEOS && !mSample;
-}
-
-} // namespace mozilla
-
diff --git a/dom/media/directshow/SampleSink.h b/dom/media/directshow/SampleSink.h
deleted file mode 100644
index 6a1af9fee..000000000
--- a/dom/media/directshow/SampleSink.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#if !defined(SampleSink_h_)
-#define SampleSink_h_
-
-#include "BaseFilter.h"
-#include "DirectShowUtils.h"
-#include "mozilla/RefPtr.h"
-#include "mozilla/ReentrantMonitor.h"
-
-namespace mozilla {
-
-class SampleSink {
-public:
- SampleSink();
- virtual ~SampleSink();
-
- // Sets the audio format of the incoming samples. The upstream filter
- // calls this. This makes a copy.
- void SetAudioFormat(const WAVEFORMATEX* aInFormat);
-
- // Copies the format of incoming audio samples into into *aOutFormat.
- void GetAudioFormat(WAVEFORMATEX* aOutFormat);
-
- // Called when a sample is delivered by the DirectShow graph to the sink.
- // The decode thread retrieves the sample by calling WaitForSample().
- // Blocks if there's already a sample waiting to be consumed by the decode
- // thread.
- HRESULT Receive(IMediaSample* aSample);
-
- // Retrieves a sample from the sample queue, blocking until one becomes
- // available, or until an error occurs. Returns S_FALSE on EOS.
- HRESULT Extract(RefPtr<IMediaSample>& aOutSample);
-
- // Unblocks any threads waiting in GetSample().
- // Clears mSample, which unblocks upstream stream.
- void Flush();
-
- // Opens up the sink to receive more samples in PutSample().
- // Clears EOS flag.
- void Reset();
-
- // Marks that we've reacehd the end of stream.
- void SetEOS();
-
- // Returns whether we're at end of stream.
- bool AtEOS();
-
-private:
- // All data in this class is syncronized by mMonitor.
- ReentrantMonitor mMonitor;
- RefPtr<IMediaSample> mSample;
-
- // Format of the audio stream we're receiving.
- WAVEFORMATEX mAudioFormat;
-
- bool mIsFlushing;
- bool mAtEOS;
-};
-
-} // namespace mozilla
-
-#endif // SampleSink_h_
diff --git a/dom/media/directshow/SourceFilter.cpp b/dom/media/directshow/SourceFilter.cpp
deleted file mode 100644
index 4c5a0882c..000000000
--- a/dom/media/directshow/SourceFilter.cpp
+++ /dev/null
@@ -1,683 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "SourceFilter.h"
-#include "MediaResource.h"
-#include "mozilla/RefPtr.h"
-#include "DirectShowUtils.h"
-#include "MP3FrameParser.h"
-#include "mozilla/Logging.h"
-#include <algorithm>
-
-using namespace mozilla::media;
-
-namespace mozilla {
-
-// Define to trace what's on...
-//#define DEBUG_SOURCE_TRACE 1
-
-#if defined (DEBUG_SOURCE_TRACE)
-static LazyLogModule gDirectShowLog("DirectShowDecoder");
-#define DIRECTSHOW_LOG(...) MOZ_LOG(gDirectShowLog, mozilla::LogLevel::Debug, (__VA_ARGS__))
-#else
-#define DIRECTSHOW_LOG(...)
-#endif
-
-static HRESULT
-DoGetInterface(IUnknown* aUnknown, void** aInterface)
-{
- if (!aInterface)
- return E_POINTER;
- *aInterface = aUnknown;
- aUnknown->AddRef();
- return S_OK;
-}
-
-// Stores details of IAsyncReader::Request().
-class ReadRequest {
-public:
-
- ReadRequest(IMediaSample* aSample,
- DWORD_PTR aDwUser,
- uint32_t aOffset,
- uint32_t aCount)
- : mSample(aSample),
- mDwUser(aDwUser),
- mOffset(aOffset),
- mCount(aCount)
- {
- MOZ_COUNT_CTOR(ReadRequest);
- }
-
- ~ReadRequest() {
- MOZ_COUNT_DTOR(ReadRequest);
- }
-
- RefPtr<IMediaSample> mSample;
- DWORD_PTR mDwUser;
- uint32_t mOffset;
- uint32_t mCount;
-};
-
-// A wrapper around media resource that presents only a partition of the
-// underlying resource to the caller to use. The partition returned is from
-// an offset to the end of stream, and this object deals with ensuring
-// the offsets and lengths etc are translated from the reduced partition
-// exposed to the caller, to the absolute offsets of the underlying stream.
-class MediaResourcePartition {
-public:
- MediaResourcePartition(MediaResource* aResource,
- int64_t aDataStart)
- : mResource(aResource),
- mDataOffset(aDataStart)
- {}
-
- int64_t GetLength() {
- int64_t len = mResource.GetLength();
- if (len == -1) {
- return len;
- }
- return std::max<int64_t>(0, len - mDataOffset);
- }
- nsresult ReadAt(int64_t aOffset, char* aBuffer,
- uint32_t aCount, uint32_t* aBytes)
- {
- return mResource.ReadAt(aOffset + mDataOffset,
- aBuffer,
- aCount,
- aBytes);
- }
- int64_t GetCachedDataEnd() {
- int64_t tell = mResource.GetResource()->Tell();
- int64_t dataEnd =
- mResource.GetResource()->GetCachedDataEnd(tell) - mDataOffset;
- return dataEnd;
- }
-private:
- // MediaResource from which we read data.
- MediaResourceIndex mResource;
- int64_t mDataOffset;
-};
-
-
-// Output pin for SourceFilter, which implements IAsyncReader, to
-// allow downstream filters to pull/read data from it. Downstream pins
-// register to read data using Request(), and asynchronously wait for the
-// reads to complete using WaitForNext(). They may also synchronously read
-// using SyncRead(). This class is a delegate (tear off) of
-// SourceFilter.
-//
-// We can expose only a segment of the MediaResource to the filter graph.
-// This is used to strip off the ID3v2 tags from the stream, as DirectShow
-// has trouble parsing some headers.
-//
-// Implements:
-// * IAsyncReader
-// * IPin
-// * IQualityControl
-// * IUnknown
-//
-class DECLSPEC_UUID("18e5cfb2-1015-440c-a65c-e63853235894")
-OutputPin : public IAsyncReader,
- public BasePin
-{
-public:
-
- OutputPin(MediaResource* aMediaResource,
- SourceFilter* aParent,
- CriticalSection& aFilterLock,
- int64_t aMP3DataStart);
- virtual ~OutputPin();
-
- // IUnknown
- // Defer to ref counting to BasePin, which defers to owning nsBaseFilter.
- STDMETHODIMP_(ULONG) AddRef() override { return BasePin::AddRef(); }
- STDMETHODIMP_(ULONG) Release() override { return BasePin::Release(); }
- STDMETHODIMP QueryInterface(REFIID iid, void** ppv) override;
-
- // BasePin Overrides.
- // Determines if the pin accepts a specific media type.
- HRESULT CheckMediaType(const MediaType* aMediaType) override;
-
- // Retrieves a preferred media type, by index value.
- HRESULT GetMediaType(int aPosition, MediaType* aMediaType) override;
-
- // Releases the pin from a connection.
- HRESULT BreakConnect(void) override;
-
- // Determines whether a pin connection is suitable.
- HRESULT CheckConnect(IPin* aPin) override;
-
-
- // IAsyncReader overrides
-
- // The RequestAllocator method requests an allocator during the
- // pin connection.
- STDMETHODIMP RequestAllocator(IMemAllocator* aPreferred,
- ALLOCATOR_PROPERTIES* aProps,
- IMemAllocator** aActual) override;
-
- // The Request method queues an asynchronous request for data. Downstream
- // will call WaitForNext() when they want to retrieve the result.
- STDMETHODIMP Request(IMediaSample* aSample, DWORD_PTR aUserData) override;
-
- // The WaitForNext method waits for the next pending read request
- // to complete. This method fails if the graph is flushing.
- // Defers to SyncRead/5.
- STDMETHODIMP WaitForNext(DWORD aTimeout,
- IMediaSample** aSamples,
- DWORD_PTR* aUserData) override;
-
- // The SyncReadAligned method performs a synchronous read. The method
- // blocks until the request is completed. Defers to SyncRead/5. This
- // method does not fail if the graph is flushing.
- STDMETHODIMP SyncReadAligned(IMediaSample* aSample) override;
-
- // The SyncRead method performs a synchronous read. The method blocks
- // until the request is completed. Defers to SyncRead/5. This
- // method does not fail if the graph is flushing.
- STDMETHODIMP SyncRead(LONGLONG aPosition, LONG aLength, BYTE* aBuffer) override;
-
- // The Length method retrieves the total length of the stream.
- STDMETHODIMP Length(LONGLONG* aTotal, LONGLONG* aAvailable) override;
-
- // IPin Overrides
- STDMETHODIMP BeginFlush(void) override;
- STDMETHODIMP EndFlush(void) override;
-
- uint32_t GetAndResetBytesConsumedCount();
-
-private:
-
- // Protects thread-shared data/structures (mFlushCount, mPendingReads).
- // WaitForNext() also waits on this monitor
- CriticalSection& mPinLock;
-
- // Signal used with mPinLock to implement WaitForNext().
- Signal mSignal;
-
- // The filter that owns us. Weak reference, as we're a delegate (tear off).
- SourceFilter* mParentSource;
-
- MediaResourcePartition mResource;
-
- // Counter, inc'd in BeginFlush(), dec'd in EndFlush(). Calls to this can
- // come from multiple threads and can interleave, hence the counter.
- int32_t mFlushCount;
-
- // Number of bytes that have been read from the output pin since the last
- // time GetAndResetBytesConsumedCount() was called.
- uint32_t mBytesConsumed;
-
- // Deque of ReadRequest* for reads that are yet to be serviced.
- // nsReadRequest's are stored on the heap, popper must delete them.
- nsDeque mPendingReads;
-
- // Flags if the downstream pin has QI'd for IAsyncReader. We refuse
- // connection if they don't query, as it means they're assuming that we're
- // a push filter, and we're not.
- bool mQueriedForAsyncReader;
-
-};
-
-// For mingw __uuidof support
-#ifdef __CRT_UUID_DECL
-}
-__CRT_UUID_DECL(mozilla::OutputPin, 0x18e5cfb2,0x1015,0x440c,0xa6,0x5c,0xe6,0x38,0x53,0x23,0x58,0x94);
-namespace mozilla {
-#endif
-
-OutputPin::OutputPin(MediaResource* aResource,
- SourceFilter* aParent,
- CriticalSection& aFilterLock,
- int64_t aMP3DataStart)
- : BasePin(static_cast<BaseFilter*>(aParent),
- &aFilterLock,
- L"MozillaOutputPin",
- PINDIR_OUTPUT),
- mPinLock(aFilterLock),
- mSignal(&mPinLock),
- mParentSource(aParent),
- mResource(aResource, aMP3DataStart),
- mFlushCount(0),
- mBytesConsumed(0),
- mQueriedForAsyncReader(false)
-{
- MOZ_COUNT_CTOR(OutputPin);
- DIRECTSHOW_LOG("OutputPin::OutputPin()");
-}
-
-OutputPin::~OutputPin()
-{
- MOZ_COUNT_DTOR(OutputPin);
- DIRECTSHOW_LOG("OutputPin::~OutputPin()");
-}
-
-HRESULT
-OutputPin::BreakConnect()
-{
- mQueriedForAsyncReader = false;
- return BasePin::BreakConnect();
-}
-
-STDMETHODIMP
-OutputPin::QueryInterface(REFIID aIId, void** aInterface)
-{
- if (aIId == IID_IAsyncReader) {
- mQueriedForAsyncReader = true;
- return DoGetInterface(static_cast<IAsyncReader*>(this), aInterface);
- }
-
- if (aIId == __uuidof(OutputPin)) {
- AddRef();
- *aInterface = this;
- return S_OK;
- }
-
- return BasePin::QueryInterface(aIId, aInterface);
-}
-
-HRESULT
-OutputPin::CheckConnect(IPin* aPin)
-{
- // Our connection is only suitable if the downstream pin knows
- // that we're asynchronous (i.e. it queried for IAsyncReader).
- return mQueriedForAsyncReader ? S_OK : S_FALSE;
-}
-
-HRESULT
-OutputPin::CheckMediaType(const MediaType* aMediaType)
-{
- const MediaType *myMediaType = mParentSource->GetMediaType();
-
- if (IsEqualGUID(aMediaType->majortype, myMediaType->majortype) &&
- IsEqualGUID(aMediaType->subtype, myMediaType->subtype) &&
- IsEqualGUID(aMediaType->formattype, myMediaType->formattype))
- {
- DIRECTSHOW_LOG("OutputPin::CheckMediaType() Match: major=%s minor=%s TC=%d FSS=%d SS=%u",
- GetDirectShowGuidName(aMediaType->majortype),
- GetDirectShowGuidName(aMediaType->subtype),
- aMediaType->TemporalCompression(),
- aMediaType->bFixedSizeSamples,
- aMediaType->SampleSize());
- return S_OK;
- }
-
- DIRECTSHOW_LOG("OutputPin::CheckMediaType() Failed to match: major=%s minor=%s TC=%d FSS=%d SS=%u",
- GetDirectShowGuidName(aMediaType->majortype),
- GetDirectShowGuidName(aMediaType->subtype),
- aMediaType->TemporalCompression(),
- aMediaType->bFixedSizeSamples,
- aMediaType->SampleSize());
- return S_FALSE;
-}
-
-HRESULT
-OutputPin::GetMediaType(int aPosition, MediaType* aMediaType)
-{
- if (!aMediaType)
- return E_POINTER;
-
- if (aPosition == 0) {
- aMediaType->Assign(mParentSource->GetMediaType());
- return S_OK;
- }
- return VFW_S_NO_MORE_ITEMS;
-}
-
-static inline bool
-IsPowerOf2(int32_t x) {
- return ((-x & x) != x);
-}
-
-STDMETHODIMP
-OutputPin::RequestAllocator(IMemAllocator* aPreferred,
- ALLOCATOR_PROPERTIES* aProps,
- IMemAllocator** aActual)
-{
- // Require the downstream pin to suggest what they want...
- if (!aPreferred) return E_POINTER;
- if (!aProps) return E_POINTER;
- if (!aActual) return E_POINTER;
-
- // We only care about alignment - our allocator will reject anything
- // which isn't power-of-2 aligned, so so try a 4-byte aligned allocator.
- ALLOCATOR_PROPERTIES props;
- memcpy(&props, aProps, sizeof(ALLOCATOR_PROPERTIES));
- if (aProps->cbAlign == 0 || IsPowerOf2(aProps->cbAlign)) {
- props.cbAlign = 4;
- }
-
- // Limit allocator's number of buffers. We know that the media will most
- // likely be bound by network speed, not by decoding speed. We also
- // store the incoming data in a Gecko stream, if we don't limit buffers
- // here we'll end up duplicating a lot of storage. We must have enough
- // space for audio key frames to fit in the first batch of buffers however,
- // else pausing may fail for some downstream decoders.
- if (props.cBuffers > BaseFilter::sMaxNumBuffers) {
- props.cBuffers = BaseFilter::sMaxNumBuffers;
- }
-
- // The allocator properties that are actually used. We don't store
- // this, we need it for SetProperties() below to succeed.
- ALLOCATOR_PROPERTIES actualProps;
- HRESULT hr;
-
- if (aPreferred) {
- // Play nice and prefer the downstream pin's preferred allocator.
- hr = aPreferred->SetProperties(&props, &actualProps);
- if (SUCCEEDED(hr)) {
- aPreferred->AddRef();
- *aActual = aPreferred;
- return S_OK;
- }
- }
-
- // Else downstream hasn't requested a specific allocator, so create one...
-
- // Just create a default allocator. It's highly unlikely that we'll use
- // this anyway, as most parsers insist on using their own allocators.
- RefPtr<IMemAllocator> allocator;
- hr = CoCreateInstance(CLSID_MemoryAllocator,
- 0,
- CLSCTX_INPROC_SERVER,
- IID_IMemAllocator,
- getter_AddRefs(allocator));
- if(FAILED(hr) || (allocator == nullptr)) {
- NS_WARNING("Can't create our own DirectShow allocator.");
- return hr;
- }
-
- // See if we can make it suitable
- hr = allocator->SetProperties(&props, &actualProps);
- if (SUCCEEDED(hr)) {
- // We need to release our refcount on pAlloc, and addref
- // it to pass a refcount to the caller - this is a net nothing.
- allocator.forget(aActual);
- return S_OK;
- }
-
- NS_WARNING("Failed to pick an allocator");
- return hr;
-}
-
-STDMETHODIMP
-OutputPin::Request(IMediaSample* aSample, DWORD_PTR aDwUser)
-{
- if (!aSample) return E_FAIL;
-
- CriticalSectionAutoEnter lock(*mLock);
- NS_ASSERTION(!mFlushCount, "Request() while flushing");
-
- if (mFlushCount)
- return VFW_E_WRONG_STATE;
-
- REFERENCE_TIME refStart = 0, refEnd = 0;
- if (FAILED(aSample->GetTime(&refStart, &refEnd))) {
- NS_WARNING("Sample incorrectly timestamped");
- return VFW_E_SAMPLE_TIME_NOT_SET;
- }
-
- // Convert reference time to bytes.
- uint32_t start = (uint32_t)(refStart / 10000000);
- uint32_t end = (uint32_t)(refEnd / 10000000);
-
- uint32_t numBytes = end - start;
-
- ReadRequest* request = new ReadRequest(aSample,
- aDwUser,
- start,
- numBytes);
- // Memory for |request| is free when it's popped from the completed
- // reads list.
-
- // Push this onto the queue of reads to be serviced.
- mPendingReads.Push(request);
-
- // Notify any threads blocked in WaitForNext() which are waiting for mPendingReads
- // to become non-empty.
- mSignal.Notify();
-
- return S_OK;
-}
-
-STDMETHODIMP
-OutputPin::WaitForNext(DWORD aTimeout,
- IMediaSample** aOutSample,
- DWORD_PTR* aOutDwUser)
-{
- NS_ASSERTION(aTimeout == 0 || aTimeout == INFINITE,
- "Oops, we don't handle this!");
-
- *aOutSample = nullptr;
- *aOutDwUser = 0;
-
- LONGLONG offset = 0;
- LONG count = 0;
- BYTE* buf = nullptr;
-
- {
- CriticalSectionAutoEnter lock(*mLock);
-
- // Wait until there's a pending read to service.
- while (aTimeout && mPendingReads.GetSize() == 0 && !mFlushCount) {
- // Note: No need to guard against shutdown-during-wait here, as
- // typically the thread doing the pull will have already called
- // Request(), so we won't Wait() here anyway. SyncRead() will fail
- // on shutdown.
- mSignal.Wait();
- }
-
- nsAutoPtr<ReadRequest> request(reinterpret_cast<ReadRequest*>(mPendingReads.PopFront()));
- if (!request)
- return VFW_E_WRONG_STATE;
-
- *aOutSample = request->mSample;
- *aOutDwUser = request->mDwUser;
-
- offset = request->mOffset;
- count = request->mCount;
- buf = nullptr;
- request->mSample->GetPointer(&buf);
- NS_ASSERTION(buf != nullptr, "Invalid buffer!");
-
- if (mFlushCount) {
- return VFW_E_TIMEOUT;
- }
- }
-
- return SyncRead(offset, count, buf);
-}
-
-STDMETHODIMP
-OutputPin::SyncReadAligned(IMediaSample* aSample)
-{
- {
- // Ignore reads while flushing.
- CriticalSectionAutoEnter lock(*mLock);
- if (mFlushCount) {
- return S_FALSE;
- }
- }
-
- if (!aSample)
- return E_FAIL;
-
- REFERENCE_TIME lStart = 0, lEnd = 0;
- if (FAILED(aSample->GetTime(&lStart, &lEnd))) {
- NS_WARNING("Sample incorrectly timestamped");
- return VFW_E_SAMPLE_TIME_NOT_SET;
- }
-
- // Convert reference time to bytes.
- int32_t start = (int32_t)(lStart / 10000000);
- int32_t end = (int32_t)(lEnd / 10000000);
-
- int32_t numBytes = end - start;
-
- // If the range extends off the end of stream, truncate to the end of stream
- // as per IAsyncReader specificiation.
- int64_t streamLength = mResource.GetLength();
- if (streamLength != -1) {
- // We know the exact length of the stream, fail if the requested offset
- // is beyond it.
- if (start > streamLength) {
- return VFW_E_BADALIGN;
- }
-
- // If the end of the chunk to read is off the end of the stream,
- // truncate it to the end of the stream.
- if ((start + numBytes) > streamLength) {
- numBytes = (uint32_t)(streamLength - start);
- }
- }
-
- BYTE* buf=0;
- aSample->GetPointer(&buf);
-
- return SyncRead(start, numBytes, buf);
-}
-
-STDMETHODIMP
-OutputPin::SyncRead(LONGLONG aPosition,
- LONG aLength,
- BYTE* aBuffer)
-{
- MOZ_ASSERT(!NS_IsMainThread());
- NS_ENSURE_TRUE(aPosition >= 0, E_FAIL);
- NS_ENSURE_TRUE(aLength > 0, E_FAIL);
- NS_ENSURE_TRUE(aBuffer, E_POINTER);
-
- DIRECTSHOW_LOG("OutputPin::SyncRead(%lld, %d)", aPosition, aLength);
- {
- // Ignore reads while flushing.
- CriticalSectionAutoEnter lock(*mLock);
- if (mFlushCount) {
- return S_FALSE;
- }
- }
-
- uint32_t totalBytesRead = 0;
- nsresult rv = mResource.ReadAt(aPosition,
- reinterpret_cast<char*>(aBuffer),
- aLength,
- &totalBytesRead);
- if (NS_FAILED(rv)) {
- return E_FAIL;
- }
- if (totalBytesRead > 0) {
- CriticalSectionAutoEnter lock(*mLock);
- mBytesConsumed += totalBytesRead;
- }
- return (totalBytesRead == aLength) ? S_OK : S_FALSE;
-}
-
-STDMETHODIMP
-OutputPin::Length(LONGLONG* aTotal, LONGLONG* aAvailable)
-{
- HRESULT hr = S_OK;
- int64_t length = mResource.GetLength();
- if (length == -1) {
- hr = VFW_S_ESTIMATED;
- // Don't have a length. Just lie, it seems to work...
- *aTotal = INT32_MAX;
- } else {
- *aTotal = length;
- }
- if (aAvailable) {
- *aAvailable = mResource.GetCachedDataEnd();
- }
-
- DIRECTSHOW_LOG("OutputPin::Length() len=%lld avail=%lld", *aTotal, *aAvailable);
-
- return hr;
-}
-
-STDMETHODIMP
-OutputPin::BeginFlush()
-{
- CriticalSectionAutoEnter lock(*mLock);
- mFlushCount++;
- mSignal.Notify();
- return S_OK;
-}
-
-STDMETHODIMP
-OutputPin::EndFlush(void)
-{
- CriticalSectionAutoEnter lock(*mLock);
- mFlushCount--;
- return S_OK;
-}
-
-uint32_t
-OutputPin::GetAndResetBytesConsumedCount()
-{
- CriticalSectionAutoEnter lock(*mLock);
- uint32_t bytesConsumed = mBytesConsumed;
- mBytesConsumed = 0;
- return bytesConsumed;
-}
-
-SourceFilter::SourceFilter(const GUID& aMajorType,
- const GUID& aSubType)
- : BaseFilter(L"MozillaDirectShowSource", __uuidof(SourceFilter))
-{
- MOZ_COUNT_CTOR(SourceFilter);
- mMediaType.majortype = aMajorType;
- mMediaType.subtype = aSubType;
-
- DIRECTSHOW_LOG("SourceFilter Constructor(%s, %s)",
- GetDirectShowGuidName(aMajorType),
- GetDirectShowGuidName(aSubType));
-}
-
-SourceFilter::~SourceFilter()
-{
- MOZ_COUNT_DTOR(SourceFilter);
- DIRECTSHOW_LOG("SourceFilter Destructor()");
-}
-
-BasePin*
-SourceFilter::GetPin(int n)
-{
- if (n == 0) {
- NS_ASSERTION(mOutputPin != 0, "GetPin with no pin!");
- return static_cast<BasePin*>(mOutputPin);
- } else {
- return nullptr;
- }
-}
-
-// Get's the media type we're supplying.
-const MediaType*
-SourceFilter::GetMediaType() const
-{
- return &mMediaType;
-}
-
-nsresult
-SourceFilter::Init(MediaResource* aResource, int64_t aMP3Offset)
-{
- DIRECTSHOW_LOG("SourceFilter::Init()");
-
- mOutputPin = new OutputPin(aResource,
- this,
- mLock,
- aMP3Offset);
- NS_ENSURE_TRUE(mOutputPin != nullptr, NS_ERROR_FAILURE);
-
- return NS_OK;
-}
-
-uint32_t
-SourceFilter::GetAndResetBytesConsumedCount()
-{
- return mOutputPin->GetAndResetBytesConsumedCount();
-}
-
-
-} // namespace mozilla
diff --git a/dom/media/directshow/SourceFilter.h b/dom/media/directshow/SourceFilter.h
deleted file mode 100644
index d5ce2770e..000000000
--- a/dom/media/directshow/SourceFilter.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#if !defined(nsDirectShowSource_h___)
-#define nsDirectShowSource_h___
-
-#include "BaseFilter.h"
-#include "BasePin.h"
-#include "MediaType.h"
-
-#include "nsDeque.h"
-#include "nsAutoPtr.h"
-#include "DirectShowUtils.h"
-#include "mozilla/RefPtr.h"
-
-namespace mozilla {
-
-class MediaResource;
-class OutputPin;
-
-
-// SourceFilter is an asynchronous DirectShow source filter which
-// reads from an MediaResource, and supplies data via a pull model downstream
-// using OutputPin. It us used to supply a generic byte stream into
-// DirectShow.
-//
-// Implements:
-// * IBaseFilter
-// * IMediaFilter
-// * IPersist
-// * IUnknown
-//
-class DECLSPEC_UUID("5c2a7ad0-ba82-4659-9178-c4719a2765d6")
-SourceFilter : public media::BaseFilter
-{
-public:
-
- // Constructs source filter to deliver given media type.
- SourceFilter(const GUID& aMajorType, const GUID& aSubType);
- ~SourceFilter();
-
- nsresult Init(MediaResource *aResource, int64_t aMP3Offset);
-
- // BaseFilter overrides.
- // Only one output - the byte stream.
- int GetPinCount() override { return 1; }
-
- media::BasePin* GetPin(int n) override;
-
- // Get's the media type we're supplying.
- const media::MediaType* GetMediaType() const;
-
- uint32_t GetAndResetBytesConsumedCount();
-
-protected:
-
- // Our async pull output pin.
- nsAutoPtr<OutputPin> mOutputPin;
-
- // Type of byte stream we output.
- media::MediaType mMediaType;
-
-};
-
-} // namespace mozilla
-
-// For mingw __uuidof support
-#ifdef __CRT_UUID_DECL
-__CRT_UUID_DECL(mozilla::SourceFilter, 0x5c2a7ad0,0xba82,0x4659,0x91,0x78,0xc4,0x71,0x9a,0x27,0x65,0xd6);
-#endif
-
-#endif
diff --git a/dom/media/directshow/moz.build b/dom/media/directshow/moz.build
deleted file mode 100644
index 8a9b76200..000000000
--- a/dom/media/directshow/moz.build
+++ /dev/null
@@ -1,41 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-EXPORTS += [
- 'AudioSinkFilter.h',
- 'AudioSinkInputPin.h',
- 'DirectShowDecoder.h',
- 'DirectShowReader.h',
- 'DirectShowUtils.h',
-]
-
-UNIFIED_SOURCES += [
- 'DirectShowDecoder.cpp',
- 'DirectShowUtils.cpp',
- 'SourceFilter.cpp',
-]
-
-SOURCES += [
- 'AudioSinkFilter.cpp',
- 'AudioSinkInputPin.cpp',
- 'DirectShowReader.cpp',
- 'SampleSink.cpp',
-]
-
-# If WebRTC isn't being built, we need to compile the DirectShow base classes so that
-# they're available at link time.
-if not CONFIG['MOZ_WEBRTC']:
- SOURCES += [
- '/media/webrtc/trunk/webrtc/modules/video_capture/windows/BaseFilter.cpp',
- '/media/webrtc/trunk/webrtc/modules/video_capture/windows/BaseInputPin.cpp',
- '/media/webrtc/trunk/webrtc/modules/video_capture/windows/BasePin.cpp',
- '/media/webrtc/trunk/webrtc/modules/video_capture/windows/MediaType.cpp',
- ]
-
-FINAL_LIBRARY = 'xul'
-LOCAL_INCLUDES += [
- '/media/webrtc/trunk/webrtc/modules/video_capture/windows',
-]
diff --git a/dom/media/eme/DetailedPromise.cpp b/dom/media/eme/DetailedPromise.cpp
index 5893bea2e..d443e3336 100644
--- a/dom/media/eme/DetailedPromise.cpp
+++ b/dom/media/eme/DetailedPromise.cpp
@@ -96,9 +96,6 @@ DetailedPromise::MaybeReportTelemetry(Status aStatus)
uint32_t latency = (TimeStamp::Now() - mStartTime).ToMilliseconds();
EME_LOG("%s %s latency %ums reported via telemetry", mName.get(),
((aStatus == Succeeded) ? "succcess" : "failure"), latency);
- Telemetry::ID tid = (aStatus == Succeeded) ? mSuccessLatencyProbe.Value()
- : mFailureLatencyProbe.Value();
- Telemetry::Accumulate(tid, latency);
}
} // namespace dom
diff --git a/dom/media/eme/MediaKeySession.cpp b/dom/media/eme/MediaKeySession.cpp
index d5eff3f77..9c002b5ba 100644
--- a/dom/media/eme/MediaKeySession.cpp
+++ b/dom/media/eme/MediaKeySession.cpp
@@ -315,9 +315,6 @@ MediaKeySession::GenerateRequest(const nsAString& aInitDataType,
// Note: Remaining steps of generateRequest method continue in CDM.
- Telemetry::Accumulate(Telemetry::VIDEO_CDM_GENERATE_REQUEST_CALLED,
- ToCDMTypeTelemetryEnum(mKeySystem));
-
// Convert initData to base64 for easier logging.
// Note: CreateSession() Move()s the data out of the array, so we have
// to copy it here.
diff --git a/dom/media/eme/MediaKeys.cpp b/dom/media/eme/MediaKeys.cpp
index eedd675e4..fea548698 100644
--- a/dom/media/eme/MediaKeys.cpp
+++ b/dom/media/eme/MediaKeys.cpp
@@ -13,7 +13,6 @@
#include "mozilla/dom/MediaKeySession.h"
#include "mozilla/dom/DOMException.h"
#include "mozilla/dom/UnionTypes.h"
-#include "mozilla/Telemetry.h"
#include "GMPCDMProxy.h"
#ifdef MOZ_WIDGET_ANDROID
#include "mozilla/MediaDrmCDMProxy.h"
@@ -457,7 +456,6 @@ MediaKeys::OnCDMCreated(PromiseId aId, const nsACString& aNodeId, const uint32_t
mKeySystem,
MediaKeySystemStatus::Cdm_created);
- Telemetry::Accumulate(Telemetry::VIDEO_CDM_CREATED, ToCDMTypeTelemetryEnum(mKeySystem));
}
static bool
diff --git a/dom/media/fmp4/MP4Decoder.cpp b/dom/media/fmp4/MP4Decoder.cpp
index fdd6f2c7e..6954e9757 100644
--- a/dom/media/fmp4/MP4Decoder.cpp
+++ b/dom/media/fmp4/MP4Decoder.cpp
@@ -83,10 +83,6 @@ MP4Decoder::CanHandleMediaType(const MediaContentType& aType,
const bool isMP4Audio = aType.GetMIMEType().EqualsASCII("audio/mp4") ||
aType.GetMIMEType().EqualsASCII("audio/x-m4a");
const bool isMP4Video =
- // On B2G, treat 3GPP as MP4 when Gonk PDM is available.
-#ifdef MOZ_GONK_MEDIACODEC
- aType.GetMIMEType().EqualsASCII(VIDEO_3GPP) ||
-#endif
aType.GetMIMEType().EqualsASCII("video/mp4") ||
aType.GetMIMEType().EqualsASCII("video/quicktime") ||
aType.GetMIMEType().EqualsASCII("video/x-m4v");
@@ -139,6 +135,14 @@ MP4Decoder::CanHandleMediaType(const MediaContentType& aType,
NS_LITERAL_CSTRING("audio/flac"), aType));
continue;
}
+#ifdef MOZ_AV1
+ if (IsAV1CodecString(codec)) {
+ trackInfos.AppendElement(
+ CreateTrackInfoWithMIMETypeAndContentTypeExtraParameters(
+ NS_LITERAL_CSTRING("video/av1"), aType));
+ continue;
+ }
+#endif
// Note: Only accept H.264 in a video content type, not in an audio
// content type.
if (IsWhitelistedH264Codec(codec) && isMP4Video) {
diff --git a/dom/media/fmp4/MP4Demuxer.cpp b/dom/media/fmp4/MP4Demuxer.cpp
index 646897468..ef68d5dca 100644
--- a/dom/media/fmp4/MP4Demuxer.cpp
+++ b/dom/media/fmp4/MP4Demuxer.cpp
@@ -16,9 +16,6 @@
#include "mp4_demuxer/Index.h"
#include "nsPrintfCString.h"
-// Used for telemetry
-#include "mozilla/Telemetry.h"
-#include "mp4_demuxer/AnnexB.h"
#include "mp4_demuxer/H264.h"
#include "nsAutoPtr.h"
@@ -72,47 +69,10 @@ private:
// Queued samples extracted by the demuxer, but not yet returned.
RefPtr<MediaRawData> mQueuedSample;
bool mNeedReIndex;
- bool mNeedSPSForTelemetry;
bool mIsH264 = false;
};
-// Returns true if no SPS was found and search for it should continue.
-bool
-AccumulateSPSTelemetry(const MediaByteBuffer* aExtradata)
-{
- mp4_demuxer::SPSData spsdata;
- if (mp4_demuxer::H264::DecodeSPSFromExtraData(aExtradata, spsdata)) {
- uint8_t constraints = (spsdata.constraint_set0_flag ? (1 << 0) : 0) |
- (spsdata.constraint_set1_flag ? (1 << 1) : 0) |
- (spsdata.constraint_set2_flag ? (1 << 2) : 0) |
- (spsdata.constraint_set3_flag ? (1 << 3) : 0) |
- (spsdata.constraint_set4_flag ? (1 << 4) : 0) |
- (spsdata.constraint_set5_flag ? (1 << 5) : 0);
- Telemetry::Accumulate(Telemetry::VIDEO_DECODED_H264_SPS_CONSTRAINT_SET_FLAG,
- constraints);
-
- // Collect profile_idc values up to 244, otherwise 0 for unknown.
- Telemetry::Accumulate(Telemetry::VIDEO_DECODED_H264_SPS_PROFILE,
- spsdata.profile_idc <= 244 ? spsdata.profile_idc : 0);
-
- // Make sure level_idc represents a value between levels 1 and 5.2,
- // otherwise collect 0 for unknown level.
- Telemetry::Accumulate(Telemetry::VIDEO_DECODED_H264_SPS_LEVEL,
- (spsdata.level_idc >= 10 && spsdata.level_idc <= 52) ?
- spsdata.level_idc : 0);
-
- // max_num_ref_frames should be between 0 and 16, anything larger will
- // be treated as invalid.
- Telemetry::Accumulate(Telemetry::VIDEO_H264_SPS_MAX_NUM_REF_FRAMES,
- std::min(spsdata.max_num_ref_frames, 17u));
-
- return false;
- }
-
- return true;
-}
-
MP4Demuxer::MP4Demuxer(MediaResource* aResource)
: mResource(aResource)
, mStream(new mp4_demuxer::ResourceStream(aResource))
@@ -243,25 +203,10 @@ MP4TrackDemuxer::MP4TrackDemuxer(MP4Demuxer* aParent,
EnsureUpToDateIndex(); // Force update of index
VideoInfo* videoInfo = mInfo->GetAsVideoInfo();
- // Collect telemetry from h264 AVCC SPS.
if (videoInfo &&
(mInfo->mMimeType.EqualsLiteral("video/mp4") ||
mInfo->mMimeType.EqualsLiteral("video/avc"))) {
mIsH264 = true;
- RefPtr<MediaByteBuffer> extraData = videoInfo->mExtraData;
- mNeedSPSForTelemetry = AccumulateSPSTelemetry(extraData);
- mp4_demuxer::SPSData spsdata;
- if (mp4_demuxer::H264::DecodeSPSFromExtraData(extraData, spsdata) &&
- spsdata.pic_width > 0 && spsdata.pic_height > 0 &&
- mp4_demuxer::H264::EnsureSPSIsSane(spsdata)) {
- videoInfo->mImage.width = spsdata.pic_width;
- videoInfo->mImage.height = spsdata.pic_height;
- videoInfo->mDisplay.width = spsdata.display_width;
- videoInfo->mDisplay.height = spsdata.display_height;
- }
- } else {
- // No SPS to be found.
- mNeedSPSForTelemetry = false;
}
}
@@ -388,15 +333,6 @@ MP4TrackDemuxer::GetSamples(int32_t aNumSamples)
if (samples->mSamples.IsEmpty()) {
return SamplesPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_END_OF_STREAM, __func__);
} else {
- for (const auto& sample : samples->mSamples) {
- // Collect telemetry from h264 Annex B SPS.
- if (mNeedSPSForTelemetry && mp4_demuxer::AnnexB::HasSPS(sample)) {
- RefPtr<MediaByteBuffer> extradata =
- mp4_demuxer::AnnexB::ExtractExtraData(sample);
- mNeedSPSForTelemetry = AccumulateSPSTelemetry(extradata);
- }
- }
-
if (mNextKeyframeTime.isNothing() ||
samples->mSamples.LastElement()->mTime >= mNextKeyframeTime.value().ToMicroseconds()) {
SetNextKeyFrameTime();
diff --git a/dom/media/fmp4/MP4Stream.cpp b/dom/media/fmp4/MP4Stream.cpp
index 615a7dc01..9a79cac7a 100644
--- a/dom/media/fmp4/MP4Stream.cpp
+++ b/dom/media/fmp4/MP4Stream.cpp
@@ -48,9 +48,6 @@ MP4Stream::BlockingReadIntoCache(int64_t aOffset, size_t aCount, Monitor* aToUnl
return true;
}
-// We surreptitiously reimplement the supposedly-blocking ReadAt as a non-
-// blocking CachedReadAt, and record when it fails. This allows MP4Reader
-// to retry the read as an actual blocking read without holding the lock.
bool
MP4Stream::ReadAt(int64_t aOffset, void* aBuffer, size_t aCount,
size_t* aBytesRead)
diff --git a/dom/media/fmp4/moz.build b/dom/media/fmp4/moz.build
index 6a249ae3e..a79fb0229 100644
--- a/dom/media/fmp4/moz.build
+++ b/dom/media/fmp4/moz.build
@@ -20,6 +20,3 @@ SOURCES += [
]
FINAL_LIBRARY = 'xul'
-
-if CONFIG['MOZ_GONK_MEDIACODEC']:
- DEFINES['MOZ_GONK_MEDIACODEC'] = True
diff --git a/dom/media/gmp/GMPParent.cpp b/dom/media/gmp/GMPParent.cpp
index 40c3e5141..418f14736 100644
--- a/dom/media/gmp/GMPParent.cpp
+++ b/dom/media/gmp/GMPParent.cpp
@@ -516,8 +516,7 @@ GMPCapability::Supports(const nsTArray<GMPCapability>& aCapabilities,
#ifdef XP_WIN
// Clearkey on Windows advertises that it can decode in its GMP info
// file, but uses Windows Media Foundation to decode. That's not present
- // on Windows XP, and on some Vista, Windows N, and KN variants without
- // certain services packs.
+ // on Windows N and KN variants without certain services packs.
if (tag.Equals(kEMEKeySystemClearkey)) {
if (capabilities.mAPIName.EqualsLiteral(GMP_API_VIDEO_DECODER)) {
if (!WMFDecoderModule::HasH264()) {
diff --git a/dom/media/gmp/widevine-adapter/WidevineAdapter.cpp b/dom/media/gmp/widevine-adapter/WidevineAdapter.cpp
index 74b5c38e8..57d4ecec2 100644
--- a/dom/media/gmp/widevine-adapter/WidevineAdapter.cpp
+++ b/dom/media/gmp/widevine-adapter/WidevineAdapter.cpp
@@ -46,7 +46,7 @@ void* GetCdmHost(int aHostInterfaceVersion, void* aUserData)
Log("GetCdmHostFunc(%d, %p)", aHostInterfaceVersion, aUserData);
WidevineDecryptor* decryptor = reinterpret_cast<WidevineDecryptor*>(aUserData);
MOZ_ASSERT(decryptor);
- return static_cast<cdm::Host_8*>(decryptor);
+ return static_cast<cdm::Host_9*>(decryptor);
}
#define STRINGIFY(s) _STRINGIFY(s)
@@ -106,8 +106,8 @@ WidevineAdapter::GMPGetAPI(const char* aAPIName,
WidevineDecryptor* decryptor = new WidevineDecryptor();
- auto cdm = reinterpret_cast<cdm::ContentDecryptionModule*>(
- create(cdm::ContentDecryptionModule::kVersion,
+ auto cdm = reinterpret_cast<cdm::ContentDecryptionModule_9*>(
+ create(cdm::ContentDecryptionModule_9::kVersion,
kEMEKeySystemWidevine.get(),
kEMEKeySystemWidevine.Length(),
&GetCdmHost,
@@ -161,8 +161,8 @@ WidevineAdapter::Supports(int32_t aModuleVersion,
int32_t aHostVersion)
{
return aModuleVersion == CDM_MODULE_VERSION &&
- aInterfaceVersion == cdm::ContentDecryptionModule::kVersion &&
- aHostVersion == cdm::Host_8::kVersion;
+ aInterfaceVersion == cdm::ContentDecryptionModule_9::kVersion &&
+ aHostVersion == cdm::Host_9::kVersion;
}
} // namespace mozilla
diff --git a/dom/media/gmp/widevine-adapter/WidevineDecryptor.cpp b/dom/media/gmp/widevine-adapter/WidevineDecryptor.cpp
index 149fa1701..4d3408804 100644
--- a/dom/media/gmp/widevine-adapter/WidevineDecryptor.cpp
+++ b/dom/media/gmp/widevine-adapter/WidevineDecryptor.cpp
@@ -102,7 +102,7 @@ WidevineDecryptor::CreateSession(uint32_t aCreateSessionToken,
} else {
// Invalid init data type
const char* errorMsg = "Invalid init data type when creating session.";
- OnRejectPromise(aPromiseId, kNotSupportedError, 0, errorMsg, sizeof(errorMsg));
+ OnRejectPromise(aPromiseId, kExceptionNotSupportedError, 0, errorMsg, sizeof(errorMsg));
return;
}
mPromiseIdToNewSessionTokens[aPromiseId] = aCreateSessionToken;
@@ -302,6 +302,12 @@ WidevineDecryptor::GetCurrentWallTime()
}
void
+WidevineDecryptor::OnResolveKeyStatusPromise(uint32_t aPromiseId,
+ cdm::KeyStatus aKeyStatus) {
+ //TODO: The callback of GetStatusForPolicy. See Mozilla bug 1404230.
+}
+
+void
WidevineDecryptor::OnResolveNewSessionPromise(uint32_t aPromiseId,
const char* aSessionId,
uint32_t aSessionIdSize)
@@ -333,41 +339,59 @@ WidevineDecryptor::OnResolvePromise(uint32_t aPromiseId)
}
static GMPDOMException
-ToGMPDOMException(cdm::Error aError)
-{
- switch (aError) {
- case kNotSupportedError: return kGMPNotSupportedError;
- case kInvalidStateError: return kGMPInvalidStateError;
- case kInvalidAccessError:
- // Note: Chrome converts kInvalidAccessError to TypeError, since the
- // Chromium CDM API doesn't have a type error enum value. The EME spec
- // requires TypeError in some places, so we do the same conversion.
- // See bug 1313202.
- return kGMPTypeError;
- case kQuotaExceededError: return kGMPQuotaExceededError;
+ConvertCDMExceptionToGMPDOMException(cdm::Exception aException)
+{
+ switch (aException) {
+ case kExceptionNotSupportedError: return kGMPNotSupportedError;
+ case kExceptionInvalidStateError: return kGMPInvalidStateError;
+ case kExceptionTypeError: return kGMPTypeError;
+ case kExceptionQuotaExceededError: return kGMPQuotaExceededError;
case kUnknownError: return kGMPInvalidModificationError; // Note: Unique placeholder.
case kClientError: return kGMPAbortError; // Note: Unique placeholder.
case kOutputError: return kGMPSecurityError; // Note: Unique placeholder.
};
- return kGMPTimeoutError; // Note: Unique placeholder.
+ return kGMPInvalidStateError; // Note: Unique placeholder.
+}
+
+// Align with spec, the Exceptions used by CDM to reject promises .
+// https://w3c.github.io/encrypted-media/#exceptions
+cdm::Exception
+ConvertCDMErrorToCDMException(cdm::Error error) {
+ switch (error) {
+ case cdm::kNotSupportedError:
+ return cdm::Exception::kExceptionNotSupportedError;
+ case cdm::kInvalidStateError:
+ return cdm::Exception::kExceptionInvalidStateError;
+ case cdm::kInvalidAccessError:
+ return cdm::Exception::kExceptionTypeError;
+ case cdm::kQuotaExceededError:
+ return cdm::Exception::kExceptionQuotaExceededError;
+
+ case cdm::kUnknownError:
+ case cdm::kClientError:
+ case cdm::kOutputError:
+ break;
+ }
+
+ return cdm::Exception::kExceptionInvalidStateError;
}
void
WidevineDecryptor::OnRejectPromise(uint32_t aPromiseId,
- Error aError,
+ cdm::Exception aException,
uint32_t aSystemCode,
const char* aErrorMessage,
uint32_t aErrorMessageSize)
{
if (!mCallback) {
Log("Decryptor::OnRejectPromise(aPromiseId=%d, err=%d, sysCode=%u, msg=%s) FAIL; !mCallback",
- aPromiseId, (int)aError, aSystemCode, aErrorMessage);
+ aPromiseId, (int)aException, aSystemCode, aErrorMessage);
return;
}
Log("Decryptor::OnRejectPromise(aPromiseId=%d, err=%d, sysCode=%u, msg=%s)",
- aPromiseId, (int)aError, aSystemCode, aErrorMessage);
+ aPromiseId, (int)aException, aSystemCode, aErrorMessage);
mCallback->RejectPromise(aPromiseId,
- ToGMPDOMException(aError),
+ ConvertCDMExceptionToGMPDOMException(aException),
!aErrorMessageSize ? "" : aErrorMessage,
aErrorMessageSize);
}
@@ -386,11 +410,9 @@ ToGMPMessageType(MessageType message_type)
void
WidevineDecryptor::OnSessionMessage(const char* aSessionId,
uint32_t aSessionIdSize,
- MessageType aMessageType,
+ cdm::MessageType aMessageType,
const char* aMessage,
- uint32_t aMessageSize,
- const char* aLegacyDestinationUrl,
- uint32_t aLegacyDestinationUrlLength)
+ uint32_t aMessageSize)
{
if (!mCallback) {
Log("Decryptor::OnSessionMessage() FAIL; !mCallback");
@@ -479,28 +501,6 @@ WidevineDecryptor::OnSessionClosed(const char* aSessionId,
}
void
-WidevineDecryptor::OnLegacySessionError(const char* aSessionId,
- uint32_t aSessionIdLength,
- Error aError,
- uint32_t aSystemCode,
- const char* aErrorMessage,
- uint32_t aErrorMessageLength)
-{
- if (!mCallback) {
- Log("Decryptor::OnLegacySessionError(sid=%s, error=%d) FAIL; !mCallback",
- aSessionId, (int)aError);
- return;
- }
- Log("Decryptor::OnLegacySessionError(sid=%s, error=%d)", aSessionId, (int)aError);
- mCallback->SessionError(aSessionId,
- aSessionIdLength,
- ToGMPDOMException(aError),
- aSystemCode,
- aErrorMessage,
- aErrorMessageLength);
-}
-
-void
WidevineDecryptor::SendPlatformChallenge(const char* aServiceId,
uint32_t aServiceIdSize,
const char* aChallenge,
@@ -538,4 +538,17 @@ WidevineDecryptor::CreateFileIO(FileIOClient* aClient)
return new WidevineFileIO(aClient);
}
+void
+WidevineDecryptor::RequestStorageId(uint32_t aVersion)
+{
+ Log("Decryptor::RequestStorageId() aVersion = %u", aVersion);
+ if (aVersion >= 0x80000000) {
+ mCDM->OnStorageId(aVersion, nullptr, 0);
+ return;
+ }
+
+ //TODO: Need to provide a menaingful buffer instead of a dummy one.
+ mCDM->OnStorageId(aVersion, new uint8_t[1024*1024], 1024 * 1024);
+}
+
} // namespace mozilla
diff --git a/dom/media/gmp/widevine-adapter/WidevineDecryptor.h b/dom/media/gmp/widevine-adapter/WidevineDecryptor.h
index d5185192b..f291c321d 100644
--- a/dom/media/gmp/widevine-adapter/WidevineDecryptor.h
+++ b/dom/media/gmp/widevine-adapter/WidevineDecryptor.h
@@ -16,7 +16,7 @@
namespace mozilla {
class WidevineDecryptor : public GMPDecryptor
- , public cdm::Host_8
+ , public cdm::Host_9
{
public:
@@ -69,16 +69,19 @@ public:
void DecryptingComplete() override;
- // cdm::Host_8
+ // cdm::Host_9 implementation
cdm::Buffer* Allocate(uint32_t aCapacity) override;
void SetTimer(int64_t aDelayMs, void* aContext) override;
cdm::Time GetCurrentWallTime() override;
+ // cdm::Host_9 interface
+ void OnResolveKeyStatusPromise(uint32_t aPromiseId,
+ cdm::KeyStatus aKeyStatus) override;
void OnResolveNewSessionPromise(uint32_t aPromiseId,
const char* aSessionId,
uint32_t aSessionIdSize) override;
void OnResolvePromise(uint32_t aPromiseId) override;
void OnRejectPromise(uint32_t aPromiseId,
- cdm::Error aError,
+ cdm::Exception aException,
uint32_t aSystemCode,
const char* aErrorMessage,
uint32_t aErrorMessageSize) override;
@@ -86,9 +89,7 @@ public:
uint32_t aSessionIdSize,
cdm::MessageType aMessageType,
const char* aMessage,
- uint32_t aMessageSize,
- const char* aLegacyDestinationUrl,
- uint32_t aLegacyDestinationUrlLength) override;
+ uint32_t aMessageSize) override;
void OnSessionKeysChange(const char* aSessionId,
uint32_t aSessionIdSize,
bool aHasAdditionalUsableKey,
@@ -99,12 +100,6 @@ public:
cdm::Time aNewExpiryTime) override;
void OnSessionClosed(const char* aSessionId,
uint32_t aSessionIdSize) override;
- void OnLegacySessionError(const char* aSessionId,
- uint32_t aSessionId_length,
- cdm::Error aError,
- uint32_t aSystemCode,
- const char* aErrorMessage,
- uint32_t aErrorMessageLength) override;
void SendPlatformChallenge(const char* aServiceId,
uint32_t aServiceIdSize,
const char* aChallenge,
@@ -113,6 +108,9 @@ public:
void QueryOutputProtectionStatus() override;
void OnDeferredInitializationDone(cdm::StreamType aStreamType,
cdm::Status aDecoderStatus) override;
+ // cdm::Host_9 interface
+ // NOTE: the interface has changed upstream.
+ void RequestStorageId(uint32_t aVersion) override;
cdm::FileIO* CreateFileIO(cdm::FileIOClient* aClient) override;
GMPDecryptorCallback* Callback() const { return mCallback; }
@@ -120,7 +118,7 @@ public:
private:
~WidevineDecryptor();
RefPtr<CDMWrapper> mCDM;
- cdm::ContentDecryptionModule_8* CDM() { return mCDM->GetCDM(); }
+ cdm::ContentDecryptionModule_9* CDM() { return mCDM->GetCDM(); }
GMPDecryptorCallback* mCallback;
std::map<uint32_t, uint32_t> mPromiseIdToNewSessionTokens;
diff --git a/dom/media/gmp/widevine-adapter/WidevineUtils.cpp b/dom/media/gmp/widevine-adapter/WidevineUtils.cpp
index 925dfe1a1..10c6c2e18 100644
--- a/dom/media/gmp/widevine-adapter/WidevineUtils.cpp
+++ b/dom/media/gmp/widevine-adapter/WidevineUtils.cpp
@@ -43,7 +43,7 @@ ToGMPErr(cdm::Status aStatus)
case cdm::kSuccess: return GMPNoErr;
case cdm::kNeedMoreData: return GMPGenericErr;
case cdm::kNoKey: return GMPNoKeyErr;
- case cdm::kSessionError: return GMPGenericErr;
+ case cdm::kInitializationError: return GMPGenericErr;
case cdm::kDecryptError: return GMPCryptoErr;
case cdm::kDecodeError: return GMPDecodeErr;
case cdm::kDeferredInitialization: return GMPGenericErr;
@@ -77,7 +77,7 @@ void InitInputBuffer(const GMPEncryptedBufferMetadata* aCrypto,
aInputBuffer.timestamp = aTimestamp;
}
-CDMWrapper::CDMWrapper(cdm::ContentDecryptionModule_8* aCDM,
+CDMWrapper::CDMWrapper(cdm::ContentDecryptionModule_9* aCDM,
WidevineDecryptor* aDecryptor)
: mCDM(aCDM)
, mDecryptor(aDecryptor)
diff --git a/dom/media/gmp/widevine-adapter/WidevineUtils.h b/dom/media/gmp/widevine-adapter/WidevineUtils.h
index 57c004a87..2f6137fe3 100644
--- a/dom/media/gmp/widevine-adapter/WidevineUtils.h
+++ b/dom/media/gmp/widevine-adapter/WidevineUtils.h
@@ -48,12 +48,16 @@ class CDMWrapper {
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CDMWrapper)
- explicit CDMWrapper(cdm::ContentDecryptionModule_8* aCDM,
+ explicit CDMWrapper(cdm::ContentDecryptionModule_9* aCDM,
WidevineDecryptor* aDecryptor);
- cdm::ContentDecryptionModule_8* GetCDM() const { return mCDM; }
+ cdm::ContentDecryptionModule_9* GetCDM() const { return mCDM; }
+ void OnStorageId(uint32_t aVersion, const uint8_t* aStorageId,
+ uint32_t aStorageIdSize) {
+ mCDM->OnStorageId(aVersion, aStorageId, aStorageIdSize);
+ }
private:
~CDMWrapper();
- cdm::ContentDecryptionModule_8* mCDM;
+ cdm::ContentDecryptionModule_9* mCDM;
RefPtr<WidevineDecryptor> mDecryptor;
};
diff --git a/dom/media/gmp/widevine-adapter/WidevineVideoDecoder.h b/dom/media/gmp/widevine-adapter/WidevineVideoDecoder.h
index b143f75f7..f5e63519b 100644
--- a/dom/media/gmp/widevine-adapter/WidevineVideoDecoder.h
+++ b/dom/media/gmp/widevine-adapter/WidevineVideoDecoder.h
@@ -45,7 +45,7 @@ private:
~WidevineVideoDecoder();
- cdm::ContentDecryptionModule_8* CDM() const {
+ cdm::ContentDecryptionModule_9* CDM() const {
// CDM should only be accessed before 'DecodingComplete'.
MOZ_ASSERT(mCDMWrapper);
// CDMWrapper ensure the CDM is non-null, no need to check again.
diff --git a/dom/media/gmp/widevine-adapter/content_decryption_module.h b/dom/media/gmp/widevine-adapter/content_decryption_module.h
index 512ca9768..0539135fb 100644
--- a/dom/media/gmp/widevine-adapter/content_decryption_module.h
+++ b/dom/media/gmp/widevine-adapter/content_decryption_module.h
@@ -5,6 +5,8 @@
#ifndef CDM_CONTENT_DECRYPTION_MODULE_H_
#define CDM_CONTENT_DECRYPTION_MODULE_H_
+#include "content_decryption_module_export.h"
+
#if defined(_MSC_VER)
typedef unsigned char uint8_t;
typedef unsigned int uint32_t;
@@ -14,25 +16,21 @@ typedef __int64 int64_t;
#include <stdint.h>
#endif
-// Define CDM_EXPORT so that functionality implemented by the CDM module
-// can be exported to consumers.
-#if defined(WIN32)
-
-#if defined(CDM_IMPLEMENTATION)
-#define CDM_EXPORT __declspec(dllexport)
-#else
-#define CDM_EXPORT __declspec(dllimport)
-#endif // defined(CDM_IMPLEMENTATION)
-
-#else // defined(WIN32)
-
-#if defined(CDM_IMPLEMENTATION)
-#define CDM_EXPORT __attribute__((visibility("default")))
+// Define CDM_CLASS_API to export class types. We have to add visibility
+// attributes to make sure virtual tables in CDM consumer and CDM implementation
+// are the same. Generally, it was always a good idea, as there're no guarantees
+// about that for the internal symbols, but it has only become a practical issue
+// after introduction of LTO devirtualization. See more details on
+// https://crbug.com/609564#c35
+#if defined(_WIN32)
+#if defined(__clang__)
+#define CDM_CLASS_API [[clang::lto_visibility_public]]
#else
-#define CDM_EXPORT
+#define CDM_CLASS_API
#endif
-
-#endif // defined(WIN32)
+#else // defined(_WIN32)
+#define CDM_CLASS_API __attribute__((visibility("default")))
+#endif // defined(_WIN32)
// The version number must be rolled when the exported functions are updated!
// If the CDM and the adapter use different versions of these functions, the
@@ -48,9 +46,9 @@ typedef __int64 int64_t;
#define BUILD_ENTRYPOINT_NO_EXPANSION(name, version) name##_##version
extern "C" {
-CDM_EXPORT void INITIALIZE_CDM_MODULE();
+CDM_API void INITIALIZE_CDM_MODULE();
-CDM_EXPORT void DeinitializeCdmModule();
+CDM_API void DeinitializeCdmModule();
// Returns a pointer to the requested CDM Host interface upon success.
// Returns NULL if the requested CDM Host interface is not supported.
@@ -65,30 +63,30 @@ typedef void* (*GetCdmHostFunc)(int host_interface_version, void* user_data);
// |cdm_interface_version|.
// Caller retains ownership of arguments and must call Destroy() on the returned
// object.
-CDM_EXPORT void* CreateCdmInstance(
+CDM_API void* CreateCdmInstance(
int cdm_interface_version,
const char* key_system, uint32_t key_system_size,
GetCdmHostFunc get_cdm_host_func, void* user_data);
-CDM_EXPORT const char* GetCdmVersion();
+CDM_API const char* GetCdmVersion();
}
namespace cdm {
-class AudioFrames;
-class DecryptedBlock;
-class VideoFrame;
+class CDM_CLASS_API AudioFrames;
+class CDM_CLASS_API DecryptedBlock;
+class CDM_CLASS_API VideoFrame;
-class Host_7;
-class Host_8;
+class CDM_CLASS_API Host_8;
+class CDM_CLASS_API Host_9;
enum Status {
kSuccess = 0,
kNeedMoreData, // Decoder needs more data to produce a decoded frame/sample.
- kNoKey, // The required decryption key is not available.
- kSessionError, // Session management error.
- kDecryptError, // Decryption failed.
- kDecodeError, // Error decoding audio or video.
+ kNoKey, // The required decryption key is not available.
+ kInitializationError, // Initialization error.
+ kDecryptError, // Decryption failed.
+ kDecodeError, // Error decoding audio or video.
kDeferredInitialization // Decoder is not ready for initialization.
};
@@ -97,6 +95,7 @@ enum Status {
// The following starts with the list of DOM4 exceptions from:
// http://www.w3.org/TR/dom/#domexception
// Some DOM4 exceptions are not included as they are not expected to be used.
+// Should only be used on Host_8 and before.
enum Error {
kNotSupportedError = 9,
kInvalidStateError = 11,
@@ -113,8 +112,20 @@ enum Error {
kOutputError = 101
};
-// Time is defined as the number of seconds since the
-// Epoch (00:00:00 UTC, January 1, 1970).
+// Exceptions used by the CDM to reject promises.
+// https://w3c.github.io/encrypted-media/#exceptions
+enum Exception {
+ kExceptionTypeError,
+ kExceptionNotSupportedError,
+ kExceptionInvalidStateError,
+ kExceptionQuotaExceededError
+};
+
+// Time is defined as the number of seconds since the Epoch
+// (00:00:00 UTC, January 1, 1970), not including any added leap second.
+// Also see Time definition in spec: https://w3c.github.io/encrypted-media/#time
+// Note that Time is defined in millisecond accuracy in the spec but in second
+// accuracy here.
typedef double Time;
// An input buffer can be split into several continuous subsamples.
@@ -151,13 +162,13 @@ struct SubsampleEntry {
// unencrypted.
struct InputBuffer {
InputBuffer()
- : data(NULL),
+ : data(nullptr),
data_size(0),
- key_id(NULL),
+ key_id(nullptr),
key_id_size(0),
- iv(NULL),
+ iv(nullptr),
iv_size(0),
- subsamples(NULL),
+ subsamples(nullptr),
num_subsamples(0),
timestamp(0) {}
@@ -188,7 +199,7 @@ struct AudioDecoderConfig {
channel_count(0),
bits_per_channel(0),
samples_per_second(0),
- extra_data(NULL),
+ extra_data(nullptr),
extra_data_size(0) {}
AudioCodec codec;
@@ -214,10 +225,25 @@ enum AudioFormat {
};
// Surface formats based on FOURCC labels, see: http://www.fourcc.org/yuv.php
+// Values are chosen to be consistent with Chromium's VideoPixelFormat values.
enum VideoFormat {
kUnknownVideoFormat = 0, // Unknown format value. Used for error reporting.
- kYv12, // 12bpp YVU planar 1x1 Y, 2x2 VU samples.
- kI420 // 12bpp YVU planar 1x1 Y, 2x2 UV samples.
+ kYv12 = 1, // 12bpp YVU planar 1x1 Y, 2x2 VU samples.
+ kI420 = 2, // 12bpp YUV planar 1x1 Y, 2x2 UV samples.
+
+ // In the following formats, each sample uses 16-bit in storage, while the
+ // sample value is stored in the least significant N bits where N is
+ // specified by the number after "P". For example, for YUV420P9, each Y, U,
+ // and V sample is stored in the least significant 9 bits in a 2-byte block.
+ kYUV420P9 = 16,
+ kYUV420P10 = 17,
+ kYUV422P9 = 18,
+ kYUV422P10 = 19,
+ kYUV444P9 = 20,
+ kYUV444P10 = 21,
+ kYUV420P12 = 22,
+ kYUV422P12 = 23,
+ kYUV444P12 = 24,
};
struct Size {
@@ -245,14 +271,19 @@ struct VideoDecoderConfig {
kH264ProfileHigh,
kH264ProfileHigh10,
kH264ProfileHigh422,
- kH264ProfileHigh444Predictive
+ kH264ProfileHigh444Predictive,
+ // VP9 Profiles are only passed in starting from CDM_9.
+ kVP9Profile0,
+ kVP9Profile1,
+ kVP9Profile2,
+ kVP9Profile3
};
VideoDecoderConfig()
: codec(kUnknownVideoCodec),
profile(kUnknownVideoCodecProfile),
format(kUnknownVideoFormat),
- extra_data(NULL),
+ extra_data(nullptr),
extra_data_size(0) {}
VideoCodec codec;
@@ -294,7 +325,7 @@ struct PlatformChallengeResponse {
// Used when passing arrays of binary data. Does not own the referenced data.
struct BinaryData {
- BinaryData() : data(NULL), length(0) {}
+ BinaryData() : data(nullptr), length(0) {}
const uint8_t* data;
uint32_t length;
};
@@ -316,7 +347,10 @@ enum KeyStatus {
// should be 0 when |status| == kUsable.
struct KeyInformation {
KeyInformation()
- : key_id(NULL), key_id_size(0), status(kInternalError), system_code(0) {}
+ : key_id(nullptr),
+ key_id_size(0),
+ status(kInternalError),
+ system_code(0) {}
const uint8_t* key_id;
uint32_t key_id_size;
KeyStatus status;
@@ -372,6 +406,24 @@ enum MessageType {
kLicenseRelease = 2
};
+enum HdcpVersion {
+ kHdcpVersionNone,
+ kHdcpVersion1_0,
+ kHdcpVersion1_1,
+ kHdcpVersion1_2,
+ kHdcpVersion1_3,
+ kHdcpVersion1_4,
+ kHdcpVersion2_0,
+ kHdcpVersion2_1,
+ kHdcpVersion2_2
+};
+
+struct Policy {
+ Policy() : min_hdcp_version(kHdcpVersionNone) {}
+
+ HdcpVersion min_hdcp_version;
+};
+
// FileIO interface provides a way for the CDM to store data in a file in
// persistent storage. This interface aims only at providing basic read/write
// capabilities and should not be used as a full fledged file IO API.
@@ -381,7 +433,7 @@ enum MessageType {
// Note to implementors of this interface:
// Per-origin storage and the ability for users to clear it are important.
// See http://www.w3.org/TR/encrypted-media/#privacy-storedinfo.
-class FileIO {
+class CDM_CLASS_API FileIO {
public:
// Opens the file with |file_name| for read and write.
// FileIOClient::OnOpenComplete() will be called after the opening
@@ -389,8 +441,9 @@ class FileIO {
// - When the file is opened by a CDM instance, it will be classified as "in
// use". In this case other CDM instances in the same domain may receive
// kInUse status when trying to open it.
- // - |file_name| must not contain forward slash ('/') or backslash ('\'), and
- // must not start with an underscore ('_').
+ // - |file_name| must only contain letters (A-Za-z), digits(0-9), or "._-".
+ // It must not start with an underscore ('_'), and must be at least 1
+ // character and no more than 256 characters long.
virtual void Open(const char* file_name, uint32_t file_name_size) = 0;
// Reads the contents of the file. FileIOClient::OnReadComplete() will be
@@ -421,7 +474,7 @@ class FileIO {
// When kError is returned, the FileIO object could be in an error state. All
// following calls (other than Close()) could return kError. The CDM should
// still call Close() to destroy the FileIO object.
-class FileIOClient {
+class CDM_CLASS_API FileIOClient {
public:
enum Status {
kSuccess = 0,
@@ -462,10 +515,20 @@ class FileIOClient {
// provided in CreateCdmInstance() to allocate any Buffer that needs to
// be passed back to the caller. Implementations must call Buffer::Destroy()
// when a Buffer is created that will never be returned to the caller.
-class ContentDecryptionModule_7 {
+class CDM_CLASS_API ContentDecryptionModule_8 {
public:
- static const int kVersion = 7;
- typedef Host_7 Host;
+ static const int kVersion = 8;
+ typedef Host_8 Host;
+
+ // Initializes the CDM instance, providing information about permitted
+ // functionalities.
+ // If |allow_distinctive_identifier| is false, messages from the CDM,
+ // such as message events, must not contain a Distinctive Identifier,
+ // even in an encrypted form.
+ // If |allow_persistent_state| is false, the CDM must not attempt to
+ // persist state. Calls to CreateFileIO() will fail.
+ virtual void Initialize(bool allow_distinctive_identifier,
+ bool allow_persistent_state) = 0;
// SetServerCertificate(), CreateSessionAndGenerateRequest(), LoadSession(),
// UpdateSession(), CloseSession(), and RemoveSession() all accept a
@@ -484,8 +547,7 @@ class ContentDecryptionModule_7 {
// or Host::OnRejectPromise().
virtual void CreateSessionAndGenerateRequest(uint32_t promise_id,
SessionType session_type,
- const char* init_data_type,
- uint32_t init_data_type_size,
+ InitDataType init_data_type,
const uint8_t* init_data,
uint32_t init_data_size) = 0;
@@ -631,8 +693,8 @@ class ContentDecryptionModule_7 {
virtual void Destroy() = 0;
protected:
- ContentDecryptionModule_7() {}
- virtual ~ContentDecryptionModule_7() {}
+ ContentDecryptionModule_8() {}
+ virtual ~ContentDecryptionModule_8() {}
};
// ContentDecryptionModule interface that all CDMs need to implement.
@@ -641,10 +703,10 @@ class ContentDecryptionModule_7 {
// provided in CreateCdmInstance() to allocate any Buffer that needs to
// be passed back to the caller. Implementations must call Buffer::Destroy()
// when a Buffer is created that will never be returned to the caller.
-class ContentDecryptionModule_8 {
+class CDM_CLASS_API ContentDecryptionModule_9 {
public:
- static const int kVersion = 8;
- typedef Host_8 Host;
+ static const int kVersion = 9;
+ typedef Host_9 Host;
// Initializes the CDM instance, providing information about permitted
// functionalities.
@@ -656,6 +718,13 @@ class ContentDecryptionModule_8 {
virtual void Initialize(bool allow_distinctive_identifier,
bool allow_persistent_state) = 0;
+ // Gets the key status if the CDM has a hypothetical key with the |policy|.
+ // The CDM must respond by calling either Host::OnResolveKeyStatusPromise()
+ // with the result key status or Host::OnRejectPromise() if an unexpected
+ // error happened or this method is not supported.
+ virtual void GetStatusForPolicy(uint32_t promise_id,
+ const Policy& policy) = 0;
+
// SetServerCertificate(), CreateSessionAndGenerateRequest(), LoadSession(),
// UpdateSession(), CloseSession(), and RemoveSession() all accept a
// |promise_id|, which must be passed to the completion Host method
@@ -731,8 +800,8 @@ class ContentDecryptionModule_8 {
//
// Returns kSuccess if the |audio_decoder_config| is supported and the CDM
// audio decoder is successfully initialized.
- // Returns kSessionError if |audio_decoder_config| is not supported. The CDM
- // may still be able to do Decrypt().
+ // Returns kInitializationError if |audio_decoder_config| is not supported.
+ // The CDM may still be able to do Decrypt().
// Returns kDeferredInitialization if the CDM is not ready to initialize the
// decoder at this time. Must call Host::OnDeferredInitializationDone() once
// initialization is complete.
@@ -744,8 +813,8 @@ class ContentDecryptionModule_8 {
//
// Returns kSuccess if the |video_decoder_config| is supported and the CDM
// video decoder is successfully initialized.
- // Returns kSessionError if |video_decoder_config| is not supported. The CDM
- // may still be able to do Decrypt().
+ // Returns kInitializationError if |video_decoder_config| is not supported.
+ // The CDM may still be able to do Decrypt().
// Returns kDeferredInitialization if the CDM is not ready to initialize the
// decoder at this time. Must call Host::OnDeferredInitializationDone() once
// initialization is complete.
@@ -815,18 +884,30 @@ class ContentDecryptionModule_8 {
uint32_t link_mask,
uint32_t output_protection_mask) = 0;
+ // Called by the host after a call to Host::RequestStorageId(). If the
+ // version of the storage ID requested is available, |storage_id| and
+ // |storage_id_size| are set appropriately. |version| will be the same as
+ // what was requested, unless 0 (latest) was requested, in which case
+ // |version| will be the actual version number for the |storage_id| returned.
+ // If the requested version is not available, null/zero will be provided as
+ // |storage_id| and |storage_id_size|, respectively, and |version| should be
+ // ignored.
+ virtual void OnStorageId(uint32_t version,
+ const uint8_t* storage_id,
+ uint32_t storage_id_size) = 0;
+
// Destroys the object in the same context as it was created.
virtual void Destroy() = 0;
protected:
- ContentDecryptionModule_8() {}
- virtual ~ContentDecryptionModule_8() {}
+ ContentDecryptionModule_9() {}
+ virtual ~ContentDecryptionModule_9() {}
};
-typedef ContentDecryptionModule_8 ContentDecryptionModule;
+typedef ContentDecryptionModule_9 ContentDecryptionModule;
// Represents a buffer created by Allocator implementations.
-class Buffer {
+class CDM_CLASS_API Buffer {
public:
// Destroys the buffer in the same context as it was created.
virtual void Destroy() = 0;
@@ -845,9 +926,9 @@ class Buffer {
void operator=(const Buffer&);
};
-class Host_7 {
+class CDM_CLASS_API Host_8 {
public:
- static const int kVersion = 7;
+ static const int kVersion = 8;
// Returns a Buffer* containing non-zero members upon success, or NULL on
// failure. The caller owns the Buffer* after this call. The buffer is not
@@ -859,7 +940,7 @@ class Host_7 {
// from now with |context|.
virtual void SetTimer(int64_t delay_ms, void* context) = 0;
- // Returns the current wall time in seconds.
+ // Returns the current wall time.
virtual Time GetCurrentWallTime() = 0;
// Called by the CDM when a session is created or loaded and the value for the
@@ -917,8 +998,10 @@ class Host_7 {
// session |session_id|. This can happen as the result of an Update() call
// or some other event. If this happens as a result of a call to Update(),
// it must be called before resolving the Update() promise. |new_expiry_time|
- // can be 0 to represent "undefined". Size parameter should not include
- // null termination.
+ // represents the time after which the key(s) in the session will no longer
+ // be usable for decryption. It can be 0 if no such time exists or if the
+ // license explicitly never expires. Size parameter should not include null
+ // termination.
virtual void OnExpirationChange(const char* session_id,
uint32_t session_id_size,
Time new_expiry_time) = 0;
@@ -978,13 +1061,13 @@ class Host_7 {
virtual FileIO* CreateFileIO(FileIOClient* client) = 0;
protected:
- Host_7() {}
- virtual ~Host_7() {}
+ Host_8() {}
+ virtual ~Host_8() {}
};
-class Host_8 {
+class CDM_CLASS_API Host_9 {
public:
- static const int kVersion = 8;
+ static const int kVersion = 9;
// Returns a Buffer* containing non-zero members upon success, or NULL on
// failure. The caller owns the Buffer* after this call. The buffer is not
@@ -996,9 +1079,14 @@ class Host_8 {
// from now with |context|.
virtual void SetTimer(int64_t delay_ms, void* context) = 0;
- // Returns the current wall time in seconds.
+ // Returns the current wall time.
virtual Time GetCurrentWallTime() = 0;
+ // Called by the CDM when a key status is available in response to
+ // GetStatusForPolicy().
+ virtual void OnResolveKeyStatusPromise(uint32_t promise_id,
+ KeyStatus key_status) = 0;
+
// Called by the CDM when a session is created or loaded and the value for the
// MediaKeySession's sessionId attribute is available (|session_id|).
// This must be called before OnSessionMessage() or
@@ -1016,26 +1104,21 @@ class Host_8 {
// Called by the CDM when an error occurs as a result of one of the
// ContentDecryptionModule calls that accept a |promise_id|.
- // |error| must be specified, |error_message| and |system_code|
+ // |exception| must be specified. |error_message| and |system_code|
// are optional. |error_message_size| should not include null termination.
virtual void OnRejectPromise(uint32_t promise_id,
- Error error,
+ Exception exception,
uint32_t system_code,
const char* error_message,
uint32_t error_message_size) = 0;
// Called by the CDM when it has a message for session |session_id|.
// Size parameters should not include null termination.
- // |legacy_destination_url| is only for supporting the prefixed EME API and
- // is ignored by unprefixed EME. It should only be non-null if |message_type|
- // is kLicenseRenewal.
virtual void OnSessionMessage(const char* session_id,
uint32_t session_id_size,
MessageType message_type,
const char* message,
- uint32_t message_size,
- const char* legacy_destination_url,
- uint32_t legacy_destination_url_length) = 0;
+ uint32_t message_size) = 0;
// Called by the CDM when there has been a change in keys or their status for
// session |session_id|. |has_additional_usable_key| should be set if a
@@ -1054,8 +1137,10 @@ class Host_8 {
// session |session_id|. This can happen as the result of an Update() call
// or some other event. If this happens as a result of a call to Update(),
// it must be called before resolving the Update() promise. |new_expiry_time|
- // can be 0 to represent "undefined". Size parameter should not include
- // null termination.
+ // represents the time after which the key(s) in the session will no longer
+ // be usable for decryption. It can be 0 if no such time exists or if the
+ // license explicitly never expires. Size parameter should not include null
+ // termination.
virtual void OnExpirationChange(const char* session_id,
uint32_t session_id_size,
Time new_expiry_time) = 0;
@@ -1065,21 +1150,6 @@ class Host_8 {
virtual void OnSessionClosed(const char* session_id,
uint32_t session_id_size) = 0;
- // Called by the CDM when an error occurs in session |session_id|
- // unrelated to one of the ContentDecryptionModule calls that accept a
- // |promise_id|. |error| must be specified, |error_message| and
- // |system_code| are optional. Length parameters should not include null
- // termination.
- // Note:
- // - This method is only for supporting prefixed EME API.
- // - This method will be ignored by unprefixed EME. All errors reported
- // in this method should probably also be reported by one of other methods.
- virtual void OnLegacySessionError(
- const char* session_id, uint32_t session_id_length,
- Error error,
- uint32_t system_code,
- const char* error_message, uint32_t error_message_length) = 0;
-
// The following are optional methods that may not be implemented on all
// platforms.
@@ -1114,13 +1184,22 @@ class Host_8 {
// CDM can call this method multiple times to operate on different files.
virtual FileIO* CreateFileIO(FileIOClient* client) = 0;
+ // Requests a specific version of the storage ID. A storage ID is a stable,
+ // device specific ID used by the CDM to securely store persistent data. The
+ // ID will be returned by the host via ContentDecryptionModule::OnStorageId().
+ // If |version| is 0, the latest version will be returned. All |version|s
+ // that are greater than or equal to 0x80000000 are reserved for the CDM and
+ // should not be supported or returned by the host. The CDM must not expose
+ // the ID outside the client device, even in encrypted form.
+ virtual void RequestStorageId(uint32_t version) = 0;
+
protected:
- Host_8() {}
- virtual ~Host_8() {}
+ Host_9() {}
+ virtual ~Host_9() {}
};
// Represents a decrypted block that has not been decoded.
-class DecryptedBlock {
+class CDM_CLASS_API DecryptedBlock {
public:
virtual void SetDecryptedBuffer(Buffer* buffer) = 0;
virtual Buffer* DecryptedBuffer() = 0;
@@ -1135,7 +1214,7 @@ class DecryptedBlock {
virtual ~DecryptedBlock() {}
};
-class VideoFrame {
+class CDM_CLASS_API VideoFrame {
public:
enum VideoPlane {
kYPlane = 0,
@@ -1178,7 +1257,7 @@ class VideoFrame {
//
// |<----------------- AudioFrames ------------------>|
// | audio buffer 0 | audio buffer 1 | audio buffer 2 |
-class AudioFrames {
+class CDM_CLASS_API AudioFrames {
public:
virtual void SetFrameBuffer(Buffer* buffer) = 0;
virtual Buffer* FrameBuffer() = 0;
diff --git a/dom/media/gmp/widevine-adapter/content_decryption_module_export.h b/dom/media/gmp/widevine-adapter/content_decryption_module_export.h
new file mode 100644
index 000000000..51d485892
--- /dev/null
+++ b/dom/media/gmp/widevine-adapter/content_decryption_module_export.h
@@ -0,0 +1,22 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CDM_CONTENT_DECRYPTION_MODULE_EXPORT_H_
+#define CDM_CONTENT_DECRYPTION_MODULE_EXPORT_H_
+
+// Define CDM_API so that functionality implemented by the CDM module
+// can be exported to consumers.
+#if defined(_WIN32)
+
+#if defined(CDM_IMPLEMENTATION)
+#define CDM_API __declspec(dllexport)
+#else
+#define CDM_API __declspec(dllimport)
+#endif // defined(CDM_IMPLEMENTATION)
+
+#else // defined(_WIN32)
+#define CDM_API __attribute__((visibility("default")))
+#endif // defined(_WIN32)
+
+#endif // CDM_CONTENT_DECRYPTION_MODULE_EXPORT_H_
diff --git a/dom/media/gmp/widevine-adapter/content_decryption_module_ext.h b/dom/media/gmp/widevine-adapter/content_decryption_module_ext.h
new file mode 100644
index 000000000..5df8344e6
--- /dev/null
+++ b/dom/media/gmp/widevine-adapter/content_decryption_module_ext.h
@@ -0,0 +1,64 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CDM_CONTENT_DECRYPTION_MODULE_EXT_H_
+#define CDM_CONTENT_DECRYPTION_MODULE_EXT_H_
+
+#if defined(_WIN32)
+#include <windows.h>
+#endif
+
+#include "content_decryption_module_export.h"
+
+#if defined(_MSC_VER)
+typedef unsigned int uint32_t;
+#else
+#include <stdint.h>
+#endif
+
+namespace cdm {
+
+#if defined(_WIN32)
+typedef wchar_t FilePathCharType;
+typedef HANDLE PlatformFile;
+const PlatformFile kInvalidPlatformFile = INVALID_HANDLE_VALUE;
+#else
+typedef char FilePathCharType;
+typedef int PlatformFile;
+const PlatformFile kInvalidPlatformFile = -1;
+#endif // defined(_WIN32)
+
+struct HostFile {
+ HostFile(const FilePathCharType* file_path,
+ PlatformFile file,
+ PlatformFile sig_file)
+ : file_path(file_path), file(file), sig_file(sig_file) {}
+
+ // File that is part of the host of the CDM.
+ const FilePathCharType* file_path = nullptr;
+ PlatformFile file = kInvalidPlatformFile;
+
+ // Signature file for |file|.
+ PlatformFile sig_file = kInvalidPlatformFile;
+};
+
+} // namespace cdm
+
+extern "C" {
+
+// Functions in this file are dynamically retrieved by their versioned function
+// names. Increment the version number for any backward incompatible API
+// changes.
+
+// Verifies CDM host. All files in |host_files| are opened in read-only mode.
+//
+// Returns false and closes all files if there is an immediate failure.
+// Otherwise returns true as soon as possible and processes the files
+// asynchronously. All files MUST be closed by the CDM after this one-time
+// processing is finished.
+CDM_API bool VerifyCdmHost_0(const cdm::HostFile* host_files,
+ uint32_t num_files);
+}
+
+#endif // CDM_CONTENT_DECRYPTION_MODULE_EXT_H_
diff --git a/dom/media/gtest/Cargo.toml b/dom/media/gtest/Cargo.toml
deleted file mode 100644
index a55f8fb68..000000000
--- a/dom/media/gtest/Cargo.toml
+++ /dev/null
@@ -1,7 +0,0 @@
-[package]
-name = "mp4parse-gtest"
-version = "0.1.0"
-authors = ["nobody@mozilla.org"]
-
-[lib]
-path = "hello.rs"
diff --git a/dom/media/gtest/TestMP3Demuxer.cpp b/dom/media/gtest/TestMP3Demuxer.cpp
index 8d2109f00..934acb60e 100644
--- a/dom/media/gtest/TestMP3Demuxer.cpp
+++ b/dom/media/gtest/TestMP3Demuxer.cpp
@@ -11,7 +11,6 @@
#include "MockMediaResource.h"
using namespace mozilla;
-using namespace mozilla::mp3;
using media::TimeUnit;
diff --git a/dom/media/gtest/TestMP4Reader.cpp b/dom/media/gtest/TestMP4Reader.cpp
deleted file mode 100644
index f08f7a40d..000000000
--- a/dom/media/gtest/TestMP4Reader.cpp
+++ /dev/null
@@ -1,217 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "gtest/gtest.h"
-#include "MP4Reader.h"
-#include "MP4Decoder.h"
-#include "mozilla/SharedThreadPool.h"
-#include "MockMediaResource.h"
-#include "MockMediaDecoderOwner.h"
-#include "mozilla/Preferences.h"
-#include "TimeUnits.h"
-
-using namespace mozilla;
-using namespace mozilla::dom;
-
-class TestBinding
-{
-public:
- NS_INLINE_DECL_THREADSAFE_REFCOUNTING(TestBinding);
-
- RefPtr<MP4Decoder> decoder;
- RefPtr<MockMediaResource> resource;
- RefPtr<MP4Reader> reader;
-
- explicit TestBinding(const char* aFileName = "gizmo.mp4")
- : decoder(new MP4Decoder())
- , resource(new MockMediaResource(aFileName))
- , reader(new MP4Reader(decoder))
- {
- EXPECT_EQ(NS_OK, Preferences::SetBool(
- "media.use-blank-decoder", true));
-
- EXPECT_EQ(NS_OK, resource->Open(nullptr));
- decoder->SetResource(resource);
-
- reader->Init(nullptr);
- // This needs to be done before invoking GetBuffered. This is normally
- // done by MediaDecoderStateMachine.
- reader->DispatchSetStartTime(0);
- }
-
- void Init() {
- nsCOMPtr<nsIThread> thread;
- nsCOMPtr<nsIRunnable> r = NewRunnableMethod(this, &TestBinding::ReadMetadata);
- nsresult rv = NS_NewThread(getter_AddRefs(thread), r);
- EXPECT_EQ(NS_OK, rv);
- thread->Shutdown();
- }
-
-private:
- virtual ~TestBinding()
- {
- {
- RefPtr<TaskQueue> queue = reader->OwnerThread();
- nsCOMPtr<nsIRunnable> task = NewRunnableMethod(reader, &MP4Reader::Shutdown);
- // Hackily bypass the tail dispatcher so that we can AwaitShutdownAndIdle.
- // In production code we'd use BeginShutdown + promises.
- queue->Dispatch(task.forget(), AbstractThread::AssertDispatchSuccess,
- AbstractThread::TailDispatch);
- queue->AwaitShutdownAndIdle();
- }
- decoder = nullptr;
- resource = nullptr;
- reader = nullptr;
- SharedThreadPool::SpinUntilEmpty();
- }
-
- void ReadMetadata()
- {
- MediaInfo info;
- MetadataTags* tags;
- EXPECT_EQ(NS_OK, reader->ReadMetadata(&info, &tags));
- }
-};
-
-TEST(MP4Reader, BufferedRange)
-{
- RefPtr<TestBinding> b = new TestBinding();
- b->Init();
-
- // Video 3-4 sec, audio 2.986666-4.010666 sec
- b->resource->MockAddBufferedRange(248400, 327455);
-
- media::TimeIntervals ranges = b->reader->GetBuffered();
- EXPECT_EQ(1U, ranges.Length());
- EXPECT_NEAR(270000 / 90000.0, ranges.Start(0).ToSeconds(), 0.000001);
- EXPECT_NEAR(360000 / 90000.0, ranges.End(0).ToSeconds(), 0.000001);
-}
-
-TEST(MP4Reader, BufferedRangeMissingLastByte)
-{
- RefPtr<TestBinding> b = new TestBinding();
- b->Init();
-
- // Dropping the last byte of the video
- b->resource->MockClearBufferedRanges();
- b->resource->MockAddBufferedRange(248400, 324912);
- b->resource->MockAddBufferedRange(324913, 327455);
-
- media::TimeIntervals ranges = b->reader->GetBuffered();
- EXPECT_EQ(1U, ranges.Length());
- EXPECT_NEAR(270000.0 / 90000.0, ranges.Start(0).ToSeconds(), 0.000001);
- EXPECT_NEAR(357000 / 90000.0, ranges.End(0).ToSeconds(), 0.000001);
-}
-
-TEST(MP4Reader, BufferedRangeSyncFrame)
-{
- RefPtr<TestBinding> b = new TestBinding();
- b->Init();
-
- // Check that missing the first byte at 2 seconds skips right through to 3
- // seconds because of a missing sync frame
- b->resource->MockClearBufferedRanges();
- b->resource->MockAddBufferedRange(146336, 327455);
-
- media::TimeIntervals ranges = b->reader->GetBuffered();
- EXPECT_EQ(1U, ranges.Length());
- EXPECT_NEAR(270000.0 / 90000.0, ranges.Start(0).ToSeconds(), 0.000001);
- EXPECT_NEAR(360000 / 90000.0, ranges.End(0).ToSeconds(), 0.000001);
-}
-
-TEST(MP4Reader, CompositionOrder)
-{
- RefPtr<TestBinding> b = new TestBinding("mediasource_test.mp4");
- b->Init();
-
- // The first 5 video samples of this file are:
- // Video timescale=2500
- // Frame Start Size Time Duration Sync
- // 1 48 5455 166 83 Yes
- // 2 5503 145 249 83
- // 3 6228 575 581 83
- // 4 7383 235 415 83
- // 5 8779 183 332 83
- // 6 9543 191 498 83
- //
- // Audio timescale=44100
- // 1 5648 580 0 1024 Yes
- // 2 6803 580 1024 1058 Yes
- // 3 7618 581 2082 1014 Yes
- // 4 8199 580 3096 1015 Yes
- // 5 8962 581 4111 1014 Yes
- // 6 9734 580 5125 1014 Yes
- // 7 10314 581 6139 1059 Yes
- // 8 11207 580 7198 1014 Yes
- // 9 12035 581 8212 1014 Yes
- // 10 12616 580 9226 1015 Yes
- // 11 13220 581 10241 1014 Yes
-
- b->resource->MockClearBufferedRanges();
- // First two frames in decoding + first audio frame
- b->resource->MockAddBufferedRange(48, 5503); // Video 1
- b->resource->MockAddBufferedRange(5503, 5648); // Video 2
- b->resource->MockAddBufferedRange(6228, 6803); // Video 3
-
- // Audio - 5 frames; 0 - 139206 us
- b->resource->MockAddBufferedRange(5648, 6228);
- b->resource->MockAddBufferedRange(6803, 7383);
- b->resource->MockAddBufferedRange(7618, 8199);
- b->resource->MockAddBufferedRange(8199, 8779);
- b->resource->MockAddBufferedRange(8962, 9563);
- b->resource->MockAddBufferedRange(9734, 10314);
- b->resource->MockAddBufferedRange(10314, 10895);
- b->resource->MockAddBufferedRange(11207, 11787);
- b->resource->MockAddBufferedRange(12035, 12616);
- b->resource->MockAddBufferedRange(12616, 13196);
- b->resource->MockAddBufferedRange(13220, 13901);
-
- media::TimeIntervals ranges = b->reader->GetBuffered();
- EXPECT_EQ(2U, ranges.Length());
-
- EXPECT_NEAR(166.0 / 2500.0, ranges.Start(0).ToSeconds(), 0.000001);
- EXPECT_NEAR(332.0 / 2500.0, ranges.End(0).ToSeconds(), 0.000001);
-
- EXPECT_NEAR(581.0 / 2500.0, ranges.Start(1).ToSeconds(), 0.000001);
- EXPECT_NEAR(11255.0 / 44100.0, ranges.End(1).ToSeconds(), 0.000001);
-}
-
-TEST(MP4Reader, Normalised)
-{
- RefPtr<TestBinding> b = new TestBinding("mediasource_test.mp4");
- b->Init();
-
- // The first 5 video samples of this file are:
- // Video timescale=2500
- // Frame Start Size Time Duration Sync
- // 1 48 5455 166 83 Yes
- // 2 5503 145 249 83
- // 3 6228 575 581 83
- // 4 7383 235 415 83
- // 5 8779 183 332 83
- // 6 9543 191 498 83
- //
- // Audio timescale=44100
- // 1 5648 580 0 1024 Yes
- // 2 6803 580 1024 1058 Yes
- // 3 7618 581 2082 1014 Yes
- // 4 8199 580 3096 1015 Yes
- // 5 8962 581 4111 1014 Yes
- // 6 9734 580 5125 1014 Yes
- // 7 10314 581 6139 1059 Yes
- // 8 11207 580 7198 1014 Yes
- // 9 12035 581 8212 1014 Yes
- // 10 12616 580 9226 1015 Yes
- // 11 13220 581 10241 1014 Yes
-
- b->resource->MockClearBufferedRanges();
- b->resource->MockAddBufferedRange(48, 13901);
-
- media::TimeIntervals ranges = b->reader->GetBuffered();
- EXPECT_EQ(1U, ranges.Length());
-
- EXPECT_NEAR(166.0 / 2500.0, ranges.Start(0).ToSeconds(), 0.000001);
- EXPECT_NEAR(11255.0 / 44100.0, ranges.End(0).ToSeconds(), 0.000001);
-}
diff --git a/dom/media/gtest/TestRust.cpp b/dom/media/gtest/TestRust.cpp
deleted file mode 100644
index 86d0e99b8..000000000
--- a/dom/media/gtest/TestRust.cpp
+++ /dev/null
@@ -1,9 +0,0 @@
-#include <stdint.h>
-#include "gtest/gtest.h"
-
-extern "C" uint8_t* test_rust();
-
-TEST(rust, CallFromCpp) {
- auto greeting = test_rust();
- EXPECT_STREQ(reinterpret_cast<char*>(greeting), "hello from rust.");
-}
diff --git a/dom/media/gtest/hello.rs b/dom/media/gtest/hello.rs
deleted file mode 100644
index cd111882a..000000000
--- a/dom/media/gtest/hello.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-#[no_mangle]
-pub extern fn test_rust() -> *const u8 {
- // NB: rust &str aren't null terminated.
- let greeting = "hello from rust.\0";
- greeting.as_ptr()
-}
diff --git a/dom/media/gtest/moz.build b/dom/media/gtest/moz.build
index d5d02bced..a7ea73807 100644
--- a/dom/media/gtest/moz.build
+++ b/dom/media/gtest/moz.build
@@ -21,7 +21,6 @@ UNIFIED_SOURCES += [
'TestMozPromise.cpp',
'TestMP3Demuxer.cpp',
'TestMP4Demuxer.cpp',
- # 'TestMP4Reader.cpp', disabled so we can turn check tests back on (bug 1175752)
'TestTrackEncoder.cpp',
'TestVideoSegment.cpp',
'TestVideoUtils.cpp',
diff --git a/dom/media/mediasource/MediaSource.cpp b/dom/media/mediasource/MediaSource.cpp
index af541bbbb..152c0085a 100644
--- a/dom/media/mediasource/MediaSource.cpp
+++ b/dom/media/mediasource/MediaSource.cpp
@@ -62,8 +62,6 @@ namespace mozilla {
// Returns true if we should enable MSE webm regardless of preferences.
// 1. If MP4/H264 isn't supported:
-// * Windows XP
-// * Windows Vista and Server 2008 without the optional "Platform Update Supplement"
// * N/KN editions (Europe and Korea) of Windows 7/8/8.1/10 without the
// optional "Windows Media Feature Pack"
// 2. If H264 hardware acceleration is not available.
diff --git a/dom/media/mediasource/moz.build b/dom/media/mediasource/moz.build
index 6ded1875d..a1689c216 100644
--- a/dom/media/mediasource/moz.build
+++ b/dom/media/mediasource/moz.build
@@ -38,9 +38,6 @@ TEST_DIRS += [
'gtest',
]
-if CONFIG['MOZ_GONK_MEDIACODEC']:
- DEFINES['MOZ_GONK_MEDIACODEC'] = True
-
include('/ipc/chromium/chromium-config.mozbuild')
FINAL_LIBRARY = 'xul'
diff --git a/dom/media/moz.build b/dom/media/moz.build
index 4d036a5f6..df8cb619d 100644
--- a/dom/media/moz.build
+++ b/dom/media/moz.build
@@ -30,6 +30,7 @@ DIRS += [
'ipc',
'mediasink',
'mediasource',
+ 'mp3',
'ogg',
'platforms',
'systemservices',
@@ -42,12 +43,6 @@ DIRS += [
'standalone',
]
-if CONFIG['MOZ_DIRECTSHOW']:
- DIRS += ['directshow']
-
-if CONFIG['MOZ_ANDROID_OMX']:
- DIRS += ['android']
-
if CONFIG['MOZ_FMP4']:
DIRS += ['fmp4']
@@ -128,9 +123,6 @@ EXPORTS += [
'MediaTimer.h',
'MediaTrack.h',
'MediaTrackList.h',
- 'MP3Decoder.h',
- 'MP3Demuxer.h',
- 'MP3FrameParser.h',
'NextFrameSeekTask.h',
'nsIDocumentActivity.h',
'PrincipalChangeObserver.h',
@@ -237,9 +229,6 @@ UNIFIED_SOURCES += [
'MediaTimer.cpp',
'MediaTrack.cpp',
'MediaTrackList.cpp',
- 'MP3Decoder.cpp',
- 'MP3Demuxer.cpp',
- 'MP3FrameParser.cpp',
'NextFrameSeekTask.cpp',
'QueueObject.cpp',
'SeekJob.cpp',
@@ -294,11 +283,6 @@ LOCAL_INCLUDES += [
'/netwerk/base',
]
-if CONFIG['MOZ_DIRECTSHOW']:
- LOCAL_INCLUDES += [
- '/media/webrtc/trunk/webrtc/modules/video_capture/windows',
- ]
-
if CONFIG['MOZ_WEBRTC']:
LOCAL_INCLUDES += [
'/media/webrtc/signaling/src/common',
diff --git a/dom/media/MP3Decoder.cpp b/dom/media/mp3/MP3Decoder.cpp
index b71111e79..074a0866d 100644
--- a/dom/media/MP3Decoder.cpp
+++ b/dom/media/mp3/MP3Decoder.cpp
@@ -24,7 +24,7 @@ MP3Decoder::Clone(MediaDecoderOwner* aOwner) {
MediaDecoderStateMachine*
MP3Decoder::CreateStateMachine() {
RefPtr<MediaDecoderReader> reader =
- new MediaFormatReader(this, new mp3::MP3Demuxer(GetResource()));
+ new MediaFormatReader(this, new MP3Demuxer(GetResource()));
return new MediaDecoderStateMachine(this, reader);
}
diff --git a/dom/media/MP3Decoder.h b/dom/media/mp3/MP3Decoder.h
index 887251065..887251065 100644
--- a/dom/media/MP3Decoder.h
+++ b/dom/media/mp3/MP3Decoder.h
diff --git a/dom/media/MP3Demuxer.cpp b/dom/media/mp3/MP3Demuxer.cpp
index 7d478a41b..5a98cabfe 100644
--- a/dom/media/MP3Demuxer.cpp
+++ b/dom/media/mp3/MP3Demuxer.cpp
@@ -33,7 +33,6 @@ using mozilla::media::TimeIntervals;
using mp4_demuxer::ByteReader;
namespace mozilla {
-namespace mp3 {
// MP3Demuxer
@@ -1338,5 +1337,4 @@ ID3Parser::ID3Header::Update(uint8_t c) {
return IsValid(mPos++);
}
-} // namespace mp3
} // namespace mozilla
diff --git a/dom/media/MP3Demuxer.h b/dom/media/mp3/MP3Demuxer.h
index 03e67b0d9..5331c4d54 100644
--- a/dom/media/MP3Demuxer.h
+++ b/dom/media/mp3/MP3Demuxer.h
@@ -13,7 +13,6 @@
#include <vector>
namespace mozilla {
-namespace mp3 {
class MP3TrackDemuxer;
@@ -468,7 +467,6 @@ private:
UniquePtr<AudioInfo> mInfo;
};
-} // namespace mp3
} // namespace mozilla
#endif
diff --git a/dom/media/mp3/moz.build b/dom/media/mp3/moz.build
new file mode 100644
index 000000000..596d061f8
--- /dev/null
+++ b/dom/media/mp3/moz.build
@@ -0,0 +1,17 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+EXPORTS += [
+ 'MP3Decoder.h',
+ 'MP3Demuxer.h',
+]
+
+UNIFIED_SOURCES += [
+ 'MP3Decoder.cpp',
+ 'MP3Demuxer.cpp',
+]
+
+FINAL_LIBRARY = 'xul'
diff --git a/dom/media/ogg/OggDemuxer.cpp b/dom/media/ogg/OggDemuxer.cpp
index 591a5248f..0cc484687 100644
--- a/dom/media/ogg/OggDemuxer.cpp
+++ b/dom/media/ogg/OggDemuxer.cpp
@@ -12,7 +12,6 @@
#include "mozilla/Atomics.h"
#include "mozilla/PodOperations.h"
#include "mozilla/SharedThreadPool.h"
-#include "mozilla/Telemetry.h"
#include "mozilla/TimeStamp.h"
#include "MediaDataDemuxer.h"
#include "nsAutoRef.h"
@@ -164,7 +163,6 @@ OggDemuxer::~OggDemuxer()
MOZ_LOG(gMediaDemuxerLog, mozilla::LogLevel::Debug,
("OggDemuxer(%p)::%s: Reporting telemetry MEDIA_OGG_LOADED_IS_CHAINED=%d",
ptr, __func__, isChained));
- Telemetry::Accumulate(Telemetry::ID::MEDIA_OGG_LOADED_IS_CHAINED, isChained);
});
AbstractThread::MainThread()->Dispatch(task.forget());
}
diff --git a/dom/media/platforms/MediaTelemetryConstants.h b/dom/media/platforms/MediaTelemetryConstants.h
deleted file mode 100644
index 5024949a8..000000000
--- a/dom/media/platforms/MediaTelemetryConstants.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#ifndef dom_media_platforms_MediaTelemetryConstants_h___
-#define dom_media_platforms_MediaTelemetryConstants_h___
-
-namespace mozilla {
-namespace media {
-
-enum class MediaDecoderBackend : uint32_t
-{
- WMFSoftware = 0,
- WMFDXVA2D3D9 = 1,
- WMFDXVA2D3D11 = 2
-};
-
-} // namespace media
-} // namespace mozilla
-
-#endif // dom_media_platforms_MediaTelemetryConstants_h___
diff --git a/dom/media/platforms/PDMFactory.cpp b/dom/media/platforms/PDMFactory.cpp
index c1e58fdc2..5bfdcffb7 100644
--- a/dom/media/platforms/PDMFactory.cpp
+++ b/dom/media/platforms/PDMFactory.cpp
@@ -19,9 +19,6 @@
#ifdef MOZ_APPLEMEDIA
#include "AppleDecoderModule.h"
#endif
-#ifdef MOZ_GONK_MEDIACODEC
-#include "GonkDecoderModule.h"
-#endif
#ifdef MOZ_WIDGET_ANDROID
#include "AndroidDecoderModule.h"
#endif
@@ -390,12 +387,6 @@ PDMFactory::CreatePDMs()
m = new AppleDecoderModule();
StartupPDM(m);
#endif
-#ifdef MOZ_GONK_MEDIACODEC
- if (MediaPrefs::PDMGonkDecoderEnabled()) {
- m = new GonkDecoderModule();
- StartupPDM(m);
- }
-#endif
#ifdef MOZ_WIDGET_ANDROID
if(MediaPrefs::PDMAndroidMediaCodecEnabled()){
m = new AndroidDecoderModule();
diff --git a/dom/media/platforms/agnostic/AOMDecoder.cpp b/dom/media/platforms/agnostic/AOMDecoder.cpp
new file mode 100644
index 000000000..b5d21375e
--- /dev/null
+++ b/dom/media/platforms/agnostic/AOMDecoder.cpp
@@ -0,0 +1,332 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "AOMDecoder.h"
+#include "MediaResult.h"
+#include "TimeUnits.h"
+#include "aom/aomdx.h"
+#include "aom/aom_image.h"
+#include "gfx2DGlue.h"
+#include "mozilla/PodOperations.h"
+#include "mozilla/SyncRunnable.h"
+#include "nsError.h"
+#include "prsystem.h"
+
+#include <algorithm>
+
+#undef LOG
+#define LOG(arg, ...) MOZ_LOG(sPDMLog, mozilla::LogLevel::Debug, ("AOMDecoder(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
+
+namespace mozilla {
+
+using namespace gfx;
+using namespace layers;
+
+AOMDecoder::AOMDecoder(const CreateDecoderParams& aParams)
+ : mImageContainer(aParams.mImageContainer)
+ , mTaskQueue(aParams.mTaskQueue)
+ , mCallback(aParams.mCallback)
+ , mIsFlushing(false)
+ , mInfo(aParams.VideoConfig())
+{
+ PodZero(&mCodec);
+}
+
+AOMDecoder::~AOMDecoder()
+{
+}
+
+void
+AOMDecoder::Shutdown()
+{
+ aom_codec_destroy(&mCodec);
+}
+
+RefPtr<MediaDataDecoder::InitPromise>
+AOMDecoder::Init()
+{
+ int decode_threads = 2;
+
+ aom_codec_iface_t* dx = aom_codec_av1_dx();
+ if (mInfo.mDisplay.width >= 2048) {
+ decode_threads = 8;
+ }
+ else if (mInfo.mDisplay.width >= 1024) {
+ decode_threads = 4;
+ }
+ decode_threads = std::min(decode_threads, PR_GetNumberOfProcessors());
+
+ aom_codec_dec_cfg_t config;
+ PodZero(&config);
+ config.threads = decode_threads;
+ config.w = config.h = 0; // set after decode
+ config.allow_lowbitdepth = true;
+
+ aom_codec_flags_t flags = 0;
+
+ if (!dx || aom_codec_dec_init(&mCodec, dx, &config, flags)) {
+ return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__);
+ }
+ return InitPromise::CreateAndResolve(TrackInfo::kVideoTrack, __func__);
+}
+
+void
+AOMDecoder::Flush()
+{
+ MOZ_ASSERT(mCallback->OnReaderTaskQueue());
+ mIsFlushing = true;
+ nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction([this] () {
+ // nothing to do for now.
+ });
+ SyncRunnable::DispatchToThread(mTaskQueue, r);
+ mIsFlushing = false;
+}
+
+// Ported from third_party/aom/tools_common.c.
+static aom_codec_err_t
+highbd_img_downshift(aom_image_t *dst, aom_image_t *src, int down_shift) {
+ int plane;
+ if (dst->d_w != src->d_w || dst->d_h != src->d_h)
+ return AOM_CODEC_INVALID_PARAM;
+ if (dst->x_chroma_shift != src->x_chroma_shift)
+ return AOM_CODEC_INVALID_PARAM;
+ if (dst->y_chroma_shift != src->y_chroma_shift)
+ return AOM_CODEC_INVALID_PARAM;
+ if (dst->fmt != (src->fmt & ~AOM_IMG_FMT_HIGHBITDEPTH))
+ return AOM_CODEC_INVALID_PARAM;
+ if (down_shift < 0)
+ return AOM_CODEC_INVALID_PARAM;
+ switch (dst->fmt) {
+ case AOM_IMG_FMT_I420:
+ case AOM_IMG_FMT_I422:
+ case AOM_IMG_FMT_I444:
+ break;
+ default:
+ return AOM_CODEC_INVALID_PARAM;
+ }
+ switch (src->fmt) {
+ case AOM_IMG_FMT_I42016:
+ case AOM_IMG_FMT_I42216:
+ case AOM_IMG_FMT_I44416:
+ break;
+ default:
+ // We don't support anything that's not 16 bit
+ return AOM_CODEC_UNSUP_BITSTREAM;
+ }
+ for (plane = 0; plane < 3; plane++) {
+ int w = src->d_w;
+ int h = src->d_h;
+ int x, y;
+ if (plane) {
+ w = (w + src->x_chroma_shift) >> src->x_chroma_shift;
+ h = (h + src->y_chroma_shift) >> src->y_chroma_shift;
+ }
+ for (y = 0; y < h; y++) {
+ uint16_t *p_src =
+ (uint16_t *)(src->planes[plane] + y * src->stride[plane]);
+ uint8_t *p_dst =
+ dst->planes[plane] + y * dst->stride[plane];
+ for (x = 0; x < w; x++) *p_dst++ = (*p_src++ >> down_shift) & 0xFF;
+ }
+ }
+ return AOM_CODEC_OK;
+}
+
+// UniquePtr dtor wrapper for aom_image_t.
+struct AomImageFree {
+ void operator()(aom_image_t* img) { aom_img_free(img); }
+};
+
+MediaResult
+AOMDecoder::DoDecode(MediaRawData* aSample)
+{
+ MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
+
+#if defined(DEBUG)
+ NS_ASSERTION(IsKeyframe(*aSample) == aSample->mKeyframe,
+ "AOM Decode Keyframe error sample->mKeyframe and si.si_kf out of sync");
+#endif
+
+ if (aom_codec_err_t r = aom_codec_decode(&mCodec, aSample->Data(), aSample->Size(), nullptr)) {
+ LOG("AOM Decode error: %s", aom_codec_err_to_string(r));
+ return MediaResult(
+ NS_ERROR_DOM_MEDIA_DECODE_ERR,
+ RESULT_DETAIL("AOM error decoding AV1 sample: %s", aom_codec_err_to_string(r)));
+ }
+
+ aom_codec_iter_t iter = nullptr;
+ aom_image_t *img;
+ UniquePtr<aom_image_t, AomImageFree> img8;
+
+ while ((img = aom_codec_get_frame(&mCodec, &iter))) {
+ // Track whether the underlying buffer is 8 or 16 bits per channel.
+ bool highbd = bool(img->fmt & AOM_IMG_FMT_HIGHBITDEPTH);
+ if (highbd) {
+ // Downsample images with more than 8 bits per channel.
+ aom_img_fmt_t fmt8 = static_cast<aom_img_fmt_t>(img->fmt ^ AOM_IMG_FMT_HIGHBITDEPTH);
+ img8.reset(aom_img_alloc(NULL, fmt8, img->d_w, img->d_h, 16));
+ if (img8 == nullptr) {
+ LOG("Couldn't allocate bitdepth reduction target!");
+ return MediaResult(
+ NS_ERROR_OUT_OF_MEMORY,
+ RESULT_DETAIL("Couldn't allocate conversion buffer for AV1 frame"));
+ }
+ if (aom_codec_err_t r = highbd_img_downshift(img8.get(), img, img->bit_depth - 8)) {
+ return MediaResult(
+ NS_ERROR_DOM_MEDIA_DECODE_ERR,
+ RESULT_DETAIL("Error converting AV1 frame to 8 bits: %s",
+ aom_codec_err_to_string(r)));
+ }
+ // img normally points to storage owned by mCodec, so it is not freed.
+ // To copy out the contents of img8 we can overwrite img with an alias.
+ // Since img is assigned at the start of the while loop and img8 is held
+ // outside that loop, the alias won't outlive the storage it points to.
+ img = img8.get();
+ highbd = false;
+ }
+
+ NS_ASSERTION(img->fmt == AOM_IMG_FMT_I420 ||
+ img->fmt == AOM_IMG_FMT_I42016 ||
+ img->fmt == AOM_IMG_FMT_I444 ||
+ img->fmt == AOM_IMG_FMT_I44416,
+ "AV1 image format not I420 or I444");
+
+ // Chroma shifts are rounded down as per the decoding examples in the SDK
+ VideoData::YCbCrBuffer b;
+ b.mPlanes[0].mData = img->planes[0];
+ b.mPlanes[0].mStride = img->stride[0];
+ b.mPlanes[0].mHeight = img->d_h;
+ b.mPlanes[0].mWidth = img->d_w;
+ b.mPlanes[0].mOffset = 0;
+ b.mPlanes[0].mSkip = highbd ? 1 : 0;
+
+ b.mPlanes[1].mData = img->planes[1];
+ b.mPlanes[1].mStride = img->stride[1];
+ b.mPlanes[1].mOffset = 0;
+ b.mPlanes[1].mSkip = highbd ? 1 : 0;
+
+ b.mPlanes[2].mData = img->planes[2];
+ b.mPlanes[2].mStride = img->stride[2];
+ b.mPlanes[2].mOffset = 0;
+ b.mPlanes[2].mSkip = highbd ? 1 : 0;
+
+ if (img->fmt == AOM_IMG_FMT_I420 ||
+ img->fmt == AOM_IMG_FMT_I42016) {
+ b.mPlanes[1].mHeight = (img->d_h + 1) >> img->y_chroma_shift;
+ b.mPlanes[1].mWidth = (img->d_w + 1) >> img->x_chroma_shift;
+
+ b.mPlanes[2].mHeight = (img->d_h + 1) >> img->y_chroma_shift;
+ b.mPlanes[2].mWidth = (img->d_w + 1) >> img->x_chroma_shift;
+ } else if (img->fmt == AOM_IMG_FMT_I444) {
+ b.mPlanes[1].mHeight = img->d_h;
+ b.mPlanes[1].mWidth = img->d_w;
+
+ b.mPlanes[2].mHeight = img->d_h;
+ b.mPlanes[2].mWidth = img->d_w;
+ } else {
+ LOG("AOM Unknown image format");
+ return MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR,
+ RESULT_DETAIL("AOM Unknown image format"));
+ }
+
+ RefPtr<VideoData> v =
+ VideoData::CreateAndCopyData(mInfo,
+ mImageContainer,
+ aSample->mOffset,
+ aSample->mTime,
+ aSample->mDuration,
+ b,
+ aSample->mKeyframe,
+ aSample->mTimecode,
+ mInfo.ScaledImageRect(img->d_w,
+ img->d_h));
+
+ if (!v) {
+ LOG("Image allocation error source %ux%u display %ux%u picture %ux%u",
+ img->d_w, img->d_h, mInfo.mDisplay.width, mInfo.mDisplay.height,
+ mInfo.mImage.width, mInfo.mImage.height);
+ return MediaResult(NS_ERROR_OUT_OF_MEMORY, __func__);
+ }
+ mCallback->Output(v);
+ }
+ return NS_OK;
+}
+
+void
+AOMDecoder::ProcessDecode(MediaRawData* aSample)
+{
+ MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
+ if (mIsFlushing) {
+ return;
+ }
+ MediaResult rv = DoDecode(aSample);
+ if (NS_FAILED(rv)) {
+ mCallback->Error(rv);
+ } else {
+ mCallback->InputExhausted();
+ }
+}
+
+void
+AOMDecoder::Input(MediaRawData* aSample)
+{
+ MOZ_ASSERT(mCallback->OnReaderTaskQueue());
+ mTaskQueue->Dispatch(NewRunnableMethod<RefPtr<MediaRawData>>(
+ this, &AOMDecoder::ProcessDecode, aSample));
+}
+
+void
+AOMDecoder::ProcessDrain()
+{
+ MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
+ mCallback->DrainComplete();
+}
+
+void
+AOMDecoder::Drain()
+{
+ MOZ_ASSERT(mCallback->OnReaderTaskQueue());
+ mTaskQueue->Dispatch(NewRunnableMethod(this, &AOMDecoder::ProcessDrain));
+}
+
+/* static */
+bool
+AOMDecoder::IsAV1(const nsACString& aMimeType)
+{
+ return aMimeType.EqualsLiteral("video/webm; codecs=av1") ||
+ aMimeType.EqualsLiteral("video/av1");
+}
+
+/* static */
+bool
+AOMDecoder::IsKeyframe(Span<const uint8_t> aBuffer) {
+ aom_codec_stream_info_t info;
+ PodZero(&info);
+
+ aom_codec_peek_stream_info(aom_codec_av1_dx(),
+ aBuffer.Elements(),
+ aBuffer.Length(),
+ &info);
+
+ return bool(info.is_kf);
+}
+
+/* static */
+nsIntSize
+AOMDecoder::GetFrameSize(Span<const uint8_t> aBuffer) {
+ aom_codec_stream_info_t info;
+ PodZero(&info);
+
+ aom_codec_peek_stream_info(aom_codec_av1_dx(),
+ aBuffer.Elements(),
+ aBuffer.Length(),
+ &info);
+
+ return nsIntSize(info.w, info.h);
+}
+
+} // namespace mozilla
+#undef LOG
diff --git a/dom/media/platforms/agnostic/AOMDecoder.h b/dom/media/platforms/agnostic/AOMDecoder.h
new file mode 100644
index 000000000..ec6b1f95a
--- /dev/null
+++ b/dom/media/platforms/agnostic/AOMDecoder.h
@@ -0,0 +1,62 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#if !defined(AOMDecoder_h_)
+#define AOMDecoder_h_
+
+#include "PlatformDecoderModule.h"
+#include "mozilla/Span.h"
+
+#include <stdint.h>
+#include "aom/aom_decoder.h"
+
+namespace mozilla {
+
+class AOMDecoder : public MediaDataDecoder
+{
+public:
+ explicit AOMDecoder(const CreateDecoderParams& aParams);
+
+ RefPtr<InitPromise> Init() override;
+ void Input(MediaRawData* aSample) override;
+ void Flush() override;
+ void Drain() override;
+ void Shutdown() override;
+ const char* GetDescriptionName() const override
+ {
+ return "libaom (AV1) video decoder";
+ }
+
+ // Return true if aMimeType is a one of the strings used
+ // by our demuxers to identify AV1 streams.
+ static bool IsAV1(const nsACString& aMimeType);
+
+ // Return true if a sample is a keyframe.
+ static bool IsKeyframe(Span<const uint8_t> aBuffer);
+
+ // Return the frame dimensions for a sample.
+ static nsIntSize GetFrameSize(Span<const uint8_t> aBuffer);
+
+private:
+ ~AOMDecoder();
+ void ProcessDecode(MediaRawData* aSample);
+ MediaResult DoDecode(MediaRawData* aSample);
+ void ProcessDrain();
+
+ const RefPtr<layers::ImageContainer> mImageContainer;
+ const RefPtr<TaskQueue> mTaskQueue;
+ MediaDataDecoderCallback* mCallback;
+ Atomic<bool> mIsFlushing;
+
+ // AOM decoder state
+ aom_codec_ctx_t mCodec;
+
+ const VideoInfo& mInfo;
+};
+
+} // namespace mozilla
+
+#endif // AOMDecoder_h_
diff --git a/dom/media/platforms/agnostic/AgnosticDecoderModule.cpp b/dom/media/platforms/agnostic/AgnosticDecoderModule.cpp
index 7bd75b7fe..cf5ed3d22 100644
--- a/dom/media/platforms/agnostic/AgnosticDecoderModule.cpp
+++ b/dom/media/platforms/agnostic/AgnosticDecoderModule.cpp
@@ -5,6 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "AgnosticDecoderModule.h"
+#include "MediaPrefs.h"
#include "mozilla/Logging.h"
#include "OpusDecoder.h"
#include "VorbisDecoder.h"
@@ -12,6 +13,10 @@
#include "WAVDecoder.h"
#include "TheoraDecoder.h"
+#ifdef MOZ_AV1
+#include "AOMDecoder.h"
+#endif
+
namespace mozilla {
bool
@@ -24,6 +29,11 @@ AgnosticDecoderModule::SupportsMimeType(const nsACString& aMimeType,
VorbisDataDecoder::IsVorbis(aMimeType) ||
WaveDataDecoder::IsWave(aMimeType) ||
TheoraDecoder::IsTheora(aMimeType);
+#ifdef MOZ_AV1
+ if (MediaPrefs::AV1Enabled()) {
+ supports |= AOMDecoder::IsAV1(aMimeType);
+ }
+#endif
MOZ_LOG(sPDMLog, LogLevel::Debug, ("Agnostic decoder %s requested type",
supports ? "supports" : "rejects"));
return supports;
@@ -36,7 +46,14 @@ AgnosticDecoderModule::CreateVideoDecoder(const CreateDecoderParams& aParams)
if (VPXDecoder::IsVPX(aParams.mConfig.mMimeType)) {
m = new VPXDecoder(aParams);
- } else if (TheoraDecoder::IsTheora(aParams.mConfig.mMimeType)) {
+ }
+#ifdef MOZ_AV1
+ else if (AOMDecoder::IsAV1(aParams.mConfig.mMimeType) &&
+ MediaPrefs::AV1Enabled()) {
+ m = new AOMDecoder(aParams);
+ }
+#endif
+ else if (TheoraDecoder::IsTheora(aParams.mConfig.mMimeType)) {
m = new TheoraDecoder(aParams);
}
diff --git a/dom/media/platforms/agnostic/VPXDecoder.cpp b/dom/media/platforms/agnostic/VPXDecoder.cpp
index 77c81b51b..f2f84487f 100644
--- a/dom/media/platforms/agnostic/VPXDecoder.cpp
+++ b/dom/media/platforms/agnostic/VPXDecoder.cpp
@@ -22,7 +22,7 @@ namespace mozilla {
using namespace gfx;
using namespace layers;
-static int MimeTypeToCodec(const nsACString& aMimeType)
+static VPXDecoder::Codec MimeTypeToCodec(const nsACString& aMimeType)
{
if (aMimeType.EqualsLiteral("video/webm; codecs=vp8")) {
return VPXDecoder::Codec::VP8;
@@ -31,7 +31,7 @@ static int MimeTypeToCodec(const nsACString& aMimeType)
} else if (aMimeType.EqualsLiteral("video/vp9")) {
return VPXDecoder::Codec::VP9;
}
- return -1;
+ return VPXDecoder::Codec::Unknown;
}
VPXDecoder::VPXDecoder(const CreateDecoderParams& aParams)
@@ -101,17 +101,10 @@ MediaResult
VPXDecoder::DoDecode(MediaRawData* aSample)
{
MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
+
#if defined(DEBUG)
- vpx_codec_stream_info_t si;
- PodZero(&si);
- si.sz = sizeof(si);
- if (mCodec == Codec::VP8) {
- vpx_codec_peek_stream_info(vpx_codec_vp8_dx(), aSample->Data(), aSample->Size(), &si);
- } else if (mCodec == Codec::VP9) {
- vpx_codec_peek_stream_info(vpx_codec_vp9_dx(), aSample->Data(), aSample->Size(), &si);
- }
- NS_ASSERTION(bool(si.is_kf) == aSample->mKeyframe,
- "VPX Decode Keyframe error sample->mKeyframe and si.si_kf out of sync");
+ NS_ASSERTION(IsKeyframe(*aSample, mCodec) == aSample->mKeyframe,
+ "VPX Decode Keyframe error sample->mKeyframe and sample data out of sync");
#endif
if (vpx_codec_err_t r = vpx_codec_decode(&mVPX, aSample->Data(), aSample->Size(), nullptr, 0)) {
@@ -249,5 +242,41 @@ VPXDecoder::IsVP9(const nsACString& aMimeType)
return IsVPX(aMimeType, VPXDecoder::VP9);
}
+/* static */
+bool
+VPXDecoder::IsKeyframe(Span<const uint8_t> aBuffer, Codec aCodec)
+{
+ vpx_codec_stream_info_t si;
+ PodZero(&si);
+ si.sz = sizeof(si);
+
+ if (aCodec == Codec::VP8) {
+ vpx_codec_peek_stream_info(vpx_codec_vp8_dx(), aBuffer.Elements(), aBuffer.Length(), &si);
+ return bool(si.is_kf);
+ } else if (aCodec == Codec::VP9) {
+ vpx_codec_peek_stream_info(vpx_codec_vp9_dx(), aBuffer.Elements(), aBuffer.Length(), &si);
+ return bool(si.is_kf);
+ }
+
+ return false;
+}
+
+/* static */
+nsIntSize
+VPXDecoder::GetFrameSize(Span<const uint8_t> aBuffer, Codec aCodec)
+{
+ vpx_codec_stream_info_t si;
+ PodZero(&si);
+ si.sz = sizeof(si);
+
+ if (aCodec == Codec::VP8) {
+ vpx_codec_peek_stream_info(vpx_codec_vp8_dx(), aBuffer.Elements(), aBuffer.Length(), &si);
+ } else if (aCodec == Codec::VP9) {
+ vpx_codec_peek_stream_info(vpx_codec_vp9_dx(), aBuffer.Elements(), aBuffer.Length(), &si);
+ }
+
+ return nsIntSize(si.w, si.h);
+}
+
} // namespace mozilla
#undef LOG
diff --git a/dom/media/platforms/agnostic/VPXDecoder.h b/dom/media/platforms/agnostic/VPXDecoder.h
index d420ec069..4e8d83617 100644
--- a/dom/media/platforms/agnostic/VPXDecoder.h
+++ b/dom/media/platforms/agnostic/VPXDecoder.h
@@ -7,6 +7,7 @@
#define VPXDecoder_h_
#include "PlatformDecoderModule.h"
+#include "mozilla/Span.h"
#include <stdint.h>
#define VPX_DONT_DEFINE_STDINT_TYPES
@@ -36,7 +37,8 @@ public:
enum Codec: uint8_t {
VP8 = 1 << 0,
- VP9 = 1 << 1
+ VP9 = 1 << 1,
+ Unknown = 1 << 7,
};
// Return true if aMimeType is a one of the strings used by our demuxers to
@@ -46,6 +48,12 @@ public:
static bool IsVP8(const nsACString& aMimeType);
static bool IsVP9(const nsACString& aMimeType);
+ // Return true if a sample is a keyframe for the specified codec.
+ static bool IsKeyframe(Span<const uint8_t> aBuffer, Codec aCodec);
+
+ // Return the frame dimensions for a sample for the specified codec.
+ static nsIntSize GetFrameSize(Span<const uint8_t> aBuffer, Codec aCodec);
+
private:
void ProcessDecode(MediaRawData* aSample);
MediaResult DoDecode(MediaRawData* aSample);
@@ -61,7 +69,7 @@ private:
const VideoInfo& mInfo;
- const int mCodec;
+ const Codec mCodec;
};
} // namespace mozilla
diff --git a/dom/media/platforms/ffmpeg/FFmpegDataDecoder.cpp b/dom/media/platforms/ffmpeg/FFmpegDataDecoder.cpp
index 8cb5c8578..8655ce25f 100644
--- a/dom/media/platforms/ffmpeg/FFmpegDataDecoder.cpp
+++ b/dom/media/platforms/ffmpeg/FFmpegDataDecoder.cpp
@@ -69,12 +69,21 @@ FFmpegDataDecoder<LIBAV_VER>::InitDecoder()
mCodecContext->extradata_size = mExtraData->Length();
// FFmpeg may use SIMD instructions to access the data which reads the
// data in 32 bytes block. Must ensure we have enough data to read.
+ uint32_t padding_size =
#if LIBAVCODEC_VERSION_MAJOR >= 58
- mExtraData->AppendElements(AV_INPUT_BUFFER_PADDING_SIZE);
+ AV_INPUT_BUFFER_PADDING_SIZE;
#else
- mExtraData->AppendElements(FF_INPUT_BUFFER_PADDING_SIZE);
+ FF_INPUT_BUFFER_PADDING_SIZE;
#endif
- mCodecContext->extradata = mExtraData->Elements();
+ mCodecContext->extradata = static_cast<uint8_t*>(
+ mLib->av_malloc(mExtraData->Length() + padding_size));
+ if (!mCodecContext->extradata) {
+ return MediaResult(NS_ERROR_OUT_OF_MEMORY,
+ RESULT_DETAIL("Couldn't init ffmpeg extradata"));
+ }
+ memcpy(mCodecContext->extradata,
+ mExtraData->Elements(),
+ mExtraData->Length());
} else {
mCodecContext->extradata_size = 0;
}
@@ -165,6 +174,9 @@ FFmpegDataDecoder<LIBAV_VER>::ProcessShutdown()
StaticMutexAutoLock mon(sMonitor);
if (mCodecContext) {
+ if (mCodecContext->extradata) {
+ mLib->av_freep(&mCodecContext->extradata);
+ }
mLib->avcodec_close(mCodecContext);
mLib->av_freep(&mCodecContext);
#if LIBAVCODEC_VERSION_MAJOR >= 55
diff --git a/dom/media/platforms/ffmpeg/FFmpegLibWrapper.cpp b/dom/media/platforms/ffmpeg/FFmpegLibWrapper.cpp
index 6302882a6..426e9f74b 100644
--- a/dom/media/platforms/ffmpeg/FFmpegLibWrapper.cpp
+++ b/dom/media/platforms/ffmpeg/FFmpegLibWrapper.cpp
@@ -7,6 +7,7 @@
#include "MediaPrefs.h"
#include "mozilla/PodOperations.h"
#include "mozilla/Types.h"
+#include "PlatformDecoderModule.h"
#include "prlink.h"
#define AV_LOG_DEBUG 48
@@ -144,6 +145,8 @@ FFmpegLibWrapper::Link()
AV_FUNC(avcodec_alloc_frame, (AV_FUNC_53 | AV_FUNC_54))
AV_FUNC(avcodec_get_frame_defaults, (AV_FUNC_53 | AV_FUNC_54))
AV_FUNC(avcodec_free_frame, AV_FUNC_54)
+ AV_FUNC(avcodec_send_packet, AV_FUNC_58)
+ AV_FUNC(avcodec_receive_frame, AV_FUNC_58)
AV_FUNC(av_log_set_level, AV_FUNC_AVUTIL_ALL)
AV_FUNC(av_malloc, AV_FUNC_AVUTIL_ALL)
AV_FUNC(av_freep, AV_FUNC_AVUTIL_ALL)
diff --git a/dom/media/platforms/ffmpeg/FFmpegLibWrapper.h b/dom/media/platforms/ffmpeg/FFmpegLibWrapper.h
index d6944a1d8..b968edd32 100644
--- a/dom/media/platforms/ffmpeg/FFmpegLibWrapper.h
+++ b/dom/media/platforms/ffmpeg/FFmpegLibWrapper.h
@@ -5,6 +5,7 @@
#ifndef __FFmpegLibWrapper_h__
#define __FFmpegLibWrapper_h__
+#include "mozilla/Attributes.h"
#include "mozilla/Types.h"
struct AVCodec;
@@ -70,6 +71,10 @@ struct FFmpegLibWrapper
// libavcodec v54 only
void (*avcodec_free_frame)(AVFrame** frame);
+ // libavcodec v58 and later only
+ int (*avcodec_send_packet)(AVCodecContext* avctx, const AVPacket* avpkt);
+ int (*avcodec_receive_frame)(AVCodecContext* avctx, AVFrame* frame);
+
// libavutil
void (*av_log_set_level)(int level);
void* (*av_malloc)(size_t size);
@@ -91,4 +96,4 @@ private:
} // namespace mozilla
-#endif // FFmpegLibWrapper \ No newline at end of file
+#endif // FFmpegLibWrapper
diff --git a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
index aec1e9136..f3101e44c 100644
--- a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
+++ b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
@@ -174,12 +174,15 @@ FFmpegVideoDecoder<LIBAV_VER>::DoDecode(MediaRawData* aSample, bool* aGotFrame)
uint8_t* inputData = const_cast<uint8_t*>(aSample->Data());
size_t inputSize = aSample->Size();
-#if LIBAVCODEC_VERSION_MAJOR >= 54
+#if LIBAVCODEC_VERSION_MAJOR >= 54 && LIBAVCODEC_VERSION_MAJOR < 58
if (inputSize && mCodecParser && (mCodecID == AV_CODEC_ID_VP8
-#if LIBAVCODEC_VERSION_MAJOR >= 55
+#if LIBAVCODEC_VERSION_MAJOR >= 55 && LIBAVCODEC_VERSION_MAJOR < 58
|| mCodecID == AV_CODEC_ID_VP9
#endif
- )) {
+ ))
+#endif
+#if LIBAVCODEC_VERSION_MAJOR >= 54
+ {
while (inputSize) {
uint8_t* data = inputData;
int size = inputSize;
@@ -224,6 +227,48 @@ FFmpegVideoDecoder<LIBAV_VER>::DoDecode(MediaRawData* aSample,
packet.flags = aSample->mKeyframe ? AV_PKT_FLAG_KEY : 0;
packet.pos = aSample->mOffset;
+#if LIBAVCODEC_VERSION_MAJOR >= 58
+ packet.duration = aSample->mDuration;
+ int res = mLib->avcodec_send_packet(mCodecContext, &packet);
+ if (res < 0) {
+ // In theory, avcodec_send_packet could sent -EAGAIN should its internal
+ // buffers be full. In practice this can't happen as we only feed one frame
+ // at a time, and we immediately call avcodec_receive_frame right after.
+ FFMPEG_LOG("avcodec_send_packet error: %d", res);
+ return MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR,
+ RESULT_DETAIL("avcodec_send_packet error: %d", res));
+ }
+
+ if (aGotFrame) {
+ *aGotFrame = false;
+ }
+ do {
+ if (!PrepareFrame()) {
+ NS_WARNING("FFmpeg h264 decoder failed to allocate frame.");
+ return MediaResult(NS_ERROR_OUT_OF_MEMORY, __func__);
+ }
+ res = mLib->avcodec_receive_frame(mCodecContext, mFrame);
+ if (res == int(AVERROR_EOF)) {
+ return NS_ERROR_DOM_MEDIA_END_OF_STREAM;
+ }
+ if (res == AVERROR(EAGAIN)) {
+ return NS_OK;
+ }
+ if (res < 0) {
+ FFMPEG_LOG("avcodec_receive_frame error: %d", res);
+ return MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR,
+ RESULT_DETAIL("avcodec_receive_frame error: %d", res));
+ }
+ MediaResult rv = CreateImage(mFrame->pkt_pos, mFrame->pkt_pts,
+ mFrame->pkt_duration);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ if (aGotFrame) {
+ *aGotFrame = true;
+ }
+ } while (true);
+#else
// LibAV provides no API to retrieve the decoded sample's duration.
// (FFmpeg >= 1.0 provides av_frame_get_pkt_duration)
// As such we instead use a map using the dts as key that we will retrieve
@@ -276,8 +321,21 @@ FFmpegVideoDecoder<LIBAV_VER>::DoDecode(MediaRawData* aSample,
// against the map becoming extremely big.
mDurationMap.Clear();
}
+
+ MediaResult rv = CreateImage(aSample->mOffset, pts, duration);
+ if (NS_SUCCEEDED(rv) && aGotFrame) {
+ *aGotFrame = true;
+ }
+ return rv;
+#endif
+}
+
+MediaResult
+FFmpegVideoDecoder<LIBAV_VER>::CreateImage(int64_t aOffset, int64_t aPts,
+ int64_t aDuration)
+{
FFMPEG_LOG("Got one frame output with pts=%lld dts=%lld duration=%lld opaque=%lld",
- pts, mFrame->pkt_dts, duration, mCodecContext->reordered_opaque);
+ aPts, mFrame->pkt_dts, aDuration, mCodecContext->reordered_opaque);
VideoData::YCbCrBuffer b;
b.mPlanes[0].mData = mFrame->data[0];
@@ -317,9 +375,9 @@ FFmpegVideoDecoder<LIBAV_VER>::DoDecode(MediaRawData* aSample,
RefPtr<VideoData> v =
VideoData::CreateAndCopyData(mInfo,
mImageContainer,
- aSample->mOffset,
- pts,
- duration,
+ aOffset,
+ aPts,
+ aDuration,
b,
!!mFrame->key_frame,
-1,
@@ -331,9 +389,6 @@ FFmpegVideoDecoder<LIBAV_VER>::DoDecode(MediaRawData* aSample,
RESULT_DETAIL("image allocation error"));
}
mCallback->Output(v);
- if (aGotFrame) {
- *aGotFrame = true;
- }
return NS_OK;
}
diff --git a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h
index 786df0da1..49a55e8a6 100644
--- a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h
+++ b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h
@@ -49,6 +49,7 @@ private:
MediaResult DoDecode(MediaRawData* aSample) override;
MediaResult DoDecode(MediaRawData* aSample, bool* aGotFrame);
MediaResult DoDecode(MediaRawData* aSample, uint8_t* aData, int aSize, bool* aGotFrame);
+ MediaResult CreateImage(int64_t aOffset, int64_t aPts, int64_t aDuration);
void ProcessDrain() override;
void ProcessFlush() override;
void OutputDelayedFrames();
diff --git a/dom/media/platforms/ffmpeg/ffvpx/moz.build b/dom/media/platforms/ffmpeg/ffvpx/moz.build
index aee58b5b0..c0041a4d4 100644
--- a/dom/media/platforms/ffmpeg/ffvpx/moz.build
+++ b/dom/media/platforms/ffmpeg/ffvpx/moz.build
@@ -20,7 +20,7 @@ SOURCES += [
]
LOCAL_INCLUDES += [
'..',
- '../ffmpeg57/include',
+ '../ffmpeg58/include',
]
if CONFIG['OS_ARCH'] == 'WINNT':
diff --git a/dom/media/platforms/moz.build b/dom/media/platforms/moz.build
index 3fb0cc842..f5fb72c5d 100644
--- a/dom/media/platforms/moz.build
+++ b/dom/media/platforms/moz.build
@@ -10,7 +10,6 @@ EXPORTS += [
'agnostic/TheoraDecoder.h',
'agnostic/VorbisDecoder.h',
'agnostic/VPXDecoder.h',
- 'MediaTelemetryConstants.h',
'PDMFactory.h',
'PlatformDecoderModule.h',
'wrappers/FuzzingWrapper.h',
@@ -55,6 +54,14 @@ if CONFIG['MOZ_FFMPEG']:
'ffmpeg',
]
+if CONFIG['MOZ_AV1']:
+ EXPORTS += [
+ 'agnostic/AOMDecoder.h',
+ ]
+ UNIFIED_SOURCES += [
+ 'agnostic/AOMDecoder.cpp',
+ ]
+
if CONFIG['MOZ_APPLEMEDIA']:
EXPORTS += [
'apple/AppleDecoderModule.h',
diff --git a/dom/media/platforms/omx/OmxPlatformLayer.cpp b/dom/media/platforms/omx/OmxPlatformLayer.cpp
index 039b4a22f..15b3062a4 100644
--- a/dom/media/platforms/omx/OmxPlatformLayer.cpp
+++ b/dom/media/platforms/omx/OmxPlatformLayer.cpp
@@ -282,26 +282,7 @@ OmxPlatformLayer::CompressionFormat()
}
}
-// Implementations for different platforms will be defined in their own files.
-#ifdef OMX_PLATFORM_GONK
-
-bool
-OmxPlatformLayer::SupportsMimeType(const nsACString& aMimeType)
-{
- return GonkOmxPlatformLayer::FindComponents(aMimeType);
-}
-
-OmxPlatformLayer*
-OmxPlatformLayer::Create(OmxDataDecoder* aDataDecoder,
- OmxPromiseLayer* aPromiseLayer,
- TaskQueue* aTaskQueue,
- layers::ImageContainer* aImageContainer)
-{
- return new GonkOmxPlatformLayer(aDataDecoder, aPromiseLayer, aTaskQueue, aImageContainer);
-}
-
-#else // For platforms without OMX IL support.
-
+// For platforms without OMX IL support.
bool
OmxPlatformLayer::SupportsMimeType(const nsACString& aMimeType)
{
@@ -317,6 +298,4 @@ OmxPlatformLayer::Create(OmxDataDecoder* aDataDecoder,
return nullptr;
}
-#endif
-
}
diff --git a/dom/media/platforms/wmf/DXVA2Manager.cpp b/dom/media/platforms/wmf/DXVA2Manager.cpp
index 0c1734c54..69e002f7f 100644
--- a/dom/media/platforms/wmf/DXVA2Manager.cpp
+++ b/dom/media/platforms/wmf/DXVA2Manager.cpp
@@ -14,8 +14,6 @@
#include "mozilla/layers/D3D11ShareHandleImage.h"
#include "mozilla/layers/ImageBridgeChild.h"
#include "mozilla/layers/TextureForwarder.h"
-#include "mozilla/Telemetry.h"
-#include "MediaTelemetryConstants.h"
#include "mfapi.h"
#include "gfxPrefs.h"
#include "MFTDecoder.h"
@@ -442,9 +440,6 @@ D3D9DXVA2Manager::Init(layers::KnowsCompositor* aKnowsCompositor,
}
mTextureClientAllocator->SetMaxPoolSize(5);
- Telemetry::Accumulate(Telemetry::MEDIA_DECODER_BACKEND_USED,
- uint32_t(media::MediaDecoderBackend::WMFDXVA2D3D9));
-
return S_OK;
}
@@ -775,9 +770,6 @@ D3D11DXVA2Manager::Init(layers::KnowsCompositor* aKnowsCompositor,
}
mTextureClientAllocator->SetMaxPoolSize(5);
- Telemetry::Accumulate(Telemetry::MEDIA_DECODER_BACKEND_USED,
- uint32_t(media::MediaDecoderBackend::WMFDXVA2D3D11));
-
return S_OK;
}
diff --git a/dom/media/platforms/wmf/WMFAudioMFTManager.cpp b/dom/media/platforms/wmf/WMFAudioMFTManager.cpp
index 69b62da51..3dacdf0aa 100644
--- a/dom/media/platforms/wmf/WMFAudioMFTManager.cpp
+++ b/dom/media/platforms/wmf/WMFAudioMFTManager.cpp
@@ -252,7 +252,6 @@ WMFAudioMFTManager::Output(int64_t aStreamOffset,
LOG("Audio MFTDecoder returned success but null output.");
nsCOMPtr<nsIRunnable> task = NS_NewRunnableFunction([]() -> void {
LOG("Reporting telemetry AUDIO_MFT_OUTPUT_NULL_SAMPLES");
- Telemetry::Accumulate(Telemetry::ID::AUDIO_MFT_OUTPUT_NULL_SAMPLES, 1);
});
AbstractThread::MainThread()->Dispatch(task.forget());
return E_FAIL;
diff --git a/dom/media/platforms/wmf/WMFDecoderModule.h b/dom/media/platforms/wmf/WMFDecoderModule.h
index cd7b8c660..6582f8056 100644
--- a/dom/media/platforms/wmf/WMFDecoderModule.h
+++ b/dom/media/platforms/wmf/WMFDecoderModule.h
@@ -40,10 +40,8 @@ public:
static int GetNumDecoderThreads();
// Accessors that report whether we have the required MFTs available
- // on the system to play various codecs. Windows Vista doesn't have the
- // H.264/AAC decoders if the "Platform Update Supplement for Windows Vista"
- // is not installed, and Window N and KN variants also require a "Media
- // Feature Pack" to be installed. Windows XP doesn't have WMF.
+ // on the system to play various codecs. Windows N and KN variants
+ // require a "Media Feature Pack" to be installed.
static bool HasAAC();
static bool HasH264();
diff --git a/dom/media/platforms/wmf/WMFMediaDataDecoder.cpp b/dom/media/platforms/wmf/WMFMediaDataDecoder.cpp
index d2c13eac7..e6dd29c6d 100644
--- a/dom/media/platforms/wmf/WMFMediaDataDecoder.cpp
+++ b/dom/media/platforms/wmf/WMFMediaDataDecoder.cpp
@@ -8,7 +8,6 @@
#include "VideoUtils.h"
#include "WMFUtils.h"
#include "nsTArray.h"
-#include "mozilla/Telemetry.h"
#include "mozilla/Logging.h"
#include "mozilla/SyncRunnable.h"
@@ -39,39 +38,6 @@ WMFMediaDataDecoder::Init()
return InitPromise::CreateAndResolve(mMFTManager->GetType(), __func__);
}
-// A single telemetry sample is reported for each MediaDataDecoder object
-// that has detected error or produced output successfully.
-static void
-SendTelemetry(unsigned long hr)
-{
- // Collapse the error codes into a range of 0-0xff that can be viewed in
- // telemetry histograms. For most MF_E_* errors, unique samples are used,
- // retaining the least significant 7 or 8 bits. Other error codes are
- // bucketed.
- uint32_t sample;
- if (SUCCEEDED(hr)) {
- sample = 0;
- } else if (hr < 0xc00d36b0) {
- sample = 1; // low bucket
- } else if (hr < 0xc00d3700) {
- sample = hr & 0xffU; // MF_E_*
- } else if (hr <= 0xc00d3705) {
- sample = 0x80 + (hr & 0xfU); // more MF_E_*
- } else if (hr < 0xc00d6d60) {
- sample = 2; // mid bucket
- } else if (hr <= 0xc00d6d78) {
- sample = hr & 0xffU; // MF_E_TRANSFORM_*
- } else {
- sample = 3; // high bucket
- }
-
- nsCOMPtr<nsIRunnable> runnable = NS_NewRunnableFunction(
- [sample] {
- Telemetry::Accumulate(Telemetry::MEDIA_WMF_DECODE_ERROR, sample);
- });
- NS_DispatchToMainThread(runnable);
-}
-
void
WMFMediaDataDecoder::Shutdown()
{
@@ -91,9 +57,6 @@ WMFMediaDataDecoder::ProcessShutdown()
if (mMFTManager) {
mMFTManager->Shutdown();
mMFTManager = nullptr;
- if (!mRecordedError && mHasSuccessfulOutput) {
- SendTelemetry(S_OK);
- }
}
}
@@ -125,10 +88,6 @@ WMFMediaDataDecoder::ProcessDecode(MediaRawData* aSample)
NS_WARNING("MFTManager rejected sample");
mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR,
RESULT_DETAIL("MFTManager::Input:%x", hr)));
- if (!mRecordedError) {
- SendTelemetry(hr);
- mRecordedError = true;
- }
return;
}
@@ -144,7 +103,6 @@ WMFMediaDataDecoder::ProcessOutput()
HRESULT hr = S_OK;
while (SUCCEEDED(hr = mMFTManager->Output(mLastStreamOffset, output)) &&
output) {
- mHasSuccessfulOutput = true;
mCallback->Output(output);
}
if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) {
@@ -153,10 +111,6 @@ WMFMediaDataDecoder::ProcessOutput()
NS_WARNING("WMFMediaDataDecoder failed to output data");
mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR,
RESULT_DETAIL("MFTManager::Output:%x", hr)));
- if (!mRecordedError) {
- SendTelemetry(hr);
- mRecordedError = true;
- }
}
}
diff --git a/dom/media/platforms/wmf/WMFMediaDataDecoder.h b/dom/media/platforms/wmf/WMFMediaDataDecoder.h
index a4dd49f56..f869012e7 100644
--- a/dom/media/platforms/wmf/WMFMediaDataDecoder.h
+++ b/dom/media/platforms/wmf/WMFMediaDataDecoder.h
@@ -33,7 +33,7 @@ public:
// Returns S_OK on success, or MF_E_TRANSFORM_NEED_MORE_INPUT if there's not
// enough data to produce more output. If this returns a failure code other
// than MF_E_TRANSFORM_NEED_MORE_INPUT, an error will be reported to the
- // MP4Reader.
+ // MP4Demuxer.
virtual HRESULT Output(int64_t aStreamOffset,
RefPtr<MediaData>& aOutput) = 0;
@@ -136,10 +136,6 @@ private:
Atomic<bool> mIsFlushing;
bool mIsShutDown;
-
- // For telemetry
- bool mHasSuccessfulOutput = false;
- bool mRecordedError = false;
};
} // namespace mozilla
diff --git a/dom/media/platforms/wmf/WMFVideoMFTManager.cpp b/dom/media/platforms/wmf/WMFVideoMFTManager.cpp
index 291bc5b74..a7633a7de 100644
--- a/dom/media/platforms/wmf/WMFVideoMFTManager.cpp
+++ b/dom/media/platforms/wmf/WMFVideoMFTManager.cpp
@@ -27,7 +27,6 @@
#include "mozilla/WindowsVersion.h"
#include "mozilla/Telemetry.h"
#include "nsPrintfCString.h"
-#include "MediaTelemetryConstants.h"
#include "GMPUtils.h" // For SplitAt. TODO: Move SplitAt to a central place.
#include "MP4Decoder.h"
#include "VPXDecoder.h"
@@ -128,7 +127,6 @@ WMFVideoMFTManager::~WMFVideoMFTManager()
nsCOMPtr<nsIRunnable> task = NS_NewRunnableFunction([=]() -> void {
LOG(nsPrintfCString("Reporting telemetry VIDEO_MFT_OUTPUT_NULL_SAMPLES=%d", telemetry).get());
- Telemetry::Accumulate(Telemetry::ID::VIDEO_MFT_OUTPUT_NULL_SAMPLES, telemetry);
});
AbstractThread::MainThread()->Dispatch(task.forget());
}
@@ -511,8 +509,6 @@ WMFVideoMFTManager::InitInternal(bool aForceD3D9)
if (mStreamType == VP9 || mStreamType == VP8) {
return false;
}
- Telemetry::Accumulate(Telemetry::MEDIA_DECODER_BACKEND_USED,
- uint32_t(media::MediaDecoderBackend::WMFSoftware));
}
mDecoder = decoder;
diff --git a/dom/media/systemservices/LoadManager.cpp b/dom/media/systemservices/LoadManager.cpp
index f0f4f83a7..34b8fc7e0 100644
--- a/dom/media/systemservices/LoadManager.cpp
+++ b/dom/media/systemservices/LoadManager.cpp
@@ -15,7 +15,6 @@
#include "nsThreadUtils.h"
#include "nsReadableUtils.h"
#include "nsIObserverService.h"
-#include "mozilla/Telemetry.h"
#include "mozilla/ArrayUtils.h"
// MOZ_LOG=LoadManager:5
@@ -192,23 +191,6 @@ LoadManagerSingleton::RemoveObserver(webrtc::CPULoadStateObserver * aObserver)
for (size_t i = 0; i < MOZ_ARRAY_LENGTH(mTimeInState); i++) {
total += mTimeInState[i];
}
- // Don't include short calls; we don't have reasonable load data, and
- // such short calls rarely reach a stable state. Keep relatively
- // short calls separate from longer ones
- bool log = total > 5*PR_MSEC_PER_SEC;
- bool small = log && total < 30*PR_MSEC_PER_SEC;
- if (log) {
- // Note: We don't care about rounding here; thus total may be < 100
- Telemetry::Accumulate(small ? Telemetry::WEBRTC_LOAD_STATE_RELAXED_SHORT :
- Telemetry::WEBRTC_LOAD_STATE_RELAXED,
- (uint32_t) (mTimeInState[webrtc::CPULoadState::kLoadRelaxed]/total * 100));
- Telemetry::Accumulate(small ? Telemetry::WEBRTC_LOAD_STATE_NORMAL_SHORT :
- Telemetry::WEBRTC_LOAD_STATE_NORMAL,
- (uint32_t) (mTimeInState[webrtc::CPULoadState::kLoadNormal]/total * 100));
- Telemetry::Accumulate(small ? Telemetry::WEBRTC_LOAD_STATE_STRESSED_SHORT :
- Telemetry::WEBRTC_LOAD_STATE_STRESSED,
- (uint32_t) (mTimeInState[webrtc::CPULoadState::kLoadStressed]/total * 100));
- }
for (auto &in_state : mTimeInState) {
in_state = 0;
}
diff --git a/dom/media/test/bug580982.webm b/dom/media/test/bug1377278.webm
index 802019f39..802019f39 100644
--- a/dom/media/test/bug580982.webm
+++ b/dom/media/test/bug1377278.webm
Binary files differ
diff --git a/dom/media/test/bug580982.webm^headers^ b/dom/media/test/bug1377278.webm^headers^
index 4030ea1d3..4030ea1d3 100644
--- a/dom/media/test/bug580982.webm^headers^
+++ b/dom/media/test/bug1377278.webm^headers^
diff --git a/dom/media/test/crashtests/1228484.html b/dom/media/test/crashtests/1228484.html
deleted file mode 100644
index 2b2e9b0f9..000000000
--- a/dom/media/test/crashtests/1228484.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<script>
-
-var htmlAudio = new Audio(URL.createObjectURL(new window.MediaSource()));
-
-(new window.AudioContext("ringer")).createMediaElementSource(htmlAudio);
-(new window.AudioContext("alarm")).createMediaElementSource(htmlAudio);
-
-</script>
-</head>
-</html>
diff --git a/dom/media/test/crashtests/crashtests.list b/dom/media/test/crashtests/crashtests.list
index 496fe5ee5..e4f25ca8d 100644
--- a/dom/media/test/crashtests/crashtests.list
+++ b/dom/media/test/crashtests/crashtests.list
@@ -81,8 +81,6 @@ load 1157994.html
load 1158427.html
load 1185176.html
load 1185192.html
-load 1223670.html
-load 1228484.html
load 1304948.html
load 1319486.html
load 1291702.html
diff --git a/dom/media/test/manifest.js b/dom/media/test/manifest.js
index c6d533c1b..52e53a271 100644
--- a/dom/media/test/manifest.js
+++ b/dom/media/test/manifest.js
@@ -224,6 +224,9 @@ var gPlayTests = [
// Test playback of a webm file
{ name:"seek-short.webm", type:"video/webm", duration:0.23 },
+ // Test playback of a webm file with 'matroska' doctype
+ { name:"bug1377278.webm", type:"video/webm", duration:4.0 },
+
// Test playback of a WebM file with non-zero start time.
{ name:"split.webm", type:"video/webm", duration:1.967 },
@@ -263,10 +266,10 @@ var gPlayTests = [
{ name:"small-shot.mp3", type:"audio/mpeg", duration:0.27 },
{ name:"owl.mp3", type:"audio/mpeg", duration:3.343 },
// owl.mp3 as above, but with something funny going on in the ID3v2 tag
- // that causes DirectShow to fail.
+ // that caused DirectShow to fail.
{ name:"owl-funny-id3.mp3", type:"audio/mpeg", duration:3.343 },
// owl.mp3 as above, but with something even funnier going on in the ID3v2 tag
- // that causes DirectShow to fail.
+ // that caused DirectShow to fail.
{ name:"owl-funnier-id3.mp3", type:"audio/mpeg", duration:3.343 },
// One second of silence with ~140KB of ID3 tags. Usually when the first MP3
// frame is at such a high offset into the file, MP3FrameParser will give up
@@ -532,7 +535,6 @@ var gErrorTests = [
{ name:"448636.ogv", type:"video/ogg" },
{ name:"bug504843.ogv", type:"video/ogg" },
{ name:"bug501279.ogg", type:"audio/ogg" },
- { name:"bug580982.webm", type:"video/webm" },
{ name:"bug603918.webm", type:"video/webm" },
{ name:"bug604067.webm", type:"video/webm" },
{ name:"bogus.duh", type:"bogus/duh" }
diff --git a/dom/media/test/mochitest.ini b/dom/media/test/mochitest.ini
index ddabf78b6..742ac1b1c 100644
--- a/dom/media/test/mochitest.ini
+++ b/dom/media/test/mochitest.ini
@@ -382,8 +382,6 @@ support-files =
bug556821.ogv^headers^
bug557094.ogv
bug557094.ogv^headers^
- bug580982.webm
- bug580982.webm^headers^
bug603918.webm
bug603918.webm^headers^
bug604067.webm
@@ -395,6 +393,8 @@ support-files =
bug1301226.wav^headers^
bug1301226-odd.wav
bug1301226-odd.wav^headers^
+ bug1377278.webm
+ bug1377278.webm^headers^
can_play_type_dash.js
can_play_type_ogg.js
can_play_type_wave.js
diff --git a/dom/media/test/test_can_play_type_mpeg.html b/dom/media/test/test_can_play_type_mpeg.html
index 89e5fabef..514b5cc2f 100644
--- a/dom/media/test/test_can_play_type_mpeg.html
+++ b/dom/media/test/test_can_play_type_mpeg.html
@@ -151,8 +151,7 @@ var haveMp4 = (getPref("media.wmf.enabled") && IsWindowsVistaOrLater()) ||
check_mp4(document.getElementById('v'), haveMp4);
-var haveMp3 = getPref("media.directshow.enabled") ||
- (getPref("media.wmf.enabled") && IsWindowsVistaOrLater()) ||
+var haveMp3 = getPref("media.wmf.enabled") ||
(IsLinux() && getPref("media.ffmpeg.enabled")) ||
(IsSupportedAndroid() &&
((IsJellyBeanOrLater() && getPref("media.android-media-codec.enabled")) ||
diff --git a/dom/media/webaudio/AudioBuffer.cpp b/dom/media/webaudio/AudioBuffer.cpp
index cb834f6a5..e7eba2d48 100644
--- a/dom/media/webaudio/AudioBuffer.cpp
+++ b/dom/media/webaudio/AudioBuffer.cpp
@@ -27,7 +27,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(AudioBuffer)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(AudioBuffer)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(AudioBuffer)
diff --git a/dom/media/webaudio/AudioContext.cpp b/dom/media/webaudio/AudioContext.cpp
index 85842c811..d58441309 100755
--- a/dom/media/webaudio/AudioContext.cpp
+++ b/dom/media/webaudio/AudioContext.cpp
@@ -179,23 +179,13 @@ AudioContext::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
AudioContext::Constructor(const GlobalObject& aGlobal,
ErrorResult& aRv)
{
- return AudioContext::Constructor(aGlobal,
- AudioChannelService::GetDefaultAudioChannel(),
- aRv);
-}
-
-/* static */ already_AddRefed<AudioContext>
-AudioContext::Constructor(const GlobalObject& aGlobal,
- AudioChannel aChannel,
- ErrorResult& aRv)
-{
nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(aGlobal.GetAsSupports());
if (!window) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
- RefPtr<AudioContext> object = new AudioContext(window, false, aChannel);
+ RefPtr<AudioContext> object = new AudioContext(window, false, AudioChannelService::GetDefaultAudioChannel());
aRv = object->Init();
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
diff --git a/dom/media/webaudio/AudioContext.h b/dom/media/webaudio/AudioContext.h
index 069efa986..599debef8 100644
--- a/dom/media/webaudio/AudioContext.h
+++ b/dom/media/webaudio/AudioContext.h
@@ -151,12 +151,6 @@ public:
static already_AddRefed<AudioContext>
Constructor(const GlobalObject& aGlobal, ErrorResult& aRv);
- // Constructor for regular AudioContext. A default audio channel is needed.
- static already_AddRefed<AudioContext>
- Constructor(const GlobalObject& aGlobal,
- AudioChannel aChannel,
- ErrorResult& aRv);
-
// Constructor for offline AudioContext
static already_AddRefed<AudioContext>
Constructor(const GlobalObject& aGlobal,
diff --git a/dom/media/webaudio/AudioParam.cpp b/dom/media/webaudio/AudioParam.cpp
index 6f5574993..c1a874264 100644
--- a/dom/media/webaudio/AudioParam.cpp
+++ b/dom/media/webaudio/AudioParam.cpp
@@ -22,7 +22,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(AudioParam)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(AudioParam)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mNode)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(AudioParam)
diff --git a/dom/media/webaudio/MediaBufferDecoder.cpp b/dom/media/webaudio/MediaBufferDecoder.cpp
index e9f1d5a47..f3b75ca1a 100644
--- a/dom/media/webaudio/MediaBufferDecoder.cpp
+++ b/dom/media/webaudio/MediaBufferDecoder.cpp
@@ -23,7 +23,6 @@
#include "VideoUtils.h"
#include "WebAudioUtils.h"
#include "mozilla/dom/Promise.h"
-#include "mozilla/Telemetry.h"
#include "nsPrintfCString.h"
#include "GMPService.h"
@@ -45,7 +44,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(WebAudioDecodeJob)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOutput)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSuccessCallback)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFailureCallback)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(WebAudioDecodeJob)
@@ -302,7 +300,6 @@ MediaDecodeTask::OnMetadataRead(MetadataHolder* aMetadata)
MOZ_LOG(gMediaDecoderLog,
LogLevel::Debug,
("Telemetry (WebAudio) MEDIA_CODEC_USED= '%s'", codec.get()));
- Telemetry::Accumulate(Telemetry::ID::MEDIA_CODEC_USED, codec);
});
AbstractThread::MainThread()->Dispatch(task.forget());
diff --git a/dom/media/webaudio/WaveShaperNode.cpp b/dom/media/webaudio/WaveShaperNode.cpp
index d5c617dcd..4c50f2f1d 100644
--- a/dom/media/webaudio/WaveShaperNode.cpp
+++ b/dom/media/webaudio/WaveShaperNode.cpp
@@ -23,7 +23,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(WaveShaperNode, AudioNode)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(WaveShaperNode, AudioNode)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(WaveShaperNode)
diff --git a/dom/media/webm/WebMDecoder.cpp b/dom/media/webm/WebMDecoder.cpp
index b41de6d40..9575d6e42 100644
--- a/dom/media/webm/WebMDecoder.cpp
+++ b/dom/media/webm/WebMDecoder.cpp
@@ -5,6 +5,10 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/Preferences.h"
+#ifdef MOZ_AV1
+#include "AOMDecoder.h"
+#endif
+#include "MediaPrefs.h"
#include "MediaDecoderStateMachine.h"
#include "WebMDemuxer.h"
#include "WebMDecoder.h"
@@ -65,6 +69,11 @@ WebMDecoder::CanHandleMediaType(const nsACString& aMIMETypeExcludingCodecs,
continue;
}
+#ifdef MOZ_AV1
+ if (MediaPrefs::AV1Enabled() && IsAV1CodecString(codec)) {
+ continue;
+ }
+#endif
// Some unsupported codec.
return false;
}
diff --git a/dom/media/webm/WebMDemuxer.cpp b/dom/media/webm/WebMDemuxer.cpp
index 20ed71581..013da9b2c 100644
--- a/dom/media/webm/WebMDemuxer.cpp
+++ b/dom/media/webm/WebMDemuxer.cpp
@@ -8,7 +8,11 @@
#include "MediaDecoderStateMachine.h"
#include "AbstractMediaDecoder.h"
#include "MediaResource.h"
+#ifdef MOZ_AV1
+#include "AOMDecoder.h"
+#endif
#include "OpusDecoder.h"
+#include "VPXDecoder.h"
#include "WebMDemuxer.h"
#include "WebMBufferedParser.h"
#include "gfx2DGlue.h"
@@ -24,12 +28,9 @@
#include "mozilla/Sprintf.h"
#include <algorithm>
+#include <numeric>
#include <stdint.h>
-#define VPX_DONT_DEFINE_STDINT_TYPES
-#include "vpx/vp8dx.h"
-#include "vpx/vpx_decoder.h"
-
#define WEBM_DEBUG(arg, ...) MOZ_LOG(gMediaDemuxerLog, mozilla::LogLevel::Debug, ("WebMDemuxer(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
extern mozilla::LazyLogModule gMediaDemuxerLog;
@@ -322,6 +323,9 @@ WebMDemuxer::ReadMetadata()
case NESTEGG_CODEC_VP9:
mInfo.mVideo.mMimeType = "video/webm; codecs=vp9";
break;
+ case NESTEGG_CODEC_AV1:
+ mInfo.mVideo.mMimeType = "video/webm; codecs=av1";
+ break;
default:
NS_WARNING("Unknown WebM video codec");
return NS_ERROR_FAILURE;
@@ -549,7 +553,7 @@ WebMDemuxer::GetTrackCrypto(TrackInfo::TrackType aType, size_t aTrackNumber) {
return crypto;
}
-bool
+nsresult
WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSamples)
{
if (mIsMediaSource) {
@@ -557,17 +561,18 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl
EnsureUpToDateIndex();
}
- RefPtr<NesteggPacketHolder> holder(NextPacket(aType));
+ RefPtr<NesteggPacketHolder> holder;
+ nsresult rv = NextPacket(aType, holder);
- if (!holder) {
- return false;
+ if (NS_FAILED(rv)) {
+ return rv;
}
int r = 0;
unsigned int count = 0;
r = nestegg_packet_count(holder->Packet(), &count);
if (r == -1) {
- return false;
+ return NS_ERROR_DOM_MEDIA_DEMUXER_ERR;
}
int64_t tstamp = holder->Timestamp();
int64_t duration = holder->Duration();
@@ -578,7 +583,11 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl
// video frame.
int64_t next_tstamp = INT64_MIN;
if (aType == TrackInfo::kAudioTrack) {
- RefPtr<NesteggPacketHolder> next_holder(NextPacket(aType));
+ RefPtr<NesteggPacketHolder> next_holder;
+ rv = NextPacket(aType, next_holder);
+ if (NS_FAILED(rv) && rv != NS_ERROR_DOM_MEDIA_END_OF_STREAM) {
+ return rv;
+ }
if (next_holder) {
next_tstamp = next_holder->Timestamp();
PushAudioPacket(next_holder);
@@ -593,7 +602,11 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl
}
mLastAudioFrameTime = Some(tstamp);
} else if (aType == TrackInfo::kVideoTrack) {
- RefPtr<NesteggPacketHolder> next_holder(NextPacket(aType));
+ RefPtr<NesteggPacketHolder> next_holder;
+ rv = NextPacket(aType, next_holder);
+ if (NS_FAILED(rv) && rv != NS_ERROR_DOM_MEDIA_END_OF_STREAM) {
+ return rv;
+ }
if (next_holder) {
next_tstamp = next_holder->Timestamp();
PushVideoPacket(next_holder);
@@ -610,7 +623,7 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl
}
if (mIsMediaSource && next_tstamp == INT64_MIN) {
- return false;
+ return NS_ERROR_DOM_MEDIA_END_OF_STREAM;
}
int64_t discardPadding = 0;
@@ -626,7 +639,7 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl
r = nestegg_packet_data(holder->Packet(), i, &data, &length);
if (r == -1) {
WEBM_DEBUG("nestegg_packet_data failed r=%d", r);
- return false;
+ return NS_ERROR_DOM_MEDIA_DEMUXER_ERR;
}
bool isKeyframe = false;
if (aType == TrackInfo::kAudioTrack) {
@@ -636,29 +649,46 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl
// Packet is encrypted, can't peek, use packet info
isKeyframe = nestegg_packet_has_keyframe(holder->Packet()) == NESTEGG_PACKET_HAS_KEYFRAME_TRUE;
} else {
- vpx_codec_stream_info_t si;
- PodZero(&si);
- si.sz = sizeof(si);
+ auto sample = MakeSpan(data, length);
switch (mVideoCodec) {
case NESTEGG_CODEC_VP8:
- vpx_codec_peek_stream_info(vpx_codec_vp8_dx(), data, length, &si);
+ isKeyframe = VPXDecoder::IsKeyframe(sample, VPXDecoder::Codec::VP8);
break;
case NESTEGG_CODEC_VP9:
- vpx_codec_peek_stream_info(vpx_codec_vp9_dx(), data, length, &si);
+ isKeyframe = VPXDecoder::IsKeyframe(sample, VPXDecoder::Codec::VP9);
+ break;
+#ifdef MOZ_AV1
+ case NESTEGG_CODEC_AV1:
+ isKeyframe = AOMDecoder::IsKeyframe(sample);
break;
+#endif
+ default:
+ NS_WARNING("Cannot detect keyframes in unknown WebM video codec");
+ return NS_ERROR_FAILURE;
}
- isKeyframe = si.is_kf;
if (isKeyframe) {
- // We only look for resolution changes on keyframes for both VP8 and
- // VP9. Other resolution changes are invalid.
- if (mLastSeenFrameWidth.isSome() && mLastSeenFrameHeight.isSome() &&
- (si.w != mLastSeenFrameWidth.value() ||
- si.h != mLastSeenFrameHeight.value())) {
- mInfo.mVideo.mDisplay = nsIntSize(si.w, si.h);
+ // For both VP8 and VP9, we only look for resolution changes
+ // on keyframes. Other resolution changes are invalid.
+ auto dimensions = nsIntSize(0, 0);
+ switch (mVideoCodec) {
+ case NESTEGG_CODEC_VP8:
+ dimensions = VPXDecoder::GetFrameSize(sample, VPXDecoder::Codec::VP8);
+ break;
+ case NESTEGG_CODEC_VP9:
+ dimensions = VPXDecoder::GetFrameSize(sample, VPXDecoder::Codec::VP9);
+ break;
+#ifdef MOZ_AV1
+ case NESTEGG_CODEC_AV1:
+ dimensions = AOMDecoder::GetFrameSize(sample);
+ break;
+#endif
+ }
+ if (mLastSeenFrameSize.isSome()
+ && (dimensions != mLastSeenFrameSize.value())) {
+ mInfo.mVideo.mDisplay = dimensions;
mSharedVideoTrackInfo = new SharedTrackInfo(mInfo.mVideo, ++sStreamSourceID);
}
- mLastSeenFrameWidth = Some(si.w);
- mLastSeenFrameHeight = Some(si.h);
+ mLastSeenFrameSize = Some(dimensions);
}
}
}
@@ -668,7 +698,7 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl
RefPtr<MediaRawData> sample = new MediaRawData(data, length);
if (length && !sample->Data()) {
// OOM.
- return false;
+ return NS_ERROR_OUT_OF_MEMORY;
}
sample->mTimecode = tstamp;
sample->mTime = tstamp;
@@ -721,11 +751,12 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl
}
aSamples->Push(sample);
}
- return true;
+ return NS_OK;
}
-RefPtr<NesteggPacketHolder>
-WebMDemuxer::NextPacket(TrackInfo::TrackType aType)
+nsresult
+WebMDemuxer::NextPacket(TrackInfo::TrackType aType,
+ RefPtr<NesteggPacketHolder>& aPacket)
{
bool isVideo = aType == TrackInfo::kVideoTrack;
@@ -734,56 +765,64 @@ WebMDemuxer::NextPacket(TrackInfo::TrackType aType)
bool hasType = isVideo ? mHasVideo : mHasAudio;
if (!hasType) {
- return nullptr;
+ return NS_ERROR_DOM_MEDIA_DEMUXER_ERR;
}
// The packet queue for the type that we are interested in.
WebMPacketQueue &packets = isVideo ? mVideoPackets : mAudioPackets;
if (packets.GetSize() > 0) {
- return packets.PopFront();
+ aPacket = packets.PopFront();
+ return NS_OK;
}
// Track we are interested in
uint32_t ourTrack = isVideo ? mVideoTrack : mAudioTrack;
do {
- RefPtr<NesteggPacketHolder> holder = DemuxPacket(aType);
+ RefPtr<NesteggPacketHolder> holder;
+ nsresult rv = DemuxPacket(aType, holder);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
if (!holder) {
- return nullptr;
+ return NS_ERROR_DOM_MEDIA_DEMUXER_ERR;
}
if (ourTrack == holder->Track()) {
- return holder;
+ aPacket = holder;
+ return NS_OK;
}
} while (true);
}
-RefPtr<NesteggPacketHolder>
-WebMDemuxer::DemuxPacket(TrackInfo::TrackType aType)
+nsresult
+WebMDemuxer::DemuxPacket(TrackInfo::TrackType aType,
+ RefPtr<NesteggPacketHolder>& aPacket)
{
nestegg_packet* packet;
int r = nestegg_read_packet(Context(aType), &packet);
if (r == 0) {
nestegg_read_reset(Context(aType));
- return nullptr;
+ return NS_ERROR_DOM_MEDIA_END_OF_STREAM;
} else if (r < 0) {
- return nullptr;
+ return NS_ERROR_DOM_MEDIA_DEMUXER_ERR;
}
unsigned int track = 0;
r = nestegg_packet_track(packet, &track);
if (r == -1) {
- return nullptr;
+ return NS_ERROR_DOM_MEDIA_DEMUXER_ERR;
}
int64_t offset = Resource(aType).Tell();
RefPtr<NesteggPacketHolder> holder = new NesteggPacketHolder();
if (!holder->Init(packet, offset, track, false)) {
- return nullptr;
+ return NS_ERROR_DOM_MEDIA_DEMUXER_ERR;
}
- return holder;
+ aPacket = holder;
+ return NS_OK;
}
void
@@ -943,7 +982,14 @@ WebMTrackDemuxer::Seek(media::TimeUnit aTime)
media::TimeUnit seekTime = aTime;
mSamples.Reset();
mParent->SeekInternal(mType, aTime);
- mParent->GetNextPacket(mType, &mSamples);
+ nsresult rv = mParent->GetNextPacket(mType, &mSamples);
+ if (NS_FAILED(rv)) {
+ if (rv == NS_ERROR_DOM_MEDIA_END_OF_STREAM) {
+ // Ignore the error for now, the next GetSample will be rejected with EOS.
+ return SeekPromise::CreateAndResolve(media::TimeUnit(), __func__);
+ }
+ return SeekPromise::CreateAndReject(rv, __func__);
+ }
mNeedKeyframe = true;
// Check what time we actually seeked to.
@@ -956,15 +1002,18 @@ WebMTrackDemuxer::Seek(media::TimeUnit aTime)
return SeekPromise::CreateAndResolve(seekTime, __func__);
}
-RefPtr<MediaRawData>
-WebMTrackDemuxer::NextSample()
+nsresult
+WebMTrackDemuxer::NextSample(RefPtr<MediaRawData>& aData)
{
- while (mSamples.GetSize() < 1 && mParent->GetNextPacket(mType, &mSamples)) {
+ nsresult rv;
+ while (mSamples.GetSize() < 1 &&
+ NS_SUCCEEDED((rv = mParent->GetNextPacket(mType, &mSamples)))) {
}
if (mSamples.GetSize()) {
- return mSamples.PopFront();
+ aData = mSamples.PopFront();
+ return NS_OK;
}
- return nullptr;
+ return rv;
}
RefPtr<WebMTrackDemuxer::SamplesPromise>
@@ -973,9 +1022,12 @@ WebMTrackDemuxer::GetSamples(int32_t aNumSamples)
RefPtr<SamplesHolder> samples = new SamplesHolder;
MOZ_ASSERT(aNumSamples);
+ nsresult rv = NS_ERROR_DOM_MEDIA_END_OF_STREAM;
+
while (aNumSamples) {
- RefPtr<MediaRawData> sample(NextSample());
- if (!sample) {
+ RefPtr<MediaRawData> sample;
+ rv = NextSample(sample);
+ if (NS_FAILED(rv)) {
break;
}
if (mNeedKeyframe && !sample->mKeyframe) {
@@ -987,7 +1039,7 @@ WebMTrackDemuxer::GetSamples(int32_t aNumSamples)
}
if (samples->mSamples.IsEmpty()) {
- return SamplesPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_END_OF_STREAM, __func__);
+ return SamplesPromise::CreateAndReject(rv, __func__);
} else {
UpdateSamples(samples->mSamples);
return SamplesPromise::CreateAndResolve(samples, __func__);
@@ -1022,7 +1074,8 @@ WebMTrackDemuxer::SetNextKeyFrameTime()
}
// Demux and buffer frames until we find a keyframe.
RefPtr<MediaRawData> sample;
- while (!foundKeyframe && (sample = NextSample())) {
+ nsresult rv = NS_OK;
+ while (!foundKeyframe && NS_SUCCEEDED((rv = NextSample(sample)))) {
if (sample->mKeyframe) {
frameTime = sample->mTime;
foundKeyframe = true;
@@ -1104,10 +1157,11 @@ WebMTrackDemuxer::SkipToNextRandomAccessPoint(media::TimeUnit aTimeThreshold)
uint32_t parsed = 0;
bool found = false;
RefPtr<MediaRawData> sample;
+ nsresult rv = NS_OK;
int64_t sampleTime;
WEBM_DEBUG("TimeThreshold: %f", aTimeThreshold.ToSeconds());
- while (!found && (sample = NextSample())) {
+ while (!found && NS_SUCCEEDED((rv = NextSample(sample)))) {
parsed++;
sampleTime = sample->mTime;
if (sample->mKeyframe && sampleTime >= aTimeThreshold.ToMicroseconds()) {
@@ -1116,7 +1170,9 @@ WebMTrackDemuxer::SkipToNextRandomAccessPoint(media::TimeUnit aTimeThreshold)
mSamples.PushFront(sample.forget());
}
}
- SetNextKeyFrameTime();
+ if (NS_SUCCEEDED(rv)) {
+ SetNextKeyFrameTime();
+ }
if (found) {
WEBM_DEBUG("next sample: %f (parsed: %d)",
media::TimeUnit::FromMicroseconds(sampleTime).ToSeconds(),
diff --git a/dom/media/webm/WebMDemuxer.h b/dom/media/webm/WebMDemuxer.h
index 6fff38e7d..36d381e57 100644
--- a/dom/media/webm/WebMDemuxer.h
+++ b/dom/media/webm/WebMDemuxer.h
@@ -8,9 +8,13 @@
#include "nsTArray.h"
#include "MediaDataDemuxer.h"
+#include "MediaResource.h"
#include "NesteggPacketHolder.h"
#include "mozilla/Move.h"
+#include <deque>
+#include <stdint.h>
+
typedef struct nestegg nestegg;
namespace mozilla {
@@ -111,7 +115,8 @@ public:
bool GetOffsetForTime(uint64_t aTime, int64_t* aOffset);
// Demux next WebM packet and append samples to MediaRawDataQueue
- bool GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSamples);
+ nsresult GetNextPacket(TrackInfo::TrackType aType,
+ MediaRawDataQueue *aSamples);
nsresult Reset(TrackInfo::TrackType aType);
@@ -175,11 +180,13 @@ private:
// Read a packet from the nestegg file. Returns nullptr if all packets for
// the particular track have been read. Pass TrackInfo::kVideoTrack or
// TrackInfo::kVideoTrack to indicate the type of the packet we want to read.
- RefPtr<NesteggPacketHolder> NextPacket(TrackInfo::TrackType aType);
+ nsresult NextPacket(TrackInfo::TrackType aType,
+ RefPtr<NesteggPacketHolder>& aPacket);
// Internal method that demuxes the next packet from the stream. The caller
// is responsible for making sure it doesn't get lost.
- RefPtr<NesteggPacketHolder> DemuxPacket(TrackInfo::TrackType aType);
+ nsresult DemuxPacket(TrackInfo::TrackType aType,
+ RefPtr<NesteggPacketHolder>& aPacket);
// libnestegg audio and video context for webm container.
// Access on reader's thread only.
@@ -237,8 +244,7 @@ private:
int64_t mLastWebMBlockOffset;
const bool mIsMediaSource;
- Maybe<uint32_t> mLastSeenFrameWidth;
- Maybe<uint32_t> mLastSeenFrameHeight;
+ Maybe<nsIntSize> mLastSeenFrameSize;
// This will be populated only if a resolution change occurs, otherwise it
// will be left as null so the original metadata is used
RefPtr<SharedTrackInfo> mSharedVideoTrackInfo;
@@ -276,7 +282,7 @@ private:
~WebMTrackDemuxer();
void UpdateSamples(nsTArray<RefPtr<MediaRawData>>& aSamples);
void SetNextKeyFrameTime();
- RefPtr<MediaRawData> NextSample ();
+ nsresult NextSample(RefPtr<MediaRawData>& aData);
RefPtr<WebMDemuxer> mParent;
TrackInfo::TrackType mType;
UniquePtr<TrackInfo> mInfo;
diff --git a/dom/media/webrtc/RTCCertificate.cpp b/dom/media/webrtc/RTCCertificate.cpp
index 3f778bcbb..9f5e27c56 100644
--- a/dom/media/webrtc/RTCCertificate.cpp
+++ b/dom/media/webrtc/RTCCertificate.cpp
@@ -74,7 +74,7 @@ private:
char buf[sizeof(randomName) * 2 + 4];
PL_strncpy(buf, "CN=", 3);
for (size_t i = 0; i < sizeof(randomName); ++i) {
- snprintf(&buf[i * 2 + 3], 2, "%.2x", randomName[i]);
+ snprintf(&buf[i * 2 + 3], 3, "%.2x", randomName[i]);
}
buf[sizeof(buf) - 1] = '\0';
diff --git a/dom/moz.build b/dom/moz.build
index 358fc6411..54dc0510e 100644
--- a/dom/moz.build
+++ b/dom/moz.build
@@ -94,7 +94,6 @@ DIRS += [
'xslt',
'xul',
'manifest',
- 'vr',
'u2f',
'console',
'performance',
diff --git a/dom/network/TCPSocketChild.cpp b/dom/network/TCPSocketChild.cpp
index 8eb19a1db..72581ca9d 100644
--- a/dom/network/TCPSocketChild.cpp
+++ b/dom/network/TCPSocketChild.cpp
@@ -50,7 +50,6 @@ namespace dom {
NS_IMPL_CYCLE_COLLECTION_CLASS(TCPSocketChildBase)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(TCPSocketChildBase)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSocket)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
diff --git a/dom/notification/Notification.cpp b/dom/notification/Notification.cpp
index 1dd5724e4..a5aa48b00 100644
--- a/dom/notification/Notification.cpp
+++ b/dom/notification/Notification.cpp
@@ -11,7 +11,6 @@
#include "mozilla/OwningNonNull.h"
#include "mozilla/Preferences.h"
#include "mozilla/Services.h"
-#include "mozilla/Telemetry.h"
#include "mozilla/Unused.h"
#include "mozilla/dom/AppNotificationServiceOptionsBinding.h"
@@ -642,8 +641,6 @@ NotificationPermissionRequest::ResolvePromise()
mCallback->Call(mPermission, error);
rv = error.StealNSResult();
}
- Telemetry::Accumulate(
- Telemetry::WEB_NOTIFICATION_REQUEST_PERMISSION_CALLBACK, !!mCallback);
mPromise->MaybeResolve(mPermission);
return rv;
}
@@ -658,195 +655,6 @@ NotificationPermissionRequest::GetTypes(nsIArray** aTypes)
aTypes);
}
-NS_IMPL_ISUPPORTS(NotificationTelemetryService, nsIObserver)
-
-NotificationTelemetryService::NotificationTelemetryService()
- : mDNDRecorded(false)
-{}
-
-NotificationTelemetryService::~NotificationTelemetryService()
-{
- Unused << NS_WARN_IF(NS_FAILED(RemovePermissionChangeObserver()));
-}
-
-/* static */ already_AddRefed<NotificationTelemetryService>
-NotificationTelemetryService::GetInstance()
-{
- nsCOMPtr<nsISupports> telemetrySupports =
- do_GetService(NOTIFICATIONTELEMETRYSERVICE_CONTRACTID);
- if (!telemetrySupports) {
- return nullptr;
- }
- RefPtr<NotificationTelemetryService> telemetry =
- static_cast<NotificationTelemetryService*>(telemetrySupports.get());
- return telemetry.forget();
-}
-
-nsresult
-NotificationTelemetryService::Init()
-{
- nsresult rv = AddPermissionChangeObserver();
- NS_ENSURE_SUCCESS(rv, rv);
-
- RecordPermissions();
-
- return NS_OK;
-}
-
-nsresult
-NotificationTelemetryService::RemovePermissionChangeObserver()
-{
- nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
- if (!obs) {
- return NS_ERROR_OUT_OF_MEMORY;
- }
- return obs->RemoveObserver(this, "perm-changed");
-}
-
-nsresult
-NotificationTelemetryService::AddPermissionChangeObserver()
-{
- nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
- if (!obs) {
- return NS_ERROR_OUT_OF_MEMORY;
- }
- return obs->AddObserver(this, "perm-changed", false);
-}
-
-void
-NotificationTelemetryService::RecordPermissions()
-{
- if (!Telemetry::CanRecordBase() || !Telemetry::CanRecordExtended()) {
- return;
- }
-
- nsCOMPtr<nsIPermissionManager> permissionManager =
- services::GetPermissionManager();
- if (!permissionManager) {
- return;
- }
-
- nsCOMPtr<nsISimpleEnumerator> enumerator;
- nsresult rv = permissionManager->GetEnumerator(getter_AddRefs(enumerator));
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return;
- }
-
- for (;;) {
- bool hasMoreElements;
- nsresult rv = enumerator->HasMoreElements(&hasMoreElements);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return;
- }
- if (!hasMoreElements) {
- break;
- }
- nsCOMPtr<nsISupports> supportsPermission;
- rv = enumerator->GetNext(getter_AddRefs(supportsPermission));
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return;
- }
- uint32_t capability;
- if (!GetNotificationPermission(supportsPermission, &capability)) {
- continue;
- }
- if (capability == nsIPermissionManager::DENY_ACTION) {
- Telemetry::Accumulate(Telemetry::WEB_NOTIFICATION_PERMISSIONS, 0);
- } else if (capability == nsIPermissionManager::ALLOW_ACTION) {
- Telemetry::Accumulate(Telemetry::WEB_NOTIFICATION_PERMISSIONS, 1);
- }
- }
-}
-
-bool
-NotificationTelemetryService::GetNotificationPermission(nsISupports* aSupports,
- uint32_t* aCapability)
-{
- nsCOMPtr<nsIPermission> permission = do_QueryInterface(aSupports);
- if (!permission) {
- return false;
- }
- nsAutoCString type;
- permission->GetType(type);
- if (!type.Equals("desktop-notification")) {
- return false;
- }
- permission->GetCapability(aCapability);
- return true;
-}
-
-void
-NotificationTelemetryService::RecordDNDSupported()
-{
- if (mDNDRecorded) {
- return;
- }
-
- nsCOMPtr<nsIAlertsService> alertService =
- do_GetService(NS_ALERTSERVICE_CONTRACTID);
- if (!alertService) {
- return;
- }
-
- nsCOMPtr<nsIAlertsDoNotDisturb> alertServiceDND =
- do_QueryInterface(alertService);
- if (!alertServiceDND) {
- return;
- }
-
- mDNDRecorded = true;
- bool isEnabled;
- nsresult rv = alertServiceDND->GetManualDoNotDisturb(&isEnabled);
- if (NS_FAILED(rv)) {
- return;
- }
-
- Telemetry::Accumulate(
- Telemetry::ALERTS_SERVICE_DND_SUPPORTED_FLAG, true);
-}
-
-nsresult
-NotificationTelemetryService::RecordSender(nsIPrincipal* aPrincipal)
-{
- if (!Telemetry::CanRecordBase() || !Telemetry::CanRecordExtended() ||
- !nsAlertsUtils::IsActionablePrincipal(aPrincipal)) {
- return NS_OK;
- }
- nsAutoString origin;
- nsresult rv = Notification::GetOrigin(aPrincipal, origin);
- if (NS_FAILED(rv)) {
- return rv;
- }
- if (!mOrigins.Contains(origin)) {
- mOrigins.PutEntry(origin);
- Telemetry::Accumulate(Telemetry::WEB_NOTIFICATION_SENDERS, 1);
- }
- return NS_OK;
-}
-
-NS_IMETHODIMP
-NotificationTelemetryService::Observe(nsISupports* aSubject,
- const char* aTopic,
- const char16_t* aData)
-{
- uint32_t capability;
- if (strcmp("perm-changed", aTopic) ||
- !NS_strcmp(u"cleared", aData) ||
- !GetNotificationPermission(aSubject, &capability)) {
- return NS_OK;
- }
- if (!NS_strcmp(u"deleted", aData)) {
- if (capability == nsIPermissionManager::DENY_ACTION) {
- Telemetry::Accumulate(
- Telemetry::WEB_NOTIFICATION_PERMISSION_REMOVED, 0);
- } else if (capability == nsIPermissionManager::ALLOW_ACTION) {
- Telemetry::Accumulate(
- Telemetry::WEB_NOTIFICATION_PERMISSION_REMOVED, 1);
- }
- }
- return NS_OK;
-}
-
// Observer that the alert service calls to do common tasks and/or dispatch to the
// specific observer for the context e.g. main thread, worker, or service worker.
class NotificationObserver final : public nsIObserver
@@ -1407,7 +1215,6 @@ NotificationObserver::Observe(nsISupports* aSubject, const char* aTopic,
AssertIsOnMainThread();
if (!strcmp("alertdisablecallback", aTopic)) {
- Telemetry::Accumulate(Telemetry::WEB_NOTIFICATION_MENU, 1);
if (XRE_IsParentProcess()) {
return Notification::RemovePermission(mPrincipal);
}
@@ -1417,10 +1224,7 @@ NotificationObserver::Observe(nsISupports* aSubject, const char* aTopic,
ContentChild::GetSingleton()->SendDisableNotifications(
IPC::Principal(mPrincipal));
return NS_OK;
- } else if (!strcmp("alertclickcallback", aTopic)) {
- Telemetry::Accumulate(Telemetry::WEB_NOTIFICATION_CLICKED, 1);
} else if (!strcmp("alertsettingscallback", aTopic)) {
- Telemetry::Accumulate(Telemetry::WEB_NOTIFICATION_MENU, 2);
if (XRE_IsParentProcess()) {
return Notification::OpenSettings(mPrincipal);
}
@@ -1431,23 +1235,7 @@ NotificationObserver::Observe(nsISupports* aSubject, const char* aTopic,
return NS_OK;
} else if (!strcmp("alertshow", aTopic) ||
!strcmp("alertfinished", aTopic)) {
- RefPtr<NotificationTelemetryService> telemetry =
- NotificationTelemetryService::GetInstance();
- if (telemetry) {
- // Record whether "do not disturb" is supported after the first
- // notification, to account for falling back to XUL alerts.
- telemetry->RecordDNDSupported();
- if (!mInPrivateBrowsing) {
- // Ignore senders in private windows.
- Unused << NS_WARN_IF(NS_FAILED(telemetry->RecordSender(mPrincipal)));
- }
- }
Unused << NS_WARN_IF(NS_FAILED(AdjustPushQuota(aTopic)));
-
- if (!strcmp("alertshow", aTopic)) {
- // Record notifications actually shown (e.g. don't count if DND is on).
- Telemetry::Accumulate(Telemetry::WEB_NOTIFICATION_SHOWN, 1);
- }
}
return mObserver->Observe(aSubject, aTopic, aData);
diff --git a/dom/notification/Notification.h b/dom/notification/Notification.h
index a2c4b5c68..11958f6ad 100644
--- a/dom/notification/Notification.h
+++ b/dom/notification/Notification.h
@@ -18,9 +18,6 @@
#include "nsTHashtable.h"
#include "nsWeakReference.h"
-#define NOTIFICATIONTELEMETRYSERVICE_CONTRACTID \
- "@mozilla.org/notificationTelemetryService;1"
-
class nsIPrincipal;
class nsIVariant;
@@ -49,36 +46,6 @@ public:
Notify(workers::Status aStatus) override;
};
-// Records telemetry probes at application startup, when a notification is
-// shown, and when the notification permission is revoked for a site.
-class NotificationTelemetryService final : public nsIObserver
-{
-public:
- NS_DECL_ISUPPORTS
- NS_DECL_NSIOBSERVER
-
- NotificationTelemetryService();
-
- static already_AddRefed<NotificationTelemetryService> GetInstance();
-
- nsresult Init();
- void RecordDNDSupported();
- void RecordPermissions();
- nsresult RecordSender(nsIPrincipal* aPrincipal);
-
-private:
- virtual ~NotificationTelemetryService();
-
- nsresult AddPermissionChangeObserver();
- nsresult RemovePermissionChangeObserver();
-
- bool GetNotificationPermission(nsISupports* aSupports,
- uint32_t* aCapability);
-
- bool mDNDRecorded;
- nsTHashtable<nsStringHashKey> mOrigins;
-};
-
/*
* Notifications on workers introduce some lifetime issues. The property we
* are trying to satisfy is:
@@ -143,7 +110,6 @@ class Notification : public DOMEventTargetHelper
friend class ServiceWorkerNotificationObserver;
friend class WorkerGetRunnable;
friend class WorkerNotificationObserver;
- friend class NotificationTelemetryService;
public:
IMPL_EVENT_HANDLER(click)
diff --git a/dom/performance/PerformanceMainThread.cpp b/dom/performance/PerformanceMainThread.cpp
index 64c06d3ea..5a84f5fb1 100644
--- a/dom/performance/PerformanceMainThread.cpp
+++ b/dom/performance/PerformanceMainThread.cpp
@@ -27,7 +27,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(PerformanceMainThread,
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTiming,
mNavigation,
mDocEntry)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(PerformanceMainThread,
diff --git a/dom/performance/PerformanceObserver.cpp b/dom/performance/PerformanceObserver.cpp
index d02acfb09..7bf194bb7 100644
--- a/dom/performance/PerformanceObserver.cpp
+++ b/dom/performance/PerformanceObserver.cpp
@@ -34,7 +34,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(PerformanceObserver)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCallback)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPerformance)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOwner)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(PerformanceObserver)
diff --git a/dom/plugins/base/nptypes.h b/dom/plugins/base/nptypes.h
index 12a5fb78e..c36532472 100644
--- a/dom/plugins/base/nptypes.h
+++ b/dom/plugins/base/nptypes.h
@@ -22,18 +22,6 @@
typedef unsigned int uint32_t;
typedef long long int64_t;
typedef unsigned long long uint64_t;
-#elif defined(_AIX) || defined(__sun) || defined(__osf__) || defined(IRIX) || defined(HPUX)
- /*
- * AIX and SunOS ship a inttypes.h header that defines [u]int32_t,
- * but not bool for C.
- */
- #include <inttypes.h>
-
- #ifndef __cplusplus
- typedef int bool;
- #define true 1
- #define false 0
- #endif
#elif defined(bsdi) || defined(FREEBSD) || defined(OPENBSD)
/*
* BSD/OS, FreeBSD, and OpenBSD ship sys/types.h that define int32_t and
diff --git a/dom/plugins/base/nsPluginHost.cpp b/dom/plugins/base/nsPluginHost.cpp
index 916bdea0f..c3de136d0 100644
--- a/dom/plugins/base/nsPluginHost.cpp
+++ b/dom/plugins/base/nsPluginHost.cpp
@@ -2148,11 +2148,7 @@ nsresult nsPluginHost::ScanPluginsDirectory(nsIFile *pluginsDir,
nsPluginInfo info;
memset(&info, 0, sizeof(info));
nsresult res;
- // Opening a block for the telemetry AutoTimer
- {
- Telemetry::AutoTimer<Telemetry::PLUGIN_LOAD_METADATA> telemetry;
- res = pluginFile.GetPluginInfo(info, &library);
- }
+ res = pluginFile.GetPluginInfo(info, &library);
// if we don't have mime type don't proceed, this is not a plugin
if (NS_FAILED(res) || !info.fMimeTypeArray) {
RefPtr<nsInvalidPluginTag> invalidTag = new nsInvalidPluginTag(filePath.get(),
@@ -2410,8 +2406,6 @@ nsPluginHost::FindPluginsInContent(bool aCreatePluginList, bool* aPluginsChanged
// This is needed in ReloadPlugins to prevent possible recursive reloads
nsresult nsPluginHost::FindPlugins(bool aCreatePluginList, bool * aPluginsChanged)
{
- Telemetry::AutoTimer<Telemetry::FIND_PLUGINS> telemetry;
-
NS_ENSURE_ARG_POINTER(aPluginsChanged);
*aPluginsChanged = false;
@@ -3412,7 +3406,6 @@ nsPluginHost::StopPluginInstance(nsNPAPIPluginInstance* aInstance)
return NS_OK;
}
- Telemetry::AutoTimer<Telemetry::PLUGIN_SHUTDOWN_MS> timer;
aInstance->Stop();
// if the instance does not want to be 'cached' just remove it
diff --git a/dom/plugins/base/nsPluginsDirUnix.cpp b/dom/plugins/base/nsPluginsDirUnix.cpp
index 6d112b4fe..e6956c34c 100644
--- a/dom/plugins/base/nsPluginsDirUnix.cpp
+++ b/dom/plugins/base/nsPluginsDirUnix.cpp
@@ -19,17 +19,7 @@
#include "nsIPrefService.h"
#define LOCAL_PLUGIN_DLL_SUFFIX ".so"
-#if defined(__hpux)
-#define DEFAULT_X11_PATH "/usr/lib/X11R6/"
-#undef LOCAL_PLUGIN_DLL_SUFFIX
-#define LOCAL_PLUGIN_DLL_SUFFIX ".sl"
-#define LOCAL_PLUGIN_DLL_ALT_SUFFIX ".so"
-#elif defined(_AIX)
-#define DEFAULT_X11_PATH "/usr/lib"
-#define LOCAL_PLUGIN_DLL_ALT_SUFFIX ".a"
-#elif defined(SOLARIS)
-#define DEFAULT_X11_PATH "/usr/openwin/lib/"
-#elif defined(LINUX)
+#if defined(LINUX)
#define DEFAULT_X11_PATH "/usr/X11R6/lib/"
#elif defined(__APPLE__)
#define DEFAULT_X11_PATH "/usr/X11R6/lib"
@@ -102,11 +92,7 @@ static bool LoadExtraSharedLib(const char *name, char **soname, bool tryToGetSon
#define PLUGIN_MAX_NUMBER_OF_EXTRA_LIBS 32
#define PREF_PLUGINS_SONAME "plugin.soname.list"
-#if defined(SOLARIS) || defined(HPUX)
-#define DEFAULT_EXTRA_LIBS_LIST "libXt" LOCAL_PLUGIN_DLL_SUFFIX ":libXext" LOCAL_PLUGIN_DLL_SUFFIX ":libXm" LOCAL_PLUGIN_DLL_SUFFIX
-#else
#define DEFAULT_EXTRA_LIBS_LIST "libXt" LOCAL_PLUGIN_DLL_SUFFIX ":libXext" LOCAL_PLUGIN_DLL_SUFFIX
-#endif
/*
this function looks for
user_pref("plugin.soname.list", "/usr/X11R6/lib/libXt.so.6:libXext.so");
@@ -280,15 +266,9 @@ nsresult nsPluginFile::LoadPlugin(PRLibrary **outLibrary)
// work fine.
-#if defined(SOLARIS) || defined(HPUX)
- // Acrobat/libXm: Lazy resolving might cause crash later (bug 211587)
- *outLibrary = PR_LoadLibraryWithFlags(libSpec, PR_LD_NOW);
- pLibrary = *outLibrary;
-#else
// Some dlopen() doesn't recover from a failed PR_LD_NOW (bug 223744)
*outLibrary = PR_LoadLibraryWithFlags(libSpec, 0);
pLibrary = *outLibrary;
-#endif
if (!pLibrary) {
LoadExtraSharedLibs();
// try reload plugin once more
diff --git a/dom/plugins/ipc/PluginAsyncSurrogate.cpp b/dom/plugins/ipc/PluginAsyncSurrogate.cpp
index da07116cc..3fe4c7168 100644
--- a/dom/plugins/ipc/PluginAsyncSurrogate.cpp
+++ b/dom/plugins/ipc/PluginAsyncSurrogate.cpp
@@ -504,8 +504,6 @@ PluginAsyncSurrogate::WaitForInit()
if (mAcceptCalls) {
return true;
}
- Telemetry::AutoTimer<Telemetry::BLOCKED_ON_PLUGINASYNCSURROGATE_WAITFORINIT_MS>
- timer(mParent->GetHistogramKey());
bool result = false;
MOZ_ASSERT(mParent);
if (mParent->IsChrome()) {
diff --git a/dom/plugins/ipc/PluginHangUIParent.cpp b/dom/plugins/ipc/PluginHangUIParent.cpp
index 5114f2e9a..908182a22 100644
--- a/dom/plugins/ipc/PluginHangUIParent.cpp
+++ b/dom/plugins/ipc/PluginHangUIParent.cpp
@@ -8,7 +8,6 @@
#include "PluginHangUIParent.h"
-#include "mozilla/Telemetry.h"
#include "mozilla/ipc/ProtocolUtils.h"
#include "mozilla/plugins/PluginModuleParent.h"
@@ -48,14 +47,6 @@ public:
NS_IMETHOD
Run() override
{
- mozilla::Telemetry::Accumulate(
- mozilla::Telemetry::PLUGIN_HANG_UI_USER_RESPONSE, mResponseCode);
- mozilla::Telemetry::Accumulate(
- mozilla::Telemetry::PLUGIN_HANG_UI_DONT_ASK, mDontAskCode);
- mozilla::Telemetry::Accumulate(
- mozilla::Telemetry::PLUGIN_HANG_UI_RESPONSE_TIME, mResponseTimeMs);
- mozilla::Telemetry::Accumulate(
- mozilla::Telemetry::PLUGIN_HANG_TIME, mTimeoutMs + mResponseTimeMs);
return NS_OK;
}
diff --git a/dom/plugins/ipc/PluginInstanceParent.cpp b/dom/plugins/ipc/PluginInstanceParent.cpp
index 02f0641f7..bdd15ca99 100644
--- a/dom/plugins/ipc/PluginInstanceParent.cpp
+++ b/dom/plugins/ipc/PluginInstanceParent.cpp
@@ -9,7 +9,6 @@
#include "mozilla/BasicEvents.h"
#include "mozilla/Preferences.h"
-#include "mozilla/Telemetry.h"
#include "PluginInstanceParent.h"
#include "BrowserStreamParent.h"
#include "PluginAsyncSurrogate.h"
@@ -206,12 +205,8 @@ NPError
PluginInstanceParent::Destroy()
{
NPError retval;
- { // Scope for timer
- Telemetry::AutoTimer<Telemetry::BLOCKED_ON_PLUGIN_INSTANCE_DESTROY_MS>
- timer(Module()->GetHistogramKey());
- if (!CallNPP_Destroy(&retval)) {
- retval = NPERR_GENERIC_ERROR;
- }
+ if (!CallNPP_Destroy(&retval)) {
+ retval = NPERR_GENERIC_ERROR;
}
#if defined(OS_WIN)
@@ -1786,9 +1781,6 @@ PluginInstanceParent::NPP_NewStream(NPMIMEType type, NPStream* stream,
return NPERR_GENERIC_ERROR;
}
- Telemetry::AutoTimer<Telemetry::BLOCKED_ON_PLUGIN_STREAM_INIT_MS>
- timer(Module()->GetHistogramKey());
-
NPError err = NPERR_NO_ERROR;
if (mParent->IsStartingAsync()) {
MOZ_ASSERT(mSurrogate);
@@ -2504,6 +2496,5 @@ PluginInstanceParent::RecordDrawingModel()
}
MOZ_ASSERT(mode >= 0);
- Telemetry::Accumulate(Telemetry::PLUGIN_DRAWING_MODEL, mode);
mLastRecordedDrawingModel = mode;
}
diff --git a/dom/plugins/ipc/PluginModuleParent.cpp b/dom/plugins/ipc/PluginModuleParent.cpp
index 2489baf16..4a509676d 100755
--- a/dom/plugins/ipc/PluginModuleParent.cpp
+++ b/dom/plugins/ipc/PluginModuleParent.cpp
@@ -20,7 +20,6 @@
#include "mozilla/Preferences.h"
#include "mozilla/ProcessHangMonitor.h"
#include "mozilla/Services.h"
-#include "mozilla/Telemetry.h"
#include "mozilla/Unused.h"
#include "nsAutoPtr.h"
#include "nsCRT.h"
@@ -93,11 +92,6 @@ mozilla::plugins::SetupBridge(uint32_t aPluginId,
return true;
}
PluginModuleChromeParent* chromeParent = static_cast<PluginModuleChromeParent*>(plugin->GetLibrary());
- /*
- * We can't accumulate BLOCKED_ON_PLUGIN_MODULE_INIT_MS until here because
- * its histogram key is not available until *after* NP_Initialize.
- */
- chromeParent->AccumulateModuleInitBlockedTime();
*rv = chromeParent->GetRunID(runID);
if (NS_FAILED(*rv)) {
return true;
@@ -336,16 +330,13 @@ PluginModuleContentParent::LoadModule(uint32_t aPluginId,
dom::ContentChild* cp = dom::ContentChild::GetSingleton();
nsresult rv;
uint32_t runID;
- TimeStamp sendLoadPluginStart = TimeStamp::Now();
if (!cp->SendLoadPlugin(aPluginId, &rv, &runID) ||
NS_FAILED(rv)) {
return nullptr;
}
- TimeStamp sendLoadPluginEnd = TimeStamp::Now();
PluginModuleContentParent* parent = mapping->GetModule();
MOZ_ASSERT(parent);
- parent->mTimeBlocked += (sendLoadPluginEnd - sendLoadPluginStart);
if (!mapping->IsChannelOpened()) {
// mapping is linked into PluginModuleMapping::sModuleListHead and is
@@ -441,7 +432,6 @@ PluginModuleChromeParent::LoadModule(const char* aFilePath, uint32_t aPluginId,
aPluginTag->mSupportsAsyncInit));
UniquePtr<LaunchCompleteTask> onLaunchedRunnable(new LaunchedTask(parent));
parent->mSubprocess->SetCallRunnableImmediately(!parent->mIsStartingAsync);
- TimeStamp launchStart = TimeStamp::Now();
bool launched = parent->mSubprocess->Launch(Move(onLaunchedRunnable),
aPluginTag->mSandboxLevel);
if (!launched) {
@@ -460,8 +450,6 @@ PluginModuleChromeParent::LoadModule(const char* aFilePath, uint32_t aPluginId,
return nullptr;
}
}
- TimeStamp launchEnd = TimeStamp::Now();
- parent->mTimeBlocked = (launchEnd - launchStart);
return parent.forget();
}
@@ -1172,11 +1160,6 @@ PluginModuleParent::GetRunID(uint32_t* aRunID)
void
PluginModuleChromeParent::ActorDestroy(ActorDestroyReason why)
{
- if (why == AbnormalShutdown) {
- Telemetry::Accumulate(Telemetry::SUBPROCESS_ABNORMAL_ABORT,
- NS_LITERAL_CSTRING("plugin"), 1);
- }
-
// We can't broadcast settings changes anymore.
UnregisterSettingsCallbacks();
@@ -1764,15 +1747,12 @@ PluginModuleChromeParent::NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs*
PluginSettings settings;
GetSettings(&settings);
- TimeStamp callNpInitStart = TimeStamp::Now();
// Asynchronous case
if (mIsStartingAsync) {
if (!SendAsyncNP_Initialize(settings)) {
Close();
return NS_ERROR_FAILURE;
}
- TimeStamp callNpInitEnd = TimeStamp::Now();
- mTimeBlocked += (callNpInitEnd - callNpInitStart);
return NS_OK;
}
@@ -1785,8 +1765,6 @@ PluginModuleChromeParent::NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs*
Close();
return NS_ERROR_FAILURE;
}
- TimeStamp callNpInitEnd = TimeStamp::Now();
- mTimeBlocked += (callNpInitEnd - callNpInitStart);
RecvNP_InitializeResult(*error);
@@ -1888,13 +1866,10 @@ PluginModuleChromeParent::NP_Initialize(NPNetscapeFuncs* bFuncs, NPError* error)
PluginSettings settings;
GetSettings(&settings);
- TimeStamp callNpInitStart = TimeStamp::Now();
if (mIsStartingAsync) {
if (!SendAsyncNP_Initialize(settings)) {
return NS_ERROR_FAILURE;
}
- TimeStamp callNpInitEnd = TimeStamp::Now();
- mTimeBlocked += (callNpInitEnd - callNpInitStart);
return NS_OK;
}
@@ -1902,8 +1877,6 @@ PluginModuleChromeParent::NP_Initialize(NPNetscapeFuncs* bFuncs, NPError* error)
Close();
return NS_ERROR_FAILURE;
}
- TimeStamp callNpInitEnd = TimeStamp::Now();
- mTimeBlocked += (callNpInitEnd - callNpInitStart);
RecvNP_InitializeResult(*error);
return NS_OK;
}
@@ -2200,18 +2173,6 @@ public:
}
};
-void
-PluginModuleParent::AccumulateModuleInitBlockedTime()
-{
- if (mPluginName.IsEmpty()) {
- GetPluginDetails();
- }
- Telemetry::Accumulate(Telemetry::BLOCKED_ON_PLUGIN_MODULE_INIT_MS,
- GetHistogramKey(),
- static_cast<uint32_t>(mTimeBlocked.ToMilliseconds()));
- mTimeBlocked = TimeDuration();
-}
-
nsresult
PluginModuleParent::NPP_NewInternal(NPMIMEType pluginType, NPP instance,
uint16_t mode,
@@ -2223,13 +2184,6 @@ PluginModuleParent::NPP_NewInternal(NPMIMEType pluginType, NPP instance,
if (mPluginName.IsEmpty()) {
GetPluginDetails();
InitQuirksModes(nsDependentCString(pluginType));
- /** mTimeBlocked measures the time that the main thread has been blocked
- * on plugin module initialization. As implemented, this is the sum of
- * plugin-container launch + toolhelp32 snapshot + NP_Initialize.
- * We don't accumulate its value until here because the plugin info
- * for its histogram key is not available until *after* NP_Initialize.
- */
- AccumulateModuleInitBlockedTime();
}
nsCaseInsensitiveUTF8StringArrayComparator comparator;
@@ -2294,27 +2248,23 @@ PluginModuleParent::NPP_NewInternal(NPMIMEType pluginType, NPP instance,
return NS_ERROR_FAILURE;
}
- { // Scope for timer
- Telemetry::AutoTimer<Telemetry::BLOCKED_ON_PLUGIN_INSTANCE_INIT_MS>
- timer(GetHistogramKey());
- if (mIsStartingAsync) {
- MOZ_ASSERT(surrogate);
- surrogate->AsyncCallDeparting();
- if (!SendAsyncNPP_New(parentInstance)) {
+ if (mIsStartingAsync) {
+ MOZ_ASSERT(surrogate);
+ surrogate->AsyncCallDeparting();
+ if (!SendAsyncNPP_New(parentInstance)) {
+ *error = NPERR_GENERIC_ERROR;
+ return NS_ERROR_FAILURE;
+ }
+ *error = NPERR_NO_ERROR;
+ } else {
+ if (!CallSyncNPP_New(parentInstance, error)) {
+ // if IPC is down, we'll get an immediate "failed" return, but
+ // without *error being set. So make sure that the error
+ // condition is signaled to nsNPAPIPluginInstance
+ if (NPERR_NO_ERROR == *error) {
*error = NPERR_GENERIC_ERROR;
- return NS_ERROR_FAILURE;
- }
- *error = NPERR_NO_ERROR;
- } else {
- if (!CallSyncNPP_New(parentInstance, error)) {
- // if IPC is down, we'll get an immediate "failed" return, but
- // without *error being set. So make sure that the error
- // condition is signaled to nsNPAPIPluginInstance
- if (NPERR_NO_ERROR == *error) {
- *error = NPERR_GENERIC_ERROR;
- }
- return NS_ERROR_FAILURE;
}
+ return NS_ERROR_FAILURE;
}
}
diff --git a/dom/plugins/ipc/PluginModuleParent.h b/dom/plugins/ipc/PluginModuleParent.h
index 0ceed6efd..909e8fe35 100644
--- a/dom/plugins/ipc/PluginModuleParent.h
+++ b/dom/plugins/ipc/PluginModuleParent.h
@@ -115,8 +115,6 @@ public:
return mPluginName + mPluginVersion;
}
- void AccumulateModuleInitBlockedTime();
-
virtual nsresult GetRunID(uint32_t* aRunID) override;
virtual void SetHasLocalInstance() override {
mHadLocalInstance = true;
@@ -315,7 +313,6 @@ protected:
nsString mBrowserDumpID;
nsString mHangID;
RefPtr<nsIObserver> mProfilerObserver;
- TimeDuration mTimeBlocked;
nsCString mPluginName;
nsCString mPluginVersion;
int32_t mSandboxLevel;
diff --git a/dom/presentation/provider/PresentationControlService.js b/dom/presentation/provider/PresentationControlService.js
index fe61d26d6..e9f92247f 100644
--- a/dom/presentation/provider/PresentationControlService.js
+++ b/dom/presentation/provider/PresentationControlService.js
@@ -100,7 +100,6 @@ PresentationControlService.prototype = {
if (aCert) {
this._serverSocket.serverCert = aCert;
- this._serverSocket.setSessionCache(false);
this._serverSocket.setSessionTickets(false);
let requestCert = Ci.nsITLSServerSocket.REQUEST_NEVER;
this._serverSocket.setRequestClientCertificate(requestCert);
diff --git a/dom/promise/Promise.cpp b/dom/promise/Promise.cpp
index 557f3a1f9..f636a9101 100644
--- a/dom/promise/Promise.cpp
+++ b/dom/promise/Promise.cpp
@@ -413,7 +413,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Promise)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mResolveCallbacks)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRejectCallbacks)
#endif // SPIDERMONKEY_PROMISE
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(Promise)
@@ -1995,7 +1994,6 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(CountdownHolder)
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(CountdownHolder)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPromise)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
diff --git a/dom/promise/PromiseCallback.cpp b/dom/promise/PromiseCallback.cpp
index 3f4a689ae..6ecf983b7 100644
--- a/dom/promise/PromiseCallback.cpp
+++ b/dom/promise/PromiseCallback.cpp
@@ -47,7 +47,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ResolvePromiseCallback,
PromiseCallback)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPromise)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(ResolvePromiseCallback)
@@ -107,7 +106,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(RejectPromiseCallback,
PromiseCallback)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPromise)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(RejectPromiseCallback)
@@ -170,7 +168,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(InvokePromiseFuncCallback,
PromiseCallback)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPromiseFunc)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(InvokePromiseFuncCallback)
@@ -256,7 +253,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(WrapperPromiseCallback,
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mResolveFunc)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRejectFunc)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCallback)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(WrapperPromiseCallback)
diff --git a/dom/push/PushSubscriptionOptions.cpp b/dom/push/PushSubscriptionOptions.cpp
index bc4fead1e..39252e9e8 100644
--- a/dom/push/PushSubscriptionOptions.cpp
+++ b/dom/push/PushSubscriptionOptions.cpp
@@ -36,7 +36,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(PushSubscriptionOptions)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(PushSubscriptionOptions)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGlobal)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(PushSubscriptionOptions)
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
diff --git a/dom/security/nsContentSecurityManager.cpp b/dom/security/nsContentSecurityManager.cpp
index 570730312..f2cbc8fcf 100644
--- a/dom/security/nsContentSecurityManager.cpp
+++ b/dom/security/nsContentSecurityManager.cpp
@@ -92,6 +92,55 @@ nsContentSecurityManager::AllowTopLevelNavigationToDataURI(nsIChannel* aChannel)
return false;
}
+/* static */ nsresult
+nsContentSecurityManager::CheckFTPSubresourceLoad(nsIChannel* aChannel)
+{
+ // We dissallow using FTP resources as a subresource everywhere.
+ // The only valid way to use FTP resources is loading it as
+ // a top level document.
+
+ nsCOMPtr<nsILoadInfo> loadInfo = aChannel->GetLoadInfo();
+ if (!loadInfo) {
+ return NS_OK;
+ }
+
+ nsContentPolicyType type = loadInfo->GetExternalContentPolicyType();
+ if (type == nsIContentPolicy::TYPE_DOCUMENT) {
+ return NS_OK;
+ }
+
+ nsCOMPtr<nsIURI> uri;
+ nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri));
+ NS_ENSURE_SUCCESS(rv, rv);
+ if (!uri) {
+ return NS_OK;
+ }
+
+ bool isFtpURI = (NS_SUCCEEDED(uri->SchemeIs("ftp", &isFtpURI)) && isFtpURI);
+ if (!isFtpURI) {
+ return NS_OK;
+ }
+
+ nsCOMPtr<nsIDocument> doc;
+ if (nsINode* node = loadInfo->LoadingNode()) {
+ doc = node->OwnerDoc();
+ }
+
+ nsAutoCString spec;
+ uri->GetSpec(spec);
+ NS_ConvertUTF8toUTF16 specUTF16(NS_UnescapeURL(spec));
+ const char16_t* params[] = { specUTF16.get() };
+
+ nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
+ NS_LITERAL_CSTRING("FTP_URI_BLOCKED"),
+ doc,
+ nsContentUtils::eSECURITY_PROPERTIES,
+ "BlockSubresourceFTP",
+ params, ArrayLength(params));
+
+ return NS_ERROR_CONTENT_BLOCKED;
+}
+
static nsresult
ValidateSecurityFlags(nsILoadInfo* aLoadInfo)
{
@@ -574,6 +623,10 @@ nsContentSecurityManager::doContentSecurityCheck(nsIChannel* aChannel,
rv = DoContentSecurityChecks(aChannel, loadInfo);
NS_ENSURE_SUCCESS(rv, rv);
+ // Apply this after CSP checks to allow CSP reporting.
+ rv = CheckFTPSubresourceLoad(aChannel);
+ NS_ENSURE_SUCCESS(rv, rv);
+
// now lets set the initalSecurityFlag for subsequent calls
loadInfo->SetInitialSecurityCheckDone(true);
@@ -591,6 +644,9 @@ nsContentSecurityManager::AsyncOnChannelRedirect(nsIChannel* aOldChannel,
// Are we enforcing security using LoadInfo?
if (loadInfo && loadInfo->GetEnforceSecurity()) {
nsresult rv = CheckChannel(aNewChannel);
+ if (NS_SUCCEEDED(rv)) {
+ rv = CheckFTPSubresourceLoad(aNewChannel);
+ }
if (NS_FAILED(rv)) {
aOldChannel->Cancel(rv);
return rv;
diff --git a/dom/security/nsContentSecurityManager.h b/dom/security/nsContentSecurityManager.h
index bab847743..750dd8803 100644
--- a/dom/security/nsContentSecurityManager.h
+++ b/dom/security/nsContentSecurityManager.h
@@ -36,6 +36,7 @@ public:
private:
static nsresult CheckChannel(nsIChannel* aChannel);
+ static nsresult CheckFTPSubresourceLoad(nsIChannel* aChannel);
virtual ~nsContentSecurityManager() {}
diff --git a/dom/security/nsMixedContentBlocker.cpp b/dom/security/nsMixedContentBlocker.cpp
index c03628da0..543429aff 100644
--- a/dom/security/nsMixedContentBlocker.cpp
+++ b/dom/security/nsMixedContentBlocker.cpp
@@ -35,7 +35,6 @@
#include "nsISiteSecurityService.h"
#include "mozilla/Logging.h"
-#include "mozilla/Telemetry.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/ipc/URIUtils.h"
@@ -814,17 +813,13 @@ nsMixedContentBlocker::ShouldLoad(bool aHadInsecureImageRedirect,
//
// We do not count requests aHadInsecureImageRedirect=true, since these are
// just an artifact of the image caching system.
- bool active = (classification == eMixedScript);
if (!aHadInsecureImageRedirect) {
- if (XRE_IsParentProcess()) {
- AccumulateMixedContentHSTS(innerContentLocation, active);
- } else {
+ if (!XRE_IsParentProcess()) {
// Ask the parent process to do the same call
mozilla::dom::ContentChild* cc = mozilla::dom::ContentChild::GetSingleton();
if (cc) {
mozilla::ipc::URIParams uri;
SerializeURI(innerContentLocation, uri);
- cc->SendAccumulateMixedContentHSTS(uri, active);
}
}
}
@@ -977,50 +972,3 @@ enum MixedContentHSTSState {
MCB_HSTS_ACTIVE_NO_HSTS = 2,
MCB_HSTS_ACTIVE_WITH_HSTS = 3
};
-
-// Record information on when HSTS would have made mixed content not mixed
-// content (regardless of whether it was actually blocked)
-void
-nsMixedContentBlocker::AccumulateMixedContentHSTS(nsIURI* aURI, bool aActive)
-{
- // This method must only be called in the parent, because
- // nsSiteSecurityService is only available in the parent
- if (!XRE_IsParentProcess()) {
- MOZ_ASSERT(false);
- return;
- }
-
- bool hsts;
- nsresult rv;
- nsCOMPtr<nsISiteSecurityService> sss = do_GetService(NS_SSSERVICE_CONTRACTID, &rv);
- if (NS_FAILED(rv)) {
- return;
- }
- rv = sss->IsSecureURI(nsISiteSecurityService::HEADER_HSTS, aURI, 0, nullptr, &hsts);
- if (NS_FAILED(rv)) {
- return;
- }
-
- // states: would upgrade, hsts info cached
- // active, passive
- //
- if (!aActive) {
- if (!hsts) {
- Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS,
- MCB_HSTS_PASSIVE_NO_HSTS);
- }
- else {
- Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS,
- MCB_HSTS_PASSIVE_WITH_HSTS);
- }
- } else {
- if (!hsts) {
- Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS,
- MCB_HSTS_ACTIVE_NO_HSTS);
- }
- else {
- Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS,
- MCB_HSTS_ACTIVE_WITH_HSTS);
- }
- }
-} \ No newline at end of file
diff --git a/dom/security/nsMixedContentBlocker.h b/dom/security/nsMixedContentBlocker.h
index 56ab9621f..068068b25 100644
--- a/dom/security/nsMixedContentBlocker.h
+++ b/dom/security/nsMixedContentBlocker.h
@@ -61,9 +61,6 @@ public:
nsISupports* aExtra,
nsIPrincipal* aRequestPrincipal,
int16_t* aDecision);
- static void AccumulateMixedContentHSTS(nsIURI* aURI,
- bool aActive);
-
static bool sBlockMixedScript;
static bool sBlockMixedDisplay;
diff --git a/dom/security/test/cors/test_CrossSiteXHR.html b/dom/security/test/cors/test_CrossSiteXHR.html
index b3cda3b87..d9aef5c60 100644
--- a/dom/security/test/cors/test_CrossSiteXHR.html
+++ b/dom/security/test/cors/test_CrossSiteXHR.html
@@ -743,7 +743,7 @@ function runTest() {
is(res.responseHeaders[header], test.responseHeaders[header],
"|xhr.getResponseHeader()|wrong response header (" + header + ") in test for " +
test.toSource());
- is(res.allResponseHeaders[header], test.responseHeaders[header],
+ is(res.allResponseHeaders[header.toLowerCase()], test.responseHeaders[header],
"|xhr.getAllResponseHeaderss()|wrong response header (" + header + ") in test for " +
test.toSource());
}
diff --git a/dom/smil/nsSMILAnimationController.cpp b/dom/smil/nsSMILAnimationController.cpp
index 0dd616346..69956203e 100644
--- a/dom/smil/nsSMILAnimationController.cpp
+++ b/dom/smil/nsSMILAnimationController.cpp
@@ -233,7 +233,7 @@ void
nsSMILAnimationController::NotifyRefreshDriverCreated(
nsRefreshDriver* aRefreshDriver)
{
- if (!mPauseState) {
+ if (!mPauseState && mChildContainerTable.Count()) {
MaybeStartSampling(aRefreshDriver);
}
}
diff --git a/dom/storage/DOMStorageCache.cpp b/dom/storage/DOMStorageCache.cpp
index 811f79fd3..a2b5a6f73 100644
--- a/dom/storage/DOMStorageCache.cpp
+++ b/dom/storage/DOMStorageCache.cpp
@@ -85,7 +85,6 @@ DOMStorageCache::DOMStorageCache(const nsACString* aOriginNoSuffix)
, mInitialized(false)
, mPersistent(false)
, mSessionOnlyDataSetActive(false)
-, mPreloadTelemetryRecorded(false)
{
MOZ_COUNT_CTOR(DOMStorageCache);
}
@@ -178,7 +177,7 @@ DOMStorageCache::DataSet(const DOMStorage* aStorage)
// Session only data set is demanded but not filled with
// current data set, copy to session only set now.
- WaitForPreload(Telemetry::LOCALDOMSTORAGE_SESSIONONLY_PRELOAD_BLOCKING_MS);
+ WaitForPreload();
Data& defaultSet = mData[kDefaultSet];
Data& sessionSet = mData[kSessionSet];
@@ -298,49 +297,18 @@ DOMStorageCache::KeepAlive()
mKeepAliveTimer.swap(timer);
}
-namespace {
-
-// The AutoTimer provided by telemetry headers is only using static,
-// i.e. compile time known ID, but here we know the ID only at run time.
-// Hence a new class.
-class TelemetryAutoTimer
-{
-public:
- explicit TelemetryAutoTimer(Telemetry::ID aId)
- : id(aId), start(TimeStamp::Now()) {}
- ~TelemetryAutoTimer()
- { Telemetry::AccumulateDelta_impl<Telemetry::Millisecond>::compute(id, start); }
-private:
- Telemetry::ID id;
- const TimeStamp start;
-};
-
-} // namespace
-
void
-DOMStorageCache::WaitForPreload(Telemetry::ID aTelemetryID)
+DOMStorageCache::WaitForPreload()
{
if (!mPersistent) {
return;
}
bool loaded = mLoaded;
-
- // Telemetry of rates of pending preloads
- if (!mPreloadTelemetryRecorded) {
- mPreloadTelemetryRecorded = true;
- Telemetry::Accumulate(
- Telemetry::LOCALDOMSTORAGE_PRELOAD_PENDING_ON_FIRST_ACCESS,
- !loaded);
- }
-
if (loaded) {
return;
}
- // Measure which operation blocks and for how long
- TelemetryAutoTimer timer(aTelemetryID);
-
// If preload already started (i.e. we got some first data, but not all)
// SyncPreload will just wait for it to finish rather then synchronously
// read from the database. It seems to me more optimal.
@@ -357,7 +325,7 @@ nsresult
DOMStorageCache::GetLength(const DOMStorage* aStorage, uint32_t* aRetval)
{
if (Persist(aStorage)) {
- WaitForPreload(Telemetry::LOCALDOMSTORAGE_GETLENGTH_BLOCKING_MS);
+ WaitForPreload();
if (NS_FAILED(mLoadResult)) {
return mLoadResult;
}
@@ -375,7 +343,7 @@ DOMStorageCache::GetKey(const DOMStorage* aStorage, uint32_t aIndex, nsAString&
// maybe we need to have a lazily populated key array here or
// something?
if (Persist(aStorage)) {
- WaitForPreload(Telemetry::LOCALDOMSTORAGE_GETKEY_BLOCKING_MS);
+ WaitForPreload();
if (NS_FAILED(mLoadResult)) {
return mLoadResult;
}
@@ -397,7 +365,7 @@ void
DOMStorageCache::GetKeys(const DOMStorage* aStorage, nsTArray<nsString>& aKeys)
{
if (Persist(aStorage)) {
- WaitForPreload(Telemetry::LOCALDOMSTORAGE_GETALLKEYS_BLOCKING_MS);
+ WaitForPreload();
}
if (NS_FAILED(mLoadResult)) {
@@ -414,7 +382,7 @@ DOMStorageCache::GetItem(const DOMStorage* aStorage, const nsAString& aKey,
nsAString& aRetval)
{
if (Persist(aStorage)) {
- WaitForPreload(Telemetry::LOCALDOMSTORAGE_GETVALUE_BLOCKING_MS);
+ WaitForPreload();
if (NS_FAILED(mLoadResult)) {
return mLoadResult;
}
@@ -439,7 +407,7 @@ DOMStorageCache::SetItem(const DOMStorage* aStorage, const nsAString& aKey,
int64_t delta = 0;
if (Persist(aStorage)) {
- WaitForPreload(Telemetry::LOCALDOMSTORAGE_SETVALUE_BLOCKING_MS);
+ WaitForPreload();
if (NS_FAILED(mLoadResult)) {
return mLoadResult;
}
@@ -488,7 +456,7 @@ DOMStorageCache::RemoveItem(const DOMStorage* aStorage, const nsAString& aKey,
nsString& aOld)
{
if (Persist(aStorage)) {
- WaitForPreload(Telemetry::LOCALDOMSTORAGE_REMOVEKEY_BLOCKING_MS);
+ WaitForPreload();
if (NS_FAILED(mLoadResult)) {
return mLoadResult;
}
@@ -527,9 +495,8 @@ DOMStorageCache::Clear(const DOMStorage* aStorage)
// We need to preload all data (know the size) before we can proceeed
// to correctly decrease cached usage number.
// XXX as in case of unload, this is not technically needed now, but
- // after super-scope quota introduction we have to do this. Get telemetry
- // right now.
- WaitForPreload(Telemetry::LOCALDOMSTORAGE_CLEAR_BLOCKING_MS);
+ // after super-scope quota introduction we have to do this.
+ WaitForPreload();
if (NS_FAILED(mLoadResult)) {
// When we failed to load data from the database, force delete of the
// scope data and make use of the storage possible again.
@@ -599,9 +566,8 @@ DOMStorageCache::UnloadItems(uint32_t aUnloadFlags)
// Must wait for preload to pass correct usage to ProcessUsageDelta
// XXX this is not technically needed right now since there is just
// per-origin isolated quota handling, but when we introduce super-
- // -scope quotas, we have to do this. Better to start getting
- // telemetry right now.
- WaitForPreload(Telemetry::LOCALDOMSTORAGE_UNLOAD_BLOCKING_MS);
+ // -scope quotas, we have to do this.
+ WaitForPreload();
mData[kDefaultSet].mKeys.Clear();
ProcessUsageDelta(kDefaultSet, -mData[kDefaultSet].mOriginQuotaUsage);
@@ -620,7 +586,7 @@ DOMStorageCache::UnloadItems(uint32_t aUnloadFlags)
#ifdef DOM_STORAGE_TESTS
if (aUnloadFlags & kTestReload) {
- WaitForPreload(Telemetry::LOCALDOMSTORAGE_UNLOAD_BLOCKING_MS);
+ WaitForPreload();
mData[kDefaultSet].mKeys.Clear();
mLoaded = false; // This is only used in testing code
diff --git a/dom/storage/DOMStorageCache.h b/dom/storage/DOMStorageCache.h
index 01cf6b3ea..4469152a2 100644
--- a/dom/storage/DOMStorageCache.h
+++ b/dom/storage/DOMStorageCache.h
@@ -14,7 +14,6 @@
#include "nsDataHashtable.h"
#include "nsHashKeys.h"
#include "mozilla/Monitor.h"
-#include "mozilla/Telemetry.h"
#include "mozilla/Atomics.h"
namespace mozilla {
@@ -168,7 +167,7 @@ private:
private:
// Synchronously blocks until the cache is fully loaded from the database
- void WaitForPreload(mozilla::Telemetry::ID aTelemetryID);
+ void WaitForPreload();
// Helper to get one of the 3 data sets (regular, private, session)
Data& DataSet(const DOMStorage* aStorage);
@@ -241,9 +240,6 @@ private:
// Drops back to false when session-only data are cleared from chrome.
bool mSessionOnlyDataSetActive : 1;
- // Whether we have already captured state of the cache preload on our first access.
- bool mPreloadTelemetryRecorded : 1;
-
// DOMStorageDBThread on the parent or single process,
// DOMStorageDBChild on the child process.
static DOMStorageDBBridge* sDatabase;
diff --git a/dom/storage/DOMStorageDBThread.cpp b/dom/storage/DOMStorageDBThread.cpp
index 183be5c5c..f86dbad9c 100644
--- a/dom/storage/DOMStorageDBThread.cpp
+++ b/dom/storage/DOMStorageDBThread.cpp
@@ -163,8 +163,6 @@ DOMStorageDBThread::Shutdown()
return NS_ERROR_NOT_INITIALIZED;
}
- Telemetry::AutoTimer<Telemetry::LOCALDOMSTORAGE_SHUTDOWN_DATABASE_MS> timer;
-
{
MonitorAutoLock monitor(mThreadObserver->GetMonitor());
diff --git a/dom/svg/DOMSVGLength.cpp b/dom/svg/DOMSVGLength.cpp
index 574617045..c72c3e383 100644
--- a/dom/svg/DOMSVGLength.cpp
+++ b/dom/svg/DOMSVGLength.cpp
@@ -43,7 +43,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(DOMSVGLength)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mList)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSVGElement)
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(DOMSVGLength)
diff --git a/dom/svg/DOMSVGLengthList.cpp b/dom/svg/DOMSVGLengthList.cpp
index 9d93546d9..88ecd6007 100644
--- a/dom/svg/DOMSVGLengthList.cpp
+++ b/dom/svg/DOMSVGLengthList.cpp
@@ -55,7 +55,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DOMSVGLengthList)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(DOMSVGLengthList)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAList)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(DOMSVGLengthList)
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
diff --git a/dom/svg/DOMSVGNumber.cpp b/dom/svg/DOMSVGNumber.cpp
index 97d80d4d0..6b9528606 100644
--- a/dom/svg/DOMSVGNumber.cpp
+++ b/dom/svg/DOMSVGNumber.cpp
@@ -35,7 +35,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(DOMSVGNumber)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mList)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(DOMSVGNumber)
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
diff --git a/dom/svg/DOMSVGNumberList.cpp b/dom/svg/DOMSVGNumberList.cpp
index 00fb7ba4d..85322688f 100644
--- a/dom/svg/DOMSVGNumberList.cpp
+++ b/dom/svg/DOMSVGNumberList.cpp
@@ -55,7 +55,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DOMSVGNumberList)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(DOMSVGNumberList)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAList)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(DOMSVGNumberList)
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
diff --git a/dom/svg/DOMSVGPathSeg.cpp b/dom/svg/DOMSVGPathSeg.cpp
index 95be3521e..a15bf42e9 100644
--- a/dom/svg/DOMSVGPathSeg.cpp
+++ b/dom/svg/DOMSVGPathSeg.cpp
@@ -31,7 +31,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(DOMSVGPathSeg)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mList)
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(DOMSVGPathSeg)
diff --git a/dom/svg/DOMSVGPathSegList.cpp b/dom/svg/DOMSVGPathSegList.cpp
index 0b811cdb1..36768ea34 100644
--- a/dom/svg/DOMSVGPathSegList.cpp
+++ b/dom/svg/DOMSVGPathSegList.cpp
@@ -36,7 +36,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DOMSVGPathSegList)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(DOMSVGPathSegList)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mElement)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(DOMSVGPathSegList)
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
diff --git a/dom/svg/DOMSVGPointList.cpp b/dom/svg/DOMSVGPointList.cpp
index 966ef476e..ca06bd270 100644
--- a/dom/svg/DOMSVGPointList.cpp
+++ b/dom/svg/DOMSVGPointList.cpp
@@ -55,7 +55,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DOMSVGPointList)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(DOMSVGPointList)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mElement)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(DOMSVGPointList)
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
diff --git a/dom/svg/DOMSVGTransformList.cpp b/dom/svg/DOMSVGTransformList.cpp
index 30760bc6d..e4bde9aeb 100644
--- a/dom/svg/DOMSVGTransformList.cpp
+++ b/dom/svg/DOMSVGTransformList.cpp
@@ -54,7 +54,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DOMSVGTransformList)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(DOMSVGTransformList)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAList)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(DOMSVGTransformList)
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
diff --git a/dom/svg/SVGTransform.cpp b/dom/svg/SVGTransform.cpp
index b73018d1c..1cba997eb 100644
--- a/dom/svg/SVGTransform.cpp
+++ b/dom/svg/SVGTransform.cpp
@@ -51,7 +51,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mList)
SVGMatrix* matrix =
SVGMatrixTearoffTable().GetTearoff(tmp);
CycleCollectionNoteChild(cb, matrix, "matrix");
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(SVGTransform)
diff --git a/dom/svg/SVGUseElement.cpp b/dom/svg/SVGUseElement.cpp
index 4911e2cac..9212ab1aa 100644
--- a/dom/svg/SVGUseElement.cpp
+++ b/dom/svg/SVGUseElement.cpp
@@ -15,6 +15,7 @@
#include "mozilla/dom/Element.h"
#include "nsContentUtils.h"
#include "nsIURI.h"
+#include "nsSVGEffects.h"
NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(Use)
@@ -418,11 +419,15 @@ SVGUseElement::LookupHref()
return;
}
+ nsCOMPtr<nsIURI> originURI =
+ mOriginal ? mOriginal->GetBaseURI() : GetBaseURI();
+ nsCOMPtr<nsIURI> baseURI = nsContentUtils::IsLocalRefURL(href)
+ ? nsSVGEffects::GetBaseURLForLocalRef(this, originURI)
+ : originURI;
+
nsCOMPtr<nsIURI> targetURI;
- nsCOMPtr<nsIURI> baseURI = mOriginal ? mOriginal->GetBaseURI() : GetBaseURI();
nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(targetURI), href,
GetComposedDoc(), baseURI);
-
mSource.Reset(this, targetURI);
}
diff --git a/dom/svg/nsISVGPoint.cpp b/dom/svg/nsISVGPoint.cpp
index 1c1971004..f4fdb9dd0 100644
--- a/dom/svg/nsISVGPoint.cpp
+++ b/dom/svg/nsISVGPoint.cpp
@@ -32,7 +32,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsISVGPoint)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mList)
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsISVGPoint)
diff --git a/dom/svg/nsSVGElement.h b/dom/svg/nsSVGElement.h
index 42bc05746..257ed7a2e 100644
--- a/dom/svg/nsSVGElement.h
+++ b/dom/svg/nsSVGElement.h
@@ -715,7 +715,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER \
NS_IMPL_CYCLE_COLLECTION_UNLINK_END \
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_val) \
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_element) \
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS \
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END \
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(_val) \
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER \
diff --git a/dom/svg/test/reftest_viewport_noninteger.html b/dom/svg/test/reftest_viewport_noninteger.html
new file mode 100644
index 000000000..3f4852b53
--- /dev/null
+++ b/dom/svg/test/reftest_viewport_noninteger.html
@@ -0,0 +1,175 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>SVG size test</title>
+ <style>
+ body {
+ margin: 30px;
+ font-family: sans-serif;
+ }
+
+ #tests {
+ display: grid;
+ grid-template-columns: repeat(4, 1fr);
+ grid-gap: 30px;
+ }
+
+ #tests div:hover {
+ opacity: 1 !important;
+ }
+
+ #tests p {
+ text-decoration: underline dotted black;
+ }
+
+ svg {
+ background: lightgrey;
+ }
+ </style>
+ </head>
+ <body>
+ <h1>SVG size test</h1>
+
+ <p>The grey boxes below are <code>&lt;svg&gt;</code> elements.</p>
+ <p>All SVGs in each row should have the exact same size.</p>
+ <p>Each row has its own viewBox width and height: <code>viewBox="0 0 width height"</code>.</p>
+ <p>Each column has its own width/height styling. For example, <code>style="width: 200px; height: auto;"</code>.</p>
+ <p>The first column has both an explicit widht and an explicit height, so there's not much that can go wrong there. It acts as a reference.</p>
+ <p>The first row has integer viewBox width and height. Firefox then sizes all SVGs correctly.</p>
+ <p>The remaining rows have at least one non-integer viewBox width and height. Firefox then sizes the SVGs a bit wrong.</p>
+ <p>Chrome, Safari and Edge seem to pass all tests.</p>
+
+ <p id="summary"></p>
+
+ <div id="tests"></div>
+
+ <script>
+ const testsElement = document.getElementById("tests");
+ const summaryElement = document.getElementById("summary");
+
+ // Turn for instance `2.3` into `230` (px). Round to avoid floating point
+ // issues.
+ const scale = (number) => Math.round(100 * number);
+
+ const widths = [2, 2.3, 2.5, 2.8];
+ const heights = [3, 3.3, 3.5, 3.8];
+
+ let numPassed = 0;
+ let numFailed = 0;
+
+ for (const width of widths) {
+ for (const height of heights) {
+ const variations = [
+ {width, height},
+ {width: "auto", height},
+ {width, height: "auto"},
+ {width: "auto", height: "auto"},
+ ];
+
+ for (const variation of variations) {
+ const cellElement = document.createElement("div");
+
+ const titleElement = document.createElement("h2");
+ titleElement.appendChild(makeTitle(width, height, variation));
+
+ const sizeElement = document.createElement("p");
+
+ const svgWrapperElement = document.createElement("div");
+ svgWrapperElement.style.width =
+ variation.width === "auto" && variation.height === "auto"
+ ? `${scale(width)}px`
+ : "auto";
+
+ const svgElement = document.createElementNS("http://www.w3.org/2000/svg", "svg");
+ svgElement.setAttribute("viewBox", `0 0 ${width} ${height}`);
+ svgElement.style.width =
+ typeof variation.width === "number"
+ ? `${scale(variation.width)}px`
+ : variation.width;
+ svgElement.style.height =
+ typeof variation.height === "number"
+ ? `${scale(variation.height)}px`
+ : variation.height;
+
+ svgWrapperElement.appendChild(svgElement);
+
+ cellElement.appendChild(titleElement);
+ cellElement.appendChild(sizeElement);
+ cellElement.appendChild(svgWrapperElement);
+
+ testsElement.appendChild(cellElement);
+
+ const rect = svgElement.getBoundingClientRect();
+ const actual = {
+ width: Math.round(rect.width),
+ height: Math.round(rect.height),
+ };
+ const expected = {
+ width: scale(width),
+ height: scale(height),
+ };
+ const passed =
+ actual.width === expected.width &&
+ actual.height === expected.height;
+
+ const icon = passed ? "✔" : "✘";
+ const iconText = passed ? "PASS" : "FAIL";
+ const expectedText = passed ? "" : `\nExpected size: ${expected.width}x${expected.height}`;
+ sizeElement.textContent = `${icon} ${actual.width}x${actual.height}`;
+ sizeElement.title = `${iconText}. Actual size, as measured by element.getBoundingClientRect().${expectedText}`;
+ sizeElement.style.color = passed ? "lime" : "red";
+ sizeElement.style.fontWeight = passed ? "normal" : "bold";
+
+ cellElement.style.opacity = passed ? 0.5 : 1;
+
+ if (passed) {
+ numPassed++;
+ } else {
+ numFailed++;
+ }
+ }
+ }
+ }
+
+ const numTotal = numPassed + numFailed;
+ const passed = numFailed === 0;
+ const icon = passed ? "✔" : "✘";
+ summaryElement.textContent = `${icon} ${numPassed}/${numTotal} tests passed.`;
+ summaryElement.style.color = passed ? "lime" : "red";
+ summaryElement.style.fontWeight = "bold";
+
+ function makeTitle(width, height, variation) {
+ const fragment = document.createDocumentFragment();
+
+ const first = document.createElement("abbr");
+ first.textContent = `${width}/${height}`;
+ first.title = `SVG viewBox width/height: viewBox="0 0 ${width} ${height}"`;
+
+ const separator = document.createTextNode(" | ");
+
+ const second = document.createElement("abbr");
+
+ const widthString = typeof variation.width === "number" ? "px" : variation.width;
+ const heightString = typeof variation.height === "number" ? "px" : variation.height;
+ second.textContent = `${widthString}/${heightString}`;
+
+ const widthExplanation =
+ typeof variation.width === "number"
+ ? "explicit width (px)"
+ : `${variation.width} width`
+ const heightExplanation =
+ typeof variation.height === "number"
+ ? "explicit height (px)"
+ : `${variation.height} height`
+ second.title = `${widthExplanation}, ${heightExplanation}`;
+
+ fragment.appendChild(first);
+ fragment.appendChild(separator);
+ fragment.appendChild(second);
+
+ return fragment;
+ }
+ </script>
+ </body>
+</html>
diff --git a/dom/system/mac/CoreLocationLocationProvider.mm b/dom/system/mac/CoreLocationLocationProvider.mm
index b39582a9e..7a3feba97 100644
--- a/dom/system/mac/CoreLocationLocationProvider.mm
+++ b/dom/system/mac/CoreLocationLocationProvider.mm
@@ -13,7 +13,6 @@
#include "CoreLocationLocationProvider.h"
#include "nsCocoaFeatures.h"
#include "prtime.h"
-#include "mozilla/Telemetry.h"
#include "MLSFallback.h"
#include <CoreLocation/CLError.h>
@@ -103,7 +102,6 @@ static const CLLocationAccuracy kDEFAULT_ACCURACY = kCLLocationAccuracyNearestTe
PR_Now() / PR_USEC_PER_MSEC);
mProvider->Update(geoPosition);
- Telemetry::Accumulate(Telemetry::GEOLOCATION_OSX_SOURCE_IS_MLS, false);
}
@end
@@ -127,7 +125,6 @@ CoreLocationLocationProvider::MLSUpdate::Update(nsIDOMGeoPosition *position)
return NS_ERROR_FAILURE;
}
mParentLocationProvider.Update(position);
- Telemetry::Accumulate(Telemetry::GEOLOCATION_OSX_SOURCE_IS_MLS, true);
return NS_OK;
}
NS_IMETHODIMP
diff --git a/dom/system/windows/WindowsLocationProvider.cpp b/dom/system/windows/WindowsLocationProvider.cpp
index fa7f8d8be..9da7bcc30 100644
--- a/dom/system/windows/WindowsLocationProvider.cpp
+++ b/dom/system/windows/WindowsLocationProvider.cpp
@@ -10,7 +10,6 @@
#include "nsComponentManagerUtils.h"
#include "prtime.h"
#include "MLSFallback.h"
-#include "mozilla/Telemetry.h"
namespace mozilla {
namespace dom {
@@ -34,7 +33,6 @@ WindowsLocationProvider::MLSUpdate::Update(nsIDOMGeoPosition *aPosition)
if (!coords) {
return NS_ERROR_FAILURE;
}
- Telemetry::Accumulate(Telemetry::GEOLOCATION_WIN8_SOURCE_IS_MLS, true);
return mCallback->Update(aPosition);
}
NS_IMETHODIMP
@@ -176,8 +174,6 @@ LocationEvent::OnLocationChanged(REFIID aReportType,
PR_Now() / PR_USEC_PER_MSEC);
mCallback->Update(position);
- Telemetry::Accumulate(Telemetry::GEOLOCATION_WIN8_SOURCE_IS_MLS, false);
-
return S_OK;
}
diff --git a/dom/url/URLSearchParams.cpp b/dom/url/URLSearchParams.cpp
index d9492f81c..f762299f8 100644
--- a/dom/url/URLSearchParams.cpp
+++ b/dom/url/URLSearchParams.cpp
@@ -314,14 +314,6 @@ URLSearchParams::URLSearchParams(nsISupports* aParent,
{
}
-URLSearchParams::URLSearchParams(nsISupports* aParent,
- const URLSearchParams& aOther)
- : mParams(new URLParams(*aOther.mParams.get()))
- , mParent(aParent)
- , mObserver(nullptr)
-{
-}
-
URLSearchParams::~URLSearchParams()
{
DeleteAll();
@@ -335,34 +327,43 @@ URLSearchParams::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
/* static */ already_AddRefed<URLSearchParams>
URLSearchParams::Constructor(const GlobalObject& aGlobal,
- const nsAString& aInit,
+ const USVStringSequenceSequenceOrUSVStringUSVStringRecordOrUSVString& aInit,
ErrorResult& aRv)
{
RefPtr<URLSearchParams> sp =
new URLSearchParams(aGlobal.GetAsSupports(), nullptr);
- NS_ConvertUTF16toUTF8 input(aInit);
-
- if (StringBeginsWith(input, NS_LITERAL_CSTRING("?"))) {
- sp->ParseInput(Substring(input, 1, input.Length() - 1));
+ if (aInit.IsUSVString()) {
+ NS_ConvertUTF16toUTF8 input(aInit.GetAsUSVString());
+ if (StringBeginsWith(input, NS_LITERAL_CSTRING("?"))) {
+ sp->ParseInput(Substring(input, 1, input.Length() - 1));
+ } else {
+ sp->ParseInput(input);
+ }
+ } else if (aInit.IsUSVStringSequenceSequence()) {
+ const Sequence<Sequence<nsString>>& list =
+ aInit.GetAsUSVStringSequenceSequence();
+ for (uint32_t i = 0; i < list.Length(); ++i) {
+ const Sequence<nsString>& item = list[i];
+ if (item.Length() != 2) {
+ aRv.Throw(NS_ERROR_DOM_TYPE_ERR);
+ return nullptr;
+ }
+ sp->Append(item[0], item[1]);
+ }
+ } else if (aInit.IsUSVStringUSVStringRecord()) {
+ const Record<nsString, nsString>& record =
+ aInit.GetAsUSVStringUSVStringRecord();
+ for (auto& entry : record.Entries()) {
+ sp->Append(entry.mKey, entry.mValue);
+ }
} else {
- sp->ParseInput(input);
+ MOZ_CRASH("URLSearchParams: Invalid string");
}
return sp.forget();
}
-/* static */ already_AddRefed<URLSearchParams>
-URLSearchParams::Constructor(const GlobalObject& aGlobal,
- URLSearchParams& aInit,
- ErrorResult& aRv)
-{
- RefPtr<URLSearchParams> sp =
- new URLSearchParams(aGlobal.GetAsSupports(), aInit);
-
- return sp.forget();
-}
-
void
URLSearchParams::ParseInput(const nsACString& aInput)
{
diff --git a/dom/url/URLSearchParams.h b/dom/url/URLSearchParams.h
index 4b0aaa991..9fefd78dd 100644
--- a/dom/url/URLSearchParams.h
+++ b/dom/url/URLSearchParams.h
@@ -20,6 +20,7 @@ namespace mozilla {
namespace dom {
class URLSearchParams;
+class USVStringSequenceSequenceOrUSVStringUSVStringRecordOrUSVString;
class URLSearchParamsObserver : public nsISupports
{
@@ -43,14 +44,6 @@ public:
DeleteAll();
}
- explicit URLParams(const URLParams& aOther)
- : mParams(aOther.mParams)
- {}
-
- URLParams(const URLParams&& aOther)
- : mParams(Move(aOther.mParams))
- {}
-
class ForEachIterator
{
public:
@@ -144,9 +137,6 @@ public:
explicit URLSearchParams(nsISupports* aParent,
URLSearchParamsObserver* aObserver=nullptr);
- URLSearchParams(nsISupports* aParent,
- const URLSearchParams& aOther);
-
// WebIDL methods
nsISupports* GetParentObject() const
{
@@ -157,11 +147,8 @@ public:
WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
static already_AddRefed<URLSearchParams>
- Constructor(const GlobalObject& aGlobal, const nsAString& aInit,
- ErrorResult& aRv);
-
- static already_AddRefed<URLSearchParams>
- Constructor(const GlobalObject& aGlobal, URLSearchParams& aInit,
+ Constructor(const GlobalObject& aGlobal,
+ const USVStringSequenceSequenceOrUSVStringUSVStringRecordOrUSVString& aInit,
ErrorResult& aRv);
void ParseInput(const nsACString& aInput);
diff --git a/dom/vr/VRDisplay.cpp b/dom/vr/VRDisplay.cpp
deleted file mode 100644
index 80922422f..000000000
--- a/dom/vr/VRDisplay.cpp
+++ /dev/null
@@ -1,802 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nsWrapperCache.h"
-
-#include "mozilla/dom/Element.h"
-#include "mozilla/dom/ElementBinding.h"
-#include "mozilla/dom/Promise.h"
-#include "mozilla/dom/VRDisplay.h"
-#include "mozilla/HoldDropJSObjects.h"
-#include "mozilla/dom/VRDisplayBinding.h"
-#include "Navigator.h"
-#include "gfxVR.h"
-#include "VRDisplayClient.h"
-#include "VRManagerChild.h"
-#include "VRDisplayPresentation.h"
-#include "nsIObserverService.h"
-#include "nsIFrame.h"
-#include "nsISupportsPrimitives.h"
-
-using namespace mozilla::gfx;
-
-namespace mozilla {
-namespace dom {
-
-VRFieldOfView::VRFieldOfView(nsISupports* aParent,
- double aUpDegrees, double aRightDegrees,
- double aDownDegrees, double aLeftDegrees)
- : mParent(aParent)
- , mUpDegrees(aUpDegrees)
- , mRightDegrees(aRightDegrees)
- , mDownDegrees(aDownDegrees)
- , mLeftDegrees(aLeftDegrees)
-{
-}
-
-VRFieldOfView::VRFieldOfView(nsISupports* aParent, const gfx::VRFieldOfView& aSrc)
- : mParent(aParent)
- , mUpDegrees(aSrc.upDegrees)
- , mRightDegrees(aSrc.rightDegrees)
- , mDownDegrees(aSrc.downDegrees)
- , mLeftDegrees(aSrc.leftDegrees)
-{
-}
-
-bool
-VRDisplayCapabilities::HasPosition() const
-{
- return bool(mFlags & gfx::VRDisplayCapabilityFlags::Cap_Position);
-}
-
-bool
-VRDisplayCapabilities::HasOrientation() const
-{
- return bool(mFlags & gfx::VRDisplayCapabilityFlags::Cap_Orientation);
-}
-
-bool
-VRDisplayCapabilities::HasExternalDisplay() const
-{
- return bool(mFlags & gfx::VRDisplayCapabilityFlags::Cap_External);
-}
-
-bool
-VRDisplayCapabilities::CanPresent() const
-{
- return bool(mFlags & gfx::VRDisplayCapabilityFlags::Cap_Present);
-}
-
-uint32_t
-VRDisplayCapabilities::MaxLayers() const
-{
- return CanPresent() ? 1 : 0;
-}
-
-/*static*/ bool
-VRDisplay::RefreshVRDisplays(uint64_t aWindowId)
-{
- gfx::VRManagerChild* vm = gfx::VRManagerChild::Get();
- return vm && vm->RefreshVRDisplaysWithCallback(aWindowId);
-}
-
-/*static*/ void
-VRDisplay::UpdateVRDisplays(nsTArray<RefPtr<VRDisplay>>& aDisplays, nsPIDOMWindowInner* aWindow)
-{
- nsTArray<RefPtr<VRDisplay>> displays;
-
- gfx::VRManagerChild* vm = gfx::VRManagerChild::Get();
- nsTArray<RefPtr<gfx::VRDisplayClient>> updatedDisplays;
- if (vm && vm->GetVRDisplays(updatedDisplays)) {
- for (size_t i = 0; i < updatedDisplays.Length(); i++) {
- RefPtr<gfx::VRDisplayClient> display = updatedDisplays[i];
- bool isNewDisplay = true;
- for (size_t j = 0; j < aDisplays.Length(); j++) {
- if (aDisplays[j]->GetClient()->GetDisplayInfo() == display->GetDisplayInfo()) {
- displays.AppendElement(aDisplays[j]);
- isNewDisplay = false;
- }
- }
-
- if (isNewDisplay) {
- displays.AppendElement(new VRDisplay(aWindow, display));
- }
- }
- }
-
- aDisplays = displays;
-}
-
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(VRFieldOfView, mParent)
-NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(VRFieldOfView, AddRef)
-NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(VRFieldOfView, Release)
-
-
-JSObject*
-VRFieldOfView::WrapObject(JSContext* aCx,
- JS::Handle<JSObject*> aGivenProto)
-{
- return VRFieldOfViewBinding::Wrap(aCx, this, aGivenProto);
-}
-
-NS_IMPL_CYCLE_COLLECTION_CLASS(VREyeParameters)
-
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(VREyeParameters)
- NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent, mFOV)
- NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
- tmp->mOffset = nullptr;
-NS_IMPL_CYCLE_COLLECTION_UNLINK_END
-
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(VREyeParameters)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent, mFOV)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
-
-NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(VREyeParameters)
- NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
- NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mOffset)
-NS_IMPL_CYCLE_COLLECTION_TRACE_END
-
-NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(VREyeParameters, AddRef)
-NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(VREyeParameters, Release)
-
-VREyeParameters::VREyeParameters(nsISupports* aParent,
- const gfx::Point3D& aEyeTranslation,
- const gfx::VRFieldOfView& aFOV,
- const gfx::IntSize& aRenderSize)
- : mParent(aParent)
- , mEyeTranslation(aEyeTranslation)
- , mRenderSize(aRenderSize)
-{
- mFOV = new VRFieldOfView(aParent, aFOV);
- mozilla::HoldJSObjects(this);
-}
-
-VREyeParameters::~VREyeParameters()
-{
- mozilla::DropJSObjects(this);
-}
-
-VRFieldOfView*
-VREyeParameters::FieldOfView()
-{
- return mFOV;
-}
-
-void
-VREyeParameters::GetOffset(JSContext* aCx, JS::MutableHandle<JSObject*> aRetval, ErrorResult& aRv)
-{
- if (!mOffset) {
- // Lazily create the Float32Array
- mOffset = dom::Float32Array::Create(aCx, this, 3, mEyeTranslation.components);
- if (!mOffset) {
- aRv.NoteJSContextException(aCx);
- return;
- }
- }
- aRetval.set(mOffset);
-}
-
-JSObject*
-VREyeParameters::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
-{
- return VREyeParametersBinding::Wrap(aCx, this, aGivenProto);
-}
-
-VRStageParameters::VRStageParameters(nsISupports* aParent,
- const gfx::Matrix4x4& aSittingToStandingTransform,
- const gfx::Size& aSize)
- : mParent(aParent)
- , mSittingToStandingTransform(aSittingToStandingTransform)
- , mSittingToStandingTransformArray(nullptr)
- , mSize(aSize)
-{
- mozilla::HoldJSObjects(this);
-}
-
-VRStageParameters::~VRStageParameters()
-{
- mozilla::DropJSObjects(this);
-}
-
-JSObject*
-VRStageParameters::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
-{
- return VRStageParametersBinding::Wrap(aCx, this, aGivenProto);
-}
-
-NS_IMPL_CYCLE_COLLECTION_CLASS(VRStageParameters)
-
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(VRStageParameters)
- NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent)
- NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
- tmp->mSittingToStandingTransformArray = nullptr;
-NS_IMPL_CYCLE_COLLECTION_UNLINK_END
-
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(VRStageParameters)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
-
-NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(VRStageParameters)
- NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
- NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mSittingToStandingTransformArray)
-NS_IMPL_CYCLE_COLLECTION_TRACE_END
-
-NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(VRStageParameters, AddRef)
-NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(VRStageParameters, Release)
-
-void
-VRStageParameters::GetSittingToStandingTransform(JSContext* aCx,
- JS::MutableHandle<JSObject*> aRetval,
- ErrorResult& aRv)
-{
- if (!mSittingToStandingTransformArray) {
- // Lazily create the Float32Array
- mSittingToStandingTransformArray = dom::Float32Array::Create(aCx, this, 16,
- mSittingToStandingTransform.components);
- if (!mSittingToStandingTransformArray) {
- aRv.NoteJSContextException(aCx);
- return;
- }
- }
- aRetval.set(mSittingToStandingTransformArray);
-}
-
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(VRDisplayCapabilities, mParent)
-NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(VRDisplayCapabilities, AddRef)
-NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(VRDisplayCapabilities, Release)
-
-JSObject*
-VRDisplayCapabilities::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
-{
- return VRDisplayCapabilitiesBinding::Wrap(aCx, this, aGivenProto);
-}
-
-VRPose::VRPose(nsISupports* aParent, const gfx::VRHMDSensorState& aState)
- : Pose(aParent)
- , mVRState(aState)
-{
- mFrameId = aState.inputFrameID;
- mozilla::HoldJSObjects(this);
-}
-
-VRPose::VRPose(nsISupports* aParent)
- : Pose(aParent)
-{
- mFrameId = 0;
- mVRState.Clear();
- mozilla::HoldJSObjects(this);
-}
-
-VRPose::~VRPose()
-{
- mozilla::DropJSObjects(this);
-}
-
-void
-VRPose::GetPosition(JSContext* aCx,
- JS::MutableHandle<JSObject*> aRetval,
- ErrorResult& aRv)
-{
- SetFloat32Array(aCx, aRetval, mPosition, mVRState.position, 3,
- !mPosition && bool(mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_Position),
- aRv);
-}
-
-void
-VRPose::GetLinearVelocity(JSContext* aCx,
- JS::MutableHandle<JSObject*> aRetval,
- ErrorResult& aRv)
-{
- SetFloat32Array(aCx, aRetval, mLinearVelocity, mVRState.linearVelocity, 3,
- !mLinearVelocity && bool(mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_Position),
- aRv);
-}
-
-void
-VRPose::GetLinearAcceleration(JSContext* aCx,
- JS::MutableHandle<JSObject*> aRetval,
- ErrorResult& aRv)
-{
- SetFloat32Array(aCx, aRetval, mLinearAcceleration, mVRState.linearAcceleration, 3,
- !mLinearAcceleration && bool(mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_LinearAcceleration),
- aRv);
-
-}
-
-void
-VRPose::GetOrientation(JSContext* aCx,
- JS::MutableHandle<JSObject*> aRetval,
- ErrorResult& aRv)
-{
- SetFloat32Array(aCx, aRetval, mOrientation, mVRState.orientation, 4,
- !mOrientation && bool(mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_Orientation),
- aRv);
-}
-
-void
-VRPose::GetAngularVelocity(JSContext* aCx,
- JS::MutableHandle<JSObject*> aRetval,
- ErrorResult& aRv)
-{
- SetFloat32Array(aCx, aRetval, mAngularVelocity, mVRState.angularVelocity, 3,
- !mAngularVelocity && bool(mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_Orientation),
- aRv);
-}
-
-void
-VRPose::GetAngularAcceleration(JSContext* aCx,
- JS::MutableHandle<JSObject*> aRetval,
- ErrorResult& aRv)
-{
- SetFloat32Array(aCx, aRetval, mAngularAcceleration, mVRState.angularAcceleration, 3,
- !mAngularAcceleration && bool(mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_AngularAcceleration),
- aRv);
-}
-
-JSObject*
-VRPose::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
-{
- return VRPoseBinding::Wrap(aCx, this, aGivenProto);
-}
-
-/* virtual */ JSObject*
-VRDisplay::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
-{
- return VRDisplayBinding::Wrap(aCx, this, aGivenProto);
-}
-
-VRDisplay::VRDisplay(nsPIDOMWindowInner* aWindow, gfx::VRDisplayClient* aClient)
- : DOMEventTargetHelper(aWindow)
- , mClient(aClient)
- , mDepthNear(0.01f) // Default value from WebVR Spec
- , mDepthFar(10000.0f) // Default value from WebVR Spec
-{
- const gfx::VRDisplayInfo& info = aClient->GetDisplayInfo();
- mDisplayId = info.GetDisplayID();
- mDisplayName = NS_ConvertASCIItoUTF16(info.GetDisplayName());
- mCapabilities = new VRDisplayCapabilities(aWindow, info.GetCapabilities());
- if (info.GetCapabilities() & gfx::VRDisplayCapabilityFlags::Cap_StageParameters) {
- mStageParameters = new VRStageParameters(aWindow,
- info.GetSittingToStandingTransform(),
- info.GetStageSize());
- }
- mozilla::HoldJSObjects(this);
-}
-
-VRDisplay::~VRDisplay()
-{
- ExitPresentInternal();
- mozilla::DropJSObjects(this);
-}
-
-void
-VRDisplay::LastRelease()
-{
- // We don't want to wait for the CC to free up the presentation
- // for use in other documents, so we do this in LastRelease().
- ExitPresentInternal();
-}
-
-already_AddRefed<VREyeParameters>
-VRDisplay::GetEyeParameters(VREye aEye)
-{
- gfx::VRDisplayInfo::Eye eye = aEye == VREye::Left ? gfx::VRDisplayInfo::Eye_Left : gfx::VRDisplayInfo::Eye_Right;
- RefPtr<VREyeParameters> params =
- new VREyeParameters(GetParentObject(),
- mClient->GetDisplayInfo().GetEyeTranslation(eye),
- mClient->GetDisplayInfo().GetEyeFOV(eye),
- mClient->GetDisplayInfo().SuggestedEyeResolution());
- return params.forget();
-}
-
-VRDisplayCapabilities*
-VRDisplay::Capabilities()
-{
- return mCapabilities;
-}
-
-VRStageParameters*
-VRDisplay::GetStageParameters()
-{
- return mStageParameters;
-}
-
-void
-VRDisplay::UpdateFrameInfo()
-{
- /**
- * The WebVR 1.1 spec Requires that VRDisplay.getPose and VRDisplay.getFrameData
- * must return the same values until the next VRDisplay.submitFrame.
- *
- * mFrameInfo is marked dirty at the end of the frame or start of a new
- * composition and lazily created here in order to receive mid-frame
- * pose-prediction updates while still ensuring conformance to the WebVR spec
- * requirements.
- *
- * If we are not presenting WebVR content, the frame will never end and we should
- * return the latest frame data always.
- */
- if (mFrameInfo.IsDirty() || !mPresentation) {
- gfx::VRHMDSensorState state = mClient->GetSensorState();
- const gfx::VRDisplayInfo& info = mClient->GetDisplayInfo();
- mFrameInfo.Update(info, state, mDepthNear, mDepthFar);
- }
-}
-
-bool
-VRDisplay::GetFrameData(VRFrameData& aFrameData)
-{
- UpdateFrameInfo();
- aFrameData.Update(mFrameInfo);
- return true;
-}
-
-already_AddRefed<VRPose>
-VRDisplay::GetPose()
-{
- UpdateFrameInfo();
- RefPtr<VRPose> obj = new VRPose(GetParentObject(), mFrameInfo.mVRState);
-
- return obj.forget();
-}
-
-void
-VRDisplay::ResetPose()
-{
- mClient->ZeroSensor();
-}
-
-already_AddRefed<Promise>
-VRDisplay::RequestPresent(const nsTArray<VRLayer>& aLayers, ErrorResult& aRv)
-{
- nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetParentObject());
- if (!global) {
- aRv.Throw(NS_ERROR_FAILURE);
- return nullptr;
- }
-
- RefPtr<Promise> promise = Promise::Create(global, aRv);
- NS_ENSURE_TRUE(!aRv.Failed(), nullptr);
-
- nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
- NS_ENSURE_TRUE(obs, nullptr);
-
- if (mClient->GetIsPresenting()) {
- // Only one presentation allowed per VRDisplay
- // on a first-come-first-serve basis.
- promise->MaybeRejectWithUndefined();
- } else {
- mPresentation = mClient->BeginPresentation(aLayers);
- mFrameInfo.Clear();
-
- nsresult rv = obs->AddObserver(this, "inner-window-destroyed", false);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- mPresentation = nullptr;
- promise->MaybeRejectWithUndefined();
- } else {
- promise->MaybeResolve(JS::UndefinedHandleValue);
- }
- }
- return promise.forget();
-}
-
-NS_IMETHODIMP
-VRDisplay::Observe(nsISupports* aSubject, const char* aTopic,
- const char16_t* aData)
-{
- MOZ_ASSERT(NS_IsMainThread());
-
- if (strcmp(aTopic, "inner-window-destroyed") == 0) {
- nsCOMPtr<nsISupportsPRUint64> wrapper = do_QueryInterface(aSubject);
- NS_ENSURE_TRUE(wrapper, NS_ERROR_FAILURE);
-
- uint64_t innerID;
- nsresult rv = wrapper->GetData(&innerID);
- NS_ENSURE_SUCCESS(rv, rv);
-
- if (!GetOwner() || GetOwner()->WindowID() == innerID) {
- ExitPresentInternal();
- }
-
- return NS_OK;
- }
-
- // This should not happen.
- return NS_ERROR_FAILURE;
-}
-
-already_AddRefed<Promise>
-VRDisplay::ExitPresent(ErrorResult& aRv)
-{
- nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetParentObject());
- if (!global) {
- aRv.Throw(NS_ERROR_FAILURE);
- return nullptr;
- }
-
-
- RefPtr<Promise> promise = Promise::Create(global, aRv);
- NS_ENSURE_TRUE(!aRv.Failed(), nullptr);
-
- if (!IsPresenting()) {
- // We can not exit a presentation outside of the context that
- // started the presentation.
- promise->MaybeRejectWithUndefined();
- } else {
- promise->MaybeResolve(JS::UndefinedHandleValue);
- ExitPresentInternal();
- }
-
- return promise.forget();
-}
-
-void
-VRDisplay::ExitPresentInternal()
-{
- mPresentation = nullptr;
-}
-
-void
-VRDisplay::GetLayers(nsTArray<VRLayer>& result)
-{
- if (mPresentation) {
- mPresentation->GetDOMLayers(result);
- } else {
- result = nsTArray<VRLayer>();
- }
-}
-
-void
-VRDisplay::SubmitFrame()
-{
- if (mPresentation) {
- mPresentation->SubmitFrame();
- }
- mFrameInfo.Clear();
-}
-
-int32_t
-VRDisplay::RequestAnimationFrame(FrameRequestCallback& aCallback,
-ErrorResult& aError)
-{
- gfx::VRManagerChild* vm = gfx::VRManagerChild::Get();
-
- int32_t handle;
- aError = vm->ScheduleFrameRequestCallback(aCallback, &handle);
- return handle;
-}
-
-void
-VRDisplay::CancelAnimationFrame(int32_t aHandle, ErrorResult& aError)
-{
- gfx::VRManagerChild* vm = gfx::VRManagerChild::Get();
- vm->CancelFrameRequestCallback(aHandle);
-}
-
-
-bool
-VRDisplay::IsPresenting() const
-{
- // IsPresenting returns true only if this Javascript context is presenting
- // and will return false if another context is presenting.
- return mPresentation != nullptr;
-}
-
-bool
-VRDisplay::IsConnected() const
-{
- return mClient->GetIsConnected();
-}
-
-NS_IMPL_CYCLE_COLLECTION_INHERITED(VRDisplay, DOMEventTargetHelper, mCapabilities, mStageParameters)
-
-NS_IMPL_ADDREF_INHERITED(VRDisplay, DOMEventTargetHelper)
-NS_IMPL_RELEASE_INHERITED(VRDisplay, DOMEventTargetHelper)
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(VRDisplay)
-NS_INTERFACE_MAP_ENTRY(nsIObserver)
-NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, DOMEventTargetHelper)
-NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
-
-NS_IMPL_CYCLE_COLLECTION_CLASS(VRFrameData)
-
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(VRFrameData)
- NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent, mPose)
- NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
- tmp->mLeftProjectionMatrix = nullptr;
- tmp->mLeftViewMatrix = nullptr;
- tmp->mRightProjectionMatrix = nullptr;
- tmp->mRightViewMatrix = nullptr;
-NS_IMPL_CYCLE_COLLECTION_UNLINK_END
-
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(VRFrameData)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent, mPose)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
-
-NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(VRFrameData)
- NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
- NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mLeftProjectionMatrix)
- NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mLeftViewMatrix)
- NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mRightProjectionMatrix)
- NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mRightViewMatrix)
-NS_IMPL_CYCLE_COLLECTION_TRACE_END
-
-NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(VRFrameData, AddRef)
-NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(VRFrameData, Release)
-
-VRFrameData::VRFrameData(nsISupports* aParent)
- : mParent(aParent)
- , mLeftProjectionMatrix(nullptr)
- , mLeftViewMatrix(nullptr)
- , mRightProjectionMatrix(nullptr)
- , mRightViewMatrix(nullptr)
-{
- mozilla::HoldJSObjects(this);
- mPose = new VRPose(aParent);
-}
-
-VRFrameData::~VRFrameData()
-{
- mozilla::DropJSObjects(this);
-}
-
-/* static */ already_AddRefed<VRFrameData>
-VRFrameData::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv)
-{
- RefPtr<VRFrameData> obj = new VRFrameData(aGlobal.GetAsSupports());
- return obj.forget();
-}
-
-JSObject*
-VRFrameData::WrapObject(JSContext* aCx,
- JS::Handle<JSObject*> aGivenProto)
-{
- return VRFrameDataBinding::Wrap(aCx, this, aGivenProto);
-}
-
-VRPose*
-VRFrameData::Pose()
-{
- return mPose;
-}
-
-void
-VRFrameData::LazyCreateMatrix(JS::Heap<JSObject*>& aArray, gfx::Matrix4x4& aMat, JSContext* aCx,
- JS::MutableHandle<JSObject*> aRetval, ErrorResult& aRv)
-{
- if (!aArray) {
- // Lazily create the Float32Array
- aArray = dom::Float32Array::Create(aCx, this, 16, aMat.components);
- if (!aArray) {
- aRv.NoteJSContextException(aCx);
- return;
- }
- }
- if (aArray) {
- JS::ExposeObjectToActiveJS(aArray);
- }
- aRetval.set(aArray);
-}
-
-double
-VRFrameData::Timestamp() const
-{
- // Converting from seconds to milliseconds
- return mFrameInfo.mVRState.timestamp * 1000.0f;
-}
-
-void
-VRFrameData::GetLeftProjectionMatrix(JSContext* aCx,
- JS::MutableHandle<JSObject*> aRetval,
- ErrorResult& aRv)
-{
- LazyCreateMatrix(mLeftProjectionMatrix, mFrameInfo.mLeftProjection, aCx,
- aRetval, aRv);
-}
-
-void
-VRFrameData::GetLeftViewMatrix(JSContext* aCx,
- JS::MutableHandle<JSObject*> aRetval,
- ErrorResult& aRv)
-{
- LazyCreateMatrix(mLeftViewMatrix, mFrameInfo.mLeftView, aCx, aRetval, aRv);
-}
-
-void
-VRFrameData::GetRightProjectionMatrix(JSContext* aCx,
- JS::MutableHandle<JSObject*> aRetval,
- ErrorResult& aRv)
-{
- LazyCreateMatrix(mRightProjectionMatrix, mFrameInfo.mRightProjection, aCx,
- aRetval, aRv);
-}
-
-void
-VRFrameData::GetRightViewMatrix(JSContext* aCx,
- JS::MutableHandle<JSObject*> aRetval,
- ErrorResult& aRv)
-{
- LazyCreateMatrix(mRightViewMatrix, mFrameInfo.mRightView, aCx, aRetval, aRv);
-}
-
-void
-VRFrameData::Update(const VRFrameInfo& aFrameInfo)
-{
- mFrameInfo = aFrameInfo;
-
- mLeftProjectionMatrix = nullptr;
- mLeftViewMatrix = nullptr;
- mRightProjectionMatrix = nullptr;
- mRightViewMatrix = nullptr;
-
- mPose = new VRPose(GetParentObject(), mFrameInfo.mVRState);
-}
-
-void
-VRFrameInfo::Update(const gfx::VRDisplayInfo& aInfo,
- const gfx::VRHMDSensorState& aState,
- float aDepthNear,
- float aDepthFar)
-{
- mVRState = aState;
-
- gfx::Quaternion qt;
- if (mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_Orientation) {
- qt.x = mVRState.orientation[0];
- qt.y = mVRState.orientation[1];
- qt.z = mVRState.orientation[2];
- qt.w = mVRState.orientation[3];
- }
- gfx::Point3D pos;
- if (mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_Position) {
- pos.x = -mVRState.position[0];
- pos.y = -mVRState.position[1];
- pos.z = -mVRState.position[2];
- }
- gfx::Matrix4x4 matHead;
- matHead.SetRotationFromQuaternion(qt);
- matHead.PreTranslate(pos);
-
- mLeftView = matHead;
- mLeftView.PostTranslate(-aInfo.mEyeTranslation[gfx::VRDisplayInfo::Eye_Left]);
-
- mRightView = matHead;
- mRightView.PostTranslate(-aInfo.mEyeTranslation[gfx::VRDisplayInfo::Eye_Right]);
-
- // Avoid division by zero within ConstructProjectionMatrix
- const float kEpsilon = 0.00001f;
- if (fabs(aDepthFar - aDepthNear) < kEpsilon) {
- aDepthFar = aDepthNear + kEpsilon;
- }
-
- const gfx::VRFieldOfView leftFOV = aInfo.mEyeFOV[gfx::VRDisplayInfo::Eye_Left];
- mLeftProjection = leftFOV.ConstructProjectionMatrix(aDepthNear, aDepthFar, true);
- const gfx::VRFieldOfView rightFOV = aInfo.mEyeFOV[gfx::VRDisplayInfo::Eye_Right];
- mRightProjection = rightFOV.ConstructProjectionMatrix(aDepthNear, aDepthFar, true);
-}
-
-VRFrameInfo::VRFrameInfo()
-{
- mVRState.Clear();
-}
-
-bool
-VRFrameInfo::IsDirty()
-{
- return mVRState.timestamp == 0;
-}
-
-void
-VRFrameInfo::Clear()
-{
- mVRState.Clear();
-}
-
-} // namespace dom
-} // namespace mozilla
diff --git a/dom/vr/VRDisplay.h b/dom/vr/VRDisplay.h
deleted file mode 100644
index d40d3d8ac..000000000
--- a/dom/vr/VRDisplay.h
+++ /dev/null
@@ -1,362 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef mozilla_dom_VRDisplay_h_
-#define mozilla_dom_VRDisplay_h_
-
-#include <stdint.h>
-
-#include "mozilla/ErrorResult.h"
-#include "mozilla/dom/TypedArray.h"
-#include "mozilla/dom/VRDisplayBinding.h"
-#include "mozilla/DOMEventTargetHelper.h"
-#include "mozilla/dom/DOMPoint.h"
-#include "mozilla/dom/DOMRect.h"
-#include "mozilla/dom/Pose.h"
-
-#include "nsCOMPtr.h"
-#include "nsString.h"
-#include "nsTArray.h"
-
-#include "gfxVR.h"
-
-namespace mozilla {
-namespace gfx {
-class VRDisplayClient;
-class VRDisplayPresentation;
-struct VRFieldOfView;
-enum class VRDisplayCapabilityFlags : uint16_t;
-struct VRHMDSensorState;
-}
-namespace dom {
-class Navigator;
-
-class VRFieldOfView final : public nsWrapperCache
-{
-public:
- VRFieldOfView(nsISupports* aParent,
- double aUpDegrees, double aRightDegrees,
- double aDownDegrees, double aLeftDegrees);
- VRFieldOfView(nsISupports* aParent, const gfx::VRFieldOfView& aSrc);
-
- NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(VRFieldOfView)
- NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(VRFieldOfView)
-
- double UpDegrees() const { return mUpDegrees; }
- double RightDegrees() const { return mRightDegrees; }
- double DownDegrees() const { return mDownDegrees; }
- double LeftDegrees() const { return mLeftDegrees; }
-
- nsISupports* GetParentObject() const { return mParent; }
- virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
-
-protected:
- virtual ~VRFieldOfView() {}
-
- nsCOMPtr<nsISupports> mParent;
-
- double mUpDegrees;
- double mRightDegrees;
- double mDownDegrees;
- double mLeftDegrees;
-};
-
-class VRDisplayCapabilities final : public nsWrapperCache
-{
-public:
- VRDisplayCapabilities(nsISupports* aParent, const gfx::VRDisplayCapabilityFlags& aFlags)
- : mParent(aParent)
- , mFlags(aFlags)
- {
- }
-
- NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(VRDisplayCapabilities)
- NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(VRDisplayCapabilities)
-
- nsISupports* GetParentObject() const
- {
- return mParent;
- }
-
- virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
-
- bool HasPosition() const;
- bool HasOrientation() const;
- bool HasExternalDisplay() const;
- bool CanPresent() const;
- uint32_t MaxLayers() const;
-
-protected:
- ~VRDisplayCapabilities() {}
- nsCOMPtr<nsISupports> mParent;
- gfx::VRDisplayCapabilityFlags mFlags;
-};
-
-class VRPose final : public Pose
-{
-
-public:
- VRPose(nsISupports* aParent, const gfx::VRHMDSensorState& aState);
- explicit VRPose(nsISupports* aParent);
-
- uint32_t FrameID() const { return mFrameId; }
-
- virtual void GetPosition(JSContext* aCx,
- JS::MutableHandle<JSObject*> aRetval,
- ErrorResult& aRv) override;
- virtual void GetLinearVelocity(JSContext* aCx,
- JS::MutableHandle<JSObject*> aRetval,
- ErrorResult& aRv) override;
- virtual void GetLinearAcceleration(JSContext* aCx,
- JS::MutableHandle<JSObject*> aRetval,
- ErrorResult& aRv) override;
- virtual void GetOrientation(JSContext* aCx,
- JS::MutableHandle<JSObject*> aRetval,
- ErrorResult& aRv) override;
- virtual void GetAngularVelocity(JSContext* aCx,
- JS::MutableHandle<JSObject*> aRetval,
- ErrorResult& aRv) override;
- virtual void GetAngularAcceleration(JSContext* aCx,
- JS::MutableHandle<JSObject*> aRetval,
- ErrorResult& aRv) override;
-
- virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
-
-protected:
- ~VRPose();
-
- uint32_t mFrameId;
- gfx::VRHMDSensorState mVRState;
-};
-
-struct VRFrameInfo
-{
- VRFrameInfo();
-
- void Update(const gfx::VRDisplayInfo& aInfo,
- const gfx::VRHMDSensorState& aState,
- float aDepthNear,
- float aDepthFar);
-
- void Clear();
- bool IsDirty();
-
- gfx::VRHMDSensorState mVRState;
- gfx::Matrix4x4 mLeftProjection;
- gfx::Matrix4x4 mLeftView;
- gfx::Matrix4x4 mRightProjection;
- gfx::Matrix4x4 mRightView;
-
-};
-
-class VRFrameData final : public nsWrapperCache
-{
-public:
- NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(VRFrameData)
- NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(VRFrameData)
-
- explicit VRFrameData(nsISupports* aParent);
- static already_AddRefed<VRFrameData> Constructor(const GlobalObject& aGlobal,
- ErrorResult& aRv);
-
- void Update(const VRFrameInfo& aFrameInfo);
-
- // WebIDL Members
- double Timestamp() const;
- void GetLeftProjectionMatrix(JSContext* aCx,
- JS::MutableHandle<JSObject*> aRetval,
- ErrorResult& aRv);
- void GetLeftViewMatrix(JSContext* aCx,
- JS::MutableHandle<JSObject*> aRetval,
- ErrorResult& aRv);
- void GetRightProjectionMatrix(JSContext* aCx,
- JS::MutableHandle<JSObject*> aRetval,
- ErrorResult& aRv);
- void GetRightViewMatrix(JSContext* aCx,
- JS::MutableHandle<JSObject*> aRetval,
- ErrorResult& aRv);
-
- VRPose* Pose();
-
- // WebIDL Boilerplate
- nsISupports* GetParentObject() const { return mParent; }
- virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
-
-protected:
- ~VRFrameData();
- nsCOMPtr<nsISupports> mParent;
-
- VRFrameInfo mFrameInfo;
- RefPtr<VRPose> mPose;
- JS::Heap<JSObject*> mLeftProjectionMatrix;
- JS::Heap<JSObject*> mLeftViewMatrix;
- JS::Heap<JSObject*> mRightProjectionMatrix;
- JS::Heap<JSObject*> mRightViewMatrix;
-
- void LazyCreateMatrix(JS::Heap<JSObject*>& aArray, gfx::Matrix4x4& aMat,
- JSContext* aCx, JS::MutableHandle<JSObject*> aRetval,
- ErrorResult& aRv);
-};
-
-class VRStageParameters final : public nsWrapperCache
-{
-public:
- VRStageParameters(nsISupports* aParent,
- const gfx::Matrix4x4& aSittingToStandingTransform,
- const gfx::Size& aSize);
-
- NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(VRStageParameters)
- NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(VRStageParameters)
-
- void GetSittingToStandingTransform(JSContext* aCx,
- JS::MutableHandle<JSObject*> aRetval,
- ErrorResult& aRv);
- float SizeX() const { return mSize.width; }
- float SizeZ() const { return mSize.height; }
-
- nsISupports* GetParentObject() const { return mParent; }
- virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
-
-protected:
- ~VRStageParameters();
-
- nsCOMPtr<nsISupports> mParent;
-
- gfx::Matrix4x4 mSittingToStandingTransform;
- JS::Heap<JSObject*> mSittingToStandingTransformArray;
- gfx::Size mSize;
-};
-
-class VREyeParameters final : public nsWrapperCache
-{
-public:
- VREyeParameters(nsISupports* aParent,
- const gfx::Point3D& aEyeTranslation,
- const gfx::VRFieldOfView& aFOV,
- const gfx::IntSize& aRenderSize);
-
- NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(VREyeParameters)
- NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(VREyeParameters)
-
- void GetOffset(JSContext* aCx, JS::MutableHandle<JSObject*> aRetVal,
- ErrorResult& aRv);
-
- VRFieldOfView* FieldOfView();
-
- uint32_t RenderWidth() const { return mRenderSize.width; }
- uint32_t RenderHeight() const { return mRenderSize.height; }
-
- nsISupports* GetParentObject() const { return mParent; }
- virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
-protected:
- ~VREyeParameters();
-
- nsCOMPtr<nsISupports> mParent;
-
-
- gfx::Point3D mEyeTranslation;
- gfx::IntSize mRenderSize;
- JS::Heap<JSObject*> mOffset;
- RefPtr<VRFieldOfView> mFOV;
-};
-
-class VRDisplay final : public DOMEventTargetHelper
- , public nsIObserver
-{
-public:
- NS_DECL_ISUPPORTS_INHERITED
- NS_DECL_NSIOBSERVER
- NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(VRDisplay, DOMEventTargetHelper)
-
- virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
-
- bool IsPresenting() const;
- bool IsConnected() const;
-
- VRDisplayCapabilities* Capabilities();
- VRStageParameters* GetStageParameters();
-
- uint32_t DisplayId() const { return mDisplayId; }
- void GetDisplayName(nsAString& aDisplayName) const { aDisplayName = mDisplayName; }
-
- static bool RefreshVRDisplays(uint64_t aWindowId);
- static void UpdateVRDisplays(nsTArray<RefPtr<VRDisplay> >& aDisplays,
- nsPIDOMWindowInner* aWindow);
-
- gfx::VRDisplayClient *GetClient() {
- return mClient;
- }
-
- virtual already_AddRefed<VREyeParameters> GetEyeParameters(VREye aEye);
-
- bool GetFrameData(VRFrameData& aFrameData);
- already_AddRefed<VRPose> GetPose();
- void ResetPose();
-
- double DepthNear() {
- return mDepthNear;
- }
-
- double DepthFar() {
- return mDepthFar;
- }
-
- void SetDepthNear(double aDepthNear) {
- // XXX When we start sending depth buffers to VRLayer's we will want
- // to communicate this with the VRDisplayHost
- mDepthNear = aDepthNear;
- }
-
- void SetDepthFar(double aDepthFar) {
- // XXX When we start sending depth buffers to VRLayer's we will want
- // to communicate this with the VRDisplayHost
- mDepthFar = aDepthFar;
- }
-
- already_AddRefed<Promise> RequestPresent(const nsTArray<VRLayer>& aLayers, ErrorResult& aRv);
- already_AddRefed<Promise> ExitPresent(ErrorResult& aRv);
- void GetLayers(nsTArray<VRLayer>& result);
- void SubmitFrame();
-
- int32_t RequestAnimationFrame(mozilla::dom::FrameRequestCallback& aCallback,
- mozilla::ErrorResult& aError);
- void CancelAnimationFrame(int32_t aHandle, mozilla::ErrorResult& aError);
-
-protected:
- VRDisplay(nsPIDOMWindowInner* aWindow, gfx::VRDisplayClient* aClient);
- virtual ~VRDisplay();
- virtual void LastRelease() override;
-
- void ExitPresentInternal();
- void UpdateFrameInfo();
-
- RefPtr<gfx::VRDisplayClient> mClient;
-
- uint32_t mDisplayId;
- nsString mDisplayName;
-
- RefPtr<VRDisplayCapabilities> mCapabilities;
- RefPtr<VRStageParameters> mStageParameters;
-
- double mDepthNear;
- double mDepthFar;
-
- RefPtr<gfx::VRDisplayPresentation> mPresentation;
-
- /**
- * The WebVR 1.1 spec Requires that VRDisplay.getPose and VRDisplay.getFrameData
- * must return the same values until the next VRDisplay.submitFrame.
- * mFrameInfo is updated only on the first call to either function within one
- * frame. Subsequent calls before the next SubmitFrame or ExitPresent call
- * will use these cached values.
- */
- VRFrameInfo mFrameInfo;
-};
-
-} // namespace dom
-} // namespace mozilla
-
-#endif
diff --git a/dom/vr/VREventObserver.cpp b/dom/vr/VREventObserver.cpp
deleted file mode 100644
index 1b6d1b978..000000000
--- a/dom/vr/VREventObserver.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
-* License, v. 2.0. If a copy of the MPL was not distributed with this
-* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "VREventObserver.h"
-
-#include "nsContentUtils.h"
-#include "nsGlobalWindow.h"
-#include "VRManagerChild.h"
-
-namespace mozilla {
-namespace dom {
-
-using namespace gfx;
-
-/**
- * This class is used by nsGlobalWindow to implement window.onvrdisplayconnected,
- * window.onvrdisplaydisconnected, and window.onvrdisplaypresentchange.
- */
-VREventObserver::VREventObserver(nsGlobalWindow* aGlobalWindow)
- : mWindow(aGlobalWindow)
-{
- MOZ_ASSERT(aGlobalWindow && aGlobalWindow->IsInnerWindow());
-
- VRManagerChild* vmc = VRManagerChild::Get();
- if (vmc) {
- vmc->AddListener(this);
- }
-}
-
-VREventObserver::~VREventObserver()
-{
- VRManagerChild* vmc = VRManagerChild::Get();
- if (vmc) {
- vmc->RemoveListener(this);
- }
-}
-
-void
-VREventObserver::NotifyVRDisplayConnect()
-{
- /**
- * We do not call nsGlobalWindow::NotifyActiveVRDisplaysChanged here, as we
- * can assume that a newly enumerated display is not presenting WebVR
- * content.
- */
- if (mWindow->AsInner()->IsCurrentInnerWindow()) {
- MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
- mWindow->GetOuterWindow()->DispatchCustomEvent(
- NS_LITERAL_STRING("vrdisplayconnected"));
- }
-}
-
-void
-VREventObserver::NotifyVRDisplayDisconnect()
-{
- if (mWindow->AsInner()->IsCurrentInnerWindow()) {
- mWindow->NotifyActiveVRDisplaysChanged();
- MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
- mWindow->GetOuterWindow()->DispatchCustomEvent(
- NS_LITERAL_STRING("vrdisplaydisconnected"));
- }
-}
-
-void
-VREventObserver::NotifyVRDisplayPresentChange()
-{
- if (mWindow->AsInner()->IsCurrentInnerWindow()) {
- mWindow->NotifyActiveVRDisplaysChanged();
- MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
- mWindow->GetOuterWindow()->DispatchCustomEvent(
- NS_LITERAL_STRING("vrdisplaypresentchange"));
- }
-}
-
-} // namespace dom
-} // namespace mozilla
diff --git a/dom/vr/VREventObserver.h b/dom/vr/VREventObserver.h
deleted file mode 100644
index a30bb5960..000000000
--- a/dom/vr/VREventObserver.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
-* License, v. 2.0. If a copy of the MPL was not distributed with this file,
-* You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef mozilla_dom_VREventObserver_h
-#define mozilla_dom_VREventObserver_h
-
-class nsGlobalWindow;
-
-namespace mozilla {
-namespace dom {
-
-class VREventObserver final
-{
-public:
- ~VREventObserver();
- explicit VREventObserver(nsGlobalWindow* aGlobalWindow);
-
- void NotifyVRDisplayConnect();
- void NotifyVRDisplayDisconnect();
- void NotifyVRDisplayPresentChange();
-
-private:
- // Weak pointer, instance is owned by mWindow.
- nsGlobalWindow* MOZ_NON_OWNING_REF mWindow;
-};
-
-} // namespace dom
-} // namespace mozilla
-
-#endif // mozilla_dom_VREventObserver_h
diff --git a/dom/vr/moz.build b/dom/vr/moz.build
deleted file mode 100644
index a4aa8d69b..000000000
--- a/dom/vr/moz.build
+++ /dev/null
@@ -1,22 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-EXPORTS.mozilla.dom += [
- 'VRDisplay.h',
- 'VREventObserver.h',
- ]
-
-UNIFIED_SOURCES = [
- 'VRDisplay.cpp',
- 'VREventObserver.cpp',
- ]
-
-include('/ipc/chromium/chromium-config.mozbuild')
-
-FINAL_LIBRARY = 'xul'
-LOCAL_INCLUDES += [
- '/dom/base'
-]
diff --git a/dom/webidl/AddonEvent.webidl b/dom/webidl/AddonEvent.webidl
deleted file mode 100644
index 235f81ec2..000000000
--- a/dom/webidl/AddonEvent.webidl
+++ /dev/null
@@ -1,12 +0,0 @@
-[ Func="mozilla::AddonManagerWebAPI::IsAPIEnabled",
- Constructor(DOMString type, AddonEventInit eventInitDict)]
-interface AddonEvent : Event {
- readonly attribute DOMString id;
- readonly attribute boolean needsRestart;
-};
-
-dictionary AddonEventInit : EventInit {
- required DOMString id;
- required boolean needsRestart;
-};
-
diff --git a/dom/webidl/AddonManager.webidl b/dom/webidl/AddonManager.webidl
deleted file mode 100644
index 02c7953e6..000000000
--- a/dom/webidl/AddonManager.webidl
+++ /dev/null
@@ -1,91 +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/.
- */
-
-/* We need a JSImplementation but cannot get one without a contract ID.
- Since Addon and AddonInstall are only ever created from JS they don't need
- real contract IDs. */
-[ChromeOnly, JSImplementation="dummy"]
-interface Addon {
- // The add-on's ID.
- readonly attribute DOMString id;
- // The add-on's version.
- readonly attribute DOMString version;
- // The add-on's type (extension, theme, etc.).
- readonly attribute DOMString type;
- // The add-on's name in the current locale.
- readonly attribute DOMString name;
- // The add-on's description in the current locale.
- readonly attribute DOMString description;
- // If the user has enabled this add-on, note that it still may not be running
- // depending on whether enabling requires a restart or if the add-on is
- // incompatible in some way.
- readonly attribute boolean isEnabled;
- // If the add-on is currently active in the browser.
- readonly attribute boolean isActive;
- // If the add-on may be uninstalled
- readonly attribute boolean canUninstall;
-
- Promise<boolean> uninstall();
- Promise<void> setEnabled(boolean value);
-};
-
-[ChromeOnly, JSImplementation="dummy"]
-interface AddonInstall : EventTarget {
- // One of the STATE_* symbols from AddonManager.jsm
- readonly attribute DOMString state;
- // One of the ERROR_* symbols from AddonManager.jsm, or null
- readonly attribute DOMString? error;
- // How many bytes have been downloaded
- readonly attribute long long progress;
- // How many total bytes will need to be downloaded or -1 if unknown
- readonly attribute long long maxProgress;
-
- Promise<void> install();
- Promise<void> cancel();
-};
-
-dictionary addonInstallOptions {
- required DOMString url;
- // If a non-empty string is passed for "hash", it is used to verify the
- // checksum of the downloaded XPI before installing. If is omitted or if
- // it is null or empty string, no checksum verification is performed.
- DOMString? hash = null;
-};
-
-[HeaderFile="mozilla/AddonManagerWebAPI.h",
- Func="mozilla::AddonManagerWebAPI::IsAPIEnabled",
- NavigatorProperty="mozAddonManager",
- JSImplementation="@mozilla.org/addon-web-api/manager;1"]
-interface AddonManager : EventTarget {
- /**
- * Gets information about an add-on
- *
- * @param id
- * The ID of the add-on to test for.
- * @return A promise. It will resolve to an Addon if the add-on is installed.
- */
- Promise<Addon> getAddonByID(DOMString id);
-
- /**
- * Creates an AddonInstall object for a given URL.
- *
- * @param options
- * Only one supported option: 'url', the URL of the addon to install.
- * @return A promise that resolves to an instance of AddonInstall.
- */
- Promise<AddonInstall> createInstall(optional addonInstallOptions options);
-
- /* Hooks for managing event listeners */
- [ChromeOnly]
- void eventListenerWasAdded(DOMString type);
- [ChromeOnly]
- void eventListenerWasRemoved(DOMString type);
-};
-
-[ChromeOnly,Exposed=System,HeaderFile="mozilla/AddonManagerWebAPI.h"]
-interface AddonManagerPermissions {
- static boolean isHostPermitted(DOMString host);
-};
-
diff --git a/dom/webidl/AudioContext.webidl b/dom/webidl/AudioContext.webidl
index c2f65abaf..9aa3d5567 100644
--- a/dom/webidl/AudioContext.webidl
+++ b/dom/webidl/AudioContext.webidl
@@ -24,7 +24,6 @@ dictionary PeriodicWaveConstraints {
};
[Constructor,
- Constructor(AudioChannel audioChannelType),
Pref="dom.webaudio.enabled"]
interface AudioContext : EventTarget {
diff --git a/dom/webidl/CommandEvent.webidl b/dom/webidl/CommandEvent.webidl
index 8c16e856c..9856c77c3 100644
--- a/dom/webidl/CommandEvent.webidl
+++ b/dom/webidl/CommandEvent.webidl
@@ -8,7 +8,7 @@ interface CommandEvent : Event {
readonly attribute DOMString? command;
void initCommandEvent(DOMString type,
- boolean canBubble,
- boolean cancelable,
- DOMString? command);
+ optional boolean canBubble = false,
+ optional boolean cancelable = false,
+ optional DOMString? command = null);
};
diff --git a/dom/webidl/CompositionEvent.webidl b/dom/webidl/CompositionEvent.webidl
index c293683ce..e4a54d678 100644
--- a/dom/webidl/CompositionEvent.webidl
+++ b/dom/webidl/CompositionEvent.webidl
@@ -25,9 +25,9 @@ interface CompositionEvent : UIEvent
partial interface CompositionEvent
{
void initCompositionEvent(DOMString typeArg,
- boolean canBubbleArg,
- boolean cancelableArg,
- Window? viewArg,
- DOMString? dataArg,
- DOMString localeArg);
+ optional boolean canBubbleArg = false,
+ optional boolean cancelableArg = false,
+ optional Window? viewArg = null,
+ optional DOMString? dataArg = null,
+ optional DOMString localeArg = "");
};
diff --git a/dom/webidl/CustomEvent.webidl b/dom/webidl/CustomEvent.webidl
index 299a41ec0..1ea5572b7 100644
--- a/dom/webidl/CustomEvent.webidl
+++ b/dom/webidl/CustomEvent.webidl
@@ -19,9 +19,9 @@ interface CustomEvent : Event
// initCustomEvent is a Gecko specific deprecated method.
[Throws]
void initCustomEvent(DOMString type,
- boolean canBubble,
- boolean cancelable,
- any detail);
+ optional boolean canBubble = false,
+ optional boolean cancelable = false,
+ optional any detail = null);
};
dictionary CustomEventInit : EventInit
diff --git a/dom/webidl/DeviceMotionEvent.webidl b/dom/webidl/DeviceMotionEvent.webidl
index fa4ecf3ca..c26ab080c 100644
--- a/dom/webidl/DeviceMotionEvent.webidl
+++ b/dom/webidl/DeviceMotionEvent.webidl
@@ -48,10 +48,10 @@ dictionary DeviceMotionEventInit : EventInit {
// Mozilla extensions.
partial interface DeviceMotionEvent {
void initDeviceMotionEvent(DOMString type,
- boolean canBubble,
- boolean cancelable,
- DeviceAccelerationInit acceleration,
- DeviceAccelerationInit accelerationIncludingGravity,
- DeviceRotationRateInit rotationRate,
- double? interval);
+ optional boolean canBubble = false,
+ optional boolean cancelable = false,
+ optional DeviceAccelerationInit acceleration,
+ optional DeviceAccelerationInit accelerationIncludingGravity,
+ optional DeviceRotationRateInit rotationRate,
+ optional double? interval = null);
};
diff --git a/dom/webidl/DeviceOrientationEvent.webidl b/dom/webidl/DeviceOrientationEvent.webidl
index 46194453e..9802b3681 100644
--- a/dom/webidl/DeviceOrientationEvent.webidl
+++ b/dom/webidl/DeviceOrientationEvent.webidl
@@ -14,12 +14,12 @@ interface DeviceOrientationEvent : Event
// initDeviceOrientationEvent is a Gecko specific deprecated method.
void initDeviceOrientationEvent(DOMString type,
- boolean canBubble,
- boolean cancelable,
- double? alpha,
- double? beta,
- double? gamma,
- boolean absolute);
+ optional boolean canBubble = false,
+ optional boolean cancelable = false,
+ optional double? alpha = null,
+ optional double? beta = null,
+ optional double? gamma = null,
+ optional boolean absolute = false);
};
dictionary DeviceOrientationEventInit : EventInit
diff --git a/dom/webidl/DragEvent.webidl b/dom/webidl/DragEvent.webidl
index 2cc173d5c..806177790 100644
--- a/dom/webidl/DragEvent.webidl
+++ b/dom/webidl/DragEvent.webidl
@@ -10,21 +10,21 @@ interface DragEvent : MouseEvent
readonly attribute DataTransfer? dataTransfer;
void initDragEvent(DOMString type,
- boolean canBubble,
- boolean cancelable,
- Window? aView,
- long aDetail,
- long aScreenX,
- long aScreenY,
- long aClientX,
- long aClientY,
- boolean aCtrlKey,
- boolean aAltKey,
- boolean aShiftKey,
- boolean aMetaKey,
- unsigned short aButton,
- EventTarget? aRelatedTarget,
- DataTransfer? aDataTransfer);
+ optional boolean canBubble = false,
+ optional boolean cancelable = false,
+ optional Window? aView = null,
+ optional long aDetail = 0,
+ optional long aScreenX = 0,
+ optional long aScreenY = 0,
+ optional long aClientX = 0,
+ optional long aClientY = 0,
+ optional boolean aCtrlKey = false,
+ optional boolean aAltKey = false,
+ optional boolean aShiftKey = false,
+ optional boolean aMetaKey = false,
+ optional unsigned short aButton = 0,
+ optional EventTarget? aRelatedTarget = null,
+ optional DataTransfer? aDataTransfer = null);
};
dictionary DragEventInit : MouseEventInit
diff --git a/dom/webidl/Element.webidl b/dom/webidl/Element.webidl
index 97eb4ffe0..cf17523a5 100644
--- a/dom/webidl/Element.webidl
+++ b/dom/webidl/Element.webidl
@@ -164,9 +164,10 @@ interface Element : Node {
};
// http://dev.w3.org/csswg/cssom-view/
-enum ScrollLogicalPosition { "start", "end" };
+enum ScrollLogicalPosition { "start", "center", "end", "nearest" };
dictionary ScrollIntoViewOptions : ScrollOptions {
ScrollLogicalPosition block = "start";
+ ScrollLogicalPosition inline = "nearest";
};
// http://dev.w3.org/csswg/cssom-view/#extensions-to-the-element-interface
@@ -175,8 +176,7 @@ partial interface Element {
DOMRect getBoundingClientRect();
// scrolling
- void scrollIntoView(boolean top);
- void scrollIntoView(optional ScrollIntoViewOptions options);
+ void scrollIntoView(optional (boolean or ScrollIntoViewOptions) arg);
// None of the CSSOM attributes are [Pure], because they flush
attribute long scrollTop; // scroll on setting
attribute long scrollLeft; // scroll on setting
diff --git a/dom/webidl/Event.webidl b/dom/webidl/Event.webidl
index 70a0ef513..a5d7da7d4 100644
--- a/dom/webidl/Event.webidl
+++ b/dom/webidl/Event.webidl
@@ -51,7 +51,9 @@ interface Event {
[Pure]
readonly attribute DOMHighResTimeStamp timeStamp;
- void initEvent(DOMString type, boolean bubbles, boolean cancelable);
+ void initEvent(DOMString type,
+ optional boolean bubbles = false,
+ optional boolean cancelable = false);
attribute boolean cancelBubble;
};
diff --git a/dom/webidl/HashChangeEvent.webidl b/dom/webidl/HashChangeEvent.webidl
index 735e8eb28..6e8be455c 100644
--- a/dom/webidl/HashChangeEvent.webidl
+++ b/dom/webidl/HashChangeEvent.webidl
@@ -11,10 +11,10 @@ interface HashChangeEvent : Event
readonly attribute DOMString newURL;
void initHashChangeEvent(DOMString typeArg,
- boolean canBubbleArg,
- boolean cancelableArg,
- DOMString oldURLArg,
- DOMString newURLArg);
+ optional boolean canBubbleArg = false,
+ optional boolean cancelableArg = false,
+ optional DOMString oldURLArg = "",
+ optional DOMString newURLArg = "");
};
dictionary HashChangeEventInit : EventInit
diff --git a/dom/webidl/Headers.webidl b/dom/webidl/Headers.webidl
index 205ab9f9e..eef552a7f 100644
--- a/dom/webidl/Headers.webidl
+++ b/dom/webidl/Headers.webidl
@@ -8,7 +8,7 @@
* http://fetch.spec.whatwg.org/#headers-class
*/
-typedef (Headers or sequence<sequence<ByteString>> or MozMap<ByteString>) HeadersInit;
+typedef (Headers or sequence<sequence<ByteString>> or record<ByteString, ByteString>) HeadersInit;
enum HeadersGuardEnum {
"none",
diff --git a/dom/webidl/InstallTrigger.webidl b/dom/webidl/InstallTrigger.webidl
index 789fb2bc4..68f48ddc6 100644
--- a/dom/webidl/InstallTrigger.webidl
+++ b/dom/webidl/InstallTrigger.webidl
@@ -57,7 +57,7 @@ interface InstallTriggerImpl {
* A callback to call as each installation succeeds or fails
* @return true if the installations were successfully started
*/
- boolean install(MozMap<(DOMString or InstallTriggerData)> installs,
+ boolean install(record<DOMString, (DOMString or InstallTriggerData)> installs,
optional InstallTriggerCallback callback);
/**
diff --git a/dom/webidl/IntersectionObserver.webidl b/dom/webidl/IntersectionObserver.webidl
index dbe8f428d..83200d950 100644
--- a/dom/webidl/IntersectionObserver.webidl
+++ b/dom/webidl/IntersectionObserver.webidl
@@ -7,7 +7,7 @@
* https://wicg.github.io/IntersectionObserver/
*/
-[ProbablyShortLivingObject, Pref="dom.IntersectionObserver.enabled"]
+[ProbablyShortLivingObject, Pref="dom.intersectionObserver.enabled"]
interface IntersectionObserverEntry {
[Constant]
readonly attribute DOMHighResTimeStamp time;
@@ -18,6 +18,8 @@ interface IntersectionObserverEntry {
[Constant]
readonly attribute DOMRectReadOnly intersectionRect;
[Constant]
+ readonly attribute boolean isIntersecting;
+ [Constant]
readonly attribute double intersectionRatio;
[Constant]
readonly attribute Element target;
@@ -25,7 +27,7 @@ interface IntersectionObserverEntry {
[Constructor(IntersectionCallback intersectionCallback,
optional IntersectionObserverInit options),
- Pref="dom.IntersectionObserver.enabled"]
+ Pref="dom.intersectionObserver.enabled"]
interface IntersectionObserver {
[Constant]
readonly attribute Element? root;
diff --git a/dom/webidl/KeyEvent.webidl b/dom/webidl/KeyEvent.webidl
index 516632854..abb4b6a34 100644
--- a/dom/webidl/KeyEvent.webidl
+++ b/dom/webidl/KeyEvent.webidl
@@ -225,13 +225,13 @@ interface KeyEvent
const unsigned long DOM_VK_WIN_OEM_CLEAR = 0xFE;
void initKeyEvent(DOMString type,
- boolean canBubble,
- boolean cancelable,
- Window? view,
- boolean ctrlKey,
- boolean altKey,
- boolean shiftKey,
- boolean metaKey,
- unsigned long keyCode,
- unsigned long charCode);
+ optional boolean canBubble = false,
+ optional boolean cancelable = false,
+ optional Window? view = null,
+ optional boolean ctrlKey = false,
+ optional boolean altKey = false,
+ optional boolean shiftKey = false,
+ optional boolean metaKey = false,
+ optional unsigned long keyCode = 0,
+ optional unsigned long charCode = 0);
};
diff --git a/dom/webidl/MessageEvent.webidl b/dom/webidl/MessageEvent.webidl
index 548f14520..be5022d67 100644
--- a/dom/webidl/MessageEvent.webidl
+++ b/dom/webidl/MessageEvent.webidl
@@ -43,10 +43,14 @@ interface MessageEvent : Event {
[Pure, Cached, Frozen]
readonly attribute sequence<MessagePort> ports;
- void initMessageEvent(DOMString type, boolean bubbles, boolean cancelable,
- any data, DOMString origin, DOMString lastEventId,
- (WindowProxy or MessagePort)? source,
- sequence<MessagePort> ports);
+ void initMessageEvent(DOMString type,
+ optional boolean bubbles = false,
+ optional boolean cancelable = false,
+ optional any data = null,
+ optional DOMString origin = "",
+ optional DOMString lastEventId = "",
+ optional (WindowProxy or MessagePort)? source = null,
+ optional sequence<MessagePort> ports = []);
};
dictionary MessageEventInit : EventInit {
diff --git a/dom/webidl/MouseEvent.webidl b/dom/webidl/MouseEvent.webidl
index d21354801..192519d57 100644
--- a/dom/webidl/MouseEvent.webidl
+++ b/dom/webidl/MouseEvent.webidl
@@ -32,21 +32,21 @@ interface MouseEvent : UIEvent {
readonly attribute long movementY;
// Deprecated in DOM Level 3:
- void initMouseEvent(DOMString typeArg,
- boolean canBubbleArg,
- boolean cancelableArg,
- Window? viewArg,
- long detailArg,
- long screenXArg,
- long screenYArg,
- long clientXArg,
- long clientYArg,
- boolean ctrlKeyArg,
- boolean altKeyArg,
- boolean shiftKeyArg,
- boolean metaKeyArg,
- short buttonArg,
- EventTarget? relatedTargetArg);
+void initMouseEvent(DOMString typeArg,
+ optional boolean canBubbleArg = false,
+ optional boolean cancelableArg = false,
+ optional Window? viewArg = null,
+ optional long detailArg = 0,
+ optional long screenXArg = 0,
+ optional long screenYArg = 0,
+ optional long clientXArg = 0,
+ optional long clientYArg = 0,
+ optional boolean ctrlKeyArg = false,
+ optional boolean altKeyArg = false,
+ optional boolean shiftKeyArg = false,
+ optional boolean metaKeyArg = false,
+ optional short buttonArg = 0,
+ optional EventTarget? relatedTargetArg = null);
// Introduced in DOM Level 3:
boolean getModifierState(DOMString keyArg);
};
@@ -90,23 +90,23 @@ partial interface MouseEvent
readonly attribute unsigned short mozInputSource;
- void initNSMouseEvent(DOMString typeArg,
- boolean canBubbleArg,
- boolean cancelableArg,
- Window? viewArg,
- long detailArg,
- long screenXArg,
- long screenYArg,
- long clientXArg,
- long clientYArg,
- boolean ctrlKeyArg,
- boolean altKeyArg,
- boolean shiftKeyArg,
- boolean metaKeyArg,
- short buttonArg,
- EventTarget? relatedTargetArg,
- float pressure,
- unsigned short inputSourceArg);
+ void initNSMouseEvent(DOMString typeArg,
+ optional boolean canBubbleArg = false,
+ optional boolean cancelableArg = false,
+ optional Window? viewArg = null,
+ optional long detailArg = 0,
+ optional long screenXArg = 0,
+ optional long screenYArg = 0,
+ optional long clientXArg = 0,
+ optional long clientYArg = 0,
+ optional boolean ctrlKeyArg = false,
+ optional boolean altKeyArg = false,
+ optional boolean shiftKeyArg = false,
+ optional boolean metaKeyArg = false,
+ optional short buttonArg = 0,
+ optional EventTarget? relatedTargetArg = null,
+ optional float pressure = 0,
+ optional unsigned short inputSourceArg = 0);
[ChromeOnly]
readonly attribute boolean hitCluster; // True when touch occurs in a cluster of links
diff --git a/dom/webidl/MouseScrollEvent.webidl b/dom/webidl/MouseScrollEvent.webidl
index aa9e30fd2..c1e52bd8c 100644
--- a/dom/webidl/MouseScrollEvent.webidl
+++ b/dom/webidl/MouseScrollEvent.webidl
@@ -12,19 +12,19 @@ interface MouseScrollEvent : MouseEvent
readonly attribute long axis;
void initMouseScrollEvent(DOMString type,
- boolean canBubble,
- boolean cancelable,
- Window? view,
- long detail,
- long screenX,
- long screenY,
- long clientX,
- long clientY,
- boolean ctrlKey,
- boolean altKey,
- boolean shiftKey,
- boolean metaKey,
- unsigned short button,
- EventTarget? relatedTarget,
- long axis);
+ optional boolean canBubble = false,
+ optional boolean cancelable = false,
+ optional Window? view = null,
+ optional long detail = 0,
+ optional long screenX = 0,
+ optional long screenY = 0,
+ optional long clientX = 0,
+ optional long clientY = 0,
+ optional boolean ctrlKey = false,
+ optional boolean altKey = false,
+ optional boolean shiftKey = false,
+ optional boolean metaKey = false,
+ optional short button = 0,
+ optional EventTarget? relatedTarget = null,
+ optional long axis = 0);
};
diff --git a/dom/webidl/MutationEvent.webidl b/dom/webidl/MutationEvent.webidl
index 43c7b1cd0..53625b4f9 100644
--- a/dom/webidl/MutationEvent.webidl
+++ b/dom/webidl/MutationEvent.webidl
@@ -23,11 +23,11 @@ interface MutationEvent : Event
[Throws]
void initMutationEvent(DOMString type,
- boolean canBubble,
- boolean cancelable,
- Node? relatedNode,
- DOMString prevValue,
- DOMString newValue,
- DOMString attrName,
- unsigned short attrChange);
+ optional boolean canBubble = false,
+ optional boolean cancelable = false,
+ optional Node? relatedNode = null,
+ optional DOMString prevValue = "",
+ optional DOMString newValue = "",
+ optional DOMString attrName = "",
+ optional unsigned short attrChange = 0);
};
diff --git a/dom/webidl/Navigator.webidl b/dom/webidl/Navigator.webidl
index 5452f3247..c353e8be7 100644
--- a/dom/webidl/Navigator.webidl
+++ b/dom/webidl/Navigator.webidl
@@ -268,14 +268,6 @@ partial interface Navigator {
};
#endif // MOZ_GAMEPAD
-partial interface Navigator {
- [Throws, Pref="dom.vr.enabled"]
- Promise<sequence<VRDisplay>> getVRDisplays();
- // TODO: Use FrozenArray once available. (Bug 1236777)
- [Frozen, Cached, Pure, Pref="dom.vr.enabled"]
- readonly attribute sequence<VRDisplay> activeVRDisplays;
-};
-
#ifdef MOZ_TIME_MANAGER
// nsIDOMMozNavigatorTime
partial interface Navigator {
diff --git a/dom/webidl/ScrollAreaEvent.webidl b/dom/webidl/ScrollAreaEvent.webidl
index 0f48b4bc8..f24b7c0ad 100644
--- a/dom/webidl/ScrollAreaEvent.webidl
+++ b/dom/webidl/ScrollAreaEvent.webidl
@@ -12,12 +12,12 @@ interface ScrollAreaEvent : UIEvent
readonly attribute float height;
void initScrollAreaEvent(DOMString type,
- boolean canBubble,
- boolean cancelable,
- Window? view,
- long detail,
- float x,
- float y,
- float width,
- float height);
+ optional boolean canBubble = false,
+ optional boolean cancelable = false,
+ optional Window? view = null,
+ optional long detail = 0,
+ optional float x = 0,
+ optional float y = 0,
+ optional float width = 0,
+ optional float height = 0);
};
diff --git a/dom/webidl/SimpleGestureEvent.webidl b/dom/webidl/SimpleGestureEvent.webidl
index 0829076dd..76d0d20f6 100644
--- a/dom/webidl/SimpleGestureEvent.webidl
+++ b/dom/webidl/SimpleGestureEvent.webidl
@@ -25,22 +25,22 @@ interface SimpleGestureEvent : MouseEvent
readonly attribute unsigned long clickCount;
void initSimpleGestureEvent(DOMString typeArg,
- boolean canBubbleArg,
- boolean cancelableArg,
- Window? viewArg,
- long detailArg,
- long screenXArg,
- long screenYArg,
- long clientXArg,
- long clientYArg,
- boolean ctrlKeyArg,
- boolean altKeyArg,
- boolean shiftKeyArg,
- boolean metaKeyArg,
- unsigned short buttonArg,
- EventTarget? relatedTargetArg,
- unsigned long allowedDirectionsArg,
- unsigned long directionArg,
- double deltaArg,
- unsigned long clickCount);
+ optional boolean canBubbleArg = false,
+ optional boolean cancelableArg = false,
+ optional Window? viewArg = null,
+ optional long detailArg = 0,
+ optional long screenXArg = 0,
+ optional long screenYArg = 0,
+ optional long clientXArg = 0,
+ optional long clientYArg = 0,
+ optional boolean ctrlKeyArg = false,
+ optional boolean altKeyArg = false,
+ optional boolean shiftKeyArg = false,
+ optional boolean metaKeyArg = false,
+ optional short buttonArg = 0,
+ optional EventTarget? relatedTargetArg = null,
+ optional unsigned long allowedDirectionsArg = 0,
+ optional unsigned long directionArg = 0,
+ optional double deltaArg = 0,
+ optional unsigned long clickCount = 0);
};
diff --git a/dom/webidl/StorageEvent.webidl b/dom/webidl/StorageEvent.webidl
index c3e9605eb..e03f8232c 100644
--- a/dom/webidl/StorageEvent.webidl
+++ b/dom/webidl/StorageEvent.webidl
@@ -21,13 +21,13 @@ interface StorageEvent : Event
// Bug 1016053 - This is not spec compliant.
void initStorageEvent(DOMString type,
- boolean canBubble,
- boolean cancelable,
- DOMString? key,
- DOMString? oldValue,
- DOMString? newValue,
- DOMString? url,
- Storage? storageArea);
+ optional boolean canBubble = false,
+ optional boolean cancelable = false,
+ optional DOMString? key = null,
+ optional DOMString? oldValue = null,
+ optional DOMString? newValue = null,
+ optional DOMString? url = null,
+ optional Storage? storageArea = null);
};
dictionary StorageEventInit : EventInit
diff --git a/dom/webidl/TestInterfaceJS.webidl b/dom/webidl/TestInterfaceJS.webidl
index 1ca629c39..2cf8d701a 100644
--- a/dom/webidl/TestInterfaceJS.webidl
+++ b/dom/webidl/TestInterfaceJS.webidl
@@ -24,7 +24,7 @@ interface TestInterfaceJS : EventTarget {
any pingPongObjectOrString((object or DOMString) objOrString);
TestInterfaceJSDictionary pingPongDictionary(optional TestInterfaceJSDictionary dict);
long pingPongDictionaryOrLong(optional (TestInterfaceJSUnionableDictionary or long) dictOrLong);
- DOMString pingPongMap(MozMap<any> map);
+ DOMString pingPongMap(record<DOMString, any> map);
long objectSequenceLength(sequence<object> seq);
long anySequenceLength(sequence<any> seq);
diff --git a/dom/webidl/TimeEvent.webidl b/dom/webidl/TimeEvent.webidl
index 40e7a0beb..8bbe4db53 100644
--- a/dom/webidl/TimeEvent.webidl
+++ b/dom/webidl/TimeEvent.webidl
@@ -15,6 +15,6 @@ interface TimeEvent : Event
readonly attribute long detail;
readonly attribute WindowProxy? view;
void initTimeEvent(DOMString aType,
- Window? aView,
- long aDetail);
+ optional Window? aView = null,
+ optional long aDetail = 0);
};
diff --git a/dom/webidl/TouchEvent.webidl b/dom/webidl/TouchEvent.webidl
index d206fe0fb..fd677787a 100644
--- a/dom/webidl/TouchEvent.webidl
+++ b/dom/webidl/TouchEvent.webidl
@@ -23,15 +23,15 @@ interface TouchEvent : UIEvent {
readonly attribute boolean shiftKey;
void initTouchEvent(DOMString type,
- boolean canBubble,
- boolean cancelable,
- Window? view,
- long detail,
- boolean ctrlKey,
- boolean altKey,
- boolean shiftKey,
- boolean metaKey,
- TouchList? touches,
- TouchList? targetTouches,
- TouchList? changedTouches);
+ optional boolean canBubble = false,
+ optional boolean cancelable = false,
+ optional Window? view = null,
+ optional long detail = 0,
+ optional boolean ctrlKey = false,
+ optional boolean altKey = false,
+ optional boolean shiftKey = false,
+ optional boolean metaKey = false,
+ optional TouchList? touches = null,
+ optional TouchList? targetTouches = null,
+ optional TouchList? changedTouches = null);
};
diff --git a/dom/webidl/UIEvent.webidl b/dom/webidl/UIEvent.webidl
index 9cc1d0cdf..5be6a443a 100644
--- a/dom/webidl/UIEvent.webidl
+++ b/dom/webidl/UIEvent.webidl
@@ -16,10 +16,10 @@ interface UIEvent : Event
readonly attribute WindowProxy? view;
readonly attribute long detail;
void initUIEvent(DOMString aType,
- boolean aCanBubble,
- boolean aCancelable,
- Window? aView,
- long aDetail);
+ optional boolean aCanBubble = false,
+ optional boolean aCancelable = false,
+ optional Window? aView = null,
+ optional long aDetail = 0);
};
// Additional DOM0 properties.
diff --git a/dom/webidl/URLSearchParams.webidl b/dom/webidl/URLSearchParams.webidl
index 93e846071..b93f4e8b1 100644
--- a/dom/webidl/URLSearchParams.webidl
+++ b/dom/webidl/URLSearchParams.webidl
@@ -13,8 +13,7 @@
* http://www.openwebfoundation.org/legal/the-owf-1-0-agreements/owfa-1-0.
*/
-[Constructor(optional USVString init = ""),
- Constructor(URLSearchParams init),
+[Constructor(optional (sequence<sequence<USVString>> or record<USVString, USVString> or USVString) init = ""),
Exposed=(Window,Worker,WorkerDebugger,System)]
interface URLSearchParams {
void append(USVString name, USVString value);
diff --git a/dom/webidl/VRDisplay.webidl b/dom/webidl/VRDisplay.webidl
deleted file mode 100644
index 63ebd1205..000000000
--- a/dom/webidl/VRDisplay.webidl
+++ /dev/null
@@ -1,286 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-enum VREye {
- "left",
- "right"
-};
-
-[Pref="dom.vr.enabled",
- HeaderFile="mozilla/dom/VRDisplay.h"]
-interface VRFieldOfView {
- readonly attribute double upDegrees;
- readonly attribute double rightDegrees;
- readonly attribute double downDegrees;
- readonly attribute double leftDegrees;
-};
-
-typedef (HTMLCanvasElement or OffscreenCanvas) VRSource;
-
-dictionary VRLayer {
- /**
- * XXX - When WebVR in WebWorkers is implemented, HTMLCanvasElement below
- * should be replaced with VRSource.
- */
- HTMLCanvasElement? source = null;
-
- /**
- * The left and right viewports contain 4 values defining the viewport
- * rectangles within the canvas to present to the eye in UV space.
- * [0] left offset of the viewport (0.0 - 1.0)
- * [1] top offset of the viewport (0.0 - 1.0)
- * [2] width of the viewport (0.0 - 1.0)
- * [3] height of the viewport (0.0 - 1.0)
- *
- * When no values are passed, they will be processed as though the left
- * and right sides of the viewport were passed:
- *
- * leftBounds: [0.0, 0.0, 0.5, 1.0]
- * rightBounds: [0.5, 0.0, 0.5, 1.0]
- */
- sequence<float> leftBounds = [];
- sequence<float> rightBounds = [];
-};
-
-/**
- * Values describing the capabilities of a VRDisplay.
- * These are expected to be static per-device/per-user.
- */
-[Pref="dom.vr.enabled",
- HeaderFile="mozilla/dom/VRDisplay.h"]
-interface VRDisplayCapabilities {
- /**
- * hasPosition is true if the VRDisplay is capable of tracking its position.
- */
- readonly attribute boolean hasPosition;
-
- /**
- * hasOrientation is true if the VRDisplay is capable of tracking its orientation.
- */
- readonly attribute boolean hasOrientation;
-
- /**
- * Whether the VRDisplay is separate from the device’s
- * primary display. If presenting VR content will obscure
- * other content on the device, this should be false. When
- * false, the application should not attempt to mirror VR content
- * or update non-VR UI because that content will not be visible.
- */
- readonly attribute boolean hasExternalDisplay;
-
- /**
- * Whether the VRDisplay is capable of presenting content to an HMD or similar device.
- * Can be used to indicate “magic window” devices that are capable of 6DoF tracking but for
- * which requestPresent is not meaningful. If false then calls to requestPresent should
- * always fail, and getEyeParameters should return null.
- */
- readonly attribute boolean canPresent;
-
- /**
- * Indicates the maximum length of the array that requestPresent() will accept. MUST be 1 if
- canPresent is true, 0 otherwise.
- */
- readonly attribute unsigned long maxLayers;
-};
-
-/**
- * Values describing the the stage / play area for devices
- * that support room-scale experiences.
- */
-[Pref="dom.vr.enabled",
- HeaderFile="mozilla/dom/VRDisplay.h"]
-interface VRStageParameters {
- /**
- * A 16-element array containing the components of a column-major 4x4
- * affine transform matrix. This matrix transforms the sitting-space position
- * returned by get{Immediate}Pose() to a standing-space position.
- */
- [Throws] readonly attribute Float32Array sittingToStandingTransform;
-
- /**
- * Dimensions of the play-area bounds. The bounds are defined
- * as an axis-aligned rectangle on the floor.
- * The center of the rectangle is at (0,0,0) in standing-space
- * coordinates.
- * These bounds are defined for safety purposes.
- * Content should not require the user to move beyond these
- * bounds; however, it is possible for the user to ignore
- * the bounds resulting in position values outside of
- * this rectangle.
- */
- readonly attribute float sizeX;
- readonly attribute float sizeZ;
-};
-
-[Pref="dom.vr.enabled",
- HeaderFile="mozilla/dom/VRDisplay.h"]
-interface VRPose
-{
- /**
- * position, linearVelocity, and linearAcceleration are 3-component vectors.
- * position is relative to a sitting space. Transforming this point with
- * VRStageParameters.sittingToStandingTransform converts this to standing space.
- */
- [Constant, Throws] readonly attribute Float32Array? position;
- [Constant, Throws] readonly attribute Float32Array? linearVelocity;
- [Constant, Throws] readonly attribute Float32Array? linearAcceleration;
-
- /* orientation is a 4-entry array representing the components of a quaternion. */
- [Constant, Throws] readonly attribute Float32Array? orientation;
- /* angularVelocity and angularAcceleration are the components of 3-dimensional vectors. */
- [Constant, Throws] readonly attribute Float32Array? angularVelocity;
- [Constant, Throws] readonly attribute Float32Array? angularAcceleration;
-};
-
-[Constructor,
- Pref="dom.vr.enabled",
- HeaderFile="mozilla/dom/VRDisplay.h"]
-interface VRFrameData {
- readonly attribute DOMHighResTimeStamp timestamp;
-
- [Throws, Pure] readonly attribute Float32Array leftProjectionMatrix;
- [Throws, Pure] readonly attribute Float32Array leftViewMatrix;
-
- [Throws, Pure] readonly attribute Float32Array rightProjectionMatrix;
- [Throws, Pure] readonly attribute Float32Array rightViewMatrix;
-
- [Pure] readonly attribute VRPose pose;
-};
-
-[Pref="dom.vr.enabled",
- HeaderFile="mozilla/dom/VRDisplay.h"]
-interface VREyeParameters {
- /**
- * offset is a 3-component vector representing an offset to
- * translate the eye. This value may vary from frame
- * to frame if the user adjusts their headset ipd.
- */
- [Constant, Throws] readonly attribute Float32Array offset;
-
- /* These values may vary as the user adjusts their headset ipd. */
- [Constant] readonly attribute VRFieldOfView fieldOfView;
-
- /**
- * renderWidth and renderHeight specify the recommended render target
- * size of each eye viewport, in pixels. If multiple eyes are rendered
- * in a single render target, then the render target should be made large
- * enough to fit both viewports.
- */
- [Constant] readonly attribute unsigned long renderWidth;
- [Constant] readonly attribute unsigned long renderHeight;
-};
-
-[Pref="dom.vr.enabled",
- HeaderFile="mozilla/dom/VRDisplay.h"]
-interface VRDisplay : EventTarget {
- readonly attribute boolean isConnected;
- readonly attribute boolean isPresenting;
-
- /**
- * Dictionary of capabilities describing the VRDisplay.
- */
- [Constant] readonly attribute VRDisplayCapabilities capabilities;
-
- /**
- * If this VRDisplay supports room-scale experiences, the optional
- * stage attribute contains details on the room-scale parameters.
- */
- readonly attribute VRStageParameters? stageParameters;
-
- /* Return the current VREyeParameters for the given eye. */
- VREyeParameters getEyeParameters(VREye whichEye);
-
- /**
- * An identifier for this distinct VRDisplay. Used as an
- * association point in the Gamepad API.
- */
- [Constant] readonly attribute unsigned long displayId;
-
- /**
- * A display name, a user-readable name identifying it.
- */
- [Constant] readonly attribute DOMString displayName;
-
- /**
- * Populates the passed VRFrameData with the information required to render
- * the current frame.
- */
- boolean getFrameData(VRFrameData frameData);
-
- /**
- * Return a VRPose containing the future predicted pose of the VRDisplay
- * when the current frame will be presented. Subsequent calls to getPose()
- * MUST return a VRPose with the same values until the next call to
- * submitFrame().
- *
- * The VRPose will contain the position, orientation, velocity,
- * and acceleration of each of these properties.
- */
- [NewObject] VRPose getPose();
-
- /**
- * Reset the pose for this display, treating its current position and
- * orientation as the "origin/zero" values. VRPose.position,
- * VRPose.orientation, and VRStageParameters.sittingToStandingTransform may be
- * updated when calling resetPose(). This should be called in only
- * sitting-space experiences.
- */
- void resetPose();
-
- /**
- * z-depth defining the near plane of the eye view frustum
- * enables mapping of values in the render target depth
- * attachment to scene coordinates. Initially set to 0.01.
- */
- attribute double depthNear;
-
- /**
- * z-depth defining the far plane of the eye view frustum
- * enables mapping of values in the render target depth
- * attachment to scene coordinates. Initially set to 10000.0.
- */
- attribute double depthFar;
-
- /**
- * The callback passed to `requestAnimationFrame` will be called
- * any time a new frame should be rendered. When the VRDisplay is
- * presenting the callback will be called at the native refresh
- * rate of the HMD. When not presenting this function acts
- * identically to how window.requestAnimationFrame acts. Content should
- * make no assumptions of frame rate or vsync behavior as the HMD runs
- * asynchronously from other displays and at differing refresh rates.
- */
- [Throws] long requestAnimationFrame(FrameRequestCallback callback);
-
- /**
- * Passing the value returned by `requestAnimationFrame` to
- * `cancelAnimationFrame` will unregister the callback.
- */
- [Throws] void cancelAnimationFrame(long handle);
-
- /**
- * Begin presenting to the VRDisplay. Must be called in response to a user gesture.
- * Repeat calls while already presenting will update the VRLayers being displayed.
- */
- [Throws] Promise<void> requestPresent(sequence<VRLayer> layers);
-
- /**
- * Stops presenting to the VRDisplay.
- */
- [Throws] Promise<void> exitPresent();
-
- /**
- * Get the layers currently being presented.
- */
- sequence<VRLayer> getLayers();
-
- /**
- * The VRLayer provided to the VRDisplay will be captured and presented
- * in the HMD. Calling this function has the same effect on the source
- * canvas as any other operation that uses its source image, and canvases
- * created without preserveDrawingBuffer set to true will be cleared.
- */
- void submitFrame();
-};
diff --git a/dom/webidl/XULCommandEvent.webidl b/dom/webidl/XULCommandEvent.webidl
index 9c024edc1..72dc3802e 100644
--- a/dom/webidl/XULCommandEvent.webidl
+++ b/dom/webidl/XULCommandEvent.webidl
@@ -15,13 +15,13 @@ interface XULCommandEvent : UIEvent
readonly attribute Event? sourceEvent;
void initCommandEvent(DOMString type,
- boolean canBubble,
- boolean cancelable,
- Window? view,
- long detail,
- boolean ctrlKey,
- boolean altKey,
- boolean shiftKey,
- boolean metaKey,
- Event? sourceEvent);
+ optional boolean canBubble = false,
+ optional boolean cancelable = false,
+ optional Window? view = null,
+ optional long detail = 0,
+ optional boolean ctrlKey = false,
+ optional boolean altKey = false,
+ optional boolean shiftKey = false,
+ optional boolean metaKey = false,
+ optional Event? sourceEvent = null);
};
diff --git a/dom/webidl/moz.build b/dom/webidl/moz.build
index 4c2567a1c..aae7e479c 100644
--- a/dom/webidl/moz.build
+++ b/dom/webidl/moz.build
@@ -555,7 +555,6 @@ WEBIDL_FILES = [
'VideoStreamTrack.webidl',
'VideoTrack.webidl',
'VideoTrackList.webidl',
- 'VRDisplay.webidl',
'VTTCue.webidl',
'VTTRegion.webidl',
'WaveShaperNode.webidl',
@@ -592,9 +591,6 @@ WEBIDL_FILES = [
'XULElement.webidl',
]
-if CONFIG['MOZ_WEBEXTENSIONS']:
- WEBIDL_FILES += ['AddonManager.webidl']
-
if CONFIG['MOZ_AUDIO_CHANNEL_MANAGER']:
WEBIDL_FILES += [
'AudioChannelManager.webidl',
@@ -723,9 +719,6 @@ GENERATED_EVENTS_WEBIDL_FILES = [
'WebGLContextEvent.webidl',
]
-if CONFIG['MOZ_WEBEXTENSIONS']:
- GENERATED_EVENTS_WEBIDL_FILES += ['AddonEvent.webidl']
-
if CONFIG['MOZ_WEBRTC']:
GENERATED_EVENTS_WEBIDL_FILES += [
'RTCDataChannelEvent.webidl',
diff --git a/dom/workers/RuntimeService.cpp b/dom/workers/RuntimeService.cpp
index e1910536f..21f6d8ddf 100644
--- a/dom/workers/RuntimeService.cpp
+++ b/dom/workers/RuntimeService.cpp
@@ -30,7 +30,6 @@
#include "mozilla/AsyncEventDispatcher.h"
#include "mozilla/Atomics.h"
#include "mozilla/CycleCollectedJSContext.h"
-#include "mozilla/Telemetry.h"
#include "mozilla/TimeStamp.h"
#include "mozilla/dom/asmjscache/AsmJSCache.h"
#include "mozilla/dom/AtomList.h"
@@ -1531,10 +1530,8 @@ RuntimeService::RegisterWorker(WorkerPrivate* aWorkerPrivate)
const bool isServiceWorker = aWorkerPrivate->IsServiceWorker();
const bool isSharedWorker = aWorkerPrivate->IsSharedWorker();
- const bool isDedicatedWorker = aWorkerPrivate->IsDedicatedWorker();
if (isServiceWorker) {
AssertIsOnMainThread();
- Telemetry::Accumulate(Telemetry::SERVICE_WORKER_SPAWN_ATTEMPTS, 1);
}
nsCString sharedWorkerScriptSpec;
@@ -1586,14 +1583,6 @@ RuntimeService::RegisterWorker(WorkerPrivate* aWorkerPrivate)
// Worker spawn gets queued due to hitting max workers per domain
// limit so let's log a warning.
WorkerPrivate::ReportErrorToConsole("HittingMaxWorkersPerDomain2");
-
- if (isServiceWorker) {
- Telemetry::Accumulate(Telemetry::SERVICE_WORKER_SPAWN_GETS_QUEUED, 1);
- } else if (isSharedWorker) {
- Telemetry::Accumulate(Telemetry::SHARED_WORKER_SPAWN_GETS_QUEUED, 1);
- } else if (isDedicatedWorker) {
- Telemetry::Accumulate(Telemetry::DEDICATED_WORKER_SPAWN_GETS_QUEUED, 1);
- }
}
else if (parent) {
domainInfo->mChildWorkerCount++;
@@ -1669,7 +1658,6 @@ RuntimeService::RegisterWorker(WorkerPrivate* aWorkerPrivate)
if (isServiceWorker) {
AssertIsOnMainThread();
- Telemetry::Accumulate(Telemetry::SERVICE_WORKER_WAS_SPAWNED, 1);
}
return true;
}
@@ -1766,8 +1754,6 @@ RuntimeService::UnregisterWorker(WorkerPrivate* aWorkerPrivate)
if (aWorkerPrivate->IsServiceWorker()) {
AssertIsOnMainThread();
- Telemetry::AccumulateTimeDelta(Telemetry::SERVICE_WORKER_LIFE_TIME,
- aWorkerPrivate->CreationTimeStamp());
}
if (aWorkerPrivate->IsSharedWorker() ||
diff --git a/dom/workers/ServiceWorkerClient.cpp b/dom/workers/ServiceWorkerClient.cpp
index 660512a5f..6ed3a6ea4 100644
--- a/dom/workers/ServiceWorkerClient.cpp
+++ b/dom/workers/ServiceWorkerClient.cpp
@@ -224,7 +224,7 @@ ServiceWorkerClient::PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
return;
}
- aRv = workerPrivate->DispatchToMainThread(runnable.forget());
+ aRv = NS_DispatchToMainThread(runnable);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
diff --git a/dom/workers/ServiceWorkerClients.cpp b/dom/workers/ServiceWorkerClients.cpp
index 11f864443..38f49e355 100644
--- a/dom/workers/ServiceWorkerClients.cpp
+++ b/dom/workers/ServiceWorkerClients.cpp
@@ -753,7 +753,7 @@ ServiceWorkerClients::Get(const nsAString& aClientId, ErrorResult& aRv)
RefPtr<GetRunnable> r =
new GetRunnable(promiseProxy, aClientId);
- MOZ_ALWAYS_SUCCEEDS(workerPrivate->DispatchToMainThread(r.forget()));
+ MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(r));
return promise.forget();
}
@@ -789,7 +789,7 @@ ServiceWorkerClients::MatchAll(const ClientQueryOptions& aOptions,
new MatchAllRunnable(promiseProxy,
NS_ConvertUTF16toUTF8(scope),
aOptions.mIncludeUncontrolled);
- MOZ_ALWAYS_SUCCEEDS(workerPrivate->DispatchToMainThread(r.forget()));
+ MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(r));
return promise.forget();
}
@@ -830,7 +830,7 @@ ServiceWorkerClients::OpenWindow(const nsAString& aUrl,
RefPtr<OpenWindowRunnable> r = new OpenWindowRunnable(promiseProxy,
aUrl, scope);
- MOZ_ALWAYS_SUCCEEDS(workerPrivate->DispatchToMainThread(r.forget()));
+ MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(r));
return promise.forget();
}
@@ -859,6 +859,6 @@ ServiceWorkerClients::Claim(ErrorResult& aRv)
RefPtr<ClaimRunnable> runnable =
new ClaimRunnable(promiseProxy, NS_ConvertUTF16toUTF8(scope));
- MOZ_ALWAYS_SUCCEEDS(workerPrivate->DispatchToMainThread(runnable.forget()));
+ MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(runnable));
return promise.forget();
}
diff --git a/dom/workers/ServiceWorkerEvents.cpp b/dom/workers/ServiceWorkerEvents.cpp
index 1f79e2c92..8b375c635 100644
--- a/dom/workers/ServiceWorkerEvents.cpp
+++ b/dom/workers/ServiceWorkerEvents.cpp
@@ -400,13 +400,7 @@ void RespondWithCopyComplete(void* aClosure, nsresult aStatus)
data->mScriptSpec,
data->mResponseURLSpec);
}
- // In theory this can happen after the worker thread is terminated.
- WorkerPrivate* worker = GetCurrentThreadWorkerPrivate();
- if (worker) {
- MOZ_ALWAYS_SUCCEEDS(worker->DispatchToMainThread(event.forget()));
- } else {
- MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(event.forget()));
- }
+ MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(event));
}
namespace {
@@ -734,13 +728,7 @@ RespondWithHandler::CancelRequest(nsresult aStatus)
{
nsCOMPtr<nsIRunnable> runnable =
new CancelChannelRunnable(mInterceptedChannel, mRegistration, aStatus);
- // Note, this may run off the worker thread during worker termination.
- WorkerPrivate* worker = GetCurrentThreadWorkerPrivate();
- if (worker) {
- MOZ_ALWAYS_SUCCEEDS(worker->DispatchToMainThread(runnable.forget()));
- } else {
- MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(runnable.forget()));
- }
+ NS_DispatchToMainThread(runnable);
mRequestWasHandled = true;
}
@@ -873,8 +861,8 @@ public:
mColumn = column;
}
- MOZ_ALWAYS_SUCCEEDS(mWorkerPrivate->DispatchToMainThread(
- NewRunnableMethod(this, &WaitUntilHandler::ReportOnMainThread)));
+ MOZ_ALWAYS_SUCCEEDS(
+ NS_DispatchToMainThread(NewRunnableMethod(this, &WaitUntilHandler::ReportOnMainThread)));
}
void
diff --git a/dom/workers/ServiceWorkerManager.cpp b/dom/workers/ServiceWorkerManager.cpp
index a66df0731..a8f191f2e 100644
--- a/dom/workers/ServiceWorkerManager.cpp
+++ b/dom/workers/ServiceWorkerManager.cpp
@@ -33,7 +33,6 @@
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/ErrorNames.h"
#include "mozilla/LoadContext.h"
-#include "mozilla/Telemetry.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/DOMError.h"
@@ -676,7 +675,6 @@ ServiceWorkerManager::Register(mozIDOMWindow* aWindow,
queue->ScheduleJob(job);
AssertIsOnMainThread();
- Telemetry::Accumulate(Telemetry::SERVICE_WORKER_REGISTRATIONS, 1);
promise.forget(aPromise);
return NS_OK;
@@ -2180,7 +2178,6 @@ ServiceWorkerManager::StartControllingADocument(ServiceWorkerRegistrationInfo* a
if (!aDocumentId.IsEmpty()) {
aDoc->SetId(aDocumentId);
}
- Telemetry::Accumulate(Telemetry::SERVICE_WORKER_CONTROLLED_DOCUMENTS, 1);
}
void
diff --git a/dom/workers/ServiceWorkerPrivate.cpp b/dom/workers/ServiceWorkerPrivate.cpp
index 24b2e11e6..23ae3b366 100644
--- a/dom/workers/ServiceWorkerPrivate.cpp
+++ b/dom/workers/ServiceWorkerPrivate.cpp
@@ -214,7 +214,7 @@ private:
mDone = true;
#endif
mCallback->SetResult(aResult);
- MOZ_ALWAYS_SUCCEEDS(mWorkerPrivate->DispatchToMainThread(mCallback));
+ MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(mCallback));
}
};
@@ -500,7 +500,7 @@ public:
if (mRegistration) {
nsCOMPtr<nsIRunnable> runnable =
new RegistrationUpdateRunnable(mRegistration, true /* time check */);
- aWorkerPrivate->DispatchToMainThread(runnable.forget());
+ NS_DispatchToMainThread(runnable.forget());
}
ExtendableEventWorkerRunnable::PostRun(aCx, aWorkerPrivate, aRunResult);
@@ -541,7 +541,7 @@ public:
Cancel() override
{
mCallback->SetResult(false);
- MOZ_ALWAYS_SUCCEEDS(mWorkerPrivate->DispatchToMainThread(mCallback));
+ MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(mCallback));
return WorkerRunnable::Cancel();
}
@@ -637,7 +637,7 @@ public:
mDone = true;
mCallback->SetResult(aResult);
- nsresult rv = mWorkerPrivate->DispatchToMainThread(mCallback);
+ nsresult rv = NS_DispatchToMainThread(mCallback);
if (NS_WARN_IF(NS_FAILED(rv))) {
NS_RUNTIMEABORT("Failed to dispatch life cycle event handler.");
}
@@ -768,7 +768,6 @@ public:
void Report(uint16_t aReason = nsIPushErrorReporter::DELIVERY_INTERNAL_ERROR)
{
- WorkerPrivate* workerPrivate = mWorkerPrivate;
mWorkerPrivate->AssertIsOnWorkerThread();
mWorkerPrivate = nullptr;
@@ -780,7 +779,7 @@ public:
NewRunnableMethod<uint16_t>(this,
&PushErrorReporter::ReportOnMainThread, aReason);
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(
- workerPrivate->DispatchToMainThread(runnable.forget())));
+ NS_DispatchToMainThread(runnable.forget())));
}
void ReportOnMainThread(uint16_t aReason)
@@ -1434,7 +1433,7 @@ public:
Cancel() override
{
nsCOMPtr<nsIRunnable> runnable = new ResumeRequest(mInterceptedChannel);
- if (NS_FAILED(mWorkerPrivate->DispatchToMainThread(runnable))) {
+ if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
NS_WARNING("Failed to resume channel on FetchEventRunnable::Cancel()!\n");
}
WorkerRunnable::Cancel();
@@ -1554,7 +1553,7 @@ private:
NS_ERROR_INTERCEPTION_FAILED);
}
- MOZ_ALWAYS_SUCCEEDS(mWorkerPrivate->DispatchToMainThread(runnable.forget()));
+ MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(runnable));
}
RefPtr<Promise> waitUntilPromise = event->GetPromise();
diff --git a/dom/workers/ServiceWorkerRegistrar.cpp b/dom/workers/ServiceWorkerRegistrar.cpp
index a4757ea54..7df129c2b 100644
--- a/dom/workers/ServiceWorkerRegistrar.cpp
+++ b/dom/workers/ServiceWorkerRegistrar.cpp
@@ -135,9 +135,6 @@ ServiceWorkerRegistrar::GetRegistrations(
if (firstTime) {
firstTime = false;
- Telemetry::AccumulateTimeDelta(
- Telemetry::SERVICE_WORKER_REGISTRATION_LOADING,
- startTime);
}
}
diff --git a/dom/workers/ServiceWorkerRegistration.cpp b/dom/workers/ServiceWorkerRegistration.cpp
index 451bd2be9..b3cda2c10 100644
--- a/dom/workers/ServiceWorkerRegistration.cpp
+++ b/dom/workers/ServiceWorkerRegistration.cpp
@@ -1107,7 +1107,7 @@ ServiceWorkerRegistrationWorkerThread::Update(ErrorResult& aRv)
}
RefPtr<UpdateRunnable> r = new UpdateRunnable(proxy, mScope);
- MOZ_ALWAYS_SUCCEEDS(worker->DispatchToMainThread(r.forget()));
+ MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(r));
return promise.forget();
}
@@ -1139,7 +1139,7 @@ ServiceWorkerRegistrationWorkerThread::Unregister(ErrorResult& aRv)
}
RefPtr<StartUnregisterRunnable> r = new StartUnregisterRunnable(proxy, mScope);
- MOZ_ALWAYS_SUCCEEDS(worker->DispatchToMainThread(r.forget()));
+ MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(r));
return promise.forget();
}
@@ -1161,7 +1161,7 @@ ServiceWorkerRegistrationWorkerThread::InitListener()
nsCOMPtr<nsIRunnable> r =
NewRunnableMethod(mListener, &WorkerListener::StartListeningForEvents);
- MOZ_ALWAYS_SUCCEEDS(worker->DispatchToMainThread(r.forget()));
+ MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(r));
}
void
@@ -1183,7 +1183,7 @@ ServiceWorkerRegistrationWorkerThread::ReleaseListener()
nsCOMPtr<nsIRunnable> r =
NewRunnableMethod(mListener, &WorkerListener::StopListeningForEvents);
- MOZ_ALWAYS_SUCCEEDS(mWorkerPrivate->DispatchToMainThread(r.forget()));
+ MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(r));
mListener = nullptr;
mWorkerPrivate = nullptr;
diff --git a/dom/workers/ServiceWorkerUpdateJob.cpp b/dom/workers/ServiceWorkerUpdateJob.cpp
index 614fe4de5..69877dfe4 100644
--- a/dom/workers/ServiceWorkerUpdateJob.cpp
+++ b/dom/workers/ServiceWorkerUpdateJob.cpp
@@ -408,8 +408,6 @@ ServiceWorkerUpdateJob::ComparisonResult(nsresult aStatus,
return;
}
- Telemetry::Accumulate(Telemetry::SERVICE_WORKER_UPDATED, 1);
-
// Begin step 7 of the Update algorithm to evaluate the new script.
RefPtr<ServiceWorkerInfo> sw =
diff --git a/dom/workers/ServiceWorkerWindowClient.cpp b/dom/workers/ServiceWorkerWindowClient.cpp
index 2ce0603cf..bae747214 100644
--- a/dom/workers/ServiceWorkerWindowClient.cpp
+++ b/dom/workers/ServiceWorkerWindowClient.cpp
@@ -183,7 +183,7 @@ ServiceWorkerWindowClient::Focus(ErrorResult& aRv) const
if (promiseProxy) {
RefPtr<ClientFocusRunnable> r = new ClientFocusRunnable(mWindowId,
promiseProxy);
- MOZ_ALWAYS_SUCCEEDS(workerPrivate->DispatchToMainThread(r.forget()));
+ MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(r));
} else {
promise->MaybeReject(NS_ERROR_DOM_ABORT_ERR);
}
@@ -549,7 +549,7 @@ ServiceWorkerWindowClient::Navigate(const nsAString& aUrl, ErrorResult& aRv)
if (promiseProxy) {
RefPtr<ClientNavigateRunnable> r =
new ClientNavigateRunnable(mWindowId, aUrl, scope, promiseProxy);
- MOZ_ALWAYS_SUCCEEDS(workerPrivate->DispatchToMainThread(r.forget()));
+ MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(r));
} else {
promise->MaybeReject(NS_ERROR_DOM_ABORT_ERR);
}
diff --git a/dom/workers/SharedWorker.cpp b/dom/workers/SharedWorker.cpp
index b0eed2def..99bb50339 100644
--- a/dom/workers/SharedWorker.cpp
+++ b/dom/workers/SharedWorker.cpp
@@ -12,7 +12,6 @@
#include "mozilla/Preferences.h"
#include "mozilla/dom/MessagePort.h"
#include "mozilla/dom/SharedWorkerBinding.h"
-#include "mozilla/Telemetry.h"
#include "nsContentUtils.h"
#include "nsIClassInfoImpl.h"
#include "nsIDOMEvent.h"
@@ -73,8 +72,6 @@ SharedWorker::Constructor(const GlobalObject& aGlobal, JSContext* aCx,
return nullptr;
}
- Telemetry::Accumulate(Telemetry::SHARED_WORKER_COUNT, 1);
-
return sharedWorker.forget();
}
diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp
index 612090027..6bc5c4f96 100644
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -404,7 +404,7 @@ private:
RefPtr<MainThreadReleaseRunnable> runnable =
new MainThreadReleaseRunnable(doomed, loadGroupToCancel);
- if (NS_FAILED(mWorkerPrivate->DispatchToMainThread(runnable.forget()))) {
+ if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
NS_WARNING("Failed to dispatch, going to leak!");
}
@@ -4078,7 +4078,7 @@ WorkerDebugger::PostMessageToDebugger(const nsAString& aMessage)
RefPtr<PostDebuggerMessageRunnable> runnable =
new PostDebuggerMessageRunnable(this, aMessage);
- if (NS_FAILED(mWorkerPrivate->DispatchToMainThread(runnable.forget()))) {
+ if (NS_FAILED(NS_DispatchToMainThread(runnable, NS_DISPATCH_NORMAL))) {
NS_WARNING("Failed to post message to debugger on main thread!");
}
}
@@ -4103,7 +4103,7 @@ WorkerDebugger::ReportErrorToDebugger(const nsAString& aFilename,
RefPtr<ReportDebuggerErrorRunnable> runnable =
new ReportDebuggerErrorRunnable(this, aFilename, aLineno, aMessage);
- if (NS_FAILED(mWorkerPrivate->DispatchToMainThread(runnable.forget()))) {
+ if (NS_FAILED(NS_DispatchToMainThread(runnable, NS_DISPATCH_NORMAL))) {
NS_WARNING("Failed to report error to debugger on main thread!");
}
}
@@ -4862,7 +4862,7 @@ WorkerPrivate::MaybeDispatchLoadFailedRunnable()
return;
}
- MOZ_ALWAYS_SUCCEEDS(DispatchToMainThread(runnable.forget()));
+ MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(runnable.forget()));
}
nsIEventTarget*
@@ -5083,7 +5083,7 @@ WorkerPrivate::ScheduleDeletion(WorkerRanOrNot aRanOrNot)
else {
RefPtr<TopLevelWorkerFinishedRunnable> runnable =
new TopLevelWorkerFinishedRunnable(this);
- if (NS_FAILED(DispatchToMainThread(runnable.forget()))) {
+ if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
NS_WARNING("Failed to dispatch runnable!");
}
}
diff --git a/dom/workers/WorkerRunnable.cpp b/dom/workers/WorkerRunnable.cpp
index 6bbe40f66..60d69d4e4 100644
--- a/dom/workers/WorkerRunnable.cpp
+++ b/dom/workers/WorkerRunnable.cpp
@@ -15,7 +15,6 @@
#include "mozilla/DebugOnly.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/dom/ScriptSettings.h"
-#include "mozilla/Telemetry.h"
#include "js/RootingAPI.h"
#include "js/Value.h"
@@ -118,7 +117,10 @@ WorkerRunnable::DispatchInternal()
return NS_SUCCEEDED(parent->Dispatch(runnable.forget()));
}
- return NS_SUCCEEDED(mWorkerPrivate->DispatchToMainThread(runnable.forget()));
+ nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
+ MOZ_ASSERT(mainThread);
+
+ return NS_SUCCEEDED(mainThread->Dispatch(runnable.forget(), NS_DISPATCH_NORMAL));
}
void
@@ -554,7 +556,10 @@ WorkerControlRunnable::DispatchInternal()
return NS_SUCCEEDED(parent->DispatchControlRunnable(runnable.forget()));
}
- return NS_SUCCEEDED(mWorkerPrivate->DispatchToMainThread(runnable.forget()));
+ nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
+ MOZ_ASSERT(mainThread);
+
+ return NS_SUCCEEDED(mainThread->Dispatch(runnable.forget(), NS_DISPATCH_NORMAL));
}
NS_IMPL_ISUPPORTS_INHERITED0(WorkerControlRunnable, WorkerRunnable)
@@ -572,8 +577,6 @@ WorkerMainThreadRunnable::Dispatch(Status aFailStatus, ErrorResult& aRv)
{
mWorkerPrivate->AssertIsOnWorkerThread();
- TimeStamp startTime = TimeStamp::NowLoRes();
-
AutoSyncLoopHolder syncLoop(mWorkerPrivate, aFailStatus);
mSyncLoopTarget = syncLoop.GetEventTarget();
@@ -583,18 +586,16 @@ WorkerMainThreadRunnable::Dispatch(Status aFailStatus, ErrorResult& aRv)
return;
}
- DebugOnly<nsresult> rv = mWorkerPrivate->DispatchToMainThread(this);
+ RefPtr<WorkerMainThreadRunnable> runnable(this);
+
+ DebugOnly<nsresult> rv =
+ NS_DispatchToMainThread(runnable.forget(), NS_DISPATCH_NORMAL);
MOZ_ASSERT(NS_SUCCEEDED(rv),
"Should only fail after xpcom-shutdown-threads and we're gone by then");
if (!syncLoop.Run()) {
aRv.ThrowUncatchableException();
}
-
- Telemetry::Accumulate(Telemetry::SYNC_WORKER_OPERATION, mTelemetryKey,
- static_cast<uint32_t>((TimeStamp::NowLoRes() - startTime)
- .ToMilliseconds()));
- Unused << startTime; // Shut the compiler up.
}
NS_IMETHODIMP
@@ -678,7 +679,7 @@ WorkerProxyToMainThreadRunnable::Dispatch()
return false;
}
- if (NS_WARN_IF(NS_FAILED(mWorkerPrivate->DispatchToMainThread(this)))) {
+ if (NS_WARN_IF(NS_FAILED(NS_DispatchToMainThread(this)))) {
ReleaseWorker();
RunBackOnWorkerThread();
return false;
diff --git a/dom/workers/WorkerScope.cpp b/dom/workers/WorkerScope.cpp
index 54252e53b..ace1a09fc 100644
--- a/dom/workers/WorkerScope.cpp
+++ b/dom/workers/WorkerScope.cpp
@@ -717,7 +717,7 @@ ServiceWorkerGlobalScope::SkipWaiting(ErrorResult& aRv)
new WorkerScopeSkipWaitingRunnable(promiseProxy,
NS_ConvertUTF16toUTF8(mScope));
- MOZ_ALWAYS_SUCCEEDS(mWorkerPrivate->DispatchToMainThread(runnable.forget()));
+ MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(runnable));
return promise.forget();
}
diff --git a/dom/worklet/WorkletGlobalScope.cpp b/dom/worklet/WorkletGlobalScope.cpp
index 4caeae81a..8c05a0abe 100644
--- a/dom/worklet/WorkletGlobalScope.cpp
+++ b/dom/worklet/WorkletGlobalScope.cpp
@@ -22,8 +22,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(WorkletGlobalScope)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(WorkletGlobalScope)
-
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindow)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mConsole)
tmp->TraverseHostObjectURIs(cb);
diff --git a/dom/xbl/nsXBLBinding.cpp b/dom/xbl/nsXBLBinding.cpp
index d9a2aacc5..b8174f6c2 100644
--- a/dom/xbl/nsXBLBinding.cpp
+++ b/dom/xbl/nsXBLBinding.cpp
@@ -1049,7 +1049,8 @@ nsXBLBinding::DoInitJSClass(JSContext *cx,
// to create and define it.
JS::Rooted<JSObject*> proto(cx);
JS::Rooted<JS::PropertyDescriptor> desc(cx);
- if (!JS_GetOwnUCPropertyDescriptor(cx, holder, aClassName.get(), &desc)) {
+ if (!JS_GetOwnUCPropertyDescriptor(cx, holder, aClassName.get(),
+ aClassName.Length(), &desc)) {
return NS_ERROR_OUT_OF_MEMORY;
}
*aNew = !desc.object();
diff --git a/dom/xbl/nsXBLDocumentInfo.cpp b/dom/xbl/nsXBLDocumentInfo.cpp
index 283775dc6..73b08d7e1 100644
--- a/dom/xbl/nsXBLDocumentInfo.cpp
+++ b/dom/xbl/nsXBLDocumentInfo.cpp
@@ -52,7 +52,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXBLDocumentInfo)
if (tmp->mDocument &&
nsCCUncollectableMarker::InGeneration(cb, tmp->mDocument->GetMarkedCCGeneration())) {
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
return NS_SUCCESS_INTERRUPTED_TRAVERSE;
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocument)
@@ -62,7 +61,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXBLDocumentInfo)
iter.UserData()->Traverse(cb);
}
}
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsXBLDocumentInfo)
if (tmp->mBindingTable) {
diff --git a/dom/xbl/nsXBLProtoImpl.cpp b/dom/xbl/nsXBLProtoImpl.cpp
index 4db9cabf0..5efcb71e0 100644
--- a/dom/xbl/nsXBLProtoImpl.cpp
+++ b/dom/xbl/nsXBLProtoImpl.cpp
@@ -100,11 +100,15 @@ nsXBLProtoImpl::InstallImplementation(nsXBLPrototypeBinding* aPrototypeBinding,
// end up with a different content prototype, but we'll already have a property
// holder called |foo| in the XBL scope. Check for that to avoid wasteful and
// weird property holder duplication.
- const char16_t* className = aPrototypeBinding->ClassName().get();
+ const nsString& className = aPrototypeBinding->ClassName();
+ const char16_t* classNameChars = className.get();
+ const size_t classNameLen = className.Length();
+
JS::Rooted<JSObject*> propertyHolder(cx);
JS::Rooted<JS::PropertyDescriptor> existingHolder(cx);
if (scopeObject != globalObject &&
- !JS_GetOwnUCPropertyDescriptor(cx, scopeObject, className, &existingHolder)) {
+ !JS_GetOwnUCPropertyDescriptor(cx, scopeObject, classNameChars,
+ classNameLen, &existingHolder)) {
return NS_ERROR_FAILURE;
}
bool propertyHolderIsNew = !existingHolder.object() || !existingHolder.value().isObject();
@@ -119,8 +123,8 @@ nsXBLProtoImpl::InstallImplementation(nsXBLPrototypeBinding* aPrototypeBinding,
// Define it as a property on the scopeObject, using the same name used on
// the content side.
- bool ok = JS_DefineUCProperty(cx, scopeObject, className, -1, propertyHolder,
- JSPROP_PERMANENT | JSPROP_READONLY,
+ bool ok = JS_DefineUCProperty(cx, scopeObject, classNameChars, classNameLen,
+ propertyHolder, JSPROP_PERMANENT | JSPROP_READONLY,
JS_STUBGETTER, JS_STUBSETTER);
NS_ENSURE_TRUE(ok, NS_ERROR_UNEXPECTED);
} else {
diff --git a/dom/xhr/XMLHttpRequestMainThread.cpp b/dom/xhr/XMLHttpRequestMainThread.cpp
index 4fd34a993..613008ad5 100644
--- a/dom/xhr/XMLHttpRequestMainThread.cpp
+++ b/dom/xhr/XMLHttpRequestMainThread.cpp
@@ -757,15 +757,6 @@ XMLHttpRequestMainThread::SetResponseType(XMLHttpRequestResponseType aResponseTy
return;
}
- // We want to get rid of this moz-only types. Bug 1335365.
- if (aResponseType == XMLHttpRequestResponseType::Moz_blob) {
- Telemetry::Accumulate(Telemetry::MOZ_BLOB_IN_XHR, 1);
- } else if (aResponseType == XMLHttpRequestResponseType::Moz_chunked_text) {
- Telemetry::Accumulate(Telemetry::MOZ_CHUNKED_TEXT_IN_XHR, 1);
- } else if (aResponseType == XMLHttpRequestResponseType::Moz_chunked_arraybuffer) {
- Telemetry::Accumulate(Telemetry::MOZ_CHUNKED_ARRAYBUFFER_IN_XHR, 1);
- }
-
// Set the responseType attribute's value to the given value.
mResponseType = aResponseType;
}
@@ -1521,8 +1512,6 @@ XMLHttpRequestMainThread::Open(const nsACString& aMethod,
GetOwner()->GetExtantDoc()->WarnOnceAbout(nsIDocument::eSyncXMLHttpRequest);
}
- Telemetry::Accumulate(Telemetry::XMLHTTPREQUEST_ASYNC_OR_SYNC, aAsync ? 0 : 1);
-
// Step 1
nsCOMPtr<nsIDocument> responsibleDocument = GetDocumentIfCurrent();
if (!responsibleDocument) {
diff --git a/dom/xhr/XMLHttpRequestWorker.cpp b/dom/xhr/XMLHttpRequestWorker.cpp
index c9e892f26..2af61bd7d 100644
--- a/dom/xhr/XMLHttpRequestWorker.cpp
+++ b/dom/xhr/XMLHttpRequestWorker.cpp
@@ -1588,8 +1588,6 @@ XMLHttpRequestWorker::Construct(const GlobalObject& aGlobal,
WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
MOZ_ASSERT(workerPrivate);
- Telemetry::Accumulate(Telemetry::XHR_IN_WORKER, 1);
-
RefPtr<XMLHttpRequestWorker> xhr = new XMLHttpRequestWorker(workerPrivate);
if (workerPrivate->XHRParamsAllowed()) {
diff --git a/dom/xslt/xpath/XPathResult.cpp b/dom/xslt/xpath/XPathResult.cpp
index 33315c942..07121347e 100644
--- a/dom/xslt/xpath/XPathResult.cpp
+++ b/dom/xslt/xpath/XPathResult.cpp
@@ -63,7 +63,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(XPathResult)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocument)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(XPathResult)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocument)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mResultNodes)
diff --git a/dom/xslt/xpath/txUnaryExpr.cpp b/dom/xslt/xpath/txUnaryExpr.cpp
index 95682b5b2..ae20fda46 100644
--- a/dom/xslt/xpath/txUnaryExpr.cpp
+++ b/dom/xslt/xpath/txUnaryExpr.cpp
@@ -23,16 +23,7 @@ UnaryExpr::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
NS_ENSURE_SUCCESS(rv, rv);
double value = exprRes->numberValue();
-#ifdef HPUX
- /*
- * Negation of a zero doesn't produce a negative
- * zero on HPUX. Perform the operation by multiplying with
- * -1.
- */
- return aContext->recycler()->getNumberResult(-1 * value, aResult);
-#else
return aContext->recycler()->getNumberResult(-value, aResult);
-#endif
}
TX_IMPL_EXPR_STUBS_1(UnaryExpr, NODESET_RESULT, expr)
diff --git a/dom/xslt/xslt/txMozillaStylesheetCompiler.cpp b/dom/xslt/xslt/txMozillaStylesheetCompiler.cpp
index 726441757..c9bcc31ff 100644
--- a/dom/xslt/xslt/txMozillaStylesheetCompiler.cpp
+++ b/dom/xslt/xslt/txMozillaStylesheetCompiler.cpp
@@ -462,10 +462,6 @@ txCompileObserver::startLoad(nsIURI* aUri, txStylesheetCompiler* aCompiler,
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
if (httpChannel) {
- httpChannel->SetRequestHeader(NS_LITERAL_CSTRING("Accept"),
- NS_LITERAL_CSTRING("*/*"),
- false);
-
nsCOMPtr<nsIURI> referrerURI;
aReferrerPrincipal->GetURI(getter_AddRefs(referrerURI));
if (referrerURI) {
diff --git a/dom/xul/nsXULElement.cpp b/dom/xul/nsXULElement.cpp
index 14fa898ab..e351a46eb 100644
--- a/dom/xul/nsXULElement.cpp
+++ b/dom/xul/nsXULElement.cpp
@@ -2173,7 +2173,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXULPrototypeNode)
}
ImplCycleCollectionTraverse(cb, elem->mChildren, "mChildren");
}
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsXULPrototypeNode)
if (tmp->mType == nsXULPrototypeNode::eType_Script) {
diff --git a/dom/xul/nsXULPrototypeCache.cpp b/dom/xul/nsXULPrototypeCache.cpp
index 84a201d59..2c3454860 100644
--- a/dom/xul/nsXULPrototypeCache.cpp
+++ b/dom/xul/nsXULPrototypeCache.cpp
@@ -45,12 +45,6 @@ UpdategDisableXULCache()
// Get the value of "nglayout.debug.disable_xul_cache" preference
gDisableXULCache =
Preferences::GetBool(kDisableXULCachePref, gDisableXULCache);
-
- // Sets the flag if the XUL cache is disabled
- if (gDisableXULCache) {
- Telemetry::Accumulate(Telemetry::XUL_CACHE_DISABLED, true);
- }
-
}
static void