merge mozilla-inbound to mozilla-central a=merge

This commit is contained in:
Carsten "Tomcat" Book 2015-10-27 10:55:48 +01:00
commit d43e51f745
370 changed files with 3964 additions and 6965 deletions

View File

@ -190,11 +190,11 @@ DocManager::OnStateChange(nsIWebProgress* aWebProgress,
aWebProgress->GetDOMWindow(getter_AddRefs(DOMWindow));
NS_ENSURE_STATE(DOMWindow);
nsCOMPtr<nsIDOMDocument> DOMDocument;
DOMWindow->GetDocument(getter_AddRefs(DOMDocument));
NS_ENSURE_STATE(DOMDocument);
nsCOMPtr<nsPIDOMWindow> piWindow = do_QueryInterface(DOMWindow);
MOZ_ASSERT(piWindow);
nsCOMPtr<nsIDocument> document(do_QueryInterface(DOMDocument));
nsCOMPtr<nsIDocument> document = piWindow->GetDoc();
NS_ENSURE_STATE(document);
// Document was loaded.
if (aStateFlags & STATE_STOP) {

View File

@ -1,5 +1,5 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim:expandtab:shiftwidth=4:tabstop=4:
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:expandtab:shiftwidth=2:tabstop=2:
*/
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
@ -193,12 +193,10 @@ ApplicationAccessible::CacheChildren()
while (hasMore) {
nsCOMPtr<nsISupports> window;
windowEnumerator->GetNext(getter_AddRefs(window));
nsCOMPtr<nsIDOMWindow> DOMWindow = do_QueryInterface(window);
nsCOMPtr<nsPIDOMWindow> DOMWindow = do_QueryInterface(window);
if (DOMWindow) {
nsCOMPtr<nsIDOMDocument> DOMDocument;
DOMWindow->GetDocument(getter_AddRefs(DOMDocument));
if (DOMDocument) {
nsCOMPtr<nsIDocument> docNode(do_QueryInterface(DOMDocument));
nsCOMPtr<nsIDocument> docNode = DOMWindow->GetDoc();
if (docNode) {
GetAccService()->GetDocAccessible(docNode); // ensure creation
}
}

View File

@ -133,13 +133,12 @@ ImageAccessible::DoAction(uint8_t aIndex)
nsIDocument* document = mContent->OwnerDoc();
nsCOMPtr<nsPIDOMWindow> piWindow = document->GetWindow();
nsCOMPtr<nsIDOMWindow> win = do_QueryInterface(piWindow);
if (!win)
if (!piWindow)
return false;
nsCOMPtr<nsIDOMWindow> tmp;
return NS_SUCCEEDED(win->Open(spec, EmptyString(), EmptyString(),
getter_AddRefs(tmp)));
nsCOMPtr<nsPIDOMWindow> tmp;
return NS_SUCCEEDED(piWindow->Open(spec, EmptyString(), EmptyString(),
getter_AddRefs(tmp)));
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -486,11 +486,9 @@ RootAccessible::RelationByType(RelationType aType)
nsPIDOMWindow* rootWindow = mDocumentNode->GetWindow();
if (rootWindow) {
nsCOMPtr<nsIDOMWindow> contentWindow = nsGlobalWindow::Cast(rootWindow)->GetContent();
if (contentWindow) {
nsCOMPtr<nsIDOMDocument> contentDOMDocument;
contentWindow->GetDocument(getter_AddRefs(contentDOMDocument));
nsCOMPtr<nsIDocument> contentDocumentNode =
do_QueryInterface(contentDOMDocument);
nsCOMPtr<nsPIDOMWindow> piWindow = do_QueryInterface(contentWindow);
if (piWindow) {
nsCOMPtr<nsIDocument> contentDocumentNode = piWindow->GetDoc();
if (contentDocumentNode) {
DocAccessible* contentDocument =
GetAccService()->GetDocAccessible(contentDocumentNode);

View File

@ -56,6 +56,7 @@ LOCAL_INCLUDES += [
'/accessible/xpcom',
'/accessible/xul',
'/dom/base',
'/layout/style',
]
include('/ipc/chromium/chromium-config.mozbuild')

View File

@ -15,13 +15,15 @@
#include "mozilla/Preferences.h"
#include "nsArrayUtils.h"
#include "nsIArray.h"
#include "nsICSSDeclaration.h"
#include "nsIDocument.h"
#include "nsIDocShellTreeItem.h"
#include "nsIDOMElement.h"
#include "mozilla/dom/Element.h"
#include "nsXULAppAPI.h"
using namespace mozilla;
using namespace mozilla::a11y;
using mozilla::dom::Element;
// Window property used by ipc related code in identifying accessible
// tab windows.
@ -43,15 +45,18 @@ nsWinUtils::GetComputedStyleDeclaration(nsIContent* aContent)
return nullptr;
// Returns number of items in style declaration
nsCOMPtr<nsIDOMWindow> window =
nsCOMPtr<nsPIDOMWindow> window =
do_QueryInterface(elm->OwnerDoc()->GetWindow());
if (!window)
return nullptr;
nsCOMPtr<nsIDOMCSSStyleDeclaration> cssDecl;
nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(elm));
window->GetComputedStyle(domElement, EmptyString(), getter_AddRefs(cssDecl));
return cssDecl.forget();
ErrorResult dummy;
nsCOMPtr<nsICSSDeclaration> cssDecl;
nsCOMPtr<Element> domElement(do_QueryInterface(elm));
cssDecl = window->GetComputedStyle(*domElement, EmptyString(), dummy);
nsCOMPtr<nsIDOMCSSStyleDeclaration> domDecl = do_QueryInterface(cssDecl);
dummy.SuppressException();
return domDecl.forget();
}
bool

View File

@ -1025,6 +1025,7 @@ pref("apz.fling_curve_function_x2", "0.80");
pref("apz.fling_curve_function_y2", "1.0");
pref("apz.fling_curve_threshold_inches_per_ms", "0.01");
pref("apz.fling_friction", "0.0019");
pref("apz.fling_snap_friction", "0.015");
pref("apz.max_velocity_inches_per_ms", "0.07");
pref("apz.touch_start_tolerance", "0.1");

View File

@ -357,7 +357,7 @@ function showDefaultSnippets()
}
function fitToWidth() {
if (window.scrollMaxX) {
if (window.scrollMaxX != window.scrollMinX) {
document.body.setAttribute("narrow", "true");
} else if (document.body.hasAttribute("narrow")) {
document.body.removeAttribute("narrow");

View File

@ -4086,7 +4086,7 @@ OverflowableToolbar.prototype = {
let child = this._target.lastChild;
while (child && this._target.scrollLeftMax > 0) {
while (child && this._target.scrollLeftMin != this._target.scrollLeftMax) {
let prevChild = child.previousSibling;
if (child.getAttribute("overflows") != "false") {
@ -4166,7 +4166,7 @@ OverflowableToolbar.prototype = {
if (!this._enabled)
return;
if (this._target.scrollLeftMax > 0) {
if (this._target.scrollLeftMin != this._target.scrollLeftMax) {
this.onOverflow();
} else {
this._moveItemsBackToTheirOrigin();

View File

@ -1181,7 +1181,7 @@ PlacesToolbar.prototype = {
},
updateOverflowStatus: function() {
if (this._rootElt.scrollLeftMax > 0) {
if (this._rootElt.scrollLeftMin != this._rootElt.scrollLeftMax) {
this._onOverflow();
} else {
this._onUnderflow();

View File

@ -340,9 +340,30 @@ BasePrincipal::GetCspJSON(nsAString& outCSPinJSON)
}
NS_IMETHODIMP
BasePrincipal::GetIsNullPrincipal(bool* aIsNullPrincipal)
BasePrincipal::GetIsNullPrincipal(bool* aResult)
{
*aIsNullPrincipal = false;
*aResult = Kind() == eNullPrincipal;
return NS_OK;
}
NS_IMETHODIMP
BasePrincipal::GetIsCodebasePrincipal(bool* aResult)
{
*aResult = Kind() == eCodebasePrincipal;
return NS_OK;
}
NS_IMETHODIMP
BasePrincipal::GetIsExpandedPrincipal(bool* aResult)
{
*aResult = Kind() == eExpandedPrincipal;
return NS_OK;
}
NS_IMETHODIMP
BasePrincipal::GetIsSystemPrincipal(bool* aResult)
{
*aResult = Kind() == eSystemPrincipal;
return NS_OK;
}

View File

@ -147,7 +147,10 @@ public:
NS_IMETHOD GetCsp(nsIContentSecurityPolicy** aCsp) override;
NS_IMETHOD SetCsp(nsIContentSecurityPolicy* aCsp) override;
NS_IMETHOD GetCspJSON(nsAString& outCSPinJSON) override;
NS_IMETHOD GetIsNullPrincipal(bool* aIsNullPrincipal) override;
NS_IMETHOD GetIsNullPrincipal(bool* aResult) override;
NS_IMETHOD GetIsCodebasePrincipal(bool* aResult) override;
NS_IMETHOD GetIsExpandedPrincipal(bool* aResult) override;
NS_IMETHOD GetIsSystemPrincipal(bool* aResult) override;
NS_IMETHOD GetJarPrefix(nsACString& aJarPrefix) final;
NS_IMETHOD GetOriginAttributes(JSContext* aCx, JS::MutableHandle<JS::Value> aVal) final;
NS_IMETHOD GetOriginSuffix(nsACString& aOriginSuffix) final;
@ -171,6 +174,15 @@ public:
uint32_t UserContextId() const { return mOriginAttributes.mUserContextId; }
bool IsInBrowserElement() const { return mOriginAttributes.mInBrowser; }
enum PrincipalKind {
eNullPrincipal,
eCodebasePrincipal,
eExpandedPrincipal,
eSystemPrincipal
};
virtual PrincipalKind Kind() = 0;
protected:
virtual ~BasePrincipal();

View File

@ -20,7 +20,7 @@ interface nsIContentSecurityPolicy;
[ptr] native JSPrincipals(JSPrincipals);
[ptr] native PrincipalArray(nsTArray<nsCOMPtr<nsIPrincipal> >);
[scriptable, builtinclass, uuid(a083acd0-1ebf-4585-85ab-08cfdd9c96bd)]
[scriptable, builtinclass, uuid(86e5fd29-dccb-4547-8918-f224005479a0)]
interface nsIPrincipal : nsISerializable
{
/**
@ -280,11 +280,26 @@ interface nsIPrincipal : nsISerializable
[infallible] readonly attribute boolean unknownAppId;
/**
* Returns true iff this principal is a null principal (corresponding to an
* Returns true iff this is a null principal (corresponding to an
* unknown, hence assumed minimally privileged, security context).
*/
[infallible] readonly attribute boolean isNullPrincipal;
/**
* Returns true iff this principal corresponds to a codebase origin.
*/
[infallible] readonly attribute boolean isCodebasePrincipal;
/**
* Returns true iff this is an expanded principal.
*/
[infallible] readonly attribute boolean isExpandedPrincipal;
/**
* Returns true iff this is the system principal.
*/
[infallible] readonly attribute boolean isSystemPrincipal;
/**
* Returns true if this principal's origin is recognized as being on the
* whitelist of sites that can use the CSS Unprefixing Service.

View File

@ -124,13 +124,6 @@ nsNullPrincipal::MayLoadInternal(nsIURI* aURI)
return false;
}
NS_IMETHODIMP
nsNullPrincipal::GetIsNullPrincipal(bool* aIsNullPrincipal)
{
*aIsNullPrincipal = true;
return NS_OK;
}
NS_IMETHODIMP
nsNullPrincipal::GetBaseDomain(nsACString& aBaseDomain)
{

View File

@ -44,7 +44,6 @@ public:
NS_IMETHOD GetURI(nsIURI** aURI) override;
NS_IMETHOD GetDomain(nsIURI** aDomain) override;
NS_IMETHOD SetDomain(nsIURI* aDomain) override;
NS_IMETHOD GetIsNullPrincipal(bool* aIsNullPrincipal) override;
NS_IMETHOD GetBaseDomain(nsACString& aBaseDomain) override;
nsresult GetOriginInternal(nsACString& aOrigin) override;
@ -59,6 +58,8 @@ public:
virtual void GetScriptLocation(nsACString &aStr) override;
PrincipalKind Kind() override { return eNullPrincipal; }
protected:
virtual ~nsNullPrincipal() {}

View File

@ -49,6 +49,8 @@ public:
*/
static void InitializeStatics();
PrincipalKind Kind() override { return eCodebasePrincipal; }
nsCOMPtr<nsIURI> mDomain;
nsCOMPtr<nsIURI> mCodebase;
// If mCodebaseImmutable is true, mCodebase is non-null and immutable
@ -83,6 +85,8 @@ public:
virtual void GetScriptLocation(nsACString &aStr) override;
nsresult GetOriginInternal(nsACString& aOrigin) override;
PrincipalKind Kind() override { return eExpandedPrincipal; }
protected:
virtual ~nsExpandedPrincipal();

View File

@ -50,6 +50,8 @@ protected:
{
return true;
}
PrincipalKind Kind() override { return eSystemPrincipal; }
};
#endif // nsSystemPrincipal_h__

View File

@ -162,4 +162,16 @@ function run_test() {
checkCrossOrigin(exampleOrg_signedPkg, exampleOrg);
checkCrossOrigin(exampleOrg_signedPkg, exampleOrg_signedPkg_browser);
checkCrossOrigin(exampleOrg_signedPkg, exampleOrg_signedPkg_another);
// Check Principal kinds.
function checkKind(prin, kind) {
do_check_eq(prin.isNullPrincipal, kind == 'nullPrincipal');
do_check_eq(prin.isCodebasePrincipal, kind == 'codebasePrincipal');
do_check_eq(prin.isExpandedPrincipal, kind == 'expandedPrincipal');
do_check_eq(prin.isSystemPrincipal, kind == 'systemPrincipal');
}
checkKind(ssm.createNullPrincipal({}), 'nullPrincipal');
checkKind(ssm.createCodebasePrincipal(makeURI('http://www.example.com'), {}), 'codebasePrincipal');
checkKind(ssm.createExpandedPrincipal([ssm.createCodebasePrincipal(makeURI('http://www.example.com'), {})]), 'expandedPrincipal');
checkKind(ssm.getSystemPrincipal(), 'systemPrincipal');
}

View File

@ -33,6 +33,7 @@ GENERATED_INCLUDES += [
]
LOCAL_INCLUDES += [
'/dom/base',
'/netwerk/base',
'/netwerk/protocol/res',
'/xpcom/components'

View File

@ -313,15 +313,10 @@ nsChromeRegistry::ConvertChromeURL(nsIURI* aChromeURI, nsIURI* *aResult)
// theme stuff
static void FlushSkinBindingsForWindow(nsIDOMWindow* aWindow)
static void FlushSkinBindingsForWindow(nsPIDOMWindow* aWindow)
{
// Get the DOM document.
nsCOMPtr<nsIDOMDocument> domDocument;
aWindow->GetDocument(getter_AddRefs(domDocument));
if (!domDocument)
return;
nsCOMPtr<nsIDocument> document = do_QueryInterface(domDocument);
// Get the document.
nsCOMPtr<nsIDocument> document = aWindow->GetDoc();
if (!document)
return;
@ -345,7 +340,7 @@ NS_IMETHODIMP nsChromeRegistry::RefreshSkins()
nsCOMPtr<nsISupports> protoWindow;
windowEnumerator->GetNext(getter_AddRefs(protoWindow));
if (protoWindow) {
nsCOMPtr<nsIDOMWindow> domWindow = do_QueryInterface(protoWindow);
nsCOMPtr<nsPIDOMWindow> domWindow = do_QueryInterface(protoWindow);
if (domWindow)
FlushSkinBindingsForWindow(domWindow);
}
@ -360,7 +355,7 @@ NS_IMETHODIMP nsChromeRegistry::RefreshSkins()
nsCOMPtr<nsISupports> protoWindow;
windowEnumerator->GetNext(getter_AddRefs(protoWindow));
if (protoWindow) {
nsCOMPtr<nsIDOMWindow> domWindow = do_QueryInterface(protoWindow);
nsCOMPtr<nsPIDOMWindow> domWindow = do_QueryInterface(protoWindow);
if (domWindow)
RefreshWindow(domWindow);
}
@ -382,28 +377,23 @@ nsChromeRegistry::FlushSkinCaches()
}
// XXXbsmedberg: move this to windowmediator
nsresult nsChromeRegistry::RefreshWindow(nsIDOMWindow* aWindow)
nsresult nsChromeRegistry::RefreshWindow(nsPIDOMWindow* aWindow)
{
// Deal with our subframes first.
nsCOMPtr<nsIDOMWindowCollection> frames;
aWindow->GetFrames(getter_AddRefs(frames));
nsCOMPtr<nsIDOMWindowCollection> frames = aWindow->GetFrames();
uint32_t length;
frames->GetLength(&length);
uint32_t j;
for (j = 0; j < length; j++) {
nsCOMPtr<nsIDOMWindow> childWin;
frames->Item(j, getter_AddRefs(childWin));
RefreshWindow(childWin);
nsCOMPtr<nsPIDOMWindow> piWindow = do_QueryInterface(childWin);
RefreshWindow(piWindow);
}
nsresult rv;
// Get the DOM document.
nsCOMPtr<nsIDOMDocument> domDocument;
aWindow->GetDocument(getter_AddRefs(domDocument));
if (!domDocument)
return NS_OK;
nsCOMPtr<nsIDocument> document = do_QueryInterface(domDocument);
// Get the document.
nsCOMPtr<nsIDocument> document = aWindow->GetDoc();
if (!document)
return NS_OK;
@ -521,10 +511,9 @@ nsChromeRegistry::ReloadChrome()
nsCOMPtr<nsISupports> protoWindow;
rv = windowEnumerator->GetNext(getter_AddRefs(protoWindow));
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIDOMWindow> domWindow = do_QueryInterface(protoWindow);
nsCOMPtr<nsPIDOMWindow> domWindow = do_QueryInterface(protoWindow);
if (domWindow) {
nsCOMPtr<nsIDOMLocation> location;
domWindow->GetLocation(getter_AddRefs(location));
nsIDOMLocation* location = domWindow->GetLocation();
if (location) {
rv = location->Reload(false);
if (NS_FAILED(rv)) return rv;

View File

@ -22,7 +22,7 @@
#include "mozilla/FileLocation.h"
class nsIDOMWindow;
class nsPIDOMWindow;
class nsIPrefBranch;
class nsIURL;
@ -95,7 +95,7 @@ protected:
nsresult SelectLocaleFromPref(nsIPrefBranch* prefs);
static nsresult RefreshWindow(nsIDOMWindow* aWindow);
static nsresult RefreshWindow(nsPIDOMWindow* aWindow);
static nsresult GetProviderAndPath(nsIURL* aChromeURL,
nsACString& aProvider, nsACString& aPath);

View File

@ -371,8 +371,10 @@ TiltUtils.DOM = {
aContentWindow)
{
return {
width: aContentWindow.innerWidth + aContentWindow.scrollMaxX,
height: aContentWindow.innerHeight + aContentWindow.scrollMaxY
width: aContentWindow.innerWidth +
aContentWindow.scrollMaxX - aContentWindow.scrollMinX,
height: aContentWindow.innerHeight +
aContentWindow.scrollMaxY - aContentWindow.scrollMinY
};
},

View File

@ -270,8 +270,8 @@ function createScreenshotData(document, args) {
// Bug 961832: GCLI screenshot shows fixed position element in wrong
// position if we don't scroll to top
window.scrollTo(0,0);
width = window.innerWidth + window.scrollMaxX;
height = window.innerHeight + window.scrollMaxY;
width = window.innerWidth + window.scrollMaxX - window.scrollMinX;
height = window.innerHeight + window.scrollMaxY - window.scrollMinY;
}
else if (args.selector) {
({ top, left, width, height } = getRect(window, args.selector, window));

View File

@ -148,8 +148,8 @@ nsDSURIContentListener::DoContent(const nsACString& aContentType,
}
if (loadFlags & nsIChannel::LOAD_RETARGETED_DOCUMENT_URI) {
nsCOMPtr<nsIDOMWindow> domWindow =
mDocShell ? mDocShell->GetWindow() : nullptr;
nsCOMPtr<nsPIDOMWindow> domWindow = do_QueryInterface(
mDocShell ? mDocShell->GetWindow() : nullptr);
NS_ENSURE_TRUE(domWindow, NS_ERROR_FAILURE);
domWindow->Focus();
}
@ -294,7 +294,7 @@ nsDSURIContentListener::CheckOneFrameOptionsPolicy(nsIHttpChannel* aHttpChannel,
// window, if we're not the top. X-F-O: SAMEORIGIN requires that the
// document must be same-origin with top window. X-F-O: DENY requires that
// the document must never be framed.
nsCOMPtr<nsIDOMWindow> thisWindow = mDocShell->GetWindow();
nsCOMPtr<nsPIDOMWindow> thisWindow = mDocShell->GetWindow();
// If we don't have DOMWindow there is no risk of clickjacking
if (!thisWindow) {
return true;
@ -302,8 +302,7 @@ nsDSURIContentListener::CheckOneFrameOptionsPolicy(nsIHttpChannel* aHttpChannel,
// GetScriptableTop, not GetTop, because we want this to respect
// <iframe mozbrowser> boundaries.
nsCOMPtr<nsIDOMWindow> topWindow;
thisWindow->GetScriptableTop(getter_AddRefs(topWindow));
nsCOMPtr<nsPIDOMWindow> topWindow = thisWindow->GetScriptableTop();
// if the document is in the top window, it's not in a frame.
if (thisWindow == topWindow) {

View File

@ -3503,14 +3503,13 @@ nsDocShell::CanAccessItem(nsIDocShellTreeItem* aTargetItem,
return false;
}
nsCOMPtr<nsIDOMWindow> targetWindow = aTargetItem->GetWindow();
nsCOMPtr<nsPIDOMWindow> targetWindow = aTargetItem->GetWindow();
if (!targetWindow) {
NS_ERROR("This should not happen, really");
return false;
}
nsCOMPtr<nsIDOMWindow> targetOpener;
targetWindow->GetOpener(getter_AddRefs(targetOpener));
nsCOMPtr<nsIDOMWindow> targetOpener = targetWindow->GetOpener();
nsCOMPtr<nsIWebNavigation> openerWebNav(do_GetInterface(targetOpener));
nsCOMPtr<nsIDocShellTreeItem> openerItem(do_QueryInterface(openerWebNav));
@ -7490,7 +7489,7 @@ nsDocShell::EndPageLoad(nsIWebProgress* aProgress,
return NS_OK;
}
thisWindow->GetFrameElement(getter_AddRefs(frameElement));
frameElement = thisWindow->GetFrameElement();
if (!frameElement) {
return NS_OK;
}
@ -9739,8 +9738,7 @@ nsDocShell::InternalLoad(nsIURI* aURI,
// So, the best we can do, is to tear down the new window
// that was just created!
//
nsCOMPtr<nsIDOMWindow> domWin = targetDocShell->GetWindow();
if (domWin) {
if (nsCOMPtr<nsPIDOMWindow> domWin = targetDocShell->GetWindow()) {
domWin->Close();
}
}
@ -13006,10 +13004,11 @@ nsDocShell::GetAssociatedWindow(nsIDOMWindow** aWindow)
NS_IMETHODIMP
nsDocShell::GetTopWindow(nsIDOMWindow** aWindow)
{
nsCOMPtr<nsIDOMWindow> win = GetWindow();
nsCOMPtr<nsPIDOMWindow> win = GetWindow();
if (win) {
win->GetTop(aWindow);
win = win->GetTop();
}
win.forget(aWindow);
return NS_OK;
}
@ -13017,23 +13016,19 @@ NS_IMETHODIMP
nsDocShell::GetTopFrameElement(nsIDOMElement** aElement)
{
*aElement = nullptr;
nsCOMPtr<nsIDOMWindow> win = GetWindow();
nsCOMPtr<nsPIDOMWindow> win = GetWindow();
if (!win) {
return NS_OK;
}
nsCOMPtr<nsIDOMWindow> top;
win->GetScriptableTop(getter_AddRefs(top));
nsCOMPtr<nsPIDOMWindow> top = win->GetScriptableTop();
NS_ENSURE_TRUE(top, NS_ERROR_FAILURE);
nsCOMPtr<nsPIDOMWindow> piTop = do_QueryInterface(top);
NS_ENSURE_TRUE(piTop, NS_ERROR_FAILURE);
// GetFrameElementInternal, /not/ GetScriptableFrameElement -- if |top| is
// inside <iframe mozbrowser>, we want to return the iframe, not null.
// And we want to cross the content/chrome boundary.
nsCOMPtr<nsIDOMElement> elt =
do_QueryInterface(piTop->GetFrameElementInternal());
do_QueryInterface(top->GetFrameElementInternal());
elt.forget(aElement);
return NS_OK;
}

View File

@ -158,9 +158,9 @@ nsDocShellEditorData::DetachFromWindow()
mDetachedMakeEditable = mMakeEditable;
mMakeEditable = false;
nsCOMPtr<nsIDOMDocument> domDoc;
domWindow->GetDocument(getter_AddRefs(domDoc));
nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(domDoc);
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(domWindow);
nsCOMPtr<nsIDocument> doc = window->GetDoc();
nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(doc);
if (htmlDoc) {
mDetachedEditingState = htmlDoc->GetEditingState();
}
@ -183,9 +183,9 @@ nsDocShellEditorData::ReattachToWindow(nsIDocShell* aDocShell)
mIsDetached = false;
mMakeEditable = mDetachedMakeEditable;
nsCOMPtr<nsIDOMDocument> domDoc;
domWindow->GetDocument(getter_AddRefs(domDoc));
nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(domDoc);
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(domWindow);
nsCOMPtr<nsIDocument> doc = window->GetDoc();
nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(doc);
if (htmlDoc) {
htmlDoc->SetEditingState(mDetachedEditingState);
}

View File

@ -112,8 +112,7 @@ AudioChannelAgent::InitInternal(nsIDOMWindow* aWindow, int32_t aChannelType,
MOZ_ASSERT(pInnerWindow->IsInnerWindow());
mInnerWindowID = pInnerWindow->WindowID();
nsCOMPtr<nsIDOMWindow> topWindow;
aWindow->GetScriptableTop(getter_AddRefs(topWindow));
nsCOMPtr<nsPIDOMWindow> topWindow = pInnerWindow->GetScriptableTop();
if (NS_WARN_IF(!topWindow)) {
return NS_OK;
}

View File

@ -97,18 +97,16 @@ NotifyChannelActive(uint64_t aWindowID, AudioChannel aAudioChannel,
}
already_AddRefed<nsPIDOMWindow>
GetTopWindow(nsIDOMWindow* aWindow)
GetTopWindow(nsPIDOMWindow* aWindow)
{
MOZ_ASSERT(aWindow);
nsCOMPtr<nsIDOMWindow> topWindow;
aWindow->GetScriptableTop(getter_AddRefs(topWindow));
nsCOMPtr<nsPIDOMWindow> topWindow = aWindow->GetScriptableTop();
MOZ_ASSERT(topWindow);
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(topWindow);
window = window->GetOuterWindow();
topWindow = topWindow->GetOuterWindow();
return window.forget();
return topWindow.forget();
}
bool
@ -347,8 +345,7 @@ AudioChannelService::GetState(nsPIDOMWindow* aWindow, uint32_t aAudioChannel,
*aVolume *= window->GetAudioVolume();
*aMuted = *aMuted || window->GetAudioMuted();
nsCOMPtr<nsIDOMWindow> win;
window->GetScriptableParent(getter_AddRefs(win));
nsCOMPtr<nsPIDOMWindow> win = window->GetScriptableParent();
if (window == win) {
break;
}
@ -540,14 +537,12 @@ AudioChannelService::RefreshAgentsVolume(nsPIDOMWindow* aWindow)
MOZ_ASSERT(aWindow);
MOZ_ASSERT(aWindow->IsOuterWindow());
nsCOMPtr<nsIDOMWindow> topWindow;
aWindow->GetScriptableTop(getter_AddRefs(topWindow));
nsCOMPtr<nsPIDOMWindow> pTopWindow = do_QueryInterface(topWindow);
if (!pTopWindow) {
nsCOMPtr<nsPIDOMWindow> topWindow = aWindow->GetScriptableTop();
if (!topWindow) {
return;
}
AudioChannelWindow* winData = GetWindowData(pTopWindow->WindowID());
AudioChannelWindow* winData = GetWindowData(topWindow->WindowID());
if (!winData) {
return;
}
@ -566,14 +561,12 @@ AudioChannelService::RefreshAgentsCapture(nsPIDOMWindow* aWindow,
MOZ_ASSERT(aWindow);
MOZ_ASSERT(aWindow->IsOuterWindow());
nsCOMPtr<nsIDOMWindow> topWindow;
aWindow->GetScriptableTop(getter_AddRefs(topWindow));
nsCOMPtr<nsPIDOMWindow> pTopWindow = do_QueryInterface(topWindow);
if (!pTopWindow) {
nsCOMPtr<nsPIDOMWindow> topWindow = aWindow->GetScriptableTop();
if (!topWindow) {
return;
}
AudioChannelWindow* winData = GetWindowData(pTopWindow->WindowID());
AudioChannelWindow* winData = GetWindowData(topWindow->WindowID());
// This can happen, but only during shutdown, because the the outer window
// changes ScriptableTop, so that its ID is different.
@ -707,7 +700,8 @@ AudioChannelService::GetAudioChannelVolume(nsIDOMWindow* aWindow,
{
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsPIDOMWindow> window = GetTopWindow(aWindow);
nsCOMPtr<nsPIDOMWindow> piWindow = do_QueryInterface(aWindow);
nsCOMPtr<nsPIDOMWindow> window = GetTopWindow(piWindow);
MOZ_ASSERT(window->IsOuterWindow());
*aVolume = GetAudioChannelVolume(window, (AudioChannel)aAudioChannel);
return NS_OK;
@ -734,7 +728,8 @@ AudioChannelService::SetAudioChannelVolume(nsIDOMWindow* aWindow,
{
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsPIDOMWindow> window = GetTopWindow(aWindow);
nsCOMPtr<nsPIDOMWindow> piWindow = do_QueryInterface(aWindow);
nsCOMPtr<nsPIDOMWindow> window = GetTopWindow(piWindow);
MOZ_ASSERT(window->IsOuterWindow());
SetAudioChannelVolume(window, (AudioChannel)aAudioChannel, aVolume);
return NS_OK;
@ -759,7 +754,8 @@ AudioChannelService::GetAudioChannelMuted(nsIDOMWindow* aWindow,
{
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsPIDOMWindow> window = GetTopWindow(aWindow);
nsCOMPtr<nsPIDOMWindow> piWindow = do_QueryInterface(aWindow);
nsCOMPtr<nsPIDOMWindow> window = GetTopWindow(piWindow);
MOZ_ASSERT(window->IsOuterWindow());
*aMuted = GetAudioChannelMuted(window, (AudioChannel)aAudioChannel);
return NS_OK;
@ -791,7 +787,8 @@ AudioChannelService::SetAudioChannelMuted(nsIDOMWindow* aWindow,
{
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsPIDOMWindow> window = GetTopWindow(aWindow);
nsCOMPtr<nsPIDOMWindow> piWindow = do_QueryInterface(aWindow);
nsCOMPtr<nsPIDOMWindow> window = GetTopWindow(piWindow);
MOZ_ASSERT(window->IsOuterWindow());
SetAudioChannelMuted(window, (AudioChannel)aAudioChannel, aMuted);
return NS_OK;
@ -816,7 +813,8 @@ AudioChannelService::IsAudioChannelActive(nsIDOMWindow* aWindow,
{
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsPIDOMWindow> window = GetTopWindow(aWindow);
nsCOMPtr<nsPIDOMWindow> piWindow = do_QueryInterface(aWindow);
nsCOMPtr<nsPIDOMWindow> window = GetTopWindow(piWindow);
MOZ_ASSERT(window->IsOuterWindow());
*aActive = IsAudioChannelActive(window, (AudioChannel)aAudioChannel);
return NS_OK;

View File

@ -777,6 +777,12 @@ public:
{
return nsPresContext::AppUnitsToIntCSSPixels(GetClientAreaRect().height);
}
int32_t ScrollTopMin()
{
nsIScrollableFrame* sf = GetScrollFrame();
return sf ?
nsPresContext::AppUnitsToIntCSSPixels(sf->GetScrollRange().y) : 0;
}
int32_t ScrollTopMax()
{
nsIScrollableFrame* sf = GetScrollFrame();
@ -784,6 +790,12 @@ public:
nsPresContext::AppUnitsToIntCSSPixels(sf->GetScrollRange().YMost()) :
0;
}
int32_t ScrollLeftMin()
{
nsIScrollableFrame* sf = GetScrollFrame();
return sf ?
nsPresContext::AppUnitsToIntCSSPixels(sf->GetScrollRange().x) : 0;
}
int32_t ScrollLeftMax()
{
nsIScrollableFrame* sf = GetScrollFrame();

View File

@ -2645,12 +2645,8 @@ Navigator::HasPresentationSupport(JSContext* aCx, JSObject* aGlobal)
return false;
}
nsCOMPtr<nsIDOMWindow> top;
nsresult rv = win->GetTop(getter_AddRefs(top));
if (NS_WARN_IF(NS_FAILED(rv))) {
return false;
}
win = win->GetOuterWindow();
nsCOMPtr<nsPIDOMWindow> top = win->GetTop();
nsCOMPtr<nsIScriptObjectPrincipal> sop = do_QueryInterface(win);
nsCOMPtr<nsIScriptObjectPrincipal> topSop = do_QueryInterface(top);
if (!sop || !topSop) {
@ -2663,8 +2659,7 @@ Navigator::HasPresentationSupport(JSContext* aCx, JSObject* aGlobal)
return false;
}
nsCOMPtr<nsPIDOMWindow> piTop = do_QueryInterface(top);
if (!piTop || !(piTop = piTop->GetCurrentInnerWindow())) {
if (!(top = top->GetCurrentInnerWindow())) {
return false;
}
@ -2675,7 +2670,7 @@ Navigator::HasPresentationSupport(JSContext* aCx, JSObject* aGlobal)
}
nsAutoString sessionId;
presentationService->GetExistentSessionIdAtLaunch(piTop->WindowID(), sessionId);
presentationService->GetExistentSessionIdAtLaunch(top->WindowID(), sessionId);
return !sessionId.IsEmpty();
}
@ -2851,53 +2846,96 @@ Navigator::GetUserAgent(nsPIDOMWindow* aWindow, nsIURI* aURI,
}
#ifdef MOZ_EME
static nsCString
ToCString(const nsString& aString)
{
return NS_ConvertUTF16toUTF8(aString);
}
static nsCString
ToCString(const MediaKeySystemMediaCapability& aValue)
{
nsCString str;
str.AppendLiteral("{contentType='");
if (!aValue.mContentType.IsEmpty()) {
str.Append(ToCString(aValue.mContentType));
}
str.AppendLiteral("'}");
return str;
}
template<class Type>
static nsCString
ToCString(const Sequence<Type>& aSequence)
{
nsCString s;
s.AppendLiteral("[");
for (size_t i = 0; i < aSequence.Length(); i++) {
if (i != 0) {
s.AppendLiteral(",");
}
s.Append(ToCString(aSequence[i]));
}
s.AppendLiteral("]");
return s;
}
static nsCString
ToCString(const MediaKeySystemConfiguration& aConfig)
{
nsCString str;
str.AppendLiteral("{");
str.AppendPrintf("label='%s'", NS_ConvertUTF16toUTF8(aConfig.mLabel).get());
if (aConfig.mInitDataTypes.WasPassed()) {
str.AppendLiteral(", initDataTypes=");
str.Append(ToCString(aConfig.mInitDataTypes.Value()));
}
if (aConfig.mAudioCapabilities.WasPassed()) {
str.AppendLiteral(", audioCapabilities=");
str.Append(ToCString(aConfig.mAudioCapabilities.Value()));
}
if (aConfig.mVideoCapabilities.WasPassed()) {
str.AppendLiteral(", videoCapabilities=");
str.Append(ToCString(aConfig.mVideoCapabilities.Value()));
}
if (!aConfig.mAudioType.IsEmpty()) {
str.AppendPrintf(", audioType='%s'",
NS_ConvertUTF16toUTF8(aConfig.mAudioType).get());
}
if (!aConfig.mInitDataType.IsEmpty()) {
str.AppendPrintf(", initDataType='%s'",
NS_ConvertUTF16toUTF8(aConfig.mInitDataType).get());
}
if (!aConfig.mVideoType.IsEmpty()) {
str.AppendPrintf(", videoType='%s'",
NS_ConvertUTF16toUTF8(aConfig.mVideoType).get());
}
str.AppendLiteral("}");
return str;
}
static nsCString
RequestKeySystemAccessLogString(const nsAString& aKeySystem,
const Sequence<MediaKeySystemConfiguration>& aConfigs)
{
nsCString str;
str.AppendPrintf("Navigator::RequestMediaKeySystemAccess(keySystem='%s' options=",
NS_ConvertUTF16toUTF8(aKeySystem).get());
str.Append(ToCString(aConfigs));
str.AppendLiteral(")");
return str;
}
already_AddRefed<Promise>
Navigator::RequestMediaKeySystemAccess(const nsAString& aKeySystem,
const Optional<Sequence<MediaKeySystemOptions>>& aOptions,
const Sequence<MediaKeySystemConfiguration>& aConfigs,
ErrorResult& aRv)
{
nsAutoCString logMsg;
logMsg.AppendPrintf("Navigator::RequestMediaKeySystemAccess(keySystem='%s' options=[",
NS_ConvertUTF16toUTF8(aKeySystem).get());
if (aOptions.WasPassed()) {
const Sequence<MediaKeySystemOptions>& options = aOptions.Value();
for (size_t i = 0; i < options.Length(); i++) {
const MediaKeySystemOptions& op = options[i];
if (i > 0) {
logMsg.AppendLiteral(",");
}
logMsg.AppendLiteral("{");
logMsg.AppendPrintf("stateful='%s'",
MediaKeysRequirementValues::strings[(size_t)op.mStateful].value);
logMsg.AppendPrintf(", uniqueIdentifier='%s'",
MediaKeysRequirementValues::strings[(size_t)op.mUniqueidentifier].value);
if (!op.mAudioCapability.IsEmpty()) {
logMsg.AppendPrintf(", audioCapability='%s'",
NS_ConvertUTF16toUTF8(op.mAudioCapability).get());
}
if (!op.mAudioType.IsEmpty()) {
logMsg.AppendPrintf(", audioType='%s'",
NS_ConvertUTF16toUTF8(op.mAudioType).get());
}
if (!op.mInitDataType.IsEmpty()) {
logMsg.AppendPrintf(", initDataType='%s'",
NS_ConvertUTF16toUTF8(op.mInitDataType).get());
}
if (!op.mVideoCapability.IsEmpty()) {
logMsg.AppendPrintf(", videoCapability='%s'",
NS_ConvertUTF16toUTF8(op.mVideoCapability).get());
}
if (!op.mVideoType.IsEmpty()) {
logMsg.AppendPrintf(", videoType='%s'",
NS_ConvertUTF16toUTF8(op.mVideoType).get());
}
logMsg.AppendLiteral("}");
}
}
logMsg.AppendPrintf("])");
EME_LOG(logMsg.get());
EME_LOG("%s", RequestKeySystemAccessLogString(aKeySystem, aConfigs).get());
nsCOMPtr<nsIGlobalObject> go = do_QueryInterface(mWindow);
RefPtr<DetailedPromise> promise =
@ -2913,10 +2951,9 @@ Navigator::RequestMediaKeySystemAccess(const nsAString& aKeySystem,
mMediaKeySystemAccessManager = new MediaKeySystemAccessManager(mWindow);
}
mMediaKeySystemAccessManager->Request(promise, aKeySystem, aOptions);
mMediaKeySystemAccessManager->Request(promise, aKeySystem, aConfigs);
return promise.forget();
}
#endif
Presentation*

View File

@ -353,7 +353,7 @@ public:
#ifdef MOZ_EME
already_AddRefed<Promise>
RequestMediaKeySystemAccess(const nsAString& aKeySystem,
const Optional<Sequence<MediaKeySystemOptions>>& aOptions,
const Sequence<MediaKeySystemConfiguration>& aConfig,
ErrorResult& aRv);
private:
RefPtr<MediaKeySystemAccessManager> mMediaKeySystemAccessManager;

View File

@ -141,14 +141,12 @@ ThirdPartyUtil::IsThirdPartyWindow(nsIDOMWindow* aWindow,
}
}
nsCOMPtr<nsIDOMWindow> current = aWindow, parent;
nsCOMPtr<nsPIDOMWindow> current = do_QueryInterface(aWindow), parent;
nsCOMPtr<nsIURI> parentURI;
do {
// We use GetScriptableParent rather than GetParent because we consider
// <iframe mozbrowser/mozapp> to be a top-level frame.
rv = current->GetScriptableParent(getter_AddRefs(parent));
NS_ENSURE_SUCCESS(rv, rv);
parent = current->GetScriptableParent();
if (SameCOMIdentity(parent, current)) {
// We're at the topmost content window. We already know the answer.
*aResult = false;
@ -275,9 +273,12 @@ ThirdPartyUtil::IsThirdPartyChannel(nsIChannel* aChannel,
ctx->GetAssociatedWindow(getter_AddRefs(ourWin));
if (!ourWin) return NS_ERROR_INVALID_ARG;
nsCOMPtr<nsPIDOMWindow> piOurWin = do_QueryInterface(ourWin);
MOZ_ASSERT(piOurWin);
// We use GetScriptableParent rather than GetParent because we consider
// <iframe mozbrowser/mozapp> to be a top-level frame.
ourWin->GetScriptableParent(getter_AddRefs(parentWin));
parentWin = piOurWin->GetScriptableParent();
NS_ENSURE_TRUE(parentWin, NS_ERROR_INVALID_ARG);
// Check whether this is the document channel for this window (representing a
@ -315,7 +316,6 @@ ThirdPartyUtil::GetTopWindowForChannel(nsIChannel* aChannel, nsIDOMWindow** aWin
{
NS_ENSURE_ARG(aWin);
nsresult rv;
// Find the associated window and its parent window.
nsCOMPtr<nsILoadContext> ctx;
NS_QueryNotificationCallbacks(aChannel, ctx);
@ -324,13 +324,15 @@ ThirdPartyUtil::GetTopWindowForChannel(nsIChannel* aChannel, nsIDOMWindow** aWin
}
nsCOMPtr<nsIDOMWindow> window;
rv = ctx->GetAssociatedWindow(getter_AddRefs(window));
if (!window) {
ctx->GetAssociatedWindow(getter_AddRefs(window));
nsCOMPtr<nsPIDOMWindow> top = do_QueryInterface(window);
if (!top) {
return NS_ERROR_INVALID_ARG;
}
rv = window->GetTop(aWin);
return rv;
top = top->GetTop();
top.forget(aWin);
return NS_OK;
}
// Get the base domain for aHostURI; e.g. for "www.bbc.co.uk", this would be

View File

@ -1139,16 +1139,20 @@ protected:
return true;
}
uint64_t windowID = 0;
nsCOMPtr<nsIDOMWindow> topWindow;
aWindow->GetScriptableTop(getter_AddRefs(topWindow));
nsCOMPtr<nsPIDOMWindow> pTopWindow = do_QueryInterface(topWindow);
if (pTopWindow) {
pTopWindow = pTopWindow->GetCurrentInnerWindow();
if (aWindow->IsOuterWindow()) {
aWindow = aWindow->GetCurrentInnerWindow();
}
if (pTopWindow) {
windowID = pTopWindow->WindowID();
MOZ_ASSERT(aWindow);
uint64_t windowID = 0;
nsCOMPtr<nsPIDOMWindow> topWindow = aWindow->GetScriptableTop();
if (topWindow) {
topWindow = topWindow->GetCurrentInnerWindow();
}
if (topWindow) {
windowID = topWindow->WindowID();
}
mImpl->AsyncOpen(principal, windowID, mRv);
@ -1210,6 +1214,8 @@ WebSocket::Constructor(const GlobalObject& aGlobal,
}
}
MOZ_ASSERT_IF(ownerWindow, ownerWindow->IsInnerWindow());
nsTArray<nsString> protocolArray;
for (uint32_t index = 0, len = aProtocols.Length(); index < len; ++index) {
@ -1323,16 +1329,16 @@ WebSocket::Constructor(const GlobalObject& aGlobal,
if (NS_IsMainThread()) {
MOZ_ASSERT(principal);
nsPIDOMWindow* outerWindow = ownerWindow->GetOuterWindow();
uint64_t windowID = 0;
nsCOMPtr<nsIDOMWindow> topWindow;
ownerWindow->GetScriptableTop(getter_AddRefs(topWindow));
nsCOMPtr<nsPIDOMWindow> pTopWindow = do_QueryInterface(topWindow);
if (pTopWindow) {
pTopWindow = pTopWindow->GetCurrentInnerWindow();
nsCOMPtr<nsPIDOMWindow> topWindow = outerWindow->GetScriptableTop();
if (topWindow) {
topWindow = topWindow->GetCurrentInnerWindow();
}
if (pTopWindow) {
windowID = pTopWindow->WindowID();
if (topWindow) {
windowID = topWindow->WindowID();
}
webSocket->mImpl->AsyncOpen(principal, windowID, aRv);

View File

@ -393,7 +393,7 @@ DragDataProducer::Produce(DataTransfer* aDataTransfer,
return NS_OK;
}
else {
mWindow->GetSelection(getter_AddRefs(selection));
selection = mWindow->GetSelection();
if (!selection)
return NS_OK;

View File

@ -188,9 +188,8 @@ nsContentPolicy::CheckPolicy(CPMethod policyMethod,
MOZ_ASSERT(window->IsOuterWindow());
if (topFrameElement) {
nsCOMPtr<nsIDOMWindow> topWindow;
window->GetScriptableTop(getter_AddRefs(topWindow));
isTopLevel = topWindow == static_cast<nsIDOMWindow*>(window);
nsCOMPtr<nsPIDOMWindow> topWindow = window->GetScriptableTop();
isTopLevel = topWindow == window;
} else {
// If we don't have a top frame element, then requestingContext is
// part of the top-level XUL document. Presumably it's the <browser>

View File

@ -6913,7 +6913,7 @@ nsContentUtils::GetRootDocument(nsIDocument* aDoc)
/* static */
bool
nsContentUtils::IsInPointerLockContext(nsIDOMWindow* aWin)
nsContentUtils::IsInPointerLockContext(nsPIDOMWindow* aWin)
{
if (!aWin) {
return false;
@ -6925,11 +6925,8 @@ nsContentUtils::IsInPointerLockContext(nsIDOMWindow* aWin)
return false;
}
nsCOMPtr<nsIDOMWindow> lockTop;
pointerLockedDoc->GetWindow()->GetScriptableTop(getter_AddRefs(lockTop));
nsCOMPtr<nsIDOMWindow> top;
aWin->GetScriptableTop(getter_AddRefs(top));
nsCOMPtr<nsPIDOMWindow> lockTop = pointerLockedDoc->GetWindow()->GetScriptableTop();
nsCOMPtr<nsPIDOMWindow> top = aWin->GetScriptableTop();
return top == lockTop;
}

View File

@ -2071,7 +2071,7 @@ public:
* Returns true if aWin and the current pointer lock document
* have common scriptable top window.
*/
static bool IsInPointerLockContext(nsIDOMWindow* aWin);
static bool IsInPointerLockContext(nsPIDOMWindow* aWin);
/**
* Returns the time limit on handling user input before

View File

@ -1994,15 +1994,20 @@ nsDOMWindowUtils::GetVisitedDependentComputedStyle(
aResult.Truncate();
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
nsCOMPtr<Element> element = do_QueryInterface(aElement);
NS_ENSURE_STATE(window && element);
window = window->GetCurrentInnerWindow();
NS_ENSURE_STATE(window);
nsCOMPtr<nsIDOMCSSStyleDeclaration> decl;
nsresult rv =
window->GetComputedStyle(aElement, aPseudoElement, getter_AddRefs(decl));
NS_ENSURE_SUCCESS(rv, rv);
{
ErrorResult rv;
decl = window->GetComputedStyle(*element, aPseudoElement, rv);
ENSURE_SUCCESS(rv, rv.StealNSResult());
}
static_cast<nsComputedDOMStyle*>(decl.get())->SetExposeVisitedStyle(true);
rv = decl->GetPropertyValue(aPropertyName, aResult);
nsresult rv = decl->GetPropertyValue(aPropertyName, aResult);
static_cast<nsComputedDOMStyle*>(decl.get())->SetExposeVisitedStyle(false);
return rv;

View File

@ -3275,12 +3275,11 @@ nsIDocument::HasFocus(ErrorResult& rv) const
return false;
}
// Are we an ancestor of the focused DOMWindow?
nsCOMPtr<nsIDOMDocument> domDocument;
focusedWindow->GetDocument(getter_AddRefs(domDocument));
nsCOMPtr<nsIDocument> document = do_QueryInterface(domDocument);
nsCOMPtr<nsPIDOMWindow> piWindow = do_QueryInterface(focusedWindow);
MOZ_ASSERT(piWindow);
for (nsIDocument* currentDoc = document; currentDoc;
// Are we an ancestor of the focused DOMWindow?
for (nsIDocument* currentDoc = piWindow->GetDoc(); currentDoc;
currentDoc = currentDoc->GetParentDocument()) {
if (currentDoc == this) {
// Yes, we are an ancestor
@ -7002,9 +7001,11 @@ nsIDocument::GetLocation() const
return nullptr;
}
nsCOMPtr<nsIDOMLocation> loc;
w->GetLocation(getter_AddRefs(loc));
return loc.forget().downcast<nsLocation>();
nsGlobalWindow* window = static_cast<nsGlobalWindow*>(w.get());
ErrorResult dummy;
RefPtr<nsLocation> loc = window->GetLocation(dummy);
dummy.SuppressException();
return loc.forget();
}
Element*
@ -11789,9 +11790,7 @@ ShouldApplyFullscreenDirectly(nsIDocument* aDoc,
} else {
// If we are in the chrome process, and the window has not been in
// fullscreen, we certainly need to make that fullscreen first.
bool fullscreen;
NS_WARN_IF(NS_FAILED(aRootWin->GetFullScreen(&fullscreen)));
if (!fullscreen) {
if (!aRootWin->GetFullScreen()) {
return false;
}
// The iterator not being at end indicates there is still some
@ -12493,18 +12492,15 @@ nsDocument::ShouldLockPointer(Element* aElement, Element* aCurrentLock,
return false;
}
nsCOMPtr<nsIDOMWindow> top;
ownerWindow->GetScriptableTop(getter_AddRefs(top));
nsCOMPtr<nsPIDOMWindow> piTop = do_QueryInterface(top);
if (!piTop || !piTop->GetExtantDoc() ||
piTop->GetExtantDoc()->Hidden()) {
nsCOMPtr<nsPIDOMWindow> top = ownerWindow->GetScriptableTop();
if (!top || !top->GetExtantDoc() || top->GetExtantDoc()->Hidden()) {
NS_WARNING("ShouldLockPointer(): Top document isn't visible.");
return false;
}
if (!aNoFocusCheck) {
mozilla::ErrorResult rv;
if (!piTop->GetExtantDoc()->HasFocus(rv)) {
if (!top->GetExtantDoc()->HasFocus(rv)) {
NS_WARNING("ShouldLockPointer(): Top document isn't focused.");
return false;
}
@ -13286,10 +13282,7 @@ nsAutoSyncOperation::nsAutoSyncOperation(nsIDocument* aDoc)
if (aDoc) {
nsPIDOMWindow* win = aDoc->GetWindow();
if (win) {
nsCOMPtr<nsIDOMWindow> topWindow;
win->GetTop(getter_AddRefs(topWindow));
nsCOMPtr<nsPIDOMWindow> top = do_QueryInterface(topWindow);
if (top) {
if (nsCOMPtr<nsPIDOMWindow> top = win->GetTop()) {
nsCOMPtr<nsIDocument> doc = top->GetExtantDoc();
MarkDocumentTreeToBeInSyncOperation(doc, &mDocuments);
}

File diff suppressed because it is too large Load Diff

View File

@ -526,31 +526,21 @@ public:
{
return FromSupports(wrapper->Native());
}
/**
* Wrap nsIDOMWindow::GetTop so we can overload the inline GetTop()
* implementation below. (nsIDOMWindow::GetTop simply calls
* nsIDOMWindow::GetRealTop().)
*/
nsresult GetTop(nsIDOMWindow **aWindow)
already_AddRefed<nsPIDOMWindow> GetTop() override;
nsPIDOMWindow* GetScriptableTop() override;
inline nsGlobalWindow *GetTopInternal()
{
return nsIDOMWindow::GetTop(aWindow);
}
inline nsGlobalWindow *GetTop()
{
nsCOMPtr<nsIDOMWindow> top;
GetTop(getter_AddRefs(top));
nsGlobalWindow* outer = IsOuterWindow() ? this : GetOuterWindowInternal();
nsCOMPtr<nsPIDOMWindow> top = outer ? outer->GetTop() : nullptr;
if (top)
return static_cast<nsGlobalWindow *>(top.get());
return nullptr;
}
inline nsGlobalWindow* GetScriptableTop()
inline nsGlobalWindow* GetScriptableTopInternal()
{
nsCOMPtr<nsIDOMWindow> top;
GetScriptableTop(getter_AddRefs(top));
return static_cast<nsGlobalWindow *>(top.get());
nsPIDOMWindow* top = GetScriptableTop();
return static_cast<nsGlobalWindow*>(top);
}
nsPIDOMWindow* GetChildWindow(const nsAString& aName);
@ -695,13 +685,8 @@ public:
IsTopLevelWindow()
{
MOZ_ASSERT(IsOuterWindow());
nsCOMPtr<nsIDOMWindow> parentWindow;
nsresult rv = GetScriptableTop(getter_AddRefs(parentWindow));
if (NS_WARN_IF(NS_FAILED(rv))) {
return false;
}
return parentWindow == static_cast<nsIDOMWindow*>(this);
nsPIDOMWindow* parentWindow = GetScriptableTop();
return parentWindow == static_cast<nsPIDOMWindow*>(this);
}
virtual void
@ -862,6 +847,7 @@ public:
void SetNameOuter(const nsAString& aName, mozilla::ErrorResult& aError);
void SetName(const nsAString& aName, mozilla::ErrorResult& aError);
nsLocation* GetLocation(mozilla::ErrorResult& aError);
nsIDOMLocation* GetLocation() override;
nsHistory* GetHistory(mozilla::ErrorResult& aError);
mozilla::dom::BarProp* GetLocationbar(mozilla::ErrorResult& aError);
mozilla::dom::BarProp* GetMenubar(mozilla::ErrorResult& aError);
@ -875,35 +861,44 @@ public:
void SetStatus(const nsAString& aStatus, mozilla::ErrorResult& aError);
void CloseOuter(bool aTrustedCaller);
void Close(mozilla::ErrorResult& aError);
nsresult Close() override;
bool GetClosedOuter();
bool GetClosed(mozilla::ErrorResult& aError);
bool Closed() override;
void StopOuter(mozilla::ErrorResult& aError);
void Stop(mozilla::ErrorResult& aError);
void FocusOuter(mozilla::ErrorResult& aError);
void Focus(mozilla::ErrorResult& aError);
nsresult Focus() override;
void BlurOuter();
void Blur(mozilla::ErrorResult& aError);
already_AddRefed<nsIDOMWindow> GetFramesOuter();
already_AddRefed<nsIDOMWindowCollection> GetFrames() override;
already_AddRefed<nsIDOMWindow> GetFrames(mozilla::ErrorResult& aError);
uint32_t Length();
already_AddRefed<nsIDOMWindow> GetTopOuter(mozilla::ErrorResult& aError);
already_AddRefed<nsIDOMWindow> GetTopOuter();
already_AddRefed<nsIDOMWindow> GetTop(mozilla::ErrorResult& aError);
nsresult GetPrompter(nsIPrompt** aPrompt) override;
protected:
explicit nsGlobalWindow(nsGlobalWindow *aOuterWindow);
nsIDOMWindow* GetOpenerWindowOuter();
nsIDOMWindow* GetOpenerWindow(mozilla::ErrorResult& aError);
nsPIDOMWindow* GetOpenerWindowOuter();
nsPIDOMWindow* GetOpenerWindow(mozilla::ErrorResult& aError);
// Initializes the mWasOffline member variable
void InitWasOffline();
public:
void GetOpener(JSContext* aCx, JS::MutableHandle<JS::Value> aRetval,
mozilla::ErrorResult& aError);
already_AddRefed<nsPIDOMWindow> GetOpener() override;
void SetOpener(JSContext* aCx, JS::Handle<JS::Value> aOpener,
mozilla::ErrorResult& aError);
using nsIDOMWindow::GetParent;
already_AddRefed<nsIDOMWindow> GetParentOuter(mozilla::ErrorResult& aError);
already_AddRefed<nsIDOMWindow> GetParentOuter();
already_AddRefed<nsIDOMWindow> GetParent(mozilla::ErrorResult& aError);
already_AddRefed<nsPIDOMWindow> GetParent() override;
nsPIDOMWindow* GetScriptableParent() override;
mozilla::dom::Element* GetFrameElementOuter();
mozilla::dom::Element* GetFrameElement(mozilla::ErrorResult& aError);
already_AddRefed<nsIDOMElement> GetFrameElement() override;
already_AddRefed<nsIDOMWindow> OpenOuter(const nsAString& aUrl,
const nsAString& aName,
const nsAString& aOptions,
@ -912,8 +907,12 @@ public:
const nsAString& aName,
const nsAString& aOptions,
mozilla::ErrorResult& aError);
nsresult Open(const nsAString& aUrl, const nsAString& aName,
const nsAString& aOptions, nsPIDOMWindow **_retval) override;
mozilla::dom::Navigator* GetNavigator(mozilla::ErrorResult& aError);
nsIDOMNavigator* GetNavigator() override;
nsIDOMOfflineResourceList* GetApplicationCache(mozilla::ErrorResult& aError);
already_AddRefed<nsIDOMOfflineResourceList> GetApplicationCache() override;
#if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GONK)
int16_t Orientation() const;
@ -987,18 +986,21 @@ public:
mozilla::dom::DOMStorage* GetLocalStorage(mozilla::ErrorResult& aError);
mozilla::dom::Selection* GetSelectionOuter();
mozilla::dom::Selection* GetSelection(mozilla::ErrorResult& aError);
already_AddRefed<nsISelection> GetSelection() override;
mozilla::dom::indexedDB::IDBFactory* GetIndexedDB(mozilla::ErrorResult& aError);
already_AddRefed<nsICSSDeclaration>
GetComputedStyle(mozilla::dom::Element& aElt, const nsAString& aPseudoElt,
mozilla::ErrorResult& aError);
mozilla::ErrorResult& aError) override;
already_AddRefed<mozilla::dom::MediaQueryList> MatchMediaOuter(const nsAString& aQuery);
already_AddRefed<mozilla::dom::MediaQueryList> MatchMedia(const nsAString& aQuery,
mozilla::ErrorResult& aError);
nsScreen* GetScreen(mozilla::ErrorResult& aError);
nsIDOMScreen* GetScreen() override;
void MoveToOuter(int32_t aXPos, int32_t aYPos, mozilla::ErrorResult& aError, bool aCallerIsChrome);
void MoveTo(int32_t aXPos, int32_t aYPos, mozilla::ErrorResult& aError);
void MoveByOuter(int32_t aXDif, int32_t aYDif, mozilla::ErrorResult& aError, bool aCallerIsChrome);
void MoveBy(int32_t aXDif, int32_t aYDif, mozilla::ErrorResult& aError);
nsresult MoveBy(int32_t aXDif, int32_t aYDif) override;
void ResizeToOuter(int32_t aWidth, int32_t aHeight, mozilla::ErrorResult& aError, bool aCallerIsChrome);
void ResizeTo(int32_t aWidth, int32_t aHeight,
mozilla::ErrorResult& aError);
@ -1069,6 +1071,7 @@ public:
mozilla::dom::Crypto* GetCrypto(mozilla::ErrorResult& aError);
nsIControllers* GetControllersOuter(mozilla::ErrorResult& aError);
nsIControllers* GetControllers(mozilla::ErrorResult& aError);
nsresult GetControllers(nsIControllers** aControllers) override;
mozilla::dom::Element* GetRealFrameElementOuter();
mozilla::dom::Element* GetRealFrameElement(mozilla::ErrorResult& aError);
float GetMozInnerScreenXOuter();
@ -1077,12 +1080,17 @@ public:
float GetMozInnerScreenY(mozilla::ErrorResult& aError);
float GetDevicePixelRatioOuter();
float GetDevicePixelRatio(mozilla::ErrorResult& aError);
nsresult GetDevicePixelRatio(float* aRatio) override;
int32_t GetScrollMinX(mozilla::ErrorResult& aError);
int32_t GetScrollMinY(mozilla::ErrorResult& aError);
int32_t GetScrollMaxX(mozilla::ErrorResult& aError);
int32_t GetScrollMaxY(mozilla::ErrorResult& aError);
bool GetFullScreenOuter();
bool GetFullScreen(mozilla::ErrorResult& aError);
bool GetFullScreen() override;
void SetFullScreenOuter(bool aFullScreen, mozilla::ErrorResult& aError);
void SetFullScreen(bool aFullScreen, mozilla::ErrorResult& aError);
nsresult SetFullScreen(bool aFullScreen) override;
void BackOuter(mozilla::ErrorResult& aError);
void Back(mozilla::ErrorResult& aError);
void ForwardOuter(mozilla::ErrorResult& aError);
@ -1114,6 +1122,10 @@ public:
const nsAString& aOptions,
const mozilla::dom::Sequence<JS::Value>& aExtraArgument,
mozilla::ErrorResult& aError);
nsresult OpenDialog(const nsAString& aUrl, const nsAString& aName,
const nsAString& aOptions,
nsISupports* aExtraArgument, nsIDOMWindow** _retval) override;
nsresult UpdateCommands(const nsAString& anAction, nsISelection* aSel, int16_t aReason) override;
already_AddRefed<nsIDOMWindow>
GetContentInternal(mozilla::ErrorResult& aError, bool aUnprivilegedCaller);
@ -1217,12 +1229,18 @@ protected:
const char* aPropName,
mozilla::ErrorResult& aError);
// And the implementations of WindowCoordGetter/WindowCoordSetter.
public:
int32_t GetInnerWidthOuter(mozilla::ErrorResult& aError);
protected:
int32_t GetInnerWidth(mozilla::ErrorResult& aError);
nsresult GetInnerWidth(int32_t* aWidth) override;
void SetInnerWidthOuter(int32_t aInnerWidth, mozilla::ErrorResult& aError, bool aCallerIsChrome);
void SetInnerWidth(int32_t aInnerWidth, mozilla::ErrorResult& aError);
public:
int32_t GetInnerHeightOuter(mozilla::ErrorResult& aError);
protected:
int32_t GetInnerHeight(mozilla::ErrorResult& aError);
nsresult GetInnerHeight(int32_t* aHeight) override;
void SetInnerHeightOuter(int32_t aInnerHeight, mozilla::ErrorResult& aError, bool aCallerIsChrome);
void SetInnerHeight(int32_t aInnerHeight, mozilla::ErrorResult& aError);
int32_t GetScreenXOuter(mozilla::ErrorResult& aError);
@ -1490,9 +1508,7 @@ public:
// Outer windows only.
mozilla::CSSIntPoint GetScrollXY(bool aDoFlush);
void GetScrollMaxXYOuter(int32_t* aScrollMaxX, int32_t* aScrollMaxY);
void GetScrollMaxXY(int32_t* aScrollMaxX, int32_t* aScrollMaxY,
mozilla::ErrorResult& aError);
int32_t GetScrollBoundaryOuter(mozilla::Side aSide);
// Outer windows only.
nsresult GetInnerSize(mozilla::CSSIntSize& aSize);

View File

@ -196,8 +196,7 @@ nsMimeTypeArray::EnsurePluginMimeTypes()
return;
}
nsCOMPtr<nsIDOMNavigator> navigator;
mWindow->GetNavigator(getter_AddRefs(navigator));
nsCOMPtr<nsIDOMNavigator> navigator = mWindow->GetNavigator();
if (!navigator) {
return;

View File

@ -3300,17 +3300,14 @@ nsObjectLoadingContent::ShouldPlay(FallbackType &aReason, bool aIgnoreCurrentTyp
MOZ_ASSERT(thisContent);
nsIDocument* ownerDoc = thisContent->OwnerDoc();
nsCOMPtr<nsIDOMWindow> window = ownerDoc->GetWindow();
nsCOMPtr<nsPIDOMWindow> window = ownerDoc->GetWindow();
if (!window) {
return false;
}
nsCOMPtr<nsIDOMWindow> topWindow;
rv = window->GetTop(getter_AddRefs(topWindow));
NS_ENSURE_SUCCESS(rv, false);
nsCOMPtr<nsIDOMDocument> topDocument;
rv = topWindow->GetDocument(getter_AddRefs(topDocument));
NS_ENSURE_SUCCESS(rv, false);
nsCOMPtr<nsIDocument> topDoc = do_QueryInterface(topDocument);
nsCOMPtr<nsPIDOMWindow> topWindow = window->GetTop();
NS_ENSURE_TRUE(topWindow, false);
nsCOMPtr<nsIDocument> topDoc = topWindow->GetDoc();
NS_ENSURE_TRUE(topDoc, false);
nsCOMPtr<nsIPermissionManager> permissionManager = services::GetPermissionManager();
NS_ENSURE_TRUE(permissionManager, false);

View File

@ -22,6 +22,7 @@
class nsIArray;
class nsIContent;
class nsICSSDeclaration;
class nsIDocShell;
class nsIDocument;
class nsIIdleObserver;
@ -62,8 +63,8 @@ enum UIStateChangeType
};
#define NS_PIDOMWINDOW_IID \
{ 0x052e675a, 0xacd3, 0x48d1, \
{ 0x8a, 0xcd, 0xbf, 0xff, 0xbd, 0x24, 0x4c, 0xed } }
{ 0x775dabc9, 0x8f43, 0x4277, \
{ 0x9a, 0xdb, 0xf1, 0x99, 0x0d, 0x77, 0xcf, 0xfb } }
class nsPIDOMWindow : public nsIDOMWindowInternal
{
@ -76,6 +77,23 @@ public:
virtual void ActivateOrDeactivate(bool aActivate) = 0;
// this is called GetTopWindowRoot to avoid conflicts with nsIDOMWindow::GetWindowRoot
/**
* |top| gets the root of the window hierarchy.
*
* This function does not cross chrome-content boundaries, so if this
* window's parent is of a different type, |top| will return this window.
*
* When script reads the top property, we run GetScriptableTop, which
* will not cross an <iframe mozbrowser> boundary.
*
* In contrast, C++ calls to GetTop are forwarded to GetRealTop, which
* ignores <iframe mozbrowser> boundaries.
*/
virtual already_AddRefed<nsPIDOMWindow> GetTop() = 0; // Outer only
virtual already_AddRefed<nsPIDOMWindow> GetParent() = 0;
virtual nsPIDOMWindow* GetScriptableTop() = 0;
virtual nsPIDOMWindow* GetScriptableParent() = 0;
virtual already_AddRefed<nsPIWindowRoot> GetTopWindowRoot() = 0;
// Inner windows only.
@ -763,6 +781,38 @@ public:
return mMarkedCCGeneration;
}
virtual nsIDOMScreen* GetScreen() = 0;
virtual nsIDOMNavigator* GetNavigator() = 0;
virtual nsIDOMLocation* GetLocation() = 0;
virtual nsresult GetPrompter(nsIPrompt** aPrompt) = 0;
virtual nsresult GetControllers(nsIControllers** aControllers) = 0;
virtual already_AddRefed<nsISelection> GetSelection() = 0;
virtual already_AddRefed<nsPIDOMWindow> GetOpener() = 0;
virtual already_AddRefed<nsIDOMWindowCollection> GetFrames() = 0;
virtual nsresult Open(const nsAString& aUrl, const nsAString& aName,
const nsAString& aOptions, nsPIDOMWindow **_retval) = 0;
virtual nsresult OpenDialog(const nsAString& aUrl, const nsAString& aName,
const nsAString& aOptions,
nsISupports* aExtraArgument, nsIDOMWindow** _retval) = 0;
virtual nsresult GetDevicePixelRatio(float* aRatio) = 0;
virtual nsresult GetInnerWidth(int32_t* aWidth) = 0;
virtual nsresult GetInnerHeight(int32_t* aHeight) = 0;
virtual already_AddRefed<nsICSSDeclaration>
GetComputedStyle(mozilla::dom::Element& aElt, const nsAString& aPseudoElt,
mozilla::ErrorResult& aError) = 0;
virtual already_AddRefed<nsIDOMElement> GetFrameElement() = 0;
virtual already_AddRefed<nsIDOMOfflineResourceList> GetApplicationCache() = 0;
virtual bool Closed() = 0;
virtual bool GetFullScreen() = 0;
virtual nsresult SetFullScreen(bool aFullScreen) = 0;
virtual nsresult Focus() = 0;
virtual nsresult Close() = 0;
virtual nsresult MoveBy(int32_t aXDif, int32_t aYDif) = 0;
virtual nsresult UpdateCommands(const nsAString& anAction, nsISelection* aSel, int16_t aReason) = 0;
protected:
// The nsPIDOMWindow constructor. The aOuterWindow argument should
// be null if and only if the created window itself is an outer

View File

@ -147,8 +147,7 @@ nsPluginArray::Refresh(bool aReloadDocuments)
mPlugins.Clear();
nsCOMPtr<nsIDOMNavigator> navigator;
mWindow->GetNavigator(getter_AddRefs(navigator));
nsCOMPtr<nsIDOMNavigator> navigator = mWindow->GetNavigator();
if (!navigator) {
return;

View File

@ -312,7 +312,7 @@ nsScreen::GetWindowInnerRect(nsRect& aRect)
{
aRect.x = 0;
aRect.y = 0;
nsCOMPtr<nsIDOMWindow> win = GetOwner();
nsCOMPtr<nsPIDOMWindow> win = GetOwner();
if (!win) {
return NS_ERROR_FAILURE;
}

View File

@ -63,12 +63,10 @@ AddNonJSSizeOfWindowAndItsDescendents(nsGlobalWindow* aWindow,
innerWindowSizes.addToTabSizes(aSizes);
}
nsCOMPtr<nsIDOMWindowCollection> frames;
nsresult rv = aWindow->GetFrames(getter_AddRefs(frames));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDOMWindowCollection> frames = aWindow->GetFrames();
uint32_t length;
rv = frames->GetLength(&length);
nsresult rv = frames->GetLength(&length);
NS_ENSURE_SUCCESS(rv, rv);
// Measure this window's descendents.
@ -252,8 +250,8 @@ CollectWindowReports(nsGlobalWindow *aWindow,
nsCOMPtr<nsIURI> location;
if (aWindow->GetOuterWindow()) {
// Our window should have a null top iff it has a null docshell.
MOZ_ASSERT(!!aWindow->GetTop() == !!aWindow->GetDocShell());
top = aWindow->GetTop();
MOZ_ASSERT(!!aWindow->GetTopInternal() == !!aWindow->GetDocShell());
top = aWindow->GetTopInternal();
if (top) {
location = GetWindowURI(top);
}
@ -747,9 +745,9 @@ CheckForGhostWindowsEnumerator(nsISupports *aKey, TimeStamp& aTimeStamp,
// Avoid calling GetTop() if we have no outer window. Nothing will break if
// we do, but it will spew debug output, which can cause our test logs to
// overflow.
nsCOMPtr<nsIDOMWindow> top;
nsCOMPtr<nsPIDOMWindow> top;
if (window->GetOuterWindow()) {
window->GetTop(getter_AddRefs(top));
top = window->GetOuterWindow()->GetTop();
}
if (top) {
@ -806,7 +804,7 @@ GetNonDetachedWindowDomainsEnumerator(const uint64_t& aId, nsGlobalWindow* aWind
// Null outer window implies null top, but calling GetTop() when there's no
// outer window causes us to spew debug warnings.
if (!aWindow->GetOuterWindow() || !aWindow->GetTop()) {
if (!aWindow->GetOuterWindow() || !aWindow->GetTopInternal()) {
// This window is detached, so we don't care about its domain.
return PL_DHASH_NEXT;
}

View File

@ -242,7 +242,7 @@ nsWindowRoot::GetControllers(nsIControllers** aResult)
return focusedWindow->GetControllers(aResult);
}
else {
nsCOMPtr<nsIDOMWindow> domWindow = do_QueryInterface(focusedWindow);
nsCOMPtr<nsPIDOMWindow> domWindow = do_QueryInterface(focusedWindow);
if (domWindow)
return domWindow->GetControllers(aResult);
}

View File

@ -2941,17 +2941,15 @@ nsXMLHttpRequest::Send(nsIVariant* aVariant, const Nullable<RequestBody>& aBody)
nsCOMPtr<nsIDocument> suspendedDoc;
nsCOMPtr<nsIRunnable> resumeTimeoutRunnable;
if (GetOwner()) {
nsCOMPtr<nsIDOMWindow> topWindow;
if (NS_SUCCEEDED(GetOwner()->GetTop(getter_AddRefs(topWindow)))) {
nsCOMPtr<nsPIDOMWindow> suspendedWindow(do_QueryInterface(topWindow));
if (suspendedWindow &&
(suspendedWindow = suspendedWindow->GetCurrentInnerWindow())) {
suspendedDoc = suspendedWindow->GetExtantDoc();
if (nsCOMPtr<nsPIDOMWindow> topWindow = GetOwner()->GetOuterWindow()->GetTop()) {
if (topWindow &&
(topWindow = topWindow->GetCurrentInnerWindow())) {
suspendedDoc = topWindow->GetExtantDoc();
if (suspendedDoc) {
suspendedDoc->SuppressEventHandling(nsIDocument::eEvents);
}
suspendedWindow->SuspendTimeouts(1, false);
resumeTimeoutRunnable = new nsResumeTimeoutsEvent(suspendedWindow);
topWindow->SuspendTimeouts(1, false);
resumeTimeoutRunnable = new nsResumeTimeoutsEvent(topWindow);
}
}
}

View File

@ -117,10 +117,7 @@ BrowserElementAudioChannel::Initialize()
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIDOMWindow> topWindow;
window->GetScriptableTop(getter_AddRefs(topWindow));
mFrameWindow = do_QueryInterface(topWindow);
mFrameWindow = window->GetScriptableTop();
mFrameWindow = mFrameWindow->GetOuterWindow();
return NS_OK;
}
@ -137,10 +134,7 @@ BrowserElementAudioChannel::Initialize()
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIDOMWindow> topWindow;
window->GetScriptableTop(getter_AddRefs(topWindow));
mFrameWindow = do_QueryInterface(topWindow);
mFrameWindow = window->GetScriptableTop();
mFrameWindow = mFrameWindow->GetOuterWindow();
return NS_OK;
}

View File

@ -348,8 +348,10 @@ const ContentPanningAPZDisabled = {
let isScrollableTextarea = (node.tagName == 'TEXTAREA' &&
(node.scrollHeight > node.clientHeight ||
node.scrollWidth > node.clientWidth ||
('scrollLeftMax' in node && node.scrollLeftMax > 0) ||
('scrollTopMax' in node && node.scrollTopMax > 0)));
('scrollLeftMin' in node && 'scrollLeftMax' in node &&
node.scrollLeftMin != node.scrollLeftMax) ||
('scrollTopMin' in node && 'scrollTopMax' in node &&
node.scrollTopMin != node.scrollTopMax)));
if (isScroll || isAuto || isScrollableTextarea) {
return node;
}
@ -357,7 +359,8 @@ const ContentPanningAPZDisabled = {
node = node.parentNode;
}
if (nodeContent.scrollMaxX || nodeContent.scrollMaxY) {
if (nodeContent.scrollMaxX != nodeContent.scrollMinX ||
nodeContent.scrollMaxY != nodeContent.scrollMinY) {
return nodeContent;
}

View File

@ -258,10 +258,8 @@ BrowserElementParent::OpenWindowInProcess(nsIDOMWindow* aOpenerWindow,
// GetScriptableTop gets us the <iframe mozbrowser>'s window; we'll use its
// frame element, rather than aOpenerWindow's frame element, as our "opener
// frame element" below.
nsCOMPtr<nsIDOMWindow> topWindow;
aOpenerWindow->GetScriptableTop(getter_AddRefs(topWindow));
nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(topWindow);
nsCOMPtr<nsPIDOMWindow> openerWindow = do_QueryInterface(aOpenerWindow);
nsCOMPtr<nsPIDOMWindow> win = openerWindow->GetScriptableTop();
nsCOMPtr<Element> openerFrameElement = win->GetFrameElementInternal();
NS_ENSURE_TRUE(openerFrameElement, BrowserElementParent::OPEN_WINDOW_IGNORED);

View File

@ -3023,17 +3023,17 @@ EventStateManager::PostHandleEvent(nsPresContext* aPresContext,
EnsureDocument(mPresContext);
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
if (mDocument && fm) {
nsCOMPtr<nsIDOMWindow> currentWindow;
fm->GetFocusedWindow(getter_AddRefs(currentWindow));
nsCOMPtr<nsIDOMWindow> window;
fm->GetFocusedWindow(getter_AddRefs(window));
nsCOMPtr<nsPIDOMWindow> currentWindow = do_QueryInterface(window);
if (currentWindow && mDocument->GetWindow() &&
currentWindow != mDocument->GetWindow() &&
!nsContentUtils::IsChromeDoc(mDocument)) {
nsCOMPtr<nsIDOMWindow> currentTop;
nsCOMPtr<nsIDOMWindow> newTop;
currentWindow->GetTop(getter_AddRefs(currentTop));
mDocument->GetWindow()->GetTop(getter_AddRefs(newTop));
nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(currentWindow);
nsCOMPtr<nsIDocument> currentDoc = win->GetExtantDoc();
nsCOMPtr<nsPIDOMWindow> currentTop;
nsCOMPtr<nsPIDOMWindow> newTop;
currentTop = currentWindow->GetTop();
newTop = mDocument->GetWindow()->GetTop();
nsCOMPtr<nsIDocument> currentDoc = currentWindow->GetExtantDoc();
if (nsContentUtils::IsChromeDoc(currentDoc) ||
(currentTop && newTop && currentTop != newTop)) {
fm->SetFocusedWindow(mDocument->GetWindow());
@ -4112,19 +4112,20 @@ GetWindowInnerRectCenter(nsPIDOMWindow* aWindow,
{
NS_ENSURE_TRUE(aWindow && aWidget && aContext, LayoutDeviceIntPoint(0, 0));
float cssInnerX = 0.0;
aWindow->GetMozInnerScreenX(&cssInnerX);
nsGlobalWindow* window = nsGlobalWindow::Cast(aWindow);
float cssInnerX = window->GetMozInnerScreenXOuter();
int32_t innerX = int32_t(NS_round(cssInnerX));
float cssInnerY = 0.0;
aWindow->GetMozInnerScreenY(&cssInnerY);
float cssInnerY = window->GetMozInnerScreenYOuter();
int32_t innerY = int32_t(NS_round(cssInnerY));
int32_t innerWidth = 0;
aWindow->GetInnerWidth(&innerWidth);
int32_t innerHeight = 0;
aWindow->GetInnerHeight(&innerHeight);
ErrorResult dummy;
int32_t innerWidth = window->GetInnerWidthOuter(dummy);
dummy.SuppressException();
int32_t innerHeight = window->GetInnerHeightOuter(dummy);
dummy.SuppressException();
nsIntRect screen;
aWidget->GetScreenBounds(screen);

View File

@ -24,6 +24,7 @@
#include "nsIDocument.h"
#include "nsIDOMDocument.h"
#include "nsIDOMRange.h"
#include "nsIEditorIMESupport.h"
#include "nsIFrame.h"
#include "nsINode.h"
#include "nsIPresShell.h"
@ -589,6 +590,25 @@ IMEContentObserver::IsEditorHandlingEventForComposition() const
return composition->IsEditorHandlingEvent();
}
bool
IMEContentObserver::IsEditorComposing() const
{
// Note that don't use TextComposition here. The important thing is,
// whether the editor already started to handle composition because
// web contents can change selection, text content and/or something from
// compositionstart event listener which is run before nsEditor handles it.
nsCOMPtr<nsIEditorIMESupport> editorIMESupport = do_QueryInterface(mEditor);
if (NS_WARN_IF(!editorIMESupport)) {
return false;
}
bool isComposing = false;
nsresult rv = editorIMESupport->GetComposing(&isComposing);
if (NS_WARN_IF(NS_FAILED(rv))) {
return false;
}
return isComposing;
}
nsresult
IMEContentObserver::GetSelectionAndRoot(nsISelection** aSelection,
nsIContent** aRootContent) const
@ -614,8 +634,10 @@ IMEContentObserver::NotifySelectionChanged(nsIDOMDocument* aDOMDocument,
if (count > 0 && mWidget) {
bool causedByComposition = IsEditorHandlingEventForComposition();
bool causedBySelectionEvent = TextComposition::IsHandlingSelectionEvent();
bool duringComposition = IsEditorComposing();
MaybeNotifyIMEOfSelectionChange(causedByComposition,
causedBySelectionEvent);
causedBySelectionEvent,
duringComposition);
}
return NS_OK;
}
@ -825,7 +847,8 @@ IMEContentObserver::CharacterDataChanged(nsIDocument* aDocument,
uint32_t oldEnd = offset + static_cast<uint32_t>(removedLength);
uint32_t newEnd = offset + newLength;
TextChangeData data(offset, oldEnd, newEnd, causedByComposition);
TextChangeData data(offset, oldEnd, newEnd, causedByComposition,
IsEditorComposing());
MaybeNotifyIMEOfTextChange(data);
}
@ -878,7 +901,7 @@ IMEContentObserver::NotifyContentAdded(nsINode* aContainer,
}
TextChangeData data(offset, offset, offset + addingLength,
causedByComposition);
causedByComposition, IsEditorComposing());
MaybeNotifyIMEOfTextChange(data);
}
@ -955,7 +978,8 @@ IMEContentObserver::ContentRemoved(nsIDocument* aDocument,
return;
}
TextChangeData data(offset, offset + textLength, offset, causedByComposition);
TextChangeData data(offset, offset + textLength, offset,
causedByComposition, IsEditorComposing());
MaybeNotifyIMEOfTextChange(data);
}
@ -1017,7 +1041,8 @@ IMEContentObserver::AttributeChanged(nsIDocument* aDocument,
NS_ENSURE_SUCCESS_VOID(rv);
TextChangeData data(start, start + mPreAttrChangeLength,
start + postAttrChangeLength, causedByComposition);
start + postAttrChangeLength, causedByComposition,
IsEditorComposing());
MaybeNotifyIMEOfTextChange(data);
}
@ -1140,15 +1165,18 @@ IMEContentObserver::MaybeNotifyIMEOfTextChange(
void
IMEContentObserver::MaybeNotifyIMEOfSelectionChange(
bool aCausedByComposition,
bool aCausedBySelectionEvent)
bool aCausedBySelectionEvent,
bool aOccurredDuringComposition)
{
MOZ_LOG(sIMECOLog, LogLevel::Debug,
("IMECO: 0x%p IMEContentObserver::MaybeNotifyIMEOfSelectionChange("
"aCausedByComposition=%s, aCausedBySelectionEvent=%s)",
"aCausedByComposition=%s, aCausedBySelectionEvent=%s, "
"aOccurredDuringComposition)",
this, ToChar(aCausedByComposition), ToChar(aCausedBySelectionEvent)));
mSelectionData.AssignReason(aCausedByComposition,
aCausedBySelectionEvent);
aCausedBySelectionEvent,
aOccurredDuringComposition);
PostSelectionChangeNotification();
FlushMergeableNotifications();
}

View File

@ -122,6 +122,7 @@ private:
nsIContent* aContent) const;
bool IsReflowLocked() const;
bool IsSafeToNotifyIME() const;
bool IsEditorComposing() const;
void PostFocusSetNotification();
void MaybeNotifyIMEOfFocusSet();
@ -129,7 +130,8 @@ private:
void MaybeNotifyIMEOfTextChange(const TextChangeDataBase& aTextChangeData);
void PostSelectionChangeNotification();
void MaybeNotifyIMEOfSelectionChange(bool aCausedByComposition,
bool aCausedBySelectionEvent);
bool aCausedBySelectionEvent,
bool aOccurredDuringComposition);
void PostPositionChangeNotification();
void MaybeNotifyIMEOfPositionChange();

View File

@ -1605,14 +1605,9 @@ Geolocation::WindowOwnerStillExists()
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mOwner);
if (window) {
bool closed = false;
window->GetClosed(&closed);
if (closed) {
return false;
}
nsPIDOMWindow* outer = window->GetOuterWindow();
if (!outer || outer->GetCurrentInnerWindow() != window) {
if (!outer || outer->GetCurrentInnerWindow() != window ||
outer->Closed()) {
return false;
}
}

View File

@ -2268,7 +2268,7 @@ HTMLMediaElement::PlayInternal(bool aCallerIsChrome)
}
if (Preferences::GetBool("media.block-play-until-visible", false) &&
!nsContentUtils::IsCallerChrome() &&
!aCallerIsChrome &&
OwnerDoc()->Hidden()) {
LOG(LogLevel::Debug, ("%p Blocked playback because owner hidden.", this));
mPlayBlockedBecauseHidden = true;
@ -4953,12 +4953,11 @@ HTMLMediaElement::GetTopLevelPrincipal()
{
RefPtr<nsIPrincipal> principal;
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(OwnerDoc()->GetParentObject());
nsCOMPtr<nsIDOMWindow> topWindow;
if (!window) {
return nullptr;
}
window->GetTop(getter_AddRefs(topWindow));
nsCOMPtr<nsPIDOMWindow> top = do_QueryInterface(topWindow);
window = window->GetOuterWindow();
nsCOMPtr<nsPIDOMWindow> top = window->GetTop();
if (!top) {
return nullptr;
}

View File

@ -132,10 +132,8 @@ public:
}
// Trying to found the top window (equivalent to window.top).
nsCOMPtr<nsIDOMWindow> top;
window->GetTop(getter_AddRefs(top));
if (top) {
window = static_cast<nsPIDOMWindow*>(top.get());
if (nsCOMPtr<nsPIDOMWindow> top = window->GetTop()) {
window = top;
}
if (window->GetFocusedNode()) {

View File

@ -261,7 +261,7 @@ var FormVisibility = {
// we also care about the window this is the more
// common case where the content is larger then
// the viewport/screen.
if (win.scrollMaxX || win.scrollMaxY) {
if (win.scrollMaxX != win.scrollMinX || win.scrollMaxY != win.scrollMinY) {
return win;
}

View File

@ -14,463 +14,17 @@ interface nsISelection;
interface nsIVariant;
/**
* The nsIDOMWindow interface is the primary interface for a DOM
* window object. It represents a single window object that may
* contain child windows if the document in the window contains a
* HTML frameset document or if the document contains iframe elements.
*
* @see <http://www.whatwg.org/html/#window>
* Empty interface for compatibility with older versions.
* @deprecated Use WebIDL for script visible features,
* nsPIDOMWindow for C++ callers.
*/
[scriptable, uuid(ab30b7cc-f7f9-4b9b-befb-7dbf6cf86d46)]
interface nsIDOMWindow : nsISupports
{
// the current browsing context
readonly attribute nsIDOMWindow window;
/* [replaceable] self */
readonly attribute nsIDOMWindow self;
/**
* Accessor for the document in this window.
*/
readonly attribute nsIDOMDocument document;
/**
* Set/Get the name of this window.
*
* This attribute is "replaceable" in JavaScript
*/
attribute DOMString name;
/* The setter that takes a string argument needs to be special cased! */
readonly attribute nsIDOMLocation location;
readonly attribute nsISupports history;
/* [replaceable] locationbar */
/* BarProp */
readonly attribute nsISupports locationbar;
/* [replaceable] menubar */
/* BarProp */
readonly attribute nsISupports menubar;
/* [replaceable] personalbar */
/* BarProp */
readonly attribute nsISupports personalbar;
/**
* Accessor for the object that controls whether or not scrollbars
* are shown in this window.
*
* This attribute is "replaceable" in JavaScript
*/
/* BarProp */
readonly attribute nsISupports scrollbars;
/* [replaceable] statusbar */
/* BarProp */
readonly attribute nsISupports statusbar;
/* [replaceable] toolbar */
/* BarProp */
readonly attribute nsISupports toolbar;
/* [replaceable] */
attribute DOMString status;
void close();
void stop();
void focus();
void blur();
// other browsing contexts
/* [replaceable] length */
readonly attribute unsigned long length;
/**
* |top| gets the root of the window hierarchy.
*
* This function does not cross chrome-content boundaries, so if this
* window's parent is of a different type, |top| will return this window.
*
* When script reads the top property, we run GetScriptableTop, which
* will not cross an <iframe mozbrowser> boundary.
*
* In contrast, C++ calls to GetTop are forwarded to GetRealTop, which
* ignores <iframe mozbrowser> boundaries.
*
* This property is "replaceable" in JavaScript.
*/
[binaryname(ScriptableTop)]
readonly attribute nsIDOMWindow top;
/**
* You shouldn't need to call this function directly; call GetTop instead.
*/
[noscript]
readonly attribute nsIDOMWindow realTop;
%{C++
nsresult GetTop(nsIDOMWindow **aWindow)
{
return GetRealTop(aWindow);
}
%}
/**
* |parent| gets this window's parent window. If this window has no parent,
* we return the window itself.
*
* This property does not cross chrome-content boundaries, so if this
* window's parent is of a different type, we return the window itself as its
* parent.
*
* When script reads the property (or when C++ calls ScriptableTop), this
* property does not cross <iframe mozbrowser> boundaries. In contrast, when
* C++ calls GetParent, we ignore the mozbrowser attribute.
*/
[binaryname(ScriptableParent)]
readonly attribute nsIDOMWindow parent;
/**
* You shouldn't need to read this property directly; call GetParent instead.
*/
[noscript]
readonly attribute nsIDOMWindow realParent;
%{C++
inline nsresult GetParent(nsIDOMWindow **aWindow)
{
return GetRealParent(aWindow);
}
%}
[implicit_jscontext, binaryname(ScriptableOpener)]
attribute jsval opener;
[noscript, binaryname(Opener)]
attribute nsIDOMWindow openerWindow;
/**
* |frameElement| gets this window's <iframe> or <frame> element, if it has
* one.
*
* When script reads this property (or when C++ calls
* ScriptableFrameElement), we return |null| if the window is inside an
* <iframe mozbrowser>. In contrast, when C++ calls GetFrameElement, we
* ignore the mozbrowser attribute.
*/
[binaryname(ScriptableFrameElement)]
readonly attribute nsIDOMElement frameElement;
/**
* You shouldn't need to read this property directly; call GetFrameElement
* instead.
*/
[noscript]
readonly attribute nsIDOMElement realFrameElement;
%{C++
inline nsresult GetFrameElement(nsIDOMElement **aElement)
{
return GetRealFrameElement(aElement);
}
%}
// the user agent
readonly attribute nsIDOMNavigator navigator;
/**
* Get the application cache object for this window.
*/
readonly attribute nsIDOMOfflineResourceList applicationCache;
// user prompts
void alert([optional, Null(Stringify)] in DOMString text);
boolean confirm([optional] in DOMString text);
// prompt() should return a null string if cancel is pressed
DOMString prompt([optional] in DOMString aMessage,
[optional] in DOMString aInitial);
void print();
[optional_argc]
nsIVariant showModalDialog(in DOMString aURI,
[optional] in nsIVariant aArgs,
[optional] in DOMString aOptions);
// cross-document messaging
/**
* Implements a safe message-passing system which can cross same-origin
* boundaries.
*
* This method, when called, causes a MessageEvent to be asynchronously
* dispatched at the primary document for the window upon which this method is
* called. (Note that the postMessage property on windows is allAccess and
* thus is readable cross-origin.) The dispatched event will have message as
* its data, the calling context's window as its source, and an origin
* determined by the calling context's main document URI. The targetOrigin
* argument specifies a URI and is used to restrict the message to be sent
* only when the target window has the same origin as targetOrigin (since,
* when the sender and the target have different origins, neither can read the
* location of the other).
*
* @see <http://www.whatwg.org/html/#dom-window-postmessage>
*/
[implicit_jscontext, binaryname(PostMessageMoz)]
void postMessage(in jsval message, in DOMString targetOrigin,
[optional] in jsval transfer);
// WindowBase64
// Ascii base64 data to binary data and vice versa...
DOMString atob(in DOMString aAsciiString);
DOMString btoa(in DOMString aBase64Data);
// WindowSessionStorage
/**
* Session storage for the current browsing context.
* This attribute is a DOMStorage
*/
readonly attribute nsISupports sessionStorage;
// WindowLocalStorage
/**
* Local storage for the current browsing context.
* This attribute is a DOMStorage
*/
readonly attribute nsISupports localStorage;
// IndexedDB
// https://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#requests
// IDBEnvironment
readonly attribute nsISupports indexedDB;
// DOM Range
/**
* Method for accessing this window's selection object.
*/
nsISelection getSelection();
// CSSOM-View
// http://dev.w3.org/csswg/cssom-view/#extensions-to-the-window-interface
nsISupports matchMedia(in DOMString media_query_list);
readonly attribute nsIDOMScreen screen;
// viewport
attribute long innerWidth;
attribute long innerHeight;
// viewport scrolling
/**
* Accessor for the current x scroll position in this window in
* pixels.
*
* This attribute is "replaceable" in JavaScript
*/
readonly attribute long scrollX;
/* The offset in pixels by which the window is scrolled */
readonly attribute long pageXOffset;
/**
* Accessor for the current y scroll position in this window in
* pixels.
*
* This attribute is "replaceable" in JavaScript
*/
readonly attribute long scrollY;
/* The offset in pixels by which the window is scrolled */
readonly attribute long pageYOffset;
void scroll(in long xScroll, in long yScroll);
/**
* Method for scrolling this window to an absolute pixel offset.
*/
void scrollTo(in long xScroll, in long yScroll);
/**
* Method for scrolling this window to a pixel offset relative to
* the current scroll position.
*/
void scrollBy(in long xScrollDif, in long yScrollDif);
// client
attribute long screenX;
attribute long screenY;
attribute long outerWidth;
attribute long outerHeight;
// CSSOM
/**
* @see <http://dev.w3.org/csswg/cssom/#dom-window-getcomputedstyle>
*/
nsIDOMCSSStyleDeclaration getComputedStyle(in nsIDOMElement elt,
[optional] in DOMString pseudoElt);
nsIDOMCSSStyleDeclaration getDefaultComputedStyle(in nsIDOMElement elt,
[optional] in DOMString pseudoElt);
// Mozilla extensions
/**
* Get the window root for this window. This is useful for hooking
* up event listeners to this window and every other window nested
* in the window root.
*/
[noscript] readonly attribute nsIDOMEventTarget windowRoot;
/**
* Accessor for the child windows in this window.
*/
[noscript] readonly attribute nsIDOMWindowCollection frames;
/**
* Set/Get the document scale factor as a multiplier on the default
* size. When setting this attribute, a NS_ERROR_NOT_IMPLEMENTED
* error may be returned by implementations not supporting
* zoom. Implementations not supporting zoom should return 1.0 all
* the time for the Get operation. 1.0 is equals normal size,
* i.e. no zoom.
*/
[noscript] attribute float textZoom;
/**
* Method for scrolling this window by a number of lines.
*/
void scrollByLines(in long numLines);
/**
* Method for scrolling this window by a number of pages.
*/
void scrollByPages(in long numPages);
/**
* Method for sizing this window to the content in the window.
*/
void sizeToContent();
/* [replaceable] prompter */
[noscript] readonly attribute nsIPrompt prompter;
readonly attribute boolean closed;
readonly attribute nsIDOMCrypto crypto;
// Note: this is [ChromeOnly] scriptable via WebIDL.
[noscript] readonly attribute nsIControllers controllers;
readonly attribute float mozInnerScreenX;
readonly attribute float mozInnerScreenY;
readonly attribute float devicePixelRatio;
/* The maximum offset that the window can be scrolled to
(i.e., the document width/height minus the scrollport width/height) */
readonly attribute long scrollMaxX;
readonly attribute long scrollMaxY;
attribute boolean fullScreen;
void back();
void forward();
void home();
void moveTo(in long xPos, in long yPos);
void moveBy(in long xDif, in long yDif);
void resizeTo(in long width, in long height);
void resizeBy(in long widthDif, in long heightDif);
/**
* Open a new window with this one as the parent. This method will
* NOT examine the JS stack for purposes of determining a caller.
* This window will be used for security checks during the search by
* name and the default character set on the newly opened window
* will just be the default character set of this window.
*/
[noscript] nsIDOMWindow open(in DOMString url, in DOMString name,
in DOMString options);
/**
* This method works like open except that aExtraArgument gets
* converted into the array window.arguments in JS, if
* aExtraArgument is a nsISupportsArray then the individual items in
* the array are inserted into window.arguments, and primitive
* nsISupports (nsISupportsPrimitives) types are converted to native
* JS types when possible.
*/
[noscript] nsIDOMWindow openDialog(in DOMString url, in DOMString name,
in DOMString options,
in nsISupports aExtraArgument);
// XXX Should this be in nsIDOMChromeWindow?
void updateCommands(in DOMString action,
[optional] in nsISelection sel,
[optional] in short reason);
/* Find in page.
* @param str: the search pattern
* @param caseSensitive: is the search caseSensitive
* @param backwards: should we search backwards
* @param wrapAround: should we wrap the search
* @param wholeWord: should we search only for whole words
* @param searchInFrames: should we search through all frames
* @param showDialog: should we show the Find dialog
*/
boolean find([optional] in DOMString str,
[optional] in boolean caseSensitive,
[optional] in boolean backwards,
[optional] in boolean wrapAround,
[optional] in boolean wholeWord,
[optional] in boolean searchInFrames,
[optional] in boolean showDialog);
/**
* Returns the number of times this document for this window has
* been painted to the screen.
*/
readonly attribute unsigned long long mozPaintCount;
/**
* Request a refresh of this browser window.
*
* @see <http://dvcs.w3.org/hg/webperf/raw-file/tip/specs/RequestAnimationFrame/Overview.html>
*/
// jsval because we want a WebIDL callback here
[implicit_jscontext]
long requestAnimationFrame(in jsval aCallback);
/**
* Cancel a refresh callback.
*/
void cancelAnimationFrame(in long aHandle);
/**
* Console API
*/
[implicit_jscontext] attribute jsval console;
};
[scriptable, uuid(b8343993-0383-4add-9930-ad176b189240)]
interface nsIDOMWindow : nsISupports {};
/**
* Empty interface for compatibility with older versions.
* @deprecated Use nsIDOMWindow instead
*/
[scriptable, uuid(2ec49e81-b2ba-4633-991a-f48f1e1d8800)]
[scriptable, uuid(8c589e65-3237-4cd1-8bad-c5c47135e79b)]
interface nsIDOMWindowInternal : nsIDOMWindow {};

View File

@ -1191,20 +1191,8 @@ TabChild::ProvideWindowCommon(nsIDOMWindow* aOpener,
NS_ConvertUTF8toUTF16(features),
aWindowIsNew);
} else {
nsCOMPtr<nsIDOMDocument> domDoc;
aOpener->GetDocument(getter_AddRefs(domDoc));
if (!domDoc) {
NS_ERROR("Could retrieve document from nsIBaseWindow");
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIDocument> doc;
doc = do_QueryInterface(domDoc);
if (!doc) {
NS_ERROR("Document from nsIBaseWindow didn't QI to nsIDocument");
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsPIDOMWindow> opener = do_QueryInterface(aOpener);
nsCOMPtr<nsIDocument> doc = opener->GetDoc();
nsCOMPtr<nsIURI> baseURI = doc->GetDocBaseURI();
if (!baseURI) {
NS_ERROR("nsIDocument didn't return a base URI");

View File

@ -755,7 +755,7 @@ private:
nsCString* mURLToLoad;
};
static already_AddRefed<nsIDOMWindow>
static already_AddRefed<nsPIDOMWindow>
FindMostRecentOpenWindow()
{
nsCOMPtr<nsIWindowMediator> windowMediator =
@ -764,17 +764,16 @@ FindMostRecentOpenWindow()
windowMediator->GetEnumerator(MOZ_UTF16("navigator:browser"),
getter_AddRefs(windowEnumerator));
nsCOMPtr<nsIDOMWindow> latest;
nsCOMPtr<nsPIDOMWindow> latest;
bool hasMore = false;
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(windowEnumerator->HasMoreElements(&hasMore)));
while (hasMore) {
nsCOMPtr<nsISupports> item;
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(windowEnumerator->GetNext(getter_AddRefs(item))));
nsCOMPtr<nsIDOMWindow> window = do_QueryInterface(item);
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(item);
bool isClosed;
if (window && NS_SUCCEEDED(window->GetClosed(&isClosed)) && !isClosed) {
if (window && !window->Closed()) {
latest = window;
}
@ -827,17 +826,14 @@ TabParent::RecvCreateWindow(PBrowserParent* aNewTab,
nsCOMPtr<nsIContent> frame(do_QueryInterface(mFrameElement));
nsCOMPtr<nsIDOMWindow> parent;
nsCOMPtr<nsPIDOMWindow> parent;
if (frame) {
parent = do_QueryInterface(frame->OwnerDoc()->GetWindow());
parent = frame->OwnerDoc()->GetWindow();
// If our chrome window is in the process of closing, don't try to open a
// new tab in it.
if (parent) {
bool isClosed;
if (NS_SUCCEEDED(parent->GetClosed(&isClosed)) && isClosed) {
parent = nullptr;
}
if (parent && parent->Closed()) {
parent = nullptr;
}
}

View File

@ -50,7 +50,7 @@ private:
return principal.forget();
}
virtual bool CanClone() override { return false; }
virtual already_AddRefed<MediaResource> CloneData(MediaDecoder* aDecoder) override
virtual already_AddRefed<MediaResource> CloneData(MediaResourceCallback*) override
{
return nullptr;
}

View File

@ -716,6 +716,50 @@ MediaDecoder::FirstFrameLoaded(nsAutoPtr<MediaInfo> aInfo,
NotifySuspendedStatusChanged();
}
nsresult
MediaDecoder::FinishDecoderSetup(MediaResource* aResource)
{
MOZ_ASSERT(NS_IsMainThread());
HTMLMediaElement* element = mOwner->GetMediaElement();
NS_ENSURE_TRUE(element, NS_ERROR_FAILURE);
element->FinishDecoderSetup(this, aResource);
return NS_OK;
}
void
MediaDecoder::NotifyNetworkError()
{
NetworkError();
}
void
MediaDecoder::NotifyDecodeError()
{
nsCOMPtr<nsIRunnable> r =
NS_NewRunnableMethod(this, &MediaDecoder::DecodeError);
AbstractThread::MainThread()->Dispatch(r.forget());
}
void
MediaDecoder::NotifyDataEnded(nsresult aStatus)
{
RefPtr<MediaDecoder> self = this;
nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction([=] () {
self->NotifyDownloadEnded(aStatus);
if (NS_SUCCEEDED(aStatus)) {
HTMLMediaElement* element = self->mOwner->GetMediaElement();
if (element) {
element->DownloadSuspended();
}
// NotifySuspendedStatusChanged will tell the element that download
// has been suspended "by the cache", which is true since we never
// download anything. The element can then transition to HAVE_ENOUGH_DATA.
self->NotifySuspendedStatusChanged();
}
});
AbstractThread::MainThread()->Dispatch(r.forget());
}
void
MediaDecoder::ResetConnectionState()
{
@ -927,6 +971,13 @@ MediaDecoder::NotifyPrincipalChanged()
void
MediaDecoder::NotifyBytesConsumed(int64_t aBytes, int64_t aOffset)
{
if (!NS_IsMainThread()) {
nsCOMPtr<nsIRunnable> r = NS_NewRunnableMethodWithArgs<int64_t, int64_t>(
this, &MediaDecoder::NotifyBytesConsumed, aBytes, aOffset);
AbstractThread::MainThread()->Dispatch(r.forget());
return;
}
MOZ_ASSERT(NS_IsMainThread());
if (mShuttingDown || mIgnoreProgressData) {

View File

@ -209,6 +209,7 @@ destroying the MediaDecoder object.
#include "MediaEventSource.h"
#include "MediaMetadataManager.h"
#include "MediaResource.h"
#include "MediaResourceCallback.h"
#include "MediaStatistics.h"
#include "MediaStreamGraph.h"
#include "TimeUnits.h"
@ -272,7 +273,7 @@ struct SeekTarget {
MediaDecoderEventVisibility mEventVisibility;
};
class MediaDecoder : public AbstractMediaDecoder
class MediaDecoder : public AbstractMediaDecoder, public MediaResourceCallback
{
public:
struct SeekResolveValue {
@ -303,7 +304,7 @@ public:
// Reset the decoder and notify the media element that
// server connection is closed.
virtual void ResetConnectionState();
virtual void ResetConnectionState() override;
// Create a new decoder of the same type as this one.
// Subclasses must implement this.
virtual MediaDecoder* Clone(MediaDecoderOwner* aOwner) = 0;
@ -410,7 +411,7 @@ public:
//
// When the media stream ends, we can know the duration, thus the stream is
// no longer considered to be infinite.
virtual void SetInfinite(bool aInfinite);
virtual void SetInfinite(bool aInfinite) override;
// Return true if the stream is infinite (see SetInfinite).
virtual bool IsInfinite();
@ -419,11 +420,11 @@ public:
// If MediaResource::IsSuspendedByCache returns true, then the decoder
// should stop buffering or otherwise waiting for download progress and
// start consuming data, if possible, because the cache is full.
virtual void NotifySuspendedStatusChanged();
virtual void NotifySuspendedStatusChanged() override;
// Called by MediaResource when some data has been received.
// Call on the main thread only.
virtual void NotifyBytesDownloaded();
virtual void NotifyBytesDownloaded() override;
// Called by nsChannelToPipeListener or MediaResource when the
// download has ended. Called on the main thread only. aStatus is
@ -437,7 +438,7 @@ public:
// Called by MediaResource when the principal of the resource has
// changed. Called on main thread only.
virtual void NotifyPrincipalChanged();
virtual void NotifyPrincipalChanged() override;
// Called by the MediaResource to keep track of the number of bytes read
// from the resource. Called on the main by an event runner dispatched
@ -509,7 +510,7 @@ public:
void SetLoadInBackground(bool aLoadInBackground);
// Returns a weak reference to the media decoder owner.
MediaDecoderOwner* GetMediaOwner() const;
MediaDecoderOwner* GetMediaOwner() const override;
bool OnStateMachineTaskQueue() const override;
@ -1054,6 +1055,13 @@ public:
AbstractCanonical<bool>* CanonicalMediaSeekable() {
return &mMediaSeekable;
}
private:
/* MediaResourceCallback functions */
virtual nsresult FinishDecoderSetup(MediaResource* aResource) override;
virtual void NotifyNetworkError() override;
virtual void NotifyDecodeError() override;
virtual void NotifyDataEnded(nsresult aStatus) override;
};
} // namespace mozilla

View File

@ -7,11 +7,11 @@
#include "mozilla/DebugOnly.h"
#include "MediaResource.h"
#include "MediaResourceCallback.h"
#include "RtspMediaResource.h"
#include "mozilla/Mutex.h"
#include "nsDebug.h"
#include "MediaDecoder.h"
#include "nsNetUtil.h"
#include "nsThreadUtils.h"
#include "nsIFile.h"
@ -65,11 +65,11 @@ NS_IMPL_ADDREF(MediaResource)
NS_IMPL_RELEASE_WITH_DESTROY(MediaResource, Destroy())
NS_IMPL_QUERY_INTERFACE0(MediaResource)
ChannelMediaResource::ChannelMediaResource(MediaDecoder* aDecoder,
ChannelMediaResource::ChannelMediaResource(MediaResourceCallback* aCallback,
nsIChannel* aChannel,
nsIURI* aURI,
const nsACString& aContentType)
: BaseMediaResource(aDecoder, aChannel, aURI, aContentType),
: BaseMediaResource(aCallback, aChannel, aURI, aContentType),
mOffset(0),
mReopenOnError(false),
mIgnoreClose(false),
@ -161,7 +161,7 @@ ChannelMediaResource::OnStartRequest(nsIRequest* aRequest)
{
NS_ASSERTION(mChannel.get() == aRequest, "Wrong channel!");
MediaDecoderOwner* owner = mDecoder->GetMediaOwner();
MediaDecoderOwner* owner = mCallback->GetMediaOwner();
NS_ENSURE_TRUE(owner, NS_ERROR_FAILURE);
dom::HTMLMediaElement* element = owner->GetMediaElement();
NS_ENSURE_TRUE(element, NS_ERROR_FAILURE);
@ -183,7 +183,7 @@ ChannelMediaResource::OnStartRequest(nsIRequest* aRequest)
// If the request was cancelled by nsCORSListenerProxy due to failing
// the CORS security check, send an error through to the media element.
if (status == NS_ERROR_DOM_BAD_URI) {
mDecoder->NetworkError();
mCallback->NotifyNetworkError();
return NS_ERROR_DOM_BAD_URI;
}
}
@ -211,7 +211,7 @@ ChannelMediaResource::OnStartRequest(nsIRequest* aRequest)
// work here.
mCacheStream.NotifyDataEnded(status);
} else {
mDecoder->NetworkError();
mCallback->NotifyNetworkError();
}
// This disconnects our listener so we don't get any more data. We
@ -249,8 +249,8 @@ ChannelMediaResource::OnStartRequest(nsIRequest* aRequest)
// Content-Range header text should be parse-able.
CMLOG("Error processing \'Content-Range' for "
"HTTP_PARTIAL_RESPONSE_CODE: rv[%x] channel[%p] decoder[%p]",
rv, hc.get(), mDecoder);
mDecoder->NetworkError();
rv, hc.get(), mCallback);
mCallback->NotifyNetworkError();
CloseChannel();
return NS_OK;
}
@ -307,7 +307,7 @@ ChannelMediaResource::OnStartRequest(nsIRequest* aRequest)
dataIsBounded = true;
}
mDecoder->SetInfinite(!dataIsBounded);
mCallback->SetInfinite(!dataIsBounded);
}
mCacheStream.SetTransportSeekable(seekable);
@ -377,7 +377,7 @@ ChannelMediaResource::ParseContentRangeHeader(nsIHttpChannel * aHttpChan,
}
CMLOG("Received bytes [%lld] to [%lld] of [%lld] for decoder[%p]",
aRangeStart, aRangeEnd, aRangeTotal, mDecoder);
aRangeStart, aRangeEnd, aRangeTotal, mCallback);
return NS_OK;
}
@ -455,14 +455,14 @@ ChannelMediaResource::CopySegmentToCache(nsIInputStream *aInStream,
{
CopySegmentClosure* closure = static_cast<CopySegmentClosure*>(aClosure);
closure->mResource->mDecoder->NotifyDataArrived(aCount, closure->mResource->mOffset,
closure->mResource->mCallback->NotifyDataArrived(aCount, closure->mResource->mOffset,
/* aThrottleUpdates = */ true);
// Keep track of where we're up to.
RESOURCE_LOG("%p [ChannelMediaResource]: CopySegmentToCache at mOffset [%lld] add "
"[%d] bytes for decoder[%p]",
closure->mResource, closure->mResource->mOffset, aCount,
closure->mResource->mDecoder);
closure->mResource->mCallback);
closure->mResource->mOffset += aCount;
closure->mResource->mCacheStream.NotifyDataReceived(aCount, aFromSegment,
@ -569,7 +569,7 @@ nsresult ChannelMediaResource::OpenChannel(nsIStreamListener** aStreamListener)
NS_ENSURE_SUCCESS(rv, rv);
// Tell the media element that we are fetching data from a channel.
MediaDecoderOwner* owner = mDecoder->GetMediaOwner();
MediaDecoderOwner* owner = mCallback->GetMediaOwner();
NS_ENSURE_TRUE(owner, NS_ERROR_FAILURE);
dom::HTMLMediaElement* element = owner->GetMediaElement();
element->DownloadResumed(true);
@ -604,7 +604,7 @@ nsresult ChannelMediaResource::SetupChannelHeaders()
// Send Accept header for video and audio types only (Bug 489071)
NS_ASSERTION(NS_IsMainThread(), "Don't call on non-main thread");
MediaDecoderOwner* owner = mDecoder->GetMediaOwner();
MediaDecoderOwner* owner = mCallback->GetMediaOwner();
NS_ENSURE_TRUE(owner, NS_ERROR_FAILURE);
dom::HTMLMediaElement* element = owner->GetMediaElement();
NS_ENSURE_TRUE(element, NS_ERROR_FAILURE);
@ -638,13 +638,13 @@ bool ChannelMediaResource::CanClone()
return mCacheStream.IsAvailableForSharing();
}
already_AddRefed<MediaResource> ChannelMediaResource::CloneData(MediaDecoder* aDecoder)
already_AddRefed<MediaResource> ChannelMediaResource::CloneData(MediaResourceCallback* aCallback)
{
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
NS_ASSERTION(mCacheStream.IsAvailableForSharing(), "Stream can't be cloned");
RefPtr<ChannelMediaResource> resource =
new ChannelMediaResource(aDecoder,
new ChannelMediaResource(aCallback,
nullptr,
mURI,
GetContentType());
@ -753,7 +753,7 @@ void ChannelMediaResource::Suspend(bool aCloseImmediately)
{
NS_ASSERTION(NS_IsMainThread(), "Don't call on non-main thread");
MediaDecoderOwner* owner = mDecoder->GetMediaOwner();
MediaDecoderOwner* owner = mCallback->GetMediaOwner();
if (!owner) {
// Shutting down; do nothing.
return;
@ -786,7 +786,7 @@ void ChannelMediaResource::Resume()
{
NS_ASSERTION(NS_IsMainThread(), "Don't call on non-main thread");
MediaDecoderOwner* owner = mDecoder->GetMediaOwner();
MediaDecoderOwner* owner = mCallback->GetMediaOwner();
if (!owner) {
// Shutting down; do nothing.
return;
@ -835,7 +835,7 @@ ChannelMediaResource::RecreateChannel()
nsICachingChannel::LOAD_BYPASS_LOCAL_CACHE_IF_BUSY |
(mLoadInBackground ? nsIRequest::LOAD_BACKGROUND : 0);
MediaDecoderOwner* owner = mDecoder->GetMediaOwner();
MediaDecoderOwner* owner = mCallback->GetMediaOwner();
if (!owner) {
// The decoder is being shut down, so don't bother opening a new channel
return NS_OK;
@ -885,7 +885,7 @@ void
ChannelMediaResource::DoNotifyDataReceived()
{
mDataReceivedEvent.Revoke();
mDecoder->NotifyBytesDownloaded();
mCallback->NotifyBytesDownloaded();
}
void
@ -903,41 +903,11 @@ ChannelMediaResource::CacheClientNotifyDataReceived()
NS_DispatchToMainThread(mDataReceivedEvent.get());
}
class DataEnded : public nsRunnable {
public:
DataEnded(MediaDecoder* aDecoder, nsresult aStatus) :
mDecoder(aDecoder), mStatus(aStatus) {}
NS_IMETHOD Run() {
mDecoder->NotifyDownloadEnded(mStatus);
if (NS_SUCCEEDED(mStatus)) {
MediaDecoderOwner* owner = mDecoder->GetMediaOwner();
if (owner) {
dom::HTMLMediaElement* element = owner->GetMediaElement();
if (element) {
element->DownloadSuspended();
}
}
// NotifySuspendedStatusChanged will tell the element that download
// has been suspended "by the cache", which is true since we never download
// anything. The element can then transition to HAVE_ENOUGH_DATA.
mDecoder->NotifySuspendedStatusChanged();
}
return NS_OK;
}
private:
RefPtr<MediaDecoder> mDecoder;
nsresult mStatus;
};
void
ChannelMediaResource::CacheClientNotifyDataEnded(nsresult aStatus)
{
MOZ_ASSERT(NS_IsMainThread());
// NOTE: this can be called with the media cache lock held, so don't
// block or do anything which might try to acquire a lock!
nsCOMPtr<nsIRunnable> event = new DataEnded(mDecoder, aStatus);
NS_DispatchToCurrentThread(event);
mCallback->NotifyDataEnded(aStatus);
}
void
@ -945,14 +915,14 @@ ChannelMediaResource::CacheClientNotifyPrincipalChanged()
{
NS_ASSERTION(NS_IsMainThread(), "Don't call on non-main thread");
mDecoder->NotifyPrincipalChanged();
mCallback->NotifyPrincipalChanged();
}
void
ChannelMediaResource::CacheClientNotifySuspendedStatusChanged()
{
NS_ASSERTION(NS_IsMainThread(), "Don't call on non-main thread");
mDecoder->NotifySuspendedStatusChanged();
mCallback->NotifySuspendedStatusChanged();
}
nsresult
@ -961,7 +931,7 @@ ChannelMediaResource::CacheClientSeek(int64_t aOffset, bool aResume)
NS_ASSERTION(NS_IsMainThread(), "Don't call on non-main thread");
CMLOG("CacheClientSeek requested for aOffset [%lld] for decoder [%p]",
aOffset, mDecoder);
aOffset, mCallback);
CloseChannel();
@ -1171,11 +1141,11 @@ ChannelSuspendAgent::IsSuspended()
class FileMediaResource : public BaseMediaResource
{
public:
FileMediaResource(MediaDecoder* aDecoder,
FileMediaResource(MediaResourceCallback* aCallback,
nsIChannel* aChannel,
nsIURI* aURI,
const nsACString& aContentType) :
BaseMediaResource(aDecoder, aChannel, aURI, aContentType),
BaseMediaResource(aCallback, aChannel, aURI, aContentType),
mSize(-1),
mLock("FileMediaResource.mLock"),
mSizeInitialized(false)
@ -1192,7 +1162,7 @@ public:
virtual void Resume() override {}
virtual already_AddRefed<nsIPrincipal> GetCurrentPrincipal() override;
virtual bool CanClone() override;
virtual already_AddRefed<MediaResource> CloneData(MediaDecoder* aDecoder) override;
virtual already_AddRefed<MediaResource> CloneData(MediaResourceCallback* aCallback) override;
virtual nsresult ReadFromCache(char* aBuffer, int64_t aOffset, uint32_t aCount) override;
// These methods are called off the main thread.
@ -1306,8 +1276,7 @@ void FileMediaResource::EnsureSizeInitialized()
nsresult res = mInput->Available(&size);
if (NS_SUCCEEDED(res) && size <= INT64_MAX) {
mSize = (int64_t)size;
nsCOMPtr<nsIRunnable> event = new DataEnded(mDecoder, NS_OK);
NS_DispatchToMainThread(event);
mCallback->NotifyDataEnded(NS_OK);
}
}
@ -1404,11 +1373,11 @@ bool FileMediaResource::CanClone()
return true;
}
already_AddRefed<MediaResource> FileMediaResource::CloneData(MediaDecoder* aDecoder)
already_AddRefed<MediaResource> FileMediaResource::CloneData(MediaResourceCallback* aCallback)
{
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
MediaDecoderOwner* owner = mDecoder->GetMediaOwner();
MediaDecoderOwner* owner = mCallback->GetMediaOwner();
if (!owner) {
// The decoder is being shut down, so we can't clone
return nullptr;
@ -1441,7 +1410,7 @@ already_AddRefed<MediaResource> FileMediaResource::CloneData(MediaDecoder* aDeco
if (NS_FAILED(rv))
return nullptr;
RefPtr<MediaResource> resource(new FileMediaResource(aDecoder, channel, mURI, GetContentType()));
RefPtr<MediaResource> resource(new FileMediaResource(aCallback, channel, mURI, GetContentType()));
return resource.forget();
}
@ -1562,7 +1531,7 @@ int64_t FileMediaResource::Tell()
}
already_AddRefed<MediaResource>
MediaResource::Create(MediaDecoder* aDecoder, nsIChannel* aChannel)
MediaResource::Create(MediaResourceCallback* aCallback, nsIChannel* aChannel)
{
NS_ASSERTION(NS_IsMainThread(),
"MediaResource::Open called on non-main thread");
@ -1580,11 +1549,11 @@ MediaResource::Create(MediaDecoder* aDecoder, nsIChannel* aChannel)
nsCOMPtr<nsIFileChannel> fc = do_QueryInterface(aChannel);
RefPtr<MediaResource> resource;
if (fc || IsBlobURI(uri)) {
resource = new FileMediaResource(aDecoder, aChannel, uri, contentType);
resource = new FileMediaResource(aCallback, aChannel, uri, contentType);
} else if (IsRtspURI(uri)) {
resource = new RtspMediaResource(aDecoder, aChannel, uri, contentType);
resource = new RtspMediaResource(aCallback, aChannel, uri, contentType);
} else {
resource = new ChannelMediaResource(aDecoder, aChannel, uri, contentType);
resource = new ChannelMediaResource(aCallback, aChannel, uri, contentType);
}
return resource.forget();
}
@ -1599,7 +1568,7 @@ void BaseMediaResource::SetLoadInBackground(bool aLoadInBackground) {
return;
}
MediaDecoderOwner* owner = mDecoder->GetMediaOwner();
MediaDecoderOwner* owner = mCallback->GetMediaOwner();
if (!owner) {
NS_WARNING("Null owner in MediaResource::SetLoadInBackground()");
return;
@ -1652,45 +1621,12 @@ void BaseMediaResource::ModifyLoadFlags(nsLoadFlags aFlags)
}
}
class DispatchBytesConsumedEvent : public nsRunnable {
public:
DispatchBytesConsumedEvent(MediaDecoder* aDecoder,
int64_t aNumBytes,
int64_t aOffset)
: mDecoder(aDecoder),
mNumBytes(aNumBytes),
mOffset(aOffset)
{
MOZ_COUNT_CTOR(DispatchBytesConsumedEvent);
}
protected:
~DispatchBytesConsumedEvent()
{
MOZ_COUNT_DTOR(DispatchBytesConsumedEvent);
}
public:
NS_IMETHOD Run() {
mDecoder->NotifyBytesConsumed(mNumBytes, mOffset);
// Drop ref to decoder on main thread, just in case this reference
// ends up being the last owning reference somehow.
mDecoder = nullptr;
return NS_OK;
}
RefPtr<MediaDecoder> mDecoder;
int64_t mNumBytes;
int64_t mOffset;
};
void BaseMediaResource::DispatchBytesConsumed(int64_t aNumBytes, int64_t aOffset)
{
if (aNumBytes <= 0) {
return;
}
RefPtr<nsIRunnable> event(new DispatchBytesConsumedEvent(mDecoder, aNumBytes, aOffset));
NS_DispatchToMainThread(event);
mCallback->NotifyBytesConsumed(aNumBytes, aOffset);
}
nsresult

View File

@ -43,7 +43,7 @@ class nsIPrincipal;
namespace mozilla {
class MediaDecoder;
class MediaResourceCallback;
class MediaChannelStatistics;
/**
@ -270,7 +270,7 @@ public:
// Create a new stream of the same type that refers to the same URI
// with a new channel. Any cached data associated with the original
// stream should be accessible in the new stream too.
virtual already_AddRefed<MediaResource> CloneData(MediaDecoder* aDecoder) = 0;
virtual already_AddRefed<MediaResource> CloneData(MediaResourceCallback* aCallback) = 0;
// Set statistics to be recorded to the object passed in.
virtual void RecordStatisticsTo(MediaChannelStatistics *aStatistics) { }
@ -387,7 +387,7 @@ public:
* Create a resource, reading data from the channel. Call on main thread only.
* The caller must follow up by calling resource->Open().
*/
static already_AddRefed<MediaResource> Create(MediaDecoder* aDecoder, nsIChannel* aChannel);
static already_AddRefed<MediaResource> Create(MediaResourceCallback* aCallback, nsIChannel* aChannel);
/**
* Open the stream. This creates a stream listener and returns it in
@ -460,7 +460,7 @@ public:
// - mChannel
// - mURI (possibly owned, looks like just a ref from mChannel)
// Not owned:
// - mDecoder
// - mCallback
size_t size = MediaResource::SizeOfExcludingThis(aMallocSizeOf);
size += mContentType.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
@ -480,11 +480,11 @@ public:
}
protected:
BaseMediaResource(MediaDecoder* aDecoder,
BaseMediaResource(MediaResourceCallback* aCallback,
nsIChannel* aChannel,
nsIURI* aURI,
const nsACString& aContentType) :
mDecoder(aDecoder),
mCallback(aCallback),
mChannel(aChannel),
mURI(aURI),
mContentType(aContentType),
@ -516,7 +516,7 @@ protected:
// This is not an nsCOMPointer to prevent a circular reference
// between the decoder to the media stream object. The stream never
// outlives the lifetime of the decoder.
MediaDecoder* mDecoder;
MediaResourceCallback* mCallback;
// Channel used to download the media data. Must be accessed
// from the main thread only.
@ -593,7 +593,7 @@ private:
class ChannelMediaResource : public BaseMediaResource
{
public:
ChannelMediaResource(MediaDecoder* aDecoder,
ChannelMediaResource(MediaResourceCallback* aDecoder,
nsIChannel* aChannel,
nsIURI* aURI,
const nsACString& aContentType);
@ -643,7 +643,7 @@ public:
// Return true if the stream has been closed.
bool IsClosed() const { return mCacheStream.IsClosed(); }
virtual bool CanClone() override;
virtual already_AddRefed<MediaResource> CloneData(MediaDecoder* aDecoder) override;
virtual already_AddRefed<MediaResource> CloneData(MediaResourceCallback* aDecoder) override;
// Set statistics to be recorded to the object passed in. If not called,
// |ChannelMediaResource| will create it's own statistics objects in |Open|.
void RecordStatisticsTo(MediaChannelStatistics *aStatistics) override {

View File

@ -0,0 +1,75 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef MediaResourceCallback_h_
#define MediaResourceCallback_h_
#include "nsError.h"
namespace mozilla {
class MediaResource;
/**
* A callback used by MediaResource (sub-classes like FileMediaResource,
* RtspMediaResource, and ChannelMediaResource) to notify various events.
* Currently this is implemented by MediaDecoder only.
*
* Since this class has no pure virtual function, it is convenient to write
* gtests for the readers without using a mock MediaResource when you don't
* care about the events notified by the MediaResource.
*/
class MediaResourceCallback {
public:
// Returns a weak reference to the media decoder owner.
virtual MediaDecoderOwner* GetMediaOwner() const { return nullptr; }
// Notify is duration is known to this MediaResource.
virtual void SetInfinite(bool aInfinite) {}
// Notify if seeking is supported by this MediaResource.
virtual void SetMediaSeekable(bool aMediaSeekable) {}
// Notify that server connection is closed.
virtual void ResetConnectionState() {}
// Used by RtspMediaResource which has an unusual sequence
// to setup the decoder.
virtual nsresult FinishDecoderSetup(MediaResource* aResource) {
return NS_OK;
}
// Notify that a network error is encountered.
virtual void NotifyNetworkError() {}
// Notify that decoding has failed.
virtual void NotifyDecodeError() {}
// Notify that data arrives on the stream and is read into the cache.
virtual void NotifyDataArrived(
uint32_t aLength, int64_t aOffset, bool aThrottleUpdates) {}
// Notify that MediaResource has received some data.
virtual void NotifyBytesDownloaded() {}
// Notify download is ended.
// NOTE: this can be called with the media cache lock held, so don't
// block or do anything which might try to acquire a lock!
virtual void NotifyDataEnded(nsresult aStatus) {}
// Notify that the principal of MediaResource has changed.
virtual void NotifyPrincipalChanged() {}
// Notify that the "cache suspended" status of MediaResource changes.
virtual void NotifySuspendedStatusChanged() {}
// Notify the number of bytes read from the resource.
virtual void NotifyBytesConsumed(int64_t aBytes, int64_t aOffset) {}
};
} // namespace mozilla
#endif //MediaResourceCallback_h_

View File

@ -488,9 +488,9 @@ RtspTrackBuffer::PlayoutDelayTimerCallback(nsITimer *aTimer,
//-----------------------------------------------------------------------------
// RtspMediaResource
//-----------------------------------------------------------------------------
RtspMediaResource::RtspMediaResource(MediaDecoder* aDecoder,
RtspMediaResource::RtspMediaResource(MediaResourceCallback* aCallback,
nsIChannel* aChannel, nsIURI* aURI, const nsACString& aContentType)
: BaseMediaResource(aDecoder, aChannel, aURI, aContentType)
: BaseMediaResource(aCallback, aChannel, aURI, aContentType)
, mIsConnected(false)
, mIsLiveStream(false)
, mHasTimestamp(true)
@ -537,8 +537,8 @@ void RtspMediaResource::NotifySuspend(bool aIsSuspend)
RTSPMLOG("NotifySuspend %d",aIsSuspend);
mIsSuspend = aIsSuspend;
if (mDecoder) {
mDecoder->NotifySuspendedStatusChanged();
if (mCallback) {
mCallback->NotifySuspendedStatusChanged();
}
}
@ -688,9 +688,7 @@ RtspMediaResource::OnConnected(uint8_t aTrackIdx,
// video, we give up moving forward.
if (!IsVideoEnabled() && IsVideo(tracks, meta)) {
// Give up, report error to media element.
nsCOMPtr<nsIRunnable> event =
NS_NewRunnableMethod(mDecoder, &MediaDecoder::DecodeError);
NS_DispatchToMainThread(event);
mCallback->NotifyDecodeError();
return NS_ERROR_FAILURE;
}
uint64_t durationUs = 0;
@ -717,7 +715,7 @@ RtspMediaResource::OnConnected(uint8_t aTrackIdx,
mTrackBuffer[i]->Start();
}
if (!mDecoder) {
if (!mCallback) {
return NS_ERROR_FAILURE;
}
@ -725,34 +723,30 @@ RtspMediaResource::OnConnected(uint8_t aTrackIdx,
if (durationUs) {
// Not live stream.
mIsLiveStream = false;
mDecoder->SetInfinite(false);
mCallback->SetInfinite(false);
} else {
// Live stream.
// Check the preference "media.realtime_decoder.enabled".
if (!Preferences::GetBool("media.realtime_decoder.enabled", false)) {
// Give up, report error to media element.
nsCOMPtr<nsIRunnable> event =
NS_NewRunnableMethod(mDecoder, &MediaDecoder::DecodeError);
NS_DispatchToMainThread(event);
mCallback->NotifyDecodeError();
return NS_ERROR_FAILURE;
} else {
mIsLiveStream = true;
bool seekable = false;
mDecoder->SetInfinite(true);
mDecoder->SetMediaSeekable(seekable);
mCallback->SetInfinite(true);
mCallback->SetMediaSeekable(seekable);
}
}
MediaDecoderOwner* owner = mDecoder->GetMediaOwner();
MediaDecoderOwner* owner = mCallback->GetMediaOwner();
NS_ENSURE_TRUE(owner, NS_ERROR_FAILURE);
// Fires an initial progress event.
owner->DownloadProgressed();
dom::HTMLMediaElement* element = owner->GetMediaElement();
NS_ENSURE_TRUE(element, NS_ERROR_FAILURE);
nsresult rv = mCallback->FinishDecoderSetup(this);
NS_ENSURE_SUCCESS(rv, rv);
element->FinishDecoderSetup(mDecoder, this);
mIsConnected = true;
return NS_OK;
}
@ -766,7 +760,7 @@ RtspMediaResource::OnDisconnected(uint8_t aTrackIdx, nsresult aReason)
mTrackBuffer[i]->Reset();
}
if (mDecoder) {
if (mCallback) {
if (aReason == NS_ERROR_NOT_INITIALIZED ||
aReason == NS_ERROR_CONNECTION_REFUSED ||
aReason == NS_ERROR_NOT_CONNECTED ||
@ -774,11 +768,11 @@ RtspMediaResource::OnDisconnected(uint8_t aTrackIdx, nsresult aReason)
// Report error code to Decoder.
RTSPMLOG("Error in OnDisconnected 0x%x", aReason);
mIsConnected = false;
mDecoder->NetworkError();
mCallback->NotifyNetworkError();
} else {
// Resetting the decoder and media element when the connection
// between RTSP client and server goes down.
mDecoder->ResetConnectionState();
mCallback->ResetConnectionState();
}
}
@ -796,18 +790,18 @@ void RtspMediaResource::Suspend(bool aCloseImmediately)
NS_ASSERTION(NS_IsMainThread(), "Don't call on non-main thread");
mIsSuspend = true;
if (NS_WARN_IF(!mDecoder)) {
if (NS_WARN_IF(!mCallback)) {
return;
}
MediaDecoderOwner* owner = mDecoder->GetMediaOwner();
MediaDecoderOwner* owner = mCallback->GetMediaOwner();
NS_ENSURE_TRUE_VOID(owner);
dom::HTMLMediaElement* element = owner->GetMediaElement();
NS_ENSURE_TRUE_VOID(element);
mMediaStreamController->Suspend();
element->DownloadSuspended();
mDecoder->NotifySuspendedStatusChanged();
mCallback->NotifySuspendedStatusChanged();
}
void RtspMediaResource::Resume()
@ -815,11 +809,11 @@ void RtspMediaResource::Resume()
NS_ASSERTION(NS_IsMainThread(), "Don't call on non-main thread");
mIsSuspend = false;
if (NS_WARN_IF(!mDecoder)) {
if (NS_WARN_IF(!mCallback)) {
return;
}
MediaDecoderOwner* owner = mDecoder->GetMediaOwner();
MediaDecoderOwner* owner = mCallback->GetMediaOwner();
NS_ENSURE_TRUE_VOID(owner);
dom::HTMLMediaElement* element = owner->GetMediaElement();
NS_ENSURE_TRUE_VOID(element);
@ -828,7 +822,7 @@ void RtspMediaResource::Resume()
element->DownloadResumed();
}
mMediaStreamController->Resume();
mDecoder->NotifySuspendedStatusChanged();
mCallback->NotifySuspendedStatusChanged();
}
nsresult RtspMediaResource::Open(nsIStreamListener **aStreamListener)
@ -840,11 +834,11 @@ nsresult RtspMediaResource::Close()
{
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
mMediaStreamController->Stop();
// Since mDecoder is not an nsCOMPtr in BaseMediaResource, we have to
// Since mCallback is not an nsCOMPtr in BaseMediaResource, we have to
// explicitly set it as null pointer in order to prevent misuse from this
// object (RtspMediaResource).
if (mDecoder) {
mDecoder = nullptr;
if (mCallback) {
mCallback = nullptr;
}
return NS_OK;
}
@ -866,7 +860,7 @@ nsresult RtspMediaResource::SeekTime(int64_t aOffset)
NS_ASSERTION(!NS_IsMainThread(), "Don't call on main thread");
RTSPMLOG("Seek requested for aOffset [%lld] for decoder [%p]",
aOffset, mDecoder);
aOffset, mCallback);
// Clear buffer and raise the frametype flag.
for(uint32_t i = 0 ; i < mTrackBuffer.Length(); ++i) {
mTrackBuffer[i]->ResetWithFrameType(MEDIASTREAM_FRAMETYPE_DISCONTINUITY);

View File

@ -71,7 +71,7 @@ class RtspTrackBuffer;
class RtspMediaResource : public BaseMediaResource
{
public:
RtspMediaResource(MediaDecoder* aDecoder, nsIChannel* aChannel, nsIURI* aURI,
RtspMediaResource(MediaResourceCallback* aCallback, nsIChannel* aChannel, nsIURI* aURI,
const nsACString& aContentType);
virtual ~RtspMediaResource();
@ -176,7 +176,7 @@ public:
virtual bool CanClone() override {
return false;
}
virtual already_AddRefed<MediaResource> CloneData(MediaDecoder* aDecoder)
virtual already_AddRefed<MediaResource> CloneData(MediaResourceCallback*)
override {
return nullptr;
}

View File

@ -52,10 +52,12 @@ NS_INTERFACE_MAP_END
MediaKeySystemAccess::MediaKeySystemAccess(nsPIDOMWindow* aParent,
const nsAString& aKeySystem,
const nsAString& aCDMVersion)
const nsAString& aCDMVersion,
const MediaKeySystemConfiguration& aConfig)
: mParent(aParent)
, mKeySystem(aKeySystem)
, mCDMVersion(aCDMVersion)
, mConfig(aConfig)
{
}
@ -81,6 +83,12 @@ MediaKeySystemAccess::GetKeySystem(nsString& aOutKeySystem) const
ConstructKeySystem(mKeySystem, mCDMVersion, aOutKeySystem);
}
void
MediaKeySystemAccess::GetConfiguration(MediaKeySystemConfiguration& aConfig)
{
aConfig = mConfig;
}
already_AddRefed<Promise>
MediaKeySystemAccess::CreateMediaKeys(ErrorResult& aRv)
{
@ -373,39 +381,114 @@ GMPDecryptsAndGeckoDecodesAAC(mozIGeckoMediaPluginService* aGMPService,
) && MP4Decoder::CanHandleMediaType(aContentType);
}
static bool
IsSupportedAudio(mozIGeckoMediaPluginService* aGMPService,
const nsAString& aKeySystem,
const nsAString& aAudioType)
{
return IsAACContentType(aAudioType) &&
(GMPDecryptsAndDecodesAAC(aGMPService, aKeySystem) ||
GMPDecryptsAndGeckoDecodesAAC(aGMPService, aKeySystem, aAudioType));
}
static bool
IsSupportedVideo(mozIGeckoMediaPluginService* aGMPService,
const nsAString& aKeySystem,
const nsAString& aVideoType)
{
return IsH264ContentType(aVideoType) &&
(GMPDecryptsAndDecodesH264(aGMPService, aKeySystem) ||
GMPDecryptsAndGeckoDecodesH264(aGMPService, aKeySystem, aVideoType));
}
static bool
IsSupported(mozIGeckoMediaPluginService* aGMPService,
const nsAString& aKeySystem,
const MediaKeySystemOptions& aConfig)
const MediaKeySystemConfiguration& aConfig)
{
if (!aConfig.mInitDataType.EqualsLiteral("cenc")) {
if (aConfig.mInitDataType.IsEmpty() &&
aConfig.mAudioType.IsEmpty() &&
aConfig.mVideoType.IsEmpty()) {
// Not an old-style request.
return false;
}
if (!aConfig.mAudioCapability.IsEmpty() ||
!aConfig.mVideoCapability.IsEmpty()) {
// Don't support any capabilities until we know we have a CDM with
// capabilities...
// Backwards compatibility with legacy MediaKeySystemConfiguration method.
if (!aConfig.mInitDataType.IsEmpty() &&
!aConfig.mInitDataType.EqualsLiteral("cenc")) {
return false;
}
if (!aConfig.mAudioType.IsEmpty() &&
(!IsAACContentType(aConfig.mAudioType) ||
(!GMPDecryptsAndDecodesAAC(aGMPService, aKeySystem) &&
!GMPDecryptsAndGeckoDecodesAAC(aGMPService, aKeySystem, aConfig.mAudioType)))) {
!IsSupportedAudio(aGMPService, aKeySystem, aConfig.mAudioType)) {
return false;
}
if (!aConfig.mVideoType.IsEmpty() &&
(!IsH264ContentType(aConfig.mVideoType) ||
(!GMPDecryptsAndDecodesH264(aGMPService, aKeySystem) &&
!GMPDecryptsAndGeckoDecodesH264(aGMPService, aKeySystem, aConfig.mVideoType)))) {
!IsSupportedVideo(aGMPService, aKeySystem, aConfig.mVideoType)) {
return false;
}
return true;
}
static bool
GetSupportedConfig(mozIGeckoMediaPluginService* aGMPService,
const nsAString& aKeySystem,
const MediaKeySystemConfiguration& aCandidate,
MediaKeySystemConfiguration& aOutConfig)
{
MediaKeySystemConfiguration config;
config.mLabel = aCandidate.mLabel;
if (aCandidate.mInitDataTypes.WasPassed()) {
nsTArray<nsString> initDataTypes;
for (const nsString& candidate : aCandidate.mInitDataTypes.Value()) {
if (candidate.EqualsLiteral("cenc")) {
initDataTypes.AppendElement(candidate);
}
}
if (initDataTypes.IsEmpty()) {
return false;
}
config.mInitDataTypes.Construct();
config.mInitDataTypes.Value().Assign(initDataTypes);
}
if (aCandidate.mAudioCapabilities.WasPassed()) {
nsTArray<MediaKeySystemMediaCapability> caps;
for (const MediaKeySystemMediaCapability& cap : aCandidate.mAudioCapabilities.Value()) {
if (IsSupportedAudio(aGMPService, aKeySystem, cap.mContentType)) {
caps.AppendElement(cap);
}
}
if (caps.IsEmpty()) {
return false;
}
config.mAudioCapabilities.Construct();
config.mAudioCapabilities.Value().Assign(caps);
}
if (aCandidate.mVideoCapabilities.WasPassed()) {
nsTArray<MediaKeySystemMediaCapability> caps;
for (const MediaKeySystemMediaCapability& cap : aCandidate.mVideoCapabilities.Value()) {
if (IsSupportedVideo(aGMPService, aKeySystem, cap.mContentType)) {
caps.AppendElement(cap);
}
}
if (caps.IsEmpty()) {
return false;
}
config.mVideoCapabilities.Construct();
config.mVideoCapabilities.Value().Assign(caps);
}
aOutConfig = config;
return true;
}
// Backwards compatibility with legacy requestMediaKeySystemAccess with fields
// from old MediaKeySystemOptions dictionary.
/* static */
bool
MediaKeySystemAccess::IsSupported(const nsAString& aKeySystem,
const Sequence<MediaKeySystemOptions>& aOptions)
const Sequence<MediaKeySystemConfiguration>& aConfigs)
{
nsCOMPtr<mozIGeckoMediaPluginService> mps =
do_GetService("@mozilla.org/gecko-media-plugin-service;1");
@ -419,7 +502,7 @@ MediaKeySystemAccess::IsSupported(const nsAString& aKeySystem,
return false;
}
for (const MediaKeySystemOptions& config : aOptions) {
for (const MediaKeySystemConfiguration& config : aConfigs) {
if (mozilla::dom::IsSupported(mps, aKeySystem, config)) {
return true;
}
@ -427,6 +510,34 @@ MediaKeySystemAccess::IsSupported(const nsAString& aKeySystem,
return false;
}
/* static */
bool
MediaKeySystemAccess::GetSupportedConfig(const nsAString& aKeySystem,
const Sequence<MediaKeySystemConfiguration>& aConfigs,
MediaKeySystemConfiguration& aOutConfig)
{
nsCOMPtr<mozIGeckoMediaPluginService> mps =
do_GetService("@mozilla.org/gecko-media-plugin-service;1");
if (NS_WARN_IF(!mps)) {
return false;
}
if (!HaveGMPFor(mps,
NS_ConvertUTF16toUTF8(aKeySystem),
NS_LITERAL_CSTRING(GMP_API_DECRYPTOR))) {
return false;
}
for (const MediaKeySystemConfiguration& config : aConfigs) {
if (mozilla::dom::GetSupportedConfig(mps, aKeySystem, config, aOutConfig)) {
return true;
}
}
return false;
}
/* static */
void
MediaKeySystemAccess::NotifyObservers(nsIDOMWindow* aWindow,

View File

@ -31,7 +31,8 @@ public:
public:
explicit MediaKeySystemAccess(nsPIDOMWindow* aParent,
const nsAString& aKeySystem,
const nsAString& aCDMVersion);
const nsAString& aCDMVersion,
const MediaKeySystemConfiguration& aConfig);
protected:
~MediaKeySystemAccess();
@ -43,6 +44,8 @@ public:
void GetKeySystem(nsString& aRetVal) const;
void GetConfiguration(MediaKeySystemConfiguration& aConfig);
already_AddRefed<Promise> CreateMediaKeys(ErrorResult& aRv);
@ -53,7 +56,7 @@ public:
nsACString& aOutCdmVersion);
static bool IsSupported(const nsAString& aKeySystem,
const Sequence<MediaKeySystemOptions>& aOptions);
const Sequence<MediaKeySystemConfiguration>& aConfigs);
static void NotifyObservers(nsIDOMWindow* aWindow,
const nsAString& aKeySystem,
@ -63,10 +66,15 @@ public:
const nsACString& aVersion,
nsACString& aOutMessage);
static bool GetSupportedConfig(const nsAString& aKeySystem,
const Sequence<MediaKeySystemConfiguration>& aConfigs,
MediaKeySystemConfiguration& aOutConfig);
private:
nsCOMPtr<nsPIDOMWindow> mParent;
const nsString mKeySystem;
const nsString mCDMVersion;
const MediaKeySystemConfiguration mConfig;
};
} // namespace dom

View File

@ -63,16 +63,14 @@ MediaKeySystemAccessManager::~MediaKeySystemAccessManager()
void
MediaKeySystemAccessManager::Request(DetailedPromise* aPromise,
const nsAString& aKeySystem,
const Optional<Sequence<MediaKeySystemOptions>>& aOptions)
const Sequence<MediaKeySystemConfiguration>& aConfigs)
{
if (aKeySystem.IsEmpty() || (aOptions.WasPassed() && aOptions.Value().IsEmpty())) {
if (aKeySystem.IsEmpty() || aConfigs.IsEmpty()) {
aPromise->MaybeReject(NS_ERROR_DOM_INVALID_ACCESS_ERR,
NS_LITERAL_CSTRING("Invalid keysystem type or invalid options sequence"));
return;
}
Sequence<MediaKeySystemOptions> optionsNotPassed;
const auto& options = aOptions.WasPassed() ? aOptions.Value() : optionsNotPassed;
Request(aPromise, aKeySystem, options, RequestType::Initial);
Request(aPromise, aKeySystem, aConfigs, RequestType::Initial);
}
static bool
@ -91,7 +89,7 @@ ShouldTrialCreateGMP(const nsAString& aKeySystem)
void
MediaKeySystemAccessManager::Request(DetailedPromise* aPromise,
const nsAString& aKeySystem,
const Sequence<MediaKeySystemOptions>& aOptions,
const Sequence<MediaKeySystemConfiguration>& aConfigs,
RequestType aType)
{
EME_LOG("MediaKeySystemAccessManager::Request %s", NS_ConvertUTF16toUTF8(aKeySystem).get());
@ -145,7 +143,7 @@ MediaKeySystemAccessManager::Request(DetailedPromise* aPromise,
// has had a new plugin added. AwaitInstall() sets a timer to fail if the
// update/download takes too long or fails.
if (aType == RequestType::Initial &&
AwaitInstall(aPromise, aKeySystem, aOptions)) {
AwaitInstall(aPromise, aKeySystem, aConfigs)) {
// Notify chrome that we're going to wait for the CDM to download/update.
// Note: If we're re-trying, we don't re-send the notificaiton,
// as chrome is already displaying the "we can't play, updating"
@ -174,10 +172,13 @@ MediaKeySystemAccessManager::Request(DetailedPromise* aPromise,
return;
}
if (aOptions.IsEmpty() ||
MediaKeySystemAccess::IsSupported(keySystem, aOptions)) {
MediaKeySystemConfiguration config;
// TODO: Remove IsSupported() check here once we remove backwards
// compatibility with initial implementation...
if (MediaKeySystemAccess::GetSupportedConfig(keySystem, aConfigs, config) ||
MediaKeySystemAccess::IsSupported(keySystem, aConfigs)) {
RefPtr<MediaKeySystemAccess> access(
new MediaKeySystemAccess(mWindow, keySystem, NS_ConvertUTF8toUTF16(cdmVersion)));
new MediaKeySystemAccess(mWindow, keySystem, NS_ConvertUTF8toUTF16(cdmVersion), config));
if (ShouldTrialCreateGMP(keySystem)) {
// Ensure we have tried creating a GMPVideoDecoder for this
// keySystem, and that we can use it to decode. This ensures that we only
@ -195,11 +196,11 @@ MediaKeySystemAccessManager::Request(DetailedPromise* aPromise,
MediaKeySystemAccessManager::PendingRequest::PendingRequest(DetailedPromise* aPromise,
const nsAString& aKeySystem,
const Sequence<MediaKeySystemOptions>& aOptions,
const Sequence<MediaKeySystemConfiguration>& aConfigs,
nsITimer* aTimer)
: mPromise(aPromise)
, mKeySystem(aKeySystem)
, mOptions(aOptions)
, mConfigs(aConfigs)
, mTimer(aTimer)
{
MOZ_COUNT_CTOR(MediaKeySystemAccessManager::PendingRequest);
@ -208,7 +209,7 @@ MediaKeySystemAccessManager::PendingRequest::PendingRequest(DetailedPromise* aPr
MediaKeySystemAccessManager::PendingRequest::PendingRequest(const PendingRequest& aOther)
: mPromise(aOther.mPromise)
, mKeySystem(aOther.mKeySystem)
, mOptions(aOther.mOptions)
, mConfigs(aOther.mConfigs)
, mTimer(aOther.mTimer)
{
MOZ_COUNT_CTOR(MediaKeySystemAccessManager::PendingRequest);
@ -238,7 +239,7 @@ MediaKeySystemAccessManager::PendingRequest::RejectPromise(const nsCString& aRea
bool
MediaKeySystemAccessManager::AwaitInstall(DetailedPromise* aPromise,
const nsAString& aKeySystem,
const Sequence<MediaKeySystemOptions>& aOptions)
const Sequence<MediaKeySystemConfiguration>& aConfigs)
{
EME_LOG("MediaKeySystemAccessManager::AwaitInstall %s", NS_ConvertUTF16toUTF8(aKeySystem).get());
@ -253,7 +254,7 @@ MediaKeySystemAccessManager::AwaitInstall(DetailedPromise* aPromise,
return false;
}
mRequests.AppendElement(PendingRequest(aPromise, aKeySystem, aOptions, timer));
mRequests.AppendElement(PendingRequest(aPromise, aKeySystem, aConfigs, timer));
return true;
}
@ -261,7 +262,7 @@ void
MediaKeySystemAccessManager::RetryRequest(PendingRequest& aRequest)
{
aRequest.CancelTimer();
Request(aRequest.mPromise, aRequest.mKeySystem, aRequest.mOptions, RequestType::Subsequent);
Request(aRequest.mPromise, aRequest.mKeySystem, aRequest.mConfigs, RequestType::Subsequent);
}
nsresult

View File

@ -30,14 +30,14 @@ public:
void Request(DetailedPromise* aPromise,
const nsAString& aKeySystem,
const Optional<Sequence<MediaKeySystemOptions>>& aOptions);
const Sequence<MediaKeySystemConfiguration>& aConfig);
void Shutdown();
struct PendingRequest {
PendingRequest(DetailedPromise* aPromise,
const nsAString& aKeySystem,
const Sequence<MediaKeySystemOptions>& aOptions,
const Sequence<MediaKeySystemConfiguration>& aConfig,
nsITimer* aTimer);
PendingRequest(const PendingRequest& aOther);
~PendingRequest();
@ -46,7 +46,7 @@ public:
RefPtr<DetailedPromise> mPromise;
const nsString mKeySystem;
const Sequence<MediaKeySystemOptions> mOptions;
const Sequence<MediaKeySystemConfiguration> mConfigs;
nsCOMPtr<nsITimer> mTimer;
};
@ -59,7 +59,7 @@ private:
void Request(DetailedPromise* aPromise,
const nsAString& aKeySystem,
const Sequence<MediaKeySystemOptions>& aOptions,
const Sequence<MediaKeySystemConfiguration>& aConfig,
RequestType aType);
~MediaKeySystemAccessManager();
@ -68,7 +68,7 @@ private:
bool AwaitInstall(DetailedPromise* aPromise,
const nsAString& aKeySystem,
const Sequence<MediaKeySystemOptions>& aOptions);
const Sequence<MediaKeySystemConfiguration>& aConfig);
void RetryRequest(PendingRequest& aRequest);

View File

@ -312,9 +312,8 @@ MediaKeys::Init(ErrorResult& aRv)
NS_LITERAL_CSTRING("Couldn't get top-level window in MediaKeys::Init"));
return promise.forget();
}
nsCOMPtr<nsIDOMWindow> topWindow;
window->GetTop(getter_AddRefs(topWindow));
nsCOMPtr<nsPIDOMWindow> top = do_QueryInterface(topWindow);
window = window->GetOuterWindow();
nsCOMPtr<nsPIDOMWindow> top = window->GetTop();
if (!top || !top->GetExtantDoc()) {
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR,
NS_LITERAL_CSTRING("Couldn't get document in MediaKeys::Init"));

View File

@ -25,7 +25,7 @@ public:
return nullptr;
}
virtual bool CanClone() override { return false; }
virtual already_AddRefed<MediaResource> CloneData(MediaDecoder* aDecoder)
virtual already_AddRefed<MediaResource> CloneData(MediaResourceCallback*)
override
{
return nullptr;

View File

@ -32,7 +32,7 @@ public:
virtual void Suspend(bool aCloseImmediately) override { UNIMPLEMENTED(); }
virtual void Resume() override { UNIMPLEMENTED(); }
virtual bool CanClone() override { UNIMPLEMENTED(); return false; }
virtual already_AddRefed<MediaResource> CloneData(MediaDecoder* aDecoder) override { UNIMPLEMENTED(); return nullptr; }
virtual already_AddRefed<MediaResource> CloneData(MediaResourceCallback*) override { UNIMPLEMENTED(); return nullptr; }
virtual void SetReadMode(MediaCacheStream::ReadMode aMode) override { UNIMPLEMENTED(); }
virtual void SetPlaybackRate(uint32_t aBytesPerSecond) override { UNIMPLEMENTED(); }
virtual nsresult ReadAt(int64_t aOffset, char* aBuffer, uint32_t aCount, uint32_t* aBytes) override { UNIMPLEMENTED(); return NS_ERROR_FAILURE; }

View File

@ -43,7 +43,7 @@ public:
virtual void Suspend(bool aCloseImmediately) override { UNIMPLEMENTED(); }
virtual void Resume() override { UNIMPLEMENTED(); }
virtual already_AddRefed<nsIPrincipal> GetCurrentPrincipal() override { UNIMPLEMENTED(); return nullptr; }
virtual already_AddRefed<MediaResource> CloneData(MediaDecoder* aDecoder) override { UNIMPLEMENTED(); return nullptr; }
virtual already_AddRefed<MediaResource> CloneData(MediaResourceCallback*) override { UNIMPLEMENTED(); return nullptr; }
virtual void SetReadMode(MediaCacheStream::ReadMode aMode) override { UNIMPLEMENTED(); }
virtual void SetPlaybackRate(uint32_t aBytesPerSecond) override { UNIMPLEMENTED(); }
virtual nsresult ReadAt(int64_t aOffset, char* aBuffer, uint32_t aCount, uint32_t* aBytes) override;

View File

@ -129,6 +129,7 @@ EXPORTS += [
'MediaQueue.h',
'MediaRecorder.h',
'MediaResource.h',
'MediaResourceCallback.h',
'MediaSegment.h',
'MediaStatistics.h',
'MediaStreamGraph.h',

View File

@ -369,14 +369,15 @@ function SetupEME(test, token, params)
})
}
var options = [
{
initDataType: ev.initDataType,
videoType: streamType("video"),
audioType: streamType("audio"),
}
];
var p = navigator.requestMediaKeySystemAccess(KEYSYSTEM_TYPE, options);
var options = { initDataTypes: [ev.initDataType] };
if (streamType("video")) {
options.videoCapabilities = [{contentType: streamType("video")}];
}
if (streamType("audio")) {
options.audioCapabilities = [{contentType: streamType("audio")}];
}
var p = navigator.requestMediaKeySystemAccess(KEYSYSTEM_TYPE, [options]);
var r = bail(token + " Failed to request key system access.");
chain(p, r)
.then(function(keySystemAccess) {

View File

@ -15,9 +15,9 @@ var manager = new MediaTestManager;
function DoSetMediaKeys(v, test)
{
var options = [{
initDataType: "cenc",
audioType: test.audioType,
videoType: test.videoType,
initDataTypes: ["cenc"],
audioCapabilities: [{contentType: test.audioType}],
videoCapabilities: [{contentType: test.videoType}],
}];
return navigator.requestMediaKeySystemAccess("org.w3.clearkey", options)

View File

@ -86,7 +86,7 @@ function startTest(test, token)
// Once the session is closed, reload the MediaKeys and reload the session
.then(function() {
return navigator.requestMediaKeySystemAccess(KEYSYSTEM_TYPE);
return navigator.requestMediaKeySystemAccess(KEYSYSTEM_TYPE, [{initDataTypes:["cenc"]}]);
})
.then(function(requestedKeySystemAccess) {

View File

@ -13,6 +13,31 @@
const CLEARKEY_ID = 'org.w3.clearkey';
const CLEARKEY_VERSION = '1';
const SUPPORTED_LABEL = "pass label";
function ValidateConfig(name, expected, observed) {
info("ValidateConfig " + name);
info("expected cfg=" + JSON.stringify(expected));
info("observed cfg=" + JSON.stringify(observed));
is(observed.label, expected.label, name + " label should match");
if (expected.initDataTypes) {
ok(expected.initDataTypes.every((element, index, array) => observed.initDataTypes.includes(element)), name + " initDataTypes should match.");
}
if (expected.audioCapabilities) {
ok(expected.audioCapabilities.length == 1, "Test function can only handle one capability.");
ok(observed.audioCapabilities.length == 1, "Test function can only handle one capability.");
is(observed.audioCapabilities[0].contentType, expected.audioCapabilities[0].contentType, name + " audioCapabilities should match.");
}
if (typeof expected.videoCapabilities !== 'undefined') {
info("expected.videoCapabilities=" + expected.videoCapabilities);
dump("expected.videoCapabilities=" + expected.videoCapabilities + "\n");
ok(expected.videoCapabilities.length == 1, "Test function can only handle one capability.");
ok(observed.videoCapabilities.length == 1, "Test function can only handle one capability.");
is(observed.videoCapabilities[0].contentType, expected.videoCapabilities[0].contentType, name + " videoCapabilities should match.");
}
}
function Test(test) {
var name = "'" + test.name + "'";
@ -27,6 +52,7 @@ function Test(test) {
function(keySystemAccess) {
ok(test.shouldPass, name + " passed and was expected to " + (test.shouldPass ? "pass" : "fail"));
is(keySystemAccess.keySystem, CLEARKEY_ID + "." + CLEARKEY_VERSION, "CDM version should be in MediaKeySystemAccess.keySystem");
ValidateConfig(name, test.expectedConfig, keySystemAccess.getConfiguration());
resolve();
},
function(ex) {
@ -43,7 +69,12 @@ var tests = [
{
name: 'Empty keySystem string',
keySystem: '',
options: [ ],
options: [
{
initDataTypes: ['cenc'],
videoCapabilities: [{contentType: 'video/mp4'}],
}
],
shouldPass: false,
},
{
@ -55,23 +86,34 @@ var tests = [
{
name: 'Undefined options',
keySystem: CLEARKEY_ID,
shouldPass: true,
shouldPass: false,
},
{
name: 'Basic MP4 cenc',
keySystem: CLEARKEY_ID,
options: [
{
initDataType: 'cenc',
videoType: 'video/mp4',
label: SUPPORTED_LABEL,
initDataTypes: ['cenc'],
videoCapabilities: [{contentType: 'video/mp4'}],
}
],
expectedConfig: {
label: SUPPORTED_LABEL,
initDataTypes: ['cenc'],
videoCapabilities: [{contentType: 'video/mp4'}],
},
shouldPass: true,
},
{
name: 'Invalid keysystem failure',
keySystem: 'bogusKeySystem',
options: [],
options: [
{
initDataTypes: ['cenc'],
videoCapabilities: [{contentType: 'video/mp4'}],
}
],
shouldPass: false,
},
{
@ -79,7 +121,32 @@ var tests = [
keySystem: CLEARKEY_ID,
options: [
{
initDataType: 'bogus',
initDataTypes: ['bogus'],
}
],
shouldPass: false,
},
{
name: 'Valid initDataType after invalid',
keySystem: CLEARKEY_ID,
options: [
{
label: SUPPORTED_LABEL,
initDataTypes: ['bogus', 'invalid', 'cenc'],
}
],
expectedConfig: {
label: SUPPORTED_LABEL,
initDataTypes: ['cenc'],
},
shouldPass: true,
},
{
name: 'Empty initDataTypes',
keySystem: CLEARKEY_ID,
options: [
{
initDataTypes: [],
}
],
shouldPass: false,
@ -89,72 +156,102 @@ var tests = [
keySystem: CLEARKEY_ID,
options: [
{
initDataType: 'cenc',
videoType: 'video/bogus',
initDataTypes: ['cenc'],
videoCapabilities: [{contentType: 'video/bogus'}],
}
],
shouldPass: false,
},
{
name: 'Invalid statefulness',
name: 'distinctiveIdentifier, persistentState, and robustness ignored',
keySystem: CLEARKEY_ID,
options: [
{
initDataType: 'cenc',
videoType: 'video/mp4',
stateful: 'bogus',
label: SUPPORTED_LABEL,
initDataTypes: ['cenc'],
videoCapabilities: [{contentType: 'video/mp4', robustness: 'somewhat'}],
distinctiveIdentifier: 'bogus',
persistentState: 'bogus',
}
],
expectedConfig: {
label: SUPPORTED_LABEL,
initDataTypes: ['cenc'],
videoCapabilities: [{contentType: 'video/mp4'}],
},
shouldPass: true,
},
{
name: 'Only unrecognised dict entries specified with unrecognised video type',
keySystem: CLEARKEY_ID,
options: [
{
videoCapabilities: [{robustness: 'very much so'}],
distinctiveIdentifier: 'required',
persistentState: 'required',
}
],
shouldPass: false,
},
{
name: 'Invalid uniqueidentifier',
name: 'Only unrecognised dict entries specified should be ignored',
keySystem: CLEARKEY_ID,
options: [
{
initDataType: 'cenc',
videoType: 'video/mp4',
uniqueidentifier: 'bogus',
label: SUPPORTED_LABEL,
distinctiveIdentifier: 'required',
persistentState: 'required',
}
],
shouldPass: false,
expectedConfig: {
label: SUPPORTED_LABEL,
},
shouldPass: true,
},
{
name: 'Audio capabilities not supported by CLEARKEY_ID',
name: 'Empty config dict',
keySystem: CLEARKEY_ID,
options: [
{
initDataType: 'cenc',
videoType: 'video/mp4',
audioCapability: 'bogus',
}
],
shouldPass: false,
options: [{ label: SUPPORTED_LABEL }],
expectedConfig: {
label: SUPPORTED_LABEL
},
shouldPass: true,
},
{
name: 'Video capabilities not supported by CLEARKEY_ID',
name: 'Unexpected config entry should be ignored',
keySystem: CLEARKEY_ID,
options: [
{
initDataType: 'cenc',
videoType: 'video/mp4',
videoCapability: 'bogus',
label: SUPPORTED_LABEL,
initDataTypes: ['cenc'],
unexpectedEntry: 'this should be ignored',
}
],
shouldPass: false,
expectedConfig: {
label: SUPPORTED_LABEL,
initDataTypes: ['cenc'],
},
shouldPass: true,
},
{
name: 'Invalid option followed by valid',
keySystem: CLEARKEY_ID,
options: [
{
bogus: 'bogon',
label: "this config should not be supported",
initDataTypes: ['bogus'],
},
{
initDataType: 'cenc',
videoType: 'video/mp4',
label: SUPPORTED_LABEL,
initDataTypes: ['cenc'],
videoCapabilities: [{contentType: 'video/mp4'}],
}
],
expectedConfig: {
label: SUPPORTED_LABEL,
initDataTypes: ['cenc'],
videoCapabilities: [{contentType: 'video/mp4'}],
},
shouldPass: true,
},
{
@ -162,10 +259,16 @@ var tests = [
keySystem: CLEARKEY_ID,
options: [
{
initDataType: 'cenc',
audioType: 'audio/mp4',
label: SUPPORTED_LABEL,
initDataTypes: ['cenc'],
audioCapabilities: [{contentType: 'audio/mp4'}],
}
],
expectedConfig: {
label: SUPPORTED_LABEL,
initDataTypes: ['cenc'],
audioCapabilities: [{contentType: 'audio/mp4'}],
},
shouldPass: true,
},
{
@ -173,10 +276,16 @@ var tests = [
keySystem: CLEARKEY_ID,
options: [
{
initDataType: 'cenc',
audioType: 'audio/mp4; codecs="mp4a.40.2"',
label: SUPPORTED_LABEL,
initDataTypes: ['cenc'],
audioCapabilities: [{contentType: 'audio/mp4; codecs="mp4a.40.2"'}],
}
],
expectedConfig: {
label: SUPPORTED_LABEL,
initDataTypes: ['cenc'],
audioCapabilities: [{contentType: 'audio/mp4; codecs="mp4a.40.2"'}],
},
shouldPass: true,
},
{
@ -184,8 +293,8 @@ var tests = [
keySystem: CLEARKEY_ID,
options: [
{
initDataType: 'cenc',
audioType: 'audio/mp4; codecs="bogus"',
initDataTypes: ['cenc'],
audioCapabilities: [{contentType: 'audio/mp4; codecs="bogus"'}],
}
],
shouldPass: false,
@ -195,19 +304,19 @@ var tests = [
keySystem: CLEARKEY_ID,
options: [
{
initDataType: 'cenc',
audioType: 'audio/mp4; codecs="mp3"',
initDataTypes: ['cenc'],
audioCapabilities: [{contentType: 'audio/mp4; codecs="mp3"'}],
}
],
shouldPass: false,
},
{
name: 'MP4 video container type with an audio codec is unsupported',
name: 'MP4 video container type with an mp3 codec is unsupported',
keySystem: CLEARKEY_ID,
options: [
{
initDataType: 'cenc',
videoType: 'video/mp4; codecs="mp3"',
initDataTypes: ['cenc'],
videoCapabilities: [{contentType: 'video/mp4; codecs="mp3"'}],
}
],
shouldPass: false,
@ -217,8 +326,8 @@ var tests = [
keySystem: CLEARKEY_ID,
options: [
{
initDataType: 'cenc',
audioType: 'audio/mp4; codecs="avc1.42E01E"',
initDataTypes: ['cenc'],
audioCapabilities: [{contentType: 'audio/mp4; codecs="avc1.42E01E"'}],
}
],
shouldPass: false,
@ -228,10 +337,16 @@ var tests = [
keySystem: CLEARKEY_ID,
options: [
{
initDataType: 'cenc',
videoType: 'video/mp4; codecs="avc1.42E01E"',
label: SUPPORTED_LABEL,
initDataTypes: ['cenc'],
videoCapabilities: [{contentType: 'video/mp4; codecs="avc1.42E01E"'}],
}
],
expectedConfig: {
label: SUPPORTED_LABEL,
initDataTypes: ['cenc'],
videoCapabilities: [{contentType: 'video/mp4; codecs="avc1.42E01E"'}],
},
shouldPass: true,
},
{
@ -239,8 +354,8 @@ var tests = [
keySystem: CLEARKEY_ID,
options: [
{
initDataType: 'cenc',
videoType: 'video/mp4; codecs="bogus"',
initDataTypes: ['cenc'],
videoCapabilities: [{contentType: 'video/mp4; codecs="bogus"'}],
}
],
shouldPass: false,
@ -250,8 +365,8 @@ var tests = [
keySystem: CLEARKEY_ID,
options: [
{
initDataType: 'cenc',
videoType: 'video/mp4; codecs="avc1.42E01E,mp4a.40.2"',
initDataTypes: ['cenc'],
videoCapabilities: [{contentType: 'video/mp4; codecs="avc1.42E01E,mp4a.40.2"'}],
}
],
shouldPass: false,
@ -261,11 +376,18 @@ var tests = [
keySystem: CLEARKEY_ID,
options: [
{
initDataType: 'cenc',
videoType: 'video/mp4; codecs="avc1.42E01E"',
audioType: 'audio/mp4; codecs="mp4a.40.2"',
label: SUPPORTED_LABEL,
initDataTypes: ['cenc'],
videoCapabilities: [{contentType: 'video/mp4; codecs="avc1.42E01E"'}],
audioCapabilities: [{contentType: 'audio/mp4; codecs="mp4a.40.2"'}],
}
],
expectedConfig: {
label: SUPPORTED_LABEL,
initDataTypes: ['cenc'],
videoCapabilities: [{contentType: 'video/mp4; codecs="avc1.42E01E"'}],
audioCapabilities: [{contentType: 'audio/mp4; codecs="mp4a.40.2"'}],
},
shouldPass: true,
},
{
@ -273,8 +395,8 @@ var tests = [
keySystem: CLEARKEY_ID,
options: [
{
initDataType: 'webm',
videoType: 'video/webm',
initDataTypes: ['webm'],
videoCapabilities: [{contentType: 'video/webm'}],
}
],
shouldPass: false,
@ -282,23 +404,103 @@ var tests = [
{
name: "CDM version less than",
keySystem: CLEARKEY_ID + ".0",
options: [
{
label: SUPPORTED_LABEL,
initDataTypes: ['cenc'],
videoCapabilities: [{contentType: 'video/mp4'}],
}
],
expectedConfig: {
label: SUPPORTED_LABEL,
initDataTypes: ['cenc'],
videoCapabilities: [{contentType: 'video/mp4'}],
},
shouldPass: true
},
{
name: "CDM version equal to",
keySystem: CLEARKEY_ID + ".1",
options: [
{
label: SUPPORTED_LABEL,
initDataTypes: ['cenc'],
videoCapabilities: [{contentType: 'video/mp4'}],
}
],
expectedConfig: {
label: SUPPORTED_LABEL,
initDataTypes: ['cenc'],
videoCapabilities: [{contentType: 'video/mp4'}],
},
shouldPass: true
},
{
name: "CDM version greater than",
keySystem: CLEARKEY_ID + ".2",
options: [
{
initDataTypes: ['cenc'],
videoCapabilities: [{contentType: 'video/mp4'}],
}
],
shouldPass: false
},
{
name: "Non-whole number CDM version",
keySystem: CLEARKEY_ID + ".0.1",
options: [
{
initDataTypes: ['cenc'],
videoCapabilities: [{contentType: 'video/mp4'}],
}
],
shouldPass: false
},
// Test legacy support. Remove when we remove backwards compatibility.
{
name: 'Legacy CENC',
keySystem: CLEARKEY_ID,
options: [
{
initDataType: 'cenc',
}
],
expectedConfig: {
label: ''
},
shouldPass: true,
},
{
name: 'Legacy CENC + MP4 video',
keySystem: CLEARKEY_ID,
options: [
{
initDataType: 'cenc',
videoType: 'video/mp4; codecs="avc1.42E01E"',
}
],
expectedConfig: {
label: ''
},
shouldPass: true,
},
{
name: 'Legacy CENC + MP4 video + MP4 audio',
keySystem: CLEARKEY_ID,
options: [
{
initDataType: 'cenc',
videoType: 'video/mp4; codecs="avc1.42E01E"',
audioType: 'audio/mp4; codecs="mp4a.40.2"',
}
],
expectedConfig: {
label: ''
},
shouldPass: true,
},
];
function beginTest() {

View File

@ -1,109 +1,109 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test Encrypted Media Extensions</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>
<script type="text/javascript" src="eme.js"></script>
</head>
<body>
<pre id="test">
<script class="testbody" type="text/javascript">
var manager = new MediaTestManager;
var observedStatus = "nothing";
var observer = function(subject, topic, data) {
observedStatus = JSON.parse(data).status;
info("Observed: " + observedStatus);
};
SpecialPowers.Services.obs.addObserver(observer, "mediakeys-request", false);
SimpleTest.registerCleanupFunction(function() {
SpecialPowers.Services.obs.removeObserver(observer, "mediakeys-request");
});
function SetPrefs(prefs) {
return new Promise(function(resolve, reject) {
SpecialPowers.pushPrefEnv({"set": prefs}, function() { resolve(); });
});
}
function Test(test) {
var p = test.prefs ? SetPrefs(test.prefs) : Promise.resolve();
observedStatus = "nothing";
var name = "'" + test.keySystem + "'";
return p.then(function() {
return new Promise(function(resolve, reject) {
navigator.requestMediaKeySystemAccess(test.keySystem)
.then(
function(keySystemAccess) {
return keySystemAccess.createMediaKeys();
})
.then(
function(mediaKeys) {
ok(test.shouldPass, name + " passed and was expected to " + (test.shouldPass ? "pass" : "fail"));
is(observedStatus, test.expectedStatus, name + " observer service result");
resolve();
}
)
.catch(
function() {
ok(!test.shouldPass, name + " failed and was expected to " + (test.shouldPass ? "pass" : "fail"));
is(observedStatus, test.expectedStatus, name + " observer service result");
resolve();
}
);
});
});
}
const CLEARKEY_ID = 'org.w3.clearkey';
var tests = [
{
keySystem: CLEARKEY_ID,
shouldPass: false,
expectedStatus: 'api-disabled',
prefs: [["media.eme.enabled", false], ["media.eme.clearkey.enabled", true]]
},
{
keySystem: CLEARKEY_ID,
shouldPass: false,
expectedStatus: 'cdm-disabled',
prefs: [["media.eme.enabled", true], ["media.eme.clearkey.enabled", false]]
},
{
keySystem: 'unsupported-keysystem',
shouldPass: false,
expectedStatus: 'cdm-not-supported'
},
{
keySystem: CLEARKEY_ID + '.10000' , // A stupendously high min CDM version, presumably not installed.
shouldPass: false,
expectedStatus: 'cdm-insufficient-version',
prefs: [["media.eme.enabled", true], ["media.eme.clearkey.enabled", true]]
},
{
keySystem: CLEARKEY_ID,
shouldPass: true,
expectedStatus: 'cdm-created',
prefs: [["media.eme.enabled", true], ["media.eme.clearkey.enabled", true]]
},
];
SetupEMEPref(function() {
tests.reduce(function(p,c,i,array) {
return p.then(function() { return Test(c); });
}, Promise.resolve()).then(SimpleTest.finish);
});
SimpleTest.waitForExplicitFinish();
</script>
</pre>
</body>
</html>
<!DOCTYPE HTML>
<html>
<head>
<title>Test Encrypted Media Extensions</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>
<script type="text/javascript" src="eme.js"></script>
</head>
<body>
<pre id="test">
<script class="testbody" type="text/javascript">
var manager = new MediaTestManager;
var observedStatus = "nothing";
var observer = function(subject, topic, data) {
observedStatus = JSON.parse(data).status;
info("Observed: " + observedStatus);
};
SpecialPowers.Services.obs.addObserver(observer, "mediakeys-request", false);
SimpleTest.registerCleanupFunction(function() {
SpecialPowers.Services.obs.removeObserver(observer, "mediakeys-request");
});
function SetPrefs(prefs) {
return new Promise(function(resolve, reject) {
SpecialPowers.pushPrefEnv({"set": prefs}, function() { resolve(); });
});
}
function Test(test) {
var p = test.prefs ? SetPrefs(test.prefs) : Promise.resolve();
observedStatus = "nothing";
var name = "'" + test.keySystem + "'";
return p.then(function() {
return new Promise(function(resolve, reject) {
navigator.requestMediaKeySystemAccess(test.keySystem, [{initDataTypes:["cenc"]}])
.then(
function(keySystemAccess) {
return keySystemAccess.createMediaKeys();
})
.then(
function(mediaKeys) {
ok(test.shouldPass, name + " passed and was expected to " + (test.shouldPass ? "pass" : "fail"));
is(observedStatus, test.expectedStatus, name + " observer service result");
resolve();
}
)
.catch(
function() {
ok(!test.shouldPass, name + " failed and was expected to " + (test.shouldPass ? "pass" : "fail"));
is(observedStatus, test.expectedStatus, name + " observer service result");
resolve();
}
);
});
});
}
const CLEARKEY_ID = 'org.w3.clearkey';
var tests = [
{
keySystem: CLEARKEY_ID,
shouldPass: false,
expectedStatus: 'api-disabled',
prefs: [["media.eme.enabled", false], ["media.eme.clearkey.enabled", true]]
},
{
keySystem: CLEARKEY_ID,
shouldPass: false,
expectedStatus: 'cdm-disabled',
prefs: [["media.eme.enabled", true], ["media.eme.clearkey.enabled", false]]
},
{
keySystem: 'unsupported-keysystem',
shouldPass: false,
expectedStatus: 'cdm-not-supported'
},
{
keySystem: CLEARKEY_ID + '.10000' , // A stupendously high min CDM version, presumably not installed.
shouldPass: false,
expectedStatus: 'cdm-insufficient-version',
prefs: [["media.eme.enabled", true], ["media.eme.clearkey.enabled", true]]
},
{
keySystem: CLEARKEY_ID,
shouldPass: true,
expectedStatus: 'cdm-created',
prefs: [["media.eme.enabled", true], ["media.eme.clearkey.enabled", true]]
},
];
SetupEMEPref(function() {
tests.reduce(function(p,c,i,array) {
return p.then(function() { return Test(c); });
}, Promise.resolve()).then(SimpleTest.finish);
});
SimpleTest.waitForExplicitFinish();
</script>
</pre>
</body>
</html>

View File

@ -693,7 +693,6 @@ AsyncCallbackAutoLock::~AsyncCallbackAutoLock()
}
}
NPP NPPStack::sCurrentNPP = nullptr;
const char *
@ -744,7 +743,6 @@ _geturl(NPP npp, const char* relativeURL, const char* target)
(strncmp(relativeURL, "ftp:", 4) != 0)) {
nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *) npp->ndata;
const char *name = nullptr;
RefPtr<nsPluginHost> host = nsPluginHost::GetInst();
host->GetPluginName(inst, &name);
@ -1958,9 +1956,7 @@ _getvalue(NPP npp, NPNVariable variable, void *result)
return NPERR_NO_ERROR;
}
}
else {
return NPERR_GENERIC_ERROR;
}
return NPERR_GENERIC_ERROR;
}
#ifndef NP_NO_QUICKDRAW
@ -2189,14 +2185,13 @@ _getvalue(NPP npp, NPNVariable variable, void *result)
// we no longer hand out any XPCOM objects
case NPNVDOMElement:
// fall through
case NPNVDOMWindow:
// fall through
case NPNVserviceManager:
// old XPCOM objects, no longer supported, but null out the out
// param to avoid crashing plugins that still try to use this.
*(nsISupports**)result = nullptr;
// fall through
MOZ_FALLTHROUGH;
default:
NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPN_getvalue unhandled get value: %d\n", variable));
return NPERR_GENERIC_ERROR;

View File

@ -3030,11 +3030,8 @@ NS_IMETHODIMP nsPluginInstanceOwner::CreateWidget(void)
#ifndef XP_MACOSX
// If we're running in the content process, we need a remote widget created in chrome.
if (XRE_IsContentProcess()) {
nsCOMPtr<nsIDOMWindow> window = doc->GetWindow();
if (window) {
nsCOMPtr<nsIDOMWindow> topWindow;
window->GetTop(getter_AddRefs(topWindow));
if (topWindow) {
if (nsCOMPtr<nsPIDOMWindow> window = doc->GetWindow()) {
if (nsCOMPtr<nsPIDOMWindow> topWindow = window->GetTop()) {
dom::TabChild* tc = dom::TabChild::GetFrom(topWindow);
if (tc) {
// This returns a PluginWidgetProxy which remotes a number of calls.

View File

@ -502,6 +502,7 @@ PluginInstanceChild::NPN_GetValue(NPNVariable aVar,
case NPNVSupportsXEmbedBool:
case NPNVSupportsWindowless:
NS_NOTREACHED("NPNVariable should be handled in PluginModuleChild.");
MOZ_FALLTHROUGH;
#endif
default:
@ -510,7 +511,6 @@ PluginInstanceChild::NPN_GetValue(NPNVariable aVar,
(int) aVar, NPNVariableToString(aVar)));
return NPERR_GENERIC_ERROR;
}
}
#ifdef MOZ_WIDGET_COCOA
@ -2313,7 +2313,6 @@ PluginInstanceChild::EnumThreadWindowsCallback(HWND hWnd,
return TRUE;
}
void
PluginInstanceChild::SetupFlashMsgThrottle()
{
@ -2610,7 +2609,6 @@ StreamNotifyChild::ActorDestroy(ActorDestroyReason why)
}
}
void
StreamNotifyChild::SetAssociatedStream(BrowserStreamChild* bs)
{

View File

@ -1135,14 +1135,6 @@ this.PushServiceWebSocket = {
data.uaid = this._UAID;
}
function sendHelloMessage(ids) {
// On success, ids is an array, on error its not.
data.channelIDs = ids.map ?
ids.map(function(el) { return el.channelID; }) : [];
this._wsSendMessage(data);
this._currentState = STATE_WAITING_FOR_HELLO;
}
this._networkInfo.getNetworkState((networkState) => {
if (networkState.ip) {
// Opening an available UDP port.
@ -1161,9 +1153,8 @@ this.PushServiceWebSocket = {
};
}
this._mainPushService.getAllUnexpired()
.then(sendHelloMessage.bind(this),
sendHelloMessage.bind(this));
this._wsSendMessage(data);
this._currentState = STATE_WAITING_FOR_HELLO;
});
},

View File

@ -7,13 +7,15 @@ onfetch = function(event) {
return;
}
if (!event.client) {
dump("ERROR: no client to post the message to!\n");
dump("request.url=" + event.request.url + "\n");
return;
}
event.client.postMessage({type: "fetch", state: state});
var currentState = state;
event.waitUntil(
clients.matchAll()
.then(clients => {
clients.forEach(client => {
client.postMessage({type: "fetch", state: currentState});
});
})
);
if (event.request.url.indexOf("update") >= 0) {
state = "update";

View File

@ -65,11 +65,6 @@ add_task(function* test_notification_ack() {
onHello(request) {
equal(request.uaid, userAgentID,
'Should send matching device IDs in handshake');
deepEqual(request.channelIDs.sort(), [
'21668e05-6da8-42c9-b8ab-9cc3f4d5630c',
'5477bfda-22db-45d4-9614-fee369630260',
'9a5ff87f-47c9-4215-b2b8-0bdd38b4b305'
], 'Should send matching channel IDs in handshake');
this.serverSendMsg(JSON.stringify({
messageType: 'hello',
uaid: userAgentID,

View File

@ -99,11 +99,6 @@ add_task(function* test_notification_ack_data() {
onHello(request) {
equal(request.uaid, userAgentID,
'Should send matching device IDs in handshake');
deepEqual(
request.channelIDs.sort(),
['subscription1', 'subscription2', 'subscription3'],
'Should send matching channel IDs in handshake'
);
this.serverSendMsg(JSON.stringify({
messageType: 'hello',
uaid: userAgentID,

View File

@ -78,11 +78,6 @@ add_task(function* test_notification_error() {
makeWebSocket(uri) {
return new MockWebSocket(uri, {
onHello(request) {
deepEqual(request.channelIDs.sort(), [
'3c3930ba-44de-40dc-a7ca-8a133ec1a866',
'b63f7bef-0a0d-4236-b41e-086a69dfd316',
'f04f1e46-9139-4826-b2d1-9411b0821283'
], 'Wrong channel list');
this.serverSendMsg(JSON.stringify({
messageType: 'hello',
status: 200,

View File

@ -96,10 +96,6 @@ add_task(function* test_expiration_origin_threshold() {
makeWebSocket(uri) {
return new MockWebSocket(uri, {
onHello(request) {
deepEqual(request.channelIDs.sort(), [
'46cc6f6a-c106-4ffa-bb7c-55c60bd50c41',
'eb33fc90-c883-4267-b5cb-613969e8e349',
], 'Wrong active registrations in handshake');
this.serverSendMsg(JSON.stringify({
messageType: 'hello',
status: 200,

View File

@ -64,9 +64,6 @@ add_task(function* test_expiration_history_observer() {
makeWebSocket(uri) {
return new MockWebSocket(uri, {
onHello(request) {
deepEqual(request.channelIDs, [
'379c0668-8323-44d2-a315-4ee83f1a9ee9',
], 'Should not include expired channel IDs');
this.serverSendMsg(JSON.stringify({
messageType: 'hello',
status: 200,

View File

@ -37,23 +37,14 @@ add_task(function* test_register_timeout() {
makeWebSocket(uri) {
return new MockWebSocket(uri, {
onHello(request) {
switch (handshakes) {
case 0:
if (handshakes === 0) {
equal(request.uaid, null, 'Should not include device ID');
deepEqual(request.channelIDs, [],
'Should include empty channel list');
break;
case 1:
} else if (handshakes === 1) {
// Should use the previously-issued device ID when reconnecting,
// but should not include the timed-out channel ID.
equal(request.uaid, userAgentID,
'Should include device ID on reconnect');
deepEqual(request.channelIDs, [],
'Should not include failed channel ID');
break;
default:
} else {
ok(false, 'Unexpected reconnect attempt ' + handshakes);
}
handshakes++;

View File

@ -51,11 +51,6 @@ add_task(function* test_registration_success() {
return new MockWebSocket(uri, {
onHello(request) {
equal(request.uaid, userAgentID, 'Wrong device ID in handshake');
deepEqual(request.channelIDs.sort(), [
'b1cf38c9-6836-4d29-8a30-a3e98d59b728',
'bf001fe0-2684-42f2-bc4d-a3e14b11dd5b',
'f6edfbcd-79d6-49b8-9766-48b9dcfeff0f',
], 'Wrong channel list in handshake');
this.serverSendMsg(JSON.stringify({
messageType: 'hello',
status: 200,

View File

@ -6,8 +6,6 @@
const {PushDB, PushService, PushServiceWebSocket} = serviceExports;
const userAgentID = 'bd744428-f125-436a-b6d0-dd0c9845837f';
const channelIDs = ['0ef2ad4a-6c49-41ad-af6e-95d2425276bf', '4818b54a-97c5-4277-ad5d-0bfe630e4e50'];
var channelIDCounter = 0;
function run_test() {
do_get_profile();

View File

@ -1542,14 +1542,6 @@ this.PushService = {
if (this._UAID)
data["uaid"] = this._UAID;
function sendHelloMessage(ids) {
// On success, ids is an array, on error its not.
data["channelIDs"] = ids.map ?
ids.map(function(el) { return el.channelID; }) : [];
this._wsSendMessage(data);
this._currentState = STATE_WAITING_FOR_HELLO;
}
this._getNetworkState((networkState) => {
if (networkState.ip) {
// Opening an available UDP port.
@ -1568,8 +1560,8 @@ this.PushService = {
};
}
this._db.getAllChannelIDs(sendHelloMessage.bind(this),
sendHelloMessage.bind(this));
this._wsSendMessage(data);
this._currentState = STATE_WAITING_FOR_HELLO;
});
},

View File

@ -217,15 +217,12 @@ nsDeviceSensors::Notify(const mozilla::hal::SensorData& aSensorData)
continue;
}
nsCOMPtr<nsIDOMDocument> domdoc;
windowListeners[i]->GetDocument(getter_AddRefs(domdoc));
if (domdoc) {
if (nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(pwindow->GetDoc())) {
nsCOMPtr<mozilla::dom::EventTarget> target = do_QueryInterface(windowListeners[i]);
if (type == nsIDeviceSensorData::TYPE_ACCELERATION ||
type == nsIDeviceSensorData::TYPE_LINEAR_ACCELERATION ||
type == nsIDeviceSensorData::TYPE_GYROSCOPE)
FireDOMMotionEvent(domdoc, target, type, x, y, z);
FireDOMMotionEvent(domDoc, target, type, x, y, z);
else if (type == nsIDeviceSensorData::TYPE_ORIENTATION)
FireDOMOrientationEvent(target, x, y, z);
else if (type == nsIDeviceSensorData::TYPE_PROXIMITY)

View File

@ -10,8 +10,9 @@
[Exposed=ServiceWorker]
interface Client {
readonly attribute DOMString id;
readonly attribute USVString url;
readonly attribute FrameType frameType;
readonly attribute DOMString id;
[Throws]
void postMessage(any message, optional sequence<Transferable> transfer);
@ -21,9 +22,8 @@ interface Client {
interface WindowClient : Client {
readonly attribute VisibilityState visibilityState;
readonly attribute boolean focused;
readonly attribute FrameType frameType;
[Throws]
[Throws, NewObject]
Promise<WindowClient> focus();
};

Some files were not shown because too many files have changed in this diff Show More