зеркало из https://github.com/mozilla/gecko-dev.git
Merge inbound to m-c a=merge
This commit is contained in:
Коммит
8cc1c6b2ac
|
@ -12,9 +12,6 @@ Cu.import("resource://gre/modules/FxAccounts.jsm");
|
|||
let fxAccountsCommon = {};
|
||||
Cu.import("resource://gre/modules/FxAccountsCommon.js", fxAccountsCommon);
|
||||
|
||||
// for master-password utilities
|
||||
Cu.import("resource://services-sync/util.js");
|
||||
|
||||
const PREF_LAST_FXA_USER = "identity.fxaccounts.lastSignedInUserHash";
|
||||
const PREF_SYNC_SHOW_CUSTOMIZATION = "services.sync.ui.showCustomizationDialog";
|
||||
|
||||
|
@ -107,12 +104,6 @@ let wrapper = {
|
|||
return;
|
||||
}
|
||||
|
||||
// If a master-password is enabled, we want to encourage the user to
|
||||
// unlock it. Things still work if not, but the user will probably need
|
||||
// to re-auth next startup (in which case we will get here again and
|
||||
// re-prompt)
|
||||
Utils.ensureMPUnlocked();
|
||||
|
||||
let iframe = document.getElementById("remote");
|
||||
this.iframe = iframe;
|
||||
iframe.addEventListener("load", this);
|
||||
|
|
|
@ -4,6 +4,20 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
let service = Cc["@mozilla.org/weave/service;1"]
|
||||
.getService(Ci.nsISupports)
|
||||
.wrappedJSObject;
|
||||
|
||||
if (!service.allowPasswordsEngine) {
|
||||
let checkbox = document.getElementById("fxa-pweng-chk");
|
||||
checkbox.checked = false;
|
||||
checkbox.disabled = true;
|
||||
}
|
||||
|
||||
addEventListener("dialogaccept", function () {
|
||||
let pane = document.getElementById("sync-customize-pane");
|
||||
pane.writePreferences(true);
|
||||
|
|
|
@ -45,7 +45,8 @@
|
|||
<checkbox label="&engine.bookmarks.label;"
|
||||
accesskey="&engine.bookmarks.accesskey;"
|
||||
preference="engine.bookmarks"/>
|
||||
<checkbox label="&engine.passwords.label;"
|
||||
<checkbox id="fxa-pweng-chk"
|
||||
label="&engine.passwords.label;"
|
||||
accesskey="&engine.passwords.accesskey;"
|
||||
preference="engine.passwords"/>
|
||||
<checkbox label="&engine.history.label;"
|
||||
|
|
|
@ -87,6 +87,12 @@ let gSyncUtils = {
|
|||
this._openLink(Weave.Svc.Prefs.get(root + "privacyURL"));
|
||||
},
|
||||
|
||||
openMPInfoPage: function (event) {
|
||||
event.stopPropagation();
|
||||
let baseURL = Services.urlFormatter.formatURLPref("app.support.baseURL");
|
||||
this._openLink(baseURL + "sync-master-password");
|
||||
},
|
||||
|
||||
openFirstSyncProgressPage: function () {
|
||||
this._openLink("about:sync-progress");
|
||||
},
|
||||
|
|
|
@ -154,6 +154,17 @@ let gSyncPane = {
|
|||
for (let checkbox of engines.querySelectorAll("checkbox")) {
|
||||
checkbox.disabled = enginesListDisabled;
|
||||
}
|
||||
|
||||
let checkbox = document.getElementById("fxa-pweng-chk");
|
||||
let help = document.getElementById("fxa-pweng-help");
|
||||
let allowPasswordsEngine = service.allowPasswordsEngine;
|
||||
|
||||
if (!allowPasswordsEngine) {
|
||||
checkbox.checked = false;
|
||||
}
|
||||
|
||||
checkbox.disabled = !allowPasswordsEngine || enginesListDisabled;
|
||||
help.hidden = allowPasswordsEngine || enginesListDisabled;
|
||||
});
|
||||
// If fxAccountEnabled is false and we are in a "not configured" state,
|
||||
// then fxAccounts is probably fully disabled rather than just unconfigured,
|
||||
|
|
|
@ -283,9 +283,20 @@
|
|||
<checkbox label="&engine.bookmarks.label;"
|
||||
accesskey="&engine.bookmarks.accesskey;"
|
||||
preference="engine.bookmarks"/>
|
||||
<checkbox label="&engine.passwords.label;"
|
||||
accesskey="&engine.passwords.accesskey;"
|
||||
preference="engine.passwords"/>
|
||||
<hbox>
|
||||
<checkbox id="fxa-pweng-chk"
|
||||
label="&engine.passwords.label;"
|
||||
accesskey="&engine.passwords.accesskey;"
|
||||
preference="engine.passwords"/>
|
||||
|
||||
<vbox id="fxa-pweng-help">
|
||||
<spacer flex="1"/>
|
||||
<hbox id="fxa-pweng-help-link">
|
||||
<image onclick="gSyncUtils.openMPInfoPage(event);" />
|
||||
</hbox>
|
||||
<spacer flex="1"/>
|
||||
</vbox>
|
||||
</hbox>
|
||||
<checkbox label="&engine.history.label;"
|
||||
accesskey="&engine.history.accesskey;"
|
||||
preference="engine.history"/>
|
||||
|
|
|
@ -154,6 +154,17 @@ let gSyncPane = {
|
|||
for (let checkbox of engines.querySelectorAll("checkbox")) {
|
||||
checkbox.disabled = enginesListDisabled;
|
||||
}
|
||||
|
||||
let checkbox = document.getElementById("fxa-pweng-chk");
|
||||
let help = document.getElementById("fxa-pweng-help");
|
||||
let allowPasswordsEngine = service.allowPasswordsEngine;
|
||||
|
||||
if (!allowPasswordsEngine) {
|
||||
checkbox.checked = false;
|
||||
}
|
||||
|
||||
checkbox.disabled = !allowPasswordsEngine || enginesListDisabled;
|
||||
help.hidden = allowPasswordsEngine || enginesListDisabled;
|
||||
});
|
||||
// If fxAccountEnabled is false and we are in a "not configured" state,
|
||||
// then fxAccounts is probably fully disabled rather than just unconfigured,
|
||||
|
|
|
@ -265,9 +265,20 @@
|
|||
<checkbox label="&engine.bookmarks.label;"
|
||||
accesskey="&engine.bookmarks.accesskey;"
|
||||
preference="engine.bookmarks"/>
|
||||
<checkbox label="&engine.passwords.label;"
|
||||
accesskey="&engine.passwords.accesskey;"
|
||||
preference="engine.passwords"/>
|
||||
<hbox>
|
||||
<checkbox id="fxa-pweng-chk"
|
||||
label="&engine.passwords.label;"
|
||||
accesskey="&engine.passwords.accesskey;"
|
||||
preference="engine.passwords"/>
|
||||
|
||||
<vbox id="fxa-pweng-help">
|
||||
<spacer flex="1"/>
|
||||
<hbox id="fxa-pweng-help-link">
|
||||
<image onclick="gSyncUtils.openMPInfoPage(event);" />
|
||||
</hbox>
|
||||
<spacer flex="1"/>
|
||||
</vbox>
|
||||
</hbox>
|
||||
<checkbox label="&engine.history.label;"
|
||||
accesskey="&engine.history.accesskey;"
|
||||
preference="engine.history"/>
|
||||
|
|
|
@ -171,4 +171,12 @@ label.small {
|
|||
margin-bottom: 0.6em;
|
||||
}
|
||||
|
||||
#fxa-pweng-help-link > label {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#fxa-pweng-help-link > image {
|
||||
list-style-image: url("chrome://global/skin/icons/question-16.png");
|
||||
}
|
||||
|
||||
%endif
|
||||
|
|
|
@ -233,4 +233,20 @@ html|a.inline-link:-moz-focusring {
|
|||
margin-bottom: 0.6em;
|
||||
}
|
||||
|
||||
#fxa-pweng-help-link > label {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#fxa-pweng-help-link > image {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
list-style-image: url("chrome://global/skin/icons/question-16.png");
|
||||
}
|
||||
|
||||
@media (min-resolution: 2dppx) {
|
||||
#fxa-pweng-help-link > image {
|
||||
list-style-image: url("chrome://global/skin/icons/question-32.png");
|
||||
}
|
||||
}
|
||||
|
||||
%endif
|
||||
|
|
|
@ -161,4 +161,12 @@ label.small {
|
|||
margin-bottom: 0.6em;
|
||||
}
|
||||
|
||||
#fxa-pweng-help-link > label {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#fxa-pweng-help-link > image {
|
||||
list-style-image: url("chrome://global/skin/icons/question-16.png");
|
||||
}
|
||||
|
||||
%endif
|
||||
|
|
|
@ -69,6 +69,7 @@
|
|||
#include "mozilla/dom/TreeWalker.h"
|
||||
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIServiceWorkerManager.h"
|
||||
|
||||
#include "nsContentCID.h"
|
||||
#include "nsError.h"
|
||||
|
@ -4465,6 +4466,24 @@ nsDocument::SetScriptGlobalObject(nsIScriptGlobalObject *aScriptGlobalObject)
|
|||
if (mTemplateContentsOwner && mTemplateContentsOwner != this) {
|
||||
mTemplateContentsOwner->SetScriptGlobalObject(aScriptGlobalObject);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIChannel> channel = GetChannel();
|
||||
if (!mMaybeServiceWorkerControlled && channel) {
|
||||
nsLoadFlags loadFlags = 0;
|
||||
channel->GetLoadFlags(&loadFlags);
|
||||
// If we are shift-reloaded, don't associate with a ServiceWorker.
|
||||
// FIXME(nsm): Bug 1041339.
|
||||
if (loadFlags & nsIRequest::LOAD_BYPASS_CACHE) {
|
||||
NS_WARNING("Page was shift reloaded, skipping ServiceWorker control");
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIServiceWorkerManager> swm = do_GetService(SERVICEWORKERMANAGER_CONTRACTID);
|
||||
if (swm) {
|
||||
swm->MaybeStartControlling(this);
|
||||
mMaybeServiceWorkerControlled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsIScriptGlobalObject*
|
||||
|
@ -8483,6 +8502,11 @@ nsDocument::Destroy()
|
|||
|
||||
mRegistry = nullptr;
|
||||
|
||||
nsCOMPtr<nsIServiceWorkerManager> swm = do_GetService(SERVICEWORKERMANAGER_CONTRACTID);
|
||||
if (swm) {
|
||||
swm->MaybeStopControlling(this);
|
||||
}
|
||||
|
||||
// XXX We really should let cycle collection do this, but that currently still
|
||||
// leaks (see https://bugzilla.mozilla.org/show_bug.cgi?id=406684).
|
||||
ReleaseWrapper(static_cast<nsINode*>(this));
|
||||
|
|
|
@ -1742,6 +1742,10 @@ private:
|
|||
nsCOMPtr<nsIDocument> mMasterDocument;
|
||||
nsRefPtr<mozilla::dom::ImportManager> mImportManager;
|
||||
|
||||
// Set to true when the document is possibly controlled by the ServiceWorker.
|
||||
// Used to prevent multiple requests to ServiceWorkerManager.
|
||||
bool mMaybeServiceWorkerControlled;
|
||||
|
||||
#ifdef DEBUG
|
||||
public:
|
||||
bool mWillReparent;
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
#include "nsJSNPRuntime.h"
|
||||
#include "nsINestedURI.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
#include "nsScriptSecurityManager.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsIStreamConverterService.h"
|
||||
|
@ -80,6 +79,7 @@
|
|||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/Event.h"
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
#include "mozilla/EventDispatcher.h"
|
||||
#include "mozilla/EventStates.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
|
@ -2914,21 +2914,9 @@ nsObjectLoadingContent::NotifyContentObjectWrapper()
|
|||
nsCOMPtr<nsIContent> thisContent =
|
||||
do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
|
||||
|
||||
nsCOMPtr<nsIDocument> doc = thisContent->GetDocument();
|
||||
if (!doc)
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(doc->GetScopeObject());
|
||||
if (!sgo)
|
||||
return;
|
||||
|
||||
nsIScriptContext *scx = sgo->GetContext();
|
||||
if (!scx)
|
||||
return;
|
||||
|
||||
JSContext *cx = scx->GetNativeContext();
|
||||
nsCxPusher pusher;
|
||||
pusher.Push(cx);
|
||||
AutoJSAPI jsapi;
|
||||
jsapi.Init();
|
||||
JSContext* cx = jsapi.cx();
|
||||
|
||||
JS::Rooted<JSObject*> obj(cx, thisContent->GetWrapper());
|
||||
if (!obj) {
|
||||
|
@ -3297,12 +3285,7 @@ nsObjectLoadingContent::SetupProtoChain(JSContext* aCx,
|
|||
}
|
||||
|
||||
if (!nsContentUtils::IsSafeToRunScript()) {
|
||||
// This may be null if the JS context is not a DOM context. That's ok, we'll
|
||||
// use the safe context from XPConnect in the runnable.
|
||||
nsCOMPtr<nsIScriptContext> scriptContext = GetScriptContextFromJSContext(aCx);
|
||||
|
||||
nsRefPtr<SetupProtoChainRunner> runner =
|
||||
new SetupProtoChainRunner(scriptContext, this);
|
||||
nsRefPtr<SetupProtoChainRunner> runner = new SetupProtoChainRunner(this);
|
||||
nsContentUtils::AddScriptRunner(runner);
|
||||
return;
|
||||
}
|
||||
|
@ -3510,10 +3493,8 @@ nsObjectLoadingContent::GetOwnPropertyNames(JSContext* aCx,
|
|||
|
||||
// SetupProtoChainRunner implementation
|
||||
nsObjectLoadingContent::SetupProtoChainRunner::SetupProtoChainRunner(
|
||||
nsIScriptContext* scriptContext,
|
||||
nsObjectLoadingContent* aContent)
|
||||
: mContext(scriptContext)
|
||||
, mContent(aContent)
|
||||
: mContent(aContent)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -3524,12 +3505,9 @@ nsObjectLoadingContent::SetupProtoChainRunner::~SetupProtoChainRunner()
|
|||
NS_IMETHODIMP
|
||||
nsObjectLoadingContent::SetupProtoChainRunner::Run()
|
||||
{
|
||||
// XXXbz Does it really matter what JSContext we use here? Seems
|
||||
// like we could just always use the safe context....
|
||||
nsCxPusher pusher;
|
||||
JSContext* cx = mContext ? mContext->GetNativeContext()
|
||||
: nsContentUtils::GetSafeJSContext();
|
||||
pusher.Push(cx);
|
||||
AutoJSAPI jsapi;
|
||||
jsapi.Init();
|
||||
JSContext* cx = jsapi.cx();
|
||||
|
||||
nsCOMPtr<nsIContent> content;
|
||||
CallQueryInterface(mContent.get(), getter_AddRefs(content));
|
||||
|
|
|
@ -477,13 +477,11 @@ class nsObjectLoadingContent : public nsImageLoadingContent
|
|||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
SetupProtoChainRunner(nsIScriptContext* scriptContext,
|
||||
nsObjectLoadingContent* aContent);
|
||||
SetupProtoChainRunner(nsObjectLoadingContent* aContent);
|
||||
|
||||
NS_IMETHOD Run() MOZ_OVERRIDE;
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIScriptContext> mContext;
|
||||
// We store an nsIObjectLoadingContent because we can
|
||||
// unambiguously refcount that.
|
||||
nsRefPtr<nsIObjectLoadingContent> mContent;
|
||||
|
|
|
@ -21,20 +21,7 @@ SOURCES += [
|
|||
]
|
||||
|
||||
if CONFIG['MOZ_WMF']:
|
||||
EXPORTS += [
|
||||
'wmf/MFTDecoder.h',
|
||||
'wmf/WMFAudioMFTManager.h',
|
||||
'wmf/WMFDecoderModule.h',
|
||||
'wmf/WMFMediaDataDecoder.h',
|
||||
'wmf/WMFVideoMFTManager.h',
|
||||
]
|
||||
UNIFIED_SOURCES += [
|
||||
'wmf/MFTDecoder.cpp',
|
||||
'wmf/WMFAudioMFTManager.cpp',
|
||||
'wmf/WMFDecoderModule.cpp',
|
||||
'wmf/WMFMediaDataDecoder.cpp',
|
||||
'wmf/WMFVideoMFTManager.cpp',
|
||||
]
|
||||
PARALLEL_DIRS += [ 'wmf' ];
|
||||
|
||||
if CONFIG['MOZ_FFMPEG']:
|
||||
EXPORTS += [
|
||||
|
|
|
@ -133,7 +133,7 @@ MFTDecoder::CreateInputSample(const uint8_t* aData,
|
|||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
|
||||
RefPtr<IMFMediaBuffer> buffer;
|
||||
int32_t bufferSize = std::max(uint32_t(mInputStreamInfo.cbSize), aDataSize);
|
||||
int32_t bufferSize = std::max<uint32_t>(uint32_t(mInputStreamInfo.cbSize), aDataSize);
|
||||
UINT32 alignment = (mInputStreamInfo.cbAlignment > 1) ? mInputStreamInfo.cbAlignment - 1 : 0;
|
||||
hr = wmf::MFCreateAlignedMemoryBuffer(bufferSize, alignment, byRef(buffer));
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
# -*- 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 += [
|
||||
'MFTDecoder.h',
|
||||
'WMFAudioMFTManager.h',
|
||||
'WMFDecoderModule.h',
|
||||
'WMFMediaDataDecoder.h',
|
||||
'WMFVideoMFTManager.h',
|
||||
]
|
||||
UNIFIED_SOURCES += [
|
||||
'MFTDecoder.cpp',
|
||||
'WMFAudioMFTManager.cpp',
|
||||
'WMFDecoderModule.cpp',
|
||||
'WMFMediaDataDecoder.cpp',
|
||||
'WMFVideoMFTManager.cpp',
|
||||
]
|
||||
|
||||
FINAL_LIBRARY = 'gklayout'
|
||||
|
||||
FAIL_ON_WARNINGS = True
|
|
@ -14,6 +14,8 @@
|
|||
#include "nsIRunnable.h"
|
||||
#include "mozIGeckoMediaPluginService.h"
|
||||
#include "mozilla/unused.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "mtransport/runnable_utils.h"
|
||||
|
||||
#include "mozilla/dom/CrashReporterParent.h"
|
||||
using mozilla::dom::CrashReporterParent;
|
||||
|
@ -321,16 +323,37 @@ GMPParent::GetCrashID(nsString& aResult)
|
|||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
GMPNotifyObservers(nsAString& aData)
|
||||
{
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
if (obs) {
|
||||
nsString temp(aData);
|
||||
obs->NotifyObservers(nullptr, "gmp-plugin-crash", temp.get());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GMPParent::ActorDestroy(ActorDestroyReason aWhy)
|
||||
{
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
if (AbnormalShutdown == aWhy) {
|
||||
nsString dumpID;
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
GetCrashID(dumpID);
|
||||
#endif
|
||||
// now do something with the crash ID, bug 1038961
|
||||
nsString id;
|
||||
// use the parent address to identify it
|
||||
// We could use any unique-to-the-parent value
|
||||
id.AppendInt(reinterpret_cast<uint64_t>(this));
|
||||
id.Append(NS_LITERAL_STRING(" "));
|
||||
AppendUTF8toUTF16(mDisplayName, id);
|
||||
id.Append(NS_LITERAL_STRING(" "));
|
||||
id.Append(dumpID);
|
||||
|
||||
// NotifyObservers is mainthread-only
|
||||
NS_DispatchToMainThread(WrapRunnableNM(&GMPNotifyObservers, id),
|
||||
NS_DISPATCH_NORMAL);
|
||||
}
|
||||
#endif
|
||||
// warn us off trying to close again
|
||||
mState = GMPStateClosing;
|
||||
CloseActive();
|
||||
|
|
|
@ -42,6 +42,7 @@ public:
|
|||
virtual nsresult Reset() MOZ_OVERRIDE;
|
||||
virtual nsresult Drain() MOZ_OVERRIDE;
|
||||
virtual nsresult DecodingComplete() MOZ_OVERRIDE;
|
||||
virtual const uint64_t ParentID() MOZ_OVERRIDE { return reinterpret_cast<uint64_t>(mPlugin.get()); }
|
||||
|
||||
// GMPSharedMemManager
|
||||
virtual void CheckThread();
|
||||
|
|
|
@ -28,6 +28,7 @@ public:
|
|||
virtual nsresult Reset() = 0;
|
||||
virtual nsresult Drain() = 0;
|
||||
virtual nsresult DecodingComplete() = 0;
|
||||
virtual const uint64_t ParentID() = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -43,6 +43,7 @@ public:
|
|||
virtual GMPErr SetRates(uint32_t aNewBitRate, uint32_t aFrameRate) MOZ_OVERRIDE;
|
||||
virtual GMPErr SetPeriodicKeyFrames(bool aEnable) MOZ_OVERRIDE;
|
||||
virtual void EncodingComplete() MOZ_OVERRIDE;
|
||||
virtual const uint64_t ParentID() MOZ_OVERRIDE { return reinterpret_cast<uint64_t>(mPlugin.get()); }
|
||||
|
||||
// GMPSharedMemManager
|
||||
virtual void CheckThread();
|
||||
|
|
|
@ -35,6 +35,7 @@ public:
|
|||
virtual GMPErr SetRates(uint32_t aNewBitRate, uint32_t aFrameRate) = 0;
|
||||
virtual GMPErr SetPeriodicKeyFrames(bool aEnable) = 0;
|
||||
virtual void EncodingComplete() = 0;
|
||||
virtual const uint64_t ParentID() = 0;
|
||||
};
|
||||
|
||||
#endif // GMPVideoEncoderProxy_h_
|
||||
|
|
|
@ -381,7 +381,8 @@ skip-if = buildapp == 'b2g' || toolkit == 'android' # mimetype check, bug 969289
|
|||
[test_mediarecorder_unsupported_src.html]
|
||||
[test_mediarecorder_record_getdata_afterstart.html]
|
||||
[test_mediatrack_consuming_mediaresource.html]
|
||||
[test_mediatrack_events_and_consuming_ms.html]
|
||||
[test_mediatrack_consuming_mediastream.html]
|
||||
[test_mediatrack_events.html]
|
||||
[test_mediatrack_replay_from_end.html]
|
||||
[test_metadata.html]
|
||||
[test_mixed_principals.html]
|
||||
|
@ -398,7 +399,6 @@ skip-if = true # bug 567954 and intermittent leaks
|
|||
# Seamonkey: Bug 598252, B2G: Bug 982100, Android: Bug 758476, bug 981086
|
||||
skip-if = appname == "seamonkey" || toolkit == 'gonk' || toolkit == 'android'
|
||||
[test_playback.html]
|
||||
skip-if = buildapp == 'b2g' || toolkit == 'android' # Disabled on Android & B2G due to bug 668973
|
||||
[test_playback_errors.html]
|
||||
[test_playback_rate.html]
|
||||
[test_playback_rate_playpause.html]
|
||||
|
|
|
@ -23,7 +23,7 @@ function cloneLoaded(event) {
|
|||
}
|
||||
|
||||
e.removeEventListener("loadeddata", cloneLoaded, false);
|
||||
|
||||
removeNodeAndSource(e);
|
||||
manager.finished(e.token);
|
||||
}
|
||||
|
||||
|
@ -39,6 +39,17 @@ function tryClone(event) {
|
|||
}
|
||||
|
||||
clone.addEventListener("loadeddata", cloneLoaded, false);
|
||||
clone.onloadstart = function(evt) {
|
||||
info("cloned " + evt.target.token + " start loading.");
|
||||
evt.target.onloadstart = null;
|
||||
// Since there is only one H264 decoder instance, we have to delete the
|
||||
// decoder of the original element for the cloned element to load. However,
|
||||
// we can't delete the decoder too early otherwise cloning decoder will
|
||||
// fail to kick in. We wait for 'loadstart' event of the cloned element to
|
||||
// know when the decoder is already cloned and we can delete the decoder of
|
||||
// the original element.
|
||||
removeNodeAndSource(e);
|
||||
}
|
||||
|
||||
e.removeEventListener("loadeddata", tryClone, false);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,157 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test track interfaces when consuming a MediaStream from gUM</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<script type="text/javascript" src="manifest.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
function startTest() {
|
||||
navigator.mozGetUserMedia({audio:true, video:true, fake:true},
|
||||
function(stream) {
|
||||
var element = document.createElement("video");
|
||||
|
||||
var audioOnchange = 0;
|
||||
var audioOnaddtrack = 0;
|
||||
var audioOnremovetrack = 0;
|
||||
var videoOnchange = 0;
|
||||
var videoOnaddtrack = 0;
|
||||
var videoOnremovetrack = 0;
|
||||
var isPlaying = false;
|
||||
|
||||
element.audioTracks.onaddtrack = function(e) {
|
||||
audioOnaddtrack++;
|
||||
}
|
||||
|
||||
element.audioTracks.onremovetrack = function(e) {
|
||||
audioOnremovetrack++;
|
||||
}
|
||||
|
||||
element.audioTracks.onchange = function(e) {
|
||||
audioOnchange++;
|
||||
}
|
||||
|
||||
element.videoTracks.onaddtrack = function(e) {
|
||||
videoOnaddtrack++;
|
||||
}
|
||||
|
||||
element.videoTracks.onremovetrack = function(e) {
|
||||
videoOnremovetrack++;
|
||||
}
|
||||
|
||||
element.videoTracks.onchange = function(e) {
|
||||
videoOnchange++;
|
||||
}
|
||||
|
||||
function checkTrackRemoved() {
|
||||
if (isPlaying) {
|
||||
is(audioOnremovetrack, 1, 'Calls of onremovetrack on audioTracks should be 1.');
|
||||
is(element.audioTracks.length, 0, 'The length of audioTracks should be 0.');
|
||||
is(videoOnremovetrack, 1, 'Calls of onremovetrack on videoTracks should be 1.');
|
||||
is(element.videoTracks.length, 0, 'The length of videoTracks should be 0.');
|
||||
}
|
||||
}
|
||||
|
||||
function onended() {
|
||||
ok(true, 'Event ended is expected to be fired on element.');
|
||||
checkTrackRemoved();
|
||||
element.onended = null;
|
||||
element.onplaying = null;
|
||||
element.onpause = null;
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
function checkTrackAdded() {
|
||||
isPlaying = true;
|
||||
is(audioOnaddtrack, 1, 'Calls of onaddtrack on audioTracks should be 1.');
|
||||
is(element.audioTracks.length, 1, 'The length of audioTracks should be 1.');
|
||||
ok(element.audioTracks[0].enabled, 'Audio track should be enabled as default.');
|
||||
is(videoOnaddtrack, 1, 'Calls of onaddtrack on videoTracks should be 1.');
|
||||
is(element.videoTracks.length, 1, 'The length of videoTracks should be 1.');
|
||||
is(element.videoTracks.selectedIndex, 0,
|
||||
'The first video track is set selected as default.');
|
||||
}
|
||||
|
||||
function setTrackEnabled(enabled) {
|
||||
element.audioTracks[0].enabled = enabled;
|
||||
element.videoTracks[0].selected = enabled;
|
||||
}
|
||||
|
||||
function checkTrackChanged(calls, enabled) {
|
||||
is(audioOnchange, calls, 'Calls of onchange on audioTracks should be '+calls);
|
||||
is(element.audioTracks[0].enabled, enabled,
|
||||
'Enabled value of the audio track should be ' +enabled);
|
||||
is(videoOnchange, calls, 'Calls of onchange on videoTracks should be '+calls);
|
||||
is(element.videoTracks[0].selected, enabled,
|
||||
'Selected value of the video track should be ' +enabled);
|
||||
var index = enabled ? 0 : -1;
|
||||
is(element.videoTracks.selectedIndex, index,
|
||||
'SelectedIndex of video tracks should be ' +index);
|
||||
}
|
||||
|
||||
function onpause() {
|
||||
element.onpause = null;
|
||||
if (element.ended) {
|
||||
return;
|
||||
}
|
||||
if (steps == 1) {
|
||||
setTrackEnabled(false);
|
||||
element.onplaying = onplaying;
|
||||
element.play();
|
||||
steps++;
|
||||
} else if (steps == 2) {
|
||||
setTrackEnabled(true);
|
||||
element.onplaying = onplaying;
|
||||
element.play();
|
||||
steps++;
|
||||
}
|
||||
}
|
||||
|
||||
function onplaying() {
|
||||
element.onplaying = null;
|
||||
if (element.ended) {
|
||||
return;
|
||||
}
|
||||
if (steps == 1) {
|
||||
element.onpause = onpause;
|
||||
element.pause();
|
||||
checkTrackAdded();
|
||||
} else if (steps == 2) {
|
||||
element.onpause = onpause;
|
||||
element.pause();
|
||||
checkTrackChanged(1, false);
|
||||
} else if (steps == 3) {
|
||||
checkTrackChanged(2, true);
|
||||
stream.stop();
|
||||
}
|
||||
}
|
||||
|
||||
var steps = 0;
|
||||
element.mozSrcObject = stream;
|
||||
element.onplaying = onplaying;
|
||||
element.onended = onended;
|
||||
element.play();
|
||||
steps++;
|
||||
},
|
||||
function(err) {
|
||||
ok(false, 'Unexpected error fired with: ' + err);
|
||||
SimpleTest.finish();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{
|
||||
"set": [
|
||||
["media.track.enabled", true]
|
||||
]
|
||||
}, startTest);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,125 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test events of media track interfaces</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<script type="text/javascript" src="manifest.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
function startTest() {
|
||||
navigator.mozGetUserMedia({audio:true, video:true, fake:true},
|
||||
function(stream) {
|
||||
var element = document.createElement("video");
|
||||
|
||||
isnot(element.audioTracks, undefined,
|
||||
'HTMLMediaElement::AudioTracks() property should be available.');
|
||||
isnot(element.videoTracks, undefined,
|
||||
'HTMLMediaElement::VideoTracks() property should be available.');
|
||||
|
||||
function verifyEvent(e, type) {
|
||||
is(e.type, type, "Event type should be " + type);
|
||||
ok(e.isTrusted, "Event should be trusted.");
|
||||
ok(!e.bubbles, "Event shouldn't bubble.");
|
||||
ok(!e.cancelable, "Event shouldn't be cancelable.");
|
||||
}
|
||||
|
||||
element.audioTracks.onaddtrack = function(e) {
|
||||
ok(e instanceof TrackEvent, "Event fired from onaddtrack should be a TrackEvent");
|
||||
ok(true, 'onaddtrack is expected to be called from audioTracks.');
|
||||
verifyEvent(e, "addtrack");
|
||||
}
|
||||
|
||||
element.audioTracks.onremovetrack = function(e) {
|
||||
ok(e instanceof TrackEvent, "Event fired from onremovetrack should be a TrackEvent");
|
||||
ok(true, 'onremovetrack is expected to be called from audioTracks.');
|
||||
verifyEvent(e, "removetrack");
|
||||
}
|
||||
|
||||
element.audioTracks.onchange = function(e) {
|
||||
ok(e instanceof window.Event, "Event fired from onchange should be a simple event.");
|
||||
ok(true, 'onchange is expected to be called from audioTracks.');
|
||||
verifyEvent(e, "change");
|
||||
}
|
||||
|
||||
element.videoTracks.onaddtrack = function(e) {
|
||||
ok(e instanceof TrackEvent, "Event fired from onaddtrack should be a TrackEvent");
|
||||
ok(true, 'onaddtrack is expected to be called from videoTracks.');
|
||||
verifyEvent(e, "addtrack");
|
||||
}
|
||||
|
||||
element.videoTracks.onremovetrack = function(e) {
|
||||
ok(e instanceof TrackEvent, "Event fired from onremovetrack should be a TrackEvent");
|
||||
ok(true, 'onremovetrack is expected to be called from videoTracks.');
|
||||
verifyEvent(e, "removetrack");
|
||||
}
|
||||
|
||||
element.videoTracks.onchange = function(e) {
|
||||
ok(e instanceof window.Event, "Event fired from onchange should be a simple event.");
|
||||
ok(true, 'onchange is expected to be called from videoTracks.');
|
||||
verifyEvent(e, "change");
|
||||
}
|
||||
|
||||
function onended() {
|
||||
ok(true, 'Event ended is expected to be fired on element.');
|
||||
element.onended = null;
|
||||
element.onplaying = null;
|
||||
element.onpause = null;
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
function onpause() {
|
||||
element.onpause = null;
|
||||
if (element.ended) {
|
||||
return;
|
||||
}
|
||||
if (steps == 1) {
|
||||
element.audioTracks[0].enabled = false;
|
||||
element.videoTracks[0].selected = false;
|
||||
element.onplaying = onplaying;
|
||||
element.play();
|
||||
steps++;
|
||||
}
|
||||
}
|
||||
|
||||
function onplaying() {
|
||||
element.onplaying = null;
|
||||
if (element.ended) {
|
||||
return;
|
||||
}
|
||||
if (steps == 1) {
|
||||
element.onpause = onpause;
|
||||
element.pause();
|
||||
} else if (steps == 2) {
|
||||
stream.stop();
|
||||
}
|
||||
}
|
||||
|
||||
var steps = 0;
|
||||
element.mozSrcObject = stream;
|
||||
element.onplaying = onplaying;
|
||||
element.onended = onended;
|
||||
element.play();
|
||||
steps++;
|
||||
},
|
||||
function(err) {
|
||||
ok(false, 'Unexpected error fired with: ' + err);
|
||||
SimpleTest.finish();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{
|
||||
"set": [
|
||||
["media.track.enabled", true]
|
||||
]
|
||||
}, startTest);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -1,189 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test track interfaces when consuming a MediaStream from gUM</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<script type="text/javascript" src="manifest.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
function startTest() {
|
||||
navigator.mozGetUserMedia({audio:true, video:true, fake:true},
|
||||
function(stream) {
|
||||
var audioStreamTracks = stream.getAudioTracks();
|
||||
var videoStreamTracks = stream.getVideoTracks();
|
||||
|
||||
var audioOnchange = 0;
|
||||
var audioOnaddtrack = 0;
|
||||
var audioOnremovetrack = 0;
|
||||
var videoOnchange = 0;
|
||||
var videoOnaddtrack = 0;
|
||||
var videoOnremovetrack = 0;
|
||||
|
||||
var element = document.createElement("video");
|
||||
isnot(element.audioTracks, undefined, "HTMLMediaElement::AudioTracks() property should be available.");
|
||||
isnot(element.videoTracks, undefined, "HTMLMediaElement::VideoTracks() property should be available.");
|
||||
|
||||
function verify_event(e, type) {
|
||||
is(e.type, type, "Event type should be " + type);
|
||||
ok(e.isTrusted, "Event should be trusted.");
|
||||
ok(!e.bubbles, "Event shouldn't bubble.");
|
||||
ok(!e.cancelable, "Event shouldn't be cancelable.");
|
||||
}
|
||||
|
||||
function setAudioEnabled(enabled, index) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
element.audioTracks[index].enabled = enabled;
|
||||
element.audioTracks.onchange = function(e) {
|
||||
ok(e instanceof window.Event, "Event fired from onchange should be a simple event.");
|
||||
ok(true, 'onchange is expected to be called from audioTracks.');
|
||||
verify_event(e, "change");
|
||||
audioOnchange++;
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function setVideoSelected(selected, index) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
element.videoTracks[index].selected = selected;
|
||||
element.videoTracks.onchange = function(e) {
|
||||
ok(e instanceof window.Event, "Event fired from onchange should be a simple event.");
|
||||
ok(true, 'onchange is expected to be called from videoTracks.');
|
||||
verify_event(e, "change");
|
||||
|
||||
var noVideoSelected = true;
|
||||
for (var i=0; i < element.videoTracks.length; ++i) {
|
||||
var track = element.videoTracks[i];
|
||||
if (track.selected == true) {
|
||||
noVideoSelected = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (selected) {
|
||||
is(element.videoTracks.selectedIndex, index,
|
||||
'SelectedIndex shuld be '+index+' if video track is set selected.');
|
||||
} else {
|
||||
if (noVideoSelected) {
|
||||
is(element.videoTracks.selectedIndex, -1,
|
||||
'SelectedIndex shuld be -1 if no video track is set selected.');
|
||||
} else {
|
||||
reject();
|
||||
}
|
||||
}
|
||||
videoOnchange++;
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
element.audioTracks.onaddtrack = function(e) {
|
||||
ok(e instanceof TrackEvent, "Event fired from onaddtrack should be a TrackEvent");
|
||||
ok(true, 'onaddtrack is expected to be called from audioTracks.');
|
||||
verify_event(e, "addtrack");
|
||||
audioOnaddtrack++;
|
||||
}
|
||||
|
||||
element.audioTracks.onremovetrack = function(e) {
|
||||
ok(e instanceof TrackEvent, "Event fired from onremovetrack should be a TrackEvent");
|
||||
ok(true, 'onremovetrack is expected to be called from audioTracks.');
|
||||
verify_event(e, "removetrack");
|
||||
audioOnremovetrack++;
|
||||
}
|
||||
|
||||
element.videoTracks.onaddtrack = function(e) {
|
||||
ok(e instanceof TrackEvent, "Event fired from onaddtrack should be a TrackEvent");
|
||||
ok(true, 'onaddtrack is expected to be called from videoTracks.');
|
||||
verify_event(e, "addtrack");
|
||||
videoOnaddtrack++;
|
||||
}
|
||||
|
||||
element.videoTracks.onremovetrack = function(e) {
|
||||
ok(e instanceof TrackEvent, "Event fired from onremovetrack should be a TrackEvent");
|
||||
ok(true, 'onremovetrack is expected to be called from videoTracks.');
|
||||
verify_event(e, "removetrack");
|
||||
videoOnremovetrack++;
|
||||
}
|
||||
|
||||
|
||||
element.onended = function() {
|
||||
is(audioOnchange, 2, 'change event on audioTracks should fired twice.');
|
||||
is(videoOnchange, 2, 'change event on videoTracks should fired twice.');
|
||||
|
||||
is(audioOnremovetrack, audioStreamTracks.length,
|
||||
'Calls of onremovetrack from audioTracks should match the numbers of AudioStreamTrack.');
|
||||
is(videoOnremovetrack, videoStreamTracks.length,
|
||||
'Calls of onremovetrack from videoTracks should match the numbers of VideoStreamTrack.');
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
var promise = new Promise(function(resolve, reject) {
|
||||
element.mozSrcObject = stream;
|
||||
element.play();
|
||||
|
||||
element.onloadedmetadata = function() {
|
||||
is(audioOnaddtrack, audioStreamTracks.length,
|
||||
'Calls of onaddtrack from audioTracks should match the numbers of AudioStreamTrack.');
|
||||
is(videoOnaddtrack, videoStreamTracks.length,
|
||||
'Calls of onaddtrack from videoTracks should match the numbers of VideoStreamTrack.');
|
||||
|
||||
is(element.audioTracks.length, audioStreamTracks.length,
|
||||
'Length of audioTracks should be the same as the length of AudioStreamTrack.');
|
||||
is(element.videoTracks.length, videoStreamTracks.length,
|
||||
'Length of videoTracks should be the same as the length of VideoStreamTrack.');
|
||||
|
||||
for (var i=0; i < audioStreamTracks.length; ++i) {
|
||||
var track = element.audioTracks.getTrackById(audioStreamTracks[i].id);
|
||||
isnot(track, null, 'Successfully get '+ track.id + ' from audioTracks.');
|
||||
}
|
||||
for (var i=0; i < videoStreamTracks.length; ++i) {
|
||||
var track = element.videoTracks.getTrackById(videoStreamTracks[i].id);
|
||||
isnot(track, null, 'Successfully get '+ track.id + ' from videoTracks.');
|
||||
}
|
||||
|
||||
is(element.videoTracks.selectedIndex, 0,
|
||||
'The first video track is set selected as default.');
|
||||
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
|
||||
promise.then(function() {
|
||||
var p1 = setAudioEnabled(false, 0);
|
||||
var p2 = setVideoSelected(false, 0);
|
||||
return Promise.all([p1, p2]);
|
||||
}).catch(function(err) {
|
||||
ok(false, 'Something went wrong in onchange callback.');
|
||||
}).then(function() {
|
||||
var p3 = setAudioEnabled(true, 0);
|
||||
var p4 = setVideoSelected(true, 0);
|
||||
return Promise.all([p3, p4]);
|
||||
}).catch(function(err) {
|
||||
ok(false, 'Something went wrong in onchange callback.');
|
||||
}).then(function() {
|
||||
stream.stop();
|
||||
});
|
||||
},
|
||||
function(err) {
|
||||
ok(false, 'Unexpected error fired with: ' + err);
|
||||
SimpleTest.finish();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{
|
||||
"set": [
|
||||
["media.track.enabled", true]
|
||||
]
|
||||
}, startTest);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -10,13 +10,37 @@
|
|||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
//longer timeout for sometimes B2G emulator runs very slowly
|
||||
if (SpecialPowers.Services.appinfo.name == "B2G") {
|
||||
SimpleTest.requestLongerTimeout(3);
|
||||
}
|
||||
|
||||
var manager = new MediaTestManager;
|
||||
|
||||
function localCheckMetadata(msg, e, test) {
|
||||
if (test.width) {
|
||||
is(e.videoWidth, test.width, msg + " video width");
|
||||
}
|
||||
if (test.height) {
|
||||
is(e.videoHeight, test.height, msg + " video height");
|
||||
}
|
||||
if (test.duration) {
|
||||
// see bug 1039901 for skipping mp3 duration test on B2G
|
||||
if (SpecialPowers.Services.appinfo.name == "B2G" && /mp3$/.test(test.name)) {
|
||||
todo(false, "Fix mp3 duration bug on B2G");
|
||||
return;
|
||||
}
|
||||
ok(Math.abs(e.duration - test.duration) < 0.1,
|
||||
msg + " duration (" + e.duration + ") should be around " + test.duration);
|
||||
}
|
||||
}
|
||||
|
||||
function startTest(test, token) {
|
||||
var v = document.createElement('video');
|
||||
v.preload = "metadata";
|
||||
v.token = token;
|
||||
manager.started(token);
|
||||
var checkMetadata = localCheckMetadata;
|
||||
|
||||
v.src = test.name;
|
||||
v.name = test.name;
|
||||
|
|
|
@ -34,6 +34,16 @@ which makes Windows Media Foundation unavailable.
|
|||
#include <wmcodecdsp.h>
|
||||
#include <codecapi.h>
|
||||
|
||||
// The Windows headers helpfully declare min and max macros, which don't
|
||||
// compile in the prescence of std::min and std::max and unified builds.
|
||||
// So undef them here.
|
||||
#ifdef min
|
||||
#undef min
|
||||
#endif
|
||||
#ifdef max
|
||||
#undef max
|
||||
#endif
|
||||
|
||||
// Some SDK versions don't define the AAC decoder CLSID.
|
||||
#ifndef CLSID_CMSAACDecMFT
|
||||
extern "C" const CLSID CLSID_CMSAACDecMFT;
|
||||
|
|
|
@ -168,10 +168,11 @@ public:
|
|||
|
||||
JSContext* cx() const {
|
||||
MOZ_ASSERT(mCx, "Must call Init before using an AutoJSAPI");
|
||||
MOZ_ASSERT_IF(NS_IsMainThread(), CxPusherIsStackTop());
|
||||
return mCx;
|
||||
}
|
||||
|
||||
bool CxPusherIsStackTop() { return mCxPusher.ref().IsStackTop(); }
|
||||
bool CxPusherIsStackTop() const { return mCxPusher.ref().IsStackTop(); }
|
||||
|
||||
protected:
|
||||
// Protected constructor, allowing subclasses to specify a particular cx to
|
||||
|
|
|
@ -936,8 +936,12 @@ nsJSContext::InitContext()
|
|||
nsresult
|
||||
nsJSContext::SetProperty(JS::Handle<JSObject*> aTarget, const char* aPropName, nsISupports* aArgs)
|
||||
{
|
||||
nsCxPusher pusher;
|
||||
pusher.Push(mContext);
|
||||
AutoJSAPI jsapi;
|
||||
if (NS_WARN_IF(!jsapi.InitWithLegacyErrorReporting(GetGlobalObject()))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
MOZ_ASSERT(jsapi.cx() == mContext,
|
||||
"AutoJSAPI should have found our own JSContext*");
|
||||
|
||||
JS::AutoValueVector args(mContext);
|
||||
|
||||
|
|
|
@ -12,17 +12,18 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=923010
|
|||
/** Test for Bug 923010 **/
|
||||
try {
|
||||
var conn = new mozRTCPeerConnection();
|
||||
var candidate = new mozRTCIceCandidate({candidate: null });
|
||||
try {
|
||||
conn.createAnswer(function() {
|
||||
ok(false, "The call to createAnswer succeeded when it should have thrown");
|
||||
conn.addIceCandidate(candidate, function() {
|
||||
ok(false, "The call to addIceCandidate succeeded when it should have thrown");
|
||||
}, function() {
|
||||
ok(false, "The call to createAnswer failed when it should have thrown");
|
||||
}, { "mandatory": { "BOGUS": 5 } } )
|
||||
ok(false, "That call to createAnswer should have thrown");
|
||||
ok(false, "The call to addIceCandidate failed when it should have thrown");
|
||||
})
|
||||
ok(false, "That call to addIceCandidate should have thrown");
|
||||
} catch (e) {
|
||||
is(e.lineNumber, 16, "Exception should have been on line 16");
|
||||
is(e.lineNumber, 17, "Exception should have been on line 17");
|
||||
is(e.message,
|
||||
"createAnswer passed invalid constraints - unknown mandatory constraint: BOGUS",
|
||||
"Invalid candidate passed to addIceCandidate!",
|
||||
"Should have the exception we expect");
|
||||
}
|
||||
} catch (e) {
|
||||
|
|
|
@ -5,9 +5,10 @@
|
|||
|
||||
#include "domstubs.idl"
|
||||
|
||||
interface nsIDocument;
|
||||
interface nsIURI;
|
||||
|
||||
[uuid(6117cdf1-cb10-42a3-9901-4f1bab7ffa4d)]
|
||||
[uuid(6e1382f4-3cbc-435f-8ce0-70175f6eb400)]
|
||||
interface nsIServiceWorkerManager : nsISupports
|
||||
{
|
||||
// Returns a Promise
|
||||
|
@ -20,6 +21,21 @@ interface nsIServiceWorkerManager : nsISupports
|
|||
[noscript] void AddContainerEventListener(in nsIURI aPageURI, in nsIDOMEventTarget aTarget);
|
||||
[noscript] void RemoveContainerEventListener(in nsIURI aPageURI, in nsIDOMEventTarget aTarget);
|
||||
|
||||
/**
|
||||
* Call this to request that document `aDoc` be controlled by a ServiceWorker
|
||||
* if a registration exists for it's scope.
|
||||
*
|
||||
* This MUST only be called once per document!
|
||||
*/
|
||||
[notxpcom,nostdcall] void MaybeStartControlling(in nsIDocument aDoc);
|
||||
|
||||
/**
|
||||
* Documents that have called MaybeStartControlling() should call this when
|
||||
* they are destroyed. This function may be called multiple times, and is
|
||||
* idempotent.
|
||||
*/
|
||||
[notxpcom,nostdcall] void MaybeStopControlling(in nsIDocument aDoc);
|
||||
|
||||
// Testing
|
||||
DOMString getScopeForUrl(in DOMString path);
|
||||
};
|
||||
|
|
|
@ -42,6 +42,7 @@ function GlobalPCList() {
|
|||
Services.obs.addObserver(this, "profile-change-net-teardown", true);
|
||||
Services.obs.addObserver(this, "network:offline-about-to-go-offline", true);
|
||||
Services.obs.addObserver(this, "network:offline-status-changed", true);
|
||||
Services.obs.addObserver(this, "gmp-plugin-crash", true);
|
||||
}
|
||||
GlobalPCList.prototype = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
|
||||
|
@ -107,6 +108,27 @@ GlobalPCList.prototype = {
|
|||
}
|
||||
};
|
||||
|
||||
let hasPluginId = function(list, winID, pluginID, name, crashReport) {
|
||||
if (list.hasOwnProperty(winID)) {
|
||||
list[winID].forEach(function(pcref) {
|
||||
let pc = pcref.get();
|
||||
if (pc) {
|
||||
if (pc._pc.pluginCrash(pluginID)) {
|
||||
// Notify DOM window of the crash
|
||||
let event = new CustomEvent("PluginCrashed",
|
||||
{ bubbles: false, cancelable: false,
|
||||
detail: {
|
||||
pluginName: name,
|
||||
pluginDumpId: crashReport,
|
||||
submittedCrashReport: false }
|
||||
});
|
||||
pc._win.dispatchEvent(event);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
if (topic == "inner-window-destroyed") {
|
||||
let winID = subject.QueryInterface(Ci.nsISupportsPRUint64).data;
|
||||
cleanupWinId(this._list, winID);
|
||||
|
@ -134,6 +156,19 @@ GlobalPCList.prototype = {
|
|||
} else if (data == "online") {
|
||||
this._networkdown = false;
|
||||
}
|
||||
} else if (topic == "gmp-plugin-crash") {
|
||||
// a plugin crashed; if it's associated with any of our PCs, fire an
|
||||
// event to the DOM window
|
||||
let sep = data.indexOf(' ');
|
||||
let pluginId = data.slice(0, sep);
|
||||
let rest = data.slice(sep+1);
|
||||
// This presumes no spaces in the name!
|
||||
sep = rest.indexOf(' ');
|
||||
let name = rest.slice(0, sep);
|
||||
let crashId = rest.slice(sep+1);
|
||||
for (let winId in this._list) {
|
||||
hasPluginId(this._list, winId, pluginId, name, crashId);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -465,50 +500,6 @@ RTCPeerConnection.prototype = {
|
|||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* MediaConstraints look like this:
|
||||
*
|
||||
* {
|
||||
* mandatory: {"OfferToReceiveAudio": true, "OfferToReceiveVideo": true },
|
||||
* optional: [{"VoiceActivityDetection": true}, {"FooBar": 10}]
|
||||
* }
|
||||
*
|
||||
* WebIDL normalizes the top structure for us, but the mandatory constraints
|
||||
* member comes in as a raw object so we can detect unknown constraints. We
|
||||
* compare its members against ones we support, and fail if not found.
|
||||
*/
|
||||
_mustValidateConstraints: function(constraints, errorMsg) {
|
||||
if (constraints.mandatory) {
|
||||
let supported;
|
||||
try {
|
||||
// Passing the raw constraints.mandatory here validates its structure
|
||||
supported = this._observer.getSupportedConstraints(constraints.mandatory);
|
||||
} catch (e) {
|
||||
throw new this._win.DOMError("", errorMsg + " - " + e.message);
|
||||
}
|
||||
|
||||
for (let constraint of Object.keys(constraints.mandatory)) {
|
||||
if (!(constraint in supported)) {
|
||||
throw new this._win.DOMError("",
|
||||
errorMsg + " - unknown mandatory constraint: " + constraint);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (constraints.optional) {
|
||||
let len = constraints.optional.length;
|
||||
for (let i = 0; i < len; i++) {
|
||||
let constraints_per_entry = 0;
|
||||
for (let constraint in Object.keys(constraints.optional[i])) {
|
||||
if (constraints_per_entry) {
|
||||
throw new this._win.DOMError("", errorMsg +
|
||||
" - optional constraint must be single key/value pair");
|
||||
}
|
||||
constraints_per_entry += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Ideally, this should be of the form _checkState(state),
|
||||
// where the state is taken from an enumeration containing
|
||||
// the valid peer connection states defined in the WebRTC
|
||||
|
@ -574,26 +565,22 @@ RTCPeerConnection.prototype = {
|
|||
});
|
||||
},
|
||||
|
||||
createOffer: function(onSuccess, onError, constraints) {
|
||||
if (!constraints) {
|
||||
constraints = {};
|
||||
}
|
||||
this._mustValidateConstraints(constraints, "createOffer passed invalid constraints");
|
||||
|
||||
createOffer: function(onSuccess, onError, options) {
|
||||
options = options || {};
|
||||
this._queueOrRun({
|
||||
func: this._createOffer,
|
||||
args: [onSuccess, onError, constraints],
|
||||
args: [onSuccess, onError, options],
|
||||
wait: true
|
||||
});
|
||||
},
|
||||
|
||||
_createOffer: function(onSuccess, onError, constraints) {
|
||||
_createOffer: function(onSuccess, onError, options) {
|
||||
this._onCreateOfferSuccess = onSuccess;
|
||||
this._onCreateOfferFailure = onError;
|
||||
this._impl.createOffer(constraints);
|
||||
this._impl.createOffer(options);
|
||||
},
|
||||
|
||||
_createAnswer: function(onSuccess, onError, constraints, provisional) {
|
||||
_createAnswer: function(onSuccess, onError) {
|
||||
this._onCreateAnswerSuccess = onSuccess;
|
||||
this._onCreateAnswerFailure = onError;
|
||||
|
||||
|
@ -610,26 +597,13 @@ RTCPeerConnection.prototype = {
|
|||
"No outstanding offer");
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Implement provisional answer.
|
||||
|
||||
this._impl.createAnswer(constraints);
|
||||
this._impl.createAnswer();
|
||||
},
|
||||
|
||||
createAnswer: function(onSuccess, onError, constraints, provisional) {
|
||||
if (!constraints) {
|
||||
constraints = {};
|
||||
}
|
||||
|
||||
this._mustValidateConstraints(constraints, "createAnswer passed invalid constraints");
|
||||
|
||||
if (!provisional) {
|
||||
provisional = false;
|
||||
}
|
||||
|
||||
createAnswer: function(onSuccess, onError) {
|
||||
this._queueOrRun({
|
||||
func: this._createAnswer,
|
||||
args: [onSuccess, onError, constraints, provisional],
|
||||
args: [onSuccess, onError],
|
||||
wait: true
|
||||
});
|
||||
},
|
||||
|
@ -794,7 +768,7 @@ RTCPeerConnection.prototype = {
|
|||
gotAssertion);
|
||||
},
|
||||
|
||||
updateIce: function(config, constraints) {
|
||||
updateIce: function(config) {
|
||||
throw new this._win.DOMError("", "updateIce not yet implemented");
|
||||
},
|
||||
|
||||
|
@ -815,22 +789,17 @@ RTCPeerConnection.prototype = {
|
|||
cand.sdpMLineIndex + 1);
|
||||
},
|
||||
|
||||
addStream: function(stream, constraints) {
|
||||
if (!constraints) {
|
||||
constraints = {};
|
||||
}
|
||||
this._mustValidateConstraints(constraints,
|
||||
"addStream passed invalid constraints");
|
||||
addStream: function(stream) {
|
||||
if (stream.currentTime === undefined) {
|
||||
throw new this._win.DOMError("", "Invalid stream passed to addStream!");
|
||||
}
|
||||
this._queueOrRun({ func: this._addStream,
|
||||
args: [stream, constraints],
|
||||
args: [stream],
|
||||
wait: false });
|
||||
},
|
||||
|
||||
_addStream: function(stream, constraints) {
|
||||
this._impl.addStream(stream, constraints);
|
||||
_addStream: function(stream) {
|
||||
this._impl.addStream(stream);
|
||||
},
|
||||
|
||||
removeStream: function(stream) {
|
||||
|
@ -1293,11 +1262,7 @@ PeerConnectionObserver.prototype = {
|
|||
notifyDataChannel: function(channel) {
|
||||
this.dispatchEvent(new this._dompc._win.RTCDataChannelEvent("datachannel",
|
||||
{ channel: channel }));
|
||||
},
|
||||
|
||||
getSupportedConstraints: function(dict) {
|
||||
return dict;
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
function RTCPeerConnectionStatic() {
|
||||
|
|
|
@ -759,10 +759,10 @@ function PCT_setMediaConstraints(constraintsLocal, constraintsRemote) {
|
|||
*
|
||||
* @param {object} constraints the media constraints to use on createOffer
|
||||
*/
|
||||
PeerConnectionTest.prototype.setOfferConstraints =
|
||||
function PCT_setOfferConstraints(constraints) {
|
||||
PeerConnectionTest.prototype.setOfferOptions =
|
||||
function PCT_setOfferOptions(options) {
|
||||
if (this.pcLocal)
|
||||
this.pcLocal.offerConstraints = constraints;
|
||||
this.pcLocal.offerOptions = options;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1362,7 +1362,7 @@ function PeerConnectionWrapper(label, configuration, h264) {
|
|||
this.whenCreated = Date.now();
|
||||
|
||||
this.constraints = [ ];
|
||||
this.offerConstraints = {};
|
||||
this.offerOptions = {};
|
||||
this.streams = [ ];
|
||||
this.mediaCheckers = [ ];
|
||||
|
||||
|
@ -1637,7 +1637,7 @@ PeerConnectionWrapper.prototype = {
|
|||
offer.sdp = removeVP8(offer.sdp);
|
||||
}
|
||||
onSuccess(offer);
|
||||
}, generateErrorCallback(), this.offerConstraints);
|
||||
}, generateErrorCallback(), this.offerOptions);
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
var pc = new mozRTCPeerConnection();
|
||||
|
||||
// necessary to circumvent bug 864109
|
||||
var options = { mandatory: { OfferToReceiveAudio: true} };
|
||||
var options = { offerToReceiveAudio: true };
|
||||
|
||||
pc.createOffer(function (offer) {
|
||||
ok(!offer.sdp.contains("m=application"),
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
});
|
||||
}, function (err) {
|
||||
croak("createOffer failed: " + err);
|
||||
}, { mandatory: { OfferToReceiveAudio: true} });
|
||||
}, { offerToReceiveAudio: true });
|
||||
});
|
||||
</script>
|
||||
</pre>
|
||||
|
|
|
@ -32,24 +32,15 @@
|
|||
ok(!exception, "createOffer(step1, failed, {}) succeeds");
|
||||
exception = null;
|
||||
try {
|
||||
pconnect.createOffer(step1, failed, { mandatory: { FooBar: true } });
|
||||
pconnect.updateIce();
|
||||
} catch (e) {
|
||||
ok(e.message.indexOf("FooBar") > 0, "createOffer has readable exceptions");
|
||||
ok(e.message.indexOf("updateIce") >= 0, "PeerConnection.js has readable exceptions");
|
||||
exception = e;
|
||||
}
|
||||
ok(exception, "createOffer(step1, failed, { mandatory: { FooBar: true } }) throws");
|
||||
ok(exception, "updateIce not yet implemented and throws");
|
||||
exception = null;
|
||||
try { pconnects.createOffer(step1, failed, { optional: [] }); } catch (e) { exception = e; }
|
||||
ok(!exception, "createOffer(step1, failed, { optional: [] }) succeeds");
|
||||
exception = null;
|
||||
try { pconnect.createOffer(step1, failed, { optional: [1] }); } catch (e) { exception = e; }
|
||||
ok(exception, "createOffer(step1, failed, { optional: [1] }) throws");
|
||||
exception = null;
|
||||
try { pconnect.createOffer(step1, failed, { optional: [{ OfferToReceiveVideo: false, OfferToReceiveAudio: true, }] }); } catch (e) { exception = e; }
|
||||
ok(exception, "createOffer(step1, failed, { optional: [{ OfferToReceiveVideo: false, OfferToReceiveAudio: true, }] }) throws");
|
||||
exception = null;
|
||||
try { pconnects.createOffer(step1, failed, { mandatory: { OfferToReceiveVideo: false, OfferToReceiveAudio: true, MozDontOfferDataChannel: true}, optional: [{ VoiceActivityDetection: true }, { FooBar: "42" }] }); } catch (e) { exception = e; }
|
||||
ok(!exception, "createOffer(step1, failed, { mandatory: { OfferToReceiveVideo: false, OfferToReceiveAudio: true, MozDontOfferDataChannel: true}, optional: [{ VoiceActivityDetection: true }, { FooBar: \"42\" }] }) succeeds");
|
||||
try { pconnects.createOffer(step1, failed, { offerToReceiveVideo: false, offerToReceiveAudio: true, MozDontOfferDataChannel: true }); } catch (e) { exception = e; }
|
||||
ok(!exception, "createOffer(step1, failed, { offerToReceiveVideo: false, offerToReceiveAudio: true, MozDontOfferDataChannel: true }) succeeds");
|
||||
pconnect.close();
|
||||
pconnects.close();
|
||||
pconnect = null;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<!DOCTYPE HTML>
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
|
@ -18,7 +18,7 @@
|
|||
|
||||
runNetworkTest(function() {
|
||||
var test = new PeerConnectionTest();
|
||||
test.setOfferConstraints({ mandatory: { OfferToReceiveAudio: true } });
|
||||
test.setOfferOptions({ offerToReceiveAudio: true });
|
||||
test.run();
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<!DOCTYPE HTML>
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
|
@ -18,7 +18,7 @@
|
|||
|
||||
runNetworkTest(function() {
|
||||
var test = new PeerConnectionTest();
|
||||
test.setOfferConstraints({ mandatory: { OfferToReceiveVideo: true } });
|
||||
test.setOfferOptions({ offerToReceiveVideo: true });
|
||||
test.run();
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<!DOCTYPE HTML>
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
|
@ -18,10 +18,10 @@
|
|||
|
||||
runNetworkTest(function() {
|
||||
var test = new PeerConnectionTest();
|
||||
test.setOfferConstraints({ mandatory: {
|
||||
OfferToReceiveVideo: true,
|
||||
OfferToReceiveAudio: true
|
||||
}});
|
||||
test.setOfferOptions({
|
||||
offerToReceiveVideo: true,
|
||||
offerToReceiveAudio: true
|
||||
});
|
||||
test.run();
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "nsWrapperCacheInlines.h"
|
||||
#include "js/HashTable.h"
|
||||
#include "mozilla/HashFunctions.h"
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
|
||||
|
||||
#define NPRUNTIME_JSCLASS_NAME "NPObject JS wrapper class"
|
||||
|
@ -291,8 +292,8 @@ namespace mozilla {
|
|||
namespace plugins {
|
||||
namespace parent {
|
||||
|
||||
JSContext *
|
||||
GetJSContext(NPP npp)
|
||||
static nsIGlobalObject*
|
||||
GetGlobalObject(NPP npp)
|
||||
{
|
||||
NS_ENSURE_TRUE(npp, nullptr);
|
||||
|
||||
|
@ -306,8 +307,13 @@ GetJSContext(NPP npp)
|
|||
owner->GetDocument(getter_AddRefs(doc));
|
||||
NS_ENSURE_TRUE(doc, nullptr);
|
||||
|
||||
nsCOMPtr<nsISupports> documentContainer = doc->GetContainer();
|
||||
nsCOMPtr<nsIScriptGlobalObject> sgo(do_GetInterface(documentContainer));
|
||||
return doc->GetScopeObject();
|
||||
}
|
||||
|
||||
JSContext *
|
||||
GetJSContext(NPP npp)
|
||||
{
|
||||
nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(GetGlobalObject(npp));
|
||||
NS_ENSURE_TRUE(sgo, nullptr);
|
||||
|
||||
nsIScriptContext *scx = sgo->GetContext();
|
||||
|
@ -571,11 +577,11 @@ bool
|
|||
nsJSObjWrapper::NP_HasMethod(NPObject *npobj, NPIdentifier id)
|
||||
{
|
||||
NPP npp = NPPStack::Peek();
|
||||
JSContext *cx = GetJSContext(npp);
|
||||
|
||||
if (!cx) {
|
||||
dom::AutoJSAPI jsapi;
|
||||
if (NS_WARN_IF(!jsapi.InitWithLegacyErrorReporting(GetGlobalObject(npp)))) {
|
||||
return false;
|
||||
}
|
||||
JSContext *cx = jsapi.cx();
|
||||
|
||||
if (!npobj) {
|
||||
ThrowJSException(cx,
|
||||
|
@ -586,8 +592,6 @@ nsJSObjWrapper::NP_HasMethod(NPObject *npobj, NPIdentifier id)
|
|||
|
||||
nsJSObjWrapper *npjsobj = (nsJSObjWrapper *)npobj;
|
||||
|
||||
nsCxPusher pusher;
|
||||
pusher.Push(cx);
|
||||
JSAutoCompartment ac(cx, npjsobj->mJSObj);
|
||||
|
||||
AutoJSExceptionReporter reporter(cx);
|
||||
|
@ -696,11 +700,11 @@ bool
|
|||
nsJSObjWrapper::NP_HasProperty(NPObject *npobj, NPIdentifier npid)
|
||||
{
|
||||
NPP npp = NPPStack::Peek();
|
||||
JSContext *cx = GetJSContext(npp);
|
||||
|
||||
if (!cx) {
|
||||
dom::AutoJSAPI jsapi;
|
||||
if (NS_WARN_IF(!jsapi.InitWithLegacyErrorReporting(GetGlobalObject(npp)))) {
|
||||
return false;
|
||||
}
|
||||
JSContext *cx = jsapi.cx();
|
||||
|
||||
if (!npobj) {
|
||||
ThrowJSException(cx,
|
||||
|
@ -712,8 +716,6 @@ nsJSObjWrapper::NP_HasProperty(NPObject *npobj, NPIdentifier npid)
|
|||
nsJSObjWrapper *npjsobj = (nsJSObjWrapper *)npobj;
|
||||
bool found, ok = false;
|
||||
|
||||
nsCxPusher pusher;
|
||||
pusher.Push(cx);
|
||||
AutoJSExceptionReporter reporter(cx);
|
||||
JS::Rooted<JSObject*> jsobj(cx, npjsobj->mJSObj);
|
||||
JSAutoCompartment ac(cx, jsobj);
|
||||
|
@ -799,11 +801,11 @@ bool
|
|||
nsJSObjWrapper::NP_RemoveProperty(NPObject *npobj, NPIdentifier npid)
|
||||
{
|
||||
NPP npp = NPPStack::Peek();
|
||||
JSContext *cx = GetJSContext(npp);
|
||||
|
||||
if (!cx) {
|
||||
dom::AutoJSAPI jsapi;
|
||||
if (NS_WARN_IF(!jsapi.InitWithLegacyErrorReporting(GetGlobalObject(npp)))) {
|
||||
return false;
|
||||
}
|
||||
JSContext *cx = jsapi.cx();
|
||||
|
||||
if (!npobj) {
|
||||
ThrowJSException(cx,
|
||||
|
@ -815,8 +817,6 @@ nsJSObjWrapper::NP_RemoveProperty(NPObject *npobj, NPIdentifier npid)
|
|||
nsJSObjWrapper *npjsobj = (nsJSObjWrapper *)npobj;
|
||||
bool ok = false;
|
||||
|
||||
nsCxPusher pusher;
|
||||
pusher.Push(cx);
|
||||
AutoJSExceptionReporter reporter(cx);
|
||||
bool deleted = false;
|
||||
JS::Rooted<JSObject*> obj(cx, npjsobj->mJSObj);
|
||||
|
@ -850,15 +850,15 @@ nsJSObjWrapper::NP_Enumerate(NPObject *npobj, NPIdentifier **idarray,
|
|||
uint32_t *count)
|
||||
{
|
||||
NPP npp = NPPStack::Peek();
|
||||
JSContext *cx = GetJSContext(npp);
|
||||
dom::AutoJSAPI jsapi;
|
||||
if (NS_WARN_IF(!jsapi.InitWithLegacyErrorReporting(GetGlobalObject(npp)))) {
|
||||
return false;
|
||||
}
|
||||
JSContext *cx = jsapi.cx();
|
||||
|
||||
*idarray = 0;
|
||||
*count = 0;
|
||||
|
||||
if (!cx) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!npobj) {
|
||||
ThrowJSException(cx,
|
||||
"Null npobj in nsJSObjWrapper::NP_Enumerate!");
|
||||
|
@ -868,8 +868,6 @@ nsJSObjWrapper::NP_Enumerate(NPObject *npobj, NPIdentifier **idarray,
|
|||
|
||||
nsJSObjWrapper *npjsobj = (nsJSObjWrapper *)npobj;
|
||||
|
||||
nsCxPusher pusher;
|
||||
pusher.Push(cx);
|
||||
AutoJSExceptionReporter reporter(cx);
|
||||
JS::Rooted<JSObject*> jsobj(cx, npjsobj->mJSObj);
|
||||
JSAutoCompartment ac(cx, jsobj);
|
||||
|
|
|
@ -25,9 +25,9 @@ interface PeerConnectionImpl {
|
|||
nsISupports thread);
|
||||
/* JSEP calls */
|
||||
[Throws]
|
||||
void createOffer(optional MediaConstraintsInternal constraints);
|
||||
void createOffer(optional RTCOfferOptions options);
|
||||
[Throws]
|
||||
void createAnswer(optional MediaConstraintsInternal constraints);
|
||||
void createAnswer();
|
||||
[Throws]
|
||||
void setLocalDescription(long action, DOMString sdp);
|
||||
[Throws]
|
||||
|
@ -40,8 +40,7 @@ interface PeerConnectionImpl {
|
|||
|
||||
/* Adds the stream created by GetUserMedia */
|
||||
[Throws]
|
||||
void addStream(MediaStream stream,
|
||||
optional MediaConstraintsInternal constraints);
|
||||
void addStream(MediaStream stream);
|
||||
[Throws]
|
||||
void removeStream(MediaStream stream);
|
||||
[Throws]
|
||||
|
@ -61,6 +60,9 @@ interface PeerConnectionImpl {
|
|||
/* Puts the SIPCC engine back to 'kIdle', shuts down threads, deletes state */
|
||||
void close();
|
||||
|
||||
/* Notify DOM window if this plugin crash is ours */
|
||||
boolean pluginCrash(unsigned long pluginId);
|
||||
|
||||
/* Attributes */
|
||||
readonly attribute DOMString fingerprint;
|
||||
readonly attribute DOMString localDescription;
|
||||
|
|
|
@ -39,9 +39,4 @@ interface PeerConnectionObserver
|
|||
void onRemoveStream();
|
||||
void onAddTrack();
|
||||
void onRemoveTrack();
|
||||
|
||||
/* Helper function to access supported constraints defined in webidl. Needs to
|
||||
* be in a separate webidl object we hold, so putting it here was convenient.
|
||||
*/
|
||||
MediaConstraintSet getSupportedConstraints(optional MediaConstraintSet constraints);
|
||||
};
|
||||
|
|
|
@ -52,33 +52,13 @@ dictionary RTCDataChannelInit {
|
|||
unsigned short stream; // now id
|
||||
};
|
||||
|
||||
// Misnomer dictionaries housing PeerConnection-specific constraints.
|
||||
//
|
||||
// Important! Do not ever add members that might need tracing (e.g. object)
|
||||
// to MediaConstraintSet or any dictionary marked XxxInternal here
|
||||
|
||||
dictionary MediaConstraintSet {
|
||||
boolean OfferToReceiveAudio;
|
||||
boolean OfferToReceiveVideo;
|
||||
dictionary RTCOfferOptions {
|
||||
long offerToReceiveVideo;
|
||||
long offerToReceiveAudio;
|
||||
boolean MozDontOfferDataChannel;
|
||||
boolean MozBundleOnly;
|
||||
};
|
||||
|
||||
// MediaConstraint = single-property-subset of MediaConstraintSet
|
||||
// Implemented as full set. Test Object.keys(pair).length == 1
|
||||
|
||||
// typedef MediaConstraintSet MediaConstraint; // TODO: Bug 913053
|
||||
|
||||
dictionary MediaConstraints {
|
||||
object mandatory; // so we can see unknown + unsupported constraints
|
||||
sequence<MediaConstraintSet> _optional; // a.k.a. MediaConstraint
|
||||
};
|
||||
|
||||
dictionary MediaConstraintsInternal {
|
||||
MediaConstraintSet mandatory; // holds only supported constraints
|
||||
sequence<MediaConstraintSet> _optional; // a.k.a. MediaConstraint
|
||||
};
|
||||
|
||||
interface RTCDataChannel;
|
||||
|
||||
[Pref="media.peerconnection.enabled",
|
||||
|
@ -95,10 +75,9 @@ interface mozRTCPeerConnection : EventTarget {
|
|||
void getIdentityAssertion();
|
||||
void createOffer (RTCSessionDescriptionCallback successCallback,
|
||||
RTCPeerConnectionErrorCallback failureCallback,
|
||||
optional MediaConstraints constraints);
|
||||
optional RTCOfferOptions options);
|
||||
void createAnswer (RTCSessionDescriptionCallback successCallback,
|
||||
RTCPeerConnectionErrorCallback failureCallback,
|
||||
optional MediaConstraints constraints);
|
||||
RTCPeerConnectionErrorCallback failureCallback);
|
||||
void setLocalDescription (mozRTCSessionDescription description,
|
||||
optional VoidFunction successCallback,
|
||||
optional RTCPeerConnectionErrorCallback failureCallback);
|
||||
|
@ -108,8 +87,7 @@ interface mozRTCPeerConnection : EventTarget {
|
|||
readonly attribute mozRTCSessionDescription? localDescription;
|
||||
readonly attribute mozRTCSessionDescription? remoteDescription;
|
||||
readonly attribute RTCSignalingState signalingState;
|
||||
void updateIce (optional RTCConfiguration configuration,
|
||||
optional MediaConstraints constraints);
|
||||
void updateIce (optional RTCConfiguration configuration);
|
||||
void addIceCandidate (mozRTCIceCandidate candidate,
|
||||
optional VoidFunction successCallback,
|
||||
optional RTCPeerConnectionErrorCallback failureCallback);
|
||||
|
@ -121,10 +99,11 @@ interface mozRTCPeerConnection : EventTarget {
|
|||
[ChromeOnly]
|
||||
readonly attribute DOMString id;
|
||||
|
||||
RTCConfiguration getConfiguration ();
|
||||
sequence<MediaStream> getLocalStreams ();
|
||||
sequence<MediaStream> getRemoteStreams ();
|
||||
MediaStream? getStreamById (DOMString streamId);
|
||||
void addStream (MediaStream stream, optional MediaConstraints constraints);
|
||||
void addStream (MediaStream stream);
|
||||
void removeStream (MediaStream stream);
|
||||
void close ();
|
||||
attribute EventHandler onnegotiationneeded;
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
|
||||
#include "jsapi.h"
|
||||
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/dom/DOMError.h"
|
||||
#include "mozilla/dom/ErrorEvent.h"
|
||||
|
@ -299,12 +298,15 @@ FinishFetchOnMainThreadRunnable::Run()
|
|||
}
|
||||
|
||||
ServiceWorkerRegistration::ServiceWorkerRegistration(const nsACString& aScope)
|
||||
: mScope(aScope),
|
||||
: mControlledDocumentsCounter(0),
|
||||
mScope(aScope),
|
||||
mPendingUninstall(false)
|
||||
{ }
|
||||
|
||||
ServiceWorkerRegistration::~ServiceWorkerRegistration()
|
||||
{ }
|
||||
{
|
||||
MOZ_ASSERT(!IsControllingDocuments());
|
||||
}
|
||||
|
||||
//////////////////////////
|
||||
// ServiceWorkerManager //
|
||||
|
@ -360,18 +362,16 @@ public:
|
|||
NS_IMETHODIMP
|
||||
Run()
|
||||
{
|
||||
nsCString domain;
|
||||
nsresult rv = mScriptURI->GetHost(domain);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
mPromise->MaybeReject(rv);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsRefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||
nsRefPtr<ServiceWorkerManager::ServiceWorkerDomainInfo> domainInfo;
|
||||
// XXXnsm: This pattern can be refactored if we end up using it
|
||||
// often enough.
|
||||
if (!swm->mDomainMap.Get(domain, getter_AddRefs(domainInfo))) {
|
||||
nsRefPtr<ServiceWorkerManager::ServiceWorkerDomainInfo> domainInfo = swm->GetDomainInfo(mScriptURI);
|
||||
if (!domainInfo) {
|
||||
nsCString domain;
|
||||
nsresult rv = mScriptURI->GetHost(domain);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
mPromise->MaybeReject(rv);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
domainInfo = new ServiceWorkerManager::ServiceWorkerDomainInfo;
|
||||
swm->mDomainMap.Put(domain, domainInfo);
|
||||
}
|
||||
|
@ -380,7 +380,7 @@ public:
|
|||
domainInfo->GetRegistration(mScope);
|
||||
|
||||
nsCString spec;
|
||||
rv = mScriptURI->GetSpec(spec);
|
||||
nsresult rv = mScriptURI->GetSpec(spec);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
mPromise->MaybeReject(rv);
|
||||
return NS_OK;
|
||||
|
@ -399,12 +399,12 @@ public:
|
|||
// There is no update in progress and since SW updating is upto the UA,
|
||||
// we will not update right now. Simply resolve with whatever worker we
|
||||
// have.
|
||||
ServiceWorkerInfo info = registration->Newest();
|
||||
if (info.IsValid()) {
|
||||
nsRefPtr<ServiceWorkerInfo> info = registration->Newest();
|
||||
if (info) {
|
||||
nsRefPtr<ServiceWorker> serviceWorker;
|
||||
nsresult rv =
|
||||
swm->CreateServiceWorkerForWindow(mWindow,
|
||||
info.GetScriptSpec(),
|
||||
info->GetScriptSpec(),
|
||||
registration->mScope,
|
||||
getter_AddRefs(serviceWorker));
|
||||
|
||||
|
@ -563,14 +563,14 @@ ServiceWorkerManager::Update(ServiceWorkerRegistration* aRegistration,
|
|||
aRegistration->mUpdateInstance = nullptr;
|
||||
}
|
||||
|
||||
if (aRegistration->mInstallingWorker.IsValid()) {
|
||||
if (aRegistration->mInstallingWorker) {
|
||||
// FIXME(nsm): Terminate the worker. We still haven't figured out worker
|
||||
// instance ownership when not associated with a window, so let's wait on
|
||||
// this.
|
||||
// FIXME(nsm): We should be setting the state on the actual worker
|
||||
// instance.
|
||||
// FIXME(nsm): Fire "statechange" on installing worker instance.
|
||||
aRegistration->mInstallingWorker.Invalidate();
|
||||
aRegistration->mInstallingWorker = nullptr;
|
||||
}
|
||||
|
||||
aRegistration->mUpdatePromise = new UpdatePromise();
|
||||
|
@ -657,7 +657,7 @@ ServiceWorkerManager::FinishFetch(ServiceWorkerRegistration* aRegistration,
|
|||
|
||||
ResolveRegisterPromises(aRegistration, aRegistration->mScriptSpec);
|
||||
|
||||
ServiceWorkerInfo info(aRegistration->mScriptSpec);
|
||||
nsRefPtr<ServiceWorkerInfo> info = new ServiceWorkerInfo(aRegistration->mScriptSpec);
|
||||
Install(aRegistration, info);
|
||||
}
|
||||
|
||||
|
@ -680,14 +680,8 @@ ServiceWorkerManager::HandleError(JSContext* aCx,
|
|||
return;
|
||||
}
|
||||
|
||||
nsCString domain;
|
||||
rv = uri->GetHost(domain);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<ServiceWorkerDomainInfo> domainInfo;
|
||||
if (!mDomainMap.Get(domain, getter_AddRefs(domainInfo))) {
|
||||
nsRefPtr<ServiceWorkerDomainInfo> domainInfo = GetDomainInfo(uri);
|
||||
if (!domainInfo) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -760,7 +754,7 @@ public:
|
|||
AssertIsOnMainThread();
|
||||
// FIXME(nsm): Change installing worker state to redundant.
|
||||
// FIXME(nsm): Fire statechange.
|
||||
mRegistration->mInstallingWorker.Invalidate();
|
||||
mRegistration->mInstallingWorker = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
|
@ -881,7 +875,7 @@ private:
|
|||
|
||||
void
|
||||
ServiceWorkerManager::Install(ServiceWorkerRegistration* aRegistration,
|
||||
ServiceWorkerInfo aServiceWorkerInfo)
|
||||
ServiceWorkerInfo* aServiceWorkerInfo)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
aRegistration->mInstallingWorker = aServiceWorkerInfo;
|
||||
|
@ -891,12 +885,12 @@ ServiceWorkerManager::Install(ServiceWorkerRegistration* aRegistration,
|
|||
|
||||
nsRefPtr<ServiceWorker> serviceWorker;
|
||||
nsresult rv =
|
||||
CreateServiceWorker(aServiceWorkerInfo.GetScriptSpec(),
|
||||
CreateServiceWorker(aServiceWorkerInfo->GetScriptSpec(),
|
||||
aRegistration->mScope,
|
||||
getter_AddRefs(serviceWorker));
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
aRegistration->mInstallingWorker.Invalidate();
|
||||
aRegistration->mInstallingWorker = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -936,12 +930,11 @@ ServiceWorkerManager::FinishInstall(ServiceWorkerRegistration* aRegistration)
|
|||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
if (aRegistration->mWaitingWorker.IsValid()) {
|
||||
if (aRegistration->mWaitingWorker) {
|
||||
// FIXME(nsm): Actually update the state of active ServiceWorker instances.
|
||||
}
|
||||
|
||||
aRegistration->mWaitingWorker = aRegistration->mInstallingWorker;
|
||||
aRegistration->mInstallingWorker.Invalidate();
|
||||
aRegistration->mWaitingWorker = aRegistration->mInstallingWorker.forget();
|
||||
|
||||
// FIXME(nsm): Actually update state of active ServiceWorker instances to
|
||||
// installed.
|
||||
|
@ -995,8 +988,8 @@ ServiceWorkerManager::CreateServiceWorkerForWindow(nsPIDOMWindow* aWindow,
|
|||
already_AddRefed<ServiceWorkerRegistration>
|
||||
ServiceWorkerManager::GetServiceWorkerRegistration(nsPIDOMWindow* aWindow)
|
||||
{
|
||||
nsCOMPtr<nsIURI> documentURI = aWindow->GetDocumentURI();
|
||||
return GetServiceWorkerRegistration(documentURI);
|
||||
nsCOMPtr<nsIDocument> document = aWindow->GetExtantDoc();
|
||||
return GetServiceWorkerRegistration(document);
|
||||
}
|
||||
|
||||
already_AddRefed<ServiceWorkerRegistration>
|
||||
|
@ -1158,6 +1151,53 @@ ServiceWorkerManager::GetDomainInfo(const nsCString& aURL)
|
|||
return GetDomainInfo(uri);
|
||||
}
|
||||
|
||||
void
|
||||
ServiceWorkerManager::MaybeStartControlling(nsIDocument* aDoc)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
if (!Preferences::GetBool("dom.serviceWorkers.enabled")) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<ServiceWorkerDomainInfo> domainInfo = GetDomainInfo(aDoc);
|
||||
if (!domainInfo) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<ServiceWorkerRegistration> registration =
|
||||
GetServiceWorkerRegistration(aDoc);
|
||||
if (registration) {
|
||||
MOZ_ASSERT(!domainInfo->mControlledDocuments.Contains(aDoc));
|
||||
registration->StartControllingADocument();
|
||||
// Use the already_AddRefed<> form of Put to avoid the addref-deref since
|
||||
// we don't need the registration pointer in this function anymore.
|
||||
domainInfo->mControlledDocuments.Put(aDoc, registration.forget());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ServiceWorkerManager::MaybeStopControlling(nsIDocument* aDoc)
|
||||
{
|
||||
MOZ_ASSERT(aDoc);
|
||||
if (!Preferences::GetBool("dom.serviceWorkers.enabled")) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<ServiceWorkerDomainInfo> domainInfo = GetDomainInfo(aDoc);
|
||||
if (!domainInfo) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<ServiceWorkerRegistration> registration;
|
||||
domainInfo->mControlledDocuments.Remove(aDoc, getter_AddRefs(registration));
|
||||
// A document which was uncontrolled does not maintain that state itself, so
|
||||
// it will always call MaybeStopControlling() even if there isn't an
|
||||
// associated registration. So this check is required.
|
||||
if (registration) {
|
||||
registration->StopControllingADocument();
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ServiceWorkerManager::GetScopeForUrl(const nsAString& aUrl, nsAString& aScope)
|
||||
{
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/LinkedList.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "mozilla/dom/ServiceWorkerContainer.h"
|
||||
|
@ -72,35 +73,22 @@ private:
|
|||
* _GetNewestWorker(serviceWorkerRegistration)", we represent the description
|
||||
* by this class and spawn a ServiceWorker in the right global when required.
|
||||
*/
|
||||
class ServiceWorkerInfo
|
||||
class ServiceWorkerInfo MOZ_FINAL
|
||||
{
|
||||
nsCString mScriptSpec;
|
||||
|
||||
~ServiceWorkerInfo()
|
||||
{ }
|
||||
|
||||
public:
|
||||
|
||||
bool
|
||||
IsValid() const
|
||||
{
|
||||
return !mScriptSpec.IsVoid();
|
||||
}
|
||||
|
||||
void
|
||||
Invalidate()
|
||||
{
|
||||
mScriptSpec.SetIsVoid(true);
|
||||
}
|
||||
NS_INLINE_DECL_REFCOUNTING(ServiceWorkerInfo)
|
||||
|
||||
const nsCString&
|
||||
GetScriptSpec() const
|
||||
{
|
||||
MOZ_ASSERT(IsValid());
|
||||
return mScriptSpec;
|
||||
}
|
||||
|
||||
ServiceWorkerInfo()
|
||||
{
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
explicit ServiceWorkerInfo(const nsACString& aScriptSpec)
|
||||
: mScriptSpec(aScriptSpec)
|
||||
{ }
|
||||
|
@ -110,6 +98,8 @@ public:
|
|||
// non-ISupports classes.
|
||||
class ServiceWorkerRegistration MOZ_FINAL : public nsISupports
|
||||
{
|
||||
uint32_t mControlledDocumentsCounter;
|
||||
|
||||
virtual ~ServiceWorkerRegistration();
|
||||
|
||||
public:
|
||||
|
@ -120,9 +110,9 @@ public:
|
|||
// the URLs of the following three workers.
|
||||
nsCString mScriptSpec;
|
||||
|
||||
ServiceWorkerInfo mCurrentWorker;
|
||||
ServiceWorkerInfo mWaitingWorker;
|
||||
ServiceWorkerInfo mInstallingWorker;
|
||||
nsRefPtr<ServiceWorkerInfo> mCurrentWorker;
|
||||
nsRefPtr<ServiceWorkerInfo> mWaitingWorker;
|
||||
nsRefPtr<ServiceWorkerInfo> mInstallingWorker;
|
||||
|
||||
nsAutoPtr<UpdatePromise> mUpdatePromise;
|
||||
nsRefPtr<ServiceWorkerUpdateInstance> mUpdateInstance;
|
||||
|
@ -147,16 +137,37 @@ public:
|
|||
|
||||
explicit ServiceWorkerRegistration(const nsACString& aScope);
|
||||
|
||||
ServiceWorkerInfo
|
||||
Newest() const
|
||||
already_AddRefed<ServiceWorkerInfo>
|
||||
Newest()
|
||||
{
|
||||
if (mInstallingWorker.IsValid()) {
|
||||
return mInstallingWorker;
|
||||
} else if (mWaitingWorker.IsValid()) {
|
||||
return mWaitingWorker;
|
||||
nsRefPtr<ServiceWorkerInfo> newest;
|
||||
if (mInstallingWorker) {
|
||||
newest = mInstallingWorker;
|
||||
} else if (mWaitingWorker) {
|
||||
newest = mWaitingWorker;
|
||||
} else {
|
||||
return mCurrentWorker;
|
||||
newest = mCurrentWorker;
|
||||
}
|
||||
|
||||
return newest.forget();
|
||||
}
|
||||
|
||||
void
|
||||
StartControllingADocument()
|
||||
{
|
||||
++mControlledDocumentsCounter;
|
||||
}
|
||||
|
||||
void
|
||||
StopControllingADocument()
|
||||
{
|
||||
--mControlledDocumentsCounter;
|
||||
}
|
||||
|
||||
bool
|
||||
IsControllingDocuments() const
|
||||
{
|
||||
return mControlledDocumentsCounter > 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -186,6 +197,11 @@ public:
|
|||
|
||||
static ServiceWorkerManager* FactoryCreate()
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
if (!Preferences::GetBool("dom.serviceWorkers.enabled")) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ServiceWorkerManager* res = new ServiceWorkerManager;
|
||||
NS_ADDREF(res);
|
||||
return res;
|
||||
|
@ -216,6 +232,8 @@ public:
|
|||
// The containers inform the SWM on creation and destruction.
|
||||
nsTObserverArray<ServiceWorkerContainer*> mServiceWorkerContainers;
|
||||
|
||||
nsRefPtrHashtable<nsISupportsHashKey, ServiceWorkerRegistration> mControlledDocuments;
|
||||
|
||||
ServiceWorkerDomainInfo()
|
||||
{ }
|
||||
|
||||
|
@ -290,7 +308,7 @@ private:
|
|||
|
||||
void
|
||||
Install(ServiceWorkerRegistration* aRegistration,
|
||||
ServiceWorkerInfo aServiceWorkerInfo);
|
||||
ServiceWorkerInfo* aServiceWorkerInfo);
|
||||
|
||||
NS_IMETHOD
|
||||
CreateServiceWorkerForWindow(nsPIDOMWindow* aWindow,
|
||||
|
|
|
@ -46,10 +46,10 @@
|
|||
#include "nsIScriptContext.h"
|
||||
#include "xpcpublic.h"
|
||||
#include "jswrapper.h"
|
||||
#include "nsCxPusher.h"
|
||||
|
||||
#include "nsThreadUtils.h"
|
||||
#include "mozilla/dom/NodeListBinding.h"
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
@ -638,21 +638,9 @@ nsBindingManager::GetBindingImplementation(nsIContent* aContent, REFNSIID aIID,
|
|||
|
||||
// We have never made a wrapper for this implementation.
|
||||
// Create an XPC wrapper for the script object and hand it back.
|
||||
|
||||
nsIDocument* doc = aContent->OwnerDoc();
|
||||
|
||||
nsCOMPtr<nsIScriptGlobalObject> global =
|
||||
do_QueryInterface(doc->GetWindow());
|
||||
if (!global)
|
||||
return NS_NOINTERFACE;
|
||||
|
||||
nsIScriptContext *context = global->GetContext();
|
||||
if (!context)
|
||||
return NS_NOINTERFACE;
|
||||
|
||||
AutoPushJSContext cx(context->GetNativeContext());
|
||||
if (!cx)
|
||||
return NS_NOINTERFACE;
|
||||
AutoJSAPI jsapi;
|
||||
jsapi.Init();
|
||||
JSContext* cx = jsapi.cx();
|
||||
|
||||
nsIXPConnect *xpConnect = nsContentUtils::XPConnect();
|
||||
|
||||
|
@ -666,8 +654,7 @@ nsBindingManager::GetBindingImplementation(nsIContent* aContent, REFNSIID aIID,
|
|||
// because they're chrome-only and no Xrays are involved.
|
||||
//
|
||||
// If there's no separate XBL scope, or if the reflector itself lives in
|
||||
// the XBL scope, we'll end up with the global of the reflector, and this
|
||||
// will all be a no-op.
|
||||
// the XBL scope, we'll end up with the global of the reflector.
|
||||
JS::Rooted<JSObject*> xblScope(cx, xpc::GetXBLScopeOrGlobal(cx, jsobj));
|
||||
JSAutoCompartment ac(cx, xblScope);
|
||||
bool ok = JS_WrapObject(cx, &jsobj);
|
||||
|
|
|
@ -10,12 +10,12 @@
|
|||
#include "nsXBLPrototypeBinding.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsCxPusher.h"
|
||||
#include "nsGlobalWindow.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIAtom.h"
|
||||
#include "nsIDOMKeyEvent.h"
|
||||
#include "nsIDOMMouseEvent.h"
|
||||
#include "nsNameSpaceManager.h"
|
||||
#include "nsIScriptContext.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIController.h"
|
||||
#include "nsIControllers.h"
|
||||
|
@ -46,6 +46,8 @@
|
|||
#include "mozilla/JSEventHandler.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/dom/EventHandlerBinding.h"
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
#include "xpcpublic.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
@ -259,10 +261,6 @@ nsXBLPrototypeHandler::ExecuteHandler(EventTarget* aTarget,
|
|||
if (!boundGlobal)
|
||||
return NS_OK;
|
||||
|
||||
nsIScriptContext *boundContext = boundGlobal->GetScriptContext();
|
||||
if (!boundContext)
|
||||
return NS_OK;
|
||||
|
||||
nsISupports *scriptTarget;
|
||||
|
||||
if (winRoot) {
|
||||
|
@ -271,16 +269,17 @@ nsXBLPrototypeHandler::ExecuteHandler(EventTarget* aTarget,
|
|||
scriptTarget = aTarget;
|
||||
}
|
||||
|
||||
// We're about to create a new JSEventHandler, which means that we're
|
||||
// responsible for pushing the context of the event target. See the similar
|
||||
// comment in nsEventManagerListener.cpp.
|
||||
nsCxPusher pusher;
|
||||
NS_ENSURE_STATE(pusher.Push(aTarget));
|
||||
|
||||
AutoPushJSContext cx(boundContext->GetNativeContext());
|
||||
// We're about to create a new JSEventHandler, which means that we need to
|
||||
// Initiatize an AutoJSAPI with aTarget's bound global to make sure any errors
|
||||
// are reported to the correct place.
|
||||
AutoJSAPI jsapi;
|
||||
if (NS_WARN_IF(!jsapi.InitWithLegacyErrorReporting(boundGlobal))) {
|
||||
return NS_OK;
|
||||
}
|
||||
JSContext* cx = jsapi.cx();
|
||||
JS::Rooted<JSObject*> handler(cx);
|
||||
|
||||
rv = EnsureEventHandler(boundGlobal, boundContext, onEventAtom, &handler);
|
||||
rv = EnsureEventHandler(jsapi, onEventAtom, &handler);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
JSAddonId* addonId = MapURIToAddonID(mPrototypeBinding->DocURI());
|
||||
|
@ -338,15 +337,14 @@ nsXBLPrototypeHandler::ExecuteHandler(EventTarget* aTarget,
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsXBLPrototypeHandler::EnsureEventHandler(nsIScriptGlobalObject* aGlobal,
|
||||
nsIScriptContext *aBoundContext,
|
||||
nsIAtom *aName,
|
||||
nsXBLPrototypeHandler::EnsureEventHandler(AutoJSAPI& jsapi, nsIAtom* aName,
|
||||
JS::MutableHandle<JSObject*> aHandler)
|
||||
{
|
||||
AutoPushJSContext cx(aBoundContext->GetNativeContext());
|
||||
JSContext* cx = jsapi.cx();
|
||||
|
||||
// Check to see if we've already compiled this
|
||||
nsCOMPtr<nsPIDOMWindow> pWindow = do_QueryInterface(aGlobal);
|
||||
JS::Rooted<JSObject*> globalObject(cx, JS::CurrentGlobalOrNull(cx));
|
||||
nsCOMPtr<nsPIDOMWindow> pWindow = xpc::WindowOrNull(globalObject);
|
||||
if (pWindow) {
|
||||
JS::Rooted<JSObject*> cachedHandler(cx, pWindow->GetCachedXBLPrototypeHandler(this));
|
||||
if (cachedHandler) {
|
||||
|
@ -363,7 +361,6 @@ nsXBLPrototypeHandler::EnsureEventHandler(nsIScriptGlobalObject* aGlobal,
|
|||
|
||||
JSAddonId* addonId = MapURIToAddonID(mPrototypeBinding->DocURI());
|
||||
|
||||
JS::Rooted<JSObject*> globalObject(cx, aGlobal->GetGlobalJSObject());
|
||||
JS::Rooted<JSObject*> scopeObject(cx, xpc::GetScopeForXBLExecution(cx, globalObject, addonId));
|
||||
NS_ENSURE_TRUE(scopeObject, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#include "nsAutoPtr.h"
|
||||
#include "nsXBLEventHandler.h"
|
||||
#include "nsIWeakReference.h"
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "js/TypeDecls.h"
|
||||
|
||||
|
@ -28,6 +27,7 @@ class nsXBLPrototypeBinding;
|
|||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
class AutoJSAPI;
|
||||
class EventTarget;
|
||||
}
|
||||
}
|
||||
|
@ -166,8 +166,7 @@ protected:
|
|||
bool aIgnoreShiftKey = false);
|
||||
nsresult DispatchXBLCommand(mozilla::dom::EventTarget* aTarget, nsIDOMEvent* aEvent);
|
||||
nsresult DispatchXULKeyCommand(nsIDOMEvent* aEvent);
|
||||
nsresult EnsureEventHandler(nsIScriptGlobalObject* aGlobal,
|
||||
nsIScriptContext *aBoundContext, nsIAtom *aName,
|
||||
nsresult EnsureEventHandler(mozilla::dom::AutoJSAPI& jsapi, nsIAtom* aName,
|
||||
JS::MutableHandle<JSObject*> aHandler);
|
||||
static int32_t KeyToMask(int32_t key);
|
||||
static int32_t AccelKeyMask();
|
||||
|
|
|
@ -272,8 +272,8 @@ float Axis::ScaleWillOverscrollAmount(float aScale, float aFocus) {
|
|||
float originAfterScale = (GetOrigin() + aFocus) - (aFocus / aScale);
|
||||
|
||||
bool both = ScaleWillOverscrollBothSides(aScale);
|
||||
bool minus = originAfterScale < GetPageStart();
|
||||
bool plus = (originAfterScale + (GetCompositionLength() / aScale)) > GetPageEnd();
|
||||
bool minus = GetPageStart() - originAfterScale > COORDINATE_EPSILON;
|
||||
bool plus = (originAfterScale + (GetCompositionLength() / aScale)) - GetPageEnd() > COORDINATE_EPSILON;
|
||||
|
||||
if ((minus && plus) || both) {
|
||||
// If we ever reach here it's a bug in the client code.
|
||||
|
@ -330,7 +330,7 @@ bool Axis::ScaleWillOverscrollBothSides(float aScale) {
|
|||
CSSToParentLayerScale scale(metrics.GetZoomToParent().scale * aScale);
|
||||
CSSRect cssCompositionBounds = metrics.mCompositionBounds / scale;
|
||||
|
||||
return GetRectLength(metrics.GetExpandedScrollableRect()) < GetRectLength(cssCompositionBounds);
|
||||
return GetRectLength(cssCompositionBounds) - GetRectLength(metrics.GetExpandedScrollableRect()) > COORDINATE_EPSILON;
|
||||
}
|
||||
|
||||
const FrameMetrics& Axis::GetFrameMetrics() const {
|
||||
|
|
|
@ -141,8 +141,13 @@ static void
|
|||
TranslateShadowLayer2D(Layer* aLayer,
|
||||
const gfxPoint& aTranslation)
|
||||
{
|
||||
// This layer might also be a scrollable layer and have an async transform.
|
||||
// To make sure we don't clobber that, we start with the shadow transform.
|
||||
// Any adjustments to the shadow transform made in this function in previous
|
||||
// frames have been cleared in ClearAsyncTransforms(), so such adjustments
|
||||
// will not compound over successive frames.
|
||||
Matrix layerTransform;
|
||||
if (!GetBaseTransform2D(aLayer, &layerTransform)) {
|
||||
if (!aLayer->GetLocalTransform().Is2D(&layerTransform)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -894,6 +899,18 @@ AsyncCompositionManager::TransformScrollableLayer(Layer* aLayer)
|
|||
aLayer->GetLocalTransform(), fixedLayerMargins);
|
||||
}
|
||||
|
||||
void
|
||||
ClearAsyncTransforms(Layer* aLayer)
|
||||
{
|
||||
if (!aLayer->AsLayerComposite()->GetShadowTransformSetByAnimation()) {
|
||||
aLayer->AsLayerComposite()->SetShadowTransform(aLayer->GetBaseTransform());
|
||||
}
|
||||
for (Layer* child = aLayer->GetFirstChild();
|
||||
child; child = child->GetNextSibling()) {
|
||||
ClearAsyncTransforms(child);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
AsyncCompositionManager::TransformShadowTree(TimeStamp aCurrentFrame)
|
||||
{
|
||||
|
@ -909,6 +926,12 @@ AsyncCompositionManager::TransformShadowTree(TimeStamp aCurrentFrame)
|
|||
// transforms.
|
||||
bool wantNextFrame = SampleAnimations(root, aCurrentFrame);
|
||||
|
||||
// Clear any async transforms (not due to animations) set in previous frames.
|
||||
// This is necessary because some things called by
|
||||
// ApplyAsyncContentTransformToTree (in particular, TranslateShadowLayer2D),
|
||||
// add to the shadow transform rather than overwriting it.
|
||||
ClearAsyncTransforms(root);
|
||||
|
||||
// FIXME/bug 775437: unify this interface with the ~native-fennec
|
||||
// derived code
|
||||
//
|
||||
|
|
|
@ -220,12 +220,6 @@ def main(argv):
|
|||
|
||||
prefix += ['-f', prolog]
|
||||
|
||||
# Avoid racing on the cache by having the js shell create a new cache
|
||||
# subdir for each process. The js shell takes care of deleting these
|
||||
# subdirs when the process exits.
|
||||
if options.max_jobs > 1 and jittests.HAVE_MULTIPROCESSING:
|
||||
prefix += ['--js-cache-per-process']
|
||||
|
||||
# Clean up any remnants from previous crashes etc
|
||||
shutil.rmtree(jittests.JS_CACHE_DIR, ignore_errors=True)
|
||||
os.mkdir(jittests.JS_CACHE_DIR)
|
||||
|
|
|
@ -35,7 +35,7 @@ function asmCompileCached()
|
|||
for (var i = 0; i < arguments.length; i++)
|
||||
quotedArgs.push("'" + arguments[i] + "'");
|
||||
var code = "var f = new Function(" + quotedArgs.join(',') + ");assertEq(isAsmJSModule(f), true);";
|
||||
nestedShell("--js-cache", "--execute=" + code);
|
||||
nestedShell("--js-cache", "--no-js-cache-per-process", "--execute=" + code);
|
||||
|
||||
var f = Function.apply(null, arguments);
|
||||
assertEq(isAsmJSModuleLoadedFromCache(f), true);
|
||||
|
|
|
@ -10,7 +10,7 @@ if (!isAsmJSCompilationAvailable())
|
|||
// nestedShell() (and the loadedFromCache assertion) to see if the error
|
||||
// reproduces.
|
||||
var code = "setIonCheckGraphCoherency(false); load('" + libdir + "bullet.js'); runBullet()";
|
||||
nestedShell("--js-cache", "--execute=" + code);
|
||||
nestedShell("--js-cache", "--no-js-cache-per-process", "--execute=" + code);
|
||||
setIonCheckGraphCoherency(false);
|
||||
load(libdir + 'bullet.js');
|
||||
var results = runBullet();
|
||||
|
|
|
@ -22,6 +22,33 @@ assertEq(f(0x7f),0x7f);
|
|||
assertEq(f(0xff),-1);
|
||||
assertEq(f(0x100),0);
|
||||
|
||||
// Test signal handlers deactivation
|
||||
(function() {
|
||||
var jco = getJitCompilerOptions();
|
||||
var signalHandlersBefore = jco["signals.enable"];
|
||||
if (signalHandlersBefore == 1) {
|
||||
setJitCompilerOption("signals.enable", 0);
|
||||
|
||||
if (isCachingEnabled()) {
|
||||
// Cloned modules should fail on linking if the initial module has
|
||||
// been compiled with signals but signals are deactivated.
|
||||
var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; i32[0] = i; return i8[0]|0}; return f');
|
||||
assertAsmLinkFail(code, this, null, new ArrayBuffer(4096));
|
||||
}
|
||||
|
||||
var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + '/* not a clone */ function f(i) {i=i|0; i32[0] = i; return i8[0]|0}; return f');
|
||||
var f = asmLink(code, this, null, new ArrayBuffer(4096));
|
||||
assertEq(f(0),0);
|
||||
assertEq(f(0x7f),0x7f);
|
||||
assertEq(f(0xff),-1);
|
||||
assertEq(f(0x100),0);
|
||||
setJitCompilerOption("signals.enable", 1);
|
||||
}
|
||||
jco = getJitCompilerOptions();
|
||||
var signalHandlersAfter = jco["signals.enable"];
|
||||
assertEq(signalHandlersBefore, signalHandlersAfter);
|
||||
})();
|
||||
|
||||
var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; i32[0] = i; return u8[0]|0}; return f');
|
||||
var f = asmLink(code, this, null, new ArrayBuffer(4096));
|
||||
assertEq(f(0),0);
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
// |jit-test| exitstatus: 6;
|
||||
|
||||
load(libdir + "asm.js");
|
||||
|
||||
var jco = getJitCompilerOptions();
|
||||
if (jco["signals.enable"] === 0 || !isCachingEnabled() || !isAsmJSCompilationAvailable())
|
||||
quit(6);
|
||||
|
||||
// Modules compiled without signal handlers should still work even if signal
|
||||
// handlers have been reactivated.
|
||||
setJitCompilerOption("signals.enable", 0);
|
||||
|
||||
var code = USE_ASM + "function f() {} function g() { while(1) { f() } } return g";
|
||||
|
||||
var m = asmCompile(code);
|
||||
assertEq(isAsmJSModule(m), true);
|
||||
assertEq(isAsmJSModuleLoadedFromCache(m), false);
|
||||
|
||||
setJitCompilerOption("signals.enable", 1);
|
||||
|
||||
var m = asmCompile(code);
|
||||
assertEq(isAsmJSModule(m), true);
|
||||
assertEq(isAsmJSModuleLoadedFromCache(m), true);
|
||||
|
||||
var g = asmLink(m);
|
||||
timeout(1);
|
||||
g();
|
||||
assertEq(true, false);
|
|
@ -0,0 +1,9 @@
|
|||
// |jit-test| exitstatus: 6;
|
||||
|
||||
load(libdir + "asm.js");
|
||||
|
||||
setJitCompilerOption("signals.enable", 0);
|
||||
var g = asmLink(asmCompile(USE_ASM + "function f() {} function g() { while(1) { f() } } return g"));
|
||||
timeout(1);
|
||||
g();
|
||||
assertEq(true, false);
|
|
@ -0,0 +1,9 @@
|
|||
// |jit-test| exitstatus: 6;
|
||||
|
||||
load(libdir + "asm.js");
|
||||
|
||||
setJitCompilerOption("signals.enable", 0);
|
||||
var g = asmLink(asmCompile(USE_ASM + "function g() { while(1) {} } return g"));
|
||||
timeout(1);
|
||||
g();
|
||||
assertEq(true, false);
|
|
@ -0,0 +1,9 @@
|
|||
// |jit-test| exitstatus: 6;
|
||||
|
||||
load(libdir + "asm.js");
|
||||
|
||||
setJitCompilerOption("signals.enable", 0);
|
||||
var f = asmLink(asmCompile(USE_ASM + "function f(i) { i=i|0; if (!i) return; f((i-1)|0); f((i-1)|0); f((i-1)|0); f((i-1)|0); f((i-1)|0); } return f"));
|
||||
timeout(1);
|
||||
f(100);
|
||||
assertEq(true, false);
|
|
@ -0,0 +1,9 @@
|
|||
// |jit-test| exitstatus: 6;
|
||||
|
||||
load(libdir + "asm.js");
|
||||
|
||||
setJitCompilerOption("signals.enable", 0);
|
||||
var g = asmLink(asmCompile(USE_ASM + "function f(d) { d=+d; d=d*.1; d=d/.4; return +d } function g() { while(1) { +f(1.1) } } return g"));
|
||||
timeout(1);
|
||||
g();
|
||||
assertEq(true, false);
|
|
@ -0,0 +1,5 @@
|
|||
// |jit-test| exitstatus: 6;
|
||||
|
||||
setJitCompilerOption('signals.enable', 0);
|
||||
timeout(1);
|
||||
for(;;);
|
|
@ -6065,7 +6065,11 @@ GenerateEntry(ModuleCompiler &m, const AsmJSModule::ExportedFunction &exportedFu
|
|||
return true;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
// This function and InvokeFromAsmJS* functions all return int32_t rather than
|
||||
// bool to prevent the compiler from optimizing bits higher than what's
|
||||
// actually needed for a bool (as the result is tested in asm.js generated code
|
||||
// which the compiler isn't aware of).
|
||||
static inline int32_t
|
||||
TryEnablingIon(JSContext *cx, AsmJSModule &module, HandleFunction fun, uint32_t exitIndex,
|
||||
int32_t argc, Value *argv)
|
||||
{
|
||||
|
@ -6105,64 +6109,53 @@ TryEnablingIon(JSContext *cx, AsmJSModule &module, HandleFunction fun, uint32_t
|
|||
|
||||
namespace js {
|
||||
|
||||
// See comment above TryEnablingIon.
|
||||
int32_t
|
||||
InvokeFromAsmJS_Ignore(JSContext *cx, int32_t exitIndex, int32_t argc, Value *argv)
|
||||
InvokeFromAsmJS(JSContext *cx, int32_t exitIndex, int32_t argc, Value *argv,
|
||||
MutableHandleValue rval)
|
||||
{
|
||||
AsmJSModule &module = cx->mainThread().asmJSActivationStackFromOwnerThread()->module();
|
||||
|
||||
RootedFunction fun(cx, module.exitIndexToGlobalDatum(exitIndex).fun);
|
||||
RootedValue fval(cx, ObjectValue(*fun));
|
||||
if (!Invoke(cx, UndefinedValue(), fval, argc, argv, rval))
|
||||
return false;
|
||||
|
||||
return TryEnablingIon(cx, module, fun, exitIndex, argc, argv);
|
||||
}
|
||||
|
||||
int32_t
|
||||
InvokeFromAsmJS_Ignore(JSContext *cx, int32_t exitIndex, int32_t argc, Value *argv)
|
||||
{
|
||||
RootedValue rval(cx);
|
||||
if (!Invoke(cx, UndefinedValue(), fval, argc, argv, &rval))
|
||||
return false;
|
||||
|
||||
if (!TryEnablingIon(cx, module, fun, exitIndex, argc, argv))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
return InvokeFromAsmJS(cx, exitIndex, argc, argv, &rval);
|
||||
}
|
||||
|
||||
int32_t
|
||||
InvokeFromAsmJS_ToInt32(JSContext *cx, int32_t exitIndex, int32_t argc, Value *argv)
|
||||
{
|
||||
AsmJSModule &module = cx->mainThread().asmJSActivationStackFromOwnerThread()->module();
|
||||
|
||||
RootedFunction fun(cx, module.exitIndexToGlobalDatum(exitIndex).fun);
|
||||
RootedValue fval(cx, ObjectValue(*fun));
|
||||
RootedValue rval(cx);
|
||||
if (!Invoke(cx, UndefinedValue(), fval, argc, argv, &rval))
|
||||
return false;
|
||||
|
||||
if (!TryEnablingIon(cx, module, fun, exitIndex, argc, argv))
|
||||
if (!InvokeFromAsmJS(cx, exitIndex, argc, argv, &rval))
|
||||
return false;
|
||||
|
||||
int32_t i32;
|
||||
if (!ToInt32(cx, rval, &i32))
|
||||
return false;
|
||||
argv[0] = Int32Value(i32);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int32_t
|
||||
InvokeFromAsmJS_ToNumber(JSContext *cx, int32_t exitIndex, int32_t argc, Value *argv)
|
||||
{
|
||||
AsmJSModule &module = cx->mainThread().asmJSActivationStackFromOwnerThread()->module();
|
||||
|
||||
RootedFunction fun(cx, module.exitIndexToGlobalDatum(exitIndex).fun);
|
||||
RootedValue fval(cx, ObjectValue(*fun));
|
||||
RootedValue rval(cx);
|
||||
if (!Invoke(cx, UndefinedValue(), fval, argc, argv, &rval))
|
||||
return false;
|
||||
|
||||
if (!TryEnablingIon(cx, module, fun, exitIndex, argc, argv))
|
||||
if (!InvokeFromAsmJS(cx, exitIndex, argc, argv, &rval))
|
||||
return false;
|
||||
|
||||
double dbl;
|
||||
if (!ToNumber(cx, rval, &dbl))
|
||||
return false;
|
||||
argv[0] = DoubleValue(dbl);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -8808,10 +8808,11 @@ CodeGenerator::visitInterruptCheck(LInterruptCheck *lir)
|
|||
bool
|
||||
CodeGenerator::visitAsmJSInterruptCheck(LAsmJSInterruptCheck *lir)
|
||||
{
|
||||
Label rejoin;
|
||||
Register scratch = ToRegister(lir->scratch());
|
||||
masm.movePtr(AsmJSImmPtr(AsmJSImm_RuntimeInterrupt), scratch);
|
||||
masm.branchIfFalseBool(scratch, &rejoin);
|
||||
masm.load8ZeroExtend(Address(scratch, 0), scratch);
|
||||
Label rejoin;
|
||||
masm.branch32(Assembler::Equal, scratch, Imm32(0), &rejoin);
|
||||
{
|
||||
uint32_t stackFixup = ComputeByteAlignment(masm.framePushed() + AsmJSFrameSize,
|
||||
StackAlignment);
|
||||
|
|
|
@ -739,6 +739,12 @@ class LAsmJSInterruptCheck : public LInstructionHelper<0, 0, 1>
|
|||
}
|
||||
};
|
||||
|
||||
class LInterruptCheck : public LInstructionHelper<0, 0, 0>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(InterruptCheck)
|
||||
};
|
||||
|
||||
// Alternative to LInterruptCheck which does not emit an explicit check of the
|
||||
// interrupt flag but relies on the loop backedge being patched via a signal
|
||||
// handler.
|
||||
|
|
|
@ -397,12 +397,6 @@ class LGuardObjectType : public LInstructionHelper<0, 1, 1>
|
|||
}
|
||||
};
|
||||
|
||||
class LInterruptCheck : public LInstructionHelper<0, 0, 0>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(InterruptCheck);
|
||||
};
|
||||
|
||||
class LMulI : public LBinaryMath<0>
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -345,12 +345,6 @@ class LGuardObjectType : public LInstructionHelper<0, 1, 1>
|
|||
}
|
||||
};
|
||||
|
||||
class LInterruptCheck : public LInstructionHelper<0, 0, 0>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(InterruptCheck);
|
||||
};
|
||||
|
||||
class LMulI : public LBinaryMath<0>
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -295,12 +295,6 @@ class LGuardObjectType : public LInstructionHelper<0, 1, 0>
|
|||
}
|
||||
};
|
||||
|
||||
class LInterruptCheck : public LInstructionHelper<0, 0, 0>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(InterruptCheck)
|
||||
};
|
||||
|
||||
class LMulI : public LBinaryMath<0, 1>
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -187,15 +187,9 @@ class MacroAssemblerX86Shared : public Assembler
|
|||
void not32(Register reg) {
|
||||
notl(reg);
|
||||
}
|
||||
void inc32(const Operand &addr) {
|
||||
incl(addr);
|
||||
}
|
||||
void atomic_inc32(const Operand &addr) {
|
||||
lock_incl(addr);
|
||||
}
|
||||
void dec32(const Operand &addr) {
|
||||
decl(addr);
|
||||
}
|
||||
void atomic_dec32(const Operand &addr) {
|
||||
lock_decl(addr);
|
||||
}
|
||||
|
|
|
@ -6309,6 +6309,15 @@ JS_SetGlobalJitCompilerOption(JSRuntime *rt, JSJitCompilerOption opt, uint32_t v
|
|||
IonSpew(js::jit::IonSpew_Scripts, "Disable offthread compilation");
|
||||
}
|
||||
break;
|
||||
case JSJITCOMPILER_SIGNALS_ENABLE:
|
||||
if (value == 1) {
|
||||
rt->setCanUseSignalHandlers(true);
|
||||
IonSpew(js::jit::IonSpew_Scripts, "Enable signals");
|
||||
} else if (value == 0) {
|
||||
rt->setCanUseSignalHandlers(false);
|
||||
IonSpew(js::jit::IonSpew_Scripts, "Disable signals");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -6330,6 +6339,8 @@ JS_GetGlobalJitCompilerOption(JSRuntime *rt, JSJitCompilerOption opt)
|
|||
return JS::RuntimeOptionsRef(rt).baseline();
|
||||
case JSJITCOMPILER_OFFTHREAD_COMPILATION_ENABLE:
|
||||
return rt->canUseOffthreadIonCompilation();
|
||||
case JSJITCOMPILER_SIGNALS_ENABLE:
|
||||
return rt->canUseSignalHandlers();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -4926,7 +4926,8 @@ JS_SetOffthreadIonCompilationEnabled(JSRuntime *rt, bool enabled);
|
|||
Register(ION_USECOUNT_TRIGGER, "ion.usecount.trigger") \
|
||||
Register(ION_ENABLE, "ion.enable") \
|
||||
Register(BASELINE_ENABLE, "baseline.enable") \
|
||||
Register(OFFTHREAD_COMPILATION_ENABLE, "offthread-compilation.enable")
|
||||
Register(OFFTHREAD_COMPILATION_ENABLE, "offthread-compilation.enable") \
|
||||
Register(SIGNALS_ENABLE, "signals.enable")
|
||||
|
||||
typedef enum JSJitCompilerOption {
|
||||
#define JIT_COMPILER_DECLARE(key, str) \
|
||||
|
|
|
@ -344,27 +344,35 @@ static const AllocKind FinalizePhaseScripts[] = {
|
|||
FINALIZE_LAZY_SCRIPT
|
||||
};
|
||||
|
||||
#ifdef JS_ION
|
||||
static const AllocKind FinalizePhaseJitCode[] = {
|
||||
FINALIZE_JITCODE
|
||||
};
|
||||
#endif
|
||||
|
||||
static const AllocKind * const FinalizePhases[] = {
|
||||
FinalizePhaseStrings,
|
||||
FinalizePhaseScripts,
|
||||
FinalizePhaseJitCode
|
||||
#ifdef JS_ION
|
||||
FinalizePhaseJitCode,
|
||||
#endif
|
||||
};
|
||||
static const int FinalizePhaseCount = sizeof(FinalizePhases) / sizeof(AllocKind*);
|
||||
|
||||
static const int FinalizePhaseLength[] = {
|
||||
sizeof(FinalizePhaseStrings) / sizeof(AllocKind),
|
||||
sizeof(FinalizePhaseScripts) / sizeof(AllocKind),
|
||||
sizeof(FinalizePhaseJitCode) / sizeof(AllocKind)
|
||||
#ifdef JS_ION
|
||||
sizeof(FinalizePhaseJitCode) / sizeof(AllocKind),
|
||||
#endif
|
||||
};
|
||||
|
||||
static const gcstats::Phase FinalizePhaseStatsPhase[] = {
|
||||
gcstats::PHASE_SWEEP_STRING,
|
||||
gcstats::PHASE_SWEEP_SCRIPT,
|
||||
gcstats::PHASE_SWEEP_JITCODE
|
||||
#ifdef JS_ION
|
||||
gcstats::PHASE_SWEEP_JITCODE,
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -2142,12 +2150,14 @@ ArenaLists::queueScriptsForSweep(FreeOp *fop)
|
|||
queueForForegroundSweep(fop, FINALIZE_LAZY_SCRIPT);
|
||||
}
|
||||
|
||||
#ifdef JS_ION
|
||||
void
|
||||
ArenaLists::queueJitCodeForSweep(FreeOp *fop)
|
||||
{
|
||||
gcstats::AutoPhase ap(fop->runtime()->gc.stats, gcstats::PHASE_SWEEP_JITCODE);
|
||||
queueForForegroundSweep(fop, FINALIZE_JITCODE);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
ArenaLists::queueShapesForSweep(FreeOp *fop)
|
||||
|
|
|
@ -919,7 +919,9 @@ class ArenaLists
|
|||
void queueStringsAndSymbolsForSweep(FreeOp *fop);
|
||||
void queueShapesForSweep(FreeOp *fop);
|
||||
void queueScriptsForSweep(FreeOp *fop);
|
||||
#ifdef JS_ION
|
||||
void queueJitCodeForSweep(FreeOp *fop);
|
||||
#endif
|
||||
|
||||
bool foregroundFinalize(FreeOp *fop, AllocKind thingKind, SliceBudget &sliceBudget,
|
||||
SortedArenaList &sweepList);
|
||||
|
|
265
js/src/jsstr.cpp
265
js/src/jsstr.cpp
|
@ -4268,271 +4268,6 @@ js_InitStringClass(JSContext *cx, HandleObject obj)
|
|||
return proto;
|
||||
}
|
||||
|
||||
JSLinearString *
|
||||
js::NewDependentString(JSContext *cx, JSString *baseArg, size_t start, size_t length)
|
||||
{
|
||||
if (length == 0)
|
||||
return cx->emptyString();
|
||||
|
||||
JSLinearString *base = baseArg->ensureLinear(cx);
|
||||
if (!base)
|
||||
return nullptr;
|
||||
|
||||
if (start == 0 && length == base->length())
|
||||
return base;
|
||||
|
||||
if (base->hasTwoByteChars()) {
|
||||
AutoCheckCannotGC nogc;
|
||||
const jschar *chars = base->twoByteChars(nogc) + start;
|
||||
if (JSLinearString *staticStr = cx->staticStrings().lookup(chars, length))
|
||||
return staticStr;
|
||||
} else {
|
||||
AutoCheckCannotGC nogc;
|
||||
const Latin1Char *chars = base->latin1Chars(nogc) + start;
|
||||
if (JSLinearString *staticStr = cx->staticStrings().lookup(chars, length))
|
||||
return staticStr;
|
||||
}
|
||||
|
||||
return JSDependentString::new_(cx, base, start, length);
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
static void
|
||||
CopyCharsMaybeInflate(jschar *dest, const CharT *src, size_t len);
|
||||
|
||||
template <>
|
||||
void
|
||||
CopyCharsMaybeInflate(jschar *dest, const jschar *src, size_t len)
|
||||
{
|
||||
PodCopy(dest, src, len);
|
||||
}
|
||||
|
||||
template <>
|
||||
void
|
||||
CopyCharsMaybeInflate(jschar *dest, const Latin1Char *src, size_t len)
|
||||
{
|
||||
CopyAndInflateChars(dest, src, len);
|
||||
}
|
||||
|
||||
static bool
|
||||
CanStoreCharsAsLatin1(const jschar *s, size_t length)
|
||||
{
|
||||
if (!EnableLatin1Strings)
|
||||
return false;
|
||||
|
||||
for (const jschar *end = s + length; s < end; ++s) {
|
||||
if (*s > JSString::MAX_LATIN1_CHAR)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
CanStoreCharsAsLatin1(const Latin1Char *s, size_t length)
|
||||
{
|
||||
MOZ_CRASH("Shouldn't be called for Latin1 chars");
|
||||
}
|
||||
|
||||
template <AllowGC allowGC>
|
||||
static MOZ_ALWAYS_INLINE JSInlineString *
|
||||
NewFatInlineStringDeflated(ThreadSafeContext *cx, mozilla::Range<const jschar> chars)
|
||||
{
|
||||
MOZ_ASSERT(EnableLatin1Strings);
|
||||
|
||||
size_t len = chars.length();
|
||||
Latin1Char *storage;
|
||||
JSInlineString *str = AllocateFatInlineString<allowGC>(cx, len, &storage);
|
||||
if (!str)
|
||||
return nullptr;
|
||||
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
MOZ_ASSERT(chars[i] <= JSString::MAX_LATIN1_CHAR);
|
||||
storage[i] = Latin1Char(chars[i]);
|
||||
}
|
||||
storage[len] = '\0';
|
||||
return str;
|
||||
}
|
||||
|
||||
template <AllowGC allowGC>
|
||||
static JSFlatString *
|
||||
NewStringDeflated(ThreadSafeContext *cx, const jschar *s, size_t n)
|
||||
{
|
||||
MOZ_ASSERT(EnableLatin1Strings);
|
||||
|
||||
if (JSFatInlineString::latin1LengthFits(n))
|
||||
return NewFatInlineStringDeflated<allowGC>(cx, mozilla::Range<const jschar>(s, n));
|
||||
|
||||
ScopedJSFreePtr<Latin1Char> news(cx->pod_malloc<Latin1Char>(n + 1));
|
||||
if (!news)
|
||||
return nullptr;
|
||||
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
MOZ_ASSERT(s[i] <= JSString::MAX_LATIN1_CHAR);
|
||||
news.get()[i] = Latin1Char(s[i]);
|
||||
}
|
||||
news[n] = '\0';
|
||||
|
||||
JSFlatString *str = JSFlatString::new_<allowGC>(cx, news.get(), n);
|
||||
if (!str)
|
||||
return nullptr;
|
||||
|
||||
news.forget();
|
||||
return str;
|
||||
}
|
||||
|
||||
template <AllowGC allowGC>
|
||||
static JSFlatString *
|
||||
NewStringDeflated(ThreadSafeContext *cx, const Latin1Char *s, size_t n)
|
||||
{
|
||||
MOZ_CRASH("Shouldn't be called for Latin1 chars");
|
||||
}
|
||||
|
||||
template <AllowGC allowGC, typename CharT>
|
||||
JSFlatString *
|
||||
js::NewStringDontDeflate(ThreadSafeContext *cx, CharT *chars, size_t length)
|
||||
{
|
||||
if (length == 1) {
|
||||
jschar c = chars[0];
|
||||
if (StaticStrings::hasUnit(c)) {
|
||||
// Free |chars| because we're taking possession of it, but it's no
|
||||
// longer needed because we use the static string instead.
|
||||
js_free(chars);
|
||||
return cx->staticStrings().getUnit(c);
|
||||
}
|
||||
}
|
||||
|
||||
return JSFlatString::new_<allowGC>(cx, chars, length);
|
||||
}
|
||||
|
||||
template JSFlatString *
|
||||
js::NewStringDontDeflate<CanGC>(ThreadSafeContext *cx, jschar *chars, size_t length);
|
||||
|
||||
template JSFlatString *
|
||||
js::NewStringDontDeflate<NoGC>(ThreadSafeContext *cx, jschar *chars, size_t length);
|
||||
|
||||
template JSFlatString *
|
||||
js::NewStringDontDeflate<CanGC>(ThreadSafeContext *cx, Latin1Char *chars, size_t length);
|
||||
|
||||
template JSFlatString *
|
||||
js::NewStringDontDeflate<NoGC>(ThreadSafeContext *cx, Latin1Char *chars, size_t length);
|
||||
|
||||
template <AllowGC allowGC, typename CharT>
|
||||
JSFlatString *
|
||||
js::NewString(ThreadSafeContext *cx, CharT *chars, size_t length)
|
||||
{
|
||||
if (IsSame<CharT, jschar>::value && CanStoreCharsAsLatin1(chars, length)) {
|
||||
if (length == 1) {
|
||||
jschar c = chars[0];
|
||||
if (StaticStrings::hasUnit(c)) {
|
||||
js_free(chars);
|
||||
return cx->staticStrings().getUnit(c);
|
||||
}
|
||||
}
|
||||
|
||||
JSFlatString *s = NewStringDeflated<allowGC>(cx, chars, length);
|
||||
if (!s)
|
||||
return nullptr;
|
||||
|
||||
// Free |chars| because we're taking possession of it but not using it.
|
||||
js_free(chars);
|
||||
return s;
|
||||
}
|
||||
|
||||
return NewStringDontDeflate<allowGC>(cx, chars, length);
|
||||
}
|
||||
|
||||
template JSFlatString *
|
||||
js::NewString<CanGC>(ThreadSafeContext *cx, jschar *chars, size_t length);
|
||||
|
||||
template JSFlatString *
|
||||
js::NewString<NoGC>(ThreadSafeContext *cx, jschar *chars, size_t length);
|
||||
|
||||
template JSFlatString *
|
||||
js::NewString<CanGC>(ThreadSafeContext *cx, Latin1Char *chars, size_t length);
|
||||
|
||||
template JSFlatString *
|
||||
js::NewString<NoGC>(ThreadSafeContext *cx, Latin1Char *chars, size_t length);
|
||||
|
||||
namespace js {
|
||||
|
||||
template <AllowGC allowGC, typename CharT>
|
||||
JSFlatString *
|
||||
NewStringCopyNDontDeflate(ThreadSafeContext *cx, const CharT *s, size_t n)
|
||||
{
|
||||
if (EnableLatin1Strings) {
|
||||
if (JSFatInlineString::lengthFits<CharT>(n))
|
||||
return NewFatInlineString<allowGC>(cx, mozilla::Range<const CharT>(s, n));
|
||||
|
||||
ScopedJSFreePtr<CharT> news(cx->pod_malloc<CharT>(n + 1));
|
||||
if (!news)
|
||||
return nullptr;
|
||||
|
||||
PodCopy(news.get(), s, n);
|
||||
news[n] = 0;
|
||||
|
||||
JSFlatString *str = JSFlatString::new_<allowGC>(cx, news.get(), n);
|
||||
if (!str)
|
||||
return nullptr;
|
||||
|
||||
news.forget();
|
||||
return str;
|
||||
}
|
||||
|
||||
if (JSFatInlineString::twoByteLengthFits(n))
|
||||
return NewFatInlineString<allowGC>(cx, mozilla::Range<const CharT>(s, n));
|
||||
|
||||
ScopedJSFreePtr<jschar> news(cx->pod_malloc<jschar>(n + 1));
|
||||
if (!news)
|
||||
return nullptr;
|
||||
|
||||
CopyCharsMaybeInflate(news.get(), s, n);
|
||||
news[n] = 0;
|
||||
|
||||
JSFlatString *str = JSFlatString::new_<allowGC>(cx, news.get(), n);
|
||||
if (!str)
|
||||
return nullptr;
|
||||
|
||||
news.forget();
|
||||
return str;
|
||||
}
|
||||
|
||||
template JSFlatString *
|
||||
NewStringCopyNDontDeflate<CanGC>(ThreadSafeContext *cx, const jschar *s, size_t n);
|
||||
|
||||
template JSFlatString *
|
||||
NewStringCopyNDontDeflate<NoGC>(ThreadSafeContext *cx, const jschar *s, size_t n);
|
||||
|
||||
template JSFlatString *
|
||||
NewStringCopyNDontDeflate<CanGC>(ThreadSafeContext *cx, const Latin1Char *s, size_t n);
|
||||
|
||||
template JSFlatString *
|
||||
NewStringCopyNDontDeflate<NoGC>(ThreadSafeContext *cx, const Latin1Char *s, size_t n);
|
||||
|
||||
template <AllowGC allowGC, typename CharT>
|
||||
JSFlatString *
|
||||
NewStringCopyN(ThreadSafeContext *cx, const CharT *s, size_t n)
|
||||
{
|
||||
if (IsSame<CharT, jschar>::value && CanStoreCharsAsLatin1(s, n))
|
||||
return NewStringDeflated<allowGC>(cx, s, n);
|
||||
|
||||
return NewStringCopyNDontDeflate<allowGC>(cx, s, n);
|
||||
}
|
||||
|
||||
template JSFlatString *
|
||||
NewStringCopyN<CanGC>(ThreadSafeContext *cx, const jschar *s, size_t n);
|
||||
|
||||
template JSFlatString *
|
||||
NewStringCopyN<NoGC>(ThreadSafeContext *cx, const jschar *s, size_t n);
|
||||
|
||||
template JSFlatString *
|
||||
NewStringCopyN<CanGC>(ThreadSafeContext *cx, const Latin1Char *s, size_t n);
|
||||
|
||||
template JSFlatString *
|
||||
NewStringCopyN<NoGC>(ThreadSafeContext *cx, const Latin1Char *s, size_t n);
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
const char *
|
||||
js_ValueToPrintable(JSContext *cx, const Value &vArg, JSAutoByteString *bytes, bool asSource)
|
||||
{
|
||||
|
|
|
@ -127,51 +127,6 @@ namespace js {
|
|||
extern mozilla::UniquePtr<jschar[], JS::FreePolicy>
|
||||
DuplicateString(ThreadSafeContext *cx, const jschar *s);
|
||||
|
||||
/* GC-allocate a string descriptor for the given malloc-allocated chars. */
|
||||
template <js::AllowGC allowGC, typename CharT>
|
||||
extern JSFlatString *
|
||||
NewString(js::ThreadSafeContext *cx, CharT *chars, size_t length);
|
||||
|
||||
/* Like NewString, but doesn't try to deflate to Latin1. */
|
||||
template <js::AllowGC allowGC, typename CharT>
|
||||
extern JSFlatString *
|
||||
NewStringDontDeflate(js::ThreadSafeContext *cx, CharT *chars, size_t length);
|
||||
|
||||
extern JSLinearString *
|
||||
NewDependentString(JSContext *cx, JSString *base, size_t start, size_t length);
|
||||
|
||||
/* Copy a counted string and GC-allocate a descriptor for it. */
|
||||
template <js::AllowGC allowGC, typename CharT>
|
||||
extern JSFlatString *
|
||||
NewStringCopyN(js::ThreadSafeContext *cx, const CharT *s, size_t n);
|
||||
|
||||
template <js::AllowGC allowGC>
|
||||
inline JSFlatString *
|
||||
NewStringCopyN(ThreadSafeContext *cx, const char *s, size_t n)
|
||||
{
|
||||
return NewStringCopyN<allowGC>(cx, reinterpret_cast<const Latin1Char *>(s), n);
|
||||
}
|
||||
|
||||
/* Like NewStringCopyN, but doesn't try to deflate to Latin1. */
|
||||
template <js::AllowGC allowGC, typename CharT>
|
||||
extern JSFlatString *
|
||||
NewStringCopyNDontDeflate(js::ThreadSafeContext *cx, const CharT *s, size_t n);
|
||||
|
||||
/* Copy a C string and GC-allocate a descriptor for it. */
|
||||
template <js::AllowGC allowGC>
|
||||
inline JSFlatString *
|
||||
NewStringCopyZ(js::ExclusiveContext *cx, const jschar *s)
|
||||
{
|
||||
return NewStringCopyN<allowGC>(cx, s, js_strlen(s));
|
||||
}
|
||||
|
||||
template <js::AllowGC allowGC>
|
||||
inline JSFlatString *
|
||||
NewStringCopyZ(js::ThreadSafeContext *cx, const char *s)
|
||||
{
|
||||
return NewStringCopyN<allowGC>(cx, s, strlen(s));
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert a non-string value to a string, returning null after reporting an
|
||||
* error, otherwise returning a new string reference.
|
||||
|
|
|
@ -6058,7 +6058,7 @@ SetRuntimeOptions(JSRuntime *rt, const OptionParser &op)
|
|||
|
||||
jsCacheDir = op.getStringOption("js-cache");
|
||||
if (jsCacheDir) {
|
||||
if (op.getBoolOption("js-cache-per-process"))
|
||||
if (!op.getBoolOption("no-js-cache-per-process"))
|
||||
jsCacheDir = JS_smprintf("%s/%u", jsCacheDir, (unsigned)getpid());
|
||||
jsCacheAsmJSPath = JS_smprintf("%s/asmjs.cache", jsCacheDir);
|
||||
}
|
||||
|
@ -6100,7 +6100,7 @@ Shell(JSContext *cx, OptionParser *op, char **envp)
|
|||
if (enableDisassemblyDumps)
|
||||
JS_DumpCompartmentPCCounts(cx);
|
||||
|
||||
if (op->getBoolOption("js-cache-per-process")) {
|
||||
if (!op->getBoolOption("no-js-cache-per-process")) {
|
||||
if (jsCacheAsmJSPath)
|
||||
unlink(jsCacheAsmJSPath);
|
||||
if (jsCacheDir)
|
||||
|
@ -6178,11 +6178,12 @@ main(int argc, char **argv, char **envp)
|
|||
|| !op.addStringOption('\0', "js-cache", "[path]",
|
||||
"Enable the JS cache by specifying the path of the directory to use "
|
||||
"to hold cache files")
|
||||
|| !op.addBoolOption('\0', "js-cache-per-process",
|
||||
"Generate a separate cache sub-directory for this process inside "
|
||||
"the cache directory specified by --js-cache. This cache directory "
|
||||
"will be removed when the js shell exits. This is useful for running "
|
||||
"tests in parallel.")
|
||||
|| !op.addBoolOption('\0', "no-js-cache-per-process",
|
||||
"Deactivates cache per process. Otherwise, generate a separate cache"
|
||||
"sub-directory for this process inside the cache directory"
|
||||
"specified by --js-cache. This cache directory will be removed"
|
||||
"when the js shell exits. This is useful for running tests in"
|
||||
"parallel.")
|
||||
#ifdef DEBUG
|
||||
|| !op.addBoolOption('O', "print-alloc", "Print the number of allocations at exit")
|
||||
#endif
|
||||
|
|
|
@ -1088,6 +1088,9 @@ struct JSRuntime : public JS::shadow::Runtime,
|
|||
bool canUseSignalHandlers() const {
|
||||
return canUseSignalHandlers_;
|
||||
}
|
||||
void setCanUseSignalHandlers(bool enable) {
|
||||
canUseSignalHandlers_ = signalHandlersInstalled_ && enable;
|
||||
}
|
||||
|
||||
private:
|
||||
js::FreeOp defaultFreeOp_;
|
||||
|
|
|
@ -895,3 +895,268 @@ JSAtom::dump()
|
|||
this->JSString::dump();
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
JSLinearString *
|
||||
js::NewDependentString(JSContext *cx, JSString *baseArg, size_t start, size_t length)
|
||||
{
|
||||
if (length == 0)
|
||||
return cx->emptyString();
|
||||
|
||||
JSLinearString *base = baseArg->ensureLinear(cx);
|
||||
if (!base)
|
||||
return nullptr;
|
||||
|
||||
if (start == 0 && length == base->length())
|
||||
return base;
|
||||
|
||||
if (base->hasTwoByteChars()) {
|
||||
AutoCheckCannotGC nogc;
|
||||
const jschar *chars = base->twoByteChars(nogc) + start;
|
||||
if (JSLinearString *staticStr = cx->staticStrings().lookup(chars, length))
|
||||
return staticStr;
|
||||
} else {
|
||||
AutoCheckCannotGC nogc;
|
||||
const Latin1Char *chars = base->latin1Chars(nogc) + start;
|
||||
if (JSLinearString *staticStr = cx->staticStrings().lookup(chars, length))
|
||||
return staticStr;
|
||||
}
|
||||
|
||||
return JSDependentString::new_(cx, base, start, length);
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
static void
|
||||
CopyCharsMaybeInflate(jschar *dest, const CharT *src, size_t len);
|
||||
|
||||
template <>
|
||||
void
|
||||
CopyCharsMaybeInflate(jschar *dest, const jschar *src, size_t len)
|
||||
{
|
||||
PodCopy(dest, src, len);
|
||||
}
|
||||
|
||||
template <>
|
||||
void
|
||||
CopyCharsMaybeInflate(jschar *dest, const Latin1Char *src, size_t len)
|
||||
{
|
||||
CopyAndInflateChars(dest, src, len);
|
||||
}
|
||||
|
||||
static bool
|
||||
CanStoreCharsAsLatin1(const jschar *s, size_t length)
|
||||
{
|
||||
if (!EnableLatin1Strings)
|
||||
return false;
|
||||
|
||||
for (const jschar *end = s + length; s < end; ++s) {
|
||||
if (*s > JSString::MAX_LATIN1_CHAR)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
CanStoreCharsAsLatin1(const Latin1Char *s, size_t length)
|
||||
{
|
||||
MOZ_CRASH("Shouldn't be called for Latin1 chars");
|
||||
}
|
||||
|
||||
template <AllowGC allowGC>
|
||||
static MOZ_ALWAYS_INLINE JSInlineString *
|
||||
NewFatInlineStringDeflated(ThreadSafeContext *cx, mozilla::Range<const jschar> chars)
|
||||
{
|
||||
MOZ_ASSERT(EnableLatin1Strings);
|
||||
|
||||
size_t len = chars.length();
|
||||
Latin1Char *storage;
|
||||
JSInlineString *str = AllocateFatInlineString<allowGC>(cx, len, &storage);
|
||||
if (!str)
|
||||
return nullptr;
|
||||
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
MOZ_ASSERT(chars[i] <= JSString::MAX_LATIN1_CHAR);
|
||||
storage[i] = Latin1Char(chars[i]);
|
||||
}
|
||||
storage[len] = '\0';
|
||||
return str;
|
||||
}
|
||||
|
||||
template <AllowGC allowGC>
|
||||
static JSFlatString *
|
||||
NewStringDeflated(ThreadSafeContext *cx, const jschar *s, size_t n)
|
||||
{
|
||||
MOZ_ASSERT(EnableLatin1Strings);
|
||||
|
||||
if (JSFatInlineString::latin1LengthFits(n))
|
||||
return NewFatInlineStringDeflated<allowGC>(cx, mozilla::Range<const jschar>(s, n));
|
||||
|
||||
ScopedJSFreePtr<Latin1Char> news(cx->pod_malloc<Latin1Char>(n + 1));
|
||||
if (!news)
|
||||
return nullptr;
|
||||
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
MOZ_ASSERT(s[i] <= JSString::MAX_LATIN1_CHAR);
|
||||
news.get()[i] = Latin1Char(s[i]);
|
||||
}
|
||||
news[n] = '\0';
|
||||
|
||||
JSFlatString *str = JSFlatString::new_<allowGC>(cx, news.get(), n);
|
||||
if (!str)
|
||||
return nullptr;
|
||||
|
||||
news.forget();
|
||||
return str;
|
||||
}
|
||||
|
||||
template <AllowGC allowGC>
|
||||
static JSFlatString *
|
||||
NewStringDeflated(ThreadSafeContext *cx, const Latin1Char *s, size_t n)
|
||||
{
|
||||
MOZ_CRASH("Shouldn't be called for Latin1 chars");
|
||||
}
|
||||
|
||||
template <AllowGC allowGC, typename CharT>
|
||||
JSFlatString *
|
||||
js::NewStringDontDeflate(ThreadSafeContext *cx, CharT *chars, size_t length)
|
||||
{
|
||||
if (length == 1) {
|
||||
jschar c = chars[0];
|
||||
if (StaticStrings::hasUnit(c)) {
|
||||
// Free |chars| because we're taking possession of it, but it's no
|
||||
// longer needed because we use the static string instead.
|
||||
js_free(chars);
|
||||
return cx->staticStrings().getUnit(c);
|
||||
}
|
||||
}
|
||||
|
||||
return JSFlatString::new_<allowGC>(cx, chars, length);
|
||||
}
|
||||
|
||||
template JSFlatString *
|
||||
js::NewStringDontDeflate<CanGC>(ThreadSafeContext *cx, jschar *chars, size_t length);
|
||||
|
||||
template JSFlatString *
|
||||
js::NewStringDontDeflate<NoGC>(ThreadSafeContext *cx, jschar *chars, size_t length);
|
||||
|
||||
template JSFlatString *
|
||||
js::NewStringDontDeflate<CanGC>(ThreadSafeContext *cx, Latin1Char *chars, size_t length);
|
||||
|
||||
template JSFlatString *
|
||||
js::NewStringDontDeflate<NoGC>(ThreadSafeContext *cx, Latin1Char *chars, size_t length);
|
||||
|
||||
template <AllowGC allowGC, typename CharT>
|
||||
JSFlatString *
|
||||
js::NewString(ThreadSafeContext *cx, CharT *chars, size_t length)
|
||||
{
|
||||
if (IsSame<CharT, jschar>::value && CanStoreCharsAsLatin1(chars, length)) {
|
||||
if (length == 1) {
|
||||
jschar c = chars[0];
|
||||
if (StaticStrings::hasUnit(c)) {
|
||||
js_free(chars);
|
||||
return cx->staticStrings().getUnit(c);
|
||||
}
|
||||
}
|
||||
|
||||
JSFlatString *s = NewStringDeflated<allowGC>(cx, chars, length);
|
||||
if (!s)
|
||||
return nullptr;
|
||||
|
||||
// Free |chars| because we're taking possession of it but not using it.
|
||||
js_free(chars);
|
||||
return s;
|
||||
}
|
||||
|
||||
return NewStringDontDeflate<allowGC>(cx, chars, length);
|
||||
}
|
||||
|
||||
template JSFlatString *
|
||||
js::NewString<CanGC>(ThreadSafeContext *cx, jschar *chars, size_t length);
|
||||
|
||||
template JSFlatString *
|
||||
js::NewString<NoGC>(ThreadSafeContext *cx, jschar *chars, size_t length);
|
||||
|
||||
template JSFlatString *
|
||||
js::NewString<CanGC>(ThreadSafeContext *cx, Latin1Char *chars, size_t length);
|
||||
|
||||
template JSFlatString *
|
||||
js::NewString<NoGC>(ThreadSafeContext *cx, Latin1Char *chars, size_t length);
|
||||
|
||||
namespace js {
|
||||
|
||||
template <AllowGC allowGC, typename CharT>
|
||||
JSFlatString *
|
||||
NewStringCopyNDontDeflate(ThreadSafeContext *cx, const CharT *s, size_t n)
|
||||
{
|
||||
if (EnableLatin1Strings) {
|
||||
if (JSFatInlineString::lengthFits<CharT>(n))
|
||||
return NewFatInlineString<allowGC>(cx, mozilla::Range<const CharT>(s, n));
|
||||
|
||||
ScopedJSFreePtr<CharT> news(cx->pod_malloc<CharT>(n + 1));
|
||||
if (!news)
|
||||
return nullptr;
|
||||
|
||||
PodCopy(news.get(), s, n);
|
||||
news[n] = 0;
|
||||
|
||||
JSFlatString *str = JSFlatString::new_<allowGC>(cx, news.get(), n);
|
||||
if (!str)
|
||||
return nullptr;
|
||||
|
||||
news.forget();
|
||||
return str;
|
||||
}
|
||||
|
||||
if (JSFatInlineString::twoByteLengthFits(n))
|
||||
return NewFatInlineString<allowGC>(cx, mozilla::Range<const CharT>(s, n));
|
||||
|
||||
ScopedJSFreePtr<jschar> news(cx->pod_malloc<jschar>(n + 1));
|
||||
if (!news)
|
||||
return nullptr;
|
||||
|
||||
CopyCharsMaybeInflate(news.get(), s, n);
|
||||
news[n] = 0;
|
||||
|
||||
JSFlatString *str = JSFlatString::new_<allowGC>(cx, news.get(), n);
|
||||
if (!str)
|
||||
return nullptr;
|
||||
|
||||
news.forget();
|
||||
return str;
|
||||
}
|
||||
|
||||
template JSFlatString *
|
||||
NewStringCopyNDontDeflate<CanGC>(ThreadSafeContext *cx, const jschar *s, size_t n);
|
||||
|
||||
template JSFlatString *
|
||||
NewStringCopyNDontDeflate<NoGC>(ThreadSafeContext *cx, const jschar *s, size_t n);
|
||||
|
||||
template JSFlatString *
|
||||
NewStringCopyNDontDeflate<CanGC>(ThreadSafeContext *cx, const Latin1Char *s, size_t n);
|
||||
|
||||
template JSFlatString *
|
||||
NewStringCopyNDontDeflate<NoGC>(ThreadSafeContext *cx, const Latin1Char *s, size_t n);
|
||||
|
||||
template <AllowGC allowGC, typename CharT>
|
||||
JSFlatString *
|
||||
NewStringCopyN(ThreadSafeContext *cx, const CharT *s, size_t n)
|
||||
{
|
||||
if (IsSame<CharT, jschar>::value && CanStoreCharsAsLatin1(s, n))
|
||||
return NewStringDeflated<allowGC>(cx, s, n);
|
||||
|
||||
return NewStringCopyNDontDeflate<allowGC>(cx, s, n);
|
||||
}
|
||||
|
||||
template JSFlatString *
|
||||
NewStringCopyN<CanGC>(ThreadSafeContext *cx, const jschar *s, size_t n);
|
||||
|
||||
template JSFlatString *
|
||||
NewStringCopyN<NoGC>(ThreadSafeContext *cx, const jschar *s, size_t n);
|
||||
|
||||
template JSFlatString *
|
||||
NewStringCopyN<CanGC>(ThreadSafeContext *cx, const Latin1Char *s, size_t n);
|
||||
|
||||
template JSFlatString *
|
||||
NewStringCopyN<NoGC>(ThreadSafeContext *cx, const Latin1Char *s, size_t n);
|
||||
|
||||
} /* namespace js */
|
||||
|
|
|
@ -1177,6 +1177,51 @@ template <typename CharT>
|
|||
void
|
||||
CopyChars(CharT *dest, const JSLinearString &str);
|
||||
|
||||
/* GC-allocate a string descriptor for the given malloc-allocated chars. */
|
||||
template <js::AllowGC allowGC, typename CharT>
|
||||
extern JSFlatString *
|
||||
NewString(js::ThreadSafeContext *cx, CharT *chars, size_t length);
|
||||
|
||||
/* Like NewString, but doesn't try to deflate to Latin1. */
|
||||
template <js::AllowGC allowGC, typename CharT>
|
||||
extern JSFlatString *
|
||||
NewStringDontDeflate(js::ThreadSafeContext *cx, CharT *chars, size_t length);
|
||||
|
||||
extern JSLinearString *
|
||||
NewDependentString(JSContext *cx, JSString *base, size_t start, size_t length);
|
||||
|
||||
/* Copy a counted string and GC-allocate a descriptor for it. */
|
||||
template <js::AllowGC allowGC, typename CharT>
|
||||
extern JSFlatString *
|
||||
NewStringCopyN(js::ThreadSafeContext *cx, const CharT *s, size_t n);
|
||||
|
||||
template <js::AllowGC allowGC>
|
||||
inline JSFlatString *
|
||||
NewStringCopyN(ThreadSafeContext *cx, const char *s, size_t n)
|
||||
{
|
||||
return NewStringCopyN<allowGC>(cx, reinterpret_cast<const Latin1Char *>(s), n);
|
||||
}
|
||||
|
||||
/* Like NewStringCopyN, but doesn't try to deflate to Latin1. */
|
||||
template <js::AllowGC allowGC, typename CharT>
|
||||
extern JSFlatString *
|
||||
NewStringCopyNDontDeflate(js::ThreadSafeContext *cx, const CharT *s, size_t n);
|
||||
|
||||
/* Copy a C string and GC-allocate a descriptor for it. */
|
||||
template <js::AllowGC allowGC>
|
||||
inline JSFlatString *
|
||||
NewStringCopyZ(js::ExclusiveContext *cx, const jschar *s)
|
||||
{
|
||||
return NewStringCopyN<allowGC>(cx, s, js_strlen(s));
|
||||
}
|
||||
|
||||
template <js::AllowGC allowGC>
|
||||
inline JSFlatString *
|
||||
NewStringCopyZ(js::ThreadSafeContext *cx, const char *s)
|
||||
{
|
||||
return NewStringCopyN<allowGC>(cx, s, strlen(s));
|
||||
}
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
// Addon IDs are interned atoms which are never destroyed. This detail is
|
||||
|
|
|
@ -161,7 +161,7 @@ AutoCxPusher::~AutoCxPusher()
|
|||
}
|
||||
|
||||
bool
|
||||
AutoCxPusher::IsStackTop()
|
||||
AutoCxPusher::IsStackTop() const
|
||||
{
|
||||
uint32_t currentDepth = XPCJSRuntime::Get()->GetJSContextStack()->Count();
|
||||
MOZ_ASSERT(currentDepth >= mStackDepthAfterPush);
|
||||
|
|
|
@ -36,7 +36,7 @@ public:
|
|||
|
||||
// Returns true if this AutoCxPusher performed the push that is currently at
|
||||
// the top of the cx stack.
|
||||
bool IsStackTop();
|
||||
bool IsStackTop() const;
|
||||
|
||||
private:
|
||||
mozilla::Maybe<JSAutoRequest> mAutoRequest;
|
||||
|
|
|
@ -6,7 +6,6 @@ frameworks/av/include/media/stagefright/foundation/ADebug.h
|
|||
frameworks/av/include/media/stagefright/foundation/AHandler.h
|
||||
frameworks/av/include/media/stagefright/foundation/AString.h
|
||||
frameworks/av/include/media/stagefright/foundation/hexdump.h
|
||||
frameworks/av/include/media/stagefright/MediaBufferGroup.h
|
||||
frameworks/av/include/media/stagefright/MediaDefs.h
|
||||
frameworks/av/include/media/stagefright/MediaErrors.h
|
||||
frameworks/av/include/media/stagefright/MediaExtractor.h
|
||||
|
|
|
@ -54,8 +54,8 @@ public:
|
|||
|
||||
MediaBuffer(const sp<ABuffer> &buffer);
|
||||
|
||||
// Decrements the reference count and returns the buffer to its
|
||||
// associated MediaBufferGroup if the reference count drops to 0.
|
||||
// Decrements the reference count and deletes it if the reference
|
||||
// count drops to 0.
|
||||
void release();
|
||||
|
||||
// Increments the reference count.
|
||||
|
|
|
@ -1,58 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2009 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef MEDIA_BUFFER_GROUP_H_
|
||||
|
||||
#define MEDIA_BUFFER_GROUP_H_
|
||||
|
||||
#include <media/stagefright/MediaBuffer.h>
|
||||
#include <utils/Errors.h>
|
||||
#include <utils/threads.h>
|
||||
|
||||
namespace stagefright {
|
||||
|
||||
class MediaBuffer;
|
||||
class MetaData;
|
||||
|
||||
class MediaBufferGroup : public MediaBufferObserver {
|
||||
public:
|
||||
MediaBufferGroup();
|
||||
~MediaBufferGroup();
|
||||
|
||||
void add_buffer(MediaBuffer *buffer);
|
||||
|
||||
// Blocks until a buffer is available and returns it to the caller,
|
||||
// the returned buffer will have a reference count of 1.
|
||||
status_t acquire_buffer(MediaBuffer **buffer);
|
||||
|
||||
protected:
|
||||
virtual void signalBufferReturned(MediaBuffer *buffer);
|
||||
|
||||
private:
|
||||
friend class MediaBuffer;
|
||||
|
||||
Mutex mLock;
|
||||
Condition mCondition;
|
||||
|
||||
MediaBuffer *mFirstBuffer, *mLastBuffer;
|
||||
|
||||
MediaBufferGroup(const MediaBufferGroup &);
|
||||
MediaBufferGroup &operator=(const MediaBufferGroup &);
|
||||
};
|
||||
|
||||
} // namespace stagefright
|
||||
|
||||
#endif // MEDIA_BUFFER_GROUP_H_
|
|
@ -33,7 +33,6 @@
|
|||
#include <media/stagefright/foundation/ADebug.h>
|
||||
#include <media/stagefright/foundation/AMessage.h>
|
||||
#include <media/stagefright/MediaBuffer.h>
|
||||
#include <media/stagefright/MediaBufferGroup.h>
|
||||
#include <media/stagefright/MediaDefs.h>
|
||||
#include <media/stagefright/MediaSource.h>
|
||||
#include <media/stagefright/MetaData.h>
|
||||
|
@ -98,8 +97,6 @@ private:
|
|||
|
||||
bool mStarted;
|
||||
|
||||
MediaBufferGroup *mGroup;
|
||||
|
||||
MediaBuffer *mBuffer;
|
||||
|
||||
bool mWantsNALFragments;
|
||||
|
@ -2392,7 +2389,6 @@ MPEG4Source::MPEG4Source(
|
|||
mIsAVC(false),
|
||||
mNALLengthSize(0),
|
||||
mStarted(false),
|
||||
mGroup(NULL),
|
||||
mBuffer(NULL),
|
||||
mWantsNALFragments(false),
|
||||
mSrcBuffer(NULL) {
|
||||
|
@ -2459,13 +2455,9 @@ status_t MPEG4Source::start(MetaData *params) {
|
|||
mWantsNALFragments = false;
|
||||
}
|
||||
|
||||
mGroup = new MediaBufferGroup;
|
||||
|
||||
int32_t max_size;
|
||||
CHECK(mFormat->findInt32(kKeyMaxInputSize, &max_size));
|
||||
|
||||
mGroup->add_buffer(new MediaBuffer(max_size));
|
||||
|
||||
mSrcBuffer = new uint8_t[max_size];
|
||||
|
||||
mStarted = true;
|
||||
|
@ -2486,9 +2478,6 @@ status_t MPEG4Source::stop() {
|
|||
delete[] mSrcBuffer;
|
||||
mSrcBuffer = NULL;
|
||||
|
||||
delete mGroup;
|
||||
mGroup = NULL;
|
||||
|
||||
mStarted = false;
|
||||
mCurrentSampleIndex = 0;
|
||||
|
||||
|
@ -3169,12 +3158,10 @@ status_t MPEG4Source::read(
|
|||
return err;
|
||||
}
|
||||
|
||||
err = mGroup->acquire_buffer(&mBuffer);
|
||||
|
||||
if (err != OK) {
|
||||
CHECK(mBuffer == NULL);
|
||||
return err;
|
||||
}
|
||||
int32_t max_size;
|
||||
CHECK(mFormat->findInt32(kKeyMaxInputSize, &max_size));
|
||||
mBuffer = new MediaBuffer(max_size);
|
||||
assert(mBuffer);
|
||||
}
|
||||
|
||||
if (!mIsAVC || mWantsNALFragments) {
|
||||
|
@ -3439,13 +3426,10 @@ status_t MPEG4Source::fragmentedRead(
|
|||
mCurrentTime += smpl->duration;
|
||||
isSyncSample = (mCurrentSampleIndex == 0); // XXX
|
||||
|
||||
status_t err = mGroup->acquire_buffer(&mBuffer);
|
||||
|
||||
if (err != OK) {
|
||||
CHECK(mBuffer == NULL);
|
||||
ALOGV("acquire_buffer returned %d", err);
|
||||
return err;
|
||||
}
|
||||
int32_t max_size;
|
||||
CHECK(mFormat->findInt32(kKeyMaxInputSize, &max_size));
|
||||
mBuffer = new MediaBuffer(max_size);
|
||||
assert(mBuffer);
|
||||
}
|
||||
|
||||
const Sample *smpl = &mCurrentSamples[mCurrentSampleIndex];
|
||||
|
@ -3454,7 +3438,7 @@ status_t MPEG4Source::fragmentedRead(
|
|||
if (smpl->encryptedsizes.size()) {
|
||||
// store clear/encrypted lengths in metadata
|
||||
bufmeta->setData(kKeyPlainSizes, 0,
|
||||
smpl->clearsizes.array(), smpl->clearsizes.size() * 4);
|
||||
smpl->clearsizes.array(), smpl->clearsizes.size() * 2);
|
||||
bufmeta->setData(kKeyEncryptedSizes, 0,
|
||||
smpl->encryptedsizes.array(), smpl->encryptedsizes.size() * 4);
|
||||
bufmeta->setData(kKeyCryptoIV, 0, smpl->iv, 16); // use 16 or the actual size?
|
||||
|
|
|
@ -1,89 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2009 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#undef LOG_TAG
|
||||
#define LOG_TAG "MediaBufferGroup"
|
||||
#include <utils/Log.h>
|
||||
|
||||
#include <media/stagefright/foundation/ADebug.h>
|
||||
#include <media/stagefright/MediaBuffer.h>
|
||||
#include <media/stagefright/MediaBufferGroup.h>
|
||||
|
||||
namespace stagefright {
|
||||
|
||||
MediaBufferGroup::MediaBufferGroup()
|
||||
: mFirstBuffer(NULL),
|
||||
mLastBuffer(NULL) {
|
||||
}
|
||||
|
||||
MediaBufferGroup::~MediaBufferGroup() {
|
||||
MediaBuffer *next;
|
||||
for (MediaBuffer *buffer = mFirstBuffer; buffer != NULL;
|
||||
buffer = next) {
|
||||
next = buffer->nextBuffer();
|
||||
|
||||
CHECK_EQ(buffer->refcount(), 0);
|
||||
|
||||
buffer->setObserver(NULL);
|
||||
buffer->release();
|
||||
}
|
||||
}
|
||||
|
||||
void MediaBufferGroup::add_buffer(MediaBuffer *buffer) {
|
||||
Mutex::Autolock autoLock(mLock);
|
||||
|
||||
buffer->setObserver(this);
|
||||
|
||||
if (mLastBuffer) {
|
||||
mLastBuffer->setNextBuffer(buffer);
|
||||
} else {
|
||||
mFirstBuffer = buffer;
|
||||
}
|
||||
|
||||
mLastBuffer = buffer;
|
||||
}
|
||||
|
||||
status_t MediaBufferGroup::acquire_buffer(MediaBuffer **out) {
|
||||
Mutex::Autolock autoLock(mLock);
|
||||
|
||||
for (;;) {
|
||||
for (MediaBuffer *buffer = mFirstBuffer;
|
||||
buffer != NULL; buffer = buffer->nextBuffer()) {
|
||||
if (buffer->refcount() == 0) {
|
||||
buffer->add_ref();
|
||||
buffer->reset();
|
||||
|
||||
*out = buffer;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
// All buffers are in use. Block until one of them is returned to us.
|
||||
mCondition.wait(mLock);
|
||||
}
|
||||
|
||||
exit:
|
||||
return OK;
|
||||
}
|
||||
|
||||
void MediaBufferGroup::signalBufferReturned(MediaBuffer *) {
|
||||
Mutex::Autolock autoLock(mLock);
|
||||
mCondition.signal();
|
||||
}
|
||||
|
||||
} // namespace stagefright
|
||||
|
||||
#undef LOG_TAG
|
|
@ -75,7 +75,6 @@ UNIFIED_SOURCES += [
|
|||
'frameworks/av/media/libstagefright/foundation/AString.cpp',
|
||||
'frameworks/av/media/libstagefright/id3/ID3.cpp',
|
||||
'frameworks/av/media/libstagefright/MediaBuffer.cpp',
|
||||
'frameworks/av/media/libstagefright/MediaBufferGroup.cpp',
|
||||
'frameworks/av/media/libstagefright/MediaDefs.cpp',
|
||||
'frameworks/av/media/libstagefright/MediaSource.cpp',
|
||||
'frameworks/av/media/libstagefright/MPEG4Extractor.cpp',
|
||||
|
|
|
@ -278,9 +278,9 @@ namespace CSF
|
|||
*/
|
||||
virtual void originateP2PCall (cc_sdp_direction_t video_pref, const std::string & digits, const std::string & ip) = 0;
|
||||
|
||||
virtual void createOffer (cc_media_constraints_t* constraints, Timecard *) = 0;
|
||||
virtual void createOffer (cc_media_options_t* options, Timecard *) = 0;
|
||||
|
||||
virtual void createAnswer(cc_media_constraints_t* constraints, Timecard *) = 0;
|
||||
virtual void createAnswer(Timecard *) = 0;
|
||||
|
||||
virtual void setLocalDescription(cc_jsep_action_t action, const std::string & sdp, Timecard *) = 0;
|
||||
|
||||
|
@ -290,8 +290,7 @@ namespace CSF
|
|||
|
||||
virtual void addStream(cc_media_stream_id_t stream_id,
|
||||
cc_media_track_id_t track_id,
|
||||
cc_media_type_t media_type,
|
||||
cc_media_constraints_t *constraints) = 0;
|
||||
cc_media_type_t media_type) = 0;
|
||||
|
||||
virtual void removeStream(cc_media_stream_id_t stream_id, cc_media_track_id_t track_id, cc_media_type_t media_type) = 0;
|
||||
|
||||
|
|
|
@ -151,6 +151,7 @@ public:
|
|||
virtual int SendRTCPPacket(int channel, const void *data, int len) ;
|
||||
|
||||
|
||||
virtual uint64_t CodecPluginID() { return 0; }
|
||||
|
||||
WebrtcAudioConduit():
|
||||
mOtherDirection(nullptr),
|
||||
|
|
|
@ -192,21 +192,31 @@ public:
|
|||
unsigned int* packetsSent,
|
||||
uint64_t* bytesSent) = 0;
|
||||
|
||||
virtual uint64_t CodecPluginID() = 0;
|
||||
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaSessionConduit)
|
||||
|
||||
};
|
||||
|
||||
// Abstract base classes for external encoder/decoder.
|
||||
class VideoEncoder
|
||||
class CodecPluginID
|
||||
{
|
||||
public:
|
||||
virtual ~VideoEncoder() {};
|
||||
virtual ~CodecPluginID() {}
|
||||
|
||||
virtual const uint64_t PluginID() = 0;
|
||||
};
|
||||
|
||||
class VideoDecoder
|
||||
class VideoEncoder : public CodecPluginID
|
||||
{
|
||||
public:
|
||||
virtual ~VideoDecoder() {};
|
||||
virtual ~VideoEncoder() {}
|
||||
};
|
||||
|
||||
class VideoDecoder : public CodecPluginID
|
||||
{
|
||||
public:
|
||||
virtual ~VideoDecoder() {}
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -1438,4 +1438,15 @@ WebrtcVideoConduit::MozVideoLatencyAvg()
|
|||
return mVideoLatencyAvg / sRoundingPadding;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
WebrtcVideoConduit::CodecPluginID()
|
||||
{
|
||||
if (mExternalSendCodecHandle) {
|
||||
return mExternalSendCodecHandle->PluginID();
|
||||
} else if (mExternalRecvCodecHandle) {
|
||||
return mExternalRecvCodecHandle->PluginID();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
}// end namespace
|
||||
|
|
|
@ -199,6 +199,8 @@ public:
|
|||
#endif
|
||||
}
|
||||
|
||||
virtual uint64_t CodecPluginID();
|
||||
|
||||
unsigned short SendingWidth() {
|
||||
return mSendingWidth;
|
||||
}
|
||||
|
|
|
@ -33,8 +33,6 @@
|
|||
#include "GMPVideoDecoderProxy.h"
|
||||
#include "GMPVideoEncoderProxy.h"
|
||||
|
||||
#include "WebrtcGmpVideoCodec.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class WebrtcGmpVideoEncoder : public WebrtcVideoEncoder,
|
||||
|
@ -45,6 +43,11 @@ public:
|
|||
virtual ~WebrtcGmpVideoEncoder() {}
|
||||
|
||||
// Implement VideoEncoder interface.
|
||||
virtual const uint64_t PluginID() MOZ_OVERRIDE
|
||||
{
|
||||
return mGMP ? mGMP->ParentID() : 0;
|
||||
}
|
||||
|
||||
virtual int32_t InitEncode(const webrtc::VideoCodec* aCodecSettings,
|
||||
int32_t aNumberOfCores,
|
||||
uint32_t aMaxPayloadSize);
|
||||
|
@ -97,6 +100,11 @@ public:
|
|||
virtual ~WebrtcGmpVideoDecoder() {}
|
||||
|
||||
// Implement VideoDecoder interface.
|
||||
virtual const uint64_t PluginID() MOZ_OVERRIDE
|
||||
{
|
||||
return mGMP ? mGMP->ParentID() : 0;
|
||||
}
|
||||
|
||||
virtual int32_t InitDecode(const webrtc::VideoCodec* aCodecSettings,
|
||||
int32_t aNumberOfCores);
|
||||
virtual int32_t Decode(const webrtc::EncodedImage& aInputImage,
|
||||
|
|
|
@ -35,6 +35,8 @@ public:
|
|||
virtual ~WebrtcOMXH264VideoEncoder();
|
||||
|
||||
// Implement VideoEncoder interface.
|
||||
virtual const uint64_t PluginID() MOZ_OVERRIDE { return 0; }
|
||||
|
||||
virtual int32_t InitEncode(const webrtc::VideoCodec* aCodecSettings,
|
||||
int32_t aNumOfCores,
|
||||
uint32_t aMaxPayloadSize) MOZ_OVERRIDE;
|
||||
|
@ -77,6 +79,8 @@ public:
|
|||
virtual ~WebrtcOMXH264VideoDecoder();
|
||||
|
||||
// Implement VideoDecoder interface.
|
||||
virtual const uint64_t PluginID() MOZ_OVERRIDE { return 0; }
|
||||
|
||||
virtual int32_t InitDecode(const webrtc::VideoCodec* aCodecSettings,
|
||||
int32_t aNumOfCores) MOZ_OVERRIDE;
|
||||
virtual int32_t Decode(const webrtc::EncodedImage& aInputImage,
|
||||
|
|
|
@ -56,52 +56,48 @@ using namespace dom;
|
|||
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
static void
|
||||
Apply(const Optional<bool> &aSrc, cc_boolean_constraint_t *aDst,
|
||||
bool mandatory = false) {
|
||||
if (aSrc.WasPassed() && (mandatory || !aDst->was_passed)) {
|
||||
Apply(const Optional<bool> &aSrc, cc_boolean_option_t *aDst) {
|
||||
if (aSrc.WasPassed()) {
|
||||
aDst->was_passed = true;
|
||||
aDst->value = aSrc.Value();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
Apply(const Optional<int32_t> &aSrc, cc_int32_option_t *aDst) {
|
||||
if (aSrc.WasPassed()) {
|
||||
aDst->was_passed = true;
|
||||
aDst->value = aSrc.Value();
|
||||
aDst->mandatory = mandatory;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
MediaConstraintsExternal::MediaConstraintsExternal() {
|
||||
memset(&mConstraints, 0, sizeof(mConstraints));
|
||||
SipccOfferOptions::SipccOfferOptions() {
|
||||
memset(&mOptions, 0, sizeof(mOptions));
|
||||
}
|
||||
|
||||
MediaConstraintsExternal::MediaConstraintsExternal(
|
||||
const MediaConstraintsInternal &aSrc) {
|
||||
cc_media_constraints_t* c = &mConstraints;
|
||||
SipccOfferOptions::SipccOfferOptions(
|
||||
const RTCOfferOptions &aSrc) {
|
||||
cc_media_options_t* c = &mOptions;
|
||||
memset(c, 0, sizeof(*c));
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
Apply(aSrc.mMandatory.mOfferToReceiveAudio, &c->offer_to_receive_audio, true);
|
||||
Apply(aSrc.mMandatory.mOfferToReceiveVideo, &c->offer_to_receive_video, true);
|
||||
Apply(aSrc.mOfferToReceiveAudio, &c->offer_to_receive_audio);
|
||||
Apply(aSrc.mOfferToReceiveVideo, &c->offer_to_receive_video);
|
||||
if (!Preferences::GetBool("media.peerconnection.video.enabled", true)) {
|
||||
c->offer_to_receive_video.was_passed = true;
|
||||
c->offer_to_receive_video.value = false;
|
||||
}
|
||||
Apply(aSrc.mMandatory.mMozDontOfferDataChannel, &c->moz_dont_offer_datachannel,
|
||||
true);
|
||||
Apply(aSrc.mMandatory.mMozBundleOnly, &c->moz_bundle_only, true);
|
||||
if (aSrc.mOptional.WasPassed()) {
|
||||
const Sequence<MediaConstraintSet> &array = aSrc.mOptional.Value();
|
||||
for (uint32_t i = 0; i < array.Length(); i++) {
|
||||
Apply(array[i].mOfferToReceiveAudio, &c->offer_to_receive_audio);
|
||||
Apply(array[i].mOfferToReceiveVideo, &c->offer_to_receive_video);
|
||||
Apply(array[i].mMozDontOfferDataChannel, &c->moz_dont_offer_datachannel);
|
||||
Apply(array[i].mMozBundleOnly, &c->moz_bundle_only);
|
||||
}
|
||||
}
|
||||
Apply(aSrc.mMozDontOfferDataChannel, &c->moz_dont_offer_datachannel);
|
||||
Apply(aSrc.mMozBundleOnly, &c->moz_bundle_only);
|
||||
#endif
|
||||
}
|
||||
|
||||
cc_media_constraints_t*
|
||||
MediaConstraintsExternal::build() const {
|
||||
cc_media_constraints_t* cc = (cc_media_constraints_t*)
|
||||
cpr_malloc(sizeof(cc_media_constraints_t));
|
||||
cc_media_options_t*
|
||||
SipccOfferOptions::build() const {
|
||||
cc_media_options_t* cc = (cc_media_options_t*)
|
||||
cpr_malloc(sizeof(cc_media_options_t));
|
||||
if (cc) {
|
||||
*cc = mConstraints;
|
||||
*cc = mOptions;
|
||||
}
|
||||
return cc;
|
||||
}
|
||||
|
|
|
@ -29,15 +29,15 @@ namespace dom {
|
|||
class WebrtcGlobalInformation;
|
||||
}
|
||||
|
||||
// Unit-test helper, because cc_media_constraints_t is hard to forward-declare
|
||||
// Unit-test helper, because cc_media_options_t is hard to forward-declare
|
||||
|
||||
class MediaConstraintsExternal {
|
||||
class SipccOfferOptions {
|
||||
public:
|
||||
MediaConstraintsExternal();
|
||||
MediaConstraintsExternal(const dom::MediaConstraintsInternal &aOther);
|
||||
cc_media_constraints_t* build() const;
|
||||
SipccOfferOptions();
|
||||
SipccOfferOptions(const dom::RTCOfferOptions &aOther);
|
||||
cc_media_options_t* build() const;
|
||||
protected:
|
||||
cc_media_constraints_t mConstraints;
|
||||
cc_media_options_t mOptions;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1083,7 +1083,7 @@ PeerConnectionImpl::CreateDataChannel(const nsAString& aLabel,
|
|||
|
||||
if (!mHaveDataStream) {
|
||||
// XXX stream_id of 0 might confuse things...
|
||||
mInternal->mCall->addStream(0, 2, DATA, 0);
|
||||
mInternal->mCall->addStream(0, 2, DATA);
|
||||
mHaveDataStream = true;
|
||||
}
|
||||
nsIDOMDataChannel *retval;
|
||||
|
@ -1170,14 +1170,14 @@ PeerConnectionImpl::NotifyDataChannel(already_AddRefed<DataChannel> aChannel)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PeerConnectionImpl::CreateOffer(const MediaConstraintsInternal& aConstraints)
|
||||
PeerConnectionImpl::CreateOffer(const RTCOfferOptions& aOptions)
|
||||
{
|
||||
return CreateOffer(MediaConstraintsExternal (aConstraints));
|
||||
return CreateOffer(SipccOfferOptions(aOptions));
|
||||
}
|
||||
|
||||
// Used by unit tests and the IDL CreateOffer.
|
||||
NS_IMETHODIMP
|
||||
PeerConnectionImpl::CreateOffer(const MediaConstraintsExternal& aConstraints)
|
||||
PeerConnectionImpl::CreateOffer(const SipccOfferOptions& aOptions)
|
||||
{
|
||||
PC_AUTO_ENTER_API_CALL(true);
|
||||
|
||||
|
@ -1185,20 +1185,14 @@ PeerConnectionImpl::CreateOffer(const MediaConstraintsExternal& aConstraints)
|
|||
mTimeCard = nullptr;
|
||||
STAMP_TIMECARD(tc, "Create Offer");
|
||||
|
||||
cc_media_constraints_t* cc_constraints = aConstraints.build();
|
||||
NS_ENSURE_TRUE(cc_constraints, NS_ERROR_UNEXPECTED);
|
||||
mInternal->mCall->createOffer(cc_constraints, tc);
|
||||
cc_media_options_t* cc_options = aOptions.build();
|
||||
NS_ENSURE_TRUE(cc_options, NS_ERROR_UNEXPECTED);
|
||||
mInternal->mCall->createOffer(cc_options, tc);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PeerConnectionImpl::CreateAnswer(const MediaConstraintsInternal& aConstraints)
|
||||
{
|
||||
return CreateAnswer(MediaConstraintsExternal (aConstraints));
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PeerConnectionImpl::CreateAnswer(const MediaConstraintsExternal& aConstraints)
|
||||
PeerConnectionImpl::CreateAnswer()
|
||||
{
|
||||
PC_AUTO_ENTER_API_CALL(true);
|
||||
|
||||
|
@ -1206,9 +1200,7 @@ PeerConnectionImpl::CreateAnswer(const MediaConstraintsExternal& aConstraints)
|
|||
mTimeCard = nullptr;
|
||||
STAMP_TIMECARD(tc, "Create Answer");
|
||||
|
||||
cc_media_constraints_t* cc_constraints = aConstraints.build();
|
||||
NS_ENSURE_TRUE(cc_constraints, NS_ERROR_UNEXPECTED);
|
||||
mInternal->mCall->createAnswer(cc_constraints, tc);
|
||||
mInternal->mCall->createAnswer(tc);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1426,15 +1418,7 @@ PeerConnectionImpl::PrincipalChanged(DOMMediaStream* aMediaStream) {
|
|||
#endif
|
||||
|
||||
nsresult
|
||||
PeerConnectionImpl::AddStream(DOMMediaStream &aMediaStream,
|
||||
const MediaConstraintsInternal& aConstraints)
|
||||
{
|
||||
return AddStream(aMediaStream, MediaConstraintsExternal(aConstraints));
|
||||
}
|
||||
|
||||
nsresult
|
||||
PeerConnectionImpl::AddStream(DOMMediaStream &aMediaStream,
|
||||
const MediaConstraintsExternal& aConstraints)
|
||||
PeerConnectionImpl::AddStream(DOMMediaStream &aMediaStream)
|
||||
{
|
||||
PC_AUTO_ENTER_API_CALL(true);
|
||||
|
||||
|
@ -1470,16 +1454,12 @@ PeerConnectionImpl::AddStream(DOMMediaStream &aMediaStream,
|
|||
|
||||
// TODO(ekr@rtfm.com): these integers should be the track IDs
|
||||
if (hints & DOMMediaStream::HINT_CONTENTS_AUDIO) {
|
||||
cc_media_constraints_t* cc_constraints = aConstraints.build();
|
||||
NS_ENSURE_TRUE(cc_constraints, NS_ERROR_UNEXPECTED);
|
||||
mInternal->mCall->addStream(stream_id, 0, AUDIO, cc_constraints);
|
||||
mInternal->mCall->addStream(stream_id, 0, AUDIO);
|
||||
mNumAudioStreams++;
|
||||
}
|
||||
|
||||
if (hints & DOMMediaStream::HINT_CONTENTS_VIDEO) {
|
||||
cc_media_constraints_t* cc_constraints = aConstraints.build();
|
||||
NS_ENSURE_TRUE(cc_constraints, NS_ERROR_UNEXPECTED);
|
||||
mInternal->mCall->addStream(stream_id, 1, VIDEO, cc_constraints);
|
||||
mInternal->mCall->addStream(stream_id, 1, VIDEO);
|
||||
mNumVideoStreams++;
|
||||
}
|
||||
|
||||
|
@ -1656,6 +1636,16 @@ PeerConnectionImpl::Close()
|
|||
return res;
|
||||
}
|
||||
|
||||
bool
|
||||
PeerConnectionImpl::PluginCrash(uint64_t aPluginID)
|
||||
{
|
||||
// fire an event to the DOM window if this is "ours"
|
||||
bool result = mMedia ? mMedia->AnyCodecHasPluginID(aPluginID) : false;
|
||||
if (result) {
|
||||
CSFLogError(logTag, "%s: Our plugin %llu crashed", __FUNCTION__, static_cast<unsigned long long>(aPluginID));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
nsresult
|
||||
PeerConnectionImpl::CloseInt()
|
||||
|
|
|
@ -73,7 +73,7 @@ class DOMMediaStream;
|
|||
|
||||
namespace dom {
|
||||
struct RTCConfiguration;
|
||||
struct MediaConstraintsInternal;
|
||||
struct RTCOfferOptions;
|
||||
class MediaStreamTrack;
|
||||
|
||||
#ifdef USE_FAKE_PCOBSERVER
|
||||
|
@ -84,7 +84,7 @@ class PeerConnectionObserver;
|
|||
typedef NS_ConvertUTF8toUTF16 PCObserverString;
|
||||
#endif
|
||||
}
|
||||
class MediaConstraintsExternal;
|
||||
class SipccOfferOptions;
|
||||
}
|
||||
|
||||
#if defined(__cplusplus) && __cplusplus >= 201103L
|
||||
|
@ -108,8 +108,7 @@ namespace sipcc {
|
|||
|
||||
using mozilla::dom::PeerConnectionObserver;
|
||||
using mozilla::dom::RTCConfiguration;
|
||||
using mozilla::dom::MediaConstraintsInternal;
|
||||
using mozilla::MediaConstraintsExternal;
|
||||
using mozilla::dom::RTCOfferOptions;
|
||||
using mozilla::DOMMediaStream;
|
||||
using mozilla::NrIceCtx;
|
||||
using mozilla::NrIceMediaStream;
|
||||
|
@ -214,13 +213,11 @@ public:
|
|||
|
||||
enum Error {
|
||||
kNoError = 0,
|
||||
kInvalidConstraintsType = 1,
|
||||
kInvalidCandidateType = 2,
|
||||
kInvalidMediastreamTrack = 3,
|
||||
kInvalidState = 4,
|
||||
kInvalidSessionDescription = 5,
|
||||
kIncompatibleSessionDescription = 6,
|
||||
kIncompatibleConstraints = 7,
|
||||
kIncompatibleMediaStreamTrack = 8,
|
||||
kInternalError = 9
|
||||
};
|
||||
|
@ -316,19 +313,18 @@ public:
|
|||
}
|
||||
|
||||
NS_IMETHODIMP_TO_ERRORRESULT(CreateOffer, ErrorResult &rv,
|
||||
const MediaConstraintsInternal& aConstraints)
|
||||
const RTCOfferOptions& aOptions)
|
||||
{
|
||||
rv = CreateOffer(aConstraints);
|
||||
rv = CreateOffer(aOptions);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_TO_ERRORRESULT(CreateAnswer, ErrorResult &rv,
|
||||
const MediaConstraintsInternal& aConstraints)
|
||||
NS_IMETHODIMP CreateAnswer();
|
||||
void CreateAnswer(ErrorResult &rv)
|
||||
{
|
||||
rv = CreateAnswer(aConstraints);
|
||||
rv = CreateAnswer();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP CreateOffer(const MediaConstraintsExternal& aConstraints);
|
||||
NS_IMETHODIMP CreateAnswer(const MediaConstraintsExternal& aConstraints);
|
||||
NS_IMETHODIMP CreateOffer(const mozilla::SipccOfferOptions& aConstraints);
|
||||
|
||||
NS_IMETHODIMP SetLocalDescription (int32_t aAction, const char* aSDP);
|
||||
|
||||
|
@ -368,15 +364,11 @@ public:
|
|||
}
|
||||
|
||||
NS_IMETHODIMP_TO_ERRORRESULT(AddStream, ErrorResult &rv,
|
||||
DOMMediaStream& aMediaStream,
|
||||
const MediaConstraintsInternal& aConstraints)
|
||||
DOMMediaStream& aMediaStream)
|
||||
{
|
||||
rv = AddStream(aMediaStream, aConstraints);
|
||||
rv = AddStream(aMediaStream);
|
||||
}
|
||||
|
||||
nsresult AddStream(DOMMediaStream &aMediaStream,
|
||||
const MediaConstraintsExternal& aConstraints);
|
||||
|
||||
NS_IMETHODIMP_TO_ERRORRESULT(RemoveStream, ErrorResult &rv,
|
||||
DOMMediaStream& aMediaStream)
|
||||
{
|
||||
|
@ -490,6 +482,8 @@ public:
|
|||
rv = Close();
|
||||
}
|
||||
|
||||
bool PluginCrash(uint64_t aPluginID);
|
||||
|
||||
nsresult InitializeDataChannel(int track_id, uint16_t aLocalport,
|
||||
uint16_t aRemoteport, uint16_t aNumstreams);
|
||||
|
||||
|
@ -669,7 +663,7 @@ private:
|
|||
mozilla::RefPtr<DtlsIdentity> mIdentity;
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
// The entity on the other end of the peer-to-peer connection;
|
||||
// void if they are not yet identified, and no constraint has been set
|
||||
// void if they are not yet identified, and no identity setting has been set
|
||||
nsAutoPtr<PeerIdentity> mPeerIdentity;
|
||||
#endif
|
||||
// Whether an app should be prevented from accessing media produced by the PC
|
||||
|
|
|
@ -636,6 +636,46 @@ void RemoteSourceStreamInfo::UpdatePrincipal_m(nsIPrincipal* aPrincipal)
|
|||
}
|
||||
#endif // MOZILLA_INTERNAL_API
|
||||
|
||||
bool
|
||||
PeerConnectionMedia::AnyCodecHasPluginID(uint64_t aPluginID)
|
||||
{
|
||||
for (uint32_t i=0; i < mLocalSourceStreams.Length(); ++i) {
|
||||
if (mLocalSourceStreams[i]->AnyCodecHasPluginID(aPluginID)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for (uint32_t i=0; i < mRemoteSourceStreams.Length(); ++i) {
|
||||
if (mRemoteSourceStreams[i]->AnyCodecHasPluginID(aPluginID)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
LocalSourceStreamInfo::AnyCodecHasPluginID(uint64_t aPluginID)
|
||||
{
|
||||
// Scan the videoConduits for this plugin ID
|
||||
for (auto it = mPipelines.begin(); it != mPipelines.end(); ++it) {
|
||||
if (it->second->Conduit()->CodecPluginID() == aPluginID) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
RemoteSourceStreamInfo::AnyCodecHasPluginID(uint64_t aPluginID)
|
||||
{
|
||||
// Scan the videoConduits for this plugin ID
|
||||
for (auto it = mPipelines.begin(); it != mPipelines.end(); ++it) {
|
||||
if (it->second->Conduit()->CodecPluginID() == aPluginID) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
LocalSourceStreamInfo::StorePipeline(
|
||||
int aTrack, mozilla::RefPtr<mozilla::MediaPipelineTransmit> aPipeline)
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче