Merge mozilla-central and inbound

This commit is contained in:
Ed Morley 2014-06-11 10:09:54 +01:00
commit 4c1a61ac09
211 changed files with 7520 additions and 1205 deletions

View File

@ -1,9 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generator: Adobe Illustrator 12.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
]>
<svg version="1.1" id="svg2997" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200" viewBox="-0.5 -0.5 200 200" overflow="visible" enable-background="new -0.5 -0.5 200 200" xml:space="preserve">
<path id="path85" fill="#FFFFFF" d="M-2559.936,6359.65c19.127,26.489,46.371,47.744,80.988,44.707 C-2479.339,6371.648-2523.898,6352.641-2559.936,6359.65z"/>
<path id="path93" fill="#FFFFFF" d="M-2634.014,6073.506c4.082-7.232,2.571-17.81,3.831-26.684 c-9.019,4.635-15.506,14.72-24.551,18.641C-2652.134,6070.818-2640.447,6070.829-2634.014,6073.506z"/>
@ -46,4 +42,4 @@
<path id="path2320" d="M185.373-1089.163c-1.527-0.85-2.496-1.666-3.189-2.689l-0.402-0.596l-0.586,0.516 c-0.816,0.725-1.141,0.965-1.887,1.406c-1.727,1.02-4.043,1.439-6.92,1.252c-5.955-0.385-9.082-3.238-9.49-8.66 c-0.182-2.412,0.223-4.607,1.158-6.289c1.281-2.305,3.789-3.914,7.313-4.695c1.803-0.398,3.266-0.545,5.977-0.594l2.516-0.049 l-0.049-1.311c-0.027-0.723-0.09-1.543-0.137-1.824c-0.25-1.477-0.871-2.223-2.035-2.445c-0.902-0.17-1.32-0.18-2.357-0.053 c-2.006,0.246-4.098,1.066-6.678,2.623c-0.691,0.416-1.297,0.744-1.346,0.725c-0.096-0.037-3.463-5.682-3.461-5.799 c0.008-0.166,2.094-1.316,3.582-1.973c4.023-1.775,6.543-2.377,9.953-2.377c3.17,0,5.359,0.533,7.127,1.736 c0.693,0.473,1.736,1.551,2.115,2.186c0.35,0.586,0.777,1.646,1.012,2.51l0.189,0.691l-0.041,4.766 c-0.021,2.619-0.041,6.43-0.041,8.467c0,4.178,0,4.18,0.633,5.414c0.273,0.537,0.498,0.814,1.266,1.57 c0.855,0.842,0.922,0.93,0.809,1.059c-0.068,0.076-1.029,1.184-2.137,2.461c-1.109,1.275-2.057,2.328-2.107,2.338 C186.108-1088.786,185.756-1088.953,185.373-1089.163z M175.903-1095.453c1.229-0.154,2.246-0.641,3.182-1.518l0.508-0.477 l0.055-3.168l0.053-3.168l-1.316,0.057c-4.154,0.178-5.707,0.842-6.377,2.729c-0.213,0.596-0.295,2.16-0.146,2.787 c0.334,1.418,1.457,2.533,2.768,2.748c0.246,0.039,0.486,0.078,0.531,0.082C175.203-1095.374,175.539-1095.408,175.903-1095.453z M137.623-1089.718c-1.318-0.205-2.459-0.68-3.502-1.459c-1.109-0.826-1.762-1.803-2.238-3.348 c-0.445-1.441-0.436-1.025-0.49-18.475c-0.051-15.838-0.057-16.158-0.236-18.186c-0.102-1.135-0.162-2.086-0.137-2.111 c0.074-0.074,8.055-1.891,8.154-1.857c0.098,0.037,0.248,1.135,0.361,2.654c0.162,10.801,0.012,21.605,0.156,32.406 c0.063,2.619,0.086,2.936,0.24,3.373c0.379,1.078,0.902,1.469,1.963,1.465c0.336,0,0.662-0.018,0.727-0.039 c0.105-0.033,0.479,1.133,1.371,4.289l0.162,0.578l-1.271,0.334C141.034-1089.607,139.186-1089.476,137.623-1089.718z M154.555-1089.644c-1.066-0.125-1.982-0.391-2.85-0.822c-2.164-1.08-3.219-2.633-3.713-5.475 c-0.066-0.375-0.109-5.193-0.146-16.57c-0.053-15.98-0.055-16.049-0.25-18.383c-0.117-1.43-0.164-2.367-0.119-2.408 c0.102-0.088,8.1-1.91,8.152-1.857c0.088,0.088,0.268,1.711,0.348,3.148c0.213,11.125-0.035,22.258,0.162,33.383 c0.055,1.18,0.107,1.611,0.238,1.984c0.221,0.625,0.525,1.014,0.945,1.199c0.457,0.203,1.182,0.281,1.516,0.166 c0.174-0.063,0.283-0.066,0.316-0.014c0.078,0.129,1.402,4.816,1.369,4.85c-0.016,0.018-0.504,0.164-1.084,0.328 C158.041-1089.722,155.75-1089.501,154.555-1089.644z M67.676-1089.716c-0.134-0.018-0.61-0.076-1.059-0.127 c-0.447-0.053-1.237-0.215-1.756-0.363c-5.568-1.582-9.046-6.182-9.853-13.021c-0.124-1.047-0.123-3.988,0.001-5.09 c0.362-3.213,1.4-6.119,2.997-8.387c1.083-1.537,2.861-3.086,4.462-3.889c2.021-1.016,3.78-1.402,6.368-1.402 c2.15,0,3.536,0.219,5.156,0.816c3.931,1.449,7.106,5.004,8.254,9.238c0.922,3.398,0.905,8.645-0.037,12.051 c-0.744,2.691-2.024,4.861-3.966,6.725s-4.086,2.918-6.7,3.297C70.775-1089.757,68.143-1089.654,67.676-1089.716z M70.77-1096.027 c1.815-0.824,2.693-2.672,3.095-6.512c0.153-1.465,0.177-5.111,0.041-6.512c-0.375-3.879-1.335-5.748-3.356-6.531 c-1.055-0.41-2.505-0.303-3.577,0.262c-1.823,0.959-2.647,2.99-2.926,7.207c-0.158,2.404-0.013,5.633,0.343,7.572 c0.475,2.602,1.225,3.77,2.859,4.457c0.768,0.322,1.166,0.387,2.144,0.344C70.09-1095.769,70.293-1095.812,70.77-1096.027z M10.314-1116.745c-0.13-1.063-0.376-2.029-0.667-2.621c-0.147-0.301-0.224-0.547-0.182-0.584c0.09-0.078,7.021-1.965,7.22-1.965 c0.204,0,0.671,0.98,0.915,1.92c0.112,0.432,0.204,0.855,0.204,0.939c0,0.086,0.027,0.152,0.061,0.152 c0.034-0.002,0.391-0.277,0.794-0.615c1.52-1.27,3.532-2.127,5.465-2.324c2.115-0.217,4.02,0.1,5.551,0.92 c0.98,0.527,2.146,1.512,2.768,2.336l0.488,0.646l0.314-0.326c0.76-0.789,2.256-1.92,3.307-2.496 c0.898-0.494,2.17-0.893,3.413-1.074c1.114-0.16,3.312-0.063,4.384,0.197c1.185,0.287,2.204,0.719,2.971,1.26 c1.574,1.109,2.172,2.082,2.584,4.207c0.172,0.885,0.174,1.025,0.203,13.373l0.029,12.479H42.15v-10.934 c0-7.029-0.03-11.18-0.084-11.623c-0.198-1.623-0.574-2.096-1.798-2.268c-1.429-0.199-3.438,0.574-5.267,2.025l-0.667,0.529 l0,22.27h-7.729c-0.473-7.383,0.652-15.438-0.186-22.727c-0.296-1.432-0.807-1.955-2.059-2.107 c-1.462-0.178-3.452,0.498-5.153,1.75l-0.664,0.488l-0.005,22.596h-7.979C10.282-1099.062,11.051-1108.048,10.314-1116.745z M86.536-1095.492l14.459-19.949l-13.248-0.043v-5.779h23.043v5.578c-4.503,6.535-9.129,12.986-13.598,19.545l14.179,0.037 l-0.059,0.182l-1.888,5.559l-22.899,0.041L86.536-1095.492z M116.735-1120.853l0.184-0.041c2.588-0.43,5.186-0.809,7.775-1.227 l0.266-0.045v31.844h-8.225V-1120.853z M120.276-1124.939c-1.963-0.195-3.682-1.678-4.188-3.611 c-0.703-2.688,0.707-5.361,3.273-6.201c0.484-0.158,0.754-0.191,1.592-0.191c1.578,0,2.482,0.357,3.508,1.381 c0.986,0.986,1.412,2.068,1.418,3.586c0.004,1.563-0.406,2.584-1.457,3.637C123.332-1125.245,121.934-1124.773,120.276-1124.939z"/>
</g>
</g>
</svg>
</svg>

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -390,10 +390,13 @@ pref("content.ime.strict_policy", true);
// $ adb shell start
pref("browser.dom.window.dump.enabled", false);
// Turn on the CSP 1.0 parser for Content Security Policy headers
pref("security.csp.speccompliant", true);
// Default Content Security Policy to apply to privileged and certified apps
pref("security.apps.privileged.CSP.default", "default-src *; script-src 'self'; object-src 'none'; style-src 'self' 'unsafe-inline'");
// If you change this CSP, make sure to update the fast path in nsCSPService.cpp
pref("security.apps.certified.CSP.default", "default-src *; script-src 'self'; object-src 'none'; style-src 'self'");
pref("security.apps.certified.CSP.default", "default-src *; script-src 'self'; object-src 'none'; style-src 'self' 'unsafe-inline'");
// Temporarily force-enable GL compositing. This is default-disabled
// deep within the bowels of the widgetry system. Remove me when GL

View File

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="aboutWordmark" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="264px" height="38px" viewBox="0 0 264 38" xml:space="preserve">

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="aboutWordmark" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="270px" height="48px" viewBox="0 0 270 48" xml:space="preserve">

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="aboutWordmark" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="130px" height="38px" viewBox="0 0 130 38" xml:space="preserve">

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="aboutWordmark" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="132px" height="48px" viewBox="0 0 132 48" xml:space="preserve">

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -4,7 +4,6 @@
- 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/. -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="64px" height="64px" viewBox="0 0 64 64">
<path fill="#00B2F7" d="M32.336,3.894c-15.74,0-28.5,12.76-28.5,28.5s12.76,28.5,28.5,28.5s28.5-12.76,28.5-28.5
S48.076,3.894,32.336,3.894z M44.86,36.966h-7.823v7.62c0,2.582-2.12,4.702-4.702,4.702c-2.584,0-4.704-2.12-4.704-4.702v-7.62

Before

Width:  |  Height:  |  Size: 934 B

After

Width:  |  Height:  |  Size: 834 B

View File

@ -4,7 +4,6 @@
- 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/. -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="64px" height="64px" viewBox="0 0 64 64">
<path fill="#E25026" d="M32,4.894c-15.74,0-28.5,12.76-28.5,28.5s12.76,28.5,28.5,28.5s28.5-12.76,28.5-28.5S47.74,4.894,32,4.894
z M46.903,48.674c-1.817,1.817-4.691,1.76-6.449,0.002l-8.327-8.327l-8.151,8.151c-1.877,1.877-4.87,1.814-6.685,0

Before

Width:  |  Height:  |  Size: 1021 B

After

Width:  |  Height:  |  Size: 921 B

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 17.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="160px" height="240px" viewBox="0 0 160 240" enable-background="new 0 0 160 240" xml:space="preserve">
<rect y="40" display="none" fill="#22272D" width="84" height="160"/>

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

View File

@ -4,7 +4,6 @@
- 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/. -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="64px" height="64px" viewBox="0 0 64 64">
<path fill="#ABABAB" d="M32.336,3.894c-15.74,0-28.5,12.76-28.5,28.5s12.76,28.5,28.5,28.5s28.5-12.76,28.5-28.5
S48.076,3.894,32.336,3.894z M44.86,36.966h-7.823v7.62c0,2.582-2.12,4.702-4.702,4.702c-2.584,0-4.704-2.12-4.704-4.702v-7.62

Before

Width:  |  Height:  |  Size: 934 B

After

Width:  |  Height:  |  Size: 834 B

View File

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- 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

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- 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

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 951 B

View File

@ -34,8 +34,10 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=995943
debug("Invoking checkLoadFileURI with domain: " + domain + ", shouldLoad: " + shouldLoad);
return new Promise(function(resolve, reject) {
$('ifr').addEventListener('load', function l1() {
debug("Invoked l1 for " + domain);
$('ifr').removeEventListener('load', l1);
function l2() {
debug("Invoked l2 for " + domain);
$('ifr').removeEventListener('load', l2);
ok(shouldLoad, "Successfully loaded file:// URI for domain: " + domain);
resolve();
@ -43,6 +45,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=995943
$('ifr').addEventListener('load', l2);
try {
window[0].wrappedJSObject.location = profileDir;
debug("Successfully navigated for " + domain);
} catch (e) {
ok(!shouldLoad && /denied|insecure/.test(e),
"Prevented loading of file:// URI for domain: " + domain + " - " + e);

View File

@ -216,7 +216,7 @@ Element::UpdateState(bool aNotify)
if (aNotify) {
EventStates changedStates = oldState ^ mState;
if (!changedStates.IsEmpty()) {
nsIDocument* doc = GetCurrentDoc();
nsIDocument* doc = GetCrossShadowCurrentDoc();
if (doc) {
nsAutoScriptBlocker scriptBlocker;
doc->ContentStateChanged(this, changedStates);

View File

@ -88,6 +88,7 @@
#include "mozilla/dom/SVGIFrameElement.h"
#include "nsSandboxFlags.h"
#include "JavaScriptParent.h"
#include "CompositorChild.h"
#include "mozilla/dom/StructuredCloneUtils.h"
@ -1543,9 +1544,16 @@ nsFrameLoader::ShouldUseRemoteProcess()
return false;
}
// If we're inside a content process, don't use a remote process for this
// frame; it won't work properly until bug 761935 is fixed.
if (XRE_GetProcessType() == GeckoProcessType_Content) {
// Don't try to launch nested children if we don't have OMTC.
// They won't render!
if (XRE_GetProcessType() == GeckoProcessType_Content &&
!CompositorChild::ChildProcessHasCompositor()) {
return false;
}
if (XRE_GetProcessType() == GeckoProcessType_Content &&
!(PR_GetEnv("MOZ_NESTED_OOP_TABS") ||
Preferences::GetBool("dom.ipc.tabs.nested.enabled", false))) {
return false;
}
@ -2093,10 +2101,7 @@ nsFrameLoader::TryRemoteBrowser()
return false;
}
nsCOMPtr<nsIXULWindow> window(do_GetInterface(parentOwner));
if (!window) {
return false;
}
if (NS_FAILED(window->GetChromeFlags(&chromeFlags))) {
if (window && NS_FAILED(window->GetChromeFlags(&chromeFlags))) {
return false;
}
@ -2135,11 +2140,12 @@ nsFrameLoader::TryRemoteBrowser()
parentAsItem->GetRootTreeItem(getter_AddRefs(rootItem));
nsCOMPtr<nsIDOMWindow> rootWin = rootItem->GetWindow();
nsCOMPtr<nsIDOMChromeWindow> rootChromeWin = do_QueryInterface(rootWin);
NS_ABORT_IF_FALSE(rootChromeWin, "How did we not get a chrome window here?");
nsCOMPtr<nsIBrowserDOMWindow> browserDOMWin;
rootChromeWin->GetBrowserDOMWindow(getter_AddRefs(browserDOMWin));
mRemoteBrowser->SetBrowserDOMWindow(browserDOMWin);
if (rootChromeWin) {
nsCOMPtr<nsIBrowserDOMWindow> browserDOMWin;
rootChromeWin->GetBrowserDOMWindow(getter_AddRefs(browserDOMWin));
mRemoteBrowser->SetBrowserDOMWindow(browserDOMWin);
}
mContentParent = mRemoteBrowser->Manager();
@ -2301,7 +2307,7 @@ nsFrameLoader::DoSendAsyncMessage(JSContext* aCx,
TabParent* tabParent = mRemoteBrowser;
if (tabParent) {
ClonedMessageData data;
ContentParent* cp = tabParent->Manager();
nsIContentParent* cp = tabParent->Manager();
if (!BuildClonedMessageDataForParent(cp, aData, data)) {
return false;
}
@ -2424,8 +2430,9 @@ nsFrameLoader::EnsureMessageManager()
return NS_OK;
}
bool useRemoteProcess = ShouldUseRemoteProcess();
if (mMessageManager) {
if (ShouldUseRemoteProcess() && mRemoteBrowserShown) {
if (useRemoteProcess && mRemoteBrowserShown) {
mMessageManager->InitWithCallback(this);
}
return NS_OK;
@ -2449,7 +2456,7 @@ nsFrameLoader::EnsureMessageManager()
}
}
if (ShouldUseRemoteProcess()) {
if (useRemoteProcess) {
mMessageManager = new nsFrameMessageManager(mRemoteBrowserShown ? this : nullptr,
static_cast<nsFrameMessageManager*>(parentManager.get()),
MM_CHROME);

View File

@ -445,7 +445,7 @@ private:
// The ContentParent associated with mRemoteBrowser. This was added as a
// strong ref in bug 545237, and we're not sure if we can get rid of it.
nsRefPtr<mozilla::dom::ContentParent> mContentParent;
nsRefPtr<mozilla::dom::nsIContentParent> mContentParent;
RenderFrameParent* mCurrentRemoteFrame;
TabParent* mRemoteBrowser;
uint64_t mChildID;

View File

@ -9,7 +9,6 @@
#include "AppProcessChecker.h"
#include "ContentChild.h"
#include "ContentParent.h"
#include "nsContentUtils.h"
#include "nsCxPusher.h"
#include "nsError.h"
@ -31,6 +30,8 @@
#include "nsIDOMFile.h"
#include "xpcpublic.h"
#include "mozilla/Preferences.h"
#include "mozilla/dom/nsIContentParent.h"
#include "mozilla/dom/PermissionMessageUtils.h"
#include "mozilla/dom/StructuredCloneUtils.h"
#include "mozilla/dom/PBlobChild.h"
#include "mozilla/dom/PBlobParent.h"
@ -38,6 +39,7 @@
#include "JavaScriptParent.h"
#include "mozilla/dom/DOMStringList.h"
#include "nsPrintfCString.h"
#include "nsXULAppAPI.h"
#include <algorithm>
#ifdef ANDROID
@ -144,7 +146,7 @@ struct BlobTraits<Parent>
{
typedef mozilla::dom::BlobParent BlobType;
typedef mozilla::dom::PBlobParent ProtocolType;
typedef mozilla::dom::ContentParent ConcreteContentManagerType;
typedef mozilla::dom::nsIContentParent ConcreteContentManagerType;
};
template <>
@ -152,7 +154,7 @@ struct BlobTraits<Child>
{
typedef mozilla::dom::BlobChild BlobType;
typedef mozilla::dom::PBlobChild ProtocolType;
typedef mozilla::dom::ContentChild ConcreteContentManagerType;
typedef mozilla::dom::nsIContentChild ConcreteContentManagerType;
};
template<ActorFlavorEnum>
@ -219,7 +221,7 @@ BuildClonedMessageData(typename BlobTraits<Flavor>::ConcreteContentManagerType*
}
bool
MessageManagerCallback::BuildClonedMessageDataForParent(ContentParent* aParent,
MessageManagerCallback::BuildClonedMessageDataForParent(nsIContentParent* aParent,
const StructuredCloneData& aData,
ClonedMessageData& aClonedData)
{
@ -227,7 +229,7 @@ MessageManagerCallback::BuildClonedMessageDataForParent(ContentParent* aParent,
}
bool
MessageManagerCallback::BuildClonedMessageDataForChild(ContentChild* aChild,
MessageManagerCallback::BuildClonedMessageDataForChild(nsIContentChild* aChild,
const StructuredCloneData& aData,
ClonedMessageData& aClonedData)
{
@ -1868,8 +1870,6 @@ NS_NewParentProcessMessageManager(nsIMessageBroadcaster** aResult)
{
NS_ASSERTION(!nsFrameMessageManager::sParentProcessManager,
"Re-creating sParentProcessManager");
NS_ENSURE_TRUE(XRE_GetProcessType() == GeckoProcessType_Default,
NS_ERROR_NOT_AVAILABLE);
nsRefPtr<nsFrameMessageManager> mm = new nsFrameMessageManager(nullptr,
nullptr,
MM_CHROME | MM_PROCESSMANAGER | MM_BROADCASTER);
@ -1880,7 +1880,7 @@ NS_NewParentProcessMessageManager(nsIMessageBroadcaster** aResult)
nsFrameMessageManager*
nsFrameMessageManager::NewProcessMessageManager(mozilla::dom::ContentParent* aProcess)
nsFrameMessageManager::NewProcessMessageManager(mozilla::dom::nsIContentParent* aProcess)
{
if (!nsFrameMessageManager::sParentProcessManager) {
nsCOMPtr<nsIMessageBroadcaster> dummy =

View File

@ -32,8 +32,8 @@
namespace mozilla {
namespace dom {
class ContentParent;
class ContentChild;
class nsIContentParent;
class nsIContentChild;
class ClonedMessageData;
class MessageManagerReporter;
@ -99,10 +99,10 @@ public:
}
protected:
bool BuildClonedMessageDataForParent(ContentParent* aParent,
bool BuildClonedMessageDataForParent(nsIContentParent* aParent,
const StructuredCloneData& aData,
ClonedMessageData& aClonedData);
bool BuildClonedMessageDataForChild(ContentChild* aChild,
bool BuildClonedMessageDataForChild(nsIContentChild* aChild,
const StructuredCloneData& aData,
ClonedMessageData& aClonedData);
};
@ -217,7 +217,7 @@ public:
NS_DECL_NSIPROCESSCHECKER
static nsFrameMessageManager*
NewProcessMessageManager(mozilla::dom::ContentParent* aProcess);
NewProcessMessageManager(mozilla::dom::nsIContentParent* aProcess);
nsresult ReceiveMessage(nsISupports* aTarget, const nsAString& aMessage,
bool aIsSync, const StructuredCloneData* aCloneData,

View File

@ -5,6 +5,7 @@
var gJar1 = "jar:http://example.org/tests/content/base/test/file_bug945152.jar!/data_1.txt";
var gJar2 = "jar:http://example.org/tests/content/base/test/file_bug945152.jar!/data_2.txt";
var gJar3 = "jar:http://example.org/tests/content/base/test/file_bug945152.jar!/data_big.txt";
var gPaddingChar = ".";
var gPaddingSize = 10000;
var gPadding = "";
@ -55,14 +56,22 @@ self.onmessage = function onmessage(event) {
var lastIndex = 0;
xhr.onprogress = function(event) {
if (xhr.response) {
var str = String.fromCharCode.apply(null, Uint8Array(xhr.response));
ok(str.length == gData1.length, "Data size is correct");
ok(str == gData1.substr(lastIndex, str.length), "Data chunk is correct");
var buf = new Uint8Array(xhr.response);
var allMatched = true;
// The content of data cycles from 0 to 9 (i.e. 01234567890123......).
for (var i = 0; i < buf.length; i++) {
if (String.fromCharCode(buf[i]) != lastIndex % 10) {
allMatched = false;
break;
}
lastIndex++;
}
ok(allMatched, "Data chunk is correct. Loaded " +
event.loaded + "/" + event.total + " bytes.");
}
lastIndex += str.length;
};
xhr.onload = runTests;
xhr.open("GET", gJar1, true);
xhr.open("GET", gJar3, true);
xhr.responseType = "moz-chunked-arraybuffer";
xhr.send();
}

Binary file not shown.

View File

@ -111,6 +111,11 @@ bool WebGLContext::DrawArrays_check(GLint first, GLsizei count, GLsizei primcoun
if (!DoFakeVertexAttrib0(checked_firstPlusCount.value())) {
return false;
}
if (!DrawInstanced_check(info)) {
return false;
}
BindFakeBlackTextures();
return true;
@ -146,9 +151,6 @@ WebGLContext::DrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsiz
if (!DrawArrays_check(first, count, primcount, "drawArraysInstanced"))
return;
if (!DrawInstanced_check("drawArraysInstanced"))
return;
RunContextLossTimer();
gl->fDrawArraysInstanced(mode, first, count, primcount);
@ -282,6 +284,11 @@ WebGLContext::DrawElements_check(GLsizei count, GLenum type,
if (!DoFakeVertexAttrib0(mMaxFetchedVertices)) {
return false;
}
if (!DrawInstanced_check(info)) {
return false;
}
BindFakeBlackTextures();
return true;
@ -329,9 +336,6 @@ WebGLContext::DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type,
if (!DrawElements_check(count, type, byteOffset, primcount, "drawElementsInstanced"))
return;
if (!DrawInstanced_check("drawElementsInstanced"))
return;
RunContextLossTimer();
gl->fDrawElementsInstanced(mode, count, type, reinterpret_cast<GLvoid*>(byteOffset), primcount);

View File

@ -35,13 +35,13 @@ WebGLContext::BindVertexArray(WebGLVertexArray *array)
MakeContextCurrent();
if (array) {
mBoundVertexArray = array;
} else {
mBoundVertexArray = mDefaultVertexArray;
if (array == nullptr) {
array = mDefaultVertexArray;
}
mBoundVertexArray->BindVertexArray();
array->BindVertexArray();
MOZ_ASSERT(mBoundVertexArray == array);
}
already_AddRefed<WebGLVertexArray>

View File

@ -244,22 +244,18 @@ WebGLContext::GetVertexAttrib(JSContext* cx, GLuint index, GLenum pname,
case LOCAL_GL_VERTEX_ATTRIB_ARRAY_SIZE:
{
if (!ValidateAttribIndex(index, "getVertexAttrib"))
return JS::NullValue();
if (!mBoundVertexArray->mAttribs[index].enabled)
return JS::Int32Value(4);
// Don't break; fall through.
return JS::Int32Value(mBoundVertexArray->mAttribs[index].size);
}
case LOCAL_GL_VERTEX_ATTRIB_ARRAY_TYPE:
{
GLint i = 0;
gl->fGetVertexAttribiv(index, pname, &i);
if (pname == LOCAL_GL_VERTEX_ATTRIB_ARRAY_SIZE)
return JS::Int32Value(i);
MOZ_ASSERT(pname == LOCAL_GL_VERTEX_ATTRIB_ARRAY_TYPE);
return JS::NumberValue(uint32_t(i));
if (!mBoundVertexArray->mAttribs[index].enabled)
return JS::NumberValue(uint32_t(LOCAL_GL_FLOAT));
return JS::NumberValue(uint32_t(mBoundVertexArray->mAttribs[index].type));
}
case LOCAL_GL_VERTEX_ATTRIB_ARRAY_DIVISOR:

View File

@ -16,6 +16,8 @@
namespace mozilla {
class WebGLVertexArrayFake;
class WebGLVertexArray
: public nsWrapperCache
, public WebGLRefCountedObject<WebGLVertexArray>
@ -88,6 +90,7 @@ protected:
// -------------------------------------------------------------------------
// FRIENDSHIPS
friend class WebGLVertexArrayFake;
friend class WebGLContext;
};

View File

@ -17,6 +17,10 @@ WebGLVertexArrayFake::BindVertexArrayImpl()
// vertex attribute pointers
gl::GLContext* gl = mContext->gl;
WebGLRefPtr<WebGLVertexArray> prevVertexArray = mContext->mBoundVertexArray;
mContext->mBoundVertexArray = this;
WebGLRefPtr<WebGLBuffer> prevBuffer = mContext->mBoundArrayBuffer;
mContext->BindBuffer(LOCAL_GL_ELEMENT_ARRAY_BUFFER, mElementArrayBuffer);
@ -35,6 +39,14 @@ WebGLVertexArrayFake::BindVertexArrayImpl()
}
}
for (size_t i = mAttribs.Length(); i < prevVertexArray->mAttribs.Length(); ++i) {
const WebGLVertexAttribData& vd = prevVertexArray->mAttribs[i];
if (vd.enabled) {
gl->fDisableVertexAttribArray(i);
}
}
mContext->BindBuffer(LOCAL_GL_ARRAY_BUFFER, prevBuffer);
}

View File

@ -22,6 +22,8 @@ WebGLVertexArrayGL::DeleteImpl()
void
WebGLVertexArrayGL::BindVertexArrayImpl()
{
mContext->mBoundVertexArray = this;
mContext->gl->fBindVertexArray(mGLName);
}

View File

@ -283,9 +283,7 @@ nsGenericHTMLFrameElement::GetReallyIsBrowserOrApp(bool *aOut)
}
// Fail if this frame doesn't have the mozbrowser attribute.
bool hasMozbrowser = false;
GetMozbrowser(&hasMozbrowser);
if (!hasMozbrowser) {
if (!GetBoolAttr(nsGkAtoms::mozbrowser)) {
return NS_OK;
}

View File

@ -10,6 +10,7 @@
#include "mozilla/Attributes.h"
#include "mozilla/ReentrantMonitor.h"
#include "mozilla/CheckedInt.h"
#include "nsIThread.h"
#if !(defined(XP_WIN) || defined(XP_MACOSX) || defined(LINUX)) || \
defined(MOZ_ASAN)
@ -92,6 +93,27 @@ private:
nsCOMPtr<nsIThread> mThread;
};
template<class T>
class DeleteObjectTask: public nsRunnable {
public:
DeleteObjectTask(nsAutoPtr<T>& aObject)
: mObject(aObject)
{
}
NS_IMETHOD Run() {
NS_ASSERTION(NS_IsMainThread(), "Must be on main thread.");
mObject = nullptr;
return NS_OK;
}
private:
nsAutoPtr<T> mObject;
};
template<class T>
void DeleteOnMainThread(nsAutoPtr<T>& aObject) {
NS_DispatchToMainThread(new DeleteObjectTask<T>(aObject));
}
class MediaResource;
namespace dom {

View File

@ -71,17 +71,17 @@ public:
size_t* aBytesRead) MOZ_OVERRIDE
{
uint32_t sum = 0;
uint32_t bytesRead = 0;
do {
uint32_t offset = aOffset + sum;
char* buffer = reinterpret_cast<char*>(aBuffer) + sum;
uint32_t toRead = aCount - sum;
uint32_t bytesRead = 0;
nsresult rv = mResource->ReadAt(offset, buffer, toRead, &bytesRead);
if (NS_FAILED(rv)) {
return false;
}
sum += bytesRead;
} while (sum < aCount);
} while (sum < aCount && bytesRead > 0);
*aBytesRead = sum;
return true;
}

View File

@ -57,8 +57,6 @@ WMFDecoderModule::Startup()
nsresult
WMFDecoderModule::Shutdown()
{
MOZ_ASSERT(NS_IsMainThread(), "Must be on main thread.");
DebugOnly<HRESULT> hr = wmf::MFShutdown();
NS_ASSERTION(SUCCEEDED(hr), "MFShutdown failed");

View File

@ -49,6 +49,8 @@ WMFVideoOutputSource::WMFVideoOutputSource(mozilla::layers::LayersBackend aLayer
WMFVideoOutputSource::~WMFVideoOutputSource()
{
MOZ_COUNT_DTOR(WMFVideoOutputSource);
// Ensure DXVA/D3D9 related objects are released on the main thread.
DeleteOnMainThread(mDXVA2Manager);
}
class CreateDXVAManagerEvent : public nsRunnable {

View File

@ -40,6 +40,14 @@ LoadContext::GetTopFrameElement(nsIDOMElement** aElement)
return NS_OK;
}
NS_IMETHODIMP
LoadContext::GetNestedFrameId(uint64_t* aId)
{
NS_ENSURE_ARG(aId);
*aId = mNestedFrameId;
return NS_OK;
}
NS_IMETHODIMP
LoadContext::IsAppOfType(uint32_t, bool*)
{

View File

@ -45,6 +45,24 @@ public:
dom::Element* aTopFrameElement,
uint32_t aAppId, bool aInBrowser)
: mTopFrameElement(do_GetWeakReference(aTopFrameElement))
, mNestedFrameId(0)
, mAppId(aAppId)
, mIsContent(aToCopy.mIsContent)
, mUsePrivateBrowsing(aToCopy.mUsePrivateBrowsing)
, mUseRemoteTabs(aToCopy.mUseRemoteTabs)
, mIsInBrowserElement(aInBrowser)
#ifdef DEBUG
, mIsNotNull(aToCopy.mIsNotNull)
#endif
{}
// AppId/inBrowser arguments override those in SerializedLoadContext provided
// by child process.
LoadContext(const IPC::SerializedLoadContext& aToCopy,
uint64_t aNestedFrameId,
uint32_t aAppId, bool aInBrowser)
: mTopFrameElement(nullptr)
, mNestedFrameId(aNestedFrameId)
, mAppId(aAppId)
, mIsContent(aToCopy.mIsContent)
, mUsePrivateBrowsing(aToCopy.mUsePrivateBrowsing)
@ -62,6 +80,7 @@ public:
bool aUseRemoteTabs,
bool aIsInBrowserElement)
: mTopFrameElement(do_GetWeakReference(aTopFrameElement))
, mNestedFrameId(0)
, mAppId(aAppId)
, mIsContent(aIsContent)
, mUsePrivateBrowsing(aUsePrivateBrowsing)
@ -75,6 +94,7 @@ public:
// Constructor taking reserved appId for the safebrowsing cookie.
LoadContext(uint32_t aAppId)
: mTopFrameElement(nullptr)
, mNestedFrameId(0)
, mAppId(aAppId)
, mIsContent(false)
, mUsePrivateBrowsing(false)
@ -87,6 +107,7 @@ public:
private:
nsWeakPtr mTopFrameElement;
uint64_t mNestedFrameId;
uint32_t mAppId;
bool mIsContent;
bool mUsePrivateBrowsing;

View File

@ -12260,6 +12260,13 @@ nsDocShell::GetTopFrameElement(nsIDOMElement** aElement)
return top->GetFrameElement(aElement);
}
NS_IMETHODIMP
nsDocShell::GetNestedFrameId(uint64_t* aId)
{
*aId = 0;
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::IsAppOfType(uint32_t aAppType, bool *aIsOfType)
{

View File

@ -210,6 +210,7 @@ public:
NS_IMETHOD GetAssociatedWindow(nsIDOMWindow**);
NS_IMETHOD GetTopWindow(nsIDOMWindow**);
NS_IMETHOD GetTopFrameElement(nsIDOMElement**);
NS_IMETHOD GetNestedFrameId(uint64_t*);
NS_IMETHOD IsAppOfType(uint32_t, bool*);
NS_IMETHOD GetIsContent(bool*);
NS_IMETHOD GetUsePrivateBrowsing(bool*);

View File

@ -14,7 +14,7 @@ interface nsIDOMElement;
* can be queried for various information about where the load is
* happening.
*/
[scriptable, uuid(852ed1f0-8ec0-11e3-baa8-0800200c9a66)]
[scriptable, uuid(6ec837fa-af93-4350-bbb8-0985d54c74ca)]
interface nsILoadContext : nsISupports
{
/**
@ -43,6 +43,14 @@ interface nsILoadContext : nsISupports
*/
readonly attribute nsIDOMElement topFrameElement;
/**
* If this LoadContext corresponds to a nested remote iframe, we don't have
* access to the topFrameElement. Instead, we must use this id to send
* messages. A return value of 0 signifies that this load context is not for
* a nested frame.
*/
readonly attribute unsigned long long nestedFrameId;
/**
* Check whether the load is happening in a particular type of application.
*

View File

@ -1936,6 +1936,7 @@ Navigator::DoNewResolve(JSContext* aCx, JS::Handle<JSObject*> aObject,
JS::Handle<jsid> aId,
JS::MutableHandle<JSPropertyDescriptor> aDesc)
{
// Note: The infallibleInit call below depends on this check.
if (!JSID_IS_STRING(aId)) {
return true;
}
@ -1945,7 +1946,8 @@ Navigator::DoNewResolve(JSContext* aCx, JS::Handle<JSObject*> aObject,
return Throw(aCx, NS_ERROR_NOT_INITIALIZED);
}
nsDependentJSString name(aId);
nsDependentJSString name;
name.infallibleInit(aId);
const nsGlobalNameStruct* name_struct =
nameSpaceManager->LookupNavigatorName(name);

View File

@ -88,6 +88,7 @@ WindowNamedPropertiesHandler::getOwnPropertyDescriptor(JSContext* aCx,
JS::Handle<jsid> aId,
JS::MutableHandle<JSPropertyDescriptor> aDesc)
{
// Note: The infallibleInit call below depends on this check.
if (!JSID_IS_STRING(aId)) {
// Nothing to do if we're resolving a non-string property.
return true;
@ -98,7 +99,8 @@ WindowNamedPropertiesHandler::getOwnPropertyDescriptor(JSContext* aCx,
return true;
}
nsDependentJSString str(aId);
nsDependentJSString str;
str.infallibleInit(aId);
// Grab the DOM window.
nsGlobalWindow* win = GetWindowFromGlobal(global);
@ -176,6 +178,15 @@ WindowNamedPropertiesHandler::ownPropNames(JSContext* aCx,
nsGlobalWindow* win = GetWindowFromGlobal(JS_GetGlobalForObject(aCx, aProxy));
nsTArray<nsString> names;
win->GetSupportedNames(names);
// Filter out the ones we wouldn't expose from getOwnPropertyDescriptor.
// We iterate backwards so we can remove things from the list easily.
for (size_t i = names.Length(); i > 0; ) {
--i; // Now we're pointing at the next name we want to look at
nsIDOMWindow* childWin = win->GetChildWindow(names[i]);
if (!childWin || !ShouldExposeChildWindow(names[i], childWin)) {
names.RemoveElementAt(i);
}
}
if (!AppendNamedPropertyIds(aCx, aProxy, names, false, aProps)) {
return false;
}

View File

@ -312,12 +312,14 @@ nsContentPermissionRequestProxy::Allow(JS::HandleValue aChoices)
if (mPermissionRequests[i].type().EqualsLiteral("audio-capture")) {
GonkPermissionService::GetInstance()->addGrantInfo(
"android.permission.RECORD_AUDIO",
static_cast<TabParent*>(mParent->Manager())->Manager()->Pid());
static_cast<TabParent*>(
mParent->Manager())->Manager()->AsContentParent()->Pid());
}
if (mPermissionRequests[i].type().EqualsLiteral("video-capture")) {
GonkPermissionService::GetInstance()->addGrantInfo(
"android.permission.CAMERA",
static_cast<TabParent*>(mParent->Manager())->Manager()->Pid());
static_cast<TabParent*>(
mParent->Manager())->Manager()->AsContentParent()->Pid());
}
}
#endif

View File

@ -2661,7 +2661,10 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
nsScriptNameSpaceManager *nameSpaceManager = GetNameSpaceManager();
NS_ENSURE_TRUE(nameSpaceManager, NS_ERROR_NOT_INITIALIZED);
nsDependentJSString name(id);
// Note - Our only caller is nsGlobalWindow::DoNewResolve, which checks that
// JSID_IS_STRING(id) is true.
nsDependentJSString name;
name.infallibleInit(id);
const char16_t *class_name = nullptr;
const nsGlobalNameStruct *name_struct =

View File

@ -4270,6 +4270,7 @@ nsGlobalWindow::DoNewResolve(JSContext* aCx, JS::Handle<JSObject*> aObj,
{
MOZ_ASSERT(IsInnerWindow());
// Note: The infallibleInit call in GlobalResolve depends on this check.
if (!JSID_IS_STRING(aId)) {
return true;
}

View File

@ -141,62 +141,71 @@ public:
class nsDependentJSString : public nsDependentString
{
public:
/**
* In the case of string ids, getting the string's chars is infallible, so
* the dependent string can be constructed directly.
*/
explicit nsDependentJSString(JS::Handle<jsid> id)
: nsDependentString(JS_GetInternedStringChars(JSID_TO_STRING(id)),
JS_GetStringLength(JSID_TO_STRING(id)))
{
}
/**
* Ditto for flat strings.
* nsDependentJSString should be default constructed, which leaves it empty
* (this->IsEmpty()), and initialized with one of the init() or infallibleInit()
* methods below.
*/
explicit nsDependentJSString(JSFlatString* fstr)
: nsDependentString(JS_GetFlatStringChars(fstr),
JS_GetStringLength(JS_FORGET_STRING_FLATNESS(fstr)))
{
}
/**
* For all other strings, the nsDependentJSString object should be default
* constructed, which leaves it empty (this->IsEmpty()), and initialized with
* one of the init() methods below.
*/
nsDependentJSString()
{
}
nsDependentJSString() {}
bool init(JSContext* aContext, JSString* str)
{
size_t length;
const jschar* chars = JS_GetStringCharsZAndLength(aContext, str, &length);
if (!chars)
return false;
size_t length;
const jschar* chars = JS_GetStringCharsZAndLength(aContext, str, &length);
if (!chars) {
return false;
}
NS_ASSERTION(IsEmpty(), "init() on initialized string");
nsDependentString* base = this;
new(base) nsDependentString(chars, length);
return true;
infallibleInit(chars, length);
return true;
}
bool init(JSContext* aContext, const JS::Value &v)
{
if (v.isString()) {
return init(aContext, v.toString());
}
// Stringify, making sure not to run script.
JS::Rooted<JSString*> str(aContext);
if (v.isObject()) {
str = JS_NewStringCopyZ(aContext, "[Object]");
} else {
JS::Rooted<JS::Value> rootedVal(aContext, v);
str = JS::ToString(aContext, rootedVal);
}
return str && init(aContext, str);
}
void init(JSFlatString* fstr)
bool init(JSContext* aContext, jsid id)
{
MOZ_ASSERT(IsEmpty(), "init() on initialized string");
new(this) nsDependentJSString(fstr);
JS::Rooted<JS::Value> v(aContext);
return JS_IdToValue(aContext, id, &v) && init(aContext, v);
}
~nsDependentJSString()
void infallibleInit(const char16_t* aChars, size_t aLength)
{
MOZ_ASSERT(IsEmpty(), "init() on initialized string");
nsDependentString* base = this;
new (base) nsDependentString(aChars, aLength);
}
// For use when JSID_IS_STRING(id) is known to be true.
void infallibleInit(jsid id)
{
MOZ_ASSERT(JSID_IS_STRING(id));
infallibleInit(JS_GetInternedStringChars(JSID_TO_STRING(id)),
JS_GetStringLength(JSID_TO_STRING(id)));
}
void infallibleInit(JSFlatString* fstr)
{
infallibleInit(JS_GetFlatStringChars(fstr), JS_GetStringLength(JS_FORGET_STRING_FLATNESS(fstr)));
}
~nsDependentJSString() {}
};
#endif /* nsJSUtils_h__ */

View File

@ -0,0 +1,8 @@
<!DOCTYPE html>
<html>
<head>
<script>
window.name = location.search.substring(1);
</script>
</head>
</html>

View File

@ -7,6 +7,7 @@ support-files =
iframe_messageChannel_post.html
file_empty.html
iframe_postMessage_solidus.html
file_setname.html
[test_appname_override.html]
[test_audioWindowUtils.html]
@ -73,4 +74,5 @@ skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop spec
[test_window_enumeration.html]
[test_window_extensible.html]
[test_window_indexing.html]
[test_window_named_frame_enumeration.html]
[test_writable-replaceable.html]

View File

@ -0,0 +1,96 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1019417
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1019417</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript">
/** Test for Bug 1019417 **/
SimpleTest.waitForExplicitFinish();
addLoadEvent(function() {
var names1 = Object.getOwnPropertyNames(window);
var names2 = [];
var gsp = Object.getPrototypeOf(Window.prototype);
var names3 = Object.getOwnPropertyNames(gsp);
for (var i in window) {
names2.push(i);
}
is(names1.indexOf(""), -1,
"Frame with no name or empty name should not be in our own prop list");
is(names2.indexOf(""), -1,
"Frame with no name or empty name should not be in our enumeration list");
is(names3.indexOf(""), -1,
"Frame with no name or empty name should not be in GSP own prop list");
is(names1.indexOf("x"), -1,
"Frame with about:blank loaded should not be in our own prop list");
isnot(names2.indexOf("x"), -1,
"Frame with about:blank loaded should be in our enumeration list");
isnot(names3.indexOf("x"), -1,
"Frame with about:blank loaded should be in GSP own prop list");
is(names1.indexOf("y"), -1,
"Frame with same-origin loaded should not be in our own prop list");
isnot(names2.indexOf("y"), -1,
"Frame with same-origin loaded should be in our enumeration list");
isnot(names3.indexOf("y"), -1,
"Frame with same-origin loaded should be in GSP own prop list");
is(names1.indexOf("z"), -1,
"Frame with cross-origin loaded should not be in our own prop list");
isnot(names2.indexOf("z"), -1,
"Frame with cross-origin loaded should be in our enumeration list");
isnot(names3.indexOf("z"), -1,
"Frame with cross-origin loaded should be in GSPown prop list");
is(names1.indexOf("sameorigin"), -1,
"Frame with same-origin changed name should not be in our own prop list");
isnot(names2.indexOf("sameorigin"), -1,
"Frame with same-origin changed name should be in our enumeration list");
isnot(names3.indexOf("sameorigin"), -1,
"Frame with same-origin changed name should be in GSP own prop list");
is(names1.indexOf("crossorigin"), -1,
"Frame with cross-origin changed name should not be in our own prop list");
is(names2.indexOf("crossorigin"), -1,
"Frame with cross-origin changed name should not be in our enumeration list");
is(names3.indexOf("crossorigin"), -1,
"Frame with cross-origin changed name should not be in GSP own prop list");
ise(Object.getOwnPropertyDescriptor(gsp, ""), undefined,
"Should not have empty string as a named frame");
isnot(Object.getOwnPropertyDescriptor(gsp, "x"), undefined,
"Should have about:blank subframe as a named frame");
isnot(Object.getOwnPropertyDescriptor(gsp, "y"), undefined,
"Should have same-origin subframe as a named frame");
isnot(Object.getOwnPropertyDescriptor(gsp, "z"), undefined,
"Should have cross-origin subframe as a named frame");
isnot(Object.getOwnPropertyDescriptor(gsp, "sameorigin"), undefined,
"Should have same-origin changed name as a named frame");
ise(Object.getOwnPropertyDescriptor(gsp, "crossorigin"), undefined,
"Should not have cross-origin-origin changed name as a named frame");
SimpleTest.finish();
});
</script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1019417">Mozilla Bug 1019417</a>
<p id="display"></p>
<div id="content" style="display: none">
<iframe></iframe>
<iframe name=""></iframe>
<iframe name="x"></iframe>
<iframe name="y"
src="http://mochi.test:8888/tests/dom/base/test/file_empty.html"></iframe>
<iframe name="z"
src="http://example.com/tests/dom/base/test/file_empty.html"></iframe>
<iframe name="v"
src="http://mochi.test:8888/tests/dom/base/test/file_setname.html?sameorigin"></iframe>
<iframe name="w"
src="http://example.com/tests/dom/base/test/file_setname.html?crossorigin"></iframe>
</div>
<pre id="test">
</pre>
</body>
</html>

View File

@ -442,9 +442,12 @@ AuthPromptWrapper.prototype = {
_canGetParentElement: function(channel) {
try {
let frame = channel.notificationCallbacks.getInterface(Ci.nsILoadContext).topFrameElement;
if (!frame)
return false;
let context = channel.notificationCallbacks.getInterface(Ci.nsILoadContext);
let frame = context.topFrameElement;
if (!frame) {
// This function returns a boolean value
return !!context.nestedFrameId;
}
if (!BrowserElementPromptService.getBrowserElementParentForFrame(frame))
return false;

View File

@ -1133,7 +1133,7 @@ ContinueHelper::SendResponseToChildProcess(nsresult aResultCode)
IDBDatabase* database = mTransaction->Database();
NS_ASSERTION(database, "This should never be null!");
ContentParent* contentParent = database->GetContentParent();
nsIContentParent* contentParent = database->GetContentParent();
NS_ASSERTION(contentParent, "This should never be null!");
FileManager* fileManager = database->Manager();

View File

@ -11,7 +11,7 @@
#include "mozilla/EventDispatcher.h"
#include "mozilla/Mutex.h"
#include "mozilla/storage.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/nsIContentParent.h"
#include "mozilla/dom/DOMStringList.h"
#include "mozilla/dom/DOMStringListBinding.h"
#include "mozilla/dom/quota/Client.h"
@ -39,7 +39,7 @@
#include "mozilla/dom/IDBDatabaseBinding.h"
USING_INDEXEDDB_NAMESPACE
using mozilla::dom::ContentParent;
using mozilla::dom::nsIContentParent;
using mozilla::dom::quota::AssertIsOnIOThread;
using mozilla::dom::quota::Client;
using mozilla::dom::quota::QuotaManager;
@ -183,7 +183,7 @@ IDBDatabase::Create(IDBWrapperCache* aOwnerCache,
already_AddRefed<DatabaseInfo> aDatabaseInfo,
const nsACString& aASCIIOrigin,
FileManager* aFileManager,
mozilla::dom::ContentParent* aContentParent)
mozilla::dom::nsIContentParent* aContentParent)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
NS_ASSERTION(aFactory, "Null pointer!");

View File

@ -28,7 +28,7 @@ class nsPIDOMWindow;
namespace mozilla {
class EventChainPostVisitor;
namespace dom {
class ContentParent;
class nsIContentParent;
namespace quota {
class Client;
}
@ -68,7 +68,7 @@ public:
already_AddRefed<DatabaseInfo> aDatabaseInfo,
const nsACString& aASCIIOrigin,
FileManager* aFileManager,
mozilla::dom::ContentParent* aContentParent);
mozilla::dom::nsIContentParent* aContentParent);
static IDBDatabase*
FromStorage(nsIOfflineStorage* aStorage);
@ -153,7 +153,7 @@ public:
return mActorParent;
}
mozilla::dom::ContentParent*
mozilla::dom::nsIContentParent*
GetContentParent() const
{
return mContentParent;
@ -258,7 +258,7 @@ private:
IndexedDBDatabaseChild* mActorChild;
IndexedDBDatabaseParent* mActorParent;
mozilla::dom::ContentParent* mContentParent;
mozilla::dom::nsIContentParent* mContentParent;
nsRefPtr<mozilla::dom::quota::Client> mQuotaClient;

View File

@ -14,7 +14,7 @@
#include "nsIXPCScriptable.h"
#include <algorithm>
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/nsIContentParent.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/IDBFactoryBinding.h"
#include "mozilla/dom/PBrowserChild.h"
@ -55,7 +55,7 @@ USING_INDEXEDDB_NAMESPACE
USING_QUOTA_NAMESPACE
using mozilla::dom::ContentChild;
using mozilla::dom::ContentParent;
using mozilla::dom::nsIContentParent;
using mozilla::dom::IDBOpenDBOptions;
using mozilla::dom::NonNull;
using mozilla::dom::Optional;
@ -103,7 +103,7 @@ nsresult
IDBFactory::Create(nsPIDOMWindow* aWindow,
const nsACString& aGroup,
const nsACString& aASCIIOrigin,
ContentParent* aContentParent,
nsIContentParent* aContentParent,
IDBFactory** aFactory)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
@ -157,7 +157,7 @@ IDBFactory::Create(nsPIDOMWindow* aWindow,
TabChild* tabChild = TabChild::GetFrom(aWindow);
IDB_ENSURE_TRUE(tabChild, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
IndexedDBChild* actor = new IndexedDBChild(origin);
IndexedDBChild* actor = new IndexedDBChild(tabChild, origin);
bool allowed;
tabChild->SendPIndexedDBConstructor(actor, group, origin, &allowed);
@ -179,7 +179,7 @@ IDBFactory::Create(nsPIDOMWindow* aWindow,
nsresult
IDBFactory::Create(JSContext* aCx,
JS::Handle<JSObject*> aOwningObject,
ContentParent* aContentParent,
nsIContentParent* aContentParent,
IDBFactory** aFactory)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
@ -216,7 +216,7 @@ IDBFactory::Create(JSContext* aCx,
ContentChild* contentChild = ContentChild::GetSingleton();
IDB_ENSURE_TRUE(contentChild, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
IndexedDBChild* actor = new IndexedDBChild(origin);
IndexedDBChild* actor = new IndexedDBChild(contentChild, origin);
contentChild->SendPIndexedDBConstructor(actor);
@ -229,7 +229,7 @@ IDBFactory::Create(JSContext* aCx,
// static
nsresult
IDBFactory::Create(ContentParent* aContentParent,
IDBFactory::Create(nsIContentParent* aContentParent,
IDBFactory** aFactory)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");

View File

@ -26,7 +26,7 @@ namespace mozilla {
class ErrorResult;
namespace dom {
class ContentParent;
class nsIContentParent;
class IDBOpenDBOptions;
namespace indexedDB {
@ -42,7 +42,7 @@ struct ObjectStoreInfo;
class IDBFactory MOZ_FINAL : public nsISupports,
public nsWrapperCache
{
typedef mozilla::dom::ContentParent ContentParent;
typedef mozilla::dom::nsIContentParent nsIContentParent;
typedef mozilla::dom::quota::PersistenceType PersistenceType;
typedef nsTArray<nsRefPtr<ObjectStoreInfo> > ObjectStoreInfoArray;
typedef mozilla::dom::quota::StoragePrivilege StoragePrivilege;
@ -55,12 +55,12 @@ public:
static nsresult Create(nsPIDOMWindow* aWindow,
const nsACString& aGroup,
const nsACString& aASCIIOrigin,
ContentParent* aContentParent,
nsIContentParent* aContentParent,
IDBFactory** aFactory);
// Called when using IndexedDB from a window in the current process.
static nsresult Create(nsPIDOMWindow* aWindow,
ContentParent* aContentParent,
nsIContentParent* aContentParent,
IDBFactory** aFactory)
{
return Create(aWindow, EmptyCString(), EmptyCString(), aContentParent,
@ -71,12 +71,12 @@ public:
// process.
static nsresult Create(JSContext* aCx,
JS::Handle<JSObject*> aOwningObject,
ContentParent* aContentParent,
nsIContentParent* aContentParent,
IDBFactory** aFactory);
// Called when using IndexedDB from a JS component or a JSM in a different
// process or from a C++ component.
static nsresult Create(ContentParent* aContentParent,
static nsresult Create(nsIContentParent* aContentParent,
IDBFactory** aFactory);
static already_AddRefed<nsIFileURL>
@ -217,7 +217,7 @@ private:
IndexedDBChild* mActorChild;
IndexedDBParent* mActorParent;
mozilla::dom::ContentParent* mContentParent;
mozilla::dom::nsIContentParent* mContentParent;
bool mRootedOwningObject;
};

View File

@ -1300,7 +1300,7 @@ GetHelper::SendResponseToChildProcess(nsresult aResultCode)
IDBDatabase* database = mIndex->ObjectStore()->Transaction()->Database();
NS_ASSERTION(database, "This should never be null!");
ContentParent* contentParent = database->GetContentParent();
nsIContentParent* contentParent = database->GetContentParent();
NS_ASSERTION(contentParent, "This should never be null!");
FileManager* fileManager = database->Manager();
@ -1674,7 +1674,7 @@ GetAllHelper::SendResponseToChildProcess(nsresult aResultCode)
IDBDatabase* database = mIndex->ObjectStore()->Transaction()->Database();
NS_ASSERTION(database, "This should never be null!");
ContentParent* contentParent = database->GetContentParent();
nsIContentParent* contentParent = database->GetContentParent();
NS_ASSERTION(contentParent, "This should never be null!");
FileManager* fileManager = database->Manager();
@ -2358,7 +2358,7 @@ OpenCursorHelper::SendResponseToChildProcess(nsresult aResultCode)
IDBDatabase* database = mIndex->ObjectStore()->Transaction()->Database();
NS_ASSERTION(database, "This should never be null!");
ContentParent* contentParent = database->GetContentParent();
nsIContentParent* contentParent = database->GetContentParent();
NS_ASSERTION(contentParent, "This should never be null!");
FileManager* fileManager = database->Manager();

View File

@ -14,9 +14,10 @@
#include <algorithm>
#include "jsfriendapi.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/nsIContentParent.h"
#include "mozilla/dom/FileHandleBinding.h"
#include "mozilla/dom/StructuredCloneTags.h"
#include "mozilla/dom/TabChild.h"
#include "mozilla/dom/ipc/Blob.h"
#include "mozilla/dom/quota/FileStreams.h"
#include "mozilla/Endian.h"
@ -111,7 +112,8 @@ public:
virtual nsresult Dispatch(nsIEventTarget* aDatabaseThread) MOZ_OVERRIDE;
virtual nsresult
PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams) = 0;
PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams,
nsIContentChild* aBlobCreator) = 0;
virtual nsresult
UnpackResponseFromParentProcess(const ResponseValue& aResponseValue) = 0;
@ -184,7 +186,8 @@ public:
virtual void ReleaseMainThreadObjects() MOZ_OVERRIDE;
virtual nsresult
PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams) MOZ_OVERRIDE;
PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams,
nsIContentChild* aBlobCreator) MOZ_OVERRIDE;
virtual ChildProcessSendResult
SendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE;
@ -228,7 +231,8 @@ public:
virtual void ReleaseMainThreadObjects() MOZ_OVERRIDE;
virtual nsresult
PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams) MOZ_OVERRIDE;
PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams,
nsIContentChild* aBlobCreator) MOZ_OVERRIDE;
virtual ChildProcessSendResult
SendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE;
@ -263,7 +267,8 @@ public:
JS::MutableHandle<JS::Value> aVal) MOZ_OVERRIDE;
virtual nsresult
PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams) MOZ_OVERRIDE;
PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams,
nsIContentChild* aBlobCreator) MOZ_OVERRIDE;
virtual ChildProcessSendResult
SendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE;
@ -286,7 +291,8 @@ public:
MOZ_OVERRIDE;
virtual nsresult
PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams) MOZ_OVERRIDE;
PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams,
nsIContentChild* aBlobCreator) MOZ_OVERRIDE;
virtual ChildProcessSendResult
SendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE;
@ -322,7 +328,8 @@ public:
virtual void ReleaseMainThreadObjects() MOZ_OVERRIDE;
virtual nsresult
PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams) MOZ_OVERRIDE;
PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams,
nsIContentChild* aBlobCreator) MOZ_OVERRIDE;
virtual ChildProcessSendResult
SendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE;
@ -373,7 +380,8 @@ public:
ReleaseMainThreadObjects() MOZ_OVERRIDE;
virtual nsresult
PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams) MOZ_OVERRIDE;
PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams,
nsIContentChild* aBlobCreator) MOZ_OVERRIDE;
virtual ChildProcessSendResult
SendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE;
@ -480,7 +488,8 @@ public:
virtual void ReleaseMainThreadObjects() MOZ_OVERRIDE;
virtual nsresult
PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams) MOZ_OVERRIDE;
PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams,
nsIContentChild* aBlobCreator) MOZ_OVERRIDE;
virtual ChildProcessSendResult
SendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE;
@ -522,7 +531,8 @@ public:
ReleaseMainThreadObjects() MOZ_OVERRIDE;
virtual nsresult
PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams) MOZ_OVERRIDE;
PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams,
nsIContentChild* aBlobCreator) MOZ_OVERRIDE;
virtual ChildProcessSendResult
SendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE;
@ -560,7 +570,8 @@ public:
virtual void ReleaseMainThreadObjects() MOZ_OVERRIDE;
virtual nsresult
PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams) MOZ_OVERRIDE;
PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams,
nsIContentChild* aBlobCreator) MOZ_OVERRIDE;
virtual ChildProcessSendResult
SendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE;
@ -1748,7 +1759,7 @@ IDBObjectStore::ConvertActorsToBlobs(
// static
nsresult
IDBObjectStore::ConvertBlobsToActors(
ContentParent* aContentParent,
nsIContentParent* aContentParent,
FileManager* aFileManager,
const nsTArray<StructuredCloneFile>& aFiles,
InfallibleTArray<PBlobParent*>& aActors)
@ -3040,7 +3051,22 @@ ObjectStoreHelper::Dispatch(nsIEventTarget* aDatabaseThread)
NS_ASSERTION(objectStoreActor, "Must have an actor here!");
ObjectStoreRequestParams params;
nsresult rv = PackArgumentsForParentProcess(params);
// Our "parent" process may be either the root process or another content
// process if this indexedDB is managed by a PBrowser that is managed by a
// PContentBridge. We need to find which one it is so that we can create
// PBlobs that are managed by the right nsIContentChild.
IndexedDBChild* rootActor =
static_cast<IndexedDBChild*>(objectStoreActor->Manager()->
Manager()->Manager());
nsIContentChild* blobCreator;
if (rootActor->GetManagerContent()) {
blobCreator = rootActor->GetManagerContent();
} else {
blobCreator = rootActor->GetManagerTab()->Manager();
}
nsresult rv = PackArgumentsForParentProcess(params, blobCreator);
IDB_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
NoDispatchEventTarget target;
@ -3320,10 +3346,12 @@ AddHelper::ReleaseMainThreadObjects()
}
nsresult
AddHelper::PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams)
AddHelper::PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams,
nsIContentChild* aBlobCreator)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
NS_ASSERTION(!IndexedDatabaseManager::IsMainProcess(), "Wrong process!");
NS_ASSERTION(aBlobCreator, "Must have a valid creator!");
PROFILER_MAIN_THREAD_LABEL("AddHelper", "PackArgumentsForParentProcess",
js::ProfileEntry::Category::STORAGE);
@ -3341,8 +3369,7 @@ AddHelper::PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams)
InfallibleTArray<PBlobChild*>& blobsChild = commonParams.blobsChild();
blobsChild.SetCapacity(fileCount);
ContentChild* contentChild = ContentChild::GetSingleton();
NS_ASSERTION(contentChild, "This should never be null!");
NS_ASSERTION(aBlobCreator, "This should never be null!");
for (uint32_t index = 0; index < fileCount; index++) {
const StructuredCloneFile& file = files[index];
@ -3351,7 +3378,7 @@ AddHelper::PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams)
NS_ASSERTION(!file.mFileInfo, "This is not yet supported!");
BlobChild* actor =
contentChild->GetOrCreateActorForBlob(file.mFile);
aBlobCreator->GetOrCreateActorForBlob(file.mFile);
if (!actor) {
IDB_REPORT_INTERNAL_ERR();
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
@ -3487,11 +3514,13 @@ GetHelper::ReleaseMainThreadObjects()
}
nsresult
GetHelper::PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams)
GetHelper::PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams,
nsIContentChild* aBlobCreator)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
NS_ASSERTION(!IndexedDatabaseManager::IsMainProcess(), "Wrong process!");
NS_ASSERTION(mKeyRange, "This should never be null!");
NS_ASSERTION(aBlobCreator, "Must have a valid creator!");
PROFILER_MAIN_THREAD_LABEL("GetHelper", "PackArgumentsForParentProcess [IDBObjectStore.cpp]",
js::ProfileEntry::Category::STORAGE);
@ -3522,7 +3551,7 @@ GetHelper::SendResponseToChildProcess(nsresult aResultCode)
IDBDatabase* database = mObjectStore->Transaction()->Database();
NS_ASSERTION(database, "This should never be null!");
ContentParent* contentParent = database->GetContentParent();
nsIContentParent* contentParent = database->GetContentParent();
NS_ASSERTION(contentParent, "This should never be null!");
FileManager* fileManager = database->Manager();
@ -3625,11 +3654,13 @@ DeleteHelper::GetSuccessResult(JSContext* aCx,
}
nsresult
DeleteHelper::PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams)
DeleteHelper::PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams,
nsIContentChild* aBlobCreator)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
NS_ASSERTION(!IndexedDatabaseManager::IsMainProcess(), "Wrong process!");
NS_ASSERTION(mKeyRange, "This should never be null!");
NS_ASSERTION(aBlobCreator, "Must have a valid creator!");
PROFILER_MAIN_THREAD_LABEL("DeleteHelper", "PackArgumentsForParentProcess",
js::ProfileEntry::Category::STORAGE);
@ -3708,10 +3739,12 @@ ClearHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
}
nsresult
ClearHelper::PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams)
ClearHelper::PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams,
nsIContentChild* aBlobCreator)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
NS_ASSERTION(!IndexedDatabaseManager::IsMainProcess(), "Wrong process!");
NS_ASSERTION(aBlobCreator, "Must have a valid creator!");
PROFILER_MAIN_THREAD_LABEL("ClearHelper", "PackArgumentsForParentProcess",
js::ProfileEntry::Category::STORAGE);
@ -3942,11 +3975,12 @@ OpenCursorHelper::ReleaseMainThreadObjects()
}
nsresult
OpenCursorHelper::PackArgumentsForParentProcess(
ObjectStoreRequestParams& aParams)
OpenCursorHelper::PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams,
nsIContentChild* aBlobCreator)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
NS_ASSERTION(!IndexedDatabaseManager::IsMainProcess(), "Wrong process!");
NS_ASSERTION(aBlobCreator, "Must have a valid creator!");
PROFILER_MAIN_THREAD_LABEL("OpenCursorHelper", "PackArgumentsForParentProcess [IDBObjectStore.cpp]",
js::ProfileEntry::Category::STORAGE);
@ -3987,7 +4021,7 @@ OpenCursorHelper::SendResponseToChildProcess(nsresult aResultCode)
IDBDatabase* database = mObjectStore->Transaction()->Database();
NS_ASSERTION(database, "This should never be null!");
ContentParent* contentParent = database->GetContentParent();
nsIContentParent* contentParent = database->GetContentParent();
NS_ASSERTION(contentParent, "This should never be null!");
FileManager* fileManager = database->Manager();
@ -4265,11 +4299,12 @@ OpenKeyCursorHelper::ReleaseMainThreadObjects()
}
nsresult
OpenKeyCursorHelper::PackArgumentsForParentProcess(
ObjectStoreRequestParams& aParams)
OpenKeyCursorHelper::PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams,
nsIContentChild* aBlobCreator)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!IndexedDatabaseManager::IsMainProcess());
NS_ASSERTION(aBlobCreator, "Must have a valid creator!");
PROFILER_MAIN_THREAD_LABEL("OpenKeyCursorHelper", "PackArgumentsForParentProcess [IDBObjectStore.cpp]",
js::ProfileEntry::Category::STORAGE);
@ -4705,10 +4740,12 @@ GetAllHelper::ReleaseMainThreadObjects()
}
nsresult
GetAllHelper::PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams)
GetAllHelper::PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams,
nsIContentChild* aBlobCreator)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
NS_ASSERTION(!IndexedDatabaseManager::IsMainProcess(), "Wrong process!");
NS_ASSERTION(aBlobCreator, "Must have a valid creator!");
PROFILER_MAIN_THREAD_LABEL("GetAllHelper", "PackArgumentsForParentProcess [IDBObjectStore.cpp]",
js::ProfileEntry::Category::STORAGE);
@ -4747,7 +4784,7 @@ GetAllHelper::SendResponseToChildProcess(nsresult aResultCode)
IDBDatabase* database = mObjectStore->Transaction()->Database();
NS_ASSERTION(database, "This should never be null!");
ContentParent* contentParent = database->GetContentParent();
nsIContentParent* contentParent = database->GetContentParent();
NS_ASSERTION(contentParent, "This should never be null!");
FileManager* fileManager = database->Manager();
@ -4951,11 +4988,12 @@ GetAllKeysHelper::ReleaseMainThreadObjects()
}
nsresult
GetAllKeysHelper::PackArgumentsForParentProcess(
ObjectStoreRequestParams& aParams)
GetAllKeysHelper::PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams,
nsIContentChild* aBlobCreator)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!IndexedDatabaseManager::IsMainProcess());
NS_ASSERTION(aBlobCreator, "Must have a valid creator!");
PROFILER_MAIN_THREAD_LABEL("GetAllKeysHelper", "PackArgumentsForParentProcess [IDBObjectStore.cpp]",
js::ProfileEntry::Category::STORAGE);
@ -5103,10 +5141,12 @@ CountHelper::ReleaseMainThreadObjects()
}
nsresult
CountHelper::PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams)
CountHelper::PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams,
nsIContentChild* aBlobCreator)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
NS_ASSERTION(!IndexedDatabaseManager::IsMainProcess(), "Wrong process!");
NS_ASSERTION(aBlobCreator, "Must have a valid creator!");
PROFILER_MAIN_THREAD_LABEL("CountHelper", "PackArgumentsForParentProcess [IDBObjectStore.cpp]",
js::ProfileEntry::Category::STORAGE);

View File

@ -26,7 +26,7 @@ class nsPIDOMWindow;
namespace mozilla {
namespace dom {
class ContentParent;
class nsIContentParent;
class PBlobChild;
class PBlobParent;
}
@ -122,7 +122,7 @@ public:
// Called only in the main process.
static nsresult
ConvertBlobsToActors(ContentParent* aContentParent,
ConvertBlobsToActors(nsIContentParent* aContentParent,
FileManager* aFileManager,
const nsTArray<StructuredCloneFile>& aFiles,
InfallibleTArray<PBlobParent*>& aActors);

View File

@ -19,7 +19,7 @@ class mozIStorageConnection;
namespace mozilla {
namespace dom {
class ContentParent;
class nsIContentParent;
}
}
@ -42,7 +42,7 @@ public:
uint64_t aRequestedVersion,
PersistenceType aPersistenceType,
bool aForDeletion,
mozilla::dom::ContentParent* aContentParent,
mozilla::dom::nsIContentParent* aContentParent,
StoragePrivilege aPrivilege)
: HelperBase(aRequest), mOpenDBRequest(aRequest), mName(aName),
mGroup(aGroup), mASCIIOrigin(aASCIIOrigin),
@ -137,7 +137,7 @@ protected:
bool mForDeletion;
StoragePrivilege mPrivilege;
nsCString mDatabaseId;
mozilla::dom::ContentParent* mContentParent;
mozilla::dom::nsIContentParent* mContentParent;
// Out-params.
nsTArray<nsRefPtr<ObjectStoreInfo> > mObjectStores;

View File

@ -159,12 +159,31 @@ public:
* IndexedDBChild
******************************************************************************/
IndexedDBChild::IndexedDBChild(const nsCString& aASCIIOrigin)
: mFactory(nullptr), mASCIIOrigin(aASCIIOrigin)
IndexedDBChild::IndexedDBChild(ContentChild* aContentChild,
const nsCString& aASCIIOrigin)
: mFactory(nullptr)
, mManagerContent(aContentChild)
, mManagerTab(nullptr)
, mASCIIOrigin(aASCIIOrigin)
#ifdef DEBUG
, mDisconnected(false)
, mDisconnected(false)
#endif
{
MOZ_ASSERT(aContentChild);
MOZ_COUNT_CTOR(IndexedDBChild);
}
IndexedDBChild::IndexedDBChild(TabChild* aTabChild,
const nsCString& aASCIIOrigin)
: mFactory(nullptr)
, mManagerContent(nullptr)
, mManagerTab(aTabChild)
, mASCIIOrigin(aASCIIOrigin)
#ifdef DEBUG
, mDisconnected(false)
#endif
{
MOZ_ASSERT(aTabChild);
MOZ_COUNT_CTOR(IndexedDBChild);
}

View File

@ -19,6 +19,13 @@
#include "mozilla/dom/indexedDB/PIndexedDBRequestChild.h"
#include "mozilla/dom/indexedDB/PIndexedDBTransactionChild.h"
namespace mozilla {
namespace dom {
class ContentChild;
class TabChild;
} // dom
} // mozilla
BEGIN_INDEXEDDB_NAMESPACE
class AsyncConnectionHelper;
@ -36,6 +43,9 @@ class IDBTransactionListener;
class IndexedDBChild : public PIndexedDBChild
{
IDBFactory* mFactory;
ContentChild* mManagerContent;
TabChild* mManagerTab;
nsCString mASCIIOrigin;
#ifdef DEBUG
@ -43,7 +53,8 @@ class IndexedDBChild : public PIndexedDBChild
#endif
public:
IndexedDBChild(const nsCString& aASCIIOrigin);
IndexedDBChild(ContentChild* aContentChild, const nsCString& aASCIIOrigin);
IndexedDBChild(TabChild* aTabChild, const nsCString& aASCIIOrigin);
virtual ~IndexedDBChild();
const nsCString&
@ -52,6 +63,18 @@ public:
return mASCIIOrigin;
}
ContentChild*
GetManagerContent() const
{
return mManagerContent;
}
TabChild*
GetManagerTab() const
{
return mManagerTab;
}
void
SetFactory(IDBFactory* aFactory);

View File

@ -12,6 +12,8 @@
#include "mozilla/DebugOnly.h"
#include "mozilla/Monitor.h"
#include "mozilla/unused.h"
#include "mozilla/dom/nsIContentParent.h"
#include "mozilla/dom/nsIContentChild.h"
#include "mozilla/dom/PBlobStreamChild.h"
#include "mozilla/dom/PBlobStreamParent.h"
#include "mozilla/dom/PFileDescriptorSetParent.h"
@ -1055,7 +1057,7 @@ RemoteBlob::GetPBlob()
* BlobChild
******************************************************************************/
BlobChild::BlobChild(ContentChild* aManager, nsIDOMBlob* aBlob)
BlobChild::BlobChild(nsIContentChild* aManager, nsIDOMBlob* aBlob)
: mBlob(aBlob)
, mRemoteBlob(nullptr)
, mStrongManager(aManager)
@ -1072,7 +1074,7 @@ BlobChild::BlobChild(ContentChild* aManager, nsIDOMBlob* aBlob)
mBlobIsFile = !!file;
}
BlobChild::BlobChild(ContentChild* aManager,
BlobChild::BlobChild(nsIContentChild* aManager,
const ChildBlobConstructorParams& aParams)
: mBlob(nullptr)
, mRemoteBlob(nullptr)
@ -1104,7 +1106,7 @@ BlobChild::~BlobChild()
}
BlobChild*
BlobChild::Create(ContentChild* aManager,
BlobChild::Create(nsIContentChild* aManager,
const ChildBlobConstructorParams& aParams)
{
MOZ_ASSERT(NS_IsMainThread());
@ -1204,6 +1206,12 @@ BlobChild::SetMysteryBlobInfo(const nsString& aContentType, uint64_t aLength)
return SendResolveMystery(params);
}
nsIContentChild*
BlobChild::Manager()
{
return mStrongManager;
}
already_AddRefed<BlobChild::RemoteBlob>
BlobChild::CreateRemoteBlob(const ChildBlobConstructorParams& aParams)
{
@ -1763,7 +1771,7 @@ RemoteBlob::GetPBlob()
* BlobParent
******************************************************************************/
BlobParent::BlobParent(ContentParent* aManager, nsIDOMBlob* aBlob)
BlobParent::BlobParent(nsIContentParent* aManager, nsIDOMBlob* aBlob)
: mBlob(aBlob)
, mRemoteBlob(nullptr)
, mStrongManager(aManager)
@ -1780,7 +1788,7 @@ BlobParent::BlobParent(ContentParent* aManager, nsIDOMBlob* aBlob)
mBlobIsFile = !!file;
}
BlobParent::BlobParent(ContentParent* aManager,
BlobParent::BlobParent(nsIContentParent* aManager,
const ParentBlobConstructorParams& aParams)
: mBlob(nullptr)
, mRemoteBlob(nullptr)
@ -1813,7 +1821,7 @@ BlobParent::~BlobParent()
}
BlobParent*
BlobParent::Create(ContentParent* aManager,
BlobParent::Create(nsIContentParent* aManager,
const ParentBlobConstructorParams& aParams)
{
MOZ_ASSERT(NS_IsMainThread());
@ -1920,6 +1928,12 @@ BlobParent::SetMysteryBlobInfo(const nsString& aContentType, uint64_t aLength)
return SendResolveMystery(params);
}
nsIContentParent*
BlobParent::Manager()
{
return mStrongManager;
}
already_AddRefed<BlobParent::RemoteBlob>
BlobParent::CreateRemoteBlob(const ParentBlobConstructorParams& aParams)
{

View File

@ -18,22 +18,22 @@ template <class> class nsRevocableEventPtr;
namespace mozilla {
namespace dom {
class ContentChild;
class ContentParent;
class nsIContentChild;
class nsIContentParent;
class PBlobStreamChild;
class PBlobStreamParent;
class BlobChild MOZ_FINAL
: public PBlobChild
{
friend class ContentChild;
friend class nsIContentChild;
class RemoteBlob;
friend class RemoteBlob;
nsIDOMBlob* mBlob;
RemoteBlob* mRemoteBlob;
nsRefPtr<ContentChild> mStrongManager;
nsRefPtr<nsIContentChild> mStrongManager;
bool mOwnsBlob;
bool mBlobIsFile;
@ -41,7 +41,7 @@ class BlobChild MOZ_FINAL
public:
// This create function is called on the sending side.
static BlobChild*
Create(ContentChild* aManager, nsIDOMBlob* aBlob)
Create(nsIContentChild* aManager, nsIDOMBlob* aBlob)
{
return new BlobChild(aManager, aBlob);
}
@ -63,19 +63,21 @@ public:
bool
SetMysteryBlobInfo(const nsString& aContentType, uint64_t aLength);
nsIContentChild* Manager();
private:
// This constructor is called on the sending side.
BlobChild(ContentChild* aManager, nsIDOMBlob* aBlob);
BlobChild(nsIContentChild* aManager, nsIDOMBlob* aBlob);
// This constructor is called on the receiving side.
BlobChild(ContentChild* aManager, const ChildBlobConstructorParams& aParams);
BlobChild(nsIContentChild* aManager, const ChildBlobConstructorParams& aParams);
// Only destroyed by ContentChild.
~BlobChild();
// This create function is called on the receiving side by ContentChild.
static BlobChild*
Create(ContentChild* aManager, const ChildBlobConstructorParams& aParams);
Create(nsIContentChild* aManager, const ChildBlobConstructorParams& aParams);
static already_AddRefed<RemoteBlob>
CreateRemoteBlob(const ChildBlobConstructorParams& aParams);
@ -103,7 +105,7 @@ private:
class BlobParent MOZ_FINAL
: public PBlobParent
{
friend class ContentParent;
friend class nsIContentParent;
class OpenStreamRunnable;
friend class OpenStreamRunnable;
@ -113,7 +115,7 @@ class BlobParent MOZ_FINAL
nsIDOMBlob* mBlob;
RemoteBlob* mRemoteBlob;
nsRefPtr<ContentParent> mStrongManager;
nsRefPtr<nsIContentParent> mStrongManager;
// nsIInputStreams backed by files must ensure that the files are actually
// opened and closed on a background thread before we can send their file
@ -130,7 +132,7 @@ class BlobParent MOZ_FINAL
public:
// This create function is called on the sending side.
static BlobParent*
Create(ContentParent* aManager, nsIDOMBlob* aBlob)
Create(nsIContentParent* aManager, nsIDOMBlob* aBlob)
{
return new BlobParent(aManager, aBlob);
}
@ -150,19 +152,21 @@ public:
bool
SetMysteryBlobInfo(const nsString& aContentType, uint64_t aLength);
nsIContentParent* Manager();
private:
// This constructor is called on the sending side.
BlobParent(ContentParent* aManager, nsIDOMBlob* aBlob);
BlobParent(nsIContentParent* aManager, nsIDOMBlob* aBlob);
// This constructor is called on the receiving side.
BlobParent(ContentParent* aManager,
BlobParent(nsIContentParent* aManager,
const ParentBlobConstructorParams& aParams);
~BlobParent();
// This create function is called on the receiving side by ContentParent.
static BlobParent*
Create(ContentParent* aManager, const ParentBlobConstructorParams& aParams);
Create(nsIContentParent* aManager, const ParentBlobConstructorParams& aParams);
static already_AddRefed<RemoteBlob>
CreateRemoteBlob(const ParentBlobConstructorParams& aParams);

View File

@ -0,0 +1,173 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=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 "mozilla/dom/ContentBridgeChild.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/StructuredCloneUtils.h"
#include "mozilla/dom/TabChild.h"
#include "mozilla/dom/ipc/Blob.h"
#include "mozilla/dom/ipc/nsIRemoteBlob.h"
#include "mozilla/ipc/InputStreamUtils.h"
#include "nsDOMFile.h"
#include "JavaScriptChild.h"
using namespace base;
using namespace mozilla::ipc;
using namespace mozilla::jsipc;
namespace mozilla {
namespace dom {
NS_IMPL_ISUPPORTS(ContentBridgeChild, nsIContentChild)
ContentBridgeChild::ContentBridgeChild(Transport* aTransport)
: mTransport(aTransport)
{}
ContentBridgeChild::~ContentBridgeChild()
{
XRE_GetIOMessageLoop()->PostTask(FROM_HERE, new DeleteTask<Transport>(mTransport));
}
void
ContentBridgeChild::ActorDestroy(ActorDestroyReason aWhy)
{
MessageLoop::current()->PostTask(
FROM_HERE,
NewRunnableMethod(this, &ContentBridgeChild::DeferredDestroy));
}
/*static*/ ContentBridgeChild*
ContentBridgeChild::Create(Transport* aTransport, ProcessId aOtherProcess)
{
nsRefPtr<ContentBridgeChild> bridge =
new ContentBridgeChild(aTransport);
ProcessHandle handle;
if (!base::OpenProcessHandle(aOtherProcess, &handle)) {
// XXX need to kill |aOtherProcess|, it's boned
return nullptr;
}
bridge->mSelfRef = bridge;
DebugOnly<bool> ok = bridge->Open(aTransport, handle, XRE_GetIOMessageLoop());
MOZ_ASSERT(ok);
return bridge;
}
void
ContentBridgeChild::DeferredDestroy()
{
mSelfRef = nullptr;
// |this| was just destroyed, hands off
}
bool
ContentBridgeChild::RecvAsyncMessage(const nsString& aMsg,
const ClonedMessageData& aData,
const InfallibleTArray<jsipc::CpowEntry>& aCpows,
const IPC::Principal& aPrincipal)
{
return nsIContentChild::RecvAsyncMessage(aMsg, aData, aCpows, aPrincipal);
}
PBlobChild*
ContentBridgeChild::SendPBlobConstructor(PBlobChild* actor,
const BlobConstructorParams& params)
{
return PContentBridgeChild::SendPBlobConstructor(actor, params);
}
bool
ContentBridgeChild::SendPBrowserConstructor(PBrowserChild* aActor,
const IPCTabContext& aContext,
const uint32_t& aChromeFlags,
const uint64_t& aID,
const bool& aIsForApp,
const bool& aIsForBrowser)
{
return PContentBridgeChild::SendPBrowserConstructor(aActor,
aContext,
aChromeFlags,
aID,
aIsForApp,
aIsForBrowser);
}
// This implementation is identical to ContentChild::GetCPOWManager but we can't
// move it to nsIContentChild because it calls ManagedPJavaScriptChild() which
// only exists in PContentChild and PContentBridgeChild.
jsipc::JavaScriptChild *
ContentBridgeChild::GetCPOWManager()
{
if (ManagedPJavaScriptChild().Length()) {
return static_cast<JavaScriptChild*>(ManagedPJavaScriptChild()[0]);
}
JavaScriptChild* actor = static_cast<JavaScriptChild*>(SendPJavaScriptConstructor());
return actor;
}
mozilla::jsipc::PJavaScriptChild *
ContentBridgeChild::AllocPJavaScriptChild()
{
return nsIContentChild::AllocPJavaScriptChild();
}
bool
ContentBridgeChild::DeallocPJavaScriptChild(PJavaScriptChild *child)
{
return nsIContentChild::DeallocPJavaScriptChild(child);
}
PBrowserChild*
ContentBridgeChild::AllocPBrowserChild(const IPCTabContext &aContext,
const uint32_t& aChromeFlags,
const uint64_t& aID,
const bool& aIsForApp,
const bool& aIsForBrowser)
{
return nsIContentChild::AllocPBrowserChild(aContext,
aChromeFlags,
aID,
aIsForApp,
aIsForBrowser);
}
bool
ContentBridgeChild::DeallocPBrowserChild(PBrowserChild* aChild)
{
return nsIContentChild::DeallocPBrowserChild(aChild);
}
bool
ContentBridgeChild::RecvPBrowserConstructor(PBrowserChild* aActor,
const IPCTabContext& aContext,
const uint32_t& aChromeFlags,
const uint64_t& aID,
const bool& aIsForApp,
const bool& aIsForBrowser)
{
return ContentChild::GetSingleton()->RecvPBrowserConstructor(aActor,
aContext,
aChromeFlags,
aID,
aIsForApp,
aIsForBrowser);
}
PBlobChild*
ContentBridgeChild::AllocPBlobChild(const BlobConstructorParams& aParams)
{
return nsIContentChild::AllocPBlobChild(aParams);
}
bool
ContentBridgeChild::DeallocPBlobChild(PBlobChild* aActor)
{
return nsIContentChild::DeallocPBlobChild(aActor);
}
} // namespace dom
} // namespace mozilla

View File

@ -0,0 +1,80 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_ContentBridgeChild_h
#define mozilla_dom_ContentBridgeChild_h
#include "mozilla/dom/PContentBridgeChild.h"
#include "mozilla/dom/nsIContentChild.h"
namespace mozilla {
namespace dom {
class ContentBridgeChild MOZ_FINAL : public PContentBridgeChild
, public nsIContentChild
{
public:
ContentBridgeChild(Transport* aTransport);
NS_DECL_ISUPPORTS
virtual ~ContentBridgeChild();
static ContentBridgeChild*
Create(Transport* aTransport, ProcessId aOtherProcess);
virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
void DeferredDestroy();
virtual bool RecvAsyncMessage(const nsString& aMsg,
const ClonedMessageData& aData,
const InfallibleTArray<jsipc::CpowEntry>& aCpows,
const IPC::Principal& aPrincipal) MOZ_OVERRIDE;
virtual PBlobChild*
SendPBlobConstructor(PBlobChild* actor,
const BlobConstructorParams& params);
jsipc::JavaScriptChild* GetCPOWManager();
virtual bool SendPBrowserConstructor(PBrowserChild* aActor,
const IPCTabContext& aContext,
const uint32_t& aChromeFlags,
const uint64_t& aID,
const bool& aIsForApp,
const bool& aIsForBrowser) MOZ_OVERRIDE;
protected:
virtual PBrowserChild* AllocPBrowserChild(const IPCTabContext& aContext,
const uint32_t& aChromeFlags,
const uint64_t& aID,
const bool& aIsForApp,
const bool& aIsForBrowser) MOZ_OVERRIDE;
virtual bool DeallocPBrowserChild(PBrowserChild*) MOZ_OVERRIDE;
virtual bool RecvPBrowserConstructor(PBrowserChild* aCctor,
const IPCTabContext& aContext,
const uint32_t& aChromeFlags,
const uint64_t& aID,
const bool& aIsForApp,
const bool& aIsForBrowser) MOZ_OVERRIDE;
virtual mozilla::jsipc::PJavaScriptChild* AllocPJavaScriptChild() MOZ_OVERRIDE;
virtual bool DeallocPJavaScriptChild(mozilla::jsipc::PJavaScriptChild*) MOZ_OVERRIDE;
virtual PBlobChild* AllocPBlobChild(const BlobConstructorParams& aParams) MOZ_OVERRIDE;
virtual bool DeallocPBlobChild(PBlobChild*) MOZ_OVERRIDE;
DISALLOW_EVIL_CONSTRUCTORS(ContentBridgeChild);
protected: // members
nsRefPtr<ContentBridgeChild> mSelfRef;
Transport* mTransport; // owned
};
} // dom
} // mozilla
#endif // mozilla_dom_ContentBridgeChild_h

View File

@ -0,0 +1,162 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=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 "mozilla/dom/ContentBridgeParent.h"
#include "mozilla/dom/TabParent.h"
#include "JavaScriptParent.h"
#include "nsXULAppAPI.h"
using namespace base;
using namespace mozilla::ipc;
using namespace mozilla::jsipc;
namespace mozilla {
namespace dom {
NS_IMPL_ISUPPORTS(ContentBridgeParent, nsIContentParent)
ContentBridgeParent::ContentBridgeParent(Transport* aTransport)
: mTransport(aTransport)
{}
ContentBridgeParent::~ContentBridgeParent()
{
XRE_GetIOMessageLoop()->PostTask(FROM_HERE, new DeleteTask<Transport>(mTransport));
}
void
ContentBridgeParent::ActorDestroy(ActorDestroyReason aWhy)
{
MessageLoop::current()->PostTask(
FROM_HERE,
NewRunnableMethod(this, &ContentBridgeParent::DeferredDestroy));
}
/*static*/ ContentBridgeParent*
ContentBridgeParent::Create(Transport* aTransport, ProcessId aOtherProcess)
{
nsRefPtr<ContentBridgeParent> bridge =
new ContentBridgeParent(aTransport);
ProcessHandle handle;
if (!base::OpenProcessHandle(aOtherProcess, &handle)) {
// XXX need to kill |aOtherProcess|, it's boned
return nullptr;
}
bridge->mSelfRef = bridge;
DebugOnly<bool> ok = bridge->Open(aTransport, handle, XRE_GetIOMessageLoop());
MOZ_ASSERT(ok);
return bridge.get();
}
void
ContentBridgeParent::DeferredDestroy()
{
mSelfRef = nullptr;
// |this| was just destroyed, hands off
}
bool
ContentBridgeParent::RecvSyncMessage(const nsString& aMsg,
const ClonedMessageData& aData,
const InfallibleTArray<jsipc::CpowEntry>& aCpows,
const IPC::Principal& aPrincipal,
InfallibleTArray<nsString>* aRetvals)
{
return nsIContentParent::RecvSyncMessage(aMsg, aData, aCpows, aPrincipal, aRetvals);
}
bool
ContentBridgeParent::RecvAsyncMessage(const nsString& aMsg,
const ClonedMessageData& aData,
const InfallibleTArray<jsipc::CpowEntry>& aCpows,
const IPC::Principal& aPrincipal)
{
return nsIContentParent::RecvAsyncMessage(aMsg, aData, aCpows, aPrincipal);
}
PBlobParent*
ContentBridgeParent::SendPBlobConstructor(PBlobParent* actor,
const BlobConstructorParams& params)
{
return PContentBridgeParent::SendPBlobConstructor(actor, params);
}
PBrowserParent*
ContentBridgeParent::SendPBrowserConstructor(PBrowserParent* aActor,
const IPCTabContext& aContext,
const uint32_t& aChromeFlags,
const uint64_t& aID,
const bool& aIsForApp,
const bool& aIsForBrowser)
{
return PContentBridgeParent::SendPBrowserConstructor(aActor,
aContext,
aChromeFlags,
aID,
aIsForApp,
aIsForBrowser);
}
PBlobParent*
ContentBridgeParent::AllocPBlobParent(const BlobConstructorParams& aParams)
{
return nsIContentParent::AllocPBlobParent(aParams);
}
bool
ContentBridgeParent::DeallocPBlobParent(PBlobParent* aActor)
{
return nsIContentParent::DeallocPBlobParent(aActor);
}
mozilla::jsipc::PJavaScriptParent *
ContentBridgeParent::AllocPJavaScriptParent()
{
return nsIContentParent::AllocPJavaScriptParent();
}
bool
ContentBridgeParent::DeallocPJavaScriptParent(PJavaScriptParent *parent)
{
return nsIContentParent::DeallocPJavaScriptParent(parent);
}
PBrowserParent*
ContentBridgeParent::AllocPBrowserParent(const IPCTabContext &aContext,
const uint32_t& aChromeFlags,
const uint64_t& aID,
const bool& aIsForApp,
const bool& aIsForBrowser)
{
return nsIContentParent::AllocPBrowserParent(aContext,
aChromeFlags,
aID,
aIsForApp,
aIsForBrowser);
}
bool
ContentBridgeParent::DeallocPBrowserParent(PBrowserParent* aParent)
{
return nsIContentParent::DeallocPBrowserParent(aParent);
}
// This implementation is identical to ContentParent::GetCPOWManager but we can't
// move it to nsIContentParent because it calls ManagedPJavaScriptParent() which
// only exists in PContentParent and PContentBridgeParent.
jsipc::JavaScriptParent*
ContentBridgeParent::GetCPOWManager()
{
if (ManagedPJavaScriptParent().Length()) {
return static_cast<JavaScriptParent*>(ManagedPJavaScriptParent()[0]);
}
JavaScriptParent* actor = static_cast<JavaScriptParent*>(SendPJavaScriptConstructor());
return actor;
}
} // namespace dom
} // namespace mozilla

View File

@ -0,0 +1,117 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_ContentBridgeParent_h
#define mozilla_dom_ContentBridgeParent_h
#include "mozilla/dom/PContentBridgeParent.h"
#include "mozilla/dom/nsIContentParent.h"
namespace mozilla {
namespace dom {
class ContentBridgeParent : public PContentBridgeParent
, public nsIContentParent
{
public:
ContentBridgeParent(Transport* aTransport);
NS_DECL_ISUPPORTS
virtual ~ContentBridgeParent();
virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
void DeferredDestroy();
static ContentBridgeParent*
Create(Transport* aTransport, ProcessId aOtherProcess);
virtual PBlobParent*
SendPBlobConstructor(PBlobParent* actor,
const BlobConstructorParams& params) MOZ_OVERRIDE;
virtual PBrowserParent*
SendPBrowserConstructor(PBrowserParent* aActor,
const IPCTabContext& aContext,
const uint32_t& aChromeFlags,
const uint64_t& aID,
const bool& aIsForApp,
const bool& aIsForBrowser) MOZ_OVERRIDE;
jsipc::JavaScriptParent* GetCPOWManager();
virtual uint64_t ChildID() MOZ_OVERRIDE
{
return mChildID;
}
virtual bool IsForApp() MOZ_OVERRIDE
{
return mIsForApp;
}
virtual bool IsForBrowser() MOZ_OVERRIDE
{
return mIsForBrowser;
}
protected:
void SetChildID(uint64_t aId)
{
mChildID = aId;
}
void SetIsForApp(bool aIsForApp)
{
mIsForApp = aIsForApp;
}
void SetIsForBrowser(bool aIsForBrowser)
{
mIsForBrowser = aIsForBrowser;
}
protected:
virtual bool RecvSyncMessage(const nsString& aMsg,
const ClonedMessageData& aData,
const InfallibleTArray<jsipc::CpowEntry>& aCpows,
const IPC::Principal& aPrincipal,
InfallibleTArray<nsString>* aRetvals) MOZ_OVERRIDE;
virtual bool RecvAsyncMessage(const nsString& aMsg,
const ClonedMessageData& aData,
const InfallibleTArray<jsipc::CpowEntry>& aCpows,
const IPC::Principal& aPrincipal) MOZ_OVERRIDE;
virtual jsipc::PJavaScriptParent* AllocPJavaScriptParent() MOZ_OVERRIDE;
virtual bool
DeallocPJavaScriptParent(jsipc::PJavaScriptParent*) MOZ_OVERRIDE;
virtual PBrowserParent*
AllocPBrowserParent(const IPCTabContext &aContext,
const uint32_t& aChromeFlags,
const uint64_t& aID,
const bool& aIsForApp,
const bool& aIsForBrowser) MOZ_OVERRIDE;
virtual bool DeallocPBrowserParent(PBrowserParent*) MOZ_OVERRIDE;
virtual PBlobParent*
AllocPBlobParent(const BlobConstructorParams& aParams) MOZ_OVERRIDE;
virtual bool DeallocPBlobParent(PBlobParent*) MOZ_OVERRIDE;
DISALLOW_EVIL_CONSTRUCTORS(ContentBridgeParent);
protected: // members
nsRefPtr<ContentBridgeParent> mSelfRef;
Transport* mTransport; // owned
uint64_t mChildID;
bool mIsForApp;
bool mIsForBrowser;
private:
friend class ContentParent;
};
} // dom
} // mozilla
#endif // mozilla_dom_ContentBridgeParent_h

View File

@ -18,12 +18,16 @@
#include "TabChild.h"
#include "mozilla/Attributes.h"
#include "mozilla/dom/asmjscache/AsmJSCache.h"
#include "mozilla/dom/asmjscache/PAsmJSCacheEntryChild.h"
#include "mozilla/Preferences.h"
#include "mozilla/dom/ContentBridgeChild.h"
#include "mozilla/dom/ContentBridgeParent.h"
#include "mozilla/dom/DOMStorageIPC.h"
#include "mozilla/dom/ExternalHelperAppChild.h"
#include "mozilla/dom/PCrashReporterChild.h"
#include "mozilla/dom/DOMStorageIPC.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/asmjscache/AsmJSCache.h"
#include "mozilla/dom/asmjscache/PAsmJSCacheEntryChild.h"
#include "mozilla/dom/nsIContentChild.h"
#include "mozilla/hal_sandbox/PHalChild.h"
#include "mozilla/ipc/BackgroundChild.h"
#include "mozilla/ipc/FileDescriptorUtils.h"
@ -31,10 +35,9 @@
#include "mozilla/ipc/TestShellChild.h"
#include "mozilla/layers/CompositorChild.h"
#include "mozilla/layers/ImageBridgeChild.h"
#include "mozilla/layers/SharedBufferManagerChild.h"
#include "mozilla/layers/PCompositorChild.h"
#include "mozilla/layers/SharedBufferManagerChild.h"
#include "mozilla/net/NeckoChild.h"
#include "mozilla/Preferences.h"
#if defined(MOZ_CONTENT_SANDBOX)
#if defined(XP_WIN)
@ -497,6 +500,11 @@ ContentChild::~ContentChild()
{
}
NS_INTERFACE_MAP_BEGIN(ContentChild)
NS_INTERFACE_MAP_ENTRY(nsIContentChild)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
bool
ContentChild::Init(MessageLoop* aIOLoop,
base::ProcessHandle aParentHandle,
@ -829,6 +837,23 @@ ContentChild::DeallocPCycleCollectWithLogsChild(PCycleCollectWithLogsChild* /* a
return true;
}
PContentBridgeChild*
ContentChild::AllocPContentBridgeChild(mozilla::ipc::Transport* aTransport,
base::ProcessId aOtherProcess)
{
return ContentBridgeChild::Create(aTransport, aOtherProcess);
}
PContentBridgeParent*
ContentChild::AllocPContentBridgeParent(mozilla::ipc::Transport* aTransport,
base::ProcessId aOtherProcess)
{
MOZ_ASSERT(!mLastBridge);
mLastBridge = static_cast<ContentBridgeParent*>(
ContentBridgeParent::Create(aTransport, aOtherProcess));
return mLastBridge;
}
PCompositorChild*
ContentChild::AllocPCompositorChild(mozilla::ipc::Transport* aTransport,
base::ProcessId aOtherProcess)
@ -900,51 +925,43 @@ ContentChild::AllocPJavaScriptChild()
{
MOZ_ASSERT(!ManagedPJavaScriptChild().Length());
nsCOMPtr<nsIJSRuntimeService> svc = do_GetService("@mozilla.org/js/xpc/RuntimeService;1");
NS_ENSURE_TRUE(svc, nullptr);
JSRuntime *rt;
svc->GetRuntime(&rt);
NS_ENSURE_TRUE(svc, nullptr);
mozilla::jsipc::JavaScriptChild *child = new mozilla::jsipc::JavaScriptChild(rt);
if (!child->init()) {
delete child;
return nullptr;
}
return child;
return nsIContentChild::AllocPJavaScriptChild();
}
bool
ContentChild::DeallocPJavaScriptChild(PJavaScriptChild *child)
ContentChild::DeallocPJavaScriptChild(PJavaScriptChild *aChild)
{
static_cast<mozilla::jsipc::JavaScriptChild *>(child)->decref();
return true;
return nsIContentChild::DeallocPJavaScriptChild(aChild);
}
PBrowserChild*
ContentChild::AllocPBrowserChild(const IPCTabContext& aContext,
const uint32_t& aChromeFlags,
const uint64_t& aId,
const uint64_t& aID,
const bool& aIsForApp,
const bool& aIsForBrowser)
{
// We'll happily accept any kind of IPCTabContext here; we don't need to
// check that it's of a certain type for security purposes, because we
// believe whatever the parent process tells us.
return nsIContentChild::AllocPBrowserChild(aContext,
aChromeFlags,
aID,
aIsForApp,
aIsForBrowser);
}
MaybeInvalidTabContext tc(aContext);
if (!tc.IsValid()) {
NS_ERROR(nsPrintfCString("Received an invalid TabContext from "
"the parent process. (%s) Crashing...",
tc.GetInvalidReason()).get());
MOZ_CRASH("Invalid TabContext received from the parent process.");
}
nsRefPtr<TabChild> child = TabChild::Create(this, tc.GetTabContext(), aChromeFlags);
// The ref here is released in DeallocPBrowserChild.
return child.forget().take();
bool
ContentChild::SendPBrowserConstructor(PBrowserChild* aActor,
const IPCTabContext& aContext,
const uint32_t& aChromeFlags,
const uint64_t& aID,
const bool& aIsForApp,
const bool& aIsForBrowser)
{
return PContentChild::SendPBrowserConstructor(aActor,
aContext,
aChromeFlags,
aID,
aIsForApp,
aIsForBrowser);
}
bool
@ -998,108 +1015,28 @@ ContentChild::DeallocPFileDescriptorSetChild(PFileDescriptorSetChild* aActor)
}
bool
ContentChild::DeallocPBrowserChild(PBrowserChild* iframe)
ContentChild::DeallocPBrowserChild(PBrowserChild* aIframe)
{
TabChild* child = static_cast<TabChild*>(iframe);
NS_RELEASE(child);
return true;
return nsIContentChild::DeallocPBrowserChild(aIframe);
}
PBlobChild*
ContentChild::AllocPBlobChild(const BlobConstructorParams& aParams)
{
return BlobChild::Create(this, aParams);
return nsIContentChild::AllocPBlobChild(aParams);
}
bool
ContentChild::DeallocPBlobChild(PBlobChild* aActor)
{
delete aActor;
return true;
return nsIContentChild::DeallocPBlobChild(aActor);
}
BlobChild*
ContentChild::GetOrCreateActorForBlob(nsIDOMBlob* aBlob)
PBlobChild*
ContentChild::SendPBlobConstructor(PBlobChild* aActor,
const BlobConstructorParams& aParams)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aBlob);
// If the blob represents a remote blob then we can simply pass its actor back
// here.
if (nsCOMPtr<nsIRemoteBlob> remoteBlob = do_QueryInterface(aBlob)) {
BlobChild* actor =
static_cast<BlobChild*>(
static_cast<PBlobChild*>(remoteBlob->GetPBlob()));
MOZ_ASSERT(actor);
return actor;
}
// All blobs shared between processes must be immutable.
nsCOMPtr<nsIMutable> mutableBlob = do_QueryInterface(aBlob);
if (!mutableBlob || NS_FAILED(mutableBlob->SetMutable(false))) {
NS_WARNING("Failed to make blob immutable!");
return nullptr;
}
#ifdef DEBUG
{
// XXX This is only safe so long as all blob implementations in our tree
// inherit nsDOMFileBase. If that ever changes then this will need to
// grow a real interface or something.
const auto* blob = static_cast<nsDOMFileBase*>(aBlob);
MOZ_ASSERT(!blob->IsSizeUnknown());
MOZ_ASSERT(!blob->IsDateUnknown());
}
#endif
ParentBlobConstructorParams params;
nsString contentType;
nsresult rv = aBlob->GetType(contentType);
NS_ENSURE_SUCCESS(rv, nullptr);
uint64_t length;
rv = aBlob->GetSize(&length);
NS_ENSURE_SUCCESS(rv, nullptr);
nsCOMPtr<nsIInputStream> stream;
rv = aBlob->GetInternalStream(getter_AddRefs(stream));
NS_ENSURE_SUCCESS(rv, nullptr);
InputStreamParams inputStreamParams;
nsTArray<mozilla::ipc::FileDescriptor> fds;
SerializeInputStream(stream, inputStreamParams, fds);
MOZ_ASSERT(fds.IsEmpty());
params.optionalInputStreamParams() = inputStreamParams;
nsCOMPtr<nsIDOMFile> file = do_QueryInterface(aBlob);
if (file) {
FileBlobConstructorParams fileParams;
rv = file->GetName(fileParams.name());
NS_ENSURE_SUCCESS(rv, nullptr);
rv = file->GetMozLastModifiedDate(&fileParams.modDate());
NS_ENSURE_SUCCESS(rv, nullptr);
fileParams.contentType() = contentType;
fileParams.length() = length;
params.blobParams() = fileParams;
} else {
NormalBlobConstructorParams blobParams;
blobParams.contentType() = contentType;
blobParams.length() = length;
params.blobParams() = blobParams;
}
BlobChild* actor = BlobChild::Create(this, aBlob);
NS_ENSURE_TRUE(actor, nullptr);
return SendPBlobConstructor(actor, params) ? actor : nullptr;
return PContentChild::SendPBlobConstructor(aActor, aParams);
}
PCrashReporterChild*

View File

@ -8,8 +8,10 @@
#define mozilla_dom_ContentChild_h
#include "mozilla/Attributes.h"
#include "mozilla/dom/PContentChild.h"
#include "mozilla/dom/ContentBridgeParent.h"
#include "mozilla/dom/ipc/Blob.h"
#include "mozilla/dom/nsIContentChild.h"
#include "mozilla/dom/PContentChild.h"
#include "nsHashKeys.h"
#include "nsIObserver.h"
#include "nsTHashtable.h"
@ -48,6 +50,7 @@ class ClonedMessageData;
class PFileDescriptorSetChild;
class ContentChild : public PContentChild
, public nsIContentChild
{
typedef mozilla::dom::ClonedMessageData ClonedMessageData;
typedef mozilla::ipc::OptionalURIParams OptionalURIParams;
@ -56,8 +59,9 @@ class ContentChild : public PContentChild
public:
ContentChild();
virtual ~ContentChild();
nsrefcnt AddRef() { return 1; }
nsrefcnt Release() { return 1; }
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr);
NS_IMETHOD_(MozExternalRefCountType) AddRef(void) { return 1; }
NS_IMETHOD_(MozExternalRefCountType) Release(void) { return 1; }
struct AppInfo
{
@ -86,6 +90,21 @@ public:
void GetProcessName(nsACString& aName);
static void AppendProcessId(nsACString& aName);
ContentBridgeParent* GetLastBridge() {
MOZ_ASSERT(mLastBridge);
ContentBridgeParent* parent = mLastBridge;
mLastBridge = nullptr;
return parent;
}
nsRefPtr<ContentBridgeParent> mLastBridge;
PContentBridgeParent*
AllocPContentBridgeParent(mozilla::ipc::Transport* transport,
base::ProcessId otherProcess) MOZ_OVERRIDE;
PContentBridgeChild*
AllocPContentBridgeChild(mozilla::ipc::Transport* transport,
base::ProcessId otherProcess) MOZ_OVERRIDE;
PCompositorChild*
AllocPCompositorChild(mozilla::ipc::Transport* aTransport,
base::ProcessId aOtherProcess) MOZ_OVERRIDE;
@ -299,7 +318,9 @@ public:
bool IsForApp() { return mIsForApp; }
bool IsForBrowser() { return mIsForBrowser; }
BlobChild* GetOrCreateActorForBlob(nsIDOMBlob* aBlob);
virtual PBlobChild*
SendPBlobConstructor(PBlobChild* actor,
const BlobConstructorParams& params) MOZ_OVERRIDE;
virtual PFileDescriptorSetChild*
AllocPFileDescriptorSetChild(const FileDescriptor&) MOZ_OVERRIDE;
@ -307,7 +328,13 @@ public:
virtual bool
DeallocPFileDescriptorSetChild(PFileDescriptorSetChild*) MOZ_OVERRIDE;
protected:
virtual bool SendPBrowserConstructor(PBrowserChild* actor,
const IPCTabContext& context,
const uint32_t& chromeFlags,
const uint64_t& aID,
const bool& aIsForApp,
const bool& aIsForBrowser) MOZ_OVERRIDE;
virtual bool RecvPBrowserConstructor(PBrowserChild* aCctor,
const IPCTabContext& aContext,
const uint32_t& aChromeFlags,

View File

@ -22,6 +22,8 @@
#include "chrome/common/process_watcher.h"
#include <set>
#include "AppProcessChecker.h"
#include "AudioChannelService.h"
#include "CrashReporterParent.h"
@ -35,6 +37,7 @@
#include "mozilla/dom/Element.h"
#include "mozilla/dom/DataStoreService.h"
#include "mozilla/dom/ExternalHelperAppParent.h"
#include "mozilla/dom/PContentBridgeParent.h"
#include "mozilla/dom/PFileDescriptorSetParent.h"
#include "mozilla/dom/PCycleCollectWithLogsParent.h"
#include "mozilla/dom/PMemoryReportRequestParent.h"
@ -480,7 +483,8 @@ ContentParentsMemoryReporter::CollectReports(nsIMemoryReporterCallback* cb,
nsPrintfCString path("queued-ipc-messages/content-parent"
"(%s, pid=%d, %s, 0x%p, refcnt=%d)",
NS_ConvertUTF16toUTF8(friendlyName).get(),
cp->Pid(), channelStr, cp, refcnt);
cp->Pid(), channelStr,
static_cast<nsIContentParent*>(cp), refcnt);
NS_NAMED_LITERAL_CSTRING(desc,
"The number of unset IPC messages held in this ContentParent's "
@ -549,6 +553,7 @@ ContentParent::RunNuwaProcess()
MOZ_ASSERT(NS_IsMainThread());
nsRefPtr<ContentParent> nuwaProcess =
new ContentParent(/* aApp = */ nullptr,
/* aOpener = */ nullptr,
/* aIsForBrowser = */ false,
/* aIsForPreallocated = */ true,
PROCESS_PRIORITY_BACKGROUND,
@ -565,6 +570,7 @@ ContentParent::PreallocateAppProcess()
{
nsRefPtr<ContentParent> process =
new ContentParent(/* app = */ nullptr,
/* aOpener = */ nullptr,
/* isForBrowserElement = */ false,
/* isForPreallocated = */ true,
PROCESS_PRIORITY_PREALLOC);
@ -595,25 +601,23 @@ ContentParent::MaybeTakePreallocatedAppProcess(const nsAString& aAppManifestURL,
/*static*/ void
ContentParent::StartUp()
{
if (XRE_GetProcessType() != GeckoProcessType_Default) {
return;
}
// Note: This reporter measures all ContentParents.
RegisterStrongMemoryReporter(new ContentParentsMemoryReporter());
mozilla::dom::time::InitializeDateCacheCleaner();
BackgroundChild::Startup();
sCanLaunchSubprocesses = true;
// Try to preallocate a process that we can transform into an app later.
PreallocatedProcessManager::AllocateAfterDelay();
if (XRE_GetProcessType() == GeckoProcessType_Default) {
BackgroundChild::Startup();
// Test the PBackground infrastructure on ENABLE_TESTS builds when a special
// testing preference is set.
MaybeTestPBackground();
// Try to preallocate a process that we can transform into an app later.
PreallocatedProcessManager::AllocateAfterDelay();
// Test the PBackground infrastructure on ENABLE_TESTS builds when a special
// testing preference is set.
MaybeTestPBackground();
}
}
/*static*/ void
@ -673,7 +677,9 @@ ContentParent::JoinAllSubprocesses()
}
/*static*/ already_AddRefed<ContentParent>
ContentParent::GetNewOrUsed(bool aForBrowserElement, ProcessPriority aPriority)
ContentParent::GetNewOrUsed(bool aForBrowserElement,
ProcessPriority aPriority,
ContentParent* aOpener)
{
if (!sNonAppContentParents)
sNonAppContentParents = new nsTArray<ContentParent*>();
@ -683,10 +689,16 @@ ContentParent::GetNewOrUsed(bool aForBrowserElement, ProcessPriority aPriority)
maxContentProcesses = 1;
if (sNonAppContentParents->Length() >= uint32_t(maxContentProcesses)) {
uint32_t idx = rand() % sNonAppContentParents->Length();
nsRefPtr<ContentParent> p = (*sNonAppContentParents)[idx];
NS_ASSERTION(p->IsAlive(), "Non-alive contentparent in sNonAppContentParents?");
return p.forget();
uint32_t startIdx = rand() % sNonAppContentParents->Length();
uint32_t currIdx = startIdx;
do {
nsRefPtr<ContentParent> p = (*sNonAppContentParents)[currIdx];
NS_ASSERTION(p->IsAlive(), "Non-alive contentparent in sNonAppContntParents?");
if (p->mOpener == aOpener) {
return p.forget();
}
currIdx = (currIdx + 1) % sNonAppContentParents->Length();
} while (currIdx != startIdx);
}
// Try to take and transform the preallocated process into browser.
@ -702,6 +714,7 @@ ContentParent::GetNewOrUsed(bool aForBrowserElement, ProcessPriority aPriority)
}
#endif
p = new ContentParent(/* app = */ nullptr,
aOpener,
aForBrowserElement,
/* isForPreallocated = */ false,
aPriority);
@ -759,6 +772,57 @@ ContentParent::RunAfterPreallocatedProcessReady(nsIRunnable* aRequest)
#endif
}
typedef std::map<ContentParent*, std::set<ContentParent*> > GrandchildMap;
static GrandchildMap sGrandchildProcessMap;
std::map<uint64_t, ContentParent*> sContentParentMap;
bool
ContentParent::RecvCreateChildProcess(const IPCTabContext& aContext,
const hal::ProcessPriority& aPriority,
uint64_t* aId,
bool* aIsForApp,
bool* aIsForBrowser)
{
#if 0
if (!CanOpenBrowser(aContext)) {
return false;
}
#endif
nsRefPtr<ContentParent> cp = GetNewOrUsed(/* isBrowserElement = */ true,
aPriority,
this);
*aId = cp->ChildID();
*aIsForApp = cp->IsForApp();
*aIsForBrowser = cp->IsForBrowser();
sContentParentMap[*aId] = cp;
auto iter = sGrandchildProcessMap.find(this);
if (iter == sGrandchildProcessMap.end()) {
std::set<ContentParent*> children;
children.insert(cp);
sGrandchildProcessMap[this] = children;
} else {
iter->second.insert(cp);
}
return true;
}
bool
ContentParent::AnswerBridgeToChildProcess(const uint64_t& id)
{
ContentParent* cp = sContentParentMap[id];
auto iter = sGrandchildProcessMap.find(this);
if (iter != sGrandchildProcessMap.end() &&
iter->second.find(cp) != iter->second.end()) {
return PContentBridge::Bridge(this, cp);
} else {
// You can't bridge to a process you didn't open!
KillHard();
return false;
}
}
/*static*/ TabParent*
ContentParent::CreateBrowserOrApp(const TabContext& aContext,
Element* aFrameElement)
@ -770,19 +834,50 @@ ContentParent::CreateBrowserOrApp(const TabContext& aContext,
ProcessPriority initialPriority = GetInitialProcessPriority(aFrameElement);
if (aContext.IsBrowserElement() || !aContext.HasOwnApp()) {
nsRefPtr<ContentParent> cp = GetNewOrUsed(aContext.IsBrowserElement(),
initialPriority);
if (cp) {
nsRefPtr<TabParent> tp;
nsRefPtr<nsIContentParent> constructorSender;
if (XRE_GetProcessType() != GeckoProcessType_Default) {
MOZ_ASSERT(aContext.IsBrowserElement());
ContentChild* child = ContentChild::GetSingleton();
uint64_t id;
bool isForApp;
bool isForBrowser;
if (!child->SendCreateChildProcess(aContext.AsIPCTabContext(),
initialPriority,
&id,
&isForApp,
&isForBrowser)) {
return nullptr;
}
if (!child->CallBridgeToChildProcess(id)) {
return nullptr;
}
ContentBridgeParent* parent = child->GetLastBridge();
parent->SetChildID(id);
parent->SetIsForApp(isForApp);
parent->SetIsForBrowser(isForBrowser);
constructorSender = parent;
} else if (nsRefPtr<ContentParent> cp =
GetNewOrUsed(aContext.IsBrowserElement(), initialPriority)) {
constructorSender = cp;
}
if (constructorSender) {
uint32_t chromeFlags = 0;
// Propagate the private-browsing status of the element's parent
// docshell to the remote docshell, via the chrome flags.
nsCOMPtr<Element> frameElement = do_QueryInterface(aFrameElement);
MOZ_ASSERT(frameElement);
nsIDocShell* docShell =
frameElement->OwnerDoc()->GetWindow()->GetDocShell();
MOZ_ASSERT(docShell);
nsPIDOMWindow* win = frameElement->OwnerDoc()->GetWindow();
if (!win) {
NS_WARNING("Remote frame has no window");
return nullptr;
}
nsIDocShell* docShell = win->GetDocShell();
if (!docShell) {
NS_WARNING("Remote frame has no docshell");
return nullptr;
}
nsCOMPtr<nsILoadContext> loadContext = do_QueryInterface(docShell);
if (loadContext && loadContext->UsePrivateBrowsing()) {
chromeFlags |= nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW;
@ -793,17 +888,18 @@ ContentParent::CreateBrowserOrApp(const TabContext& aContext,
chromeFlags |= nsIWebBrowserChrome::CHROME_PRIVATE_LIFETIME;
}
nsRefPtr<TabParent> tp(new TabParent(cp, aContext, chromeFlags));
nsRefPtr<TabParent> tp(new TabParent(constructorSender,
aContext, chromeFlags));
tp->SetOwnerElement(aFrameElement);
PBrowserParent* browser = cp->SendPBrowserConstructor(
PBrowserParent* browser = constructorSender->SendPBrowserConstructor(
// DeallocPBrowserParent() releases this ref.
tp.forget().take(),
aContext.AsIPCTabContext(),
chromeFlags,
cp->ChildID(),
cp->IsForApp(),
cp->IsForBrowser());
constructorSender->ChildID(),
constructorSender->IsForApp(),
constructorSender->IsForBrowser());
return static_cast<TabParent*>(browser);
}
return nullptr;
@ -885,6 +981,7 @@ ContentParent::CreateBrowserOrApp(const TabContext& aContext,
#endif
NS_WARNING("Unable to use pre-allocated app process");
p = new ContentParent(ownApp,
/* aOpener = */ nullptr,
/* isForBrowserElement = */ false,
/* isForPreallocated = */ false,
initialPriority);
@ -1229,6 +1326,13 @@ ContentParent::MarkAsDead()
}
mIsAlive = false;
sGrandchildProcessMap.erase(this);
for (auto iter = sGrandchildProcessMap.begin();
iter != sGrandchildProcessMap.end();
iter++) {
iter->second.erase(this);
}
}
void
@ -1291,6 +1395,39 @@ ContentParent::ProcessingError(Result what)
KillHard();
}
typedef std::pair<ContentParent*, std::set<uint64_t> > IDPair;
static std::map<ContentParent*, std::set<uint64_t> > sNestedBrowserIds;
bool
ContentParent::RecvAllocateLayerTreeId(uint64_t* aId)
{
*aId = CompositorParent::AllocateLayerTreeId();
auto iter = sNestedBrowserIds.find(this);
if (iter == sNestedBrowserIds.end()) {
std::set<uint64_t> ids;
ids.insert(*aId);
sNestedBrowserIds.insert(IDPair(this, ids));
} else {
iter->second.insert(*aId);
}
return true;
}
bool
ContentParent::RecvDeallocateLayerTreeId(const uint64_t& aId)
{
auto iter = sNestedBrowserIds.find(this);
if (iter != sNestedBrowserIds.end() &&
iter->second.find(aId) != iter->second.end()) {
CompositorParent::DeallocateLayerTreeId(aId);
} else {
// You can't deallocate layer tree ids that you didn't allocate
KillHard();
}
return true;
}
namespace {
void
@ -1422,6 +1559,19 @@ ContentParent::ActorDestroy(ActorDestroyReason why)
// This runnable ensures that a reference to |this| lives on at
// least until after the current task finishes running.
NS_DispatchToCurrentThread(new DelayedDeleteContentParentTask(this));
// Destroy any processes created by this ContentParent
auto iter = sGrandchildProcessMap.find(this);
if (iter != sGrandchildProcessMap.end()) {
for(auto child = iter->second.begin();
child != iter->second.end();
child++) {
MessageLoop::current()->PostTask(
FROM_HERE,
NewRunnableMethod(*child, &ContentParent::ShutDownProcess,
/* closeWithError */ false));
}
}
}
void
@ -1518,11 +1668,14 @@ ContentParent::InitializeMembers()
}
ContentParent::ContentParent(mozIApplication* aApp,
ContentParent* aOpener,
bool aIsForBrowser,
bool aIsForPreallocated,
ProcessPriority aInitialPriority /* = PROCESS_PRIORITY_FOREGROUND */,
bool aIsNuwaProcess /* = false */)
: mIsForBrowser(aIsForBrowser)
: nsIContentParent()
, mOpener(aOpener)
, mIsForBrowser(aIsForBrowser)
, mIsNuwaProcess(aIsNuwaProcess)
{
InitializeMembers(); // Perform common initialization.
@ -1733,8 +1886,6 @@ ContentParent::InitInternal(ProcessPriority aInitialPriority,
chromeRegistry->SendRegisteredChrome(this);
}
mMessageManager = nsFrameMessageManager::NewProcessMessageManager(this);
if (gAppData) {
nsCString version(gAppData->version);
nsCString buildID(gAppData->buildID);
@ -2193,6 +2344,7 @@ NS_IMPL_CYCLE_COLLECTING_ADDREF(ContentParent)
NS_IMPL_CYCLE_COLLECTING_RELEASE(ContentParent)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ContentParent)
NS_INTERFACE_MAP_ENTRY(nsIContentParent)
NS_INTERFACE_MAP_ENTRY(nsIObserver)
NS_INTERFACE_MAP_ENTRY(nsIDOMGeoPositionCallback)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIObserver)
@ -2397,27 +2549,13 @@ mozilla::jsipc::PJavaScriptParent *
ContentParent::AllocPJavaScriptParent()
{
MOZ_ASSERT(!ManagedPJavaScriptParent().Length());
nsCOMPtr<nsIJSRuntimeService> svc = do_GetService("@mozilla.org/js/xpc/RuntimeService;1");
NS_ENSURE_TRUE(svc, nullptr);
JSRuntime *rt;
svc->GetRuntime(&rt);
NS_ENSURE_TRUE(svc, nullptr);
mozilla::jsipc::JavaScriptParent *parent = new mozilla::jsipc::JavaScriptParent(rt);
if (!parent->init()) {
delete parent;
return nullptr;
}
return parent;
return nsIContentParent::AllocPJavaScriptParent();
}
bool
ContentParent::DeallocPJavaScriptParent(PJavaScriptParent *parent)
{
static_cast<mozilla::jsipc::JavaScriptParent *>(parent)->decref();
return true;
return nsIContentParent::DeallocPJavaScriptParent(parent);
}
PBrowserParent*
@ -2427,55 +2565,17 @@ ContentParent::AllocPBrowserParent(const IPCTabContext& aContext,
const bool& aIsForApp,
const bool& aIsForBrowser)
{
unused << aChromeFlags;
const IPCTabAppBrowserContext& appBrowser = aContext.appBrowserContext();
// We don't trust the IPCTabContext we receive from the child, so we'll bail
// if we receive an IPCTabContext that's not a PopupIPCTabContext.
// (PopupIPCTabContext lets the child process prove that it has access to
// the app it's trying to open.)
if (appBrowser.type() != IPCTabAppBrowserContext::TPopupIPCTabContext) {
NS_ERROR("Unexpected IPCTabContext type. Aborting AllocPBrowserParent.");
return nullptr;
}
const PopupIPCTabContext& popupContext = appBrowser.get_PopupIPCTabContext();
TabParent* opener = static_cast<TabParent*>(popupContext.openerParent());
if (!opener) {
NS_ERROR("Got null opener from child; aborting AllocPBrowserParent.");
return nullptr;
}
// Popup windows of isBrowser frames must be isBrowser if the parent
// isBrowser. Allocating a !isBrowser frame with same app ID would allow
// the content to access data it's not supposed to.
if (!popupContext.isBrowserElement() && opener->IsBrowserElement()) {
NS_ERROR("Child trying to escalate privileges! Aborting AllocPBrowserParent.");
return nullptr;
}
MaybeInvalidTabContext tc(aContext);
if (!tc.IsValid()) {
NS_ERROR(nsPrintfCString("Child passed us an invalid TabContext. (%s) "
"Aborting AllocPBrowserParent.",
tc.GetInvalidReason()).get());
return nullptr;
}
TabParent* parent = new TabParent(this, tc.GetTabContext(), aChromeFlags);
// We release this ref in DeallocPBrowserParent()
NS_ADDREF(parent);
return parent;
return nsIContentParent::AllocPBrowserParent(aContext,
aChromeFlags,
aId,
aIsForApp,
aIsForBrowser);
}
bool
ContentParent::DeallocPBrowserParent(PBrowserParent* frame)
{
TabParent* parent = static_cast<TabParent*>(frame);
NS_RELEASE(parent);
return true;
return nsIContentParent::DeallocPBrowserParent(frame);
}
PDeviceStorageRequestParent*
@ -2518,7 +2618,7 @@ ContentParent::DeallocPFileSystemRequestParent(PFileSystemRequestParent* doomed)
PBlobParent*
ContentParent::AllocPBlobParent(const BlobConstructorParams& aParams)
{
return BlobParent::Create(this, aParams);
return nsIContentParent::AllocPBlobParent(aParams);
}
bool
@ -2528,81 +2628,6 @@ ContentParent::DeallocPBlobParent(PBlobParent* aActor)
return true;
}
BlobParent*
ContentParent::GetOrCreateActorForBlob(nsIDOMBlob* aBlob)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aBlob);
// If the blob represents a remote blob for this ContentParent then we can
// simply pass its actor back here.
if (nsCOMPtr<nsIRemoteBlob> remoteBlob = do_QueryInterface(aBlob)) {
if (BlobParent* actor = static_cast<BlobParent*>(
static_cast<PBlobParent*>(remoteBlob->GetPBlob()))) {
if (static_cast<ContentParent*>(actor->Manager()) == this) {
return actor;
}
}
}
// All blobs shared between processes must be immutable.
nsCOMPtr<nsIMutable> mutableBlob = do_QueryInterface(aBlob);
if (!mutableBlob || NS_FAILED(mutableBlob->SetMutable(false))) {
NS_WARNING("Failed to make blob immutable!");
return nullptr;
}
// XXX This is only safe so long as all blob implementations in our tree
// inherit nsDOMFileBase. If that ever changes then this will need to grow
// a real interface or something.
const auto* blob = static_cast<nsDOMFileBase*>(aBlob);
ChildBlobConstructorParams params;
if (blob->IsSizeUnknown() || blob->IsDateUnknown()) {
// We don't want to call GetSize or GetLastModifiedDate
// yet since that may stat a file on the main thread
// here. Instead we'll learn the size lazily from the
// other process.
params = MysteryBlobConstructorParams();
}
else {
nsString contentType;
nsresult rv = aBlob->GetType(contentType);
NS_ENSURE_SUCCESS(rv, nullptr);
uint64_t length;
rv = aBlob->GetSize(&length);
NS_ENSURE_SUCCESS(rv, nullptr);
nsCOMPtr<nsIDOMFile> file = do_QueryInterface(aBlob);
if (file) {
FileBlobConstructorParams fileParams;
rv = file->GetMozLastModifiedDate(&fileParams.modDate());
NS_ENSURE_SUCCESS(rv, nullptr);
rv = file->GetName(fileParams.name());
NS_ENSURE_SUCCESS(rv, nullptr);
fileParams.contentType() = contentType;
fileParams.length() = length;
params = fileParams;
} else {
NormalBlobConstructorParams blobParams;
blobParams.contentType() = contentType;
blobParams.length() = length;
params = blobParams;
}
}
BlobParent* actor = BlobParent::Create(this, aBlob);
NS_ENSURE_TRUE(actor, nullptr);
return SendPBlobConstructor(actor, params) ? actor : nullptr;
}
void
ContentParent::KillHard()
{
@ -3180,21 +3205,8 @@ ContentParent::RecvSyncMessage(const nsString& aMsg,
const IPC::Principal& aPrincipal,
InfallibleTArray<nsString>* aRetvals)
{
nsIPrincipal* principal = aPrincipal;
if (!Preferences::GetBool("dom.testing.ignore_ipc_principal", false) &&
principal && !AssertAppPrincipal(this, principal)) {
return false;
}
nsRefPtr<nsFrameMessageManager> ppm = mMessageManager;
if (ppm) {
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
CpowIdHolder cpows(GetCPOWManager(), aCpows);
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()),
aMsg, true, &cloneData, &cpows, aPrincipal, aRetvals);
}
return true;
return nsIContentParent::RecvSyncMessage(aMsg, aData, aCpows, aPrincipal,
aRetvals);
}
bool
@ -3204,20 +3216,8 @@ ContentParent::AnswerRpcMessage(const nsString& aMsg,
const IPC::Principal& aPrincipal,
InfallibleTArray<nsString>* aRetvals)
{
nsIPrincipal* principal = aPrincipal;
if (!Preferences::GetBool("dom.testing.ignore_ipc_principal", false) &&
principal && !AssertAppPrincipal(this, principal)) {
return false;
}
nsRefPtr<nsFrameMessageManager> ppm = mMessageManager;
if (ppm) {
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
CpowIdHolder cpows(GetCPOWManager(), aCpows);
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()),
aMsg, true, &cloneData, &cpows, aPrincipal, aRetvals);
}
return true;
return nsIContentParent::AnswerRpcMessage(aMsg, aData, aCpows, aPrincipal,
aRetvals);
}
bool
@ -3226,20 +3226,7 @@ ContentParent::RecvAsyncMessage(const nsString& aMsg,
const InfallibleTArray<CpowEntry>& aCpows,
const IPC::Principal& aPrincipal)
{
nsIPrincipal* principal = aPrincipal;
if (!Preferences::GetBool("dom.testing.ignore_ipc_principal", false) &&
principal && !AssertAppPrincipal(this, principal)) {
return false;
}
nsRefPtr<nsFrameMessageManager> ppm = mMessageManager;
if (ppm) {
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
CpowIdHolder cpows(GetCPOWManager(), aCpows);
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()),
aMsg, false, &cloneData, &cpows, aPrincipal, nullptr);
}
return true;
return nsIContentParent::RecvAsyncMessage(aMsg, aData, aCpows, aPrincipal);
}
bool
@ -3447,6 +3434,13 @@ ContentParent::CheckAppHasStatus(unsigned short aStatus)
return AssertAppHasStatus(this, aStatus);
}
PBlobParent*
ContentParent::SendPBlobConstructor(PBlobParent* aActor,
const BlobConstructorParams& aParams)
{
return PContentParent::SendPBlobConstructor(aActor, aParams);
}
bool
ContentParent::RecvSystemMessageHandled()
{
@ -3454,6 +3448,22 @@ ContentParent::RecvSystemMessageHandled()
return true;
}
PBrowserParent*
ContentParent::SendPBrowserConstructor(PBrowserParent* aActor,
const IPCTabContext& aContext,
const uint32_t& aChromeFlags,
const uint64_t& aId,
const bool& aIsForApp,
const bool& aIsForBrowser)
{
return PContentParent::SendPBrowserConstructor(aActor,
aContext,
aChromeFlags,
aId,
aIsForApp,
aIsForBrowser);
}
bool
ContentParent::RecvCreateFakeVolume(const nsString& fsName, const nsString& mountPoint)
{

View File

@ -8,6 +8,7 @@
#define mozilla_dom_ContentParent_h
#include "mozilla/dom/PContentParent.h"
#include "mozilla/dom/nsIContentParent.h"
#include "mozilla/ipc/GeckoChildProcessHost.h"
#include "mozilla/dom/ipc/Blob.h"
#include "mozilla/Attributes.h"
@ -63,9 +64,9 @@ class TabContext;
class PFileDescriptorSetParent;
class ContentParent : public PContentParent
, public nsIContentParent
, public nsIObserver
, public nsIDOMGeoPositionCallback
, public mozilla::dom::ipc::MessageManagerCallback
, public mozilla::LinkedListElement<ContentParent>
{
typedef mozilla::ipc::GeckoChildProcessHost GeckoChildProcessHost;
@ -75,6 +76,7 @@ class ContentParent : public PContentParent
typedef mozilla::dom::ClonedMessageData ClonedMessageData;
public:
virtual bool IsContentParent() MOZ_OVERRIDE { return true; }
/**
* Start up the content-process machinery. This might include
* scheduling pre-launch tasks.
@ -96,7 +98,8 @@ public:
static already_AddRefed<ContentParent>
GetNewOrUsed(bool aForBrowserElement = false,
hal::ProcessPriority aPriority =
hal::ProcessPriority::PROCESS_PRIORITY_FOREGROUND);
hal::ProcessPriority::PROCESS_PRIORITY_FOREGROUND,
ContentParent* aOpener = nullptr);
/**
* Create a subprocess suitable for use as a preallocated app process.
@ -117,6 +120,13 @@ public:
static void GetAll(nsTArray<ContentParent*>& aArray);
static void GetAllEvenIfDead(nsTArray<ContentParent*>& aArray);
virtual bool RecvCreateChildProcess(const IPCTabContext& aContext,
const hal::ProcessPriority& aPriority,
uint64_t* aId,
bool* aIsForApp,
bool* aIsForBrowser) MOZ_OVERRIDE;
virtual bool AnswerBridgeToChildProcess(const uint64_t& id) MOZ_OVERRIDE;
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(ContentParent, nsIObserver)
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
@ -151,8 +161,8 @@ public:
bool RequestRunToCompletion();
bool IsAlive();
bool IsForApp();
bool IsForBrowser()
virtual bool IsForApp() MOZ_OVERRIDE;
virtual bool IsForBrowser() MOZ_OVERRIDE
{
return mIsForBrowser;
}
@ -166,6 +176,10 @@ public:
int32_t Pid();
ContentParent* Opener() {
return mOpener;
}
bool NeedsPermissionsUpdate() const {
return mSendPermissionUpdates;
}
@ -174,8 +188,6 @@ public:
return mSendDataStoreInfos;
}
BlobParent* GetOrCreateActorForBlob(nsIDOMBlob* aBlob);
/**
* Kill our subprocess and make sure it dies. Should only be used
* in emergency situations since it bypasses the normal shutdown
@ -183,7 +195,7 @@ public:
*/
void KillHard();
uint64_t ChildID() { return mChildID; }
uint64_t ChildID() MOZ_OVERRIDE { return mChildID; }
const nsString& AppManifestURL() const { return mAppManifestURL; }
bool IsPreallocated();
@ -241,6 +253,10 @@ public:
nsICycleCollectorLogSink* aSink,
nsIDumpGCAndCCLogsCallback* aCallback);
virtual PBlobParent* SendPBlobConstructor(
PBlobParent* aActor,
const BlobConstructorParams& aParams) MOZ_OVERRIDE;
protected:
void OnChannelConnected(int32_t pid) MOZ_OVERRIDE;
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;
@ -269,12 +285,19 @@ private:
// Hide the raw constructor methods since we don't want client code
// using them.
using PContentParent::SendPBrowserConstructor;
virtual PBrowserParent* SendPBrowserConstructor(
PBrowserParent* actor,
const IPCTabContext& context,
const uint32_t& chromeFlags,
const uint64_t& aId,
const bool& aIsForApp,
const bool& aIsForBrowser) MOZ_OVERRIDE;
using PContentParent::SendPTestShellConstructor;
// No more than one of !!aApp, aIsForBrowser, and aIsForPreallocated may be
// true.
ContentParent(mozIApplication* aApp,
ContentParent* aOpener,
bool aIsForBrowser,
bool aIsForPreallocated,
hal::ProcessPriority aInitialPriority = hal::PROCESS_PRIORITY_FOREGROUND,
@ -568,6 +591,9 @@ private:
virtual void ProcessingError(Result what) MOZ_OVERRIDE;
virtual bool RecvAllocateLayerTreeId(uint64_t* aId) MOZ_OVERRIDE;
virtual bool RecvDeallocateLayerTreeId(const uint64_t& aId) MOZ_OVERRIDE;
virtual bool RecvGetGraphicsFeatureStatus(const int32_t& aFeature,
int32_t* aStatus,
bool* aSuccess) MOZ_OVERRIDE;
@ -591,6 +617,7 @@ private:
// details.
GeckoChildProcessHost* mSubprocess;
ContentParent* mOpener;
uint64_t mChildID;
int32_t mGeolocationWatchID;
@ -604,8 +631,6 @@ private:
*/
nsString mAppName;
nsRefPtr<nsFrameMessageManager> mMessageManager;
// After we initiate shutdown, we also start a timer to ensure
// that even content processes that are 100% blocked (say from
// SIGSTOP), are still killed eventually. This task enforces that

View File

@ -113,7 +113,7 @@ FilePickerParent::FileSizeAndDateRunnable::Destroy()
void
FilePickerParent::SendFiles(const nsCOMArray<nsIDOMFile>& aDomfiles)
{
ContentParent* parent = static_cast<ContentParent*>(Manager()->Manager());
nsIContentParent* parent = static_cast<TabParent*>(Manager())->Manager();
InfallibleTArray<PBlobParent*> files;
for (unsigned i = 0; i < aDomfiles.Length(); i++) {

View File

@ -4,6 +4,7 @@
include protocol PBlobStream;
include protocol PContent;
include protocol PContentBridge;
include DOMTypes;
@ -18,7 +19,7 @@ union ResolveMysteryParams
protocol PBlob
{
manager PContent;
manager PContent or PContentBridge;
manages PBlobStream;
both:

View File

@ -8,6 +8,7 @@
include protocol PBlob;
include protocol PColorPicker;
include protocol PContent;
include protocol PContentBridge;
include protocol PDocumentRenderer;
include protocol PContentPermissionRequest;
include protocol PFilePicker;
@ -70,7 +71,7 @@ union MaybeNativeKeyBinding
intr protocol PBrowser
{
manager PContent;
manager PContent or PContentBridge;
manages PColorPicker;
manages PDocumentRenderer;
@ -356,6 +357,15 @@ parent:
UpdateZoomConstraints(uint32_t aPresShellId, ViewID aViewId, bool aIsRoot,
ZoomConstraints aConstraints);
/**
* Brings up the auth prompt dialog.
* Called when this is the PBrowserParent for a nested remote iframe.
* aCallbackId corresponds to an nsIAuthPromptCallback that lives in the
* root process. It will be passed back to the root process with either the
* OnAuthAvailable or OnAuthCancelled message.
*/
AsyncAuthPrompt(nsCString uri, nsString realm, uint64_t aCallbackId);
__delete__();
ReplyKeyEvent(WidgetKeyboardEvent event);

View File

@ -10,6 +10,7 @@ include protocol PBlob;
include protocol PBluetooth;
include protocol PBrowser;
include protocol PCompositor;
include protocol PContentBridge;
include protocol PCycleCollectWithLogs;
include protocol PCrashReporter;
include protocol PExternalHelperApp;
@ -443,6 +444,11 @@ parent:
sync GetXPCOMProcessAttributes()
returns (bool isOffline);
sync CreateChildProcess(IPCTabContext context,
ProcessPriority priority)
returns (uint64_t id, bool isForApp, bool isForBrowser);
intr BridgeToChildProcess(uint64_t id);
async PJavaScript();
PDeviceStorageRequest(DeviceStorageParams params);
@ -590,6 +596,11 @@ parent:
sync KeywordToURI(nsCString keyword)
returns (OptionalInputStreamParams postData, OptionalURIParams uri);
// Tell the compositor to allocate a layer tree id for nested remote mozbrowsers.
sync AllocateLayerTreeId()
returns (uint64_t id);
async DeallocateLayerTreeId(uint64_t id);
sync SpeakerManagerForceSpeaker(bool aEnable);
sync SpeakerManagerGetSpeakerStatus()

View File

@ -0,0 +1,56 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=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 protocol PBlob;
include protocol PBrowser;
include protocol PContent;
include protocol PJavaScript;
include DOMTypes;
include JavaScriptTypes;
include PTabContext;
using class IPC::Principal from "mozilla/dom/PermissionMessageUtils.h";
namespace mozilla {
namespace dom {
/*
* PContentBridge allows us to represent a parent/child relationship between two
* child processes. When a child process wants to open its own child, it asks
* the root process to create a new process and then bridge them. The first
* child will allocate the PContentBridgeParent, and the newly opened child will
* allocate the PContentBridgeChild. This protocol allows these processes to
* share PBrowsers and send messages to each other.
*/
intr protocol PContentBridge
{
bridges PContent, PContent;
manages PBlob;
manages PBrowser;
manages PJavaScript;
parent:
sync SyncMessage(nsString aMessage, ClonedMessageData aData,
CpowEntry[] aCpows, Principal aPrincipal)
returns (nsString[] retval);
both:
// Both the parent and the child can construct the PBrowser.
// See the comment in PContent::PBrowser().
async PBrowser(IPCTabContext context, uint32_t chromeFlags,
uint64_t id, bool isForApp, bool isForBrowser);
async PBlob(BlobConstructorParams params);
async PJavaScript();
AsyncMessage(nsString aMessage, ClonedMessageData aData,
CpowEntry[] aCpows, Principal aPrincipal);
};
}
}

View File

@ -502,9 +502,9 @@ ProcessPriorityManagerImpl::ObserveContentParentCreated(
{
// Do nothing; it's sufficient to get the PPPM. But assign to nsRefPtr so we
// don't leak the already_AddRefed object.
nsCOMPtr<nsIObserver> cp = do_QueryInterface(aContentParent);
nsCOMPtr<nsIContentParent> cp = do_QueryInterface(aContentParent);
nsRefPtr<ParticularProcessPriorityManager> pppm =
GetParticularProcessPriorityManager(static_cast<ContentParent*>(cp.get()));
GetParticularProcessPriorityManager(cp->AsContentParent());
}
static PLDHashOperator
@ -816,6 +816,7 @@ ParticularProcessPriorityManager::OnRemoteBrowserFrameShown(nsISupports* aSubjec
fl->GetTabParent(getter_AddRefs(tp));
NS_ENSURE_TRUE_VOID(tp);
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
if (static_cast<TabParent*>(tp.get())->Manager() != mContentParent) {
return;
}
@ -829,6 +830,7 @@ ParticularProcessPriorityManager::OnTabParentDestroyed(nsISupports* aSubject)
nsCOMPtr<nsITabParent> tp = do_QueryInterface(aSubject);
NS_ENSURE_TRUE_VOID(tp);
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
if (static_cast<TabParent*>(tp.get())->Manager() != mContentParent) {
return;
}
@ -848,6 +850,7 @@ ParticularProcessPriorityManager::OnFrameloaderVisibleChanged(nsISupports* aSubj
return;
}
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
if (static_cast<TabParent*>(tp.get())->Manager() != mContentParent) {
return;
}

View File

@ -617,6 +617,15 @@ private:
StaticRefPtr<TabChild> sPreallocatedTab;
/*static*/
std::map<uint64_t, nsRefPtr<TabChild> >&
TabChild::NestedTabChildMap()
{
MOZ_ASSERT(NS_IsMainThread());
static std::map<uint64_t, nsRefPtr<TabChild> > sNestedTabChildMap;
return sNestedTabChildMap;
}
/*static*/ void
TabChild::PreloadSlowThings()
{
@ -652,7 +661,7 @@ TabChild::PreloadSlowThings()
}
/*static*/ already_AddRefed<TabChild>
TabChild::Create(ContentChild* aManager, const TabContext &aContext, uint32_t aChromeFlags)
TabChild::Create(nsIContentChild* aManager, const TabContext &aContext, uint32_t aChromeFlags)
{
if (sPreallocatedTab &&
sPreallocatedTab->mChromeFlags == aChromeFlags &&
@ -674,7 +683,7 @@ TabChild::Create(ContentChild* aManager, const TabContext &aContext, uint32_t aC
}
TabChild::TabChild(ContentChild* aManager, const TabContext& aContext, uint32_t aChromeFlags)
TabChild::TabChild(nsIContentChild* aManager, const TabContext& aContext, uint32_t aChromeFlags)
: TabContext(aContext)
, mRemoteFrame(nullptr)
, mManager(aManager)
@ -696,6 +705,7 @@ TabChild::TabChild(ContentChild* aManager, const TabContext& aContext, uint32_t
, mIgnoreKeyPressEvent(false)
, mActiveElementManager(new ActiveElementManager())
, mHasValidInnerSize(false)
, mUniqueId(0)
{
if (!sActiveDurationMsSet) {
Preferences::AddIntVarCache(&sActiveDurationMs,
@ -1372,6 +1382,9 @@ TabChild::ActorDestroy(ActorDestroyReason why)
(mTabChildGlobal->mMessageManager.get())->Disconnect();
mTabChildGlobal->mMessageManager = nullptr;
}
if (Id() != 0) {
NestedTabChildMap().erase(Id());
}
}
TabChild::~TabChild()
@ -2322,7 +2335,7 @@ TabChild::RecvAsyncMessage(const nsString& aMessage,
StructuredCloneData cloneData = UnpackClonedMessageDataForChild(aData);
nsRefPtr<nsFrameMessageManager> mm =
static_cast<nsFrameMessageManager*>(mTabChildGlobal->mMessageManager.get());
CpowIdHolder cpows(static_cast<ContentChild*>(Manager())->GetCPOWManager(), aCpows);
CpowIdHolder cpows(Manager()->GetCPOWManager(), aCpows);
mm->ReceiveMessage(static_cast<EventTarget*>(mTabChildGlobal),
aMessage, false, &cloneData, &cpows, aPrincipal, nullptr);
}
@ -2668,14 +2681,13 @@ TabChild::DoSendBlockingMessage(JSContext* aCx,
InfallibleTArray<nsString>* aJSONRetVal,
bool aIsSync)
{
ContentChild* cc = Manager();
ClonedMessageData data;
if (!BuildClonedMessageDataForChild(cc, aData, data)) {
if (!BuildClonedMessageDataForChild(Manager(), aData, data)) {
return false;
}
InfallibleTArray<CpowEntry> cpows;
if (sCpowsEnabled) {
if (!cc->GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) {
if (!Manager()->GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) {
return false;
}
}
@ -2695,14 +2707,13 @@ TabChild::DoSendAsyncMessage(JSContext* aCx,
JS::Handle<JSObject *> aCpows,
nsIPrincipal* aPrincipal)
{
ContentChild* cc = Manager();
ClonedMessageData data;
if (!BuildClonedMessageDataForChild(cc, aData, data)) {
if (!BuildClonedMessageDataForChild(Manager(), aData, data)) {
return false;
}
InfallibleTArray<CpowEntry> cpows;
if (sCpowsEnabled) {
if (!cc->GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) {
if (!Manager()->GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) {
return false;
}
}

View File

@ -240,6 +240,9 @@ class TabChild : public TabChildBase,
typedef mozilla::layout::ScrollingBehavior ScrollingBehavior;
typedef mozilla::layers::ActiveElementManager ActiveElementManager;
public:
static std::map<uint64_t, nsRefPtr<TabChild> >& NestedTabChildMap();
public:
/**
* This is expected to be called off the critical path to content
@ -250,12 +253,30 @@ public:
/** Return a TabChild with the given attributes. */
static already_AddRefed<TabChild>
Create(ContentChild* aManager, const TabContext& aContext, uint32_t aChromeFlags);
Create(nsIContentChild* aManager, const TabContext& aContext, uint32_t aChromeFlags);
virtual ~TabChild();
bool IsRootContentDocument();
const uint64_t Id() const {
return mUniqueId;
}
static uint64_t
GetTabChildId(TabChild* aTabChild)
{
MOZ_ASSERT(NS_IsMainThread());
if (aTabChild->Id() != 0) {
return aTabChild->Id();
}
static uint64_t sId = 0;
sId++;
aTabChild->mUniqueId = sId;
NestedTabChildMap()[sId] = aTabChild;
return sId;
}
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIWEBBROWSERCHROME
NS_DECL_NSIWEBBROWSERCHROME2
@ -430,7 +451,7 @@ public:
const nsAString& aPath,
nsICachedFileDescriptorListener* aCallback);
ContentChild* Manager() { return mManager; }
nsIContentChild* Manager() { return mManager; }
bool GetUpdateHitRegion() { return mUpdateHitRegion; }
@ -483,7 +504,7 @@ private:
*
* |aIsBrowserElement| indicates whether we're a browser (but not an app).
*/
TabChild(ContentChild* aManager, const TabContext& aContext, uint32_t aChromeFlags);
TabChild(nsIContentChild* aManager, const TabContext& aContext, uint32_t aChromeFlags);
nsresult Init();
@ -536,7 +557,7 @@ private:
nsCOMPtr<nsIWidget> mWidget;
nsCOMPtr<nsIURI> mLastURI;
RenderFrameChild* mRemoteFrame;
nsRefPtr<ContentChild> mManager;
nsRefPtr<nsIContentChild> mManager;
uint32_t mChromeFlags;
uint64_t mLayersId;
nsIntRect mOuterRect;
@ -568,6 +589,7 @@ private:
bool mIgnoreKeyPressEvent;
nsRefPtr<ActiveElementManager> mActiveElementManager;
bool mHasValidInnerSize;
uint64_t mUniqueId;
DISALLOW_EVIL_CONSTRUCTORS(TabChild);
};

View File

@ -22,6 +22,7 @@
#include "mozilla/layers/CompositorParent.h"
#include "mozilla/layout/RenderFrameParent.h"
#include "mozilla/MouseEvents.h"
#include "mozilla/net/NeckoChild.h"
#include "mozilla/Preferences.h"
#include "mozilla/TextEvents.h"
#include "mozilla/TouchEvents.h"
@ -61,6 +62,10 @@
#include "TabChild.h"
#include "LoadContext.h"
#include "nsNetCID.h"
#include "nsIAuthInformation.h"
#include "nsIAuthPromptCallback.h"
#include "nsAuthInformationHolder.h"
#include "nsICancelable.h"
#include "gfxPrefs.h"
#include <algorithm>
@ -206,7 +211,7 @@ NS_IMPL_ISUPPORTS(TabParent,
nsISecureBrowserUI,
nsISupportsWeakReference)
TabParent::TabParent(ContentParent* aManager, const TabContext& aContext, uint32_t aChromeFlags)
TabParent::TabParent(nsIContentParent* aManager, const TabContext& aContext, uint32_t aChromeFlags)
: TabContext(aContext)
, mFrameElement(nullptr)
, mIMESelectionAnchor(0)
@ -230,6 +235,7 @@ TabParent::TabParent(ContentParent* aManager, const TabContext& aContext, uint32
, mAppPackageFileDescriptorSent(false)
, mChromeFlags(aChromeFlags)
{
MOZ_ASSERT(aManager);
}
TabParent::~TabParent()
@ -299,14 +305,18 @@ TabParent::Destroy()
}
mIsDestroyed = true;
Manager()->NotifyTabDestroying(this);
if (XRE_GetProcessType() == GeckoProcessType_Default) {
Manager()->AsContentParent()->NotifyTabDestroying(this);
}
mMarkedDestroying = true;
}
bool
TabParent::Recv__delete__()
{
Manager()->NotifyTabDestroyed(this, mMarkedDestroying);
if (XRE_GetProcessType() == GeckoProcessType_Default) {
Manager()->AsContentParent()->NotifyTabDestroyed(this, mMarkedDestroying);
}
return true;
}
@ -972,15 +982,16 @@ TabParent::RecvSyncMessage(const nsString& aMessage,
const IPC::Principal& aPrincipal,
InfallibleTArray<nsString>* aJSONRetVal)
{
// FIXME Permission check for TabParent in Content process
nsIPrincipal* principal = aPrincipal;
ContentParent* parent = static_cast<ContentParent*>(Manager());
ContentParent* parent = Manager()->AsContentParent();
if (!Preferences::GetBool("dom.testing.ignore_ipc_principal", false) &&
principal && !AssertAppPrincipal(parent, principal)) {
parent && principal && !AssertAppPrincipal(parent, principal)) {
return false;
}
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
CpowIdHolder cpows(parent->GetCPOWManager(), aCpows);
CpowIdHolder cpows(Manager()->GetCPOWManager(), aCpows);
return ReceiveMessage(aMessage, true, &cloneData, &cpows, aPrincipal, aJSONRetVal);
}
@ -991,15 +1002,16 @@ TabParent::AnswerRpcMessage(const nsString& aMessage,
const IPC::Principal& aPrincipal,
InfallibleTArray<nsString>* aJSONRetVal)
{
// FIXME Permission check for TabParent in Content process
nsIPrincipal* principal = aPrincipal;
ContentParent* parent = static_cast<ContentParent*>(Manager());
ContentParent* parent = Manager()->AsContentParent();
if (!Preferences::GetBool("dom.testing.ignore_ipc_principal", false) &&
principal && !AssertAppPrincipal(parent, principal)) {
parent && principal && !AssertAppPrincipal(parent, principal)) {
return false;
}
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
CpowIdHolder cpows(parent->GetCPOWManager(), aCpows);
CpowIdHolder cpows(Manager()->GetCPOWManager(), aCpows);
return ReceiveMessage(aMessage, true, &cloneData, &cpows, aPrincipal, aJSONRetVal);
}
@ -1009,15 +1021,16 @@ TabParent::RecvAsyncMessage(const nsString& aMessage,
const InfallibleTArray<CpowEntry>& aCpows,
const IPC::Principal& aPrincipal)
{
// FIXME Permission check for TabParent in Content process
nsIPrincipal* principal = aPrincipal;
ContentParent* parent = static_cast<ContentParent*>(Manager());
ContentParent* parent = Manager()->AsContentParent();
if (!Preferences::GetBool("dom.testing.ignore_ipc_principal", false) &&
principal && !AssertAppPrincipal(parent, principal)) {
parent && principal && !AssertAppPrincipal(parent, principal)) {
return false;
}
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
CpowIdHolder cpows(parent->GetCPOWManager(), aCpows);
CpowIdHolder cpows(Manager()->GetCPOWManager(), aCpows);
return ReceiveMessage(aMessage, false, &cloneData, &cpows, aPrincipal, nullptr);
}
@ -1702,11 +1715,10 @@ TabParent::RecvPIndexedDBConstructor(PIndexedDBParent* aActor,
return true;
}
ContentParent* contentParent = Manager();
NS_ASSERTION(contentParent, "Null manager?!");
NS_ASSERTION(Manager(), "Null manager?!");
nsRefPtr<IDBFactory> factory;
rv = IDBFactory::Create(window, aGroup, aASCIIOrigin, contentParent,
rv = IDBFactory::Create(window, aGroup, aASCIIOrigin, Manager(),
getter_AddRefs(factory));
NS_ENSURE_SUCCESS(rv, false);
@ -2069,5 +2081,145 @@ TabParent::SetIsDocShellActive(bool isActive)
return NS_OK;
}
class FakeChannel MOZ_FINAL : public nsIChannel,
public nsIAuthPromptCallback,
public nsIInterfaceRequestor,
public nsILoadContext
{
public:
FakeChannel(const nsCString& aUri, uint64_t aCallbackId, Element* aElement)
: mCallbackId(aCallbackId)
, mElement(aElement)
{
NS_NewURI(getter_AddRefs(mUri), aUri);
}
NS_DECL_ISUPPORTS
#define NO_IMPL { return NS_ERROR_NOT_IMPLEMENTED; }
NS_IMETHOD GetName(nsACString&) NO_IMPL
NS_IMETHOD IsPending(bool*) NO_IMPL
NS_IMETHOD GetStatus(nsresult*) NO_IMPL
NS_IMETHOD Cancel(nsresult) NO_IMPL
NS_IMETHOD Suspend() NO_IMPL
NS_IMETHOD Resume() NO_IMPL
NS_IMETHOD GetLoadGroup(nsILoadGroup**) NO_IMPL
NS_IMETHOD SetLoadGroup(nsILoadGroup*) NO_IMPL
NS_IMETHOD SetLoadFlags(nsLoadFlags) NO_IMPL
NS_IMETHOD GetLoadFlags(nsLoadFlags*) NO_IMPL
NS_IMETHOD GetOriginalURI(nsIURI**) NO_IMPL
NS_IMETHOD SetOriginalURI(nsIURI*) NO_IMPL
NS_IMETHOD GetURI(nsIURI** aUri)
{
NS_IF_ADDREF(mUri);
*aUri = mUri;
return NS_OK;
}
NS_IMETHOD GetOwner(nsISupports**) NO_IMPL
NS_IMETHOD SetOwner(nsISupports*) NO_IMPL
NS_IMETHOD GetNotificationCallbacks(nsIInterfaceRequestor** aRequestor)
{
NS_ADDREF(*aRequestor = this);
return NS_OK;
}
NS_IMETHOD SetNotificationCallbacks(nsIInterfaceRequestor*) NO_IMPL
NS_IMETHOD GetSecurityInfo(nsISupports**) NO_IMPL
NS_IMETHOD GetContentType(nsACString&) NO_IMPL
NS_IMETHOD SetContentType(const nsACString&) NO_IMPL
NS_IMETHOD GetContentCharset(nsACString&) NO_IMPL
NS_IMETHOD SetContentCharset(const nsACString&) NO_IMPL
NS_IMETHOD GetContentLength(int64_t*) NO_IMPL
NS_IMETHOD SetContentLength(int64_t) NO_IMPL
NS_IMETHOD Open(nsIInputStream**) NO_IMPL
NS_IMETHOD AsyncOpen(nsIStreamListener*, nsISupports*) NO_IMPL
NS_IMETHOD GetContentDisposition(uint32_t*) NO_IMPL
NS_IMETHOD SetContentDisposition(uint32_t) NO_IMPL
NS_IMETHOD GetContentDispositionFilename(nsAString&) NO_IMPL
NS_IMETHOD SetContentDispositionFilename(const nsAString&) NO_IMPL
NS_IMETHOD GetContentDispositionHeader(nsACString&) NO_IMPL
NS_IMETHOD OnAuthAvailable(nsISupports *aContext, nsIAuthInformation *aAuthInfo);
NS_IMETHOD OnAuthCancelled(nsISupports *aContext, bool userCancel);
NS_IMETHOD GetInterface(const nsIID & uuid, void **result)
{
return QueryInterface(uuid, result);
}
NS_IMETHOD GetAssociatedWindow(nsIDOMWindow**) NO_IMPL
NS_IMETHOD GetTopWindow(nsIDOMWindow**) NO_IMPL
NS_IMETHOD GetTopFrameElement(nsIDOMElement** aElement)
{
nsCOMPtr<nsIDOMElement> elem = do_QueryInterface(mElement);
elem.forget(aElement);
return NS_OK;
}
NS_IMETHOD GetNestedFrameId(uint64_t*) NO_IMPL
NS_IMETHOD IsAppOfType(uint32_t, bool*) NO_IMPL
NS_IMETHOD GetIsContent(bool*) NO_IMPL
NS_IMETHOD GetUsePrivateBrowsing(bool*) NO_IMPL
NS_IMETHOD SetUsePrivateBrowsing(bool) NO_IMPL
NS_IMETHOD SetPrivateBrowsing(bool) NO_IMPL
NS_IMETHOD GetIsInBrowserElement(bool*) NO_IMPL
NS_IMETHOD GetAppId(uint32_t*) NO_IMPL
NS_IMETHOD GetUseRemoteTabs(bool*) NO_IMPL
NS_IMETHOD SetRemoteTabs(bool) NO_IMPL
#undef NO_IMPL
protected:
nsCOMPtr<nsIURI> mUri;
uint64_t mCallbackId;
nsCOMPtr<Element> mElement;
};
NS_IMPL_ISUPPORTS(FakeChannel, nsIChannel, nsIAuthPromptCallback,
nsIRequest, nsIInterfaceRequestor, nsILoadContext);
bool
TabParent::RecvAsyncAuthPrompt(const nsCString& aUri,
const nsString& aRealm,
const uint64_t& aCallbackId)
{
nsCOMPtr<nsIAuthPrompt2> authPrompt;
GetAuthPrompt(nsIAuthPromptProvider::PROMPT_NORMAL,
NS_GET_IID(nsIAuthPrompt2),
getter_AddRefs(authPrompt));
nsRefPtr<FakeChannel> channel = new FakeChannel(aUri, aCallbackId, mFrameElement);
uint32_t promptFlags = nsIAuthInformation::AUTH_HOST;
nsRefPtr<nsAuthInformationHolder> holder =
new nsAuthInformationHolder(promptFlags, aRealm,
EmptyCString());
uint32_t level = nsIAuthPrompt2::LEVEL_NONE;
nsCOMPtr<nsICancelable> dummy;
nsresult rv =
authPrompt->AsyncPromptAuth(channel, channel, nullptr,
level, holder, getter_AddRefs(dummy));
return rv == NS_OK;
}
NS_IMETHODIMP
FakeChannel::OnAuthAvailable(nsISupports *aContext, nsIAuthInformation *aAuthInfo)
{
nsAuthInformationHolder* holder =
static_cast<nsAuthInformationHolder*>(aAuthInfo);
if (!net::gNeckoChild->SendOnAuthAvailable(mCallbackId,
holder->User(),
holder->Password(),
holder->Domain())) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
NS_IMETHODIMP
FakeChannel::OnAuthCancelled(nsISupports *aContext, bool userCancel)
{
if (!net::gNeckoChild->SendOnAuthCancelled(mCallbackId, userCancel)) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
} // namespace tabs
} // namespace mozilla

View File

@ -43,7 +43,7 @@ class RenderFrameParent;
namespace dom {
class ClonedMessageData;
class ContentParent;
class nsIContentParent;
class Element;
struct StructuredCloneData;
@ -61,7 +61,7 @@ public:
// nsITabParent
NS_DECL_NSITABPARENT
TabParent(ContentParent* aManager, const TabContext& aContext, uint32_t aChromeFlags);
TabParent(nsIContentParent* aManager, const TabContext& aContext, uint32_t aChromeFlags);
virtual ~TabParent();
Element* GetOwnerElement() const { return mFrameElement; }
void SetOwnerElement(Element* aElement);
@ -291,7 +291,7 @@ public:
static TabParent* GetFrom(nsFrameLoader* aFrameLoader);
static TabParent* GetFrom(nsIContent* aContent);
ContentParent* Manager() { return mManager; }
nsIContentParent* Manager() { return mManager; }
/**
* Let managees query if Destroy() is already called so they don't send out
@ -307,6 +307,10 @@ protected:
nsIPrincipal* aPrincipal,
InfallibleTArray<nsString>* aJSONRetVal = nullptr);
virtual bool RecvAsyncAuthPrompt(const nsCString& aUri,
const nsString& aRealm,
const uint64_t& aCallbackId) MOZ_OVERRIDE;
virtual bool Recv__delete__() MOZ_OVERRIDE;
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;
@ -368,7 +372,7 @@ private:
already_AddRefed<nsFrameLoader> GetFrameLoader() const;
already_AddRefed<nsIWidget> GetWidget() const;
layout::RenderFrameParent* GetRenderFrame();
nsRefPtr<ContentParent> mManager;
nsRefPtr<nsIContentParent> mManager;
void TryCacheDPIAndScale();
CSSPoint AdjustTapToChildWidget(const CSSPoint& aPoint);

View File

@ -17,6 +17,8 @@ EXPORTS.mozilla.dom.ipc += [
]
EXPORTS.mozilla.dom += [
'ContentBridgeChild.h',
'ContentBridgeParent.h',
'ContentChild.h',
'ContentParent.h',
'ContentProcess.h',
@ -25,6 +27,8 @@ EXPORTS.mozilla.dom += [
'FileDescriptorSetChild.h',
'FileDescriptorSetParent.h',
'FilePickerParent.h',
'nsIContentChild.h',
'nsIContentParent.h',
'PermissionMessageUtils.h',
'StructuredCloneUtils.h',
'TabChild.h',
@ -42,12 +46,16 @@ EXPORTS.mozilla += [
UNIFIED_SOURCES += [
'AppProcessChecker.cpp',
'ColorPickerParent.cpp',
'ContentBridgeChild.cpp',
'ContentBridgeParent.cpp',
'ContentParent.cpp',
'ContentProcess.cpp',
'CrashReporterParent.cpp',
'FileDescriptorSetChild.cpp',
'FileDescriptorSetParent.cpp',
'FilePickerParent.cpp',
'nsIContentChild.cpp',
'nsIContentParent.cpp',
'PermissionMessageUtils.cpp',
'PreallocatedProcessManager.cpp',
'ProcessPriorityManager.cpp',
@ -75,6 +83,7 @@ IPDL_SOURCES += [
'PBrowser.ipdl',
'PColorPicker.ipdl',
'PContent.ipdl',
'PContentBridge.ipdl',
'PContentPermission.ipdlh',
'PContentPermissionRequest.ipdl',
'PCrashReporter.ipdl',

200
dom/ipc/nsIContentChild.cpp Normal file
View File

@ -0,0 +1,200 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=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 "nsIContentChild.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/PermissionMessageUtils.h"
#include "mozilla/dom/StructuredCloneUtils.h"
#include "mozilla/dom/TabChild.h"
#include "mozilla/dom/ipc/nsIRemoteBlob.h"
#include "mozilla/ipc/InputStreamUtils.h"
#include "JavaScriptChild.h"
#include "nsDOMFile.h"
#include "nsIJSRuntimeService.h"
#include "nsPrintfCString.h"
using namespace mozilla::ipc;
using namespace mozilla::jsipc;
namespace mozilla {
namespace dom {
PJavaScriptChild*
nsIContentChild::AllocPJavaScriptChild()
{
nsCOMPtr<nsIJSRuntimeService> svc = do_GetService("@mozilla.org/js/xpc/RuntimeService;1");
NS_ENSURE_TRUE(svc, nullptr);
JSRuntime *rt;
svc->GetRuntime(&rt);
NS_ENSURE_TRUE(svc, nullptr);
nsAutoPtr<JavaScriptChild> child(new JavaScriptChild(rt));
if (!child->init()) {
return nullptr;
}
return child.forget();
}
bool
nsIContentChild::DeallocPJavaScriptChild(PJavaScriptChild* aChild)
{
static_cast<JavaScriptChild*>(aChild)->decref();
return true;
}
PBrowserChild*
nsIContentChild::AllocPBrowserChild(const IPCTabContext& aContext,
const uint32_t& aChromeFlags,
const uint64_t& aID,
const bool& aIsForApp,
const bool& aIsForBrowser)
{
// We'll happily accept any kind of IPCTabContext here; we don't need to
// check that it's of a certain type for security purposes, because we
// believe whatever the parent process tells us.
MaybeInvalidTabContext tc(aContext);
if (!tc.IsValid()) {
NS_ERROR(nsPrintfCString("Received an invalid TabContext from "
"the parent process. (%s) Crashing...",
tc.GetInvalidReason()).get());
MOZ_CRASH("Invalid TabContext received from the parent process.");
}
nsRefPtr<TabChild> child = TabChild::Create(this, tc.GetTabContext(), aChromeFlags);
// The ref here is released in DeallocPBrowserChild.
return child.forget().take();
}
bool
nsIContentChild::DeallocPBrowserChild(PBrowserChild* aIframe)
{
TabChild* child = static_cast<TabChild*>(aIframe);
NS_RELEASE(child);
return true;
}
PBlobChild*
nsIContentChild::AllocPBlobChild(const BlobConstructorParams& aParams)
{
return BlobChild::Create(this, aParams);
}
bool
nsIContentChild::DeallocPBlobChild(PBlobChild* aActor)
{
delete aActor;
return true;
}
BlobChild*
nsIContentChild::GetOrCreateActorForBlob(nsIDOMBlob* aBlob)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aBlob);
// If the blob represents a remote blob then we can simply pass its actor back
// here.
if (nsCOMPtr<nsIRemoteBlob> remoteBlob = do_QueryInterface(aBlob)) {
BlobChild* actor =
static_cast<BlobChild*>(
static_cast<PBlobChild*>(remoteBlob->GetPBlob()));
MOZ_ASSERT(actor);
if (actor->Manager() == this) {
return actor;
}
}
// All blobs shared between processes must be immutable.
nsCOMPtr<nsIMutable> mutableBlob = do_QueryInterface(aBlob);
if (!mutableBlob || NS_FAILED(mutableBlob->SetMutable(false))) {
NS_WARNING("Failed to make blob immutable!");
return nullptr;
}
#ifdef DEBUG
{
// XXX This is only safe so long as all blob implementations in our tree
// inherit nsDOMFileBase. If that ever changes then this will need to
// grow a real interface or something.
const auto* blob = static_cast<nsDOMFileBase*>(aBlob);
MOZ_ASSERT(!blob->IsSizeUnknown());
MOZ_ASSERT(!blob->IsDateUnknown());
}
#endif
ParentBlobConstructorParams params;
nsString contentType;
nsresult rv = aBlob->GetType(contentType);
NS_ENSURE_SUCCESS(rv, nullptr);
uint64_t length;
rv = aBlob->GetSize(&length);
NS_ENSURE_SUCCESS(rv, nullptr);
nsCOMPtr<nsIInputStream> stream;
rv = aBlob->GetInternalStream(getter_AddRefs(stream));
NS_ENSURE_SUCCESS(rv, nullptr);
InputStreamParams inputStreamParams;
nsTArray<mozilla::ipc::FileDescriptor> fds;
SerializeInputStream(stream, inputStreamParams, fds);
MOZ_ASSERT(fds.IsEmpty());
params.optionalInputStreamParams() = inputStreamParams;
nsCOMPtr<nsIDOMFile> file = do_QueryInterface(aBlob);
if (file) {
FileBlobConstructorParams fileParams;
rv = file->GetName(fileParams.name());
NS_ENSURE_SUCCESS(rv, nullptr);
rv = file->GetMozLastModifiedDate(&fileParams.modDate());
NS_ENSURE_SUCCESS(rv, nullptr);
fileParams.contentType() = contentType;
fileParams.length() = length;
params.blobParams() = fileParams;
} else {
NormalBlobConstructorParams blobParams;
blobParams.contentType() = contentType;
blobParams.length() = length;
params.blobParams() = blobParams;
}
BlobChild* actor = BlobChild::Create(this, aBlob);
NS_ENSURE_TRUE(actor, nullptr);
return SendPBlobConstructor(actor, params) ? actor : nullptr;
}
bool
nsIContentChild::RecvAsyncMessage(const nsString& aMsg,
const ClonedMessageData& aData,
const InfallibleTArray<CpowEntry>& aCpows,
const IPC::Principal& aPrincipal)
{
nsRefPtr<nsFrameMessageManager> cpm = nsFrameMessageManager::sChildProcessManager;
if (cpm) {
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForChild(aData);
CpowIdHolder cpows(GetCPOWManager(), aCpows);
cpm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(cpm.get()),
aMsg, false, &cloneData, &cpows, aPrincipal, nullptr);
}
return true;
}
} // dom
} // mozilla

77
dom/ipc/nsIContentChild.h Normal file
View File

@ -0,0 +1,77 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_nsIContentChild_h
#define mozilla_dom_nsIContentChild_h
#include "mozilla/dom/ipc/Blob.h"
#include "nsISupports.h"
#define NS_ICONTENTCHILD_IID \
{ 0x4eed2e73, 0x94ba, 0x48a8, \
{ 0xa2, 0xd1, 0xa5, 0xed, 0x86, 0xd7, 0xbb, 0xe4 } }
class PBrowserChild;
namespace IPC {
class Principal;
} // IPC
namespace mozilla {
namespace jsipc {
class PJavaScriptChild;
class JavaScriptChild;
class CpowEntry;
} // jsipc
namespace dom {
struct IPCTabContext;
class nsIContentChild : public nsISupports
{
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ICONTENTCHILD_IID)
BlobChild* GetOrCreateActorForBlob(nsIDOMBlob* aBlob);
virtual PBlobChild*
SendPBlobConstructor(PBlobChild* aActor,
const BlobConstructorParams& params) = 0;
virtual bool
SendPBrowserConstructor(PBrowserChild* aActor,
const IPCTabContext& aContext,
const uint32_t& aChromeFlags,
const uint64_t& aID,
const bool& aIsForApp,
const bool& aIsForBrowser) = 0;
virtual jsipc::JavaScriptChild* GetCPOWManager() = 0;
protected:
virtual jsipc::PJavaScriptChild* AllocPJavaScriptChild();
virtual bool DeallocPJavaScriptChild(jsipc::PJavaScriptChild*);
virtual PBrowserChild* AllocPBrowserChild(const IPCTabContext& aContext,
const uint32_t& aChromeFlags,
const uint64_t& aID,
const bool& aIsForApp,
const bool& aIsForBrowser);
virtual bool DeallocPBrowserChild(PBrowserChild*);
virtual PBlobChild* AllocPBlobChild(const BlobConstructorParams& aParams);
virtual bool DeallocPBlobChild(PBlobChild*);
virtual bool RecvAsyncMessage(const nsString& aMsg,
const ClonedMessageData& aData,
const InfallibleTArray<jsipc::CpowEntry>& aCpows,
const IPC::Principal& aPrincipal);
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIContentChild, NS_ICONTENTCHILD_IID)
} // dom
} // mozilla
#endif /* mozilla_dom_nsIContentChild_h */

View File

@ -0,0 +1,306 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=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 "nsIContentParent.h"
#include "mozilla/AppProcessChecker.h"
#include "mozilla/Preferences.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/PTabContext.h"
#include "mozilla/dom/PermissionMessageUtils.h"
#include "mozilla/dom/StructuredCloneUtils.h"
#include "mozilla/dom/TabParent.h"
#include "mozilla/dom/ipc/nsIRemoteBlob.h"
#include "mozilla/unused.h"
#include "JavaScriptParent.h"
#include "nsDOMFile.h"
#include "nsFrameMessageManager.h"
#include "nsIJSRuntimeService.h"
#include "nsPrintfCString.h"
using namespace mozilla::jsipc;
namespace mozilla {
namespace dom {
nsIContentParent::nsIContentParent()
{
mMessageManager = nsFrameMessageManager::NewProcessMessageManager(this);
}
ContentParent*
nsIContentParent::AsContentParent()
{
MOZ_ASSERT(IsContentParent());
return static_cast<ContentParent*>(this);
}
PJavaScriptParent*
nsIContentParent::AllocPJavaScriptParent()
{
nsCOMPtr<nsIJSRuntimeService> svc =
do_GetService("@mozilla.org/js/xpc/RuntimeService;1");
NS_ENSURE_TRUE(svc, nullptr);
JSRuntime *rt;
svc->GetRuntime(&rt);
NS_ENSURE_TRUE(svc, nullptr);
nsAutoPtr<JavaScriptParent> parent(new JavaScriptParent(rt));
if (!parent->init()) {
return nullptr;
}
return parent.forget();
}
bool
nsIContentParent::DeallocPJavaScriptParent(PJavaScriptParent* aParent)
{
static_cast<JavaScriptParent*>(aParent)->decref();
return true;
}
bool
nsIContentParent::CanOpenBrowser(const IPCTabContext& aContext)
{
const IPCTabAppBrowserContext& appBrowser = aContext.appBrowserContext();
// We don't trust the IPCTabContext we receive from the child, so we'll bail
// if we receive an IPCTabContext that's not a PopupIPCTabContext.
// (PopupIPCTabContext lets the child process prove that it has access to
// the app it's trying to open.)
if (appBrowser.type() != IPCTabAppBrowserContext::TPopupIPCTabContext) {
NS_ERROR("Unexpected IPCTabContext type. Aborting AllocPBrowserParent.");
return false;
}
const PopupIPCTabContext& popupContext = appBrowser.get_PopupIPCTabContext();
TabParent* opener = static_cast<TabParent*>(popupContext.openerParent());
if (!opener) {
NS_ERROR("Got null opener from child; aborting AllocPBrowserParent.");
return false;
}
// Popup windows of isBrowser frames must be isBrowser if the parent
// isBrowser. Allocating a !isBrowser frame with same app ID would allow
// the content to access data it's not supposed to.
if (!popupContext.isBrowserElement() && opener->IsBrowserElement()) {
NS_ERROR("Child trying to escalate privileges! Aborting AllocPBrowserParent.");
return false;
}
MaybeInvalidTabContext tc(aContext);
if (!tc.IsValid()) {
NS_ERROR(nsPrintfCString("Child passed us an invalid TabContext. (%s) "
"Aborting AllocPBrowserParent.",
tc.GetInvalidReason()).get());
return false;
}
return true;
}
PBrowserParent*
nsIContentParent::AllocPBrowserParent(const IPCTabContext& aContext,
const uint32_t& aChromeFlags,
const uint64_t& aId,
const bool& aIsForApp,
const bool& aIsForBrowser)
{
unused << aChromeFlags;
unused << aId;
unused << aIsForApp;
unused << aIsForBrowser;
if (!CanOpenBrowser(aContext)) {
return nullptr;
}
MaybeInvalidTabContext tc(aContext);
MOZ_ASSERT(tc.IsValid());
TabParent* parent = new TabParent(this, tc.GetTabContext(), aChromeFlags);
// We release this ref in DeallocPBrowserParent()
NS_ADDREF(parent);
return parent;
}
bool
nsIContentParent::DeallocPBrowserParent(PBrowserParent* aFrame)
{
TabParent* parent = static_cast<TabParent*>(aFrame);
NS_RELEASE(parent);
return true;
}
PBlobParent*
nsIContentParent::AllocPBlobParent(const BlobConstructorParams& aParams)
{
return BlobParent::Create(this, aParams);
}
bool
nsIContentParent::DeallocPBlobParent(PBlobParent* aActor)
{
delete aActor;
return true;
}
BlobParent*
nsIContentParent::GetOrCreateActorForBlob(nsIDOMBlob* aBlob)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aBlob);
// If the blob represents a remote blob for this ContentParent then we can
// simply pass its actor back here.
if (nsCOMPtr<nsIRemoteBlob> remoteBlob = do_QueryInterface(aBlob)) {
if (BlobParent* actor = static_cast<BlobParent*>(
static_cast<PBlobParent*>(remoteBlob->GetPBlob()))) {
MOZ_ASSERT(actor);
if (actor->Manager() == this) {
return actor;
}
}
}
// All blobs shared between processes must be immutable.
nsCOMPtr<nsIMutable> mutableBlob = do_QueryInterface(aBlob);
if (!mutableBlob || NS_FAILED(mutableBlob->SetMutable(false))) {
NS_WARNING("Failed to make blob immutable!");
return nullptr;
}
// XXX This is only safe so long as all blob implementations in our tree
// inherit nsDOMFileBase. If that ever changes then this will need to grow
// a real interface or something.
const auto* blob = static_cast<nsDOMFileBase*>(aBlob);
ChildBlobConstructorParams params;
if (blob->IsSizeUnknown() || blob->IsDateUnknown()) {
// We don't want to call GetSize or GetLastModifiedDate
// yet since that may stat a file on the main thread
// here. Instead we'll learn the size lazily from the
// other process.
params = MysteryBlobConstructorParams();
}
else {
nsString contentType;
nsresult rv = aBlob->GetType(contentType);
NS_ENSURE_SUCCESS(rv, nullptr);
uint64_t length;
rv = aBlob->GetSize(&length);
NS_ENSURE_SUCCESS(rv, nullptr);
nsCOMPtr<nsIDOMFile> file = do_QueryInterface(aBlob);
if (file) {
FileBlobConstructorParams fileParams;
rv = file->GetMozLastModifiedDate(&fileParams.modDate());
NS_ENSURE_SUCCESS(rv, nullptr);
rv = file->GetName(fileParams.name());
NS_ENSURE_SUCCESS(rv, nullptr);
fileParams.contentType() = contentType;
fileParams.length() = length;
params = fileParams;
} else {
NormalBlobConstructorParams blobParams;
blobParams.contentType() = contentType;
blobParams.length() = length;
params = blobParams;
}
}
BlobParent* actor = BlobParent::Create(this, aBlob);
NS_ENSURE_TRUE(actor, nullptr);
return SendPBlobConstructor(actor, params) ? actor : nullptr;
}
bool
nsIContentParent::RecvSyncMessage(const nsString& aMsg,
const ClonedMessageData& aData,
const InfallibleTArray<CpowEntry>& aCpows,
const IPC::Principal& aPrincipal,
InfallibleTArray<nsString>* aRetvals)
{
// FIXME Permission check in Content process
nsIPrincipal* principal = aPrincipal;
ContentParent* parent = AsContentParent();
if (!Preferences::GetBool("dom.testing.ignore_ipc_principal", false) &&
parent && principal && !AssertAppPrincipal(parent, principal)) {
return false;
}
nsRefPtr<nsFrameMessageManager> ppm = mMessageManager;
if (ppm) {
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
CpowIdHolder cpows(GetCPOWManager(), aCpows);
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()),
aMsg, true, &cloneData, &cpows, aPrincipal, aRetvals);
}
return true;
}
bool
nsIContentParent::AnswerRpcMessage(const nsString& aMsg,
const ClonedMessageData& aData,
const InfallibleTArray<CpowEntry>& aCpows,
const IPC::Principal& aPrincipal,
InfallibleTArray<nsString>* aRetvals)
{
// FIXME Permission check in Content process
nsIPrincipal* principal = aPrincipal;
ContentParent* parent = AsContentParent();
if (!Preferences::GetBool("dom.testing.ignore_ipc_principal", false) &&
parent && principal && !AssertAppPrincipal(parent, principal)) {
return false;
}
nsRefPtr<nsFrameMessageManager> ppm = mMessageManager;
if (ppm) {
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
CpowIdHolder cpows(GetCPOWManager(), aCpows);
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()),
aMsg, true, &cloneData, &cpows, aPrincipal, aRetvals);
}
return true;
}
bool
nsIContentParent::RecvAsyncMessage(const nsString& aMsg,
const ClonedMessageData& aData,
const InfallibleTArray<CpowEntry>& aCpows,
const IPC::Principal& aPrincipal)
{
// FIXME Permission check in Content process
nsIPrincipal* principal = aPrincipal;
ContentParent* parent = AsContentParent();
if (!Preferences::GetBool("dom.testing.ignore_ipc_principal", false) &&
parent && principal && !AssertAppPrincipal(parent, principal)) {
return false;
}
nsRefPtr<nsFrameMessageManager> ppm = mMessageManager;
if (ppm) {
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
CpowIdHolder cpows(GetCPOWManager(), aCpows);
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()),
aMsg, false, &cloneData, &cpows, aPrincipal, nullptr);
}
return true;
}
} // namespace dom
} // namespace mozilla

108
dom/ipc/nsIContentParent.h Normal file
View File

@ -0,0 +1,108 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_nsIContentParent_h
#define mozilla_dom_nsIContentParent_h
#include "mozilla/dom/ipc/Blob.h"
#include "nsFrameMessageManager.h"
#include "nsISupports.h"
#define NS_ICONTENTPARENT_IID \
{ 0xeeec9ebf, 0x8ecf, 0x4e38, \
{ 0x81, 0xda, 0xb7, 0x34, 0x13, 0x7e, 0xac, 0xf3 } }
class nsFrameMessageManager;
namespace IPC {
class Principal;
} // namespace IPC
namespace mozilla {
namespace jsipc {
class PJavaScriptParent;
class JavaScriptParent;
class CpowEntry;
} // namespace jsipc
namespace dom {
struct IPCTabContext;
class ContentParent;
class nsIContentParent : public nsISupports
, public mozilla::dom::ipc::MessageManagerCallback
{
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ICONTENTPARENT_IID)
nsIContentParent();
BlobParent* GetOrCreateActorForBlob(nsIDOMBlob* aBlob);
virtual uint64_t ChildID() = 0;
virtual bool IsForApp() = 0;
virtual bool IsForBrowser() = 0;
virtual PBlobParent* SendPBlobConstructor(
PBlobParent* actor,
const BlobConstructorParams& params) NS_WARN_UNUSED_RESULT = 0;
virtual PBrowserParent* SendPBrowserConstructor(
PBrowserParent* actor,
const IPCTabContext& context,
const uint32_t& chromeFlags,
const uint64_t& aId,
const bool& aIsForApp,
const bool& aIsForBrowser) NS_WARN_UNUSED_RESULT = 0;
virtual jsipc::JavaScriptParent *GetCPOWManager() = 0;
virtual bool IsContentParent() { return false; }
ContentParent* AsContentParent();
protected: // methods
bool CanOpenBrowser(const IPCTabContext& aContext);
protected: // IPDL methods
virtual mozilla::jsipc::PJavaScriptParent* AllocPJavaScriptParent();
virtual bool DeallocPJavaScriptParent(mozilla::jsipc::PJavaScriptParent*);
virtual PBrowserParent* AllocPBrowserParent(const IPCTabContext& aContext,
const uint32_t& aChromeFlags,
const uint64_t& aId,
const bool& aIsForApp,
const bool& aIsForBrowser);
virtual bool DeallocPBrowserParent(PBrowserParent* frame);
virtual PBlobParent* AllocPBlobParent(const BlobConstructorParams& aParams);
virtual bool DeallocPBlobParent(PBlobParent*);
virtual bool RecvSyncMessage(const nsString& aMsg,
const ClonedMessageData& aData,
const InfallibleTArray<jsipc::CpowEntry>& aCpows,
const IPC::Principal& aPrincipal,
InfallibleTArray<nsString>* aRetvals);
virtual bool AnswerRpcMessage(const nsString& aMsg,
const ClonedMessageData& aData,
const InfallibleTArray<jsipc::CpowEntry>& aCpows,
const IPC::Principal& aPrincipal,
InfallibleTArray<nsString>* aRetvals);
virtual bool RecvAsyncMessage(const nsString& aMsg,
const ClonedMessageData& aData,
const InfallibleTArray<jsipc::CpowEntry>& aCpows,
const IPC::Principal& aPrincipal);
protected: // members
nsRefPtr<nsFrameMessageManager> mMessageManager;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIContentParent, NS_ICONTENTPARENT_IID)
} // namespace dom
} // namespace mozilla
#endif /* mozilla_dom_nsIContentParent_h */

View File

@ -1192,12 +1192,16 @@ EventRunnable::PreDispatch(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
mUseCachedArrayBufferResponse = true;
doClone = false;
} else {
MOZ_ASSERT(!JS_IsNeuteredArrayBufferObject(obj));
JS::AutoValueArray<1> argv(aCx);
argv[0].set(response);
obj = JS_NewArrayObject(aCx, argv);
if (obj) {
transferable.setObject(*obj);
mProxy->mArrayBufferResponseWasTransferred = true;
// Only cache the response when the readyState is DONE.
if (xhr->ReadyState() == nsIXMLHttpRequest::DONE) {
mProxy->mArrayBufferResponseWasTransferred = true;
}
} else {
mResponseResult = NS_ERROR_OUT_OF_MEMORY;
doClone = false;

View File

@ -1096,10 +1096,13 @@ nsXBLBinding::LookupMember(JSContext* aCx, JS::Handle<jsid> aId,
// Get the string as an nsString before doing anything, so we can make
// convenient comparisons during our search.
//
// Note: the infallibleInit call below depends on this check.
if (!JSID_IS_STRING(aId)) {
return true;
}
nsDependentJSString name(aId);
nsDependentJSString name;
name.infallibleInit(aId);
// We have a weak reference to our bound element, so make sure it's alive.
if (!mBoundElement || !mBoundElement->GetWrapper()) {

View File

@ -189,7 +189,7 @@ InstallXBLField(JSContext* cx,
JS::Rooted<JS::Value> name(cx, js::GetFunctionNativeReserved(callee, FIELD_SLOT));
JSFlatString* fieldStr = JS_ASSERT_STRING_IS_FLAT(name.toString());
fieldName.init(fieldStr);
fieldName.infallibleInit(fieldStr);
MOZ_ALWAYS_TRUE(JS_ValueToId(cx, name, idp));

View File

@ -472,7 +472,8 @@ UpdateLinearParametersToIncludePoint(double *min_t, double *max_t,
*/
static void
CalculateRepeatingGradientParams(CGPoint *aStart, CGPoint *aEnd,
CGRect aExtents, int *aRepeatCount)
CGRect aExtents, int *aRepeatStartFactor,
int *aRepeatEndFactor)
{
double t_min = INFINITY;
double t_max = -INFINITY;
@ -506,39 +507,38 @@ CalculateRepeatingGradientParams(CGPoint *aStart, CGPoint *aEnd,
aStart->x = aStart->x + dx * t_min;
aStart->y = aStart->y + dy * t_min;
*aRepeatCount = t_max - t_min;
*aRepeatStartFactor = t_min;
*aRepeatEndFactor = t_max;
}
static void
DrawLinearRepeatingGradient(CGContextRef cg, const LinearGradientPattern &aPattern, const CGRect &aExtents)
static CGGradientRef
CreateRepeatingGradient(CGContextRef cg, GradientStopsCG* aStops,
int aRepeatStartFactor, int aRepeatEndFactor,
bool aReflect)
{
GradientStopsCG *stops = static_cast<GradientStopsCG*>(aPattern.mStops.get());
CGPoint startPoint = { aPattern.mBegin.x, aPattern.mBegin.y };
CGPoint endPoint = { aPattern.mEnd.x, aPattern.mEnd.y };
int repeatCount = 1;
// if we don't have a line then we can't extend it
if (aPattern.mEnd.x != aPattern.mBegin.x ||
aPattern.mEnd.y != aPattern.mBegin.y) {
CalculateRepeatingGradientParams(&startPoint, &endPoint, aExtents,
&repeatCount);
}
int repeatCount = aRepeatEndFactor - aRepeatStartFactor;
uint32_t stopCount = aStops->mStops.size();
double scale = 1./repeatCount;
std::vector<CGFloat> colors;
std::vector<CGFloat> offsets;
colors.reserve(stops->mStops.size()*repeatCount*4);
offsets.reserve(stops->mStops.size()*repeatCount);
colors.reserve(stopCount*repeatCount*4);
offsets.reserve(stopCount*repeatCount);
for (int j = 0; j < repeatCount; j++) {
for (uint32_t i = 0; i < stops->mStops.size(); i++) {
colors.push_back(stops->mStops[i].color.r);
colors.push_back(stops->mStops[i].color.g);
colors.push_back(stops->mStops[i].color.b);
colors.push_back(stops->mStops[i].color.a);
for (int j = aRepeatStartFactor; j < aRepeatEndFactor; j++) {
bool isReflected = aReflect && (j % 2) != 0;
for (uint32_t i = 0; i < stopCount; i++) {
uint32_t stopIndex = isReflected ? stopCount - i - 1 : i;
colors.push_back(aStops->mStops[stopIndex].color.r);
colors.push_back(aStops->mStops[stopIndex].color.g);
colors.push_back(aStops->mStops[stopIndex].color.b);
colors.push_back(aStops->mStops[stopIndex].color.a);
offsets.push_back((stops->mStops[i].offset + j)*scale);
CGFloat offset = aStops->mStops[stopIndex].offset;
if (isReflected) {
offset = 1 - offset;
}
offsets.push_back((offset + (j - aRepeatStartFactor)) * scale);
}
}
@ -546,8 +546,28 @@ DrawLinearRepeatingGradient(CGContextRef cg, const LinearGradientPattern &aPatte
CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace,
&colors.front(),
&offsets.front(),
repeatCount*stops->mStops.size());
repeatCount*stopCount);
CGColorSpaceRelease(colorSpace);
return gradient;
}
static void
DrawLinearRepeatingGradient(CGContextRef cg, const LinearGradientPattern &aPattern,
const CGRect &aExtents, bool aReflect)
{
GradientStopsCG *stops = static_cast<GradientStopsCG*>(aPattern.mStops.get());
CGPoint startPoint = { aPattern.mBegin.x, aPattern.mBegin.y };
CGPoint endPoint = { aPattern.mEnd.x, aPattern.mEnd.y };
int repeatStartFactor = 0, repeatEndFactor = 1;
// if we don't have a line then we can't extend it
if (aPattern.mEnd.x != aPattern.mBegin.x ||
aPattern.mEnd.y != aPattern.mBegin.y) {
CalculateRepeatingGradientParams(&startPoint, &endPoint, aExtents,
&repeatStartFactor, &repeatEndFactor);
}
CGGradientRef gradient = CreateRepeatingGradient(cg, stops, repeatStartFactor, repeatEndFactor, aReflect);
CGContextDrawLinearGradient(cg, gradient, startPoint, endPoint,
kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation);
@ -570,7 +590,8 @@ CGPointDistance(CGPoint a, CGPoint b)
}
static void
DrawRadialRepeatingGradient(CGContextRef cg, const RadialGradientPattern &aPattern, const CGRect &aExtents)
DrawRadialRepeatingGradient(CGContextRef cg, const RadialGradientPattern &aPattern,
const CGRect &aExtents, bool aReflect)
{
GradientStopsCG *stops = static_cast<GradientStopsCG*>(aPattern.mStops.get());
CGPoint startCenter = { aPattern.mCenter1.x, aPattern.mCenter1.y };
@ -586,40 +607,18 @@ DrawRadialRepeatingGradient(CGContextRef cg, const RadialGradientPattern &aPatte
minimumEndRadius = max(minimumEndRadius, CGPointDistance(endCenter, CGRectBottomRight(aExtents)));
CGFloat length = endRadius - startRadius;
int repeatCount = 1;
int repeatStartFactor = 0, repeatEndFactor = 1;
while (endRadius < minimumEndRadius) {
endRadius += length;
repeatCount++;
repeatEndFactor++;
}
while (startRadius-length >= 0) {
startRadius -= length;
repeatCount++;
repeatStartFactor--;
}
double scale = 1./repeatCount;
std::vector<CGFloat> colors;
std::vector<CGFloat> offsets;
colors.reserve(stops->mStops.size()*repeatCount*4);
offsets.reserve(stops->mStops.size()*repeatCount);
for (int j = 0; j < repeatCount; j++) {
for (uint32_t i = 0; i < stops->mStops.size(); i++) {
colors.push_back(stops->mStops[i].color.r);
colors.push_back(stops->mStops[i].color.g);
colors.push_back(stops->mStops[i].color.b);
colors.push_back(stops->mStops[i].color.a);
offsets.push_back((stops->mStops[i].offset + j)*scale);
}
}
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace,
&colors.front(),
&offsets.front(),
repeatCount*stops->mStops.size());
CGColorSpaceRelease(colorSpace);
CGGradientRef gradient = CreateRepeatingGradient(cg, stops, repeatStartFactor, repeatEndFactor, aReflect);
//XXX: are there degenerate radial gradients that we should avoid drawing?
CGContextDrawRadialGradient(cg, gradient, startCenter, startRadius, endCenter, endRadius,
@ -650,8 +649,8 @@ DrawGradient(CGContextRef cg, const Pattern &aPattern, const CGRect &aExtents)
CGContextDrawLinearGradient(cg, stops->mGradient, startPoint, endPoint,
kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation);
} else if (stops->mExtend == ExtendMode::REPEAT) {
DrawLinearRepeatingGradient(cg, pat, aExtents);
} else if (stops->mExtend == ExtendMode::REPEAT || stops->mExtend == ExtendMode::REFLECT) {
DrawLinearRepeatingGradient(cg, pat, aExtents, stops->mExtend == ExtendMode::REFLECT);
}
} else if (aPattern.GetType() == PatternType::RADIAL_GRADIENT) {
const RadialGradientPattern& pat = static_cast<const RadialGradientPattern&>(aPattern);
@ -668,8 +667,8 @@ DrawGradient(CGContextRef cg, const Pattern &aPattern, const CGRect &aExtents)
//XXX: are there degenerate radial gradients that we should avoid drawing?
CGContextDrawRadialGradient(cg, stops->mGradient, startCenter, startRadius, endCenter, endRadius,
kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation);
} else if (stops->mExtend == ExtendMode::REPEAT) {
DrawRadialRepeatingGradient(cg, pat, aExtents);
} else if (stops->mExtend == ExtendMode::REPEAT || stops->mExtend == ExtendMode::REFLECT) {
DrawRadialRepeatingGradient(cg, pat, aExtents, stops->mExtend == ExtendMode::REFLECT);
}
} else {
assert(0);

View File

@ -12,19 +12,32 @@
#include "BasePoint3D.h"
#include "BasePoint4D.h"
#include "BaseSize.h"
#include "mozilla/TypeTraits.h"
#include <cmath>
namespace mozilla {
template <typename> struct IsPixel;
namespace gfx {
// This should only be used by the typedefs below.
struct UnknownUnits {};
} // close namespace 'gfx' because IsPixel specialization must be in 'mozilla'
template<> struct IsPixel<gfx::UnknownUnits> : TrueType {};
namespace gfx {
template<class units>
struct IntPointTyped :
public BasePoint< int32_t, IntPointTyped<units> >,
public units {
static_assert(IsPixel<units>::value,
"'units' must be a coordinate system tag");
typedef BasePoint< int32_t, IntPointTyped<units> > Super;
MOZ_CONSTEXPR IntPointTyped() : Super() {}
@ -47,6 +60,9 @@ template<class units>
struct PointTyped :
public BasePoint< Float, PointTyped<units> >,
public units {
static_assert(IsPixel<units>::value,
"'units' must be a coordinate system tag");
typedef BasePoint< Float, PointTyped<units> > Super;
MOZ_CONSTEXPR PointTyped() : Super() {}
@ -75,6 +91,9 @@ IntPointTyped<units> RoundedToInt(const PointTyped<units>& aPoint) {
template<class units>
struct Point3DTyped :
public BasePoint3D< Float, Point3DTyped<units> > {
static_assert(IsPixel<units>::value,
"'units' must be a coordinate system tag");
typedef BasePoint3D< Float, Point3DTyped<units> > Super;
Point3DTyped() : Super() {}
@ -96,6 +115,9 @@ typedef Point3DTyped<UnknownUnits> Point3D;
template<class units>
struct Point4DTyped :
public BasePoint4D< Float, Point4DTyped<units> > {
static_assert(IsPixel<units>::value,
"'units' must be a coordinate system tag");
typedef BasePoint4D< Float, Point4DTyped<units> > Super;
Point4DTyped() : Super() {}
@ -118,6 +140,9 @@ template<class units>
struct IntSizeTyped :
public BaseSize< int32_t, IntSizeTyped<units> >,
public units {
static_assert(IsPixel<units>::value,
"'units' must be a coordinate system tag");
typedef BaseSize< int32_t, IntSizeTyped<units> > Super;
MOZ_CONSTEXPR IntSizeTyped() : Super() {}
@ -140,6 +165,9 @@ template<class units>
struct SizeTyped :
public BaseSize< Float, SizeTyped<units> >,
public units {
static_assert(IsPixel<units>::value,
"'units' must be a coordinate system tag");
typedef BaseSize< Float, SizeTyped<units> > Super;
MOZ_CONSTEXPR SizeTyped() : Super() {}

View File

@ -14,12 +14,18 @@
#include <cmath>
namespace mozilla {
template <typename> struct IsPixel;
namespace gfx {
template<class units>
struct IntMarginTyped:
public BaseMargin<int32_t, IntMarginTyped<units> >,
public units {
static_assert(IsPixel<units>::value,
"'units' must be a coordinate system tag");
typedef BaseMargin<int32_t, IntMarginTyped<units> > Super;
IntMarginTyped() : Super() {}
@ -32,6 +38,9 @@ template<class units>
struct MarginTyped:
public BaseMargin<Float, MarginTyped<units> >,
public units {
static_assert(IsPixel<units>::value,
"'units' must be a coordinate system tag");
typedef BaseMargin<Float, MarginTyped<units> > Super;
MarginTyped() : Super() {}
@ -56,6 +65,9 @@ template<class units>
struct IntRectTyped :
public BaseRect<int32_t, IntRectTyped<units>, IntPointTyped<units>, IntSizeTyped<units>, IntMarginTyped<units> >,
public units {
static_assert(IsPixel<units>::value,
"'units' must be a coordinate system tag");
typedef BaseRect<int32_t, IntRectTyped<units>, IntPointTyped<units>, IntSizeTyped<units>, IntMarginTyped<units> > Super;
IntRectTyped() : Super() {}
@ -86,6 +98,9 @@ template<class units>
struct RectTyped :
public BaseRect<Float, RectTyped<units>, PointTyped<units>, SizeTyped<units>, MarginTyped<units> >,
public units {
static_assert(IsPixel<units>::value,
"'units' must be a coordinate system tag");
typedef BaseRect<Float, RectTyped<units>, PointTyped<units>, SizeTyped<units>, MarginTyped<units> > Super;
RectTyped() : Super() {}

View File

@ -32,6 +32,8 @@ namespace mozilla {
// to get a picture of how the various coordinate systems relate to each other.
struct ParentLayerPixel {};
template<> struct IsPixel<ParentLayerPixel> : TrueType {};
typedef gfx::PointTyped<ParentLayerPixel> ParentLayerPoint;
typedef gfx::RectTyped<ParentLayerPixel> ParentLayerRect;
typedef gfx::SizeTyped<ParentLayerPixel> ParentLayerSize;

View File

@ -151,9 +151,7 @@ struct LayerPropertiesBase : public LayerProperties
{
aGeometryChanged = true;
result = OldTransformedBounds();
if (transformChanged) {
AddRegion(result, NewTransformedBounds());
}
AddRegion(result, NewTransformedBounds());
// If we don't have to generate invalidations separately for child
// layers then we can just stop here since we've already invalidated the entire

View File

@ -84,6 +84,7 @@ WalkTheTree(Layer* aLayer,
ref->ConnectReferentLayer(referent);
} else {
ref->DetachReferentLayer(referent);
WalkTheTree<OP>(referent, aReady, aTargetConfig);
}
}
}

View File

@ -10,7 +10,10 @@
#include "mozilla/gfx/Blur.h"
#include "mozilla/gfx/2D.h"
#include "nsExpirationTracker.h"
#include "nsClassHashtable.h"
using namespace mozilla;
using namespace mozilla::gfx;
gfxAlphaBoxBlur::gfxAlphaBoxBlur()
@ -87,52 +90,71 @@ gfxAlphaBoxBlur::Init(const gfxRect& aRect,
return mContext;
}
void
DrawBlur(gfxContext* aDestinationCtx,
SourceSurface* aBlur,
const IntPoint& aTopLeft,
const Rect* aDirtyRect)
{
DrawTarget *dest = aDestinationCtx->GetDrawTarget();
nsRefPtr<gfxPattern> thebesPat = aDestinationCtx->GetPattern();
Pattern* pat = thebesPat->GetPattern(dest, nullptr);
Matrix oldTransform = dest->GetTransform();
Matrix newTransform = oldTransform;
newTransform.Translate(aTopLeft.x, aTopLeft.y);
// Avoid a semi-expensive clip operation if we can, otherwise
// clip to the dirty rect
if (aDirtyRect) {
dest->PushClipRect(*aDirtyRect);
}
dest->SetTransform(newTransform);
dest->MaskSurface(*pat, aBlur, Point(0, 0));
dest->SetTransform(oldTransform);
if (aDirtyRect) {
dest->PopClip();
}
}
TemporaryRef<SourceSurface>
gfxAlphaBoxBlur::DoBlur(DrawTarget* aDT, IntPoint* aTopLeft)
{
mBlur->Blur(mData);
*aTopLeft = mBlur->GetRect().TopLeft();
return aDT->CreateSourceSurfaceFromData(mData,
mBlur->GetSize(),
mBlur->GetStride(),
SurfaceFormat::A8);
}
void
gfxAlphaBoxBlur::Paint(gfxContext* aDestinationCtx)
{
if (!mContext)
return;
mBlur->Blur(mData);
mozilla::gfx::Rect* dirtyRect = mBlur->GetDirtyRect();
DrawTarget *dest = aDestinationCtx->GetDrawTarget();
if (!dest) {
NS_WARNING("Blurring not supported for Thebes contexts!");
return;
}
mozilla::RefPtr<SourceSurface> mask
= dest->CreateSourceSurfaceFromData(mData,
mBlur->GetSize(),
mBlur->GetStride(),
SurfaceFormat::A8);
Rect* dirtyRect = mBlur->GetDirtyRect();
IntPoint topLeft;
RefPtr<SourceSurface> mask = DoBlur(dest, &topLeft);
if (!mask) {
NS_ERROR("Failed to create mask!");
return;
}
nsRefPtr<gfxPattern> thebesPat = aDestinationCtx->GetPattern();
Pattern* pat = thebesPat->GetPattern(dest, nullptr);
Matrix oldTransform = dest->GetTransform();
Matrix newTransform = oldTransform;
newTransform.Translate(mBlur->GetRect().x, mBlur->GetRect().y);
// Avoid a semi-expensive clip operation if we can, otherwise
// clip to the dirty rect
if (dirtyRect) {
dest->PushClipRect(*dirtyRect);
}
dest->SetTransform(newTransform);
dest->MaskSurface(*pat, mask, Point(0, 0));
dest->SetTransform(oldTransform);
if (dirtyRect) {
dest->PopClip();
}
DrawBlur(aDestinationCtx, mask, topLeft, dirtyRect);
}
gfxIntSize gfxAlphaBoxBlur::CalculateBlurRadius(const gfxPoint& aStd)
@ -142,6 +164,204 @@ gfxIntSize gfxAlphaBoxBlur::CalculateBlurRadius(const gfxPoint& aStd)
return gfxIntSize(size.width, size.height);
}
struct BlurCacheKey : public PLDHashEntryHdr {
typedef const BlurCacheKey& KeyType;
typedef const BlurCacheKey* KeyTypePointer;
enum { ALLOW_MEMMOVE = true };
gfxRect mRect;
gfxIntSize mBlurRadius;
gfxRect mSkipRect;
BackendType mBackend;
BlurCacheKey(const gfxRect& aRect, const gfxIntSize &aBlurRadius, const gfxRect& aSkipRect, BackendType aBackend)
: mRect(aRect)
, mBlurRadius(aBlurRadius)
, mSkipRect(aSkipRect)
, mBackend(aBackend)
{ }
BlurCacheKey(const BlurCacheKey* aOther)
: mRect(aOther->mRect)
, mBlurRadius(aOther->mBlurRadius)
, mSkipRect(aOther->mSkipRect)
, mBackend(aOther->mBackend)
{ }
static PLDHashNumber
HashKey(const KeyTypePointer aKey)
{
PLDHashNumber hash = HashBytes(&aKey->mRect.x, 4 * sizeof(gfxFloat));
hash = AddToHash(hash, aKey->mBlurRadius.width, aKey->mBlurRadius.height);
hash = AddToHash(hash, HashBytes(&aKey->mSkipRect.x, 4 * sizeof(gfxFloat)));
hash = AddToHash(hash, (uint32_t)aKey->mBackend);
return hash;
}
bool KeyEquals(KeyTypePointer aKey) const
{
if (aKey->mRect.IsEqualInterior(mRect) &&
aKey->mBlurRadius == mBlurRadius &&
aKey->mSkipRect.IsEqualInterior(mSkipRect) &&
aKey->mBackend == mBackend) {
return true;
}
return false;
}
static KeyTypePointer KeyToPointer(KeyType aKey)
{
return &aKey;
}
};
/**
* This class is what is cached. It need to be allocated in an object separated
* to the cache entry to be able to be tracked by the nsExpirationTracker.
* */
struct BlurCacheData {
BlurCacheData(SourceSurface* aBlur, const IntPoint& aTopLeft, const gfxRect& aDirtyRect, const BlurCacheKey& aKey)
: mBlur(aBlur)
, mTopLeft(aTopLeft)
, mDirtyRect(aDirtyRect)
, mKey(aKey)
{}
BlurCacheData(const BlurCacheData& aOther)
: mBlur(aOther.mBlur)
, mTopLeft(aOther.mTopLeft)
, mDirtyRect(aOther.mDirtyRect)
, mKey(aOther.mKey)
{ }
nsExpirationState *GetExpirationState() {
return &mExpirationState;
}
nsExpirationState mExpirationState;
RefPtr<SourceSurface> mBlur;
IntPoint mTopLeft;
gfxRect mDirtyRect;
BlurCacheKey mKey;
};
/**
* This class implements a cache with no maximum size, that retains the
* SourceSurfaces used to draw the blurs.
*
* An entry stays in the cache as long as it is used often.
*/
class BlurCache MOZ_FINAL : public nsExpirationTracker<BlurCacheData,4>
{
public:
BlurCache()
: nsExpirationTracker<BlurCacheData, 4>(GENERATION_MS)
{
}
virtual void NotifyExpired(BlurCacheData* aObject)
{
RemoveObject(aObject);
mHashEntries.Remove(aObject->mKey);
}
BlurCacheData* Lookup(const gfxRect& aRect,
const gfxIntSize& aBlurRadius,
const gfxRect& aSkipRect,
BackendType aBackendType,
const gfxRect* aDirtyRect)
{
BlurCacheData* blur =
mHashEntries.Get(BlurCacheKey(aRect, aBlurRadius, aSkipRect, aBackendType));
if (blur) {
if (aDirtyRect && !blur->mDirtyRect.Contains(*aDirtyRect)) {
return nullptr;
}
MarkUsed(blur);
}
return blur;
}
// Returns true if we successfully register the blur in the cache, false
// otherwise.
bool RegisterEntry(BlurCacheData* aValue)
{
nsresult rv = AddObject(aValue);
if (NS_FAILED(rv)) {
// We are OOM, and we cannot track this object. We don't want stall
// entries in the hash table (since the expiration tracker is responsible
// for removing the cache entries), so we avoid putting that entry in the
// table, which is a good things considering we are short on memory
// anyway, we probably don't want to retain things.
return false;
}
mHashEntries.Put(aValue->mKey, aValue);
return true;
}
protected:
static const uint32_t GENERATION_MS = 1000;
/**
* FIXME use nsTHashtable to avoid duplicating the BlurCacheKey.
* https://bugzilla.mozilla.org/show_bug.cgi?id=761393#c47
*/
nsClassHashtable<BlurCacheKey, BlurCacheData> mHashEntries;
};
static BlurCache* gBlurCache = nullptr;
SourceSurface*
GetCachedBlur(DrawTarget *aDT,
const gfxRect& aRect,
const gfxIntSize& aBlurRadius,
const gfxRect& aSkipRect,
const gfxRect& aDirtyRect,
IntPoint* aTopLeft)
{
if (!gBlurCache) {
gBlurCache = new BlurCache();
}
BlurCacheData* cached = gBlurCache->Lookup(aRect, aBlurRadius, aSkipRect, aDT->GetType(), &aDirtyRect);
if (cached) {
*aTopLeft = cached->mTopLeft;
return cached->mBlur;
}
return nullptr;
}
void
CacheBlur(DrawTarget *aDT,
const gfxRect& aRect,
const gfxIntSize& aBlurRadius,
const gfxRect& aSkipRect,
SourceSurface* aBlur,
const IntPoint& aTopLeft,
const gfxRect& aDirtyRect)
{
// If we already had a cached value with this key, but an incorrect dirty region then just update
// the existing entry
if (BlurCacheData* cached = gBlurCache->Lookup(aRect, aBlurRadius, aSkipRect, aDT->GetType(), nullptr)) {
cached->mBlur = aBlur;
cached->mTopLeft = aTopLeft;
cached->mDirtyRect = aDirtyRect;
return;
}
BlurCacheKey key(aRect, aBlurRadius, aSkipRect, aDT->GetType());
BlurCacheData* data = new BlurCacheData(aBlur, aTopLeft, aDirtyRect, key);
if (!gBlurCache->RegisterEntry(data)) {
delete data;
}
}
void
gfxAlphaBoxBlur::ShutdownBlurCache()
{
delete gBlurCache;
gBlurCache = nullptr;
}
/* static */ void
gfxAlphaBoxBlur::BlurRectangle(gfxContext *aDestinationCtx,
const gfxRect& aRect,
@ -152,26 +372,41 @@ gfxAlphaBoxBlur::BlurRectangle(gfxContext *aDestinationCtx,
const gfxRect& aSkipRect)
{
gfxIntSize blurRadius = CalculateBlurRadius(aBlurStdDev);
// Create the temporary surface for blurring
gfxAlphaBoxBlur blur;
gfxContext *dest = blur.Init(aRect, gfxIntSize(), blurRadius, &aDirtyRect, &aSkipRect);
if (!dest) {
DrawTarget *dt = aDestinationCtx->GetDrawTarget();
if (!dt) {
NS_WARNING("Blurring not supported for Thebes contexts!");
return;
}
gfxRect shadowGfxRect = aRect;
shadowGfxRect.Round();
IntPoint topLeft;
RefPtr<SourceSurface> surface = GetCachedBlur(dt, aRect, blurRadius, aSkipRect, aDirtyRect, &topLeft);
if (!surface) {
// Create the temporary surface for blurring
gfxAlphaBoxBlur blur;
gfxContext *dest = blur.Init(aRect, gfxIntSize(), blurRadius, &aDirtyRect, &aSkipRect);
dest->NewPath();
if (aCornerRadii) {
dest->RoundedRectangle(shadowGfxRect, *aCornerRadii);
} else {
dest->Rectangle(shadowGfxRect);
if (!dest) {
return;
}
gfxRect shadowGfxRect = aRect;
shadowGfxRect.Round();
dest->NewPath();
if (aCornerRadii) {
dest->RoundedRectangle(shadowGfxRect, *aCornerRadii);
} else {
dest->Rectangle(shadowGfxRect);
}
dest->Fill();
surface = blur.DoBlur(dt, &topLeft);
CacheBlur(dt, aRect, blurRadius, aSkipRect, surface, topLeft, aDirtyRect);
}
dest->Fill();
aDestinationCtx->SetColor(aShadowColor);
blur.Paint(aDestinationCtx);
Rect dirtyRect(aDirtyRect.x, aDirtyRect.y, aDirtyRect.width, aDirtyRect.height);
DrawBlur(aDestinationCtx, surface, topLeft, &dirtyRect);
}

View File

@ -86,6 +86,8 @@ public:
return mContext;
}
mozilla::TemporaryRef<mozilla::gfx::SourceSurface> DoBlur(mozilla::gfx::DrawTarget* aDT, mozilla::gfx::IntPoint* aTopLeft);
/**
* Does the actual blurring/spreading and mask applying. Users of this
* object must have drawn whatever they want to be blurred onto the internal
@ -129,6 +131,8 @@ public:
const gfxRect& aDirtyRect,
const gfxRect& aSkipRect);
static void ShutdownBlurCache();
protected:

View File

@ -452,6 +452,7 @@ gfxPlatform::Shutdown()
gfxFontCache::Shutdown();
gfxFontGroup::Shutdown();
gfxGradientCache::Shutdown();
gfxAlphaBoxBlur::ShutdownBlurCache();
gfxGraphiteShaper::Shutdown();
#if defined(XP_MACOSX) || defined(XP_WIN) // temporary, until this is implemented on others
gfxPlatformFontList::Shutdown();

View File

@ -14,6 +14,7 @@
#include "gfxTypes.h"
#include "gfxFontFamilyList.h"
#include "gfxBlur.h"
#include "nsRect.h"
#include "qcms.h"

View File

@ -4240,7 +4240,7 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
case.addstmts([
StmtDecl(Decl(Type('Transport', ptr=1), tvar.name)),
StmtDecl(Decl(Type(_actorName(actor.ptype.name(), self.side),
StmtDecl(Decl(Type(_actorName(actor.ptype.name(), actor.side),
ptr=1), pvar.name)),
iffailopen,
iffailalloc,

View File

@ -21,3 +21,5 @@ EXTRA_JS_MODULES += [
]
FINAL_LIBRARY = 'xul'
FAIL_ON_WARNINGS = True

View File

@ -6,6 +6,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
include protocol PContent;
include protocol PContentBridge;
include DOMTypes;
include JavaScriptTypes;
@ -16,7 +17,7 @@ namespace jsipc {
intr protocol PJavaScript
{
manager PContent;
manager PContent or PContentBridge;
both:
// Sent when a CPOW has been finalized and table entries can be freed up.

View File

@ -1681,7 +1681,7 @@ jsdContext::SetOptions(uint32_t options)
/* don't let users change this option, they'd just be shooting themselves
* in the foot. */
if (JS::ContextOptionsRef(mJSCx).privateIsNSISupports() !=
(options & JSOPTION_PRIVATE_IS_NSISUPPORTS))
!!(options & JSOPTION_PRIVATE_IS_NSISUPPORTS))
return NS_ERROR_ILLEGAL_VALUE;
JS::ContextOptionsRef(mJSCx).setExtraWarnings(options & JSOPTION_EXTRA_WARNINGS)

View File

@ -35,3 +35,5 @@ if CONFIG['JS_THREADSAFE']:
DEFINES['JS_THREADSAFE'] = True
FINAL_LIBRARY = 'xul'
FAIL_ON_WARNINGS = True

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