Merge mozilla-central to autoland

This commit is contained in:
Carsten "Tomcat" Book 2017-07-06 11:24:24 +02:00
Родитель 920860b1f3 7857fa0a5e
Коммит 2178a22de4
127 изменённых файлов: 1368 добавлений и 2581 удалений

Просмотреть файл

@ -1414,6 +1414,22 @@ Accessible::SetCurValue(double aValue)
role
Accessible::ARIATransformRole(role aRole)
{
// Beginning with ARIA 1.1, user agents are expected to use the native host
// language role of the element when the region role is used without a name.
// https://rawgit.com/w3c/aria/master/core-aam/core-aam.html#role-map-region
//
// XXX: While the name computation algorithm can be non-trivial in the general
// case, it should not be especially bad here: If the author hasn't used the
// region role, this calculation won't occur. And the region role's name
// calculation rule excludes name from content. That said, this use case is
// another example of why we should consider caching the accessible name. See:
// https://bugzilla.mozilla.org/show_bug.cgi?id=1378235.
if (aRole == roles::REGION) {
nsAutoString name;
Name(name);
return name.IsEmpty() ? NativeRole() : aRole;
}
// XXX: these unfortunate exceptions don't fit into the ARIA table. This is
// where the accessible role depends on both the role and ARIA state.
if (aRole == roles::PUSHBUTTON) {

Просмотреть файл

@ -4,10 +4,10 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/a11y/Compatibility.h"
#include "mozilla/a11y/PlatformChild.h"
#include "mozilla/mscom/EnsureMTA.h"
#include "mozilla/mscom/InterceptorLog.h"
#include "mozilla/WindowsVersion.h"
#include "Accessible2.h"
#include "Accessible2_2.h"
@ -49,20 +49,7 @@ PlatformChild::PlatformChild()
, mMiscTypelib(mozilla::mscom::RegisterTypelib(L"Accessible.tlb"))
, mSdnTypelib(mozilla::mscom::RegisterTypelib(L"AccessibleMarshal.dll"))
{
// The manifest for 32-bit Windows is embedded with resource ID 32.
// The manifest for 64-bit Windows is embedded with resource ID 64.
// Beginning with Windows 10 Creators Update, 32-bit builds use the 64-bit
// manifest.
WORD actCtxResourceId;
#if defined(HAVE_64BIT_BUILD)
actCtxResourceId = 64;
#else
if (IsWin10CreatorsUpdateOrLater()) {
actCtxResourceId = 64;
} else {
actCtxResourceId = 32;
}
#endif
WORD actCtxResourceId = Compatibility::GetActCtxResourceId();
mozilla::mscom::MTADeletePtr<mozilla::mscom::ActivationContextRegion> tmpActCtxMTA;
mozilla::mscom::EnsureMTA([actCtxResourceId, &tmpActCtxMTA]() -> void {

Просмотреть файл

@ -222,17 +222,12 @@ AccessibleHandler::ReadHandlerPayload(IStream* aStream, REFIID aIid)
return S_OK;
}
long pid = static_cast<long>(::GetCurrentProcessId());
RefPtr<IHandlerControl> ctl;
HRESULT hr = gControlFactory.CreateInstance(nullptr, IID_IHandlerControl,
getter_AddRefs(ctl));
if (SUCCEEDED(hr)) {
hr = mCachedData.mGeckoBackChannel->put_HandlerControl(pid, ctl);
MOZ_ASSERT(SUCCEEDED(hr));
RefPtr<AccessibleHandlerControl> ctl(gControlFactory.GetOrCreateSingleton());
if (!ctl) {
return E_OUTOFMEMORY;
}
return hr;
return ctl->Register(WrapNotNull(mCachedData.mGeckoBackChannel));
}
REFIID

Просмотреть файл

@ -132,7 +132,8 @@ AccessibleHandlerControl::Create(AccessibleHandlerControl** aOutObject)
}
AccessibleHandlerControl::AccessibleHandlerControl()
: mCacheGen(0)
: mIsRegistered(false)
, mCacheGen(0)
, mIA2Proxy(mscom::RegisterProxy(L"ia2marshal.dll"))
, mHandlerProxy(mscom::RegisterProxy())
{
@ -189,5 +190,19 @@ AccessibleHandlerControl::GetHandlerTypeInfo(ITypeInfo** aOutTypeInfo)
aOutTypeInfo);
}
HRESULT
AccessibleHandlerControl::Register(NotNull<IGeckoBackChannel*> aGecko)
{
if (mIsRegistered) {
return S_OK;
}
long pid = static_cast<long>(::GetCurrentProcessId());
HRESULT hr = aGecko->put_HandlerControl(pid, this);
mIsRegistered = SUCCEEDED(hr);
MOZ_ASSERT(mIsRegistered);
return hr;
}
} // namespace a11y
} // namespace mozilla

Просмотреть файл

@ -71,10 +71,13 @@ public:
HRESULT GetHandlerTypeInfo(ITypeInfo** aOutTypeInfo);
HRESULT Register(NotNull<IGeckoBackChannel*> aGecko);
private:
AccessibleHandlerControl();
~AccessibleHandlerControl() = default;
bool mIsRegistered;
uint32_t mCacheGen;
detail::TextChange mTextChange;
UniquePtr<mscom::RegisteredProxy> mIA2Proxy;

Просмотреть файл

@ -798,7 +798,7 @@ ConvertToNSArray(nsTArray<ProxyAccessible*>& aArray)
if (roleAtom == nsGkAtoms::note_)
return @"AXDocumentNote";
if (roleAtom == nsGkAtoms::region)
return @"AXLandmarkRegion";
return mRole == roles::REGION ? @"AXLandmarkRegion" : nil;
if (roleAtom == nsGkAtoms::status)
return @"AXApplicationStatus";
if (roleAtom == nsGkAtoms::tabpanel)

Просмотреть файл

@ -54,7 +54,11 @@
testRole("aria_progressbar", ROLE_PROGRESSBAR);
testRole("aria_radio", ROLE_RADIOBUTTON);
testRole("aria_radiogroup", ROLE_RADIO_GROUP);
testRole("aria_region", ROLE_REGION);
testRole("aria_region_no_name", ROLE_TEXT);
testRole("aria_region_has_label", ROLE_REGION);
testRole("aria_region_has_labelledby", ROLE_REGION);
testRole("aria_region_has_title", ROLE_REGION);
testRole("aria_region_empty_name", ROLE_TEXT);
testRole("aria_row", ROLE_ROW);
testRole("aria_rowheader", ROLE_ROWHEADER);
testRole("aria_scrollbar", ROLE_SCROLLBAR);
@ -238,7 +242,11 @@
<span id="aria_progressbar" role="progressbar"/>
<span id="aria_radio" role="radio"/>
<span id="aria_radiogroup" role="radiogroup"/>
<span id="aria_region" role="region"/>
<span id="aria_region_no_name" role="region"/>
<span id="aria_region_has_label" role="region" aria-label="label"/>
<span id="aria_region_has_labelledby" role="region" aria-labelledby="label"/><span id="label" aria-label="label">
<span id="aria_region_has_title" role="region" title="title"/>
<span id="aria_region_empty_name" role="region" aria-label="" title="" aria-labelledby="empty"/><span id="empty"/>
<span id="aria_row" role="row"/>
<span id="aria_rowheader" role="rowheader"/>
<span id="aria_scrollbar" role="scrollbar"/>

Просмотреть файл

@ -6,12 +6,17 @@
#include "Compatibility.h"
#include "mozilla/WindowsVersion.h"
#include "nsExceptionHandler.h"
#include "nsUnicharUtils.h"
#include "nsWindowsDllInterceptor.h"
#include "nsWinUtils.h"
#include "Statistics.h"
#include "mozilla/Preferences.h"
#include <shlobj.h>
using namespace mozilla;
using namespace mozilla::a11y;
@ -203,3 +208,178 @@ Compatibility::Init()
}
}
#if !defined(HAVE_64BIT_BUILD)
static bool
ReadCOMRegDefaultString(const nsString& aRegPath, nsAString& aOutBuf)
{
aOutBuf.Truncate();
// Get the required size and type of the registry value.
// We expect either REG_SZ or REG_EXPAND_SZ.
DWORD type;
DWORD bufLen = 0;
LONG result = ::RegGetValue(HKEY_CLASSES_ROOT, aRegPath.get(),
nullptr, RRF_RT_ANY, &type, nullptr, &bufLen);
if (result != ERROR_SUCCESS || (type != REG_SZ && type != REG_EXPAND_SZ)) {
return false;
}
// Now obtain the value
DWORD flags = type == REG_SZ ? RRF_RT_REG_SZ : RRF_RT_REG_EXPAND_SZ;
aOutBuf.SetLength((bufLen + 1) / sizeof(char16_t));
result = ::RegGetValue(HKEY_CLASSES_ROOT, aRegPath.get(), nullptr,
flags, nullptr, aOutBuf.BeginWriting(), &bufLen);
if (result != ERROR_SUCCESS) {
aOutBuf.Truncate();
return false;
}
// Truncate terminator
aOutBuf.Truncate((bufLen + 1) / sizeof(char16_t) - 1);
return true;
}
static bool
IsSystemOleAcc(nsCOMPtr<nsIFile>& aFile)
{
// Use FOLDERID_SystemX86 so that Windows doesn't give us a redirected
// system32 if we're a 32-bit process running on a 64-bit OS. This is
// necessary because the values that we are reading from the registry
// are not redirected; they reference SysWOW64 directly.
PWSTR systemPath = nullptr;
HRESULT hr = ::SHGetKnownFolderPath(FOLDERID_SystemX86, 0, nullptr,
&systemPath);
if (FAILED(hr)) {
return false;
}
nsCOMPtr<nsIFile> oleAcc;
nsresult rv = NS_NewLocalFile(nsDependentString(systemPath), false,
getter_AddRefs(oleAcc));
::CoTaskMemFree(systemPath);
systemPath = nullptr;
if (NS_FAILED(rv)) {
return false;
}
rv = oleAcc->Append(NS_LITERAL_STRING("oleacc.dll"));
if (NS_FAILED(rv)) {
return false;
}
bool isEqual;
rv = oleAcc->Equals(aFile, &isEqual);
return NS_SUCCEEDED(rv) && isEqual;
}
static bool
IsTypelibPreferred()
{
// If IAccessible's Proxy/Stub CLSID is kUniversalMarshalerClsid, then any
// external a11y clients are expecting to use a typelib.
NS_NAMED_LITERAL_STRING(kUniversalMarshalerClsid,
"{00020424-0000-0000-C000-000000000046}");
NS_NAMED_LITERAL_STRING(kIAccessiblePSClsidPath,
"Interface\\{618736E0-3C3D-11CF-810C-00AA00389B71}\\ProxyStubClsid32");
nsAutoString psClsid;
if (!ReadCOMRegDefaultString(kIAccessiblePSClsidPath, psClsid)) {
return false;
}
return psClsid.Equals(kUniversalMarshalerClsid,
nsCaseInsensitiveStringComparator());
}
static bool
IsIAccessibleTypelibRegistered()
{
// The system default IAccessible typelib is always registered with version
// 1.1, under the neutral locale (LCID 0).
NS_NAMED_LITERAL_STRING(kIAccessibleTypelibRegPath,
"TypeLib\\{1EA4DBF0-3C3B-11CF-810C-00AA00389B71}\\1.1\\0\\win32");
nsAutoString typelibPath;
if (!ReadCOMRegDefaultString(kIAccessibleTypelibRegPath, typelibPath)) {
return false;
}
nsCOMPtr<nsIFile> libTestFile;
nsresult rv = NS_NewLocalFile(typelibPath, false, getter_AddRefs(libTestFile));
if (NS_FAILED(rv)) {
return false;
}
return IsSystemOleAcc(libTestFile);
}
static bool
IsIAccessiblePSRegistered()
{
NS_NAMED_LITERAL_STRING(kIAccessiblePSRegPath,
"CLSID\\{03022430-ABC4-11D0-BDE2-00AA001A1953}\\InProcServer32");
nsAutoString proxyStubPath;
if (!ReadCOMRegDefaultString(kIAccessiblePSRegPath, proxyStubPath)) {
return false;
}
nsCOMPtr<nsIFile> libTestFile;
nsresult rv = NS_NewLocalFile(proxyStubPath, false, getter_AddRefs(libTestFile));
if (NS_FAILED(rv)) {
return false;
}
return IsSystemOleAcc(libTestFile);
}
static bool
UseIAccessibleProxyStub()
{
// If a typelib is preferred then external clients are expecting to use
// typelib marshaling, so we should use that whenever available.
if (IsTypelibPreferred() && IsIAccessibleTypelibRegistered()) {
return false;
}
// Otherwise we try the proxy/stub
if (IsIAccessiblePSRegistered()) {
return true;
}
// If we reach this point then something is seriously wrong with the
// IAccessible configuration in the computer's registry. Let's annotate this
// so that we can easily determine this condition during crash analysis.
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("IAccessibleConfig"),
NS_LITERAL_CSTRING("NoSystemTypeLibOrPS"));
return false;
}
#endif // !defined(HAVE_64BIT_BUILD)
uint16_t
Compatibility::GetActCtxResourceId()
{
#if defined(HAVE_64BIT_BUILD)
// The manifest for 64-bit Windows is embedded with resource ID 64.
return 64;
#else
// The manifest for 32-bit Windows is embedded with resource ID 32.
// Beginning with Windows 10 Creators Update, 32-bit builds always use the
// 64-bit manifest. Older builds of Windows may or may not require the 64-bit
// manifest: UseIAccessibleProxyStub() determines the course of action.
if (mozilla::IsWin10CreatorsUpdateOrLater() ||
UseIAccessibleProxyStub()) {
return 64;
}
return 32;
#endif // defined(HAVE_64BIT_BUILD)
}

Просмотреть файл

@ -39,6 +39,12 @@ public:
*/
static bool IsDolphin() { return !!(sConsumers & DOLPHIN); }
/**
* @return ID of a11y manifest resource to be passed to
* mscom::ActivationContext
*/
static uint16_t GetActCtxResourceId();
private:
Compatibility();
Compatibility(const Compatibility&);

Просмотреть файл

@ -5121,7 +5121,7 @@ nsBrowserAccess.prototype = {
return browser;
},
openURI(aURI, aOpener, aWhere, aFlags) {
openURI(aURI, aOpener, aWhere, aFlags, aTriggeringPrincipal) {
// This function should only ever be called if we're opening a URI
// from a non-remote browser window (via nsContentTreeOwner).
if (aOpener && Cu.isCrossProcessWrapper(aOpener)) {
@ -5153,11 +5153,9 @@ nsBrowserAccess.prototype = {
}
let referrer = aOpener ? makeURI(aOpener.location.href) : null;
let triggeringPrincipal = null;
let referrerPolicy = Ci.nsIHttpChannel.REFERRER_POLICY_UNSET;
if (aOpener && aOpener.document) {
referrerPolicy = aOpener.document.referrerPolicy;
triggeringPrincipal = aOpener.document.nodePrincipal;
}
let isPrivate = aOpener
? PrivateBrowsingUtils.isContentWindowPrivate(aOpener)
@ -5191,7 +5189,7 @@ nsBrowserAccess.prototype = {
let browser = this._openURIInNewTab(aURI, referrer, referrerPolicy,
isPrivate, isExternal,
forceNotRemote, userContextId,
openerWindow, triggeringPrincipal);
openerWindow, aTriggeringPrincipal);
if (browser)
newWindow = browser.contentWindow;
break;
@ -5202,7 +5200,7 @@ nsBrowserAccess.prototype = {
Ci.nsIWebNavigation.LOAD_FLAGS_FROM_EXTERNAL :
Ci.nsIWebNavigation.LOAD_FLAGS_NONE;
gBrowser.loadURIWithFlags(aURI.spec, {
triggeringPrincipal,
aTriggeringPrincipal,
flags: loadflags,
referrerURI: referrer,
referrerPolicy,

Просмотреть файл

@ -4,7 +4,8 @@ function test() {
window.browserDOMWindow.openURI(makeURI("about:blank"),
null,
Ci.nsIBrowserDOMWindow.OPEN_NEWTAB,
Ci.nsIBrowserDOMWindow.OPEN_EXTERNAL);
Ci.nsIBrowserDOMWindow.OPEN_EXTERNAL,
Services.scriptSecurityManager.getSystemPrincipal());
is(gBrowser.tabs.length, tabCount + 1,
"'--new-tab about:blank' opens a new tab");
is(gBrowser.selectedTab, gBrowser.tabs[tabCount],

Просмотреть файл

@ -1,7 +1,8 @@
add_task(async function() {
let browserLoadedPromise = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
window.browserDOMWindow.openURI(makeURI("about:"), null,
Ci.nsIBrowserDOMWindow.OPEN_CURRENTWINDOW, null)
Ci.nsIBrowserDOMWindow.OPEN_CURRENTWINDOW, null,
Services.scriptSecurityManager.getSystemPrincipal())
await browserLoadedPromise;
is(gBrowser.currentURI.spec, "about:", "page loads in the current content window");
});

Просмотреть файл

@ -3,7 +3,8 @@ function test() {
window.browserDOMWindow.openURI(makeURI(URI),
null,
Ci.nsIBrowserDOMWindow.OPEN_NEWTAB,
Ci.nsIBrowserDOMWindow.OPEN_EXTERNAL);
Ci.nsIBrowserDOMWindow.OPEN_EXTERNAL,
Services.scriptSecurityManager.getSystemPrincipal());
is(gBrowser.userTypedValue, URI, "userTypedValue matches test URI");
is(gURLBar.value, URI, "location bar value matches test URI");

Просмотреть файл

@ -343,7 +343,8 @@ nsBrowserContentHandler.prototype = {
try {
while ((uriparam = cmdLine.handleFlagWithParam("new-tab", false))) {
let uri = resolveURIInternal(cmdLine, uriparam);
handURIToExistingBrowser(uri, nsIBrowserDOMWindow.OPEN_NEWTAB, cmdLine);
handURIToExistingBrowser(uri, nsIBrowserDOMWindow.OPEN_NEWTAB, cmdLine, false,
Services.scriptSecurityManager.getSystemPrincipal());
cmdLine.preventDefault = true;
}
} catch (e) {
@ -391,7 +392,8 @@ nsBrowserContentHandler.prototype = {
var privateWindowParam = cmdLine.handleFlagWithParam("private-window", false);
if (privateWindowParam) {
let resolvedURI = resolveURIInternal(cmdLine, privateWindowParam);
handURIToExistingBrowser(resolvedURI, nsIBrowserDOMWindow.OPEN_NEWTAB, cmdLine, true);
handURIToExistingBrowser(resolvedURI, nsIBrowserDOMWindow.OPEN_NEWTAB, cmdLine, true,
Services.scriptSecurityManager.getSystemPrincipal());
cmdLine.preventDefault = true;
}
} catch (e) {
@ -607,8 +609,8 @@ nsBrowserContentHandler.prototype = {
}
request.QueryInterface(nsIChannel);
handURIToExistingBrowser(request.URI,
nsIBrowserDOMWindow.OPEN_DEFAULTWINDOW, null);
handURIToExistingBrowser(request.URI, nsIBrowserDOMWindow.OPEN_DEFAULTWINDOW, null, false,
request.loadInfo.triggeringPrincipal);
request.cancel(NS_BINDING_ABORTED);
},
@ -642,7 +644,7 @@ nsBrowserContentHandler.prototype = {
};
var gBrowserContentHandler = new nsBrowserContentHandler();
function handURIToExistingBrowser(uri, location, cmdLine, forcePrivate) {
function handURIToExistingBrowser(uri, location, cmdLine, forcePrivate, triggeringPrincipal) {
if (!shouldLoadURI(uri))
return;
@ -667,7 +669,7 @@ function handURIToExistingBrowser(uri, location, cmdLine, forcePrivate) {
.getInterface(nsIDOMWindow);
var bwin = rootWin.QueryInterface(nsIDOMChromeWindow).browserDOMWindow;
bwin.openURI(uri, null, location,
nsIBrowserDOMWindow.OPEN_EXTERNAL);
nsIBrowserDOMWindow.OPEN_EXTERNAL, triggeringPrincipal);
}
function nsDefaultCommandLineHandler() {
@ -742,7 +744,8 @@ nsDefaultCommandLineHandler.prototype = {
// Try to find an existing window and load our URI into the
// current tab, new tab, or new window as prefs determine.
try {
handURIToExistingBrowser(urilist[0], nsIBrowserDOMWindow.OPEN_DEFAULTWINDOW, cmdLine);
handURIToExistingBrowser(urilist[0], nsIBrowserDOMWindow.OPEN_DEFAULTWINDOW, cmdLine, false,
Services.scriptSecurityManager.getSystemPrincipal());
return;
} catch (e) {
}

Просмотреть файл

@ -241,13 +241,18 @@ function tunnelToInnerBrowser(outer, inner) {
let { detail } = event;
event.preventDefault();
let uri = Services.io.newURI(detail.url);
let sourceNode = event.dataTransfer.mozSourceNode;
let triggeringPrincipal = sourceNode
? sourceNode.nodePrincipal
: Services.scriptSecurityManager.getSystemPrincipal();
// This API is used mainly because it's near the path used for <a target/> with
// regular browser tabs (which calls `openURIInFrame`). The more elaborate APIs
// that support openers, window features, etc. didn't seem callable from JS and / or
// this event doesn't give enough info to use them.
browserWindow.browserDOMWindow
.openURI(uri, null, Ci.nsIBrowserDOMWindow.OPEN_NEWTAB,
Ci.nsIBrowserDOMWindow.OPEN_NEW);
Ci.nsIBrowserDOMWindow.OPEN_NEW,
triggeringPrincipal);
},
stop() {

Просмотреть файл

@ -40,6 +40,21 @@ nsOpenURIInFrameParams::GetIsPrivate(bool* aIsPrivate)
return NS_OK;
}
NS_IMETHODIMP
nsOpenURIInFrameParams::GetTriggeringPrincipal(nsIPrincipal** aTriggeringPrincipal)
{
NS_ADDREF(*aTriggeringPrincipal = mTriggeringPrincipal);
return NS_OK;
}
NS_IMETHODIMP
nsOpenURIInFrameParams::SetTriggeringPrincipal(nsIPrincipal* aTriggeringPrincipal)
{
NS_ENSURE_TRUE(aTriggeringPrincipal, NS_ERROR_INVALID_ARG);
mTriggeringPrincipal = aTriggeringPrincipal;
return NS_OK;
}
NS_IMETHODIMP
nsOpenURIInFrameParams::GetOpenerOriginAttributes(JSContext* aCx,
JS::MutableHandle<JS::Value> aValue)

Просмотреть файл

@ -25,4 +25,5 @@ private:
mozilla::OriginAttributes mOpenerOriginAttributes;
nsString mReferrer;
nsCOMPtr<nsIPrincipal> mTriggeringPrincipal;
};

Просмотреть файл

@ -9,12 +9,14 @@ interface mozIDOMWindowProxy;
interface nsIDOMWindow;
interface nsIURI;
interface nsIFrameLoaderOwner;
interface nsIPrincipal;
[scriptable, uuid(e774db14-79ac-4156-a7a3-aa3fd0a22c10)]
interface nsIOpenURIInFrameParams : nsISupports
{
attribute DOMString referrer;
readonly attribute boolean isPrivate;
attribute nsIPrincipal triggeringPrincipal;
[implicit_jscontext]
readonly attribute jsval openerOriginAttributes;
@ -97,11 +99,12 @@ interface nsIBrowserDOMWindow : nsISupports
* @param aFlags flags which control the behavior of the load. The
* OPEN_EXTERNAL/OPEN_NEW flag is only used when
* aWhere == OPEN_DEFAULTWINDOW.
* @param aTriggeringPrincipal the principal that triggered the load of aURI
* @return the window into which the URI was opened.
*/
mozIDOMWindowProxy
openURI(in nsIURI aURI, in mozIDOMWindowProxy aOpener,
in short aWhere, in long aFlags);
in short aWhere, in long aFlags, in nsIPrincipal aTriggeringPrincipal);
/**
* As above, but return the nsIFrameLoaderOwner for the new window.

Просмотреть файл

@ -72,6 +72,7 @@
#include "mozilla/WebBrowserPersistDocumentChild.h"
#include "imgLoader.h"
#include "GMPServiceChild.h"
#include "NullPrincipal.h"
#ifdef MOZ_GECKO_PROFILER
#include "ChildProfilerController.h"
@ -690,15 +691,19 @@ ContentChild::ProvideWindow(mozIDOMWindowProxy* aParent,
static nsresult
GetWindowParamsFromParent(mozIDOMWindowProxy* aParent,
nsACString& aBaseURIString, float* aFullZoom)
nsACString& aBaseURIString, float* aFullZoom,
nsIPrincipal** aTriggeringPrincipal)
{
*aFullZoom = 1.0f;
auto* opener = nsPIDOMWindowOuter::From(aParent);
if (!opener) {
nsCOMPtr<nsIPrincipal> nullPrincipal = NullPrincipal::Create();
NS_ADDREF(*aTriggeringPrincipal = nullPrincipal);
return NS_OK;
}
nsCOMPtr<nsIDocument> doc = opener->GetDoc();
NS_ADDREF(*aTriggeringPrincipal = doc->NodePrincipal());
nsCOMPtr<nsIURI> baseURI = doc->GetDocBaseURI();
if (!baseURI) {
NS_ERROR("nsIDocument didn't return a base URI");
@ -778,7 +783,9 @@ ContentChild::ProvideWindowCommon(TabChild* aTabOpener,
if (loadInDifferentProcess) {
nsAutoCString baseURIString;
float fullZoom;
rv = GetWindowParamsFromParent(aParent, baseURIString, &fullZoom);
nsCOMPtr<nsIPrincipal> triggeringPrincipal;
rv = GetWindowParamsFromParent(aParent, baseURIString, &fullZoom,
getter_AddRefs(triggeringPrincipal));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@ -794,7 +801,8 @@ ContentChild::ProvideWindowCommon(TabChild* aTabOpener,
features,
baseURIString,
fullZoom,
name);
name,
Principal(triggeringPrincipal));
// We return NS_ERROR_ABORT, so that the caller knows that we've abandoned
// the window open as far as it is concerned.
@ -890,7 +898,9 @@ ContentChild::ProvideWindowCommon(TabChild* aTabOpener,
} else {
nsAutoCString baseURIString;
float fullZoom;
rv = GetWindowParamsFromParent(aParent, baseURIString, &fullZoom);
nsCOMPtr<nsIPrincipal> triggeringPrincipal;
rv = GetWindowParamsFromParent(aParent, baseURIString, &fullZoom,
getter_AddRefs(triggeringPrincipal));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@ -901,7 +911,8 @@ ContentChild::ProvideWindowCommon(TabChild* aTabOpener,
aSizeSpecified,
features,
baseURIString,
fullZoom);
fullZoom,
Principal(triggeringPrincipal));
}
// Await the promise being resolved. When the promise is resolved, we'll set
@ -2748,29 +2759,6 @@ ContentChild::DeallocPOfflineCacheUpdateChild(POfflineCacheUpdateChild* actor)
return true;
}
mozilla::ipc::IPCResult
ContentChild::RecvLoadPluginResult(const uint32_t& aPluginId,
const bool& aResult)
{
nsresult rv;
Endpoint<PPluginModuleParent> endpoint;
bool finalResult = aResult &&
SendConnectPluginBridge(aPluginId, &rv, &endpoint) &&
NS_SUCCEEDED(rv);
plugins::PluginModuleContentParent::OnLoadPluginResult(aPluginId,
finalResult,
Move(endpoint));
return IPC_OK();
}
mozilla::ipc::IPCResult
ContentChild::RecvAssociatePluginId(const uint32_t& aPluginId,
const base::ProcessId& aProcessId)
{
plugins::PluginModuleContentParent::AssociatePluginId(aPluginId, aProcessId);
return IPC_OK();
}
mozilla::ipc::IPCResult
ContentChild::RecvDomainSetChanged(const uint32_t& aSetType,
const uint32_t& aChangeType,

Просмотреть файл

@ -438,12 +438,6 @@ public:
const nsCString& aTopic,
const nsString& aData) override;
virtual mozilla::ipc::IPCResult RecvAssociatePluginId(const uint32_t& aPluginId,
const base::ProcessId& aProcessId) override;
virtual mozilla::ipc::IPCResult RecvLoadPluginResult(const uint32_t& aPluginId,
const bool& aResult) override;
virtual mozilla::ipc::IPCResult RecvUpdateWindow(const uintptr_t& aChildId) override;
virtual mozilla::ipc::IPCResult RecvDomainSetChanged(const uint32_t& aSetType,

Просмотреть файл

@ -1104,8 +1104,7 @@ ContentParent::RecvLoadPlugin(const uint32_t& aPluginId,
Endpoint<PPluginModuleParent>* aEndpoint)
{
*aRv = NS_OK;
if (!mozilla::plugins::SetupBridge(aPluginId, this, false, aRv, aRunID,
aEndpoint)) {
if (!mozilla::plugins::SetupBridge(aPluginId, this, aRv, aRunID, aEndpoint)) {
return IPC_FAIL_NO_REASON(this);
}
return IPC_OK();
@ -1141,7 +1140,7 @@ ContentParent::RecvConnectPluginBridge(const uint32_t& aPluginId,
// in the first call to SetupBridge in RecvLoadPlugin, so we pass in a dummy
// pointer and just throw it away.
uint32_t dummy = 0;
if (!mozilla::plugins::SetupBridge(aPluginId, this, true, aRv, &dummy, aEndpoint)) {
if (!mozilla::plugins::SetupBridge(aPluginId, this, aRv, &dummy, aEndpoint)) {
return IPC_FAIL(this, "SetupBridge failed");
}
return IPC_OK();
@ -4504,7 +4503,8 @@ ContentParent::CommonCreateWindow(PBrowserParent* aThisTab,
const nsString& aName,
nsresult& aResult,
nsCOMPtr<nsITabParent>& aNewTabParent,
bool* aWindowIsNew)
bool* aWindowIsNew,
nsIPrincipal* aTriggeringPrincipal)
{
// The content process should never be in charge of computing whether or
@ -4582,6 +4582,8 @@ ContentParent::CommonCreateWindow(PBrowserParent* aThisTab,
nsCOMPtr<nsIOpenURIInFrameParams> params =
new nsOpenURIInFrameParams(openerOriginAttributes);
params->SetReferrer(NS_ConvertUTF8toUTF16(aBaseURI));
MOZ_ASSERT(aTriggeringPrincipal, "need a valid triggeringPrincipal");
params->SetTriggeringPrincipal(aTriggeringPrincipal);
nsCOMPtr<nsIFrameLoaderOwner> frameLoaderOwner;
aResult = browserDOMWin->OpenURIInFrame(aURIToLoad, params, openLocation,
@ -4647,6 +4649,7 @@ ContentParent::CommonCreateWindow(PBrowserParent* aThisTab,
aResult = newBrowserDOMWin->OpenURI(aURIToLoad, openerWindow,
nsIBrowserDOMWindow::OPEN_CURRENTWINDOW,
nsIBrowserDOMWindow::OPEN_NEW,
aTriggeringPrincipal,
getter_AddRefs(win));
}
@ -4664,6 +4667,7 @@ ContentParent::RecvCreateWindow(PBrowserParent* aThisTab,
const nsCString& aFeatures,
const nsCString& aBaseURI,
const float& aFullZoom,
const IPC::Principal& aTriggeringPrincipal,
CreateWindowResolver&& aResolve)
{
nsresult rv = NS_OK;
@ -4708,7 +4712,8 @@ ContentParent::RecvCreateWindow(PBrowserParent* aThisTab,
aCalledFromJS, aPositionSpecified, aSizeSpecified,
nullptr, aFeatures, aBaseURI, aFullZoom,
nextTabParentId, NullString(), rv,
newRemoteTab, &cwi.windowOpened());
newRemoteTab, &cwi.windowOpened(),
aTriggeringPrincipal);
if (!ipcResult) {
return ipcResult;
}
@ -4751,7 +4756,8 @@ ContentParent::RecvCreateWindowInDifferentProcess(
const nsCString& aFeatures,
const nsCString& aBaseURI,
const float& aFullZoom,
const nsString& aName)
const nsString& aName,
const IPC::Principal& aTriggeringPrincipal)
{
nsCOMPtr<nsITabParent> newRemoteTab;
bool windowIsNew;
@ -4762,7 +4768,7 @@ ContentParent::RecvCreateWindowInDifferentProcess(
aCalledFromJS, aPositionSpecified, aSizeSpecified,
uriToLoad, aFeatures, aBaseURI, aFullZoom,
/* aNextTabParentId = */ 0, aName, rv,
newRemoteTab, &windowIsNew);
newRemoteTab, &windowIsNew, aTriggeringPrincipal);
if (!ipcResult) {
return ipcResult;
}

Просмотреть файл

@ -536,6 +536,7 @@ public:
const nsCString& aFeatures,
const nsCString& aBaseURI,
const float& aFullZoom,
const IPC::Principal& aTriggeringPrincipal,
CreateWindowResolver&& aResolve) override;
virtual mozilla::ipc::IPCResult RecvCreateWindowInDifferentProcess(
@ -548,7 +549,8 @@ public:
const nsCString& aFeatures,
const nsCString& aBaseURI,
const float& aFullZoom,
const nsString& aName) override;
const nsString& aName,
const IPC::Principal& aTriggeringPrincipal) override;
static bool AllocateLayerTreeId(TabParent* aTabParent, uint64_t* aId);
@ -709,7 +711,8 @@ private:
const nsString& aName,
nsresult& aResult,
nsCOMPtr<nsITabParent>& aNewTabParent,
bool* aWindowIsNew);
bool* aWindowIsNew,
nsIPrincipal* aTriggeringPrincipal);
FORWARD_SHMEM_ALLOCATOR_TO(PContentParent)

Просмотреть файл

@ -489,19 +489,6 @@ child:
*/
async NotifyIdleObserver(uint64_t observerId, nsCString topic, nsString str);
/**
* Called during plugin initialization to map a plugin id to a child process
* id.
*/
async AssociatePluginId(uint32_t aPluginId, ProcessId aProcessId);
/**
* This call is used by async plugin initialization to notify the
* PluginModuleContentParent that the PluginModuleChromeParent's async
* init has completed.
*/
async LoadPluginResult(uint32_t aPluginId, bool aResult);
async InvokeDragSession(IPCDataTransfer[] transfers, uint32_t action);
async EndDragSession(bool aDoneDrag, bool aUserCancelled,
@ -991,7 +978,8 @@ parent:
bool aSizeSpecified,
nsCString aFeatures,
nsCString aBaseURI,
float aFullZoom)
float aFullZoom,
Principal aTriggeringPrincipal)
returns (CreatedWindowInfo window);
async CreateWindowInDifferentProcess(
@ -1004,7 +992,8 @@ parent:
nsCString aFeatures,
nsCString aBaseURI,
float aFullZoom,
nsString aName);
nsString aName,
Principal aTriggeringPrincipal);
sync GetAndroidSystemInfo()
returns (AndroidSystemInfo info);

Просмотреть файл

@ -3444,7 +3444,7 @@ TabChildSHistoryListener::OnRequestCrossBrowserNavigation(uint32_t aIndex)
NS_OK : NS_ERROR_FAILURE;
}
TabChildGlobal::TabChildGlobal(TabChildBase* aTabChild)
TabChildGlobal::TabChildGlobal(TabChild* aTabChild)
: mTabChild(aTabChild)
{
SetIsNotDOMBinding();
@ -3546,3 +3546,32 @@ TabChildGlobal::GetGlobalJSObject()
NS_ENSURE_TRUE(mTabChild, nullptr);
return mTabChild->GetGlobal();
}
nsresult
TabChildGlobal::Dispatch(const char* aName,
TaskCategory aCategory,
already_AddRefed<nsIRunnable>&& aRunnable)
{
if (mTabChild && mTabChild->TabGroup()) {
return mTabChild->TabGroup()->Dispatch(aName, aCategory, Move(aRunnable));
}
return DispatcherTrait::Dispatch(aName, aCategory, Move(aRunnable));
}
nsISerialEventTarget*
TabChildGlobal::EventTargetFor(TaskCategory aCategory) const
{
if (mTabChild && mTabChild->TabGroup()) {
return mTabChild->TabGroup()->EventTargetFor(aCategory);
}
return DispatcherTrait::EventTargetFor(aCategory);
}
AbstractThread*
TabChildGlobal::AbstractMainThreadFor(TaskCategory aCategory)
{
if (mTabChild && mTabChild->TabGroup()) {
return mTabChild->TabGroup()->AbstractMainThreadFor(aCategory);
}
return DispatcherTrait::AbstractMainThreadFor(aCategory);
}

Просмотреть файл

@ -45,8 +45,10 @@
class nsIDOMWindowUtils;
class nsIHttpChannel;
class nsISerialEventTarget;
namespace mozilla {
class AbstractThread;
namespace layout {
class RenderFrameChild;
} // namespace layout
@ -69,7 +71,6 @@ class TabChild;
class TabGroup;
class ClonedMessageData;
class CoalescedWheelData;
class TabChildBase;
class TabChildGlobal : public DOMEventTargetHelper,
public nsIContentFrameMessageManager,
@ -78,7 +79,7 @@ class TabChildGlobal : public DOMEventTargetHelper,
public nsSupportsWeakReference
{
public:
explicit TabChildGlobal(TabChildBase* aTabChild);
explicit TabChildGlobal(TabChild* aTabChild);
void Init();
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(TabChildGlobal, DOMEventTargetHelper)
@ -149,8 +150,19 @@ public:
MOZ_CRASH("TabChildGlobal doesn't use DOM bindings!");
}
// Dispatch a runnable related to the global.
virtual nsresult Dispatch(const char* aName,
mozilla::TaskCategory aCategory,
already_AddRefed<nsIRunnable>&& aRunnable) override;
virtual nsISerialEventTarget*
EventTargetFor(mozilla::TaskCategory aCategory) const override;
virtual AbstractThread*
AbstractMainThreadFor(mozilla::TaskCategory aCategory) override;
nsCOMPtr<nsIContentFrameMessageManager> mMessageManager;
RefPtr<TabChildBase> mTabChild;
RefPtr<TabChild> mTabChild;
protected:
~TabChildGlobal();

Просмотреть файл

@ -28,7 +28,7 @@ class MediaDrmCDMCallbackProxy;
class MediaDrmCDMProxy : public CDMProxy {
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaDrmCDMProxy)
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaDrmCDMProxy, override)
MediaDrmCDMProxy(dom::MediaKeys* aKeys,
const nsAString& aKeySystem,

Просмотреть файл

@ -589,6 +589,12 @@ PaymentRequest::UpdateShippingAddress(const nsAString& aCountry,
return DispatchUpdateEvent(NS_LITERAL_STRING("shippingaddresschange"));
}
void
PaymentRequest::SetShippingOption(const nsAString& aShippingOption)
{
mShippingOption = aShippingOption;
}
void
PaymentRequest::GetShippingOption(nsAString& aRetVal) const
{
@ -604,10 +610,16 @@ PaymentRequest::UpdateShippingOption(const nsAString& aShippingOption)
return DispatchUpdateEvent(NS_LITERAL_STRING("shippingoptionchange"));
}
void
PaymentRequest::SetShippingType(const Nullable<PaymentShippingType>& aShippingType)
{
mShippingType = aShippingType;
}
Nullable<PaymentShippingType>
PaymentRequest::GetShippingType() const
{
return nullptr;
return mShippingType;
}
PaymentRequest::~PaymentRequest()

Просмотреть файл

@ -106,12 +106,15 @@ public:
const nsAString& aRecipient,
const nsAString& aPhone);
void SetShippingOption(const nsAString& aShippingOption);
void GetShippingOption(nsAString& aRetVal) const;
nsresult UpdateShippingOption(const nsAString& aShippingOption);
nsresult UpdatePayment(const PaymentDetailsUpdate& aDetails);
void AbortUpdate(nsresult aRv);
void SetShippingType(const Nullable<PaymentShippingType>& aShippingType);
Nullable<PaymentShippingType> GetShippingType() const;
IMPL_EVENT_HANDLER(shippingaddresschange);
@ -143,6 +146,8 @@ protected:
// It is populated when the user chooses a shipping option.
nsString mShippingOption;
Nullable<PaymentShippingType> mShippingType;
// "true" when there is a pending updateWith() call to update the payment request
// and "false" otherwise.
bool mUpdating;

Просмотреть файл

@ -103,7 +103,8 @@ nsresult
ConvertDetailsBase(const PaymentDetailsBase& aDetails,
nsTArray<IPCPaymentItem>& aDisplayItems,
nsTArray<IPCPaymentShippingOption>& aShippingOptions,
nsTArray<IPCPaymentDetailsModifier>& aModifiers)
nsTArray<IPCPaymentDetailsModifier>& aModifiers,
bool aResetShippingOptions)
{
if (aDetails.mDisplayItems.WasPassed()) {
for (const PaymentItem& item : aDetails.mDisplayItems.Value()) {
@ -112,7 +113,7 @@ ConvertDetailsBase(const PaymentDetailsBase& aDetails,
aDisplayItems.AppendElement(displayItem);
}
}
if (aDetails.mShippingOptions.WasPassed()) {
if (aDetails.mShippingOptions.WasPassed() && !aResetShippingOptions) {
for (const PaymentShippingOption& option : aDetails.mShippingOptions.Value()) {
IPCPaymentShippingOption shippingOption;
ConvertShippingOption(option, shippingOption);
@ -134,13 +135,14 @@ ConvertDetailsBase(const PaymentDetailsBase& aDetails,
nsresult
ConvertDetailsInit(const PaymentDetailsInit& aDetails,
IPCPaymentDetails& aIPCDetails)
IPCPaymentDetails& aIPCDetails,
bool aResetShippingOptions)
{
// Convert PaymentDetailsBase members
nsTArray<IPCPaymentItem> displayItems;
nsTArray<IPCPaymentShippingOption> shippingOptions;
nsTArray<IPCPaymentDetailsModifier> modifiers;
nsresult rv = ConvertDetailsBase(aDetails, displayItems, shippingOptions, modifiers);
nsresult rv = ConvertDetailsBase(aDetails, displayItems, shippingOptions, modifiers, aResetShippingOptions);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@ -175,7 +177,10 @@ ConvertDetailsUpdate(const PaymentDetailsUpdate& aDetails,
nsTArray<IPCPaymentItem> displayItems;
nsTArray<IPCPaymentShippingOption> shippingOptions;
nsTArray<IPCPaymentDetailsModifier> modifiers;
nsresult rv = ConvertDetailsBase(aDetails, displayItems, shippingOptions, modifiers);
// [TODO] Populate a boolean flag as aResetShippingOptions based on the
// result of processing details.shippingOptions in UpdatePayment method.
nsresult rv = ConvertDetailsBase(
aDetails, displayItems, shippingOptions, modifiers, false);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@ -352,6 +357,37 @@ PaymentRequestManager::GetPaymentRequestById(const nsAString& aRequestId)
return nullptr;
}
void
GetSelectedShippingOption(const PaymentDetailsInit& aDetails,
nsAString& aOption,
bool* aResetOptions)
{
SetDOMStringToNull(aOption);
if (!aDetails.mShippingOptions.WasPassed()) {
return;
}
nsTArray<nsString> seenIDs;
const Sequence<PaymentShippingOption>& shippingOptions =
aDetails.mShippingOptions.Value();
for (const PaymentShippingOption& shippingOption : shippingOptions) {
// If there are duplicate IDs present in the shippingOptions, reset aOption
// to null and set resetOptions flag to reset details.shippingOptions later
// when converting to IPC structure.
if (seenIDs.Contains(shippingOption.mId)) {
SetDOMStringToNull(aOption);
*aResetOptions = true;
return;
}
seenIDs.AppendElement(shippingOption.mId);
// set aOption to last selected option's ID
if (shippingOption.mSelected) {
aOption = shippingOption.mId;
}
}
}
nsresult
PaymentRequestManager::CreatePayment(nsPIDOMWindowInner* aWindow,
const Sequence<PaymentMethodData>& aMethodData,
@ -362,26 +398,7 @@ PaymentRequestManager::CreatePayment(nsPIDOMWindowInner* aWindow,
MOZ_ASSERT(NS_IsMainThread());
NS_ENSURE_ARG_POINTER(aRequest);
*aRequest = nullptr;
nsresult rv;
nsTArray<IPCPaymentMethodData> methodData;
for (const PaymentMethodData& data : aMethodData) {
IPCPaymentMethodData ipcMethodData;
rv = ConvertMethodData(data, ipcMethodData);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
methodData.AppendElement(ipcMethodData);
}
IPCPaymentDetails details;
rv = ConvertDetailsInit(aDetails, details);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
IPCPaymentOptions options;
ConvertOptions(aOptions, options);
RefPtr<PaymentRequest> request = PaymentRequest::CreatePaymentRequest(aWindow, rv);
if (NS_WARN_IF(NS_FAILED(rv))) {
@ -400,8 +417,48 @@ PaymentRequestManager::CreatePayment(nsPIDOMWindowInner* aWindow,
}
request->SetId(requestId);
/*
* Set request's mShippingOption to last selected option's ID if
* details.shippingOptions exists and IDs of all options are unique.
* Otherwise, set mShippingOption to null and set the resetShippingOptions
* flag to reset details.shippingOptions to an empty array later when
* converting details to IPC structure.
*/
nsAutoString shippingOption;
bool resetShippingOptions = false;
GetSelectedShippingOption(aDetails, shippingOption, &resetShippingOptions);
request->SetShippingOption(shippingOption);
/*
* Set request's |mShippingType| if shipping is required.
*/
if (aOptions.mRequestShipping) {
request->SetShippingType(
Nullable<PaymentShippingType>(aOptions.mShippingType));
}
nsAutoString internalId;
request->GetInternalId(internalId);
nsTArray<IPCPaymentMethodData> methodData;
for (const PaymentMethodData& data : aMethodData) {
IPCPaymentMethodData ipcMethodData;
rv = ConvertMethodData(data, ipcMethodData);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
methodData.AppendElement(ipcMethodData);
}
IPCPaymentDetails details;
rv = ConvertDetailsInit(aDetails, details, resetShippingOptions);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
IPCPaymentOptions options;
ConvertOptions(aOptions, options);
IPCPaymentCreateActionRequest action(internalId,
methodData,
details,
@ -489,6 +546,12 @@ PaymentRequestManager::UpdatePayment(const nsAString& aRequestId,
return NS_ERROR_UNEXPECTED;
}
// [TODO] Process details.shippingOptions if presented.
// 1) Check if there are duplicate IDs in details.shippingOptions,
// if so, reset details.shippingOptions to an empty sequence.
// 2) Set request's selectedShippingOption to the ID of last selected
// option.
IPCPaymentDetails details;
nsresult rv = ConvertDetailsUpdate(aDetails, details);
if (NS_WARN_IF(NS_FAILED(rv))) {

Просмотреть файл

@ -227,6 +227,67 @@ function checkComplexRequest(payRequest) {
}
}
function checkDuplicateShippingOptionsRequest(payRequest) {
if (payRequest.paymentMethods.length != 1) {
emitTestFail("paymentMethods' length should be 1.");
}
const methodData = payRequest.paymentMethods.queryElementAt(0, Ci.nsIPaymentMethodData);
if (!methodData) {
emitTestFail("Fail to get payment methodData.");
}
let supportedMethod = methodData.supportedMethods;
if (supportedMethod != "basic-card") {
emitTestFail("supported method should be 'basic-card'.");
}
// checking the passed PaymentDetails parameter
const details = payRequest.paymentDetails;
if (details.id != "duplicate shipping options details" ) {
emitTestFail("details.id should be 'duplicate shipping options details'.");
}
if (details.totalItem.label != "Total") {
emitTestFail("total item's label should be 'Total'.");
}
if (details.totalItem.amount.currency != "USD") {
emitTestFail("total item's currency should be 'USD'.");
}
if (details.totalItem.amount.value != "1.00") {
emitTestFail("total item's value should be '1.00'.");
}
if (details.displayItems) {
emitTestFail("details.displayItems should be undefined.");
}
if (details.modifiers) {
emitTestFail("details.displayItems should be undefined.");
}
const shippingOptions = details.shippingOptions;
if (!shippingOptions) {
emitTestFail("details.shippingOptions should not be undefined.");
}
if (shippingOptions.length != 0) {
emitTestFail("shippingOptions' length should be 0.");
}
// checking the default generated PaymentOptions parameter
const paymentOptions = payRequest.paymentOptions;
if (paymentOptions.requestPayerName) {
emitTestFail("requestPayerName option should be false.");
}
if (paymentOptions.requestPayerEmail) {
emitTestFail("requestPayerEmail option should be false.");
}
if (paymentOptions.requestPayerPhone) {
emitTestFail("requestPayerPhone option should be false.");
}
if (paymentOptions.requestShipping) {
emitTestFail("requestShipping option should be false.");
}
if (paymentOptions.shippingType != "shipping") {
emitTestFail("shippingType option should be 'shipping'.")
}
}
function checkSimplestRequestHandler() {
const paymentEnum = paymentSrv.enumerate();
if (!paymentEnum.hasMoreElements()) {
@ -261,6 +322,23 @@ function checkComplexRequestHandler() {
sendAsyncMessage("check-complete");
}
function checkDuplicateShippingOptionsRequestHandler() {
const paymentEnum = paymentSrv.enumerate();
if (!paymentEnum.hasMoreElements()) {
emitTestFail("PaymentRequestService should have at least one payment request.");
}
while (paymentEnum.hasMoreElements()) {
let payRequest = paymentEnum.getNext().QueryInterface(Ci.nsIPaymentRequest);
if (!payRequest) {
emitTestFail("Fail to get existing payment request.");
break;
}
checkDuplicateShippingOptionsRequest(payRequest);
}
paymentSrv.cleanup();
sendAsyncMessage("check-complete");
}
function checkMultipleRequestsHandler () {
const paymentEnum = paymentSrv.enumerate();
if (!paymentEnum.hasMoreElements()) {
@ -272,10 +350,12 @@ function checkMultipleRequestsHandler () {
emitTestFail("Fail to get existing payment request.");
break;
}
if (payRequest.paymentDetails.id != "payment details") {
checkSimplestRequest(payRequest);
} else {
if (payRequest.paymentDetails.id == "payment details") {
checkComplexRequest(payRequest);
} else if (payRequest.paymentDetails.id == "duplicate shipping options details") {
checkDuplicateShippingOptionsRequest(payRequest);
} else {
checkSimplestRequest(payRequest);
}
}
paymentSrv.cleanup();
@ -284,6 +364,7 @@ function checkMultipleRequestsHandler () {
addMessageListener("check-simplest-request", checkSimplestRequestHandler);
addMessageListener("check-complex-request", checkComplexRequestHandler);
addMessageListener("check-duplicate-shipping-options-request", checkDuplicateShippingOptionsRequestHandler);
addMessageListener("check-multiple-requests", checkMultipleRequestsHandler);
addMessageListener("teardown", function() {

Просмотреть файл

@ -22,6 +22,8 @@ add_task(async function() {
checkComplexPayment(payment);
} else if (payment.paymentDetails.id == "simple details") {
checkSimplePayment(payment);
} else if (payment.paymentDetails.id == "duplicate shipping options details") {
checkDupShippingOptionsPayment(payment);
} else {
ok(false, "Unknown payment.");
}

Просмотреть файл

@ -101,6 +101,34 @@ function checkComplexPayment(aPayment) {
is(paymentOptions.shippingType, "shipping", "shippingType option should be 'shipping'");
}
function checkDupShippingOptionsPayment(aPayment) {
// checking the passed PaymentMethods parameter
is(aPayment.paymentMethods.length, 1, "paymentMethods' length should be 1.");
const methodData = aPayment.paymentMethods.queryElementAt(0, Ci.nsIPaymentMethodData);
ok(methodData, "Fail to get payment methodData.");
is(methodData.supportedMethods, "MyPay", "modifier's supported method name should be 'MyPay'.");
is(methodData.data, "", "method data should be empty");
// checking the passed PaymentDetails parameter
const details = aPayment.paymentDetails;
is(details.id, "duplicate shipping options details", "details.id should be 'duplicate shipping options details'.");
is(details.totalItem.label, "Donation", "total item's label should be 'Donation'.");
is(details.totalItem.amount.currency, "USD", "total item's currency should be 'USD'.");
is(details.totalItem.amount.value, "55.00", "total item's value should be '55.00'.");
const shippingOptions = details.shippingOptions;
is(shippingOptions.length, 0, "shippingOptions' length should be 0.");
// checking the passed PaymentOptions parameter
const paymentOptions = aPayment.paymentOptions;
ok(paymentOptions.requestPayerName, "payerName option should be true");
ok(paymentOptions.requestPayerEmail, "payerEmail option should be true");
ok(paymentOptions.requestPayerPhone, "payerPhone option should be true");
ok(paymentOptions.requestShipping, "requestShipping option should be true");
is(paymentOptions.shippingType, "shipping", "shippingType option should be 'shipping'");
}
function cleanup() {
const paymentSrv = Cc["@mozilla.org/dom/payments/payment-request-service;1"].getService(Ci.nsIPaymentRequestService);
if (paymentSrv) {

Просмотреть файл

@ -66,6 +66,28 @@
},
};
const dupShippingOptionsDetails = {
id: "duplicate shipping options details",
total: {
label: "Donation",
amount: { currency: "USD", value: "55.00" }
},
shippingOptions: [
{
id: "dupShipping",
label: "NormalShipping",
amount: { currency: "USD", value: "10.00", },
selected: true,
},
{
id: "dupShipping",
label: "FastShipping",
amount: { currency: "USD", value: "30.00", },
selected: false,
},
],
};
const options = {
requestPayerName: true,
requestPayerEmail: true,
@ -79,6 +101,9 @@
options);
const paymentRequest2 = new PaymentRequest(supportedInstruments,
simpleDetails);
const paymentRequest3 = new PaymentRequest(supportedInstruments,
dupShippingOptionsDetails,
options);
</script>
</body>
</html>

Просмотреть файл

@ -121,6 +121,37 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1345361
shippingType: "shipping"
};
const duplicateShippingOptionsDetails = {
id: "duplicate shipping options details",
total: {
label: "Total",
amount: {
currency: "USD",
value: "1.00"
}
},
shippingOptions: [
{
id: "dupShipping",
label: "NormalShipping",
amount: {
currency: "USD",
value: "10.00"
},
selected: true,
},
{
id: "dupShipping",
label: "FastShipping",
amount: {
currency: "USD",
value: "30.00"
},
selected: false,
},
],
};
function testWithSimplestParameters() {
return new Promise((resolve, reject) => {
@ -146,12 +177,26 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1345361
});
}
function testWithDuplicateShippingOptionsParameters() {
return new Promise((resolve, reject) => {
const payRequest = new PaymentRequest(simplestMethods, duplicateShippingOptionsDetails);
ok(payRequest, "PaymentRequest should be created");
gScript.addMessageListener("check-complete", function checkCompleteHandler() {
gScript.removeMessageListener("check-complete", checkCompleteHandler);
resolve();
});
gScript.sendAsyncMessage("check-duplicate-shipping-options-request");
});
}
function testMultipleRequests() {
return new Promise((resolve, reject) => {
const payRequest1 = new PaymentRequest(complexMethods, complexDetails, complexOptions);
const payRequest2 = new PaymentRequest(simplestMethods, simplestDetails);
const payRequest3 = new PaymentRequest(simplestMethods, duplicateShippingOptionsDetails);
ok(payRequest1, "PaymentRequest with complex parameters should be created");
ok(payRequest2, "PaymentRequest with simplest parameters should be created");
ok(payRequest3, "PaymentRequest with duplicate shipping options parameters should be created");
gScript.addMessageListener("check-complete", function checkCompleteHandler() {
gScript.removeMessageListener("check-complete", checkCompleteHandler);
resolve();
@ -173,6 +218,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1345361
function runTests() {
testWithSimplestParameters()
.then(testWithComplexParameters)
.then(testWithDuplicateShippingOptionsParameters)
.then(testMultipleRequests)
.then(teardown)
.catch( e => {

Просмотреть файл

@ -1,4 +1,5 @@
/* -*- Mode: C++; tab-width: 2; 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/. */
@ -29,10 +30,6 @@
#include "js/TracingAPI.h"
#include "mozilla/HashFunctions.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/plugins/PluginAsyncSurrogate.h"
using mozilla::plugins::AsyncNPObject;
using mozilla::plugins::PluginAsyncSurrogate;
#define NPRUNTIME_JSCLASS_NAME "NPObject JS wrapper class"
@ -109,24 +106,10 @@ static nsTArray<NPObject*>* sDelayedReleases;
namespace {
inline void
CastNPObject(NPObject *aObj, PluginScriptableObjectParent*& aActor,
PluginAsyncSurrogate*& aSurrogate)
{
aActor = nullptr;
aSurrogate = nullptr;
if (aObj->_class == PluginScriptableObjectParent::GetClass()) {
aActor = static_cast<ParentNPObject*>(aObj)->parent;
} else if (aObj->_class == PluginAsyncSurrogate::GetClass()) {
aSurrogate = static_cast<AsyncNPObject*>(aObj)->mSurrogate;
}
}
inline bool
NPObjectIsOutOfProcessProxy(NPObject *obj)
{
return obj->_class == PluginScriptableObjectParent::GetClass() ||
obj->_class == PluginAsyncSurrogate::GetClass();
return obj->_class == PluginScriptableObjectParent::GetClass();
}
} // namespace
@ -1097,17 +1080,6 @@ nsJSObjWrapper::GetNewOrUsed(NPP npp, JS::Handle<JSObject*> obj)
return nullptr;
}
// If we're running out-of-process and initializing asynchronously, and if
// the plugin has been asked to destroy itself during initialization,
// don't return any new NPObjects.
nsNPAPIPluginInstance* inst = static_cast<nsNPAPIPluginInstance*>(npp->ndata);
if (inst->GetPlugin()->GetLibrary()->IsOOP()) {
PluginAsyncSurrogate* surrogate = PluginAsyncSurrogate::Cast(npp);
if (surrogate && surrogate->IsDestroyPending()) {
return nullptr;
}
}
// No need to enter the right compartment here as we only get the
// class and private from the JSObject, neither of which cares about
// compartments.
@ -1404,22 +1376,15 @@ NPObjWrapper_GetProperty(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<js
NPIdentifier identifier = JSIdToNPIdentifier(id);
if (NPObjectIsOutOfProcessProxy(npobj)) {
PluginScriptableObjectParent* actor = nullptr;
PluginAsyncSurrogate* surrogate = nullptr;
CastNPObject(npobj, actor, surrogate);
PluginScriptableObjectParent* actor =
static_cast<ParentNPObject*>(npobj)->parent;
// actor and surrogate may be null if the plugin crashed.
if (!actor && !surrogate)
// actor may be null if the plugin crashed.
if (!actor)
return false;
bool success = false;
if (surrogate) {
success = surrogate->GetPropertyHelper(npobj, identifier, &hasProperty,
&hasMethod, &npv);
} else if (actor) {
success = actor->GetPropertyHelper(identifier, &hasProperty, &hasMethod,
&npv);
}
bool success = actor->GetPropertyHelper(identifier, &hasProperty,
&hasMethod, &npv);
if (!ReportExceptionIfPending(cx)) {
if (success)

Просмотреть файл

@ -53,7 +53,6 @@
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/FakePluginTagInitBinding.h"
#include "mozilla/LoadInfo.h"
#include "mozilla/plugins/PluginAsyncSurrogate.h"
#include "mozilla/plugins/PluginBridge.h"
#include "mozilla/plugins/PluginTypes.h"
#include "mozilla/Preferences.h"
@ -119,7 +118,6 @@ using namespace mozilla;
using mozilla::TimeStamp;
using mozilla::plugins::FakePluginTag;
using mozilla::plugins::PluginTag;
using mozilla::plugins::PluginAsyncSurrogate;
using mozilla::dom::FakePluginTagInit;
using mozilla::dom::FakePluginMimeEntry;
@ -758,7 +756,6 @@ nsPluginHost::InstantiatePluginInstance(const nsACString& aMimeType, nsIURI* aUR
instanceOwner->Destroy();
return NS_ERROR_FAILURE;
}
const bool isAsyncInit = (rv == NS_PLUGIN_INIT_PENDING);
RefPtr<nsNPAPIPluginInstance> instance;
rv = instanceOwner->GetInstance(getter_AddRefs(instance));
@ -767,8 +764,7 @@ nsPluginHost::InstantiatePluginInstance(const nsACString& aMimeType, nsIURI* aUR
return rv;
}
// Async init plugins will initiate their own widget creation.
if (!isAsyncInit && instance) {
if (instance) {
CreateWidget(instanceOwner);
}
@ -2383,7 +2379,6 @@ nsPluginHost::SetPluginsInContent(uint32_t aPluginEpoch,
nsTArray<nsCString>(tag.extensions()),
tag.isJavaPlugin(),
tag.isFlashPlugin(),
tag.supportsAsyncInit(),
tag.supportsAsyncRender(),
tag.lastModifiedTime(),
tag.isFromExtension(),
@ -2624,7 +2619,6 @@ nsPluginHost::SendPluginsToContent()
tag->Extensions(),
tag->mIsJavaPlugin,
tag->mIsFlashPlugin,
tag->mSupportsAsyncInit,
tag->mSupportsAsyncRender,
tag->FileName(),
tag->Version(),
@ -4023,12 +4017,6 @@ PluginDestructionGuard::PluginDestructionGuard(nsNPAPIPluginInstance *aInstance)
Init();
}
PluginDestructionGuard::PluginDestructionGuard(PluginAsyncSurrogate *aSurrogate)
: mInstance(static_cast<nsNPAPIPluginInstance*>(aSurrogate->GetNPP()->ndata))
{
InitAsync();
}
PluginDestructionGuard::PluginDestructionGuard(NPP npp)
: mInstance(npp ? static_cast<nsNPAPIPluginInstance*>(npp->ndata) : nullptr)
{

Просмотреть файл

@ -35,7 +35,6 @@
namespace mozilla {
namespace plugins {
class FakePluginTag;
class PluginAsyncSurrogate;
class PluginTag;
} // namespace plugins
} // namespace mozilla
@ -425,7 +424,6 @@ class PluginDestructionGuard : public mozilla::LinkedListElement<PluginDestructi
{
public:
explicit PluginDestructionGuard(nsNPAPIPluginInstance *aInstance);
explicit PluginDestructionGuard(mozilla::plugins::PluginAsyncSurrogate *aSurrogate);
explicit PluginDestructionGuard(NPP npp);
~PluginDestructionGuard();
@ -442,17 +440,6 @@ protected:
sList.insertBack(this);
}
void InitAsync()
{
NS_ASSERTION(NS_IsMainThread(), "Should be on the main thread");
mDelayedDestroy = false;
// Instances with active surrogates must be inserted *in front of* sList so
// that they appear to be at the bottom of the stack
sList.insertFront(this);
}
RefPtr<nsNPAPIPluginInstance> mInstance;
bool mDelayedDestroy;

Просмотреть файл

@ -1668,45 +1668,6 @@ void nsPluginInstanceOwner::ExitFullScreen(jobject view) {
#endif
void
nsPluginInstanceOwner::NotifyHostAsyncInitFailed()
{
nsCOMPtr<nsIObjectLoadingContent> content = do_QueryReferent(mContent);
content->StopPluginInstance();
}
void
nsPluginInstanceOwner::NotifyHostCreateWidget()
{
mPluginHost->CreateWidget(this);
#ifdef XP_MACOSX
FixUpPluginWindow(ePluginPaintEnable);
#else
if (mPluginFrame) {
mPluginFrame->InvalidateFrame();
} else {
CallSetWindow();
}
#endif
}
void
nsPluginInstanceOwner::NotifyDestroyPending()
{
if (!mInstance) {
return;
}
bool isOOP = false;
if (NS_FAILED(mInstance->GetIsOOP(&isOOP)) || !isOOP) {
return;
}
NPP npp = nullptr;
if (NS_FAILED(mInstance->GetNPP(&npp)) || !npp) {
return;
}
PluginAsyncSurrogate::NotifyDestroyPending(npp);
}
nsresult nsPluginInstanceOwner::DispatchFocusToPlugin(nsIDOMEvent* aFocusEvent)
{
#ifdef MOZ_WIDGET_ANDROID

Просмотреть файл

@ -269,10 +269,6 @@ public:
static void ExitFullScreen(jobject view);
#endif
void NotifyHostAsyncInitFailed();
void NotifyHostCreateWidget();
void NotifyDestroyPending();
bool GetCompositionString(uint32_t aIndex, nsTArray<uint8_t>* aString,
int32_t* aLength);
bool SetCandidateWindow(

Просмотреть файл

@ -233,7 +233,6 @@ nsPluginTag::nsPluginTag(nsPluginInfo* aPluginInfo,
mLibrary(nullptr),
mIsJavaPlugin(false),
mIsFlashPlugin(false),
mSupportsAsyncInit(false),
mSupportsAsyncRender(false),
mFullPath(aPluginInfo->fFullPath),
mLastModifiedTime(aLastModifiedTime),
@ -270,7 +269,6 @@ nsPluginTag::nsPluginTag(const char* aName,
mLibrary(nullptr),
mIsJavaPlugin(false),
mIsFlashPlugin(false),
mSupportsAsyncInit(false),
mSupportsAsyncRender(false),
mFullPath(aFullPath),
mLastModifiedTime(aLastModifiedTime),
@ -298,7 +296,6 @@ nsPluginTag::nsPluginTag(uint32_t aId,
nsTArray<nsCString> aExtensions,
bool aIsJavaPlugin,
bool aIsFlashPlugin,
bool aSupportsAsyncInit,
bool aSupportsAsyncRender,
int64_t aLastModifiedTime,
bool aFromExtension,
@ -310,7 +307,6 @@ nsPluginTag::nsPluginTag(uint32_t aId,
mLibrary(nullptr),
mIsJavaPlugin(aIsJavaPlugin),
mIsFlashPlugin(aIsFlashPlugin),
mSupportsAsyncInit(aSupportsAsyncInit),
mSupportsAsyncRender(aSupportsAsyncRender),
mLastModifiedTime(aLastModifiedTime),
mSandboxLevel(aSandboxLevel),
@ -356,25 +352,17 @@ void nsPluginTag::InitMime(const char* const* aMimeTypes,
switch (nsPluginHost::GetSpecialType(mimeType)) {
case nsPluginHost::eSpecialType_Java:
mIsJavaPlugin = true;
mSupportsAsyncInit = true;
break;
case nsPluginHost::eSpecialType_Flash:
// VLC sometimes claims to implement the Flash MIME type, and we want
// to allow users to control that separately from Adobe Flash.
if (Name().EqualsLiteral("Shockwave Flash")) {
mIsFlashPlugin = true;
mSupportsAsyncInit = true;
}
break;
case nsPluginHost::eSpecialType_Test:
mSupportsAsyncInit = true;
break;
case nsPluginHost::eSpecialType_None:
default:
#ifndef RELEASE_OR_BETA
// Allow async init for all plugins on Nightly and Aurora
mSupportsAsyncInit = true;
#endif
break;
}

Просмотреть файл

@ -132,7 +132,6 @@ public:
nsTArray<nsCString> aExtensions,
bool aIsJavaPlugin,
bool aIsFlashPlugin,
bool aSupportsAsyncInit,
bool aSupportsAsyncRender,
int64_t aLastModifiedTime,
bool aFromExtension,
@ -169,7 +168,6 @@ public:
RefPtr<nsNPAPIPlugin> mPlugin;
bool mIsJavaPlugin;
bool mIsFlashPlugin;
bool mSupportsAsyncInit;
bool mSupportsAsyncRender;
nsCString mFullPath; // UTF-8
int64_t mLastModifiedTime;

Просмотреть файл

@ -5,7 +5,6 @@
#include "BrowserStreamParent.h"
#include "PluginAsyncSurrogate.h"
#include "PluginInstanceParent.h"
#include "nsNPAPIPlugin.h"
@ -23,7 +22,6 @@ BrowserStreamParent::BrowserStreamParent(PluginInstanceParent* npp,
NPStream* stream)
: mNPP(npp)
, mStream(stream)
, mDeferredDestroyReason(NPRES_DONE)
, mState(INITIALIZING)
{
mStream->pdata = static_cast<AStream*>(this);
@ -45,41 +43,6 @@ BrowserStreamParent::ActorDestroy(ActorDestroyReason aWhy)
// Implement me! Bug 1005159
}
mozilla::ipc::IPCResult
BrowserStreamParent::RecvAsyncNPP_NewStreamResult(const NPError& rv,
const uint16_t& stype)
{
PLUGIN_LOG_DEBUG_FUNCTION;
PluginAsyncSurrogate* surrogate = mNPP->GetAsyncSurrogate();
MOZ_ASSERT(surrogate);
surrogate->AsyncCallArriving();
if (mState == DEFERRING_DESTROY) {
// We've been asked to destroy ourselves before init was complete.
mState = DYING;
Unused << SendNPP_DestroyStream(mDeferredDestroyReason);
return IPC_OK();
}
NPError error = rv;
if (error == NPERR_NO_ERROR) {
if (!mStreamListener) {
return IPC_FAIL_NO_REASON(this);
}
if (mStreamListener->SetStreamType(stype)) {
mState = ALIVE;
} else {
error = NPERR_GENERIC_ERROR;
}
}
if (error != NPERR_NO_ERROR) {
surrogate->DestroyAsyncStream(mStream);
Unused << PBrowserStreamParent::Send__delete__(this);
}
return IPC_OK();
}
mozilla::ipc::IPCResult
BrowserStreamParent::AnswerNPN_RequestRead(const IPCByteRanges& ranges,
NPError* result)
@ -149,7 +112,6 @@ BrowserStreamParent::NPP_DestroyStream(NPReason reason)
bool stillInitializing = INITIALIZING == mState;
if (stillInitializing) {
mState = DEFERRING_DESTROY;
mDeferredDestroyReason = reason;
} else {
mState = DYING;
Unused << SendNPP_DestroyStream(reason);

Просмотреть файл

@ -30,10 +30,6 @@ public:
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
virtual mozilla::ipc::IPCResult RecvAsyncNPP_NewStreamResult(
const NPError& rv,
const uint16_t& stype) override;
virtual mozilla::ipc::IPCResult AnswerNPN_RequestRead(const IPCByteRanges& ranges,
NPError* result) override;
@ -61,7 +57,6 @@ private:
NPStream* mStream;
nsCOMPtr<nsISupports> mStreamPeer;
RefPtr<nsNPAPIPluginStreamListener> mStreamListener;
NPReason mDeferredDestroyReason;
enum {
INITIALIZING,

Просмотреть файл

@ -36,7 +36,6 @@ child:
async __delete__();
parent:
async AsyncNPP_NewStreamResult(NPError rv, uint16_t stype);
intr NPN_RequestRead(IPCByteRanges ranges)
returns (NPError result);
async NPN_DestroyStream(NPReason reason);

Просмотреть файл

@ -254,9 +254,6 @@ parent:
async RedrawPlugin();
// Notifies the parent of its NPP_New result code.
async AsyncNPP_NewResult(NPError aResult);
// Sends a native window to be adopted by the native window that would be
// returned by NPN_GetValue_NPNVnetscapeWindow. Only used on Windows.
async SetNetscapeWindowAsParent(NativeWindowHandle childWindow);
@ -293,9 +290,6 @@ child:
returns (NPError rv,
uint16_t stype);
// Implements the async plugin init version of NPP_NewStream.
async AsyncNPP_NewStream(PBrowserStream actor, nsCString mimeType, bool seekable);
parent:
/* NPN_NewStream */
intr PPluginStream(nsCString mimeType,

Просмотреть файл

@ -62,8 +62,6 @@ child:
intr NP_Initialize(PluginSettings settings)
returns (NPError rv);
async AsyncNP_Initialize(PluginSettings settings);
async PPluginInstance(nsCString aMimeType,
nsCString[] aNames,
nsCString[] aValues);
@ -73,9 +71,6 @@ child:
intr SyncNPP_New(PPluginInstance aActor)
returns (NPError rv);
// Implements the async plugin init version of NPP_New.
async AsyncNPP_New(PPluginInstance aActor);
intr NP_Shutdown()
returns (NPError rv);
@ -104,8 +99,6 @@ child:
async InitPluginModuleChild(Endpoint<PPluginModuleChild> endpoint);
parent:
async NP_InitializeResult(NPError aError);
/**
* This message is only used on X11 platforms.
*

Просмотреть файл

@ -1,996 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "PluginAsyncSurrogate.h"
#include "base/message_loop.h"
#include "base/message_pump_default.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/plugins/PluginInstanceParent.h"
#include "mozilla/plugins/PluginModuleParent.h"
#include "mozilla/plugins/PluginScriptableObjectParent.h"
#include "mozilla/Telemetry.h"
#include "nsJSNPRuntime.h"
#include "nsNPAPIPlugin.h"
#include "nsNPAPIPluginInstance.h"
#include "nsNPAPIPluginStreamListener.h"
#include "nsPluginInstanceOwner.h"
#include "nsPluginStreamListenerPeer.h"
#include "npruntime.h"
#include "nsThreadUtils.h"
#include "PluginMessageUtils.h"
namespace mozilla {
namespace plugins {
AsyncNPObject::AsyncNPObject(PluginAsyncSurrogate* aSurrogate)
: NPObject()
, mSurrogate(aSurrogate)
, mRealObject(nullptr)
{
}
AsyncNPObject::~AsyncNPObject()
{
if (mRealObject) {
--mRealObject->asyncWrapperCount;
parent::_releaseobject(mRealObject);
mRealObject = nullptr;
}
}
NPObject*
AsyncNPObject::GetRealObject()
{
if (mRealObject) {
return mRealObject;
}
PluginInstanceParent* instance = PluginInstanceParent::Cast(mSurrogate->GetNPP());
if (!instance) {
return nullptr;
}
NPObject* realObject = nullptr;
NPError err = instance->NPP_GetValue(NPPVpluginScriptableNPObject,
&realObject);
if (err != NPERR_NO_ERROR) {
return nullptr;
}
if (realObject->_class != PluginScriptableObjectParent::GetClass()) {
NS_ERROR("Don't know what kind of object this is!");
parent::_releaseobject(realObject);
return nullptr;
}
mRealObject = static_cast<ParentNPObject*>(realObject);
++mRealObject->asyncWrapperCount;
return mRealObject;
}
class MOZ_STACK_CLASS RecursionGuard
{
public:
RecursionGuard()
: mIsRecursive(sHasEntered)
{
if (!mIsRecursive) {
sHasEntered = true;
}
}
~RecursionGuard()
{
if (!mIsRecursive) {
sHasEntered = false;
}
}
inline bool
IsRecursive()
{
return mIsRecursive;
}
private:
bool mIsRecursive;
static bool sHasEntered;
};
bool RecursionGuard::sHasEntered = false;
PluginAsyncSurrogate::PluginAsyncSurrogate(PluginModuleParent* aParent)
: mParent(aParent)
, mWindow(nullptr)
, mAcceptCalls(false)
, mInstantiated(false)
, mAsyncSetWindow(false)
, mInitCancelled(false)
, mDestroyPending(false)
, mAsyncCallsInFlight(0)
{
MOZ_ASSERT(aParent);
}
PluginAsyncSurrogate::~PluginAsyncSurrogate()
{
}
bool
PluginAsyncSurrogate::Init(NPMIMEType aPluginType, NPP aInstance,
int16_t aArgc, char* aArgn[], char* aArgv[])
{
mMimeType = aPluginType;
nsNPAPIPluginInstance* instance =
static_cast<nsNPAPIPluginInstance*>(aInstance->ndata);
MOZ_ASSERT(instance);
mInstance = instance;
for (int i = 0; i < aArgc; ++i) {
mNames.AppendElement(NullableString(aArgn[i]));
mValues.AppendElement(NullableString(aArgv[i]));
}
return true;
}
/* static */ bool
PluginAsyncSurrogate::Create(PluginModuleParent* aParent, NPMIMEType aPluginType,
NPP aInstance, int16_t aArgc,
char* aArgn[], char* aArgv[])
{
RefPtr<PluginAsyncSurrogate> surrogate(new PluginAsyncSurrogate(aParent));
if (!surrogate->Init(aPluginType, aInstance, aArgc, aArgn, aArgv)) {
return false;
}
PluginAsyncSurrogate* rawSurrogate = nullptr;
surrogate.forget(&rawSurrogate);
aInstance->pdata = static_cast<PluginDataResolver*>(rawSurrogate);
return true;
}
/* static */ PluginAsyncSurrogate*
PluginAsyncSurrogate::Cast(NPP aInstance)
{
MOZ_ASSERT(aInstance);
PluginDataResolver* resolver =
reinterpret_cast<PluginDataResolver*>(aInstance->pdata);
if (!resolver) {
return nullptr;
}
return resolver->GetAsyncSurrogate();
}
nsresult
PluginAsyncSurrogate::NPP_New(NPError* aError)
{
if (!mInstance) {
return NS_ERROR_NULL_POINTER;
}
nsresult rv = mParent->NPP_NewInternal(mMimeType.BeginWriting(), GetNPP(),
mNames, mValues, nullptr,
aError);
if (NS_FAILED(rv)) {
return rv;
}
return NS_OK;
}
void
PluginAsyncSurrogate::NP_GetEntryPoints(NPPluginFuncs* aFuncs)
{
aFuncs->version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR;
aFuncs->destroy = &NPP_Destroy;
aFuncs->getvalue = &NPP_GetValue;
aFuncs->setvalue = &NPP_SetValue;
aFuncs->newstream = &NPP_NewStream;
aFuncs->setwindow = &NPP_SetWindow;
aFuncs->writeready = &NPP_WriteReady;
aFuncs->event = &NPP_HandleEvent;
aFuncs->destroystream = &NPP_DestroyStream;
// We need to set these so that content code doesn't make assumptions
// about these operations not being supported
aFuncs->write = &PluginModuleParent::NPP_Write;
aFuncs->asfile = &PluginModuleParent::NPP_StreamAsFile;
}
/* static */ void
PluginAsyncSurrogate::NotifyDestroyPending(NPP aInstance)
{
PluginAsyncSurrogate* surrogate = Cast(aInstance);
if (!surrogate) {
return;
}
surrogate->NotifyDestroyPending();
}
NPP
PluginAsyncSurrogate::GetNPP()
{
MOZ_ASSERT(mInstance);
NPP npp;
DebugOnly<nsresult> rv = mInstance->GetNPP(&npp);
MOZ_ASSERT(NS_SUCCEEDED(rv));
return npp;
}
void
PluginAsyncSurrogate::NotifyDestroyPending()
{
mDestroyPending = true;
nsJSNPRuntime::OnPluginDestroyPending(GetNPP());
}
NPError
PluginAsyncSurrogate::NPP_Destroy(NPSavedData** aSave)
{
NotifyDestroyPending();
if (!WaitForInit()) {
return NPERR_GENERIC_ERROR;
}
return PluginModuleParent::NPP_Destroy(GetNPP(), aSave);
}
NPError
PluginAsyncSurrogate::NPP_GetValue(NPPVariable aVariable, void* aRetval)
{
if (aVariable != NPPVpluginScriptableNPObject) {
if (!WaitForInit()) {
return NPERR_GENERIC_ERROR;
}
PluginInstanceParent* instance = PluginInstanceParent::Cast(GetNPP());
MOZ_ASSERT(instance);
return instance->NPP_GetValue(aVariable, aRetval);
}
NPObject* npobject = parent::_createobject(GetNPP(),
const_cast<NPClass*>(GetClass()));
MOZ_ASSERT(npobject);
MOZ_ASSERT(npobject->_class == GetClass());
MOZ_ASSERT(npobject->referenceCount == 1);
*(NPObject**)aRetval = npobject;
return npobject ? NPERR_NO_ERROR : NPERR_GENERIC_ERROR;
}
NPError
PluginAsyncSurrogate::NPP_SetValue(NPNVariable aVariable, void* aValue)
{
if (!WaitForInit()) {
return NPERR_GENERIC_ERROR;
}
return PluginModuleParent::NPP_SetValue(GetNPP(), aVariable, aValue);
}
NPError
PluginAsyncSurrogate::NPP_NewStream(NPMIMEType aType, NPStream* aStream,
NPBool aSeekable, uint16_t* aStype)
{
mPendingNewStreamCalls.AppendElement(PendingNewStreamCall(aType, aStream,
aSeekable));
if (aStype) {
*aStype = nsPluginStreamListenerPeer::STREAM_TYPE_UNKNOWN;
}
return NPERR_NO_ERROR;
}
NPError
PluginAsyncSurrogate::NPP_SetWindow(NPWindow* aWindow)
{
mWindow = aWindow;
mAsyncSetWindow = false;
return NPERR_NO_ERROR;
}
nsresult
PluginAsyncSurrogate::AsyncSetWindow(NPWindow* aWindow)
{
mWindow = aWindow;
mAsyncSetWindow = true;
return NS_OK;
}
void
PluginAsyncSurrogate::NPP_Print(NPPrint* aPrintInfo)
{
// Do nothing, we've got nothing to print right now
}
int16_t
PluginAsyncSurrogate::NPP_HandleEvent(void* event)
{
// Drop the event -- the plugin isn't around to handle it
return false;
}
int32_t
PluginAsyncSurrogate::NPP_WriteReady(NPStream* aStream)
{
// We'll tell the browser to retry in a bit. Eventually NPP_WriteReady
// will resolve to the plugin's NPP_WriteReady and this should all just work.
return 0;
}
NPError
PluginAsyncSurrogate::NPP_DestroyStream(NPStream* aStream, NPReason aReason)
{
for (uint32_t idx = 0, len = mPendingNewStreamCalls.Length(); idx < len; ++idx) {
PendingNewStreamCall& curPendingCall = mPendingNewStreamCalls[idx];
if (curPendingCall.mStream == aStream) {
mPendingNewStreamCalls.RemoveElementAt(idx);
break;
}
}
return NPERR_NO_ERROR;
}
/* static */ NPError
PluginAsyncSurrogate::NPP_Destroy(NPP aInstance, NPSavedData** aSave)
{
PluginAsyncSurrogate* rawSurrogate = Cast(aInstance);
MOZ_ASSERT(rawSurrogate);
PluginModuleParent* module = rawSurrogate->GetParent();
if (module && !module->IsInitialized()) {
// Take ownership of pdata's surrogate since we're going to release it
RefPtr<PluginAsyncSurrogate> surrogate(dont_AddRef(rawSurrogate));
aInstance->pdata = nullptr;
// We haven't actually called NPP_New yet, so we should remove the
// surrogate for this instance.
bool removeOk = module->RemovePendingSurrogate(surrogate);
MOZ_ASSERT(removeOk);
if (!removeOk) {
return NPERR_GENERIC_ERROR;
}
surrogate->mInitCancelled = true;
return NPERR_NO_ERROR;
}
return rawSurrogate->NPP_Destroy(aSave);
}
/* static */ NPError
PluginAsyncSurrogate::NPP_GetValue(NPP aInstance, NPPVariable aVariable,
void* aRetval)
{
PluginAsyncSurrogate* surrogate = Cast(aInstance);
MOZ_ASSERT(surrogate);
return surrogate->NPP_GetValue(aVariable, aRetval);
}
/* static */ NPError
PluginAsyncSurrogate::NPP_SetValue(NPP aInstance, NPNVariable aVariable,
void* aValue)
{
PluginAsyncSurrogate* surrogate = Cast(aInstance);
MOZ_ASSERT(surrogate);
return surrogate->NPP_SetValue(aVariable, aValue);
}
/* static */ NPError
PluginAsyncSurrogate::NPP_NewStream(NPP aInstance, NPMIMEType aType,
NPStream* aStream, NPBool aSeekable,
uint16_t* aStype)
{
PluginAsyncSurrogate* surrogate = Cast(aInstance);
MOZ_ASSERT(surrogate);
return surrogate->NPP_NewStream(aType, aStream, aSeekable, aStype);
}
/* static */ NPError
PluginAsyncSurrogate::NPP_SetWindow(NPP aInstance, NPWindow* aWindow)
{
PluginAsyncSurrogate* surrogate = Cast(aInstance);
MOZ_ASSERT(surrogate);
return surrogate->NPP_SetWindow(aWindow);
}
/* static */ void
PluginAsyncSurrogate::NPP_Print(NPP aInstance, NPPrint* aPrintInfo)
{
PluginAsyncSurrogate* surrogate = Cast(aInstance);
MOZ_ASSERT(surrogate);
surrogate->NPP_Print(aPrintInfo);
}
/* static */ int16_t
PluginAsyncSurrogate::NPP_HandleEvent(NPP aInstance, void* aEvent)
{
PluginAsyncSurrogate* surrogate = Cast(aInstance);
MOZ_ASSERT(surrogate);
return surrogate->NPP_HandleEvent(aEvent);
}
/* static */ int32_t
PluginAsyncSurrogate::NPP_WriteReady(NPP aInstance, NPStream* aStream)
{
PluginAsyncSurrogate* surrogate = Cast(aInstance);
MOZ_ASSERT(surrogate);
return surrogate->NPP_WriteReady(aStream);
}
/* static */ NPError
PluginAsyncSurrogate::NPP_DestroyStream(NPP aInstance,
NPStream* aStream,
NPReason aReason)
{
PluginAsyncSurrogate* surrogate = Cast(aInstance);
MOZ_ASSERT(surrogate);
return surrogate->NPP_DestroyStream(aStream, aReason);
}
PluginAsyncSurrogate::PendingNewStreamCall::PendingNewStreamCall(
NPMIMEType aType, NPStream* aStream, NPBool aSeekable)
: mType(NullableString(aType))
, mStream(aStream)
, mSeekable(aSeekable)
{
}
/* static */ nsNPAPIPluginStreamListener*
PluginAsyncSurrogate::GetStreamListener(NPStream* aStream)
{
nsNPAPIStreamWrapper* wrapper =
reinterpret_cast<nsNPAPIStreamWrapper*>(aStream->ndata);
if (!wrapper) {
return nullptr;
}
return wrapper->GetStreamListener();
}
void
PluginAsyncSurrogate::DestroyAsyncStream(NPStream* aStream)
{
MOZ_ASSERT(aStream);
nsNPAPIPluginStreamListener* streamListener = GetStreamListener(aStream);
MOZ_ASSERT(streamListener);
// streamListener was suspended during async init. We must resume the stream
// request prior to calling _destroystream for cleanup to work correctly.
streamListener->ResumeRequest();
if (!mInstance) {
return;
}
parent::_destroystream(GetNPP(), aStream, NPRES_DONE);
}
/* static */ bool
PluginAsyncSurrogate::SetStreamType(NPStream* aStream, uint16_t aStreamType)
{
nsNPAPIPluginStreamListener* streamListener = GetStreamListener(aStream);
if (!streamListener) {
return false;
}
return streamListener->SetStreamType(aStreamType);
}
void
PluginAsyncSurrogate::OnInstanceCreated(PluginInstanceParent* aInstance)
{
if (!mDestroyPending) {
// If NPP_Destroy has already been called then these streams have already
// been cleaned up on the browser side and are no longer valid.
for (uint32_t i = 0, len = mPendingNewStreamCalls.Length(); i < len; ++i) {
PendingNewStreamCall& curPendingCall = mPendingNewStreamCalls[i];
uint16_t streamType = NP_NORMAL;
NPError curError = aInstance->NPP_NewStream(
const_cast<char*>(NullableStringGet(curPendingCall.mType)),
curPendingCall.mStream, curPendingCall.mSeekable,
&streamType);
if (curError != NPERR_NO_ERROR) {
// If we failed here then the send failed and we need to clean up
DestroyAsyncStream(curPendingCall.mStream);
}
}
}
mPendingNewStreamCalls.Clear();
mInstantiated = true;
}
/**
* During asynchronous initialization it might be necessary to wait for the
* plugin to complete its initialization. This typically occurs when the result
* of a plugin call depends on the plugin being fully instantiated. For example,
* if some JS calls into the plugin, the call must be executed synchronously to
* preserve correctness.
*
* This function works by pumping the plugin's IPC channel for events until
* initialization has completed.
*/
bool
PluginAsyncSurrogate::WaitForInit()
{
if (mInitCancelled) {
return false;
}
if (mAcceptCalls) {
return true;
}
Telemetry::AutoTimer<Telemetry::BLOCKED_ON_PLUGINASYNCSURROGATE_WAITFORINIT_MS>
timer(mParent->GetHistogramKey());
bool result = false;
MOZ_ASSERT(mParent);
if (mParent->IsChrome()) {
PluginProcessParent* process = static_cast<PluginModuleChromeParent*>(mParent)->Process();
MOZ_ASSERT(process);
process->SetCallRunnableImmediately(true);
if (!process->WaitUntilConnected()) {
return false;
}
}
if (!mParent->WaitForIPCConnection()) {
return false;
}
if (!mParent->IsChrome()) {
// For e10s content processes, we need to spin the content channel until the
// protocol bridging has occurred.
dom::ContentChild* cp = dom::ContentChild::GetSingleton();
mozilla::ipc::MessageChannel* contentChannel = cp->GetIPCChannel();
MOZ_ASSERT(contentChannel);
while (!mParent->mNPInitialized) {
if (mParent->mShutdown) {
// Since we are pumping the message channel for events, it may be
// possible for module initialization to fail during this loop. We must
// return false if this happens or else we'll be permanently stuck.
return false;
}
result = contentChannel->WaitForIncomingMessage();
if (!result) {
return result;
}
}
}
mozilla::ipc::MessageChannel* channel = mParent->GetIPCChannel();
MOZ_ASSERT(channel);
while (!mAcceptCalls) {
if (mInitCancelled) {
// Since we are pumping the message channel for events, it may be
// possible for plugin instantiation to fail during this loop. We must
// return false if this happens or else we'll be permanently stuck.
return false;
}
result = channel->WaitForIncomingMessage();
if (!result) {
break;
}
}
return result;
}
void
PluginAsyncSurrogate::AsyncCallDeparting()
{
++mAsyncCallsInFlight;
if (!mPluginDestructionGuard) {
mPluginDestructionGuard = MakeUnique<PluginDestructionGuard>(this);
}
}
void
PluginAsyncSurrogate::AsyncCallArriving()
{
MOZ_ASSERT(mAsyncCallsInFlight > 0);
if (--mAsyncCallsInFlight == 0) {
mPluginDestructionGuard.reset(nullptr);
}
}
void
PluginAsyncSurrogate::NotifyAsyncInitFailed()
{
if (!mDestroyPending) {
// Clean up any pending NewStream requests
for (uint32_t i = 0, len = mPendingNewStreamCalls.Length(); i < len; ++i) {
PendingNewStreamCall& curPendingCall = mPendingNewStreamCalls[i];
DestroyAsyncStream(curPendingCall.mStream);
}
}
mPendingNewStreamCalls.Clear();
// Make sure that any WaitForInit calls on this surrogate will fail, or else
// we'll be perma-blocked
mInitCancelled = true;
if (!mInstance) {
return;
}
nsPluginInstanceOwner* owner = mInstance->GetOwner();
if (owner) {
owner->NotifyHostAsyncInitFailed();
}
}
// static
NPObject*
PluginAsyncSurrogate::ScriptableAllocate(NPP aInstance, NPClass* aClass)
{
PLUGIN_LOG_DEBUG_FUNCTION;
if (aClass != GetClass()) {
NS_ERROR("Huh?! Wrong class!");
return nullptr;
}
return new AsyncNPObject(Cast(aInstance));
}
// static
void
PluginAsyncSurrogate::ScriptableInvalidate(NPObject* aObject)
{
PLUGIN_LOG_DEBUG_FUNCTION;
if (aObject->_class != GetClass()) {
NS_ERROR("Don't know what kind of object this is!");
return;
}
AsyncNPObject* object = static_cast<AsyncNPObject*>(aObject);
if (!object->mSurrogate->WaitForInit()) {
return;
}
NPObject* realObject = object->GetRealObject();
if (!realObject) {
return;
}
realObject->_class->invalidate(realObject);
}
// static
void
PluginAsyncSurrogate::ScriptableDeallocate(NPObject* aObject)
{
PLUGIN_LOG_DEBUG_FUNCTION;
if (aObject->_class != GetClass()) {
NS_ERROR("Don't know what kind of object this is!");
return;
}
AsyncNPObject* object = static_cast<AsyncNPObject*>(aObject);
delete object;
}
// static
bool
PluginAsyncSurrogate::ScriptableHasMethod(NPObject* aObject,
NPIdentifier aName)
{
PLUGIN_LOG_DEBUG_FUNCTION;
if (aObject->_class != GetClass()) {
NS_ERROR("Don't know what kind of object this is!");
return false;
}
RecursionGuard guard;
if (guard.IsRecursive()) {
return false;
}
AsyncNPObject* object = static_cast<AsyncNPObject*>(aObject);
MOZ_ASSERT(object);
bool checkPluginObject = !object->mSurrogate->mInstantiated &&
!object->mSurrogate->mAcceptCalls;
if (!object->mSurrogate->WaitForInit()) {
return false;
}
NPObject* realObject = object->GetRealObject();
if (!realObject) {
return false;
}
bool result = realObject->_class->hasMethod(realObject, aName);
if (!result && checkPluginObject) {
// We may be calling into this object because properties in the WebIDL
// object hadn't been set yet. Now that we're further along in
// initialization, we should try again.
const NPNetscapeFuncs* npn = object->mSurrogate->mParent->GetNetscapeFuncs();
NPObject* pluginObject = nullptr;
NPError nperror = npn->getvalue(object->mSurrogate->GetNPP(),
NPNVPluginElementNPObject,
(void*)&pluginObject);
if (nperror == NPERR_NO_ERROR) {
NPPAutoPusher nppPusher(object->mSurrogate->GetNPP());
result = pluginObject->_class->hasMethod(pluginObject, aName);
npn->releaseobject(pluginObject);
NPUTF8* idstr = npn->utf8fromidentifier(aName);
npn->memfree(idstr);
}
}
return result;
}
bool
PluginAsyncSurrogate::GetPropertyHelper(NPObject* aObject, NPIdentifier aName,
bool* aHasProperty, bool* aHasMethod,
NPVariant* aResult)
{
PLUGIN_LOG_DEBUG_FUNCTION;
if (!aObject) {
return false;
}
RecursionGuard guard;
if (guard.IsRecursive()) {
return false;
}
if (!WaitForInit()) {
return false;
}
AsyncNPObject* object = static_cast<AsyncNPObject*>(aObject);
NPObject* realObject = object->GetRealObject();
if (!realObject) {
return false;
}
if (realObject->_class != PluginScriptableObjectParent::GetClass()) {
NS_ERROR("Don't know what kind of object this is!");
return false;
}
PluginScriptableObjectParent* actor =
static_cast<ParentNPObject*>(realObject)->parent;
if (!actor) {
return false;
}
bool success = actor->GetPropertyHelper(aName, aHasProperty, aHasMethod, aResult);
if (!success) {
const NPNetscapeFuncs* npn = mParent->GetNetscapeFuncs();
NPObject* pluginObject = nullptr;
NPError nperror = npn->getvalue(GetNPP(), NPNVPluginElementNPObject,
(void*)&pluginObject);
if (nperror == NPERR_NO_ERROR) {
NPPAutoPusher nppPusher(GetNPP());
bool hasProperty = nsJSObjWrapper::HasOwnProperty(pluginObject, aName);
NPUTF8* idstr = npn->utf8fromidentifier(aName);
npn->memfree(idstr);
bool hasMethod = false;
if (hasProperty) {
hasMethod = pluginObject->_class->hasMethod(pluginObject, aName);
success = pluginObject->_class->getProperty(pluginObject, aName, aResult);
idstr = npn->utf8fromidentifier(aName);
npn->memfree(idstr);
}
*aHasProperty = hasProperty;
*aHasMethod = hasMethod;
npn->releaseobject(pluginObject);
}
}
return success;
}
// static
bool
PluginAsyncSurrogate::ScriptableInvoke(NPObject* aObject,
NPIdentifier aName,
const NPVariant* aArgs,
uint32_t aArgCount,
NPVariant* aResult)
{
PLUGIN_LOG_DEBUG_FUNCTION;
if (aObject->_class != GetClass()) {
NS_ERROR("Don't know what kind of object this is!");
return false;
}
AsyncNPObject* object = static_cast<AsyncNPObject*>(aObject);
if (!object->mSurrogate->WaitForInit()) {
return false;
}
NPObject* realObject = object->GetRealObject();
if (!realObject) {
return false;
}
return realObject->_class->invoke(realObject, aName, aArgs, aArgCount, aResult);
}
// static
bool
PluginAsyncSurrogate::ScriptableInvokeDefault(NPObject* aObject,
const NPVariant* aArgs,
uint32_t aArgCount,
NPVariant* aResult)
{
PLUGIN_LOG_DEBUG_FUNCTION;
if (aObject->_class != GetClass()) {
NS_ERROR("Don't know what kind of object this is!");
return false;
}
AsyncNPObject* object = static_cast<AsyncNPObject*>(aObject);
if (!object->mSurrogate->WaitForInit()) {
return false;
}
NPObject* realObject = object->GetRealObject();
if (!realObject) {
return false;
}
return realObject->_class->invokeDefault(realObject, aArgs, aArgCount, aResult);
}
// static
bool
PluginAsyncSurrogate::ScriptableHasProperty(NPObject* aObject,
NPIdentifier aName)
{
PLUGIN_LOG_DEBUG_FUNCTION;
if (aObject->_class != GetClass()) {
NS_ERROR("Don't know what kind of object this is!");
return false;
}
RecursionGuard guard;
if (guard.IsRecursive()) {
return false;
}
AsyncNPObject* object = static_cast<AsyncNPObject*>(aObject);
MOZ_ASSERT(object);
bool checkPluginObject = !object->mSurrogate->mInstantiated &&
!object->mSurrogate->mAcceptCalls;
if (!object->mSurrogate->WaitForInit()) {
return false;
}
NPObject* realObject = object->GetRealObject();
if (!realObject) {
return false;
}
bool result = realObject->_class->hasProperty(realObject, aName);
const NPNetscapeFuncs* npn = object->mSurrogate->mParent->GetNetscapeFuncs();
NPUTF8* idstr = npn->utf8fromidentifier(aName);
npn->memfree(idstr);
if (!result && checkPluginObject) {
// We may be calling into this object because properties in the WebIDL
// object hadn't been set yet. Now that we're further along in
// initialization, we should try again.
NPObject* pluginObject = nullptr;
NPError nperror = npn->getvalue(object->mSurrogate->GetNPP(),
NPNVPluginElementNPObject,
(void*)&pluginObject);
if (nperror == NPERR_NO_ERROR) {
NPPAutoPusher nppPusher(object->mSurrogate->GetNPP());
result = nsJSObjWrapper::HasOwnProperty(pluginObject, aName);
npn->releaseobject(pluginObject);
idstr = npn->utf8fromidentifier(aName);
npn->memfree(idstr);
}
}
return result;
}
// static
bool
PluginAsyncSurrogate::ScriptableGetProperty(NPObject* aObject,
NPIdentifier aName,
NPVariant* aResult)
{
PLUGIN_LOG_DEBUG_FUNCTION;
// See GetPropertyHelper below.
NS_NOTREACHED("Shouldn't ever call this directly!");
return false;
}
// static
bool
PluginAsyncSurrogate::ScriptableSetProperty(NPObject* aObject,
NPIdentifier aName,
const NPVariant* aValue)
{
PLUGIN_LOG_DEBUG_FUNCTION;
if (aObject->_class != GetClass()) {
NS_ERROR("Don't know what kind of object this is!");
return false;
}
AsyncNPObject* object = static_cast<AsyncNPObject*>(aObject);
if (!object->mSurrogate->WaitForInit()) {
return false;
}
NPObject* realObject = object->GetRealObject();
if (!realObject) {
return false;
}
return realObject->_class->setProperty(realObject, aName, aValue);
}
// static
bool
PluginAsyncSurrogate::ScriptableRemoveProperty(NPObject* aObject,
NPIdentifier aName)
{
PLUGIN_LOG_DEBUG_FUNCTION;
if (aObject->_class != GetClass()) {
NS_ERROR("Don't know what kind of object this is!");
return false;
}
AsyncNPObject* object = static_cast<AsyncNPObject*>(aObject);
if (!object->mSurrogate->WaitForInit()) {
return false;
}
NPObject* realObject = object->GetRealObject();
if (!realObject) {
return false;
}
return realObject->_class->removeProperty(realObject, aName);
}
// static
bool
PluginAsyncSurrogate::ScriptableEnumerate(NPObject* aObject,
NPIdentifier** aIdentifiers,
uint32_t* aCount)
{
PLUGIN_LOG_DEBUG_FUNCTION;
if (aObject->_class != GetClass()) {
NS_ERROR("Don't know what kind of object this is!");
return false;
}
AsyncNPObject* object = static_cast<AsyncNPObject*>(aObject);
if (!object->mSurrogate->WaitForInit()) {
return false;
}
NPObject* realObject = object->GetRealObject();
if (!realObject) {
return false;
}
return realObject->_class->enumerate(realObject, aIdentifiers, aCount);
}
// static
bool
PluginAsyncSurrogate::ScriptableConstruct(NPObject* aObject,
const NPVariant* aArgs,
uint32_t aArgCount,
NPVariant* aResult)
{
PLUGIN_LOG_DEBUG_FUNCTION;
if (aObject->_class != GetClass()) {
NS_ERROR("Don't know what kind of object this is!");
return false;
}
AsyncNPObject* object = static_cast<AsyncNPObject*>(aObject);
if (!object->mSurrogate->WaitForInit()) {
return false;
}
NPObject* realObject = object->GetRealObject();
if (!realObject) {
return false;
}
return realObject->_class->construct(realObject, aArgs, aArgCount, aResult);
}
const NPClass PluginAsyncSurrogate::sNPClass = {
NP_CLASS_STRUCT_VERSION,
PluginAsyncSurrogate::ScriptableAllocate,
PluginAsyncSurrogate::ScriptableDeallocate,
PluginAsyncSurrogate::ScriptableInvalidate,
PluginAsyncSurrogate::ScriptableHasMethod,
PluginAsyncSurrogate::ScriptableInvoke,
PluginAsyncSurrogate::ScriptableInvokeDefault,
PluginAsyncSurrogate::ScriptableHasProperty,
PluginAsyncSurrogate::ScriptableGetProperty,
PluginAsyncSurrogate::ScriptableSetProperty,
PluginAsyncSurrogate::ScriptableRemoveProperty,
PluginAsyncSurrogate::ScriptableEnumerate,
PluginAsyncSurrogate::ScriptableConstruct
};
PushSurrogateAcceptCalls::PushSurrogateAcceptCalls(PluginInstanceParent* aInstance)
: mSurrogate(nullptr)
, mPrevAcceptCallsState(false)
{
MOZ_ASSERT(aInstance);
mSurrogate = aInstance->GetAsyncSurrogate();
if (mSurrogate) {
mPrevAcceptCallsState = mSurrogate->SetAcceptingCalls(true);
}
}
PushSurrogateAcceptCalls::~PushSurrogateAcceptCalls()
{
if (mSurrogate) {
mSurrogate->SetAcceptingCalls(mPrevAcceptCallsState);
}
}
} // namespace plugins
} // namespace mozilla

Просмотреть файл

@ -1,187 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef dom_plugins_ipc_PluginAsyncSurrogate_h
#define dom_plugins_ipc_PluginAsyncSurrogate_h
#include "mozilla/UniquePtr.h"
#include "npapi.h"
#include "npfunctions.h"
#include "npruntime.h"
#include "nsISupportsImpl.h"
#include "nsPluginHost.h"
#include "nsString.h"
#include "nsTArray.h"
#include "PluginDataResolver.h"
namespace mozilla {
namespace plugins {
struct ParentNPObject;
class PluginInstanceParent;
class PluginModuleParent;
class PluginAsyncSurrogate : public PluginDataResolver
{
public:
NS_INLINE_DECL_REFCOUNTING(PluginAsyncSurrogate)
bool Init(NPMIMEType aPluginType, NPP aInstance,
int16_t aArgc, char* aArgn[], char* aArgv[]);
nsresult NPP_New(NPError* aError);
NPError NPP_Destroy(NPSavedData** aSave);
NPError NPP_GetValue(NPPVariable aVariable, void* aRetval);
NPError NPP_SetValue(NPNVariable aVariable, void* aValue);
NPError NPP_NewStream(NPMIMEType aType, NPStream* aStream, NPBool aSeekable,
uint16_t* aStype);
NPError NPP_SetWindow(NPWindow* aWindow);
nsresult AsyncSetWindow(NPWindow* aWindow);
void NPP_Print(NPPrint* aPrintInfo);
int16_t NPP_HandleEvent(void* aEvent);
int32_t NPP_WriteReady(NPStream* aStream);
NPError NPP_DestroyStream(NPStream* aStream, NPReason aReason);
void OnInstanceCreated(PluginInstanceParent* aInstance);
static bool Create(PluginModuleParent* aParent, NPMIMEType aPluginType,
NPP aInstance, int16_t aArgc,
char* aArgn[], char* aArgv[]);
static const NPClass* GetClass() { return &sNPClass; }
static void NP_GetEntryPoints(NPPluginFuncs* aFuncs);
static PluginAsyncSurrogate* Cast(NPP aInstance);
static void NotifyDestroyPending(NPP aInstance);
void NotifyDestroyPending();
virtual PluginAsyncSurrogate*
GetAsyncSurrogate() { return this; }
virtual PluginInstanceParent*
GetInstance() { return nullptr; }
NPP GetNPP();
bool GetPropertyHelper(NPObject* aObject, NPIdentifier aName,
bool* aHasProperty, bool* aHasMethod,
NPVariant* aResult);
PluginModuleParent* GetParent() { return mParent; }
bool IsDestroyPending() const { return mDestroyPending; }
bool SetAcceptingCalls(bool aAccept)
{
bool prevState = mAcceptCalls;
if (mInstantiated) {
aAccept = true;
}
mAcceptCalls = aAccept;
return prevState;
}
void AsyncCallDeparting();
void AsyncCallArriving();
void NotifyAsyncInitFailed();
void DestroyAsyncStream(NPStream* aStream);
private:
explicit PluginAsyncSurrogate(PluginModuleParent* aParent);
virtual ~PluginAsyncSurrogate();
bool WaitForInit();
static bool SetStreamType(NPStream* aStream, uint16_t aStreamType);
static NPError NPP_Destroy(NPP aInstance, NPSavedData** aSave);
static NPError NPP_GetValue(NPP aInstance, NPPVariable aVariable, void* aRetval);
static NPError NPP_SetValue(NPP aInstance, NPNVariable aVariable, void* aValue);
static NPError NPP_NewStream(NPP aInstance, NPMIMEType aType, NPStream* aStream,
NPBool aSeekable, uint16_t* aStype);
static NPError NPP_SetWindow(NPP aInstance, NPWindow* aWindow);
static void NPP_Print(NPP aInstance, NPPrint* aPrintInfo);
static int16_t NPP_HandleEvent(NPP aInstance, void* aEvent);
static int32_t NPP_WriteReady(NPP aInstance, NPStream* aStream);
static NPError NPP_DestroyStream(NPP aInstance, NPStream* aStream,
NPReason aReason);
static NPObject* ScriptableAllocate(NPP aInstance, NPClass* aClass);
static void ScriptableInvalidate(NPObject* aObject);
static void ScriptableDeallocate(NPObject* aObject);
static bool ScriptableHasMethod(NPObject* aObject, NPIdentifier aName);
static bool ScriptableInvoke(NPObject* aObject, NPIdentifier aName,
const NPVariant* aArgs, uint32_t aArgCount,
NPVariant* aResult);
static bool ScriptableInvokeDefault(NPObject* aObject, const NPVariant* aArgs,
uint32_t aArgCount, NPVariant* aResult);
static bool ScriptableHasProperty(NPObject* aObject, NPIdentifier aName);
static bool ScriptableGetProperty(NPObject* aObject, NPIdentifier aName,
NPVariant* aResult);
static bool ScriptableSetProperty(NPObject* aObject, NPIdentifier aName,
const NPVariant* aValue);
static bool ScriptableRemoveProperty(NPObject* aObject, NPIdentifier aName);
static bool ScriptableEnumerate(NPObject* aObject, NPIdentifier** aIdentifiers,
uint32_t* aCount);
static bool ScriptableConstruct(NPObject* aObject, const NPVariant* aArgs,
uint32_t aArgCount, NPVariant* aResult);
static nsNPAPIPluginStreamListener* GetStreamListener(NPStream* aStream);
private:
struct PendingNewStreamCall
{
PendingNewStreamCall(NPMIMEType aType, NPStream* aStream, NPBool aSeekable);
~PendingNewStreamCall() {}
nsCString mType;
NPStream* mStream;
NPBool mSeekable;
};
private:
PluginModuleParent* mParent;
// These values are used to construct the plugin instance
nsCString mMimeType;
mozilla::WeakPtr<nsNPAPIPluginInstance> mInstance;
InfallibleTArray<nsCString> mNames;
InfallibleTArray<nsCString> mValues;
// This is safe to store as a pointer because the spec says it will remain
// valid until destruction or a subsequent NPP_SetWindow call.
NPWindow* mWindow;
nsTArray<PendingNewStreamCall> mPendingNewStreamCalls;
UniquePtr<PluginDestructionGuard> mPluginDestructionGuard;
bool mAcceptCalls;
bool mInstantiated;
bool mAsyncSetWindow;
bool mInitCancelled;
bool mDestroyPending;
int32_t mAsyncCallsInFlight;
static const NPClass sNPClass;
};
struct AsyncNPObject : NPObject
{
explicit AsyncNPObject(PluginAsyncSurrogate* aSurrogate);
~AsyncNPObject();
NPObject* GetRealObject();
RefPtr<PluginAsyncSurrogate> mSurrogate;
ParentNPObject* mRealObject;
};
class MOZ_STACK_CLASS PushSurrogateAcceptCalls
{
public:
explicit PushSurrogateAcceptCalls(PluginInstanceParent* aInstance);
~PushSurrogateAcceptCalls();
private:
PluginAsyncSurrogate* mSurrogate;
bool mPrevAcceptCallsState;
};
} // namespace plugins
} // namespace mozilla
#endif // dom_plugins_ipc_PluginAsyncSurrogate_h

Просмотреть файл

@ -28,7 +28,7 @@ class PPluginModuleParent;
bool
SetupBridge(uint32_t aPluginId, dom::ContentParent* aContentParent,
bool aForceBridgeNow, nsresult* aResult, uint32_t* aRunID,
nsresult* aResult, uint32_t* aRunID,
ipc::Endpoint<PPluginModuleParent>* aEndpoint);
nsresult

Просмотреть файл

@ -1,26 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef dom_plugins_ipc_PluginDataResolver_h
#define dom_plugins_ipc_PluginDataResolver_h
namespace mozilla {
namespace plugins {
class PluginAsyncSurrogate;
class PluginInstanceParent;
class PluginDataResolver
{
public:
virtual PluginAsyncSurrogate* GetAsyncSurrogate() = 0;
virtual PluginInstanceParent* GetInstance() = 0;
};
} // namespace plugins
} // namespace mozilla
#endif // dom_plugins_ipc_PluginDataResolver_h

Просмотреть файл

@ -2508,52 +2508,6 @@ PluginInstanceChild::AnswerNPP_NewStream(PBrowserStreamChild* actor,
return IPC_OK();
}
class NewStreamAsyncCall : public ChildAsyncCall
{
public:
NewStreamAsyncCall(PluginInstanceChild* aInstance,
BrowserStreamChild* aBrowserStreamChild,
const nsCString& aMimeType,
const bool aSeekable)
: ChildAsyncCall(aInstance, nullptr, nullptr)
, mBrowserStreamChild(aBrowserStreamChild)
, mMimeType(aMimeType)
, mSeekable(aSeekable)
{
}
NS_IMETHOD Run() override
{
RemoveFromAsyncList();
uint16_t stype = NP_NORMAL;
NPError rv = mInstance->DoNPP_NewStream(mBrowserStreamChild, mMimeType,
mSeekable, &stype);
DebugOnly<bool> sendOk =
mBrowserStreamChild->SendAsyncNPP_NewStreamResult(rv, stype);
MOZ_ASSERT(sendOk);
return NS_OK;
}
private:
BrowserStreamChild* mBrowserStreamChild;
const nsCString mMimeType;
const bool mSeekable;
};
mozilla::ipc::IPCResult
PluginInstanceChild::RecvAsyncNPP_NewStream(PBrowserStreamChild* actor,
const nsCString& mimeType,
const bool& seekable)
{
// Reusing ChildAsyncCall so that the task is cancelled properly on Destroy
BrowserStreamChild* child = static_cast<BrowserStreamChild*>(actor);
RefPtr<NewStreamAsyncCall> task =
new NewStreamAsyncCall(this, child, mimeType, seekable);
PostChildAsyncCall(task.forget());
return IPC_OK();
}
PBrowserStreamChild*
PluginInstanceChild::AllocPBrowserStreamChild(const nsCString& url,
const uint32_t& length,

Просмотреть файл

@ -165,12 +165,6 @@ protected:
NPError* rv,
uint16_t* stype) override;
virtual mozilla::ipc::IPCResult
RecvAsyncNPP_NewStream(
PBrowserStreamChild* actor,
const nsCString& mimeType,
const bool& seekable) override;
virtual PBrowserStreamChild*
AllocPBrowserStreamChild(const nsCString& url,
const uint32_t& length,

Просмотреть файл

@ -12,7 +12,6 @@
#include "mozilla/Telemetry.h"
#include "PluginInstanceParent.h"
#include "BrowserStreamParent.h"
#include "PluginAsyncSurrogate.h"
#include "PluginBackgroundDestroyer.h"
#include "PluginModuleParent.h"
#include "PluginStreamParent.h"
@ -115,8 +114,6 @@ PluginInstanceParent::PluginInstanceParent(PluginModuleParent* parent,
const nsCString& aMimeType,
const NPNetscapeFuncs* npniface)
: mParent(parent)
, mSurrogate(PluginAsyncSurrogate::Cast(npp))
, mUseSurrogate(true)
, mNPP(npp)
, mNPNIface(npniface)
, mWindowType(NPWindowTypeWindow)
@ -1223,12 +1220,6 @@ PluginInstanceParent::GetScrollCaptureContainer(ImageContainer** aContainer)
}
#endif // XP_WIN
PluginAsyncSurrogate*
PluginInstanceParent::GetAsyncSurrogate()
{
return mSurrogate;
}
bool
PluginInstanceParent::CreateBackground(const nsIntSize& aSize)
{
@ -1775,22 +1766,12 @@ PluginInstanceParent::NPP_NewStream(NPMIMEType type, NPStream* stream,
timer(Module()->GetHistogramKey());
NPError err = NPERR_NO_ERROR;
if (mParent->IsStartingAsync()) {
MOZ_ASSERT(mSurrogate);
mSurrogate->AsyncCallDeparting();
if (SendAsyncNPP_NewStream(bs, NullableString(type), seekable)) {
*stype = nsPluginStreamListenerPeer::STREAM_TYPE_UNKNOWN;
} else {
err = NPERR_GENERIC_ERROR;
}
} else {
bs->SetAlive();
if (!CallNPP_NewStream(bs, NullableString(type), seekable, &err, stype)) {
err = NPERR_GENERIC_ERROR;
}
if (NPERR_NO_ERROR != err) {
Unused << PBrowserStreamParent::Send__delete__(bs);
}
bs->SetAlive();
if (!CallNPP_NewStream(bs, NullableString(type), seekable, &err, stype)) {
err = NPERR_GENERIC_ERROR;
}
if (NPERR_NO_ERROR != err) {
Unused << PBrowserStreamParent::Send__delete__(bs);
}
return err;
@ -2051,42 +2032,6 @@ PluginInstanceParent::GetOwner()
return inst->GetOwner();
}
mozilla::ipc::IPCResult
PluginInstanceParent::RecvAsyncNPP_NewResult(const NPError& aResult)
{
// NB: mUseSurrogate must be cleared before doing anything else, especially
// calling NPP_SetWindow!
mUseSurrogate = false;
mSurrogate->AsyncCallArriving();
if (aResult == NPERR_NO_ERROR) {
mSurrogate->SetAcceptingCalls(true);
}
// It is possible for a plugin instance to outlive its owner (eg. When a
// PluginDestructionGuard was on the stack at the time the owner was being
// destroyed). We need to handle that case.
nsPluginInstanceOwner* owner = GetOwner();
if (!owner) {
// We can't do anything at this point, just return. Any pending browser
// streams will be cleaned up when the plugin instance is destroyed.
return IPC_OK();
}
if (aResult != NPERR_NO_ERROR) {
mSurrogate->NotifyAsyncInitFailed();
return IPC_OK();
}
// Now we need to do a bunch of exciting post-NPP_New housekeeping.
owner->NotifyHostCreateWidget();
MOZ_ASSERT(mSurrogate);
mSurrogate->OnInstanceCreated(this);
return IPC_OK();
}
mozilla::ipc::IPCResult
PluginInstanceParent::RecvSetNetscapeWindowAsParent(const NativeWindowHandle& childWindow)
{
@ -2335,28 +2280,21 @@ PluginInstanceParent::AnswerPluginFocusChange(const bool& gotFocus)
}
PluginInstanceParent*
PluginInstanceParent::Cast(NPP aInstance, PluginAsyncSurrogate** aSurrogate)
PluginInstanceParent::Cast(NPP aInstance)
{
PluginDataResolver* resolver =
static_cast<PluginDataResolver*>(aInstance->pdata);
auto ip = static_cast<PluginInstanceParent*>(aInstance->pdata);
// If the plugin crashed and the PluginInstanceParent was deleted,
// aInstance->pdata will be nullptr.
if (!resolver) {
if (!ip) {
return nullptr;
}
PluginInstanceParent* instancePtr = resolver->GetInstance();
if (instancePtr && aInstance != instancePtr->mNPP) {
if (aInstance != ip->mNPP) {
MOZ_CRASH("Corrupted plugin data.");
}
if (aSurrogate) {
*aSurrogate = resolver->GetAsyncSurrogate();
}
return instancePtr;
return ip;
}
mozilla::ipc::IPCResult

Просмотреть файл

@ -21,7 +21,6 @@
#include "nsDataHashtable.h"
#include "nsHashKeys.h"
#include "nsRect.h"
#include "PluginDataResolver.h"
#include "mozilla/Unused.h"
#include "mozilla/EventForwards.h"
@ -43,7 +42,6 @@ class PluginModuleParent;
class D3D11SurfaceHolder;
class PluginInstanceParent : public PPluginInstanceParent
, public PluginDataResolver
{
friend class PluginModuleParent;
friend class BrowserStreamParent;
@ -241,9 +239,6 @@ public:
virtual mozilla::ipc::IPCResult
RecvRedrawPlugin() override;
virtual mozilla::ipc::IPCResult
RecvAsyncNPP_NewResult(const NPError& aResult) override;
virtual mozilla::ipc::IPCResult
RecvSetNetscapeWindowAsParent(const NativeWindowHandle& childWindow) override;
@ -291,12 +286,6 @@ public:
return mNPP;
}
bool
UseSurrogate() const
{
return mUseSurrogate;
}
void
GetSrcAttribute(nsACString& aOutput) const
{
@ -327,12 +316,7 @@ public:
bool IsUsingDirectDrawing();
virtual PluginAsyncSurrogate* GetAsyncSurrogate() override;
virtual PluginInstanceParent* GetInstance() override { return this; }
static PluginInstanceParent* Cast(NPP instance,
PluginAsyncSurrogate** aSurrogate = nullptr);
static PluginInstanceParent* Cast(NPP instance);
// for IME hook
virtual mozilla::ipc::IPCResult
@ -382,8 +366,6 @@ private:
private:
PluginModuleParent* mParent;
RefPtr<PluginAsyncSurrogate> mSurrogate;
bool mUseSurrogate;
NPP mNPP;
const NPNetscapeFuncs* mNPNIface;
nsCString mSrcAttribute;

Просмотреть файл

@ -1842,16 +1842,6 @@ PluginModuleChild::AnswerNP_Initialize(const PluginSettings& aSettings, NPError*
return IPC_OK();
}
mozilla::ipc::IPCResult
PluginModuleChild::RecvAsyncNP_Initialize(const PluginSettings& aSettings)
{
NPError error = DoNP_Initialize(aSettings);
if (!SendNP_InitializeResult(error)) {
return IPC_FAIL_NO_REASON(this);
}
return IPC_OK();
}
NPError
PluginModuleChild::DoNP_Initialize(const PluginSettings& aSettings)
{
@ -2386,51 +2376,6 @@ PluginModuleChild::AnswerSyncNPP_New(PPluginInstanceChild* aActor, NPError* rv)
return IPC_OK();
}
class AsyncNewResultSender : public ChildAsyncCall
{
public:
AsyncNewResultSender(PluginInstanceChild* aInstance, NPError aResult)
: ChildAsyncCall(aInstance, nullptr, nullptr)
, mResult(aResult)
{
}
NS_IMETHOD Run() override
{
RemoveFromAsyncList();
DebugOnly<bool> sendOk = mInstance->SendAsyncNPP_NewResult(mResult);
MOZ_ASSERT(sendOk);
return NS_OK;
}
private:
NPError mResult;
};
static void
RunAsyncNPP_New(void* aChildInstance)
{
MOZ_ASSERT(aChildInstance);
PluginInstanceChild* childInstance =
static_cast<PluginInstanceChild*>(aChildInstance);
NPError rv = childInstance->DoNPP_New();
RefPtr<AsyncNewResultSender> task =
new AsyncNewResultSender(childInstance, rv);
childInstance->PostChildAsyncCall(task.forget());
}
mozilla::ipc::IPCResult
PluginModuleChild::RecvAsyncNPP_New(PPluginInstanceChild* aActor)
{
PLUGIN_LOG_DEBUG_METHOD;
PluginInstanceChild* childInstance =
reinterpret_cast<PluginInstanceChild*>(aActor);
AssertPluginThread();
// We don't want to run NPP_New async from within nested calls
childInstance->AsyncCall(&RunAsyncNPP_New, childInstance);
return IPC_OK();
}
bool
PluginModuleChild::DeallocPPluginInstanceChild(PPluginInstanceChild* aActor)
{

Просмотреть файл

@ -72,10 +72,8 @@ protected:
virtual mozilla::ipc::IPCResult RecvDisableFlashProtectedMode() override;
virtual mozilla::ipc::IPCResult AnswerNP_GetEntryPoints(NPError* rv) override;
virtual mozilla::ipc::IPCResult AnswerNP_Initialize(const PluginSettings& aSettings, NPError* rv) override;
virtual mozilla::ipc::IPCResult RecvAsyncNP_Initialize(const PluginSettings& aSettings) override;
virtual mozilla::ipc::IPCResult AnswerSyncNPP_New(PPluginInstanceChild* aActor, NPError* rv)
override;
virtual mozilla::ipc::IPCResult RecvAsyncNPP_New(PPluginInstanceChild* aActor) override;
virtual mozilla::ipc::IPCResult
RecvInitPluginModuleChild(Endpoint<PPluginModuleChild>&& endpoint) override;

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -47,7 +47,6 @@ namespace plugins {
//-----------------------------------------------------------------------------
class BrowserStreamParent;
class PluginAsyncSurrogate;
class PluginInstanceParent;
#ifdef XP_WIN
@ -94,16 +93,9 @@ protected:
DeallocPPluginInstanceParent(PPluginInstanceParent* aActor) override;
public:
explicit PluginModuleParent(bool aIsChrome, bool aAllowAsyncInit);
explicit PluginModuleParent(bool aIsChrome);
virtual ~PluginModuleParent();
bool RemovePendingSurrogate(const RefPtr<PluginAsyncSurrogate>& aSurrogate);
/** @return the state of the pref that controls async plugin init */
bool IsStartingAsync() const { return mIsStartingAsync; }
/** @return whether this modules NP_Initialize has successfully completed
executing */
bool IsInitialized() const { return mNPInitialized; }
bool IsChrome() const { return mIsChrome; }
virtual void SetPlugin(nsNPAPIPlugin* plugin) override
@ -123,8 +115,6 @@ public:
void ProcessRemoteNativeEventsInInterruptCall() override;
virtual bool WaitForIPCConnection() { return true; }
nsCString GetHistogramKey() const {
return mPluginName + mPluginVersion;
}
@ -180,11 +170,7 @@ protected:
virtual mozilla::ipc::IPCResult
RecvNPN_ReloadPlugins(const bool& aReloadPages) override;
virtual mozilla::ipc::IPCResult
RecvNP_InitializeResult(const NPError& aError) override;
static BrowserStreamParent* StreamCast(NPP instance, NPStream* s,
PluginAsyncSurrogate** aSurrogate = nullptr);
static BrowserStreamParent* StreamCast(NPP instance, NPStream* s);
virtual mozilla::ipc::IPCResult
AnswerNPN_SetValue_NPPVpluginRequiresAudioDeviceChanges(
@ -315,8 +301,6 @@ public:
virtual nsresult ContentsScaleFactorChanged(NPP instance, double aContentsScaleFactor) override;
#endif
void InitAsyncSurrogates();
layers::TextureClientRecycleAllocator* EnsureTextureAllocatorForDirectBitmap();
layers::TextureClientRecycleAllocator* EnsureTextureAllocatorForDXGISurface();
@ -324,7 +308,6 @@ protected:
void NotifyFlashHang();
void NotifyPluginCrashed();
void OnInitFailure();
bool MaybeRunDeferredShutdown();
bool DoShutdown(NPError* error);
bool GetSetting(NPNVariable aVariable);
@ -355,13 +338,6 @@ protected:
bool
GetPluginDetails();
friend class mozilla::plugins::PluginAsyncSurrogate;
bool mIsStartingAsync;
bool mNPInitialized;
bool mIsNPShutdownPending;
nsTArray<RefPtr<PluginAsyncSurrogate>> mSurrogateInstances;
nsresult mAsyncNewRv;
uint32_t mRunID;
RefPtr<layers::TextureClientRecycleAllocator> mTextureAllocatorForDirectBitmap;
@ -382,16 +358,10 @@ protected:
class PluginModuleContentParent : public PluginModuleParent
{
public:
explicit PluginModuleContentParent(bool aAllowAsyncInit);
explicit PluginModuleContentParent();
static PluginLibrary* LoadModule(uint32_t aPluginId, nsPluginTag* aPluginTag);
static void OnLoadPluginResult(const uint32_t& aPluginId,
const bool& aResult,
Endpoint<PPluginModuleParent>&& aEndpoint);
static void AssociatePluginId(uint32_t aPluginId, base::ProcessId aProcessId);
virtual ~PluginModuleContentParent();
#if defined(XP_WIN) || defined(XP_MACOSX)
@ -432,14 +402,6 @@ class PluginModuleChromeParent
static PluginLibrary* LoadModule(const char* aFilePath, uint32_t aPluginId,
nsPluginTag* aPluginTag);
/**
* The following two functions are called by SetupBridge to determine
* whether an existing plugin module was reused, or whether a new module
* was instantiated by the plugin host.
*/
static void ClearInstantiationFlag() { sInstantiated = false; }
static bool DidInstantiate() { return sInstantiated; }
virtual ~PluginModuleChromeParent();
/*
@ -535,17 +497,6 @@ class PluginModuleChromeParent
EvaluateHangUIState(const bool aReset);
#endif // XP_WIN
virtual bool WaitForIPCConnection() override;
virtual mozilla::ipc::IPCResult
RecvNP_InitializeResult(const NPError& aError) override;
void
SetContentParent(dom::ContentParent* aContentParent);
bool
SendAssociatePluginId();
void CachedSettingChanged();
virtual mozilla::ipc::IPCResult
@ -600,8 +551,7 @@ private:
// aFilePath is UTF8, not native!
explicit PluginModuleChromeParent(const char* aFilePath, uint32_t aPluginId,
int32_t aSandboxLevel,
bool aAllowAsyncInit);
int32_t aSandboxLevel);
void CleanupFromTimeout(const bool aByHangUI);
@ -657,8 +607,6 @@ private:
FinishHangUI();
#endif
friend class mozilla::plugins::PluginAsyncSurrogate;
#ifdef MOZ_CRASHREPORTER_INJECTOR
friend class mozilla::plugins::FinishInjectorInitTask;
@ -696,17 +644,8 @@ private:
friend class LaunchedTask;
bool mInitOnAsyncConnect;
nsresult mAsyncInitRv;
NPError mAsyncInitError;
// mContentParent is to be used ONLY during the IPC dance that occurs
// when ContentParent::RecvLoadPlugin is called under async plugin init!
// In other contexts it is *unsafe*, as there might be multiple content
// processes in existence!
dom::ContentParent* mContentParent;
nsCOMPtr<nsIObserver> mPluginOfflineObserver;
bool mIsBlocklisted;
static bool sInstantiated;
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
mozilla::SandboxPermissions mSandboxPermissions;
#endif

Просмотреть файл

@ -32,7 +32,6 @@ PluginProcessParent::PluginProcessParent(const std::string& aPluginFilePath) :
, mPluginFilePath(aPluginFilePath)
, mTaskFactory(this)
, mMainMsgLoop(MessageLoop::current())
, mRunCompleteTaskImmediately(false)
#ifdef XP_WIN
, mChildPid(0)
#endif
@ -130,12 +129,6 @@ PluginProcessParent::Delete()
&PluginProcessParent::Delete));
}
void
PluginProcessParent::SetCallRunnableImmediately(bool aCallImmediately)
{
mRunCompleteTaskImmediately = aCallImmediately;
}
/**
* This function exists so that we may provide an additional level of
* indirection between the task being posted to main event loop (a
@ -156,7 +149,7 @@ bool
PluginProcessParent::WaitUntilConnected(int32_t aTimeoutMs)
{
bool result = GeckoChildProcessHost::WaitUntilConnected(aTimeoutMs);
if (mRunCompleteTaskImmediately && mLaunchCompleteTask) {
if (mLaunchCompleteTask) {
if (result) {
mLaunchCompleteTask->SetLaunchSucceeded();
}
@ -177,21 +170,12 @@ PluginProcessParent::OnChannelConnected(int32_t peer_pid)
#endif
GeckoChildProcessHost::OnChannelConnected(peer_pid);
if (mLaunchCompleteTask && !mRunCompleteTaskImmediately) {
mLaunchCompleteTask->SetLaunchSucceeded();
mMainMsgLoop->PostTask(mTaskFactory.NewRunnableMethod(
&PluginProcessParent::RunLaunchCompleteTask));
}
}
void
PluginProcessParent::OnChannelError()
{
GeckoChildProcessHost::OnChannelError();
if (mLaunchCompleteTask && !mRunCompleteTaskImmediately) {
mMainMsgLoop->PostTask(mTaskFactory.NewRunnableMethod(
&PluginProcessParent::RunLaunchCompleteTask));
}
}
bool

Просмотреть файл

@ -68,7 +68,6 @@ public:
using mozilla::ipc::GeckoChildProcessHost::GetChannel;
void SetCallRunnableImmediately(bool aCallImmediately);
virtual bool WaitUntilConnected(int32_t aTimeoutMs = 0) override;
virtual void OnChannelConnected(int32_t peer_pid) override;
@ -85,7 +84,6 @@ private:
ipc::TaskFactory<PluginProcessParent> mTaskFactory;
UniquePtr<LaunchCompleteTask> mLaunchCompleteTask;
MessageLoop* mMainMsgLoop;
bool mRunCompleteTaskImmediately;
#ifdef XP_WIN
typedef nsTHashtable<nsUint32HashKey> PidSet;
// Set of PIDs for all plugin child processes or NULL if empty.

Просмотреть файл

@ -12,7 +12,6 @@
#include "mozilla/plugins/PluginTypes.h"
#include "mozilla/Unused.h"
#include "nsNPAPIPlugin.h"
#include "PluginAsyncSurrogate.h"
#include "PluginScriptableObjectUtils.h"
using namespace mozilla;
@ -111,7 +110,6 @@ inline void
ReleaseVariant(NPVariant& aVariant,
PluginInstanceParent* aInstance)
{
PushSurrogateAcceptCalls acceptCalls(aInstance);
const NPNetscapeFuncs* npn = GetNetscapeFuncs(aInstance);
if (npn) {
npn->releasevariantvalue(&aVariant);
@ -654,7 +652,6 @@ PluginScriptableObjectParent::CreateProxyObject()
NS_ASSERTION(mInstance, "Must have an instance!");
NS_ASSERTION(mType == Proxy, "Shouldn't call this for non-proxy object!");
PushSurrogateAcceptCalls acceptCalls(mInstance);
const NPNetscapeFuncs* npn = GetNetscapeFuncs(mInstance);
NPObject* npobject = npn->createobject(mInstance->GetNPP(),
@ -773,7 +770,6 @@ PluginScriptableObjectParent::AnswerHasMethod(const PluginIdentifier& aId,
return IPC_OK();
}
PushSurrogateAcceptCalls acceptCalls(instance);
const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance);
if (!npn) {
NS_ERROR("No netscape funcs?!");
@ -814,7 +810,6 @@ PluginScriptableObjectParent::AnswerInvoke(const PluginIdentifier& aId,
return IPC_OK();
}
PushSurrogateAcceptCalls acceptCalls(instance);
const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance);
if (!npn) {
NS_ERROR("No netscape funcs?!");
@ -904,7 +899,6 @@ PluginScriptableObjectParent::AnswerInvokeDefault(InfallibleTArray<Variant>&& aA
return IPC_OK();
}
PushSurrogateAcceptCalls acceptCalls(instance);
const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance);
if (!npn) {
NS_ERROR("No netscape funcs?!");
@ -985,7 +979,6 @@ PluginScriptableObjectParent::AnswerHasProperty(const PluginIdentifier& aId,
return IPC_OK();
}
PushSurrogateAcceptCalls acceptCalls(instance);
const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance);
if (!npn) {
NS_ERROR("No netscape funcs?!");
@ -1028,7 +1021,6 @@ PluginScriptableObjectParent::AnswerGetParentProperty(
return IPC_OK();
}
PushSurrogateAcceptCalls acceptCalls(instance);
const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance);
if (!npn) {
NS_ERROR("No netscape funcs?!");
@ -1085,7 +1077,6 @@ PluginScriptableObjectParent::AnswerSetProperty(const PluginIdentifier& aId,
return IPC_OK();
}
PushSurrogateAcceptCalls acceptCalls(instance);
const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance);
if (!npn) {
NS_ERROR("No netscape funcs?!");
@ -1132,7 +1123,6 @@ PluginScriptableObjectParent::AnswerRemoveProperty(const PluginIdentifier& aId,
return IPC_OK();
}
PushSurrogateAcceptCalls acceptCalls(instance);
const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance);
if (!npn) {
NS_ERROR("No netscape funcs?!");
@ -1171,7 +1161,6 @@ PluginScriptableObjectParent::AnswerEnumerate(InfallibleTArray<PluginIdentifier>
return IPC_OK();
}
PushSurrogateAcceptCalls acceptCalls(instance);
const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance);
if (!npn) {
NS_WARNING("No netscape funcs?!");
@ -1224,7 +1213,6 @@ PluginScriptableObjectParent::AnswerConstruct(InfallibleTArray<Variant>&& aArgs,
return IPC_OK();
}
PushSurrogateAcceptCalls acceptCalls(instance);
const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance);
if (!npn) {
NS_ERROR("No netscape funcs?!");
@ -1317,7 +1305,6 @@ PluginScriptableObjectParent::AnswerNPN_Evaluate(const nsCString& aScript,
return IPC_OK();
}
PushSurrogateAcceptCalls acceptCalls(instance);
const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance);
if (!npn) {
NS_ERROR("No netscape funcs?!");

Просмотреть файл

@ -18,7 +18,6 @@ struct PluginTag
nsCString[] extensions;
bool isJavaPlugin;
bool isFlashPlugin;
bool supportsAsyncInit;
bool supportsAsyncRender; // flash specific
nsCString filename;
nsCString version;

Просмотреть файл

@ -21,9 +21,7 @@ EXPORTS.mozilla.plugins += [
'NPEventOSX.h',
'NPEventUnix.h',
'NPEventWindows.h',
'PluginAsyncSurrogate.h',
'PluginBridge.h',
'PluginDataResolver.h',
'PluginInstanceChild.h',
'PluginInstanceParent.h',
'PluginMessageUtils.h',
@ -70,7 +68,6 @@ UNIFIED_SOURCES += [
'BrowserStreamParent.cpp',
'ChildAsyncCall.cpp',
'ChildTimer.cpp',
'PluginAsyncSurrogate.cpp',
'PluginBackgroundDestroyer.cpp',
'PluginInstanceParent.cpp',
'PluginMessageUtils.cpp',

Просмотреть файл

@ -754,10 +754,14 @@ private:
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIPrincipal> triggeringPrincipal = workerPrivate->GetPrincipal();
MOZ_DIAGNOSTIC_ASSERT(triggeringPrincipal);
nsCOMPtr<mozIDOMWindowProxy> win;
rv = bwin->OpenURI(uri, nullptr,
nsIBrowserDOMWindow::OPEN_DEFAULTWINDOW,
nsIBrowserDOMWindow::OPEN_NEW,
triggeringPrincipal,
getter_AddRefs(win));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;

Просмотреть файл

@ -165,7 +165,7 @@ public:
void ClearById(const uint64_t& aId);
private:
~CompositorAnimationStorage() { Clear(); };
~CompositorAnimationStorage() { };
private:
AnimatedValueTable mAnimatedValues;

Просмотреть файл

@ -6,7 +6,11 @@
#include "PaintThread.h"
#include "base/task.h"
#include "gfxPrefs.h"
#include "mozilla/layers/CompositorBridgeChild.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/Preferences.h"
#include "mozilla/SyncRunnable.h"
namespace mozilla {
@ -15,6 +19,8 @@ namespace layers {
using namespace gfx;
StaticAutoPtr<PaintThread> PaintThread::sSingleton;
StaticRefPtr<nsIThread> PaintThread::sThread;
PlatformThreadId PaintThread::sThreadId;
void
PaintThread::Release()
@ -30,24 +36,25 @@ void
PaintThread::InitOnPaintThread()
{
MOZ_ASSERT(!NS_IsMainThread());
mThreadId = PlatformThread::CurrentId();
sThreadId = PlatformThread::CurrentId();
}
bool
PaintThread::Init()
{
MOZ_ASSERT(NS_IsMainThread());
nsresult rv = NS_NewNamedThread("PaintThread", getter_AddRefs(mThread));
RefPtr<nsIThread> thread;
nsresult rv = NS_NewNamedThread("PaintThread", getter_AddRefs(thread));
if (NS_FAILED(rv)) {
return false;
}
sThread = thread;
nsCOMPtr<nsIRunnable> paintInitTask =
NewRunnableMethod("PaintThread::InitOnPaintThread",
this, &PaintThread::InitOnPaintThread);
SyncRunnable::DispatchToThread(PaintThread::sSingleton->mThread, paintInitTask);
SyncRunnable::DispatchToThread(sThread, paintInitTask);
return true;
}
@ -69,49 +76,84 @@ PaintThread::Get()
return PaintThread::sSingleton.get();
}
void
DestroyPaintThread(UniquePtr<PaintThread>&& pt)
{
MOZ_ASSERT(PaintThread::IsOnPaintThread());
pt->ShutdownOnPaintThread();
}
/* static */ void
PaintThread::Shutdown()
{
if (!PaintThread::sSingleton) {
MOZ_ASSERT(NS_IsMainThread());
UniquePtr<PaintThread> pt(sSingleton.forget());
if (!pt) {
return;
}
PaintThread::sSingleton->ShutdownImpl();
PaintThread::sSingleton = nullptr;
sThread->Dispatch(NewRunnableFunction(DestroyPaintThread, Move(pt)));
sThread->Shutdown();
sThread = nullptr;
}
void
PaintThread::ShutdownImpl()
PaintThread::ShutdownOnPaintThread()
{
MOZ_ASSERT(NS_IsMainThread());
PaintThread::sSingleton->mThread->AsyncShutdown();
MOZ_ASSERT(IsOnPaintThread());
}
bool
/* static */ bool
PaintThread::IsOnPaintThread()
{
MOZ_ASSERT(mThread);
return PlatformThread::CurrentId() == mThreadId;
return sThreadId == PlatformThread::CurrentId();
}
void
PaintThread::PaintContentsAsync(CompositorBridgeChild* aBridge,
gfx::DrawTargetCapture* aCapture,
gfx::DrawTarget* aTarget)
{
MOZ_ASSERT(IsOnPaintThread());
// Draw all the things into the actual dest target.
aTarget->DrawCapturedDT(aCapture, Matrix());
if (aBridge) {
aBridge->NotifyFinishedAsyncPaint();
}
}
void
PaintThread::PaintContents(DrawTargetCapture* aCapture,
DrawTarget* aTarget)
{
if (!IsOnPaintThread()) {
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsIRunnable> paintTask =
NewRunnableMethod<DrawTargetCapture*, DrawTarget*>("PaintThread::PaintContents",
this,
&PaintThread::PaintContents,
aCapture, aTarget);
MOZ_ASSERT(NS_IsMainThread());
SyncRunnable::DispatchToThread(mThread, paintTask);
return;
// If painting asynchronously, we need to acquire the compositor bridge which
// owns the underlying MessageChannel. Otherwise we leave it null and use
// synchronous dispatch.
RefPtr<CompositorBridgeChild> cbc;
if (!gfxPrefs::LayersOMTPForceSync()) {
cbc = CompositorBridgeChild::Get();
cbc->NotifyBeginAsyncPaint();
}
RefPtr<DrawTargetCapture> capture(aCapture);
RefPtr<DrawTarget> target(aTarget);
// Draw all the things into the actual dest target.
aTarget->DrawCapturedDT(aCapture, Matrix());
RefPtr<PaintThread> self = this;
RefPtr<Runnable> task = NS_NewRunnableFunction("PaintThread::PaintContents",
[self, cbc, capture, target]() -> void
{
self->PaintContentsAsync(cbc, capture, target);
});
if (cbc) {
sThread->Dispatch(task.forget());
} else {
SyncRunnable::DispatchToThread(sThread, task);
}
}
} // namespace layers

Просмотреть файл

@ -9,6 +9,7 @@
#include "base/platform_thread.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/UniquePtr.h"
#include "nsThreadUtils.h"
namespace mozilla {
@ -19,14 +20,19 @@ class DrawTargetCapture;
namespace layers {
class CompositorBridgeChild;
class PaintThread final
{
friend void DestroyPaintThread(UniquePtr<PaintThread>&& aPaintThread);
public:
static void Start();
static void Shutdown();
static PaintThread* Get();
void PaintContents(gfx::DrawTargetCapture* aCapture,
gfx::DrawTarget* aTarget);
// Sync Runnables need threads to be ref counted,
// But this thread lives through the whole process.
// We're only temporarily using sync runnables so
@ -34,15 +40,20 @@ public:
void Release();
void AddRef();
// Helper for asserts.
static bool IsOnPaintThread();
private:
bool IsOnPaintThread();
bool Init();
void ShutdownImpl();
void ShutdownOnPaintThread();
void InitOnPaintThread();
void PaintContentsAsync(CompositorBridgeChild* aBridge,
gfx::DrawTargetCapture* aCapture,
gfx::DrawTarget* aTarget);
static StaticAutoPtr<PaintThread> sSingleton;
RefPtr<nsIThread> mThread;
PlatformThreadId mThreadId;
static StaticRefPtr<nsIThread> sThread;
static PlatformThreadId sThreadId;
};
} // namespace layers

Просмотреть файл

@ -226,6 +226,9 @@ ClientLayerManager::CreateReadbackLayer()
bool
ClientLayerManager::BeginTransactionWithTarget(gfxContext* aTarget)
{
// Wait for any previous async paints to complete before starting to paint again.
GetCompositorBridgeChild()->FlushAsyncPaints();
MOZ_ASSERT(mForwarder, "ClientLayerManager::BeginTransaction without forwarder");
if (!mForwarder->IPCOpen()) {
gfxCriticalNote << "ClientLayerManager::BeginTransaction with IPC channel down. GPU process may have died.";

Просмотреть файл

@ -313,6 +313,7 @@ public:
virtual already_AddRefed<RefLayer> CreateRefLayer() override;
virtual bool AreComponentAlphaLayersEnabled() override;
virtual bool SupportsBackdropCopyForComponentAlpha() override { return false; }
virtual already_AddRefed<DrawTarget>
CreateOptimalMaskDrawTarget(const IntSize &aSize) override;
@ -514,7 +515,7 @@ private:
#endif
#if defined(MOZ_WIDGET_ANDROID)
public:
virtual void RequestScreenPixels(UiCompositorControllerParent* aController)
virtual void RequestScreenPixels(UiCompositorControllerParent* aController) override
{
mScreenPixelsTarget = aController;
}

Просмотреть файл

@ -19,6 +19,7 @@
#include "mozilla/layers/IAPZCTreeManager.h"
#include "mozilla/layers/APZCTreeManagerChild.h"
#include "mozilla/layers/LayerTransactionChild.h"
#include "mozilla/layers/PaintThread.h"
#include "mozilla/layers/PLayerTransactionChild.h"
#include "mozilla/layers/PTextureChild.h"
#include "mozilla/layers/TextureClient.h"// for TextureClient
@ -89,6 +90,9 @@ CompositorBridgeChild::CompositorBridgeChild(CompositorManagerChild *aManager)
, mMessageLoop(MessageLoop::current())
, mProcessToken(0)
, mSectionAllocator(nullptr)
, mPaintLock("CompositorBridgeChild.mPaintLock")
, mOutstandingAsyncPaints(0)
, mIsWaitingForPaint(false)
{
MOZ_ASSERT(NS_IsMainThread());
}
@ -542,8 +546,20 @@ CompositorBridgeChild::ActorDestroy(ActorDestroyReason aWhy)
gfxCriticalNote << "Receive IPC close with reason=AbnormalShutdown";
}
mCanSend = false;
mActorDestroyed = true;
{
// We take the lock to update these fields, since they are read from the
// paint thread. We don't need the lock to init them, since that happens
// on the main thread before the paint thread can ever grab a reference
// to the CompositorBridge object.
//
// Note that it is useful to take this lock for one other reason: It also
// tells us whether GetIPCChannel is safe to call. If we access the IPC
// channel within this lock, when mCanSend is true, then we know it has not
// been zapped by IPDL.
MonitorAutoLock lock(mPaintLock);
mCanSend = false;
mActorDestroyed = true;
}
if (mProcessToken && XRE_IsParentProcess()) {
GPUProcessManager::Get()->NotifyRemoteActorDestroyed(mProcessToken);
@ -1114,6 +1130,86 @@ CompositorBridgeChild::GetNextPipelineId()
return wr::AsPipelineId(GetNextResourceId());
}
void
CompositorBridgeChild::NotifyBeginAsyncPaint()
{
MOZ_ASSERT(NS_IsMainThread());
MonitorAutoLock lock(mPaintLock);
// We must not be waiting for paints to complete yet. This would imply we
// started a new paint without waiting for a previous one, which could lead to
// incorrect rendering or IPDL deadlocks.
MOZ_ASSERT(!mIsWaitingForPaint);
mOutstandingAsyncPaints++;
}
void
CompositorBridgeChild::NotifyFinishedAsyncPaint()
{
MOZ_ASSERT(PaintThread::IsOnPaintThread());
MonitorAutoLock lock(mPaintLock);
mOutstandingAsyncPaints--;
// It's possible that we painted so fast that the main thread never reached
// the code that starts delaying messages. If so, mIsWaitingForPaint will be
// false, and we can safely return.
if (mIsWaitingForPaint && mOutstandingAsyncPaints == 0) {
ResumeIPCAfterAsyncPaint();
// Notify the main thread in case it's blocking. We do this unconditionally
// to avoid deadlocking.
lock.Notify();
}
}
void
CompositorBridgeChild::PostponeMessagesIfAsyncPainting()
{
MOZ_ASSERT(NS_IsMainThread());
MonitorAutoLock lock(mPaintLock);
MOZ_ASSERT(!mIsWaitingForPaint);
if (mOutstandingAsyncPaints > 0) {
mIsWaitingForPaint = true;
GetIPCChannel()->BeginPostponingSends();
}
}
void
CompositorBridgeChild::ResumeIPCAfterAsyncPaint()
{
// Note: the caller is responsible for holding the lock.
mPaintLock.AssertCurrentThreadOwns();
MOZ_ASSERT(PaintThread::IsOnPaintThread());
MOZ_ASSERT(mOutstandingAsyncPaints == 0);
MOZ_ASSERT(mIsWaitingForPaint);
mIsWaitingForPaint = false;
// It's also possible that the channel has shut down already.
if (!mCanSend || mActorDestroyed) {
return;
}
GetIPCChannel()->StopPostponingSends();
}
void
CompositorBridgeChild::FlushAsyncPaints()
{
MOZ_ASSERT(NS_IsMainThread());
MonitorAutoLock lock(mPaintLock);
while (mIsWaitingForPaint) {
lock.Wait();
}
}
} // namespace layers
} // namespace mozilla

Просмотреть файл

@ -10,6 +10,7 @@
#include "base/basictypes.h" // for DISALLOW_EVIL_CONSTRUCTORS
#include "mozilla/Assertions.h" // for MOZ_ASSERT_HELPER2
#include "mozilla/Attributes.h" // for override
#include "mozilla/Monitor.h"
#include "mozilla/ipc/ProtocolUtils.h"
#include "mozilla/layers/PCompositorBridgeChild.h"
#include "mozilla/layers/TextureForwarder.h" // for TextureForwarder
@ -220,10 +221,33 @@ public:
wr::PipelineId GetNextPipelineId();
// Must only be called from the main thread. Notifies the CompositorBridge
// that the paint thread is going to begin painting asynchronously.
void NotifyBeginAsyncPaint();
// Must only be called from the paint thread. Notifies the CompositorBridge
// that the paint thread has finished an asynchronous paint request.
void NotifyFinishedAsyncPaint();
// Must only be called from the main thread. Notifies the CompoistorBridge
// that a transaction is about to be sent, and if the paint thread is
// currently painting, to begin delaying IPC messages.
void PostponeMessagesIfAsyncPainting();
// Must only be called from the main thread. Ensures that any paints from
// previous frames have been flushed. The main thread blocks until the
// operation completes.
void FlushAsyncPaints();
private:
// Private destructor, to discourage deletion outside of Release():
virtual ~CompositorBridgeChild();
// Must only be called from the paint thread. If the main thread is delaying
// IPC messages, this forwards all such delayed IPC messages to the I/O thread
// and resumes IPC.
void ResumeIPCAfterAsyncPaint();
void AfterDestroy();
virtual PLayerTransactionChild*
@ -328,6 +352,20 @@ private:
uint64_t mProcessToken;
FixedSizeSmallShmemSectionAllocator* mSectionAllocator;
// Off-Main-Thread Painting state. This covers access to the OMTP-related
// state below.
Monitor mPaintLock;
// Contains the number of outstanding asynchronous paints tied to a
// PLayerTransaction on this bridge. This is R/W on both the main and paint
// threads, and must be accessed within the paint lock.
size_t mOutstandingAsyncPaints;
// True if this CompositorBridge is currently delaying its messages until the
// paint thread completes. This is R/W on both the main and paint threads, and
// must be accessed within the paint lock.
bool mIsWaitingForPaint;
};
} // namespace layers

Просмотреть файл

@ -1515,14 +1515,14 @@ CompositorBridgeParent::AllocPLayerTransactionParent(const nsTArray<LayersBacken
if (!mLayerManager) {
NS_WARNING("Failed to initialise Compositor");
LayerTransactionParent* p = new LayerTransactionParent(nullptr, this, 0);
LayerTransactionParent* p = new LayerTransactionParent(/* aManager */ nullptr, this, /* aAnimStorage */ nullptr, 0);
p->AddIPDLReference();
return p;
}
mCompositionManager = new AsyncCompositionManager(this, mLayerManager);
LayerTransactionParent* p = new LayerTransactionParent(mLayerManager, this, 0);
LayerTransactionParent* p = new LayerTransactionParent(mLayerManager, this, GetAnimationStorage(0), 0);
p->AddIPDLReference();
return p;
}
@ -1644,7 +1644,7 @@ CompositorBridgeParent::RecvAdoptChild(const uint64_t& child)
MOZ_ASSERT(sIndirectLayerTrees[child].mParent->mOptions == mOptions);
NotifyChildCreated(child);
if (sIndirectLayerTrees[child].mLayerTree) {
sIndirectLayerTrees[child].mLayerTree->SetLayerManager(mLayerManager);
sIndirectLayerTrees[child].mLayerTree->SetLayerManager(mLayerManager, GetAnimationStorage(0));
// Trigger composition to handle a case that mLayerTree was not composited yet
// by previous CompositorBridgeParent, since nsRefreshDriver might wait composition complete.
ScheduleComposition();

Просмотреть файл

@ -88,14 +88,15 @@ CrossProcessCompositorBridgeParent::AllocPLayerTransactionParent(
if (state && state->mLayerManager) {
state->mCrossProcessParent = this;
HostLayerManager* lm = state->mLayerManager;
LayerTransactionParent* p = new LayerTransactionParent(lm, this, aId);
CompositorAnimationStorage* animStorage = state->mParent ? state->mParent->GetAnimationStorage(0) : nullptr;
LayerTransactionParent* p = new LayerTransactionParent(lm, this, animStorage, aId);
p->AddIPDLReference();
sIndirectLayerTrees[aId].mLayerTree = p;
return p;
}
NS_WARNING("Created child without a matching parent?");
LayerTransactionParent* p = new LayerTransactionParent(nullptr, this, aId);
LayerTransactionParent* p = new LayerTransactionParent(/* aManager */ nullptr, this, /* aAnimStorage */ nullptr, aId);
p->AddIPDLReference();
return p;
}

Просмотреть файл

@ -51,9 +51,11 @@ namespace layers {
// LayerTransactionParent
LayerTransactionParent::LayerTransactionParent(HostLayerManager* aManager,
CompositorBridgeParentBase* aBridge,
CompositorAnimationStorage* aAnimStorage,
uint64_t aId)
: mLayerManager(aManager)
, mCompositorBridge(aBridge)
, mAnimStorage(aAnimStorage)
, mId(aId)
, mChildEpoch(0)
, mParentEpoch(0)
@ -68,13 +70,21 @@ LayerTransactionParent::~LayerTransactionParent()
}
void
LayerTransactionParent::SetLayerManager(HostLayerManager* aLayerManager)
LayerTransactionParent::SetLayerManager(HostLayerManager* aLayerManager, CompositorAnimationStorage* aAnimStorage)
{
if (mDestroyed) {
return;
}
mLayerManager = aLayerManager;
for (auto iter = mLayerMap.Iter(); !iter.Done(); iter.Next()) {
auto layer = iter.Data();
if (mAnimStorage &&
layer->GetCompositorAnimationsId()) {
mAnimStorage->ClearById(layer->GetCompositorAnimationsId());
}
layer->AsHostLayer()->SetLayerManager(aLayerManager);
}
mAnimStorage = aAnimStorage;
}
mozilla::ipc::IPCResult
@ -101,7 +111,16 @@ LayerTransactionParent::Destroy()
return;
}
mDestroyed = true;
if (mAnimStorage) {
for (auto iter = mLayerMap.Iter(); !iter.Done(); iter.Next()) {
auto layer = iter.Data();
if (layer->GetCompositorAnimationsId()) {
mAnimStorage->ClearById(layer->GetCompositorAnimationsId());
}
}
}
mCompositables.clear();
mAnimStorage = nullptr;
}
class MOZ_STACK_CLASS AutoLayerTransactionParentAsyncMessageSender
@ -535,14 +554,10 @@ LayerTransactionParent::SetLayerAttributes(const OpSetLayerAttributes& aOp)
layer->SetCompositorAnimations(common.compositorAnimations());
// Clean up the Animations by id in the CompositorAnimationStorage
// if there are no active animations on the layer
if (layer->GetCompositorAnimationsId() &&
if (mAnimStorage &&
layer->GetCompositorAnimationsId() &&
layer->GetAnimations().IsEmpty()) {
CompositorAnimationStorage* storage =
mCompositorBridge->GetAnimationStorage(GetId());
if (storage) {
storage->ClearById(layer->GetCompositorAnimationsId());
}
mAnimStorage->ClearById(layer->GetCompositorAnimationsId());
}
if (common.scrollMetadata() != layer->GetAllScrollMetadata()) {
UpdateHitTestingTree(layer, "scroll metadata changed");
@ -727,14 +742,11 @@ LayerTransactionParent::RecvGetAnimationOpacity(const uint64_t& aCompositorAnima
mCompositorBridge->ApplyAsyncProperties(this);
CompositorAnimationStorage* storage =
mCompositorBridge->GetAnimationStorage(GetId());
if (!storage) {
if (!mAnimStorage) {
return IPC_FAIL_NO_REASON(this);
}
Maybe<float> opacity = storage->GetAnimationOpacity(aCompositorAnimationsId);
Maybe<float> opacity = mAnimStorage->GetAnimationOpacity(aCompositorAnimationsId);
if (opacity) {
*aOpacity = *opacity;
*aHasAnimationOpacity = true;
@ -756,14 +768,11 @@ LayerTransactionParent::RecvGetAnimationTransform(const uint64_t& aCompositorAni
// the value.
mCompositorBridge->ApplyAsyncProperties(this);
CompositorAnimationStorage* storage =
mCompositorBridge->GetAnimationStorage(GetId());
if (!storage) {
if (!mAnimStorage) {
return IPC_FAIL_NO_REASON(this);
}
Maybe<Matrix4x4> transform = storage->GetAnimationTransform(aCompositorAnimationsId);
Maybe<Matrix4x4> transform = mAnimStorage->GetAnimationTransform(aCompositorAnimationsId);
if (transform) {
*aTransform = *transform;
} else {
@ -1008,6 +1017,10 @@ LayerTransactionParent::RecvReleaseLayer(const LayerHandle& aHandle)
if (!aHandle || !mLayerMap.Remove(aHandle.Value(), getter_AddRefs(layer))) {
return IPC_FAIL_NO_REASON(this);
}
if (mAnimStorage &&
layer->GetCompositorAnimationsId()) {
mAnimStorage->ClearById(layer->GetCompositorAnimationsId());
}
layer->Disconnect();
return IPC_OK();
}

Просмотреть файл

@ -33,6 +33,7 @@ class Layer;
class HostLayerManager;
class ShadowLayerParent;
class CompositableParent;
class CompositorAnimationStorage;
class CompositorBridgeParentBase;
class LayerTransactionParent final : public PLayerTransactionParent,
@ -48,6 +49,7 @@ class LayerTransactionParent final : public PLayerTransactionParent,
public:
LayerTransactionParent(HostLayerManager* aManager,
CompositorBridgeParentBase* aBridge,
CompositorAnimationStorage* aAnimStorage,
uint64_t aId);
protected:
@ -58,7 +60,7 @@ public:
HostLayerManager* layer_manager() const { return mLayerManager; }
void SetLayerManager(HostLayerManager* aLayerManager);
void SetLayerManager(HostLayerManager* aLayerManager, CompositorAnimationStorage* aAnimStorage);
uint64_t GetId() const { return mId; }
Layer* GetRoot() const { return mRoot; }
@ -174,6 +176,7 @@ private:
private:
RefPtr<HostLayerManager> mLayerManager;
CompositorBridgeParentBase* mCompositorBridge;
RefPtr<CompositorAnimationStorage> mAnimStorage;
// Hold the root because it might be grafted under various
// containers in the "real" layer tree

Просмотреть файл

@ -764,6 +764,10 @@ ShadowLayerForwarder::EndTransaction(const nsIntRegion& aRegionToClear,
}
}
// We delay at the last possible minute, to give the paint thread a chance to
// finish. If it does we don't have to delay messages at all.
GetCompositorBridgeChild()->PostponeMessagesIfAsyncPainting();
MOZ_LAYERS_LOG(("[LayersForwarder] sending transaction..."));
RenderTraceScope rendertrace3("Forward Transaction", "000093");
if (!mShadowManager->SendUpdate(info)) {

Просмотреть файл

@ -348,6 +348,10 @@ ShaderRenderPass::SetupPSBuffer0(float aOpacity)
void
ShaderRenderPass::ExecuteRendering()
{
if (mVertices.IsEmpty() && mInstances.IsEmpty()) {
return;
}
mDevice->SetPSConstantBuffer(0, &mPSBuffer0);
if (MaskOperation* mask = GetMask()) {
mDevice->SetPSTexture(kMaskLayerTextureSlot, mask->GetTexture());
@ -881,6 +885,10 @@ RenderViewPass::AddToPass(LayerMLGPU* aLayer, ItemInfo& aInfo)
}
mSource = mAssignedLayer->GetRenderTarget();
if (!mSource) {
return false;
}
mParentView = aInfo.view;
Txn txn(this);

Просмотреть файл

@ -127,14 +127,14 @@ public:
virtual gfxFontEntry* LookupLocalFont(const nsAString& aFontName,
uint16_t aWeight,
int16_t aStretch,
uint8_t aStyle);
uint8_t aStyle) override;
virtual gfxFontEntry* MakePlatformFont(const nsAString& aFontName,
uint16_t aWeight,
int16_t aStretch,
uint8_t aStyle,
const uint8_t* aFontData,
uint32_t aLength);
uint32_t aLength) override;
void GetSystemFontList(InfallibleTArray<FontListEntry>* retValue);
@ -142,7 +142,7 @@ public:
return static_cast<gfxFT2FontList*>(gfxPlatformFontList::PlatformFontList());
}
virtual void GetFontFamilyList(nsTArray<RefPtr<gfxFontFamily> >& aFamilyArray);
virtual void GetFontFamilyList(nsTArray<RefPtr<gfxFontFamily> >& aFamilyArray) override;
void WillShutdown();

Просмотреть файл

@ -585,6 +585,7 @@ private:
DECL_GFX_PREF(Once, "layers.mlgpu.enable-container-resizing", AdvancedLayersEnableContainerResizing, bool, true);
DECL_GFX_PREF(Once, "layers.offmainthreadcomposition.force-disabled", LayersOffMainThreadCompositionForceDisabled, bool, false);
DECL_GFX_PREF(Live, "layers.offmainthreadcomposition.frame-rate", LayersCompositionFrameRate, int32_t,-1);
DECL_GFX_PREF(Live, "layers.omtp.force-sync", LayersOMTPForceSync, bool, true);
DECL_GFX_PREF(Live, "layers.orientation.sync.timeout", OrientationSyncMillis, uint32_t, (uint32_t)0);
DECL_GFX_PREF(Once, "layers.prefer-opengl", LayersPreferOpenGL, bool, false);
DECL_GFX_PREF(Live, "layers.progressive-paint", ProgressivePaint, bool, false);

Просмотреть файл

@ -541,7 +541,7 @@ public:
void AddProxy(imgRequestProxy* aProxy);
NS_DECL_ISUPPORTS
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER
NS_DECL_NSISTREAMLISTENER
NS_DECL_NSIREQUESTOBSERVER

Просмотреть файл

@ -6,11 +6,13 @@
#include "mozilla/mscom/MainThreadRuntime.h"
#if defined(ACCESSIBILITY)
#include "mozilla/a11y/Compatibility.h"
#endif
#include "mozilla/ArrayUtils.h"
#include "mozilla/Assertions.h"
#include "mozilla/RefPtr.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/WindowsVersion.h"
#include "nsWindowsHelpers.h"
#include "nsXULAppAPI.h"
@ -34,29 +36,6 @@ struct LocalFreeDeleter
// This API from oleaut32.dll is not declared in Windows SDK headers
extern "C" void __cdecl SetOaNoCache(void);
#if defined(ACCESSIBILITY)
static WORD
GetActCtxResourceId()
{
// The manifest for 32-bit Windows is embedded with resource ID 32.
// The manifest for 64-bit Windows is embedded with resource ID 64.
// Beginning with Windows 10 Creators Update, 32-bit builds use the 64-bit
// manifest.
WORD actCtxResourceId;
#if defined(HAVE_64BIT_BUILD)
actCtxResourceId = 64;
#else
if (mozilla::IsWin10CreatorsUpdateOrLater()) {
actCtxResourceId = 64;
} else {
actCtxResourceId = 32;
}
#endif // defined(HAVE_64BIT_BUILD)
return actCtxResourceId;
}
#endif // defined(ACCESSIBILITY)
namespace mozilla {
namespace mscom {
@ -65,7 +44,7 @@ MainThreadRuntime* MainThreadRuntime::sInstance = nullptr;
MainThreadRuntime::MainThreadRuntime()
: mInitResult(E_UNEXPECTED)
#if defined(ACCESSIBILITY)
, mActCtxRgn(::GetActCtxResourceId())
, mActCtxRgn(a11y::Compatibility::GetActCtxResourceId())
#endif // defined(ACCESSIBILITY)
{
// We must be the outermost COM initialization on this thread. The COM runtime

Просмотреть файл

@ -0,0 +1,2 @@
getLcovInfo();
getLcovInfo();

Просмотреть файл

@ -7169,9 +7169,6 @@ PresShell::HandleEvent(nsIFrame* aFrame,
// Update the latest focus sequence number with this new sequence number
if (mAPZFocusSequenceNumber < aEvent->mFocusSequenceNumber) {
mAPZFocusSequenceNumber = aEvent->mFocusSequenceNumber;
// Schedule an empty transaction to transmit this focus update
aFrame->SchedulePaint(nsIFrame::PAINT_COMPOSITE_ONLY);
}
if (sPointerEventEnabled) {

Просмотреть файл

@ -857,8 +857,10 @@ AddAndRemoveImageAssociations(nsFrame* aFrame,
continue;
}
if (imgRequestProxy* req = oldImage.GetImageData()) {
imageLoader->DisassociateRequestFromFrame(req, aFrame);
if (aFrame->HasImageRequest()) {
if (imgRequestProxy* req = oldImage.GetImageData()) {
imageLoader->DisassociateRequestFromFrame(req, aFrame);
}
}
}
}
@ -972,7 +974,7 @@ nsFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
// they won't have the correct size for the border either.
if (oldBorderImage != newBorderImage) {
// stop and restart the image loading/notification
if (oldBorderImage) {
if (oldBorderImage && HasImageRequest()) {
imageLoader->DisassociateRequestFromFrame(oldBorderImage, this);
}
if (newBorderImage) {

Просмотреть файл

@ -4749,6 +4749,7 @@ nsGridContainerFrame::Tracks::AlignJustifyContent(
default:
MOZ_ASSERT_UNREACHABLE("unknown align-/justify-content value");
between = 0; // just to avoid a compiler warning
roundingError = 0; // just to avoid a compiler warning
}
between += mGridGap;
for (TrackSize& sz : mSizes) {

Просмотреть файл

@ -5137,8 +5137,7 @@ nsDisplayText::nsDisplayText(nsDisplayListBuilder* aBuilder, nsTextFrame* aFrame
Color color;
if (!capture->ContainsOnlyColoredGlyphs(mFont, color, glyphs)
|| !mFont
|| !mFont->CanSerialize()
|| XRE_IsParentProcess()) {
|| !mFont->CanSerialize()) {
mFont = nullptr;
mGlyphs.Clear();
} else {

Просмотреть файл

@ -95,6 +95,11 @@ public:
mBits |= eUncacheable;
}
void Clear()
{
*this = RuleNodeCacheConditions();
}
bool Cacheable() const
{
return !(mBits & eUncacheable);

Просмотреть файл

@ -2678,6 +2678,42 @@ nsRuleNode::WalkRuleTree(const nsStyleStructID aSID,
"not forcing detail to eRulePartialMixed just below is no "
"longer valid");
if (detail == eRuleNone && isReset) {
// We specified absolutely no rule information for a reset struct, and we
// may or may not have found a parent rule in the tree that specified all
// the rule information. Regardless, we don't need to use any cache
// conditions if we cache this struct in the rule tree.
//
// Normally ruleData.mConditions would already indicate that the struct
// is cacheable without conditions if detail is eRuleNone, but because
// of the UnsetPropertiesWithoutFlags call above, we may have encountered
// some rules with dependencies, which we then cleared out of ruleData.
//
// ruleData.mConditions could also indicate we are not cacheable at all,
// such as when AnimValuesStyleRule prevents us from caching structs
// when attempting to apply animations to pseudos.
//
// So if we we are uncacheable, we leave it, but if we are cacheable
// with dependencies, we convert that to cacheable without dependencies.
if (ruleData.mConditions.CacheableWithDependencies()) {
MOZ_ASSERT(pseudoRestriction,
"should only be cacheable with dependencies if we had a "
"pseudo restriction");
ruleData.mConditions.Clear();
} else {
// XXXheycam We shouldn't have `|| GetLevel() == SheetType::Transition`
// in the assertion condition, but rule nodes created by
// ResolveStyleByAddingRules don't call SetIsAnimationRule().
MOZ_ASSERT(ruleData.mConditions.CacheableWithoutDependencies() ||
((HasAnimationData() ||
GetLevel() == SheetType::Transition) &&
aContext->GetParent() &&
aContext->GetParent()->HasPseudoElementData()),
"should only be uncacheable if we had an animation rule "
"and we're inside a pseudo");
}
}
if (!ruleData.mConditions.CacheableWithoutDependencies() &&
aSID != eStyleStruct_Variables) {
// Treat as though some data is specified to avoid the optimizations and

Просмотреть файл

@ -193,6 +193,7 @@ public:
MOZ_ASSERT(!(mConditionalBits & GetBitForSID(aSID)),
"rule node should not have unconditional and conditional style "
"data for a given struct");
mConditionalBits &= ~GetBitForSID(aSID);
mEntries[aSID] = aStyleStruct;
}
@ -200,13 +201,17 @@ public:
nsPresContext* aPresContext,
void* aStyleStruct,
const mozilla::RuleNodeCacheConditions& aConditions) {
MOZ_ASSERT((mConditionalBits & GetBitForSID(aSID)) ||
!mEntries[aSID],
"rule node should not have unconditional and conditional style "
"data for a given struct");
if (!(mConditionalBits & GetBitForSID(aSID))) {
MOZ_ASSERT(!mEntries[aSID],
"rule node should not have unconditional and conditional "
"style data for a given struct");
mEntries[aSID] = nullptr;
}
MOZ_ASSERT(aConditions.CacheableWithDependencies(),
"don't call SetStyleData with a cache key that has no "
"conditions or is uncacheable");
#ifdef DEBUG
for (Entry* e = static_cast<Entry*>(mEntries[aSID]); e; e = e->mNext) {
NS_WARNING_ASSERTION(e->mConditions != aConditions,

Просмотреть файл

@ -3351,7 +3351,7 @@ function nsBrowserAccess() {
nsBrowserAccess.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIBrowserDOMWindow]),
_getBrowser: function _getBrowser(aURI, aOpener, aWhere, aFlags) {
_getBrowser: function _getBrowser(aURI, aOpener, aWhere, aFlags, aTriggeringPrincipal) {
let isExternal = !!(aFlags & Ci.nsIBrowserDOMWindow.OPEN_EXTERNAL);
if (isExternal && aURI && aURI.schemeIs("chrome"))
return null;
@ -3427,7 +3427,8 @@ nsBrowserAccess.prototype = {
opener: openerWindow,
selected: true,
isPrivate: isPrivate,
pinned: pinned });
pinned: pinned,
triggeringPrincipal: aTriggeringPrincipal});
return tab.browser;
}
@ -3435,14 +3436,18 @@ nsBrowserAccess.prototype = {
// OPEN_CURRENTWINDOW and illegal values
let browser = BrowserApp.selectedBrowser;
if (aURI && browser) {
browser.loadURIWithFlags(aURI.spec, loadflags, referrer, null, null);
browser.loadURIWithFlags(aURI.spec, {
flags: loadflags,
referrerURI: referrer,
triggeringPrincipal: aTriggeringPrincipal,
});
}
return browser;
},
openURI: function browser_openURI(aURI, aOpener, aWhere, aFlags) {
let browser = this._getBrowser(aURI, aOpener, aWhere, aFlags);
openURI: function browser_openURI(aURI, aOpener, aWhere, aFlags, aTriggeringPrincipal) {
let browser = this._getBrowser(aURI, aOpener, aWhere, aFlags, aTriggeringPrincipal);
return browser ? browser.contentWindow : null;
},
@ -3454,7 +3459,7 @@ nsBrowserAccess.prototype = {
//
// We also ignore aName if it is set, as it is currently only used on the
// e10s codepath.
let browser = this._getBrowser(aURI, null, aWhere, aFlags);
let browser = this._getBrowser(aURI, null, aWhere, aFlags, null);
if (browser)
return browser.QueryInterface(Ci.nsIFrameLoaderOwner);
return null;

Просмотреть файл

@ -3158,9 +3158,6 @@ pref("dom.ipc.plugins.reportCrashURL", true);
// Defaults to 30 seconds.
pref("dom.ipc.plugins.unloadTimeoutSecs", 30);
// Asynchronous plugin initialization is on hold.
pref("dom.ipc.plugins.asyncInit.enabled", false);
// Allow Flash async drawing mode in 64-bit release builds
pref("dom.ipc.plugins.asyncdrawing.enabled", true);
// Force the accelerated direct path for a subset of Flash wmode values

Просмотреть файл

@ -779,38 +779,6 @@ continue_loading:
return stub_LdrLoadDll(filePath, flags, moduleFileName, handle);
}
#ifdef _M_AMD64
typedef NTSTATUS (NTAPI *LdrUnloadDll_func)(HMODULE module);
static LdrUnloadDll_func stub_LdrUnloadDll;
static NTSTATUS NTAPI
patched_LdrUnloadDll(HMODULE module)
{
// Prevent the stack walker from suspending this thread when LdrUnloadDll
// holds the RtlLookupFunctionEntry lock.
AutoSuppressStackWalking suppress;
return stub_LdrUnloadDll(module);
}
// These pointers are disguised as PVOID to avoid pulling in obscure headers
typedef PVOID (WINAPI *LdrResolveDelayLoadedAPI_func)(PVOID ParentModuleBase,
PVOID DelayloadDescriptor, PVOID FailureDllHook, PVOID FailureSystemHook,
PVOID ThunkAddress, ULONG Flags);
static LdrResolveDelayLoadedAPI_func stub_LdrResolveDelayLoadedAPI;
static PVOID WINAPI patched_LdrResolveDelayLoadedAPI(PVOID ParentModuleBase,
PVOID DelayloadDescriptor, PVOID FailureDllHook, PVOID FailureSystemHook,
PVOID ThunkAddress, ULONG Flags)
{
// Prevent the stack walker from suspending this thread when
// LdrResolveDelayLoadAPI holds the RtlLookupFunctionEntry lock.
AutoSuppressStackWalking suppress;
return stub_LdrResolveDelayLoadedAPI(ParentModuleBase, DelayloadDescriptor,
FailureDllHook, FailureSystemHook,
ThunkAddress, Flags);
}
#endif
#ifdef _M_IX86
static bool
ShouldBlockThread(void* aStartAddress)
@ -890,14 +858,6 @@ DllBlocklist_Initialize(uint32_t aInitFlags)
Kernel32Intercept.Init("kernel32.dll");
#ifdef _M_AMD64
NtDllIntercept.AddHook("LdrUnloadDll",
reinterpret_cast<intptr_t>(patched_LdrUnloadDll),
(void**)&stub_LdrUnloadDll);
if (IsWin8OrLater()) { // LdrResolveDelayLoadedAPI was introduced in Win8
NtDllIntercept.AddHook("LdrResolveDelayLoadedAPI",
reinterpret_cast<intptr_t>(patched_LdrResolveDelayLoadedAPI),
(void**)&stub_LdrResolveDelayLoadedAPI);
}
if (!IsWin8OrLater()) {
// The crash that this hook works around is only seen on Win7.
Kernel32Intercept.AddHook("RtlInstallFunctionTableCallback",

Просмотреть файл

@ -1598,15 +1598,17 @@ HttpChannelChild::SetupRedirect(nsIURI* uri,
void
HttpChannelChild::Redirect1Begin(const uint32_t& registrarId,
const URIParams& newUri,
const URIParams& newOriginalURI,
const uint32_t& redirectFlags,
const nsHttpResponseHead& responseHead,
const nsACString& securityInfoSerialization,
const uint64_t& channelId)
{
nsresult rv;
LOG(("HttpChannelChild::Redirect1Begin [this=%p]\n", this));
nsCOMPtr<nsIURI> uri = DeserializeURI(newUri);
nsCOMPtr<nsIURI> uri = DeserializeURI(newOriginalURI);
if (!securityInfoSerialization.IsEmpty()) {
NS_DeserializeObject(securityInfoSerialization,
@ -1614,10 +1616,10 @@ HttpChannelChild::Redirect1Begin(const uint32_t& registrarId,
}
nsCOMPtr<nsIChannel> newChannel;
nsresult rv = SetupRedirect(uri,
&responseHead,
redirectFlags,
getter_AddRefs(newChannel));
rv = SetupRedirect(uri,
&responseHead,
redirectFlags,
getter_AddRefs(newChannel));
if (NS_SUCCEEDED(rv)) {
if (mRedirectChannelChild) {

Просмотреть файл

@ -1754,6 +1754,8 @@ HttpChannelParent::StartRedirect(uint32_t registrarId,
uint32_t redirectFlags,
nsIAsyncVerifyRedirectCallback* callback)
{
nsresult rv;
LOG(("HttpChannelParent::StartRedirect [this=%p, registrarId=%" PRIu32 " "
"newChannel=%p callback=%p]\n", this, registrarId, newChannel,
callback));
@ -1761,11 +1763,16 @@ HttpChannelParent::StartRedirect(uint32_t registrarId,
if (mIPCClosed)
return NS_BINDING_ABORTED;
nsCOMPtr<nsIURI> newURI;
newChannel->GetURI(getter_AddRefs(newURI));
// Sending down the original URI, because that is the URI we have
// to construct the channel from - this is the URI we've been actually
// redirected to. URI of the channel may be an inner channel URI.
// URI of the channel will be reconstructed by the protocol handler
// on the child process, no need to send it then.
nsCOMPtr<nsIURI> newOriginalURI;
newChannel->GetOriginalURI(getter_AddRefs(newOriginalURI));
URIParams uriParams;
SerializeURI(newURI, uriParams);
SerializeURI(newOriginalURI, uriParams);
nsCString secInfoSerialization;
UpdateAndSerializeSecurityInfo(secInfoSerialization);
@ -1776,7 +1783,7 @@ HttpChannelParent::StartRedirect(uint32_t registrarId,
uint64_t channelId;
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(newChannel);
if (httpChannel) {
nsresult rv = httpChannel->GetChannelId(&channelId);
rv = httpChannel->GetChannelId(&channelId);
NS_ENSURE_SUCCESS(rv, NS_BINDING_ABORTED);
}

Просмотреть файл

@ -117,7 +117,7 @@ child:
// Called to initiate content channel redirect, starts talking to sinks
// on the content process and reports result via Redirect2Verify above
async Redirect1Begin(uint32_t registrarId,
URIParams newUri,
URIParams newOriginalUri,
uint32_t redirectFlags,
nsHttpResponseHead responseHead,
nsCString securityInfoSerialization,

Просмотреть файл

@ -83,7 +83,11 @@ DWORD CreateRestrictedToken(TokenLevel security_level,
sid_exceptions.push_back(WinWorldSid);
sid_exceptions.push_back(WinInteractiveSid);
privilege_exceptions.push_back(SE_CHANGE_NOTIFY_NAME);
restricted_token.AddUserSidForDenyOnly();
// This breaks web audio, so we don't want to do this in the restricting
// SIDs (normal) case. See bug 1378061.
if (!gUseRestricting) {
restricted_token.AddUserSidForDenyOnly();
}
restricted_token.AddRestrictingSid(WinBuiltinUsersSid);
restricted_token.AddRestrictingSid(WinWorldSid);
restricted_token.AddRestrictingSid(WinRestrictedCodeSid);

Просмотреть файл

@ -70,7 +70,7 @@ config = {
},
"check_test_env": {
'MINIDUMP_STACKWALK': '%(abs_tools_dir)s\\breakpad\\win32\\minidump_stackwalk.exe',
'MINIDUMP_SAVE_PATH': '%(base_work_dir)s\\minidumps',
'MINIDUMP_SAVE_PATH': os.path.join(os.getcwd(), 'public', 'build'),
},
'src_mozconfig': 'browser\\config\\mozconfigs\\win32\\clang',
'artifact_flag_build_variant_in_try': None,

Просмотреть файл

@ -72,7 +72,7 @@ config = {
},
"check_test_env": {
'MINIDUMP_STACKWALK': '%(abs_tools_dir)s\\breakpad\\win32\\minidump_stackwalk.exe',
'MINIDUMP_SAVE_PATH': '%(base_work_dir)s\\minidumps',
'MINIDUMP_SAVE_PATH': os.path.join(os.getcwd(), 'public', 'build'),
},
'src_mozconfig': 'browser\\config\\mozconfigs\\win32\\clang-debug',
'artifact_flag_build_variant_in_try': None,

Просмотреть файл

@ -74,7 +74,7 @@ config = {
},
"check_test_env": {
'MINIDUMP_STACKWALK': '%(abs_tools_dir)s\\breakpad\\win32\\minidump_stackwalk.exe',
'MINIDUMP_SAVE_PATH': '%(base_work_dir)s\\minidumps',
'MINIDUMP_SAVE_PATH': os.path.join(os.getcwd(), 'public', 'build'),
},
'src_mozconfig': 'browser\\config\\mozconfigs\\win32\\noopt-debug',
'artifact_flag_build_variant_in_try': None,

Просмотреть файл

@ -68,7 +68,7 @@ config = {
},
"check_test_env": {
'MINIDUMP_STACKWALK': '%(abs_tools_dir)s\\breakpad\\win64\\minidump_stackwalk.exe',
'MINIDUMP_SAVE_PATH': '%(base_work_dir)s\\minidumps',
'MINIDUMP_SAVE_PATH': os.path.join(os.getcwd(), 'public', 'build'),
},
'src_mozconfig': 'browser\\config\\mozconfigs\\win64\\debug-asan',
#########################################################################

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше