merge mozilla-central to autoland. r=merge

This commit is contained in:
Sebastian Hengst 2017-06-18 00:21:41 +02:00
commit efd723cdad
76 changed files with 21983 additions and 21758 deletions

View File

@ -1074,6 +1074,16 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
kGenericAccType,
kNoReqStates
},
{ // term
&nsGkAtoms::term,
roles::TERM,
kUseMapRole,
eNoValue,
eNoAction,
eNoLiveAttr,
kGenericAccType,
states::READONLY
},
{ // textbox
&nsGkAtoms::textbox,
roles::ENTRY,

View File

@ -306,8 +306,8 @@ ROLE(OUTLINE,
ROLE(OUTLINEITEM,
"outlineitem",
ATK_ROLE_LIST_ITEM,
NSAccessibilityRowRole, //XXX: use OutlineRow as subrole.
ATK_ROLE_TREE_ITEM,
NSAccessibilityRowRole,
ROLE_SYSTEM_OUTLINEITEM,
ROLE_SYSTEM_OUTLINEITEM,
eNameFromSubtreeRule)
@ -1034,7 +1034,7 @@ ROLE(DEFINITION_LIST,
ROLE(TERM,
"term",
ATK_ROLE_LIST_ITEM,
ATK_ROLE_DESCRIPTION_TERM,
NSAccessibilityGroupRole,
ROLE_SYSTEM_LISTITEM,
ROLE_SYSTEM_LISTITEM,

View File

@ -901,6 +901,9 @@ ConvertToNSArray(nsTArray<ProxyAccessible*>& aArray)
case roles::NOTE:
return @"AXDocumentNote";
case roles::OUTLINEITEM:
return @"AXOutlineRow";
// macOS added an AXSubrole value to distinguish generic AXGroup objects
// from those which are AXGroups as a result of an explicit ARIA role,
// such as the non-landmark, non-listitem text containers in DPub ARIA.

View File

@ -66,6 +66,7 @@
testRole("aria_tab", ROLE_PAGETAB);
testRole("aria_tablist", ROLE_PAGETABLIST);
testRole("aria_tabpanel", ROLE_PROPERTYPAGE);
testRole("aria_term", ROLE_TERM);
testRole("aria_textbox", ROLE_ENTRY);
testRole("aria_timer", ROLE_TEXT); // weak role
testRole("aria_toolbar", ROLE_TOOLBAR);
@ -243,6 +244,7 @@
<span id="aria_tab" role="tab"/>
<span id="aria_tablist" role="tablist"/>
<span id="aria_tabpanel" role="tabpanel"/>
<span id="aria_term" role="term"/>
<span id="aria_textbox" role="textbox"/>
<span id="aria_timer" role="timer"/>
<span id="aria_toolbar" role="toolbar"/>

View File

@ -56,7 +56,7 @@ tags = blocklist
skip-if = toolkit == "gtk2" || toolkit == "gtk3" # fails intermittently on Linux (bug 909342)
tags = blocklist
[browser_CTP_crashreporting.js]
skip-if = !crashreporter || (os == 'linux' && debug)
skip-if = !crashreporter
tags = blocklist
[browser_CTP_data_urls.js]
tags = blocklist

View File

@ -133,10 +133,11 @@ add_task(async function() {
getUI("submitButton").click();
// And wait for the parent to say that the crash report was submitted
// successfully.
// successfully. This can take time on debug builds.
await ContentTaskUtils.waitForCondition(() => {
return statusDiv.getAttribute("status") == "success";
}, "Timed out waiting for plugin binding to be in success state");
}, "Timed out waiting for plugin binding to be in success state",
100, 200);
});
let [subject, ] = await crashReportPromise;

View File

@ -167,6 +167,9 @@ this.PanelMultiView = class {
get _mainView() {
return this._mainViewId ? this.document.getElementById(this._mainViewId) : null;
}
get showingSubViewAsMainView() {
return this.node.getAttribute("mainViewIsSubView") == "true";
}
get _transitioning() {
return this.__transitioning;
@ -457,7 +460,6 @@ this.PanelMultiView = class {
};
// Make sure that new panels always have a title set.
let cancel = false;
if (this.panelViews && aAnchor) {
if (aAnchor && !viewNode.hasAttribute("title"))
viewNode.setAttribute("title", aAnchor.getAttribute("label"));
@ -466,17 +468,17 @@ this.PanelMultiView = class {
if (custWidget) {
if (custWidget.onInit)
custWidget.onInit(aAnchor);
custWidget.onViewShowing({ target: viewNode, preventDefault: () => cancel = true, detail });
custWidget.onViewShowing({ target: aAnchor, detail });
}
}
viewNode.setAttribute("current", true);
if (this.panelViews && this._mainViewWidth)
viewNode.style.maxWidth = viewNode.style.minWidth = this._mainViewWidth + "px";
let evt = new window.CustomEvent("ViewShowing", { bubbles: true, cancelable: true, detail });
viewNode.dispatchEvent(evt);
if (!cancel)
cancel = evt.defaultPrevented;
let cancel = evt.defaultPrevented;
if (detail.blockers.size) {
try {
let results = await Promise.all(detail.blockers);
@ -492,7 +494,6 @@ this.PanelMultiView = class {
}
this._currentSubView = viewNode;
viewNode.setAttribute("current", true);
if (this.panelViews) {
this.node.setAttribute("viewtype", "subview");
if (!playTransition)
@ -624,8 +625,8 @@ this.PanelMultiView = class {
this._viewContainer.removeAttribute("transition-reverse");
viewNode.dispatchEvent(new window.CustomEvent("ViewShown",
{ bubbles: true, cancelable: false }));
evt = new window.CustomEvent("ViewShown", { bubbles: true, cancelable: false });
viewNode.dispatchEvent(evt);
}, { once: true });
});
}, { once: true });
@ -637,8 +638,6 @@ this.PanelMultiView = class {
// Now that the subview is visible, we can check the height of the
// description elements it contains.
this.descriptionHeightWorkaround(viewNode);
viewNode.dispatchEvent(new window.CustomEvent("ViewShown",
{ bubbles: true, cancelable: false }));
});
this._shiftMainView(aAnchor);
}

View File

@ -515,14 +515,12 @@ const PanelUI = {
multiView.setAttribute("nosubviews", "true");
multiView.setAttribute("viewCacheId", "appMenu-viewCache");
if (gPhotonStructure) {
tempPanel.setAttribute("photon", true);
multiView.setAttribute("mainViewId", viewNode.id);
multiView.appendChild(viewNode);
}
tempPanel.appendChild(multiView);
if (!gPhotonStructure) {
multiView.setMainView(viewNode);
}
multiView.setAttribute("mainViewIsSubView", "true");
multiView.setMainView(viewNode);
viewNode.classList.add("cui-widget-panelview");
let viewShown = false;

View File

@ -14,10 +14,8 @@ add_task(async function() {
let historyButton = document.getElementById("history-panelmenu");
ok(historyButton, "History button appears in Panel Menu");
let historyPanel = document.getElementById("PanelUI-history");
let promise = BrowserTestUtils.waitForEvent(historyPanel, "ViewShown");
historyButton.click();
await promise;
let historyPanel = document.getElementById("PanelUI-history");
ok(historyPanel.getAttribute("current"), "History Panel is in view");
let panelHiddenPromise = promisePanelHidden(window);

View File

@ -130,7 +130,6 @@ this.browserAction = class extends ExtensionAPI {
let view = document.createElementNS(XUL_NS, "panelview");
view.id = this.viewId;
view.setAttribute("flex", "1");
view.setAttribute("extension", true);
document.getElementById("PanelUI-multiView").appendChild(view);
document.addEventListener("popupshowing", this);
@ -172,10 +171,6 @@ this.browserAction = class extends ExtensionAPI {
// Google Chrome onClicked extension API.
if (popupURL) {
try {
// FIXME: The line below needs to change eventually, but for now:
// ensure the view is _always_ visible _before_ `popup.attach()` is
// called. PanelMultiView.jsm dictates different behavior.
event.target.setAttribute("current", true);
let popup = this.getPopup(document.defaultView, popupURL);
event.detail.addBlocker(popup.attach(event.target));
} catch (e) {

View File

@ -3,8 +3,6 @@
"use strict";
add_task(async function testPopupBorderRadius() {
await SpecialPowers.pushPrefEnv({set: [["browser.photon.structure.enabled", false]]});
let extension = ExtensionTestUtils.loadExtension({
background() {
browser.tabs.query({active: true, currentWindow: true}, tabs => {

View File

@ -9,7 +9,6 @@ const {classes: Cc, interfaces: Ci, utils: Cu, manager: Cm} = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://services-common/utils.js");
Cu.import("resource://gre/modules/Preferences.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Services",
"resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "RecentWindow",
@ -318,7 +317,7 @@ var PocketOverlay = {
for (let window of CustomizableUI.windows) {
for (let id of ["panelMenu_pocket", "menu_pocket", "BMB_pocket",
"panelMenu_pocketSeparator", "menu_pocketSeparator",
"BMB_pocketSeparator"]) {
"BMB_pocketSeparator", "appMenu-library-pocket-button"]) {
let element = window.document.getElementById(id);
if (element)
element.remove();
@ -412,6 +411,19 @@ var PocketOverlay = {
sib.parentNode.insertBefore(sep, sib);
sib.parentNode.insertBefore(menu, sib);
}
// Add to library panel
sib = document.getElementById("appMenu-library-history-button");
if (sib && !document.getElementById("appMenu-library-pocket-button")) {
let menu = createElementWithAttrs(document, "toolbarbutton", {
"id": "appMenu-library-pocket-button",
"label": gPocketBundle.GetStringFromName("pocketMenuitem.label"),
"class": "subviewbutton subviewbutton-iconic",
"oncommand": "openUILink(Pocket.listURL, event);",
"hidden": hidden
});
sib.parentNode.insertBefore(menu, sib);
}
},
onWidgetAfterDOMChange(aWidgetNode) {
if (aWidgetNode.id != "pocket-button") {
@ -419,11 +431,20 @@ var PocketOverlay = {
}
let doc = aWidgetNode.ownerDocument;
let hidden = !CustomizableUI.getPlacementOfWidget("pocket-button");
for (let prefix of ["panelMenu_", "menu_", "BMB_"]) {
let element = doc.getElementById(prefix + "pocket");
let elementIds = [
"panelMenu_pocket",
"menu_pocket",
"BMB_pocket",
"appMenu-library-pocket-button",
];
for (let elementId of elementIds) {
let element = doc.getElementById(elementId);
if (element) {
element.hidden = hidden;
doc.getElementById(prefix + "pocketSeparator").hidden = hidden;
let sep = doc.getElementById(elementId + "Separator");
if (sep) {
sep.hidden = hidden;
}
}
}
// enable or disable reader button

View File

@ -0,0 +1,7 @@
<!-- 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/. -->
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<path fill="context-fill" d="M4 7a4 4 0 0 1-4-4V1a1 1 0 0 1 1-1h6a1 1 0 0 1 1 1v2a4 4 0 0 1-4 4zm1.993-5.016a.5.5 0 0 0-.362.159L3.989 3.785 2.378 2.168A.492.492 0 0 0 2 1.984a.5.5 0 0 0-.357.85l-.008.006 1.647 1.653.353.354a.5.5 0 0 0 .707 0l.358-.354L6.35 2.84a.5.5 0 0 0-.357-.856z"/>
<path fill="context-fill" d="M13 1h-3a1 1 0 0 0 0 2h3a1 1 0 0 1 1 1v8a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V8a1 1 0 0 0-2 0v4a3 3 0 0 0 3 3h10a3 3 0 0 0 3-3V4a3 3 0 0 0-3-3z"/>
</svg>

After

Width:  |  Height:  |  Size: 764 B

View File

@ -51,6 +51,10 @@ toolbar[brighttext] #pocket-button {
}
}
#appMenu-library-pocket-button {
list-style-image: url("chrome://pocket-shared/skin/pocket-list.svg");
}
#panelMenu_pocket,
#menu_pocket,
#BMB_pocket {

View File

@ -261,8 +261,7 @@ photonpanelmultiview .panel-subview-header {
}
#appMenu-popup > .panel-arrowcontainer > .panel-arrowcontent,
#PanelUI-popup > .panel-arrowcontainer > .panel-arrowcontent,
panel[photon] > .panel-arrowcontainer > .panel-arrowcontent {
#PanelUI-popup > .panel-arrowcontainer > .panel-arrowcontent {
overflow: hidden;
}
@ -339,8 +338,7 @@ panelview:not([mainview]) .toolbarbutton-text,
/* START photonpanelview adjustments */
#appMenu-popup > .panel-arrowcontainer > .panel-arrowcontent,
panel[photon] > .panel-arrowcontainer > .panel-arrowcontent {
#appMenu-popup > .panel-arrowcontainer > .panel-arrowcontent {
padding: 0;
border-radius: 0;
}
@ -350,8 +348,7 @@ photonpanelmultiview panelview {
padding: 6px 0;
}
#appMenu-popup panelview,
#customizationui-widget-multiview panelview:not([extension]) {
#appMenu-popup panelview {
min-width: @menuPanelWidth@;
}
@ -2079,14 +2076,4 @@ photonpanelmultiview .PanelUI-subView toolbarseparator {
margin-inline-end: 0;
}
photonpanelmultiview#customizationui-widget-multiview > .panel-viewcontainer {
overflow: hidden;
}
/* This is explicitly overriding the overflow properties set above. */
photonpanelmultiview .cui-widget-panelview {
overflow-x: visible;
overflow-y: visible;
}
/* END photon adjustments */

View File

@ -150,12 +150,11 @@ DOMIntersectionObserver::GetThresholds(nsTArray<double>& aRetVal)
void
DOMIntersectionObserver::Observe(Element& aTarget)
{
if (mObservationTargets.Contains(&aTarget)) {
return;
if (mObservationTargets.EnsureInserted(&aTarget)) {
// A new entry was created.
aTarget.RegisterIntersectionObserver(this);
Connect();
}
aTarget.RegisterIntersectionObserver(this);
mObservationTargets.PutEntry(&aTarget);
Connect();
}
void
@ -173,14 +172,11 @@ DOMIntersectionObserver::Unobserve(Element& aTarget)
void
DOMIntersectionObserver::UnlinkTarget(Element& aTarget)
{
if (!mObservationTargets.Contains(&aTarget)) {
return;
}
mObservationTargets.RemoveEntry(&aTarget);
if (mObservationTargets.Count() == 0) {
Disconnect();
}
if (mObservationTargets.EnsureRemoved(&aTarget) &&
mObservationTargets.Count() == 0) {
// We removed the last entry.
Disconnect();
}
}
void

View File

@ -1309,6 +1309,7 @@ GK_ATOM(td, "td")
GK_ATOM(_template, "template")
GK_ATOM(text_decoration, "text-decoration")
GK_ATOM(terminate, "terminate")
GK_ATOM(term, "term")
GK_ATOM(test, "test")
GK_ATOM(text, "text")
GK_ATOM(textAlign, "text-align")

View File

@ -195,7 +195,7 @@ static bool sNeedsFullCC = false;
static bool sNeedsFullGC = false;
static bool sNeedsGCAfterCC = false;
static bool sIncrementalCC = false;
static int32_t sActiveIntersliceGCBudget = 0; // ms;
static int32_t sActiveIntersliceGCBudget = 5; // ms;
static nsScriptNameSpaceManager *gNameSpaceManager;
static PRTime sFirstCollectionTime;

View File

@ -324,9 +324,8 @@ nsWindowRoot::GetEnabledDisabledCommandsForControllers(nsIControllers* aControll
// Use a hash to determine which commands have already been handled by
// earlier controllers, as the earlier controller's result should get
// priority.
if (!aCommandsHandled.Contains(commands[e])) {
aCommandsHandled.PutEntry(commands[e]);
if (aCommandsHandled.EnsureInserted(commands[e])) {
// We inserted a new entry into aCommandsHandled.
bool enabled = false;
controller->IsCommandEnabled(commands[e], &enabled);

View File

@ -4988,7 +4988,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
}
${typeName}::EntryType* entry;
if (idsSeen.Contains(propName)) {
if (!idsSeen.EnsureInserted(propName)) {
// Find the existing entry.
auto idx = recordEntries.IndexOf(propName);
MOZ_ASSERT(idx != recordEntries.NoIndex,
@ -5004,7 +5004,6 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
// Safe to do an infallible append here, because we did a
// SetCapacity above to the right capacity.
entry = recordEntries.AppendElement();
idsSeen.PutEntry(propName);
}
entry->mKey = propName;
${valueType}& slot = entry->mValue;

View File

@ -0,0 +1,9 @@
<!DOCTYPE html>
<html>
<script>
var c = document.createElementNS('http://www.w3.org/1999/xhtml', 'canvas');
var cx = c.getContext('2d');
cx.setTransform(1, 2, 2, 4, 0.41577222277777554, 0.89);
cx.fillText("AA",2048,4);
</script>
</html>

View File

@ -38,6 +38,7 @@ load 1290628-1.html
load 1283113-1.html
load 1286458-1.html
load 1299062-1.html
load 1305085-1.html
load 1305312-1.html
load 1298576-1.html
load 1334366-1.html

View File

@ -9,6 +9,7 @@
#include "base/compiler_specific.h"
#include "mozilla/ArrayUtils.h"
#include "nsGkAtoms.h"
#include "nsITableCellLayout.h" // for MAX_COLSPAN / MAX_ROWSPAN
#include "nsCRT.h"
#include "nsLayoutStylesheetCache.h"
#include "nsRuleData.h"
@ -146,8 +147,10 @@ nsMathMLElement::ParseAttribute(int32_t aNamespaceID,
const nsAString& aValue,
nsAttrValue& aResult)
{
MOZ_ASSERT(IsMathMLElement());
if (aNamespaceID == kNameSpaceID_None) {
if (IsMathMLElement(nsGkAtoms::math) && aAttribute == nsGkAtoms::mode) {
if (mNodeInfo->Equals(nsGkAtoms::math) && aAttribute == nsGkAtoms::mode) {
WarnDeprecated(nsGkAtoms::mode->GetUTF16String(),
nsGkAtoms::display->GetUTF16String(), OwnerDoc());
}
@ -161,6 +164,16 @@ nsMathMLElement::ParseAttribute(int32_t aNamespaceID,
aAttribute == nsGkAtoms::mathbackground_) {
return aResult.ParseColor(aValue);
}
if (mNodeInfo->Equals(nsGkAtoms::mtd_)) {
if (aAttribute == nsGkAtoms::columnspan_) {
aResult.ParseClampedNonNegativeInt(aValue, 1, 1, MAX_COLSPAN);
return true;
}
if (aAttribute == nsGkAtoms::rowspan) {
aResult.ParseClampedNonNegativeInt(aValue, 1, 0, MAX_ROWSPAN);
return true;
}
}
}
return nsMathMLElementBase::ParseAttribute(aNamespaceID, aAttribute,
@ -205,6 +218,8 @@ static Element::MappedAttributeEntry sDirStyles[] = {
bool
nsMathMLElement::IsAttributeMapped(const nsIAtom* aAttribute) const
{
MOZ_ASSERT(IsMathMLElement());
static const MappedAttributeEntry* const mtableMap[] = {
sMtableStyles,
sCommonPresStyles
@ -236,10 +251,10 @@ nsMathMLElement::IsAttributeMapped(const nsIAtom* aAttribute) const
if (IsAnyOfMathMLElements(nsGkAtoms::mstyle_, nsGkAtoms::math))
return FindAttributeDependence(aAttribute, mstyleMap);
if (IsMathMLElement(nsGkAtoms::mtable_))
if (mNodeInfo->Equals(nsGkAtoms::mtable_))
return FindAttributeDependence(aAttribute, mtableMap);
if (IsMathMLElement(nsGkAtoms::mrow_))
if (mNodeInfo->Equals(nsGkAtoms::mrow_))
return FindAttributeDependence(aAttribute, mrowMap);
if (IsAnyOfMathMLElements(nsGkAtoms::maction_,

View File

@ -23,6 +23,8 @@ fivee sixx<br>
<script class="testbody" type="application/javascript">
let {onSpellCheck} = SpecialPowers.Cu.import("resource://testing-common/AsyncSpellCheckTestHelper.jsm", {});
/** Test for Bug 1100966 **/
SimpleTest.waitForExplicitFinish();
SimpleTest.waitForFocus(function() {
@ -37,12 +39,14 @@ SimpleTest.waitForFocus(function() {
setTimeout(function() {
synthesizeKey("VK_BACK_SPACE", {});
var sel = getSpellCheckSelection();
is(sel.rangeCount, 2, "We should have two misspelled words");
is(String(sel.getRangeAt(0)), "fivee", "Correct misspelled word");
is(String(sel.getRangeAt(1)), "sixx", "Correct misspelled word");
onSpellCheck(div, function() {
var sel = getSpellCheckSelection();
is(sel.rangeCount, 2, "We should have two misspelled words");
is(String(sel.getRangeAt(0)), "fivee", "Correct misspelled word");
is(String(sel.getRangeAt(1)), "sixx", "Correct misspelled word");
SimpleTest.finish();
SimpleTest.finish();
});
},0);
},0);
});

View File

@ -22,6 +22,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1154791
<script class="testbody" type="application/javascript">
let {onSpellCheck} = SpecialPowers.Cu.import("resource://testing-common/AsyncSpellCheckTestHelper.jsm", {});
/** Test for Bug 1154791 **/
SimpleTest.waitForExplicitFinish();
SimpleTest.waitForFocus(function() {
@ -37,14 +39,14 @@ SimpleTest.waitForFocus(function() {
setTimeout(function() {
synthesizeKey(" ", {});
setTimeout(function() {
onSpellCheck(div, function() {
var sel = getSpellCheckSelection();
is(sel.rangeCount, 2, "We should have two misspelled words");
is(String(sel.getRangeAt(0)), "thiss", "Correct misspelled word");
is(String(sel.getRangeAt(1)), "onee", "Correct misspelled word");
SimpleTest.finish();
},0);
});
},0);
},0);
});

View File

@ -21,6 +21,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=432225
/** Test for Bug 432225 **/
let {onSpellCheck} = SpecialPowers.Cu.import("resource://testing-common/AsyncSpellCheckTestHelper.jsm", {});
SimpleTest.waitForExplicitFinish();
addLoadEvent(runTest);
@ -60,7 +62,9 @@ function addWords(aLimit) {
getEdit().focus();
sendString('aa OK ');
gMisspeltWords.push("aa");
setTimeout(function() { addWords(aLimit-1); }, 0);
onSpellCheck(editDoc(), function() {
addWords(aLimit-1);
});
}
</script>
</pre>

View File

@ -490,7 +490,8 @@ public:
nsresult Post()
{
return NS_DispatchToMainThread(this);
nsCOMPtr<nsIRunnable> runnable(this);
return NS_IdleDispatchToCurrentThread(runnable.forget(), 1000);
}
NS_IMETHOD Run() override

View File

@ -760,12 +760,24 @@ bool SkScalerContextRec::computeMatrices(PreMatrixScale preMatrixScale, SkVector
// At this point, given GA, create s.
switch (preMatrixScale) {
case kFull_PreMatrixScale:
s->fX = SkScalarAbs(GA.get(SkMatrix::kMScaleX));
s->fY = SkScalarAbs(GA.get(SkMatrix::kMScaleY));
case kFull_PreMatrixScale: {
SkScalar xScale = SkScalarAbs(GA.get(SkMatrix::kMScaleX));
SkScalar yScale = SkScalarAbs(GA.get(SkMatrix::kMScaleY));
if (xScale <= SK_ScalarNearlyZero) {
xScale = SK_Scalar1;
}
if (yScale <= SK_ScalarNearlyZero) {
yScale = SK_Scalar1;
}
s->fX = xScale;
s->fY = yScale;
break;
}
case kVertical_PreMatrixScale: {
SkScalar yScale = SkScalarAbs(GA.get(SkMatrix::kMScaleY));
if (yScale <= SK_ScalarNearlyZero) {
yScale = SK_Scalar1;
}
s->fX = yScale;
s->fY = yScale;
break;

View File

@ -591,6 +591,10 @@ GetBlur(gfxContext* aDestinationCtx,
return nullptr;
}
if (RefPtr<SourceSurface> opt = destDT->OptimizeSourceSurface(boxShadow)) {
boxShadow = opt;
}
if (!useDestRect) {
CacheBlur(destDT, minSize, aBlurRadius, aCornerRadii, aShadowColor,
aOutBlurMargin, boxShadow);
@ -1133,6 +1137,10 @@ gfxAlphaBoxBlur::GetInsetBlur(const Rect& aOuterRect,
return nullptr;
}
if (RefPtr<SourceSurface> opt = aDestDrawTarget->OptimizeSourceSurface(minInsetBlur)) {
minInsetBlur = opt;
}
if (!aIsDestRect) {
CacheInsetBlur(outerSize, whitespaceSize,
aBlurRadius, aInnerClipRadii,

View File

@ -3428,7 +3428,8 @@ ICCall_Native::Compiler::generateStubCode(MacroAssembler& masm)
// Load the callee in R1.
if (isSpread_) {
masm.loadValue(Address(masm.getStackPointer(), ICStackValueOffset + 2 * sizeof(Value)), R1);
unsigned skipToCallee = (2 + isConstructing_) * sizeof(Value);
masm.loadValue(Address(masm.getStackPointer(), skipToCallee + ICStackValueOffset), R1);
} else {
unsigned nonArgsSlots = (1 + isConstructing_) * sizeof(Value);
BaseValueIndex calleeSlot(masm.getStackPointer(), argcReg, ICStackValueOffset + nonArgsSlots);

View File

@ -575,6 +575,12 @@ JS_NewDeadWrapper(JSContext* cx, JSObject* origObj)
return NewDeadProxyObject(cx, origObj);
}
JS_FRIEND_API(bool)
JS_IsScriptSourceObject(JSObject* obj)
{
return obj->is<ScriptSourceObject>();
}
void
js::TraceWeakMaps(WeakMapTracer* trc)
{

View File

@ -106,6 +106,12 @@ JS_IsDeadWrapper(JSObject* obj);
extern JS_FRIEND_API(JSObject*)
JS_NewDeadWrapper(JSContext* cx, JSObject* origObject = nullptr);
/**
* Determine whether the given object is a ScriptSourceObject.
*/
extern JS_FRIEND_API(bool)
JS_IsScriptSourceObject(JSObject* obj);
/*
* Used by the cycle collector to trace through a shape or object group and
* all cycle-participating data it reaches, using bounded stack space.
@ -1383,6 +1389,10 @@ class MOZ_STACK_CLASS JS_FRIEND_API(AutoStableStringChars)
bool isLatin1() const { return state_ == Latin1; }
bool isTwoByte() const { return state_ == TwoByte; }
const JS::Latin1Char* latin1Chars() const {
MOZ_ASSERT(state_ == Latin1);
return latin1Chars_;
}
const char16_t* twoByteChars() const {
MOZ_ASSERT(state_ == TwoByte);
return twoByteChars_;

View File

@ -2906,6 +2906,67 @@ CharSplitHelper(JSContext* cx, HandleLinearString str, uint32_t limit, HandleObj
return NewCopiedArrayTryUseGroup(cx, group, splits.begin(), splits.length());
}
template <typename TextChar>
static MOZ_ALWAYS_INLINE JSObject*
SplitSingleCharHelper(JSContext* cx, HandleLinearString str, const TextChar* text,
uint32_t textLen, char16_t patCh, HandleObjectGroup group)
{
// Count the number of occurrences of patCh within text.
uint32_t count = 0;
for (size_t index = 0; index < textLen; index++) {
if (static_cast<char16_t>(text[index]) == patCh)
count++;
}
// Handle zero-occurrence case - return input string in an array.
if (count == 0) {
RootedValue strValue(cx, StringValue(str.get()));
return NewCopiedArrayTryUseGroup(cx, group, &strValue.get(), 1);
}
// Reserve memory for substring values.
AutoValueVector splits(cx);
if (!splits.reserve(count + 1))
return nullptr;
// Add substrings.
size_t lastEndIndex = 0;
for (size_t index = 0; index < textLen; index++) {
if (static_cast<char16_t>(text[index]) == patCh) {
size_t subLength = size_t(index - lastEndIndex);
JSString* sub = NewDependentString(cx, str, lastEndIndex, subLength);
if (!sub || !splits.append(StringValue(sub)))
return nullptr;
lastEndIndex = index + 1;
}
}
// Add substring for tail of string (after last match).
JSString* sub = NewDependentString(cx, str, lastEndIndex, textLen - lastEndIndex);
if (!sub || !splits.append(StringValue(sub)))
return nullptr;
return NewCopiedArrayTryUseGroup(cx, group, splits.begin(), splits.length());
}
// ES 2016 draft Mar 25, 2016 21.1.3.17 steps 4, 8, 12-18.
static JSObject*
SplitSingleCharHelper(JSContext* cx, HandleLinearString str, char16_t ch, HandleObjectGroup group) {
// Step 12.
size_t strLength = str->length();
AutoStableStringChars linearChars(cx);
if (!linearChars.init(cx, str))
return nullptr;
if (linearChars.isLatin1()) {
return SplitSingleCharHelper(cx, str, linearChars.latin1Chars(), strLength, ch, group);
} else {
return SplitSingleCharHelper(cx, str, linearChars.twoByteChars(), strLength, ch, group);
}
}
// ES 2016 draft Mar 25, 2016 21.1.3.17 steps 4, 8, 12-18.
JSObject*
js::str_split_string(JSContext* cx, HandleObjectGroup group, HandleString str, HandleString sep, uint32_t limit)
@ -2922,6 +2983,11 @@ js::str_split_string(JSContext* cx, HandleObjectGroup group, HandleString str, H
if (linearSep->length() == 0)
return CharSplitHelper(cx, linearStr, limit, group);
if (linearSep->length() == 1 && limit >= static_cast<uint32_t>(INT32_MAX)) {
char16_t ch = linearSep->latin1OrTwoByteChar(0);
return SplitSingleCharHelper(cx, linearStr, ch, group);
}
return SplitHelper(cx, linearStr, limit, linearSep, group);
}

View File

@ -219,6 +219,26 @@ EvalScript(JSContext* cx,
nsCString uriStr;
if (preloadCache && NS_SUCCEEDED(uri->GetSpec(uriStr))) {
// Note that, when called during startup, this will keep the
// original JSScript object alive for an indefinite amount of time.
// This has the side-effect of keeping the global that the script
// was compiled for alive, too.
//
// For most startups, the global in question will be the
// CompilationScope, since we pre-compile any scripts that were
// needed during the last startup in that scope. But for startups
// when a non-cached script is used (e.g., after add-on
// installation), this may be a Sandbox global, which may be
// nuked but held alive by the JSScript.
//
// In general, this isn't a problem, since add-on Sandboxes which
// use the script preloader are not destroyed until add-on shutdown,
// and when add-ons are uninstalled or upgraded, the preloader cache
// is immediately flushed after shutdown. But it's possible to
// disable and reenable an add-on without uninstalling it, leading
// to cached scripts being held alive, and tied to nuked Sandbox
// globals. Given the unusual circumstances required to trigger
// this, it's not a major concern. But it should be kept in mind.
ScriptPreloader::GetSingleton().NoteScript(uriStr, cachePath, script);
}

View File

@ -139,12 +139,8 @@ public:
nsresult Dispatch()
{
nsCOMPtr<nsIThread> thread = do_GetCurrentThread();
if (!thread) {
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIRunnable> self(this);
return thread->IdleDispatch(self.forget());
return NS_IdleDispatchToCurrentThread(self.forget(), 1000);
}
void Start(bool aContinuation = false, bool aPurge = false)

View File

@ -0,0 +1,20 @@
"use strict";
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
Cu.import("resource://gre/modules/Services.jsm");
add_task(function* test_executeScriptAfterNuked() {
let scriptUrl = Services.io.newFileURI(do_get_file("file_simple_script.js")).spec;
// Load the script for the first time into a sandbox, and then nuke
// that sandbox.
let sandbox = Cu.Sandbox(Services.scriptSecurityManager.getSystemPrincipal());
Services.scriptloader.loadSubScript(scriptUrl, sandbox);
Cu.nukeSandbox(sandbox);
// Load the script again into a new sandbox, and make sure it
// succeeds.
sandbox = Cu.Sandbox(Services.scriptSecurityManager.getSystemPrincipal());
Services.scriptloader.loadSubScript(scriptUrl, sandbox);
});

View File

@ -99,6 +99,7 @@ skip-if = toolkit == "android" # bug 1347431
[test_nuke_sandbox.js]
[test_nuke_sandbox_event_listeners.js]
[test_nuke_webextension_wrappers.js]
[test_subScriptLoader.js]
[test_rewrap_dead_wrapper.js]
[test_sandbox_metadata.js]
[test_exportFunction.js]

View File

@ -191,10 +191,14 @@ WrapperFactory::PrepareForWrapping(JSContext* cx, HandleObject scope,
// If we've somehow gotten to this point after either the source or target
// compartment has been nuked, return a DeadObjectProxy to prevent further
// access.
// However, we always need to provide live wrappers for ScriptSourceObjects,
// since they're used for cross-compartment cloned scripts, and need to
// remain accessible even after the original compartment has been nuked.
JSCompartment* origin = js::GetObjectCompartment(obj);
JSCompartment* target = js::GetObjectCompartment(scope);
if (CompartmentPrivate::Get(origin)->wasNuked ||
CompartmentPrivate::Get(target)->wasNuked) {
if (!JS_IsScriptSourceObject(obj) &&
(CompartmentPrivate::Get(origin)->wasNuked ||
CompartmentPrivate::Get(target)->wasNuked)) {
NS_WARNING("Trying to create a wrapper into or out of a nuked compartment");
retObj.set(JS_NewDeadWrapper(cx));
@ -352,7 +356,8 @@ static void
DEBUG_CheckUnwrapSafety(HandleObject obj, const js::Wrapper* handler,
JSCompartment* origin, JSCompartment* target)
{
if (CompartmentPrivate::Get(origin)->wasNuked || CompartmentPrivate::Get(target)->wasNuked) {
if (!JS_IsScriptSourceObject(obj) &&
(CompartmentPrivate::Get(origin)->wasNuked || CompartmentPrivate::Get(target)->wasNuked)) {
// If either compartment has already been nuked, we should have returned
// a dead wrapper from our prewrap callback, and this function should
// not be called.

View File

@ -5768,10 +5768,8 @@ PresShell::MarkFramesInListApproximatelyVisible(const nsDisplayList& aList,
// Use the presshell containing the frame.
auto* presShell = static_cast<PresShell*>(frame->PresContext()->PresShell());
uint32_t count = presShell->mApproximatelyVisibleFrames.Count();
MOZ_ASSERT(!presShell->AssumeAllFramesVisible());
presShell->mApproximatelyVisibleFrames.PutEntry(frame);
if (presShell->mApproximatelyVisibleFrames.Count() > count) {
if (presShell->mApproximatelyVisibleFrames.EnsureInserted(frame)) {
// The frame was added to mApproximatelyVisibleFrames, so increment its visible count.
frame->IncApproximateVisibleCount();
}
@ -5909,9 +5907,7 @@ PresShell::MarkFramesInSubtreeApproximatelyVisible(nsIFrame* aFrame,
aFrame->StyleVisibility()->IsVisible() &&
(!aRemoveOnly || aFrame->GetVisibility() == Visibility::APPROXIMATELY_VISIBLE)) {
MOZ_ASSERT(!AssumeAllFramesVisible());
uint32_t count = mApproximatelyVisibleFrames.Count();
mApproximatelyVisibleFrames.PutEntry(aFrame);
if (mApproximatelyVisibleFrames.Count() > count) {
if (mApproximatelyVisibleFrames.EnsureInserted(aFrame)) {
// The frame was added to mApproximatelyVisibleFrames, so increment its visible count.
aFrame->IncApproximateVisibleCount();
}
@ -6233,9 +6229,8 @@ PresShell::EnsureFrameInApproximatelyVisibleList(nsIFrame* aFrame)
}
#endif
if (!mApproximatelyVisibleFrames.Contains(aFrame)) {
MOZ_ASSERT(!AssumeAllFramesVisible());
mApproximatelyVisibleFrames.PutEntry(aFrame);
if (mApproximatelyVisibleFrames.EnsureInserted(aFrame)) {
// We inserted a new entry.
aFrame->IncApproximateVisibleCount();
}
}
@ -6258,11 +6253,8 @@ PresShell::RemoveFrameFromApproximatelyVisibleList(nsIFrame* aFrame)
return;
}
uint32_t count = mApproximatelyVisibleFrames.Count();
mApproximatelyVisibleFrames.RemoveEntry(aFrame);
if (aFrame->TrackingVisibility() &&
mApproximatelyVisibleFrames.Count() < count) {
if (mApproximatelyVisibleFrames.EnsureRemoved(aFrame) &&
aFrame->TrackingVisibility()) {
// aFrame was in the hashtable, and we're still tracking its visibility,
// so we need to decrement its visible count.
aFrame->DecApproximateVisibleCount();

View File

@ -239,10 +239,6 @@ public:
{
MOZ_ASSERT(NS_IsMainThread());
if (LastTickSkippedAnyPaints()) {
return TimeStamp::Now();
}
TimeStamp mostRecentRefresh = MostRecentRefresh();
TimeDuration refreshRate = GetTimerRate();
TimeStamp idleEnd = mostRecentRefresh + refreshRate;

View File

@ -1161,47 +1161,6 @@ nsMathMLmtdFrame::Init(nsIContent* aContent,
RemoveStateBits(NS_FRAME_FONT_INFLATION_FLOW_ROOT);
}
int32_t
nsMathMLmtdFrame::GetRowSpan()
{
int32_t rowspan = 1;
// Don't look at the content's rowspan if we're not an mtd or a pseudo cell.
if (mContent->IsMathMLElement(nsGkAtoms::mtd_) &&
!StyleContext()->GetPseudo()) {
nsAutoString value;
mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::rowspan, value);
if (!value.IsEmpty()) {
nsresult error;
rowspan = value.ToInteger(&error);
if (NS_FAILED(error) || rowspan < 0)
rowspan = 1;
rowspan = std::min(rowspan, MAX_ROWSPAN);
}
}
return rowspan;
}
int32_t
nsMathMLmtdFrame::GetColSpan()
{
int32_t colspan = 1;
// Don't look at the content's colspan if we're not an mtd or a pseudo cell.
if (mContent->IsMathMLElement(nsGkAtoms::mtd_) &&
!StyleContext()->GetPseudo()) {
nsAutoString value;
mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::columnspan_, value);
if (!value.IsEmpty()) {
nsresult error;
colspan = value.ToInteger(&error);
if (NS_FAILED(error) || colspan <= 0 || colspan > MAX_COLSPAN)
colspan = 1;
}
}
return colspan;
}
nsresult
nsMathMLmtdFrame::AttributeChanged(int32_t aNameSpaceID,
nsIAtom* aAttribute,

View File

@ -266,8 +266,6 @@ public:
nsDisplayListBuilder* aBuilder,
const nsDisplayListSet& aLists) override;
virtual int32_t GetRowSpan() override;
virtual int32_t GetColSpan() override;
virtual bool IsFrameOfType(uint32_t aFlags) const override
{
return nsTableCellFrame::IsFrameOfType(aFlags & ~(nsIFrame::eMathML));

View File

@ -2312,14 +2312,17 @@ ContainerState::AttemptToRecyclePaintedLayer(AnimatedGeometryRoot* aAnimatedGeom
const nsPoint& aTopLeft)
{
Layer* oldLayer = mLayerBuilder->GetOldLayerFor(aItem);
if (!oldLayer || !oldLayer->AsPaintedLayer() ||
!mPaintedLayersAvailableForRecycling.Contains(oldLayer->AsPaintedLayer())) {
if (!oldLayer || !oldLayer->AsPaintedLayer()) {
return nullptr;
}
// Try to recycle a layer
if (!mPaintedLayersAvailableForRecycling.EnsureRemoved(oldLayer->AsPaintedLayer())) {
// Not found.
return nullptr;
}
// Try to recycle the layer.
RefPtr<PaintedLayer> layer = oldLayer->AsPaintedLayer();
mPaintedLayersAvailableForRecycling.RemoveEntry(layer);
// Check if the layer hint has changed and whether or not the layer should
// be recreated because of it.
@ -4548,8 +4551,6 @@ FrameLayerBuilder::ComputeGeometryChangeForItem(DisplayItemData* aData)
return;
}
PaintedLayerItemsEntry* entry = mPaintedLayerItems.GetEntry(paintedLayer);
nsAutoPtr<nsDisplayItemGeometry> geometry;
PaintedDisplayItemLayerUserData* layerData =
@ -4611,6 +4612,7 @@ FrameLayerBuilder::ComputeGeometryChangeForItem(DisplayItemData* aData)
changedFrameInvalidations.IsEmpty() == 0) {
notifyRenderingChanged = false;
}
PaintedLayerItemsEntry* entry = mPaintedLayerItems.GetEntry(paintedLayer);
aData->mClip.AddOffsetAndComputeDifference(entry->mCommonClipCount,
shift, aData->mGeometry->ComputeInvalidationRegion(),
clip, entry->mLastCommonClipCount,

View File

@ -725,16 +725,16 @@ FontFaceSet::UpdateRules(const nsTArray<nsFontFaceRuleContainer>& aRules)
// font entries if possible rather than creating new ones; set modified to
// true if we detect that rule ordering has changed, or if a new entry is
// created.
if (handledRules.Contains(aRules[i].mRule)) {
nsCSSFontFaceRule* rule = aRules[i].mRule;
if (!handledRules.EnsureInserted(rule)) {
// rule was already present in the hashtable
continue;
}
nsCSSFontFaceRule* rule = aRules[i].mRule;
RefPtr<FontFace> f = ruleFaceMap.Get(rule);
if (!f.get()) {
f = FontFace::CreateForRule(GetParentObject(), this, rule);
}
InsertRuleFontFace(f, aRules[i].mSheetType, oldRecords, modified);
handledRules.PutEntry(aRules[i].mRule);
}
for (size_t i = 0, i_end = mNonRuleFaces.Length(); i < i_end; ++i) {

View File

@ -6,6 +6,7 @@
#define CellData_h__
#include "nsISupports.h"
#include "nsITableCellLayout.h" // for MAX_COLSPAN / MAX_ROWSPAN
#include "nsCoord.h"
#include "mozilla/gfx/Types.h"
#include "mozilla/WritingModes.h"
@ -16,10 +17,6 @@ class nsCellMap;
class BCCellData;
#define MAX_ROWSPAN 65534 // the cellmap can not handle more.
#define MAX_COLSPAN 1000 // limit as IE and opera do. If this ever changes,
// change COL_SPAN_OFFSET/COL_SPAN_SHIFT accordingly.
/**
* Data stored by nsCellMap to rationalize rowspan and colspan cells.
*/

View File

@ -7,6 +7,10 @@
#include "nsQueryFrame.h"
#define MAX_ROWSPAN 65534 // the cellmap can not handle more.
#define MAX_COLSPAN 1000 // limit as IE and opera do. If this ever changes,
// change COL_SPAN_OFFSET/COL_SPAN_SHIFT accordingly.
/**
* nsITableCellLayout
* interface for layout objects that act like table cells.

View File

@ -709,16 +709,18 @@ nsTableCellFrame::GetCellBaseline() const
borderPadding;
}
int32_t nsTableCellFrame::GetRowSpan()
int32_t
nsTableCellFrame::GetRowSpan()
{
int32_t rowSpan=1;
nsGenericHTMLElement *hc = nsGenericHTMLElement::FromContent(mContent);
// Don't look at the content's rowspan if we're a pseudo cell
if (hc && !StyleContext()->GetPseudo()) {
const nsAttrValue* attr = hc->GetParsedAttr(nsGkAtoms::rowspan);
if (!StyleContext()->GetPseudo()) {
dom::Element* elem = mContent->AsElement();
const nsAttrValue* attr = elem->GetParsedAttr(nsGkAtoms::rowspan);
// Note that we don't need to check the tag name, because only table cells
// and table headers parse the "rowspan" attribute into an integer.
// (including MathML <mtd>) and table headers parse the "rowspan" attribute
// into an integer.
if (attr && attr->Type() == nsAttrValue::eInteger) {
rowSpan = attr->GetIntegerValue();
}
@ -726,16 +728,20 @@ int32_t nsTableCellFrame::GetRowSpan()
return rowSpan;
}
int32_t nsTableCellFrame::GetColSpan()
int32_t
nsTableCellFrame::GetColSpan()
{
int32_t colSpan=1;
nsGenericHTMLElement *hc = nsGenericHTMLElement::FromContent(mContent);
// Don't look at the content's colspan if we're a pseudo cell
if (hc && !StyleContext()->GetPseudo()) {
const nsAttrValue* attr = hc->GetParsedAttr(nsGkAtoms::colspan);
if (!StyleContext()->GetPseudo()) {
dom::Element* elem = mContent->AsElement();
const nsAttrValue* attr = elem->GetParsedAttr(
MOZ_UNLIKELY(elem->IsMathMLElement()) ? nsGkAtoms::columnspan_
: nsGkAtoms::colspan);
// Note that we don't need to check the tag name, because only table cells
// and table headers parse the "colspan" attribute into an integer.
// (including MathML <mtd>) and table headers parse the "colspan" attribute
// into an integer.
if (attr && attr->Type() == nsAttrValue::eInteger) {
colSpan = attr->GetIntegerValue();
}

View File

@ -150,11 +150,11 @@ public:
/**
* return the cell's specified row span. this is what was specified in the
* content model or in the style info, and is always >= 1.
* content model or in the style info, and is always >= 0.
* to get the effective row span (the actual value that applies), use GetEffectiveRowSpan()
* @see nsTableFrame::GetEffectiveRowSpan()
*/
virtual int32_t GetRowSpan();
int32_t GetRowSpan();
// there is no set row index because row index depends on the cell's parent row only
@ -179,7 +179,7 @@ public:
* to get the effective col span (the actual value that applies), use GetEffectiveColSpan()
* @see nsTableFrame::GetEffectiveColSpan()
*/
virtual int32_t GetColSpan();
int32_t GetColSpan();
/** return the cell's column index (starting at 0 for the first column) */
virtual nsresult GetColIndex(int32_t &aColIndex) const override;

View File

@ -100,7 +100,7 @@ protected:
};
// I420 buffer size macros
#define YSIZE(x,y) ((x)*(y))
#define YSIZE(x,y) (CheckedInt<int>(x)*(y))
#define CRSIZE(x,y) ((((x)+1) >> 1) * (((y)+1) >> 1))
#define I420SIZE(x,y) (YSIZE((x),(y)) + 2 * CRSIZE((x),(y)))
@ -295,20 +295,26 @@ protected:
if (aForceBlack) {
IntSize size = aImage->GetSize();
uint32_t yPlaneLen = YSIZE(size.width, size.height);
uint32_t cbcrPlaneLen = 2 * CRSIZE(size.width, size.height);
uint32_t length = yPlaneLen + cbcrPlaneLen;
CheckedInt<int> yPlaneLen = YSIZE(size.width, size.height);
// doesn't need to be CheckedInt, any overflow will be caught by YSIZE
int cbcrPlaneLen = 2 * CRSIZE(size.width, size.height);
CheckedInt<int> length = yPlaneLen + cbcrPlaneLen;
if (!yPlaneLen.isValid() || !length.isValid()) {
return;
}
// Send a black image.
auto pixelData = MakeUniqueFallible<uint8_t[]>(length);
auto pixelData = MakeUniqueFallible<uint8_t[]>(length.value());
if (pixelData) {
// YCrCb black = 0x10 0x80 0x80
memset(pixelData.get(), 0x10, yPlaneLen);
memset(pixelData.get(), 0x10, yPlaneLen.value());
// Fill Cb/Cr planes
memset(pixelData.get() + yPlaneLen, 0x80, cbcrPlaneLen);
memset(pixelData.get() + yPlaneLen.value(), 0x80, cbcrPlaneLen);
MOZ_MTLOG(ML_DEBUG, "Sending a black video frame");
VideoFrameConverted(Move(pixelData), length, size.width, size.height,
VideoFrameConverted(Move(pixelData), length.value(),
size.width, size.height,
mozilla::kVideoI420, 0);
}
return;
@ -363,11 +369,17 @@ protected:
}
IntSize size = aImage->GetSize();
// these don't need to be CheckedInt, any overflow will be caught by YSIZE
int half_width = (size.width + 1) >> 1;
int half_height = (size.height + 1) >> 1;
int c_size = half_width * half_height;
int buffer_size = YSIZE(size.width, size.height) + 2 * c_size;
auto yuv_scoped = MakeUniqueFallible<uint8[]>(buffer_size);
CheckedInt<int> buffer_size = YSIZE(size.width, size.height) + 2 * c_size;
if (!buffer_size.isValid()) {
return;
}
auto yuv_scoped = MakeUniqueFallible<uint8[]>(buffer_size.value());
if (!yuv_scoped) {
return;
}
@ -382,7 +394,7 @@ protected:
}
int rv;
int cb_offset = YSIZE(size.width, size.height);
int cb_offset = YSIZE(size.width, size.height).value();
int cr_offset = cb_offset + c_size;
switch (surf->GetFormat()) {
case SurfaceFormat::B8G8R8A8:
@ -413,7 +425,7 @@ protected:
}
MOZ_MTLOG(ML_DEBUG, "Sending an I420 video frame converted from " <<
Stringify(surf->GetFormat()));
VideoFrameConverted(Move(yuv_scoped), buffer_size, size.width, size.height, mozilla::kVideoI420, 0);
VideoFrameConverted(Move(yuv_scoped), buffer_size.value(), size.width, size.height, mozilla::kVideoI420, 0);
}
Atomic<int32_t, Relaxed> mLength;

View File

@ -1409,7 +1409,7 @@ public abstract class GeckoApp extends GeckoActivity
"ToggleChrome:Show",
null);
Tabs.getInstance().attachToContext(this, mLayerView);
Tabs.getInstance().attachToContext(this, mLayerView, getAppEventDispatcher());
Tabs.registerOnTabsChangedListener(this);
// Use global layout state change to kick off additional initialization
@ -1503,7 +1503,7 @@ public abstract class GeckoApp extends GeckoActivity
// If we are doing a restore, send the parsed session data to Gecko.
if (!mIsRestoringActivity) {
EventDispatcher.getInstance().dispatch("Session:Restore", restoreMessage);
getAppEventDispatcher().dispatch("Session:Restore", restoreMessage);
}
// Make sure sessionstore.old is either updated or deleted as necessary.
@ -2480,6 +2480,7 @@ public abstract class GeckoApp extends GeckoActivity
super.onDestroy();
Tabs.unregisterOnTabsChangedListener(this);
Tabs.getInstance().detachFromContext();
if (mShutdownOnDestroy) {
GeckoApplication.shutdown(!mRestartOnShutdown ? null : new Intent(

View File

@ -102,6 +102,7 @@ public class Tabs implements BundleEventListener {
private volatile boolean mInitialTabsAdded;
private Context mAppContext;
private EventDispatcher mEventDispatcher;
private LayerView mLayerView;
private ContentObserver mBookmarksContentObserver;
private PersistTabsRunnable mPersistTabsRunnable;
@ -166,18 +167,11 @@ public class Tabs implements BundleEventListener {
mPrivateClearColor = Color.RED;
}
public synchronized void attachToContext(Context context, LayerView layerView) {
public synchronized void attachToContext(Context context, LayerView layerView, EventDispatcher eventDispatcher) {
final Context appContext = context.getApplicationContext();
if (mAppContext == appContext) {
return;
}
if (mAppContext != null) {
// This should never happen.
Log.w(LOGTAG, "The application context has changed!");
}
mAppContext = appContext;
mEventDispatcher = eventDispatcher;
mLayerView = layerView;
mPrivateClearColor = ContextCompat.getColor(context, R.color.tabs_tray_grey_pressed);
mAccountManager = AccountManager.get(appContext);
@ -199,6 +193,10 @@ public class Tabs implements BundleEventListener {
}
}
public void detachFromContext() {
mLayerView = null;
}
/**
* Gets the tab count corresponding to the category and private state of the
* selected tab.
@ -333,6 +331,7 @@ public class Tabs implements BundleEventListener {
// Pass a message to Gecko to update tab state in BrowserApp.
final GeckoBundle data = new GeckoBundle(1);
data.putInt("id", tab.getId());
mEventDispatcher.dispatch("Tab:Selected", data);
EventDispatcher.getInstance().dispatch("Tab:Selected", data);
return tab;
}
@ -474,7 +473,7 @@ public class Tabs implements BundleEventListener {
final GeckoBundle data = new GeckoBundle(2);
data.putInt("tabId", tabId);
data.putBoolean("showUndoToast", showUndoToast);
EventDispatcher.getInstance().dispatch("Tab:Closed", data);
mEventDispatcher.dispatch("Tab:Closed", data);
}
/** Return the tab that will be selected by default after this one is closed */
@ -1088,7 +1087,7 @@ public class Tabs implements BundleEventListener {
}
}
EventDispatcher.getInstance().dispatch("Tab:Load", data);
mEventDispatcher.dispatch("Tab:Load", data);
if (tabToSelect == null) {
return null;
@ -1282,7 +1281,7 @@ public class Tabs implements BundleEventListener {
data.putInt("fromPosition", fromPosition);
data.putInt("toTabId", toTabId);
data.putInt("toPosition", toPosition);
EventDispatcher.getInstance().dispatch("Tab:Move", data);
mEventDispatcher.dispatch("Tab:Move", data);
}
/**

View File

@ -28,6 +28,7 @@ import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import org.mozilla.gecko.GeckoView;
import org.mozilla.gecko.R;
import org.mozilla.gecko.SiteIdentity;
import org.mozilla.gecko.Tab;
@ -106,25 +107,24 @@ public class ActionBarPresenter {
* @param url Url String to display
*/
public void displayUrlOnly(@NonNull final String url) {
updateCustomView(null, null, url);
updateCustomView(null, url, GeckoView.ProgressListener.STATE_IS_INSECURE);
}
/**
* Update appearance of CustomView of ActionBar.
* Update appearance of CustomView of ActionBar
*
* @param tab a Tab instance of current web page to provide information to render ActionBar.
* @param title Title for current website. Could be null if don't want to show title.
* @param url URL for current website. At least Custom will show this url.
* @param securityStatus Security status, possible values given in GeckoView.ProgressListener
*/
public void update(@NonNull final Tab tab) {
final String title = tab.getTitle();
final String url = tab.getBaseDomain();
public void update(final String title, final String url, final int securityStatus) {
// Do not update CustomView immediately. If this method be invoked rapidly several times,
// only apply last one.
mHandler.removeCallbacks(mUpdateAction);
mUpdateAction = new Runnable() {
@Override
public void run() {
updateCustomView(tab.getSiteIdentity(), title, url);
updateCustomView(title, url, securityStatus);
}
};
mHandler.postDelayed(mUpdateAction, CUSTOM_VIEW_UPDATE_DELAY);
@ -218,25 +218,15 @@ public class ActionBarPresenter {
* @param url URL for current website. At least Custom will show this url.
*/
@UiThread
private void updateCustomView(@Nullable SiteIdentity identity,
@Nullable String title,
@NonNull String url) {
// update site-info icon
if (identity == null) {
mIconView.setVisibility(View.INVISIBLE);
} else {
final SecurityModeUtil.IconType type = SecurityModeUtil.resolve(identity);
private void updateCustomView(final String title, final String url, final int securityStatus) {
if (securityStatus == GeckoView.ProgressListener.STATE_IS_SECURE) {
mIconView.setVisibility(View.VISIBLE);
mIconView.setImageLevel(SecurityModeUtil.getImageLevel(type));
mIdentityPopup.setSiteIdentity(identity);
if (type == SecurityModeUtil.IconType.LOCK_SECURE) {
// Lock-Secure is special case. Keep its original green color.
DrawableCompat.setTintList(mIconView.getDrawable(), null);
} else {
// Icon use same color as TextView.
DrawableCompat.setTint(mIconView.getDrawable(), mTextPrimaryColor);
}
mIconView.setImageLevel(SecurityModeUtil.getImageLevel(SecurityModeUtil.IconType.LOCK_SECURE));
// Lock-Secure is special case. Keep its original green color.
DrawableCompat.setTintList(mIconView.getDrawable(), null);
} else {
mIconView.setVisibility(View.INVISIBLE);
DrawableCompat.setTint(mIconView.getDrawable(), mTextPrimaryColor);
}
// If no title to use, use Url as title

View File

@ -20,7 +20,7 @@ import android.support.annotation.NonNull;
import android.support.design.widget.Snackbar;
import android.support.v4.util.SparseArrayCompat;
import android.support.v7.app.ActionBar;
import android.support.v7.view.ActionMode;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.util.Log;
@ -28,17 +28,14 @@ import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.ProgressBar;
import org.mozilla.gecko.EventDispatcher;
import org.mozilla.gecko.GeckoView;
import org.mozilla.gecko.GeckoViewSettings;
import org.mozilla.gecko.R;
import org.mozilla.gecko.SingleTabActivity;
import org.mozilla.gecko.SnackbarBuilder;
import org.mozilla.gecko.Tab;
import org.mozilla.gecko.Tabs;
import org.mozilla.gecko.Telemetry;
import org.mozilla.gecko.TelemetryContract;
import org.mozilla.gecko.gfx.DynamicToolbarAnimator.PinReason;
import org.mozilla.gecko.menu.GeckoMenu;
import org.mozilla.gecko.menu.GeckoMenuInflater;
import org.mozilla.gecko.mozglue.SafeIntent;
@ -46,14 +43,15 @@ import org.mozilla.gecko.util.Clipboard;
import org.mozilla.gecko.util.ColorUtil;
import org.mozilla.gecko.util.GeckoBundle;
import org.mozilla.gecko.util.IntentUtils;
import org.mozilla.gecko.widget.ActionModePresenter;
import org.mozilla.gecko.widget.GeckoPopupMenu;
import java.util.List;
import static org.mozilla.gecko.Tabs.TabEvents;
public class CustomTabsActivity extends SingleTabActivity implements Tabs.OnTabsChangedListener {
public class CustomTabsActivity extends AppCompatActivity
implements GeckoMenu.Callback,
GeckoView.ContentListener,
GeckoView.NavigationListener,
GeckoView.ProgressListener {
private static final String LOGTAG = "CustomTabsActivity";
@ -61,21 +59,30 @@ public class CustomTabsActivity extends SingleTabActivity implements Tabs.OnTabs
private GeckoPopupMenu popupMenu;
private View doorhangerOverlay;
private ActionBarPresenter actionBarPresenter;
private ProgressBar mProgressView;
// A state to indicate whether this activity is finishing with customize animation
private boolean usingCustomAnimation = false;
private MenuItem menuItemControl;
private GeckoView mGeckoView;
private boolean mCanGoBack = false;
private boolean mCanGoForward = false;
private boolean mCanStop = false;
private String mCurrentUrl;
private String mCurrentTitle;
private int mSecurityStatus = GeckoView.ProgressListener.STATE_IS_INSECURE;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.customtabs_activity);
final SafeIntent intent = new SafeIntent(getIntent());
doorhangerOverlay = findViewById(R.id.custom_tabs_doorhanger_overlay);
mProgressView = (ProgressBar) findViewById(R.id.page_progress);
final Toolbar toolbar = (Toolbar) findViewById(R.id.actionbar);
setSupportActionBar(toolbar);
final ActionBar actionBar = getSupportActionBar();
@ -85,26 +92,22 @@ public class CustomTabsActivity extends SingleTabActivity implements Tabs.OnTabs
actionBarPresenter.displayUrlOnly(intent.getDataString());
actionBarPresenter.setBackgroundColor(IntentUtil.getToolbarColor(intent), getWindow());
actionBarPresenter.setTextLongClickListener(new UrlCopyListener());
}
@Override
protected void onTabOpenFromIntent(Tab tab) {
super.onTabOpenFromIntent(tab);
mGeckoView = (GeckoView) findViewById(R.id.gecko_view);
final String host = getReferrerHost();
recordCustomTabUsage(host);
sendTelemetry();
}
mGeckoView.setNavigationListener(this);
mGeckoView.setProgressListener(this);
mGeckoView.setContentListener(this);
@Override
protected void onTabSelectFromIntent(Tab tab) {
super.onTabSelectFromIntent(tab);
final GeckoViewSettings settings = mGeckoView.getSettings();
settings.setBoolean(GeckoViewSettings.USE_MULTIPROCESS, false);
// We already listen for SELECTED events, but if the activity has been destroyed and
// subsequently recreated without a different tab having been selected in Gecko in the
// meantime, our startup won't trigger a SELECTED event because the selected tab in Gecko
// doesn't actually change.
actionBarPresenter.update(tab);
if (intent != null && !TextUtils.isEmpty(intent.getDataString())) {
mGeckoView.loadUri(intent.getDataString());
} else {
Log.w(LOGTAG, "No intend found for custom tab");
finish();
}
}
private void sendTelemetry() {
@ -154,13 +157,6 @@ public class CustomTabsActivity extends SingleTabActivity implements Tabs.OnTabs
}
}
@Override
public void onDone() {
// We're most probably running within a foreign app's task, so we have no choice what to
// call here if we want to allow the user to return to that task's previous activity.
finish();
}
@Override
public void finish() {
super.finish();
@ -176,63 +172,12 @@ public class CustomTabsActivity extends SingleTabActivity implements Tabs.OnTabs
}
@Override
protected int getNewTabFlags() {
return Tabs.LOADURL_CUSTOMTAB | super.getNewTabFlags();
}
@Override
public int getLayout() {
return R.layout.customtabs_activity;
}
@Override
public View getDoorhangerOverlay() {
return doorhangerOverlay;
}
@Override
public void onTabChanged(Tab tab, TabEvents msg, String data) {
super.onTabChanged(tab, msg, data);
if (!Tabs.getInstance().isSelectedTab(tab) ||
tab.getType() != Tab.TabType.CUSTOMTAB) {
return;
public void onBackPressed() {
if (mCanGoBack) {
mGeckoView.goBack();
} else {
finish();
}
if (msg == TabEvents.START
|| msg == TabEvents.STOP
|| msg == TabEvents.ADDED
|| msg == TabEvents.LOAD_ERROR
|| msg == TabEvents.LOADED
|| msg == TabEvents.LOCATION_CHANGE
|| msg == TabEvents.SELECTED) {
updateProgress((tab.getState() == Tab.STATE_LOADING),
tab.getLoadProgress());
}
if (msg == TabEvents.LOCATION_CHANGE
|| msg == TabEvents.SECURITY_CHANGE
|| msg == TabEvents.TITLE
|| msg == TabEvents.SELECTED) {
actionBarPresenter.update(tab);
}
updateMenuItemForward();
}
@Override
public void onResume() {
super.onResume();
mLayerView.getDynamicToolbarAnimator().setPinned(true, PinReason.CUSTOM_TAB);
actionBarPresenter.onResume();
}
@Override
public void onPause() {
super.onPause();
mLayerView.getDynamicToolbarAnimator().setPinned(false, PinReason.CUSTOM_TAB);
actionBarPresenter.onPause();
}
// Usually should use onCreateOptionsMenu() to initialize menu items. But GeckoApp overwrite
@ -240,7 +185,7 @@ public class CustomTabsActivity extends SingleTabActivity implements Tabs.OnTabs
// and this.onPrepareOptionsMenu() are different instances - GeckoApp.onCreatePanelMenu() changed it.
// CustomTabsActivity only use standard menu in ActionBar, so initialize menu here.
@Override
public boolean onCreatePanelMenu(final int id, final Menu menu) {
public boolean onCreateOptionsMenu(final Menu menu) {
// if 3rd-party app asks to add an action button
SafeIntent intent = new SafeIntent(getIntent());
@ -275,6 +220,16 @@ public class CustomTabsActivity extends SingleTabActivity implements Tabs.OnTabs
return true;
}
@Override
public boolean onMenuItemClick(MenuItem item) {
return onOptionsItemSelected(item);
}
@Override
public boolean onMenuItemLongClick(MenuItem item) {
return false;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
@ -317,34 +272,11 @@ public class CustomTabsActivity extends SingleTabActivity implements Tabs.OnTabs
performPendingIntent(intent);
}
@Override
protected ActionModePresenter getTextSelectPresenter() {
return new ActionModePresenter() {
private ActionMode mMode;
@Override
public void startActionMode(ActionMode.Callback callback) {
mMode = startSupportActionMode(callback);
}
@Override
public void endActionMode() {
if (mMode != null) {
mMode.finish();
}
}
};
}
private void bindNavigationCallback(@NonNull final Toolbar toolbar) {
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onDone();
final Tabs tabs = Tabs.getInstance();
final Tab tab = tabs.getSelectedTab();
mSuppressActivitySwitch = true;
tabs.closeTab(tab);
finish();
}
});
}
@ -352,8 +284,7 @@ public class CustomTabsActivity extends SingleTabActivity implements Tabs.OnTabs
private void performPendingIntent(@NonNull PendingIntent pendingIntent) {
// bug 1337771: If intent-creator haven't set data url, call send() directly won't work.
final Intent additional = new Intent();
final Tab tab = Tabs.getInstance().getSelectedTab();
additional.setData(Uri.parse(tab.getURL()));
additional.setData(Uri.parse(mCurrentUrl));
try {
pendingIntent.send(this, 0, additional);
} catch (PendingIntent.CanceledException e) {
@ -435,49 +366,45 @@ public class CustomTabsActivity extends SingleTabActivity implements Tabs.OnTabs
}
final MenuItem forwardMenuItem = popupMenu.getMenu().findItem(R.id.custom_tabs_menu_forward);
final Tab tab = Tabs.getInstance().getSelectedTab();
final boolean enabled = (tab != null && tab.canDoForward());
forwardMenuItem.setEnabled(enabled);
forwardMenuItem.setEnabled(mCanGoForward);
}
/**
* Update loading progress of current page
*
* @param isLoading to indicate whether ProgressBar should be visible or not
* @param progress value of loading progress in percent, should be 0 - 100.
* Update loading status of current page
*/
private void updateProgress(final boolean isLoading, final int progress) {
if (isLoading) {
mProgressView.setVisibility(View.VISIBLE);
mProgressView.setProgress(progress);
} else {
mProgressView.setVisibility(View.GONE);
}
private void updateCanStop() {
if (menuItemControl != null) {
Drawable icon = menuItemControl.getIcon();
icon.setLevel(progress);
if (mCanStop) {
icon.setLevel(0);
} else {
icon.setLevel(100);
}
}
}
/**
* Update the state of the action bar
*/
private void updateActionBar() {
actionBarPresenter.update(mCurrentTitle, mCurrentUrl, mSecurityStatus);
}
/**
* Call this method to reload page, or stop page loading if progress not complete yet.
*/
private void onLoadingControlClicked() {
final Tab tab = Tabs.getInstance().getSelectedTab();
if (tab != null) {
if (tab.getLoadProgress() == Tab.LOAD_PROGRESS_STOP) {
tab.doReload(true);
} else {
tab.doStop();
}
if (mCanStop) {
// TODO: enable this after implementing GeckoView.stop()
//mGeckoView.stop();
} else {
mGeckoView.reload();
}
}
private void onForwardClicked() {
final Tab tab = Tabs.getInstance().getSelectedTab();
if ((tab != null) && tab.canDoForward()) {
tab.doForward();
if (mCanGoForward) {
mGeckoView.goForward();
}
}
@ -485,15 +412,11 @@ public class CustomTabsActivity extends SingleTabActivity implements Tabs.OnTabs
* Callback for Open-in menu item.
*/
private void onOpenInClicked() {
final Tab tab = Tabs.getInstance().getSelectedTab();
if (tab != null) {
// To launch default browser with url of current tab.
final Intent intent = new Intent();
intent.setData(Uri.parse(tab.getURL()));
intent.setAction(Intent.ACTION_VIEW);
startActivity(intent);
finish();
}
final Intent intent = new Intent();
intent.setData(Uri.parse(mCurrentUrl));
intent.setAction(Intent.ACTION_VIEW);
startActivity(intent);
finish();
}
private void onActionButtonClicked() {
@ -507,12 +430,10 @@ public class CustomTabsActivity extends SingleTabActivity implements Tabs.OnTabs
* Callback for Share menu item.
*/
private void onShareClicked() {
final String url = Tabs.getInstance().getSelectedTab().getURL();
if (!TextUtils.isEmpty(url)) {
if (!TextUtils.isEmpty(mCurrentUrl)) {
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("text/plain");
shareIntent.putExtra(Intent.EXTRA_TEXT, url);
shareIntent.putExtra(Intent.EXTRA_TEXT, mCurrentUrl);
Intent chooserIntent = Intent.createChooser(shareIntent, getString(R.string.share_title));
chooserIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
@ -526,9 +447,8 @@ public class CustomTabsActivity extends SingleTabActivity implements Tabs.OnTabs
private class UrlCopyListener implements View.OnLongClickListener {
@Override
public boolean onLongClick(View v) {
final String url = Tabs.getInstance().getSelectedTab().getURL();
if (!TextUtils.isEmpty(url)) {
Clipboard.setText(url);
if (!TextUtils.isEmpty(mCurrentUrl)) {
Clipboard.setText(mCurrentUrl);
SnackbarBuilder.builder(CustomTabsActivity.this)
.message(R.string.custom_tabs_hint_url_copy)
.duration(Snackbar.LENGTH_SHORT)
@ -554,4 +474,59 @@ public class CustomTabsActivity extends SingleTabActivity implements Tabs.OnTabs
}
return null;
}
/* GeckoView.NavigationListener */
@Override
public void onLocationChange(GeckoView view, String url) {
mCurrentUrl = url;
updateActionBar();
}
@Override
public void onCanGoBack(GeckoView view, boolean canGoBack) {
mCanGoBack = canGoBack;
}
@Override
public void onCanGoForward(GeckoView view, boolean canGoForward) {
mCanGoForward = canGoForward;
updateMenuItemForward();
}
/* GeckoView.ProgressListener */
@Override
public void onPageStart(GeckoView view, String url) {
mCurrentUrl = url;
mCanStop = true;
updateActionBar();
updateCanStop();
}
@Override
public void onPageStop(GeckoView view, boolean success) {
mCanStop = false;
updateCanStop();
}
@Override
public void onSecurityChange(GeckoView view, int status) {
if ((status & STATE_IS_INSECURE) != 0) {
mSecurityStatus = STATE_IS_INSECURE;
} else if ((status & STATE_IS_BROKEN) != 0) {
mSecurityStatus = STATE_IS_BROKEN;
} else if ((status & STATE_IS_SECURE) != 0) {
mSecurityStatus = STATE_IS_SECURE;
}
updateActionBar();
}
/* GeckoView.ContentListener */
@Override
public void onTitleChange(GeckoView view, String title) {
mCurrentTitle = title;
updateActionBar();
}
@Override
public void onFullScreen(GeckoView view, boolean fullScreen) {}
}

View File

@ -7,15 +7,17 @@ package org.mozilla.gecko.webapps;
import java.io.File;
import java.io.IOException;
import java.util.List;
import android.app.ActivityManager;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.view.ActionMode;
import android.support.v7.widget.Toolbar;
import android.support.v7.app.ActionBar;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
@ -30,6 +32,8 @@ import org.json.JSONException;
import org.mozilla.gecko.AppConstants;
import org.mozilla.gecko.EventDispatcher;
import org.mozilla.gecko.GeckoAppShell;
import org.mozilla.gecko.GeckoView;
import org.mozilla.gecko.GeckoViewSettings;
import org.mozilla.gecko.SingleTabActivity;
import org.mozilla.gecko.Telemetry;
import org.mozilla.gecko.TelemetryContract;
@ -48,20 +52,22 @@ import org.mozilla.gecko.widget.AnchoredPopup;
import static org.mozilla.gecko.Tabs.TabEvents;
public class WebAppActivity extends SingleTabActivity {
public class WebAppActivity extends AppCompatActivity
implements GeckoView.NavigationListener {
private static final String LOGTAG = "WebAppActivity";
public static final String MANIFEST_PATH = "MANIFEST_PATH";
private static final String SAVED_INTENT = "savedIntent";
private TextView mUrlView;
private View doorhangerOverlay;
private GeckoView mGeckoView;
private Uri mScope;
@Override
public void onCreate(Bundle savedInstanceState) {
if ((getIntent().getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0 &&
savedInstanceState != null) {
savedInstanceState != null) {
// Even though we're a single task activity, Android's task switcher has the
// annoying habit of never updating its stored intent after our initial creation,
// even if we've been subsequently started with a new intent.
@ -75,73 +81,33 @@ public class WebAppActivity extends SingleTabActivity {
super.onCreate(savedInstanceState);
setContentView(R.layout.customtabs_activity);
final Toolbar toolbar = (Toolbar) findViewById(R.id.actionbar);
setSupportActionBar(toolbar);
final ProgressBar progressBar = (ProgressBar) findViewById(R.id.page_progress);
progressBar.setVisibility(View.GONE);
final ActionBar actionBar = getSupportActionBar();
actionBar.setCustomView(R.layout.webapps_action_bar_custom_view);
actionBar.setDisplayShowCustomEnabled(true);
actionBar.setDisplayShowTitleEnabled(false);
actionBar.hide();
doorhangerOverlay = findViewById(R.id.custom_tabs_doorhanger_overlay);
final View customView = actionBar.getCustomView();
mUrlView = (TextView) customView.findViewById(R.id.webapps_action_bar_url);
EventDispatcher.getInstance().registerUiThreadListener(this,
"Website:AppEntered",
"Website:AppLeft",
null);
}
mGeckoView = (GeckoView) findViewById(R.id.gecko_view);
@Override
public View getDoorhangerOverlay() {
return doorhangerOverlay;
}
mGeckoView.setNavigationListener(this);
@Override
public int getLayout() {
return R.layout.customtabs_activity;
}
final GeckoViewSettings settings = mGeckoView.getSettings();
settings.setBoolean(GeckoViewSettings.USE_MULTIPROCESS, false);
@Override
public void handleMessage(final String event, final GeckoBundle message,
final EventCallback callback) {
super.handleMessage(event, message, callback);
if (message == null ||
!message.containsKey("tabId") || message.getInt("tabId") != mLastSelectedTabId) {
return;
final Uri u = getIntent().getData();
if (u != null) {
mGeckoView.loadUri(u.toString());
}
switch (event) {
case "Website:AppEntered":
getSupportActionBar().hide();
break;
case "Website:AppLeft":
getSupportActionBar().show();
break;
}
}
@Override
public void onTabChanged(Tab tab, Tabs.TabEvents msg, String data) {
super.onTabChanged(tab, msg, data);
if (tab == null || !Tabs.getInstance().isSelectedTab(tab) ||
tab.getType() != Tab.TabType.WEBAPP) {
return;
}
if (msg == TabEvents.LOCATION_CHANGE ||
msg == TabEvents.SELECTED) {
mUrlView.setText(tab.getURL());
}
loadManifest(getIntent().getStringExtra(MANIFEST_PATH));
}
@Override
@ -151,75 +117,6 @@ public class WebAppActivity extends SingleTabActivity {
outState.putParcelable(SAVED_INTENT, getIntent());
}
@Override
public void onDestroy() {
super.onDestroy();
EventDispatcher.getInstance().unregisterUiThreadListener(this,
"Website:AppEntered",
"Website:AppLeft",
null);
}
@Override
protected int getNewTabFlags() {
return Tabs.LOADURL_WEBAPP | super.getNewTabFlags();
}
@Override
protected void onTabOpenFromIntent(Tab tab) {
super.onTabOpenFromIntent(tab);
Telemetry.sendUIEvent(TelemetryContract.Event.LOAD_URL, TelemetryContract.Method.INTENT, "webapp");
loadManifest(tab.getManifestPath());
}
/**
* In case this activity and its tab are reused (the user has opened
* > 10 current web apps), we check that app launched is still within
* the same host as the intent has set.
* If it isn't, we reload the intent URL.
*/
@Override
protected void onTabSelectFromIntent(Tab tab) {
super.onTabSelectFromIntent(tab);
SafeIntent intent = new SafeIntent(getIntent());
final String launchUrl = intent.getDataString();
final String currentUrl = tab.getURL();
final boolean isSameDomain = Uri.parse(currentUrl).getHost()
.equals(Uri.parse(launchUrl).getHost());
final String manifestPath;
if (!isSameDomain) {
Telemetry.sendUIEvent(TelemetryContract.Event.LOAD_URL, TelemetryContract.Method.INTENT, "webapp");
manifestPath = intent.getStringExtra(MANIFEST_PATH);
tab.setManifestUrl(manifestPath);
Tabs.getInstance().loadUrl(launchUrl);
} else {
manifestPath = tab.getManifestPath();
}
loadManifest(manifestPath);
}
@Override
protected ActionModePresenter getTextSelectPresenter() {
return new ActionModePresenter() {
private ActionMode mMode;
@Override
public void startActionMode(ActionMode.Callback callback) {
mMode = startSupportActionMode(callback);
}
@Override
public void endActionMode() {
if (mMode != null) {
mMode.finish();
}
}
};
}
private void loadManifest(String manifestPath) {
if (TextUtils.isEmpty(manifestPath)) {
Log.e(LOGTAG, "Missing manifest");
@ -237,6 +134,7 @@ public class WebAppActivity extends SingleTabActivity {
final Integer color = readColorFromManifest(manifestField);
final String name = readNameFromManifest(manifestField);
final Bitmap icon = readIconFromManifest(manifest);
mScope = readScopeFromManifest(manifest, manifestPath);
final ActivityManager.TaskDescription taskDescription = (color == null)
? new ActivityManager.TaskDescription(name, icon)
: new ActivityManager.TaskDescription(name, icon, color);
@ -288,4 +186,70 @@ public class WebAppActivity extends SingleTabActivity {
}
return loadIconResult.getBestBitmap(GeckoAppShell.getPreferredIconSize());
}
private Uri readScopeFromManifest(JSONObject manifest, String manifestPath) {
final String scopeStr = manifest.optString("scope", null);
if (scopeStr == null) {
return null;
}
Uri res = Uri.parse(scopeStr);
if (res.isRelative()) {
// TODO: Handle this more correctly.
return null;
}
return res;
}
private boolean isInScope(String url) {
if (mScope == null) {
return true;
}
final Uri uri = Uri.parse(url);
if (!uri.getScheme().equals(mScope.getScheme())) {
return false;
}
if (!uri.getHost().equals(mScope.getHost())) {
return false;
}
final List<String> scopeSegments = mScope.getPathSegments();
final List<String> urlSegments = uri.getPathSegments();
if (scopeSegments.size() > urlSegments.size()) {
return false;
}
for (int i = 0; i < scopeSegments.size(); i++) {
if (!scopeSegments.get(i).equals(urlSegments.get(i))) {
return false;
}
}
return true;
}
/* GeckoView.NavigationListener */
@Override
public void onLocationChange(GeckoView view, String url) {
if (isInScope(url)) {
getSupportActionBar().hide();
} else {
getSupportActionBar().show();
}
mUrlView.setText(url);
}
@Override
public void onCanGoBack(GeckoView view, boolean canGoBack) {
}
@Override
public void onCanGoForward(GeckoView view, boolean canGoForward) {
}
}

View File

@ -12,11 +12,6 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--
This layout is quite complex because GeckoApp accesses all view groups
in this tree. In a perfect world this should just include a GeckoView.
-->
<android.support.v7.widget.Toolbar
android:id="@id/actionbar"
android:layout_width="match_parent"
@ -25,48 +20,18 @@
android:background="@color/text_and_tabs_tray_grey"
app:layout_scrollFlags="scroll|enterAlways"/>
<view class="org.mozilla.gecko.GeckoApp$MainLayout"
android:id="@+id/main_layout"
android:layout_width="match_parent"
<org.mozilla.gecko.GeckoView
android:id="@+id/gecko_view"
android:layout_width="fill_parent"
android:layout_below="@id/actionbar"
android:layout_height="match_parent"
android:background="@android:color/transparent">
<RelativeLayout android:id="@+id/gecko_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/tablet_tab_strip"
android:layout_above="@+id/find_in_page">
<fragment class="org.mozilla.gecko.GeckoViewFragment"
android:id="@+id/layer_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="none"/>
<org.mozilla.gecko.FormAssistPopup android:id="@+id/form_assist_popup"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"/>
</RelativeLayout>
</view>
<ProgressBar
android:id="@id/page_progress"
style="@style/Base.Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="4dp"
android:layout_alignTop="@id/main_layout"
android:background="@drawable/url_bar_bg"
android:progressDrawable="@drawable/progressbar"
tools:progress="70"/>
android:scrollbars="none"/>
<View android:id="@+id/custom_tabs_doorhanger_overlay"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/dark_transparent_overlay"
android:alpha="0"
android:layerType="hardware"/>
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/dark_transparent_overlay"
android:alpha="0"
android:layerType="hardware"/>
</RelativeLayout>

View File

@ -87,7 +87,7 @@ var FindHelper = {
this._initialViewport = JSON.stringify(this._targetTab.getViewport());
this._viewportChanged = false;
GlobalEventDispatcher.registerListener(this, [
WindowEventDispatcher.registerListener(this, [
"Tab:Selected",
]);
},
@ -109,7 +109,7 @@ var FindHelper = {
this._initialViewport = null;
this._viewportChanged = false;
GlobalEventDispatcher.unregisterListener(this, [
WindowEventDispatcher.unregisterListener(this, [
"Tab:Selected",
]);
},

View File

@ -388,11 +388,15 @@ var BrowserApp = {
Services.androidBridge.browserApp = this;
GlobalEventDispatcher.registerListener(this, [
WindowEventDispatcher.registerListener(this, [
"Session:Restore",
"Tab:Load",
"Tab:Selected",
"Tab:Closed",
"Tab:Move",
]);
GlobalEventDispatcher.registerListener(this, [
"Browser:LoadManifest",
"Browser:Quit",
"Fonts:Reload",
@ -1850,6 +1854,10 @@ var BrowserApp = {
break;
}
case "Session:Restore":
GlobalEventDispatcher.dispatch("Session:Restore", data);
break;
case "Session:Stop":
browser.stop();
break;

View File

@ -7,7 +7,7 @@
<window id="main-window"
onload="startup();"
windowtype="navigator:browser"
windowtype="navigator:geckoview"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<browser id="content" type="content" primary="true" src="about:blank" flex="1"/>

View File

@ -599,6 +599,13 @@ public class GeckoView extends LayerView {
throw new IllegalArgumentException("Must import script from 'resources://android/assets/' location.");
}
/**
* Exits fullscreen mode
*/
public void exitFullScreen() {
mEventDispatcher.dispatch("GeckoViewContent:ExitFullScreen", null);
}
/**
* Set the content callback handler.
* This will replace the current handler.

View File

@ -28,8 +28,21 @@ class GeckoViewContent extends GeckoViewModule {
/* capture */ true, /* untrusted */ false);
this.window.addEventListener("MozDOMFullscreen:Exited", this,
/* capture */ true, /* untrusted */ false);
this.eventDispatcher.registerListener(this, ["GeckoViewContent:ExitFullScreen"]);
}
// Bundle event handler.
onEvent(aEvent, aData, aCallback) {
debug("onEvent: " + aEvent);
switch (aEvent) {
case "GeckoViewContent:ExitFullScreen":
this.messageManager.sendAsyncMessage("GeckoView:DOMFullscreenExited");
break;
}
}
// DOM event handler
handleEvent(aEvent) {
debug("handleEvent: aEvent.type=" + aEvent.type);
@ -37,11 +50,11 @@ class GeckoViewContent extends GeckoViewModule {
case "MozDOMFullscreen:Entered":
if (this.browser == aEvent.target) {
// Remote browser; dispatch to content process.
this.browser.messageManager.sendAsyncMessage("GeckoView:DOMFullscreenEntered");
this.messageManager.sendAsyncMessage("GeckoView:DOMFullscreenEntered");
}
break;
case "MozDOMFullscreen:Exited":
this.browser.messageManager.sendAsyncMessage("GeckoView:DOMFullscreenExited");
this.messageManager.sendAsyncMessage("GeckoView:DOMFullscreenExited");
break;
}
}

View File

@ -440,6 +440,17 @@ WebSocketEventService::RemoveListener(uint64_t aInnerWindowID,
return NS_OK;
}
NS_IMETHODIMP
WebSocketEventService::HasListenerFor(uint64_t aInnerWindowID,
bool* aResult)
{
MOZ_ASSERT(NS_IsMainThread());
*aResult = mWindows.Get(aInnerWindowID);
return NS_OK;
}
NS_IMETHODIMP
WebSocketEventService::Observe(nsISupports* aSubject, const char* aTopic,
const char16_t* aData)

View File

@ -76,4 +76,6 @@ interface nsIWebSocketEventService : nsISupports
[must_use] void removeListener(in unsigned long long aInnerWindowID,
in nsIWebSocketEventListener aListener);
[must_use] bool hasListenerFor(in unsigned long long aInnerWindowID);
};

View File

@ -933,11 +933,7 @@ nsHtml5TreeOpExecutor::ShouldPreloadURI(nsIURI *aURI)
nsAutoCString spec;
nsresult rv = aURI->GetSpec(spec);
NS_ENSURE_SUCCESS(rv, false);
if (mPreloadedURLs.Contains(spec)) {
return false;
}
mPreloadedURLs.PutEntry(spec);
return true;
return mPreloadedURLs.EnsureInserted(spec);
}
void

View File

@ -293,6 +293,10 @@ class LcovFile(object):
print("Invalid lcov line start at %s:%d:\n%s" %
(lcov_fh.name, count + 1, line))
raise
except TypeError:
print("Invalid lcov line start at %s:%d:\n%s" %
(lcov_fh.name, count + 1, line))
raise
def print_file(self, fh):
for record in self.records:

View File

@ -1161,4 +1161,4 @@ static const TransportSecurityPreload kPublicKeyPinningPreloadList[] = {
static const int32_t kUnknownId = -1;
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1506094491659000);
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1506180969403000);

View File

@ -37,6 +37,8 @@
1stcapital.com.sg: did not receive HSTS header
1xcess.com: did not receive HSTS header
1years.cc: could not connect to host
2048-spiel.de: could not connect to host
2048game.co.uk: could not connect to host
206rc.net: max-age too low: 2592000
21lg.co: could not connect to host
247loan.com: max-age too low: 0
@ -124,6 +126,7 @@ abt.de: did not receive HSTS header
abtom.de: did not receive HSTS header
abury.fr: did not receive HSTS header
abury.me: did not receive HSTS header
ac-epmservices.com: could not connect to host
academicenterprise.org: could not connect to host
accelerole.com: did not receive HSTS header
accelight.co.jp: did not receive HSTS header
@ -148,7 +151,6 @@ actu-medias.com: did not receive HSTS header
acuve.jp: could not connect to host
ada.is: max-age too low: 2592000
adajwells.me: could not connect to host
adam-kostecki.de: could not connect to host
adamgold.net: could not connect to host
adams.net: max-age too low: 0
adamwk.com: did not receive HSTS header
@ -158,7 +160,6 @@ addvocate.com: could not connect to host
adelevie.com: could not connect to host
adequatetechnology.com: could not connect to host
aderal.io: could not connect to host
adfa-1.com: did not receive HSTS header
adhs-chaoten.net: did not receive HSTS header
adindexr.com: could not connect to host
admin.google.com: did not receive HSTS header (error ignored - included regardless)
@ -193,7 +194,6 @@ agalaxyfarfaraway.co.uk: could not connect to host
agate.pw: did not receive HSTS header
agatheetraphael.fr: could not connect to host
agbremen.de: did not receive HSTS header
ageg.ca: did not receive HSTS header
agentseeker.ca: did not receive HSTS header
agevio.com: could not connect to host
agrimap.com: did not receive HSTS header
@ -218,7 +218,6 @@ akerek.hu: could not connect to host
akgundemirbas.com: could not connect to host
akkadia.cc: could not connect to host
akombakom.net: did not receive HSTS header
akostecki.de: could not connect to host
akselimedia.fi: did not receive HSTS header
aktivist.in: did not receive HSTS header
al-shami.net: could not connect to host
@ -263,6 +262,7 @@ alterbaum.net: did not receive HSTS header
altfire.ca: could not connect to host
altmv.com: max-age too low: 7776000
aluminium-scaffolding.co.uk: could not connect to host
alvicom.hu: could not connect to host
alza.at: did not receive HSTS header
alza.co.uk: did not receive HSTS header
alza.cz: did not receive HSTS header
@ -342,6 +342,7 @@ antscript.com: did not receive HSTS header
anycoin.me: could not connect to host
aocast.info: could not connect to host
aojf.fr: could not connect to host
aozora.moe: could not connect to host
apachelounge.com: did not receive HSTS header
aparaatti.org: could not connect to host
apeasternpower.com: could not connect to host
@ -391,6 +392,7 @@ armsday.com: could not connect to host
armytricka.cz: did not receive HSTS header
arocloud.de: did not receive HSTS header
arod.tk: could not connect to host
aroundme.org: did not receive HSTS header
arpa.ph: could not connect to host
arpr.co: did not receive HSTS header
arrayify.com: could not connect to host
@ -491,7 +493,6 @@ azprep.us: could not connect to host
b-landia.net: could not connect to host
b303.me: did not receive HSTS header
b3orion.com: max-age too low: 0
b422edu.com: could not connect to host
baby-click.de: could not connect to host
babybee.ie: could not connect to host
babybic.hu: did not receive HSTS header
@ -577,7 +578,6 @@ beikeil.de: did not receive HSTS header
belairsewvac.com: did not receive HSTS header
belics.com: did not receive HSTS header
belltower.io: could not connect to host
belly-button-piercings.com: could not connect to host
bemyvictim.com: max-age too low: 2678400
beneffy.com: did not receive HSTS header
benjakesjohnson.com: could not connect to host
@ -616,7 +616,7 @@ bfelob.gov: max-age too low: 86400
bffm.biz: could not connect to host
bgcparkstad.nl: did not receive HSTS header
bgmn.net: could not connect to host
bhatia.at: could not connect to host
bhatia.at: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 118" data: no]
bi.search.yahoo.com: did not receive HSTS header
biblerhymes.com: did not receive HSTS header
bidon.ca: did not receive HSTS header
@ -631,7 +631,6 @@ bildiri.ci: did not receive HSTS header
bildschirmflackern.de: did not receive HSTS header
billaud.eu.org: could not connect to host
billin.net: did not receive HSTS header
billionairemailinglist.com: could not connect to host
billkiss.com: could not connect to host
billninja.com: did not receive HSTS header
billrusling.com: could not connect to host
@ -666,9 +665,7 @@ bitvigor.com: could not connect to host
bivsi.com: could not connect to host
bizcms.com: did not receive HSTS header
bizon.sk: did not receive HSTS header
bjornhelmersson.se: could not connect to host
bkb-skandal.ch: could not connect to host
bl4ckb0x.eu: could not connect to host
black-armada.com.pl: could not connect to host
black-armada.pl: could not connect to host
black-octopus.ru: did not receive HSTS header
@ -816,7 +813,21 @@ bw81.xyz: could not connect to host
bwear4all.de: did not receive HSTS header
by4cqb.cn: could not connect to host
bydisk.com: could not connect to host
bypassed.bid: did not receive HSTS header
bypassed.cc: did not receive HSTS header
bypassed.club: did not receive HSTS header
bypassed.date: did not receive HSTS header
bypassed.download: did not receive HSTS header
bypassed.faith: did not receive HSTS header
bypassed.host: did not receive HSTS header
bypassed.me: did not receive HSTS header
bypassed.online: did not receive HSTS header
bypassed.org: did not receive HSTS header
bypassed.party: did not receive HSTS header
bypassed.press: could not connect to host
bypassed.pw: did not receive HSTS header
bypassed.rocks: did not receive HSTS header
bypassed.site: did not receive HSTS header
bypassed.today: did not receive HSTS header
bypassed.works: did not receive HSTS header
bypassed.world: did not receive HSTS header
@ -854,12 +865,14 @@ calvin.me: max-age too low: 2592000
calvinallen.net: could not connect to host
camashop.de: did not receive HSTS header
cambridgeanalytica.org: did not receive HSTS header
camerweb.es: could not connect to host
camjackson.net: did not receive HSTS header
camolist.com: could not connect to host
campaignelves.com: did not receive HSTS header
campfire.co.il: did not receive HSTS header
camsanalytics.com: could not connect to host
canadiangamblingchoice.com: did not receive HSTS header
canarianlegalalliance.com: did not receive HSTS header
cancelmyprofile.com: did not receive HSTS header
candicontrols.com: did not receive HSTS header
candratech.com: could not connect to host
@ -879,7 +892,7 @@ cardoni.net: did not receive HSTS header
cardstream.com: did not receive HSTS header
cardurl.com: did not receive HSTS header
caringladies.org: could not connect to host
carlo.mx: did not receive HSTS header
carlo.mx: could not connect to host
carlolly.co.uk: could not connect to host
carlosalves.info: could not connect to host
carpliyz.com: could not connect to host
@ -1011,7 +1024,6 @@ cityoflaurel.org: did not receive HSTS header
ciuciucadou.ro: could not connect to host
cium.ru: could not connect to host
cjcaron.org: could not connect to host
ckleemann.de: could not connect to host
clara-baumert.de: could not connect to host
claralabs.com: did not receive HSTS header
classicsandexotics.com: did not receive HSTS header
@ -1052,7 +1064,6 @@ cloudstrike.co: could not connect to host
cloudwalk.io: did not receive HSTS header
cloverleaf.net: max-age too low: 0
clowde.in: could not connect to host
cloxy.com: did not receive HSTS header
clubmix.co.kr: could not connect to host
cluster.id: could not connect to host
clustermaze.net: could not connect to host
@ -1077,6 +1088,7 @@ codabix.net: could not connect to host
code-35.com: did not receive HSTS header
code-digsite.com: could not connect to host
code.google.com: did not receive HSTS header (error ignored - included regardless)
codealkemy.co: could not connect to host
codeco.pw: could not connect to host
codecontrollers.de: could not connect to host
codeforce.io: could not connect to host
@ -1088,7 +1100,6 @@ codepoet.de: could not connect to host
codepx.com: did not receive HSTS header
codewild.de: could not connect to host
codiva.io: max-age too low: 2592000
codymoniz.com: did not receive HSTS header
coffeeetc.co.uk: did not receive HSTS header
coffeestrategies.com: max-age too low: 0
coiffeurschnittstelle.ch: did not receive HSTS header
@ -1286,6 +1297,7 @@ danielverlaan.nl: did not receive HSTS header
danielworthy.com: did not receive HSTS header
danijobs.com: could not connect to host
danishenanigans.com: could not connect to host
dankim.de: could not connect to host
dannycrichton.com: did not receive HSTS header
danrl.de: could not connect to host
danwillenberg.com: did not receive HSTS header
@ -1320,7 +1332,7 @@ datenreiter.ml: could not connect to host
datenreiter.tk: could not connect to host
davidandkailey.com: could not connect to host
davidglidden.eu: did not receive HSTS header
davidhunter.scot: did not receive HSTS header
davidhunter.scot: could not connect to host
davidnoren.com: did not receive HSTS header
davidreinhardt.de: could not connect to host
davidscherzer.at: could not connect to host
@ -1332,7 +1344,7 @@ dccode.gov: could not connect to host
dcl.re: did not receive HSTS header
dcuofriends.net: could not connect to host
dcurt.is: did not receive HSTS header
ddatsh.com: max-age too low: 0
ddatsh.com: could not connect to host
dden.website: could not connect to host
dden.xyz: could not connect to host
debank.tv: did not receive HSTS header
@ -1366,6 +1378,7 @@ demo.swedbank.se: did not receive HSTS header
demotops.com: did not receive HSTS header
dengyong.org: could not connect to host
denh.am: did not receive HSTS header
denimtoday.com: did not receive HSTS header
denisjean.fr: could not connect to host
dentaldomain.org: did not receive HSTS header
dentaldomain.ph: could not connect to host
@ -1392,8 +1405,8 @@ devafterdark.com: could not connect to host
devcu.com: could not connect to host
devcu.net: could not connect to host
develop.cool: could not connect to host
developerfair.com: could not connect to host
devincrow.me: could not connect to host
devkit.cc: could not connect to host
devmsg.com: did not receive HSTS header
devnsec.com: could not connect to host
devnull.team: could not connect to host
@ -1401,10 +1414,10 @@ devopps.me: did not receive HSTS header
devtub.com: did not receive HSTS header
devuan.org: did not receive HSTS header
dewin.io: could not connect to host
df1paw.de: could not connect to host
dfviana.com.br: did not receive HSTS header
dhpcs.com: did not receive HSTS header
dhpiggott.net: did not receive HSTS header
dhuy.net: could not connect to host
diablotine.rocks: could not connect to host
dianlujitao.com: did not receive HSTS header
diannaobos.com: did not receive HSTS header
@ -1426,12 +1439,12 @@ digitalriver.tk: could not connect to host
digitalskillswap.com: could not connect to host
dim.lighting: could not connect to host
dinamoelektrik.com: could not connect to host
dingcc.com: could not connect to host
dingcc.me: could not connect to host
dinkum.online: could not connect to host
directhskincream.com: could not connect to host
directorinegocis.cat: could not connect to host
discovery.lookout.com: did not receive HSTS header
discoveryrom.org: could not connect to host
dise-online.de: did not receive HSTS header
dislocated.de: did not receive HSTS header
disowned.net: max-age too low: 0
@ -1452,6 +1465,7 @@ dkniss.de: could not connect to host
dl.google.com: did not receive HSTS header (error ignored - included regardless)
dlc.viasinc.com: could not connect to host
dlemper.de: did not receive HSTS header
dlitz.net: could not connect to host
dlscomputers.com.au: did not receive HSTS header
dmcibulldog.com: did not receive HSTS header
dmix.ca: could not connect to host
@ -1532,13 +1546,14 @@ drhopeson.com: could not connect to host
drishti.guru: could not connect to host
droidboss.com: did not receive HSTS header
droncentrum.pl: did not receive HSTS header
droomhuis-in-zuid-holland-kopen.nl: did not receive HSTS header
droomhuis-in-zuid-holland-kopen.nl: could not connect to host
dropcam.com: did not receive HSTS header
drtroyhendrickson.com: could not connect to host
drumbandesperanto.nl: could not connect to host
ds-christiansen.de: could not connect to host
dshiv.io: could not connect to host
dtub.co: did not receive HSTS header
dubrovskiy.net: could not connect to host
dubrovskiy.pro: could not connect to host
duesee.org: could not connect to host
dullsir.com: did not receive HSTS header
@ -1615,11 +1630,11 @@ egbert.net: could not connect to host
egit.co: could not connect to host
eglek.com: did not receive HSTS header
ego-world.org: could not connect to host
ehipaadev.com: could not connect to host
ehito.ovh: could not connect to host
ehrenamt-skpfcw.de: could not connect to host
eicfood.com: could not connect to host
ekbanden.nl: could not connect to host
ekostecki.de: could not connect to host
eksik.com: could not connect to host
elaintehtaat.fi: did not receive HSTS header
elan-organics.com: did not receive HSTS header
@ -1637,8 +1652,6 @@ elenag.ga: could not connect to host
elenoon.ir: did not receive HSTS header
elgacien.de: could not connect to host
elimdengelen.com: did not receive HSTS header
elisabeth-kostecki.de: could not connect to host
elisabethkostecki.de: could not connect to host
elite-porno.ru: did not receive HSTS header
elitefishtank.com: could not connect to host
elnutricionista.es: did not receive HSTS header
@ -1763,6 +1776,7 @@ eupho.me: could not connect to host
euren.se: could not connect to host
eurocamping.se: could not connect to host
euroshop24.net: could not connect to host
eurostrategy.vn.ua: could not connect to host
evafojtova.cz: did not receive HSTS header
evalesc.com: could not connect to host
evdenevenakliyatankara.pw: did not receive HSTS header
@ -1831,6 +1845,7 @@ fantasyfootballpundit.com: did not receive HSTS header
fanyl.cn: could not connect to host
farhadexchange.com: did not receive HSTS header
fashioncare.cz: did not receive HSTS header
fashionunited.nl: did not receive HSTS header
fasset.jp: could not connect to host
fastdigitizing.com: max-age too low: 300
fastograph.com: could not connect to host
@ -1979,6 +1994,7 @@ frasys.io: could not connect to host
frasys.net: could not connect to host
frau-inge.de: could not connect to host
fraurichter.net: could not connect to host
frederik-braun.com: did not receive HSTS header
fredvoyage.fr: did not receive HSTS header
free.com.tw: did not receive HSTS header
freeboson.org: could not connect to host
@ -1997,6 +2013,7 @@ freshlymind.com: did not receive HSTS header
frforms.com: did not receive HSTS header
friendica.ch: could not connect to host
friendlyfiregameshow.com: could not connect to host
friendship-quotes.co.uk: could not connect to host
frimons.com: could not connect to host
froggstack.de: could not connect to host
frontisme.nl: could not connect to host
@ -2045,6 +2062,7 @@ g4w.co: did not receive HSTS header (error ignored - included regardless)
g5led.nl: could not connect to host
gabber.scot: could not connect to host
gabi.com.es: could not connect to host
gabi.uno: could not connect to host
gaelleetarnaud.com: did not receive HSTS header
gafachi.com: could not connect to host
gagstempel.de: max-age too low: 86400
@ -2062,6 +2080,7 @@ game.yt: could not connect to host
gamecave.de: could not connect to host
gamechasm.com: could not connect to host
gamefund.me: did not receive HSTS header
gameguardian.net: could not connect to host
gamehacks.me: could not connect to host
gameink.net: max-age too low: 0
gamek.es: did not receive HSTS header
@ -2086,6 +2105,7 @@ gatapro.net: could not connect to host
gatorsa.es: did not receive HSTS header
gdegem.org: did not receive HSTS header
gdpventure.com: max-age too low: 0
gdz.tv: did not receive HSTS header
gebn.co.uk: did not receive HSTS header
gedankenbude.info: could not connect to host
geekcast.co.uk: did not receive HSTS header
@ -2138,6 +2158,7 @@ gfwsb.ml: could not connect to host
ggss.ml: could not connect to host
gheorghesarcov.ga: could not connect to host
gheorghesarcov.tk: could not connect to host
ghostblog.info: could not connect to host
giantmicrobes.de: max-age too low: 86400
gibraltar.at: could not connect to host
gietvloergarant.nl: did not receive HSTS header
@ -2155,6 +2176,7 @@ gis3m.org: did not receive HSTS header
gistfy.com: could not connect to host
givemyanswer.com: could not connect to host
gizzo.sk: could not connect to host
gjspunk.de: could not connect to host
gjung.com: could not connect to host
gl.search.yahoo.com: did not receive HSTS header
glass.google.com: did not receive HSTS header (error ignored - included regardless)
@ -2304,7 +2326,6 @@ gyboche.com: could not connect to host
gyboche.science: could not connect to host
gycis.me: could not connect to host
gylauto.fr: could not connect to host
gyoza.beer: could not connect to host
gypthecat.com: max-age too low: 604800
gyz.io: could not connect to host
h-og.com: could not connect to host
@ -2345,11 +2366,10 @@ handicapindeles.nl: did not receive HSTS header
handiworker.com: could not connect to host
hanfu.la: could not connect to host
hanimalis.fr: could not connect to host
hannover-banditen.de: could not connect to host
hansen.hn: could not connect to host
hao2taiwan.com: max-age too low: 0
haoyugao.com: could not connect to host
haozi.me: could not connect to host
haozi.me: did not receive HSTS header
happix.nl: did not receive HSTS header
happyfabric.me: did not receive HSTS header
happygastro.com: could not connect to host
@ -2372,6 +2392,7 @@ hasinase.de: did not receive HSTS header
haste.ch: could not connect to host
hastherebeenamassshooting.today: could not connect to host
hatoko.net: could not connect to host
haucke.xyz: could not connect to host
haufschild.de: could not connect to host
haurumcraft.net: could not connect to host
hausarzt-stader-str.de: did not receive HSTS header
@ -2406,7 +2427,7 @@ hekeki.com: could not connect to host
helencrump.co.uk: did not receive HSTS header
helloworldhost.com: did not receive HSTS header
helpadmin.net: could not connect to host
helpium.de: could not connect to host
helpium.de: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 118" data: no]
helpmebuild.com: did not receive HSTS header
hemdal.se: could not connect to host
hencagon.com: could not connect to host
@ -2415,7 +2436,6 @@ hepteract.us: could not connect to host
herbert.io: could not connect to host
heritagedentistry.ca: did not receive HSTS header
herrenfahrt.com: did not receive HSTS header
herrsmith.com: could not connect to host
herzbotschaft.de: did not receive HSTS header
heutger.net: did not receive HSTS header
heyguevara.com: could not connect to host
@ -2540,6 +2560,7 @@ ichoosebtec.com: did not receive HSTS header
icity.ly: did not receive HSTS header
icloud.net: could not connect to host
icntorrent.download: could not connect to host
icodeconnect.com: could not connect to host
icodesign.me: did not receive HSTS header
icreative.nl: did not receive HSTS header
ictual.com: max-age too low: 0
@ -2591,13 +2612,17 @@ immoralgods.com: could not connect to host
immortals-co.com: did not receive HSTS header
immoverkauf24.at: did not receive HSTS header
immoverkauf24.de: did not receive HSTS header
immunicity.cc: did not receive HSTS header
immunicity.date: could not connect to host
immunicity.eu: did not receive HSTS header
immunicity.host: did not receive HSTS header
immunicity.info: could not connect to host
immunicity.online: could not connect to host
immunicity.press: could not connect to host
immunicity.rocks: did not receive HSTS header
immunicity.today: did not receive HSTS header
immunicity.top: could not connect to host
immunicity.win: did not receive HSTS header
immunicity.works: did not receive HSTS header
immunicity.world: did not receive HSTS header
imolug.org: did not receive HSTS header
@ -2646,6 +2671,7 @@ ins1gn1a.com: did not receive HSTS header
insane-bullets.com: could not connect to host
insane.zone: could not connect to host
insite-feedback.com: could not connect to host
inspirationalquotesuk.co.uk: could not connect to host
inspire-av.com: did not receive HSTS header
inspiroinc.com: could not connect to host
inspy.me: max-age too low: 0
@ -2731,6 +2757,7 @@ ithakama.cz: did not receive HSTS header
ithenrik.com: could not connect to host
itos.asia: did not receive HSTS header
itos.pl: did not receive HSTS header
itpros.ru: did not receive HSTS header
itriskltd.com: could not connect to host
itsadog.co.uk: did not receive HSTS header
itsagadget.com: did not receive HSTS header
@ -2852,6 +2879,7 @@ jiyuu-ni.net: could not connect to host
jkb.pics: could not connect to host
jkbuster.com: could not connect to host
jko.works: could not connect to host
jmdekker.it: could not connect to host
joakimalgroy.com: could not connect to host
jobmedic.com: did not receive HSTS header
jobshq.com: did not receive HSTS header
@ -2924,7 +2952,6 @@ kamcvicit.sk: could not connect to host
kamikano.com: could not connect to host
kanar.nl: could not connect to host
kaneo-gmbh.de: did not receive HSTS header
kaniklani.co.za: could not connect to host
kaohub.com: could not connect to host
kaplatz.is: could not connect to host
kapucini.si: max-age too low: 0
@ -2936,6 +2963,7 @@ karpanhellas.com: did not receive HSTS header
karting34.com: could not connect to host
kasilag.me: did not receive HSTS header
katiaetdavid.fr: could not connect to host
katproxy.al: did not receive HSTS header
katproxy.online: could not connect to host
katproxy.site: could not connect to host
katproxy.tech: could not connect to host
@ -2959,6 +2987,7 @@ kerangalam.com: could not connect to host
kerksanders.nl: did not receive HSTS header
kermadec.blog: could not connect to host
kermadec.net: could not connect to host
kernelpanics.nl: could not connect to host
kernl.us: did not receive HSTS header
kevinbowers.me: did not receive HSTS header
keymaster.lookout.com: did not receive HSTS header
@ -3011,7 +3040,7 @@ kleppe.co: could not connect to host
kletterkater.com: did not receive HSTS header
klicktojob.de: could not connect to host
kmartin.io: did not receive HSTS header
knccloud.com: did not receive HSTS header
knccloud.com: could not connect to host
knightsbridgegroup.org: could not connect to host
knowdebt.org: did not receive HSTS header
knowledgesnap.com: could not connect to host
@ -3046,6 +3075,7 @@ kostuumstore.nl: could not connect to host
kotois.com: could not connect to host
kotonehoko.net: could not connect to host
kotovstyle.ru: could not connect to host
kottur.is: did not receive HSTS header
koukni.cz: could not connect to host
kourpe.online: could not connect to host
kprog.net: could not connect to host
@ -3057,7 +3087,6 @@ kreb.io: could not connect to host
kredite.sale: could not connect to host
krestanskydarek.cz: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 118" data: no]
kriegt.es: did not receive HSTS header
kristikala.nl: could not connect to host
krizevackapajdasija.hr: could not connect to host
krizevci.info: did not receive HSTS header
kroetenfuchs.de: could not connect to host
@ -3107,6 +3136,7 @@ lacaverne.nl: could not connect to host
lachlankidson.net: did not receive HSTS header
lacledeslan.ninja: could not connect to host
lacocinadelila.com: did not receive HSTS header
laextra.mx: could not connect to host
laf.in.net: could not connect to host
lagalerievirtuelle.fr: did not receive HSTS header
lagoza.name: could not connect to host
@ -3168,7 +3198,6 @@ leonhooijer.nl: could not connect to host
leopold.email: could not connect to host
leopotamgroup.com: could not connect to host
lepont.pl: could not connect to host
lerasenglish.com: did not receive HSTS header
lerner.moscow: did not receive HSTS header
les-corsaires.net: could not connect to host
les-voitures-electriques.com: did not receive HSTS header
@ -3215,6 +3244,7 @@ lifecoach.tw: did not receive HSTS header
lifecoachproviders.com: did not receive HSTS header
lifeguard.aecom.com: did not receive HSTS header
lifeinitsownway.com: could not connect to host
lifequotes-uk.co.uk: could not connect to host
lifeskillsdirect.com: did not receive HSTS header
lifestylehunter.co.uk: did not receive HSTS header
lifetimemoneymachine.com: did not receive HSTS header
@ -3272,7 +3302,6 @@ localdrive.me: could not connect to host
locktheirphone.com: could not connect to host
locomotive.ca: did not receive HSTS header
loftboard.eu: could not connect to host
logaldeveloper.com: could not connect to host
logario.com.br: could not connect to host
logcat.info: could not connect to host
logicaladvertising.com: could not connect to host
@ -3283,6 +3312,7 @@ lognot.net: could not connect to host
lojadoprazer.com.br: could not connect to host
lolicore.ch: could not connect to host
lolidunno.com: could not connect to host
lolmegafroi.de: could not connect to host
london-transfers.com: did not receive HSTS header
londoncalling.co: did not receive HSTS header
londonlanguageexchange.com: could not connect to host
@ -3418,6 +3448,8 @@ mariannematthew.com: could not connect to host
marie-curie.fr: could not connect to host
marie-elisabeth.dk: did not receive HSTS header
marie-en-provence.com: did not receive HSTS header
marie.club: could not connect to host
marinazarza.es: could not connect to host
mario.party: did not receive HSTS header
markaconnor.com: could not connect to host
markayapilandirma.com: could not connect to host
@ -3425,7 +3457,6 @@ markcp.me: could not connect to host
market.android.com: did not receive HSTS header (error ignored - included regardless)
marketespace.fr: did not receive HSTS header
markorszulak.com: did not receive HSTS header
markprof.ru: could not connect to host
markrego.com: could not connect to host
marksill.com: could not connect to host
marktboten.de: did not receive HSTS header
@ -3484,9 +3515,7 @@ mcga.media: could not connect to host
mclab.su: could not connect to host
mclist.it: could not connect to host
mdfnet.se: did not receive HSTS header
mdkr.nl: did not receive HSTS header
mdscomp.net: did not receive HSTS header
meadowfen.farm: could not connect to host
meamod.com: max-age too low: 0
mechmk1.me: did not receive HSTS header
medallia.io: could not connect to host
@ -3604,7 +3633,7 @@ minikneet.nl: did not receive HSTS header
minimoo.se: could not connect to host
minnesotadata.com: could not connect to host
minora.io: could not connect to host
minoris.se: did not receive HSTS header
minoris.se: could not connect to host
miragrow.com: could not connect to host
mirindadomo.ru: did not receive HSTS header
mironized.com: did not receive HSTS header
@ -3619,6 +3648,7 @@ mizd.at: could not connect to host
mizi.name: could not connect to host
mk-dizajn.com: did not receive HSTS header
mkakh.xyz: did not receive HSTS header
mkcert.org: could not connect to host
mlcdn.co: could not connect to host
mlp.ee: could not connect to host
mlpepilepsy.org: could not connect to host
@ -3707,7 +3737,7 @@ moy.cat: did not receive HSTS header
mozart-game.cz: could not connect to host
mozartgame.cz: could not connect to host
mp3juices.is: could not connect to host
mpe.org: did not receive HSTS header
mpe.org: could not connect to host
mpintaamalabanna.it: could not connect to host
mqas.net: could not connect to host
mrawe.com: could not connect to host
@ -3811,6 +3841,7 @@ nanogi.ga: could not connect to host
nansay.cn: could not connect to host
nanto.eu: could not connect to host
narada.com.ua: could not connect to host
narrativasdigitais.pt: could not connect to host
nashira.cz: did not receive HSTS header
natalia-fadeeva.ru: could not connect to host
natalia.io: could not connect to host
@ -3837,6 +3868,7 @@ near.st: did not receive HSTS header
nebulousenhanced.com: could not connect to host
nedlinin.com: could not connect to host
nedzad.me: could not connect to host
neer.io: could not connect to host
neftaly.com: did not receive HSTS header
negativecurvature.net: could not connect to host
neilgreen.net: did not receive HSTS header
@ -3852,14 +3884,13 @@ neosolution.ca: did not receive HSTS header
nephos.xyz: did not receive HSTS header
nepustil.net: could not connect to host
nestedquotes.ca: could not connect to host
net-navi.cc: could not connect to host
net-navi.cc: max-age too low: 0
netbox.cc: could not connect to host
netherwind.eu: could not connect to host
netica.fr: could not connect to host
netlilo.com: could not connect to host
netloanusa.com: could not connect to host
netmagik.com: did not receive HSTS header
netmazk.net: could not connect to host
netresourcedesign.com: did not receive HSTS header
nettefoundation.com: could not connect to host
networx-online.de: could not connect to host
@ -3914,7 +3945,6 @@ nightwinds.tk: could not connect to host
niho.jp: did not receive HSTS header
nikcub.com: could not connect to host
niklaslindblad.se: did not receive HSTS header
nikolasbradshaw.com: did not receive HSTS header
nikomo.fi: did not receive HSTS header
ninchisho-online.com: did not receive HSTS header
ninhs.org: could not connect to host
@ -3999,7 +4029,6 @@ nwork.media: could not connect to host
nyantec.com: did not receive HSTS header
nycroth.com: did not receive HSTS header
nyffo.com: could not connect to host
nymphetomania.net: could not connect to host
nys-hk.com: could not connect to host
nysepho.pw: could not connect to host
nysifclaimcentral.com: did not receive HSTS header
@ -4015,19 +4044,19 @@ oblast45.ru: did not receive HSTS header
obsydian.org: could not connect to host
occentus.net: did not receive HSTS header
ochaken.cf: could not connect to host
octocat.ninja: could not connect to host
odin.xxx: could not connect to host
odinoffice.no: did not receive HSTS header
odysseyandco.com: could not connect to host
oe8.bet: could not connect to host
ofcourselanguages.com: could not connect to host
offenedialoge.de: max-age too low: 2592000
officeclub.com.mx: did not receive HSTS header
officeclub.com.mx: could not connect to host
offshore-firma.org: could not connect to host
ogogoshop.com: could not connect to host
oiepoie.nl: could not connect to host
oishioffice.com: did not receive HSTS header
okane.love: could not connect to host
okhrana.agency: did not receive HSTS header
okok-rent.com: could not connect to host
okok.rent: could not connect to host
okutama.in.th: could not connect to host
@ -4137,6 +4166,7 @@ othercode.nl: could not connect to host
othermedia.cc: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 118" data: no]
otherstuff.nl: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 118" data: no]
otichi.com: did not receive HSTS header
otorrino.pt: could not connect to host
ottospora.nl: could not connect to host
ourbank.com: did not receive HSTS header
ourevents.net: could not connect to host
@ -4211,7 +4241,7 @@ partyvan.nl: could not connect to host
partyvan.se: could not connect to host
passumpsicbank.com: did not receive HSTS header
passwordbox.com: did not receive HSTS header
passwordrevelator.net: did not receive HSTS header
passwordrevelator.net: could not connect to host
pastaf.com: could not connect to host
paste.linode.com: could not connect to host
pastebin.linode.com: could not connect to host
@ -4246,7 +4276,7 @@ pdf.yt: could not connect to host
peakapp.nl: could not connect to host
peerherrmann.de: could not connect to host
peetah.com: could not connect to host
peissen.com: could not connect to host
peissen.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 118" data: no]
pekkapikkarainen.fi: did not receive HSTS header
pekkarik.ru: could not connect to host
peliculasaudiolatinoonline.com: could not connect to host
@ -4305,7 +4335,6 @@ pilgermaske.org: did not receive HSTS header
piligrimname.com: could not connect to host
pillowandpepper.com: did not receive HSTS header
pimpmymac.ru: did not receive HSTS header
pincha.com.tw: could not connect to host
pinoyonlinetv.com: did not receive HSTS header
pippen.io: could not connect to host
piratebit.tech: could not connect to host
@ -4318,6 +4347,7 @@ pirateproxy.sx: could not connect to host
pirateproxy.vip: could not connect to host
pirati.cz: did not receive HSTS header
pirlitu.com: did not receive HSTS header
pirman.es: could not connect to host
pisexy.me: did not receive HSTS header
pisidia.de: could not connect to host
pitonarms.com: could not connect to host
@ -4345,6 +4375,7 @@ playmaker.io: could not connect to host
playmyplay.com: did not receive HSTS header
playnation.io: could not connect to host
playsharp.com: could not connect to host
pleasure.forsale: could not connect to host
pleier-it.de: did not receive HSTS header
pleier.it: did not receive HSTS header
plfgr.eu.org: could not connect to host
@ -4375,6 +4406,7 @@ pol.in.th: could not connect to host
pole.net.nz: could not connect to host
policeiwitness.sg: could not connect to host
polimat.org: could not connect to host
politic.org.ua: could not connect to host
politically-incorrect.xyz: could not connect to host
politologos.org: did not receive HSTS header
polycoise.com: could not connect to host
@ -4388,9 +4420,9 @@ poon.tech: could not connect to host
porno-gif.ru: did not receive HSTS header
pornstars.me: did not receive HSTS header
portalplatform.net: could not connect to host
portaluniversalista.org: could not connect to host
poshpak.com: max-age too low: 86400
postcodewise.co.uk: did not receive HSTS header
posterspy.com: did not receive HSTS header
postscheduler.org: could not connect to host
posylka.de: did not receive HSTS header
potatoheads.net: could not connect to host
@ -4400,7 +4432,6 @@ potsky.com: did not receive HSTS header
poussinooz.fr: could not connect to host
povitria.net: could not connect to host
power99press.com: did not receive HSTS header
powermeter.at: did not receive HSTS header
powerplannerapp.com: did not receive HSTS header
powershift.ne.jp: did not receive HSTS header
powerxequality.com: could not connect to host
@ -4497,10 +4528,12 @@ pwd.ovh: could not connect to host
pwnsdx.pw: could not connect to host
pwntr.com: could not connect to host
py.search.yahoo.com: did not receive HSTS header
pycrypto.org: could not connect to host
pyol.org: could not connect to host
pypi-status.org: could not connect to host
pyplo.org: did not receive HSTS header
pypt.lt: did not receive HSTS header
python-hyper.org: could not connect to host
q2.si: did not receive HSTS header
qbik.de: did not receive HSTS header
qccqld.org.au: could not connect to host
@ -4513,6 +4546,7 @@ qldconservation.org: could not connect to host
qonqa.de: did not receive HSTS header
qop.io: could not connect to host
qorm.co.uk: did not receive HSTS header
qqj.net: did not receive HSTS header
qqq.gg: could not connect to host
qrara.net: did not receive HSTS header
qrlending.com: did not receive HSTS header
@ -4597,6 +4631,8 @@ realmofespionage.com: could not connect to host
reaper.rip: could not connect to host
reardenporn.com: could not connect to host
rebekaesgabor.online: could not connect to host
receitas-de-bolos.pt: could not connect to host
receitasdebacalhau.pt: could not connect to host
recommended.reviews: could not connect to host
redable.hosting: could not connect to host
redar.xyz: could not connect to host
@ -4620,7 +4656,7 @@ rehabthailand.nl: could not connect to host
reic.me: could not connect to host
reikiqueen.uk: could not connect to host
reinaldudras.ee: did not receive HSTS header
reisyukaku.org: could not connect to host
reisyukaku.org: did not receive HSTS header
reithguard-it.de: did not receive HSTS header
rejo.in: could not connect to host
rejuvemedspa.com: did not receive HSTS header
@ -4721,6 +4757,7 @@ rolemaster.net: could not connect to host
rolroer.co.za: could not connect to host
romab.com: did not receive HSTS header
romans-place.me.uk: could not connect to host
romantic-quotes.co.uk: could not connect to host
romeoferraris.com: did not receive HSTS header
romulusapp.com: could not connect to host
ron2k.za.net: could not connect to host
@ -4906,6 +4943,7 @@ segulink.com: could not connect to host
sehenderson.com: did not receive HSTS header
seiko-dojo.com: could not connect to host
selecadm.name: could not connect to host
selectel.ru: did not receive HSTS header
selectruckscalltrackingreports.com: could not connect to host
selfcarecentral.com: did not receive HSTS header
selfdefenserx.com: did not receive HSTS header
@ -4927,7 +4965,7 @@ senseofnumber.co.uk: could not connect to host
sensiblemn.org: could not connect to host
sensibus.com: did not receive HSTS header
seo.consulting: did not receive HSTS header
seobot.com.au: could not connect to host
seobot.com.au: did not receive HSTS header
seomobo.com: could not connect to host
seosanantonioinc.com: did not receive HSTS header
seowarp.net: did not receive HSTS header
@ -5050,7 +5088,6 @@ skoda-clever-lead.de: could not connect to host
skotty.io: did not receive HSTS header
skullhouse.nyc: did not receive HSTS header
skyflix.me: could not connect to host
skynet233.ch: could not connect to host
skyoy.com: did not receive HSTS header
skyrunners.ch: could not connect to host
slanterns.net: could not connect to host
@ -5114,7 +5151,6 @@ socialhead.io: could not connect to host
socialhub.com: did not receive HSTS header
socialprize.com: could not connect to host
socialspirit.com.br: did not receive HSTS header
socioambiental.org: could not connect to host
sockeye.cc: could not connect to host
socomponents.co.uk: could not connect to host
sodacore.com: could not connect to host
@ -5134,7 +5170,6 @@ sonic.network: did not receive HSTS header
sonicrainboom.rocks: did not receive HSTS header
soobi.org: did not receive HSTS header
soondy.com: did not receive HSTS header
soph.us: could not connect to host
sosaka.ml: could not connect to host
sotor.de: did not receive HSTS header
soucorneteiro.com.br: could not connect to host
@ -5179,7 +5214,6 @@ spirit-dev.net: max-age too low: 0
spititout.it: could not connect to host
spittersberger.recipes: did not receive HSTS header
splunk.net: could not connect to host
spodelime.com: did not receive HSTS header
sponsortobias.com: could not connect to host
sportchirp-internal.azurewebsites.net: did not receive HSTS header
sporthit.ru: did not receive HSTS header
@ -5199,6 +5233,7 @@ srevilak.net: did not receive HSTS header
srmaximo.com: could not connect to host
srna.sk: could not connect to host
srrr.ca: could not connect to host
ss.lv: could not connect to host
ss.wtf: could not connect to host
ssl.panoramio.com: did not receive HSTS header
ssl.rip: could not connect to host
@ -5211,7 +5246,6 @@ ssworld.ga: could not connect to host
staack.com: could not connect to host
stabletoken.com: could not connect to host
stackfiles.io: could not connect to host
stacktile.io: did not receive HSTS header
stadjerspasonline.nl: could not connect to host
stadtbauwerk.at: did not receive HSTS header
staffjoy.com: did not receive HSTS header
@ -5314,6 +5348,7 @@ summitbankofkc.com: did not receive HSTS header
sumoatm.com: did not receive HSTS header
sumoscout.de: did not receive HSTS header
suncountrymarine.com: did not receive HSTS header
sunflyer.cn: did not receive HSTS header
sunfulong.me: could not connect to host
sunnyfruit.ru: could not connect to host
sunshinepress.org: could not connect to host
@ -5518,19 +5553,16 @@ thebrotherswarde.com: could not connect to host
thecapitalbank.com: did not receive HSTS header
thecharlestonwaldorf.com: did not receive HSTS header
theclementinebutchers.com: could not connect to host
thecloudrevolution.net: could not connect to host
theclubjersey.com: did not receive HSTS header
thecoffeehouse.xyz: could not connect to host
theelitebuzz.com: did not receive HSTS header
theendofzion.com: did not receive HSTS header
theescapistswiki.com: could not connect to host
theeyeopener.com: did not receive HSTS header
thefarbeyond.com: could not connect to host
theflowerbasketonline.com: could not connect to host
thefootballanalyst.com: did not receive HSTS header
thefrozenfire.com: did not receive HSTS header
thefutureharrills.com: could not connect to host
thegasshop.co.uk: could not connect to host
thegcccoin.com: did not receive HSTS header
thego2swatking.com: could not connect to host
thehiddenbay.eu: could not connect to host
@ -5565,7 +5597,6 @@ theworkingeye.nl: could not connect to host
thewp.pro: could not connect to host
thezonders.com: did not receive HSTS header
thierfreund.de: could not connect to host
thingies.site: could not connect to host
thinkcoding.de: could not connect to host
thinkcoding.org: could not connect to host
thinlyveiledcontempt.com: could not connect to host
@ -5616,7 +5647,7 @@ timotrans.de: did not receive HSTS header
timotrans.eu: did not receive HSTS header
timowi.de: could not connect to host
timowi.net: could not connect to host
timstoffel.net: could not connect to host
timstoffel.net: did not receive HSTS header
timwittenberg.com: could not connect to host
tinkerboard.org: could not connect to host
tipsyk.ru: could not connect to host
@ -5655,6 +5686,7 @@ tokoone.com: did not receive HSTS header
tollmanz.com: did not receive HSTS header
tolud.com: could not connect to host
tomeara.net: could not connect to host
tomend.es: could not connect to host
tomharris.tech: could not connect to host
tomlankhorst.nl: did not receive HSTS header
tomli.me: could not connect to host
@ -5700,6 +5732,7 @@ trafficmanager.xxx: did not receive HSTS header
traindb.nl: did not receive HSTS header
training4girls.ru: did not receive HSTS header
trainut.com: did not receive HSTS header
trajano.net: could not connect to host
transformify.org: did not receive HSTS header
translate.googleapis.com: did not receive HSTS header (error ignored - included regardless)
transportal.sk: did not receive HSTS header
@ -5746,7 +5779,7 @@ turtlementors.com: could not connect to host
tuturulianda.com: did not receive HSTS header
tuvalie.com: could not connect to host
tuxcall.de: could not connect to host
tuxcloud.net: could not connect to host
tuxflow.de: could not connect to host
tuxz.net: did not receive HSTS header
tv.search.yahoo.com: could not connect to host
tvtubeflix.com: did not receive HSTS header
@ -5809,7 +5842,10 @@ umwandeln-online.de: could not connect to host
unart.info: could not connect to host
unbanthe.net: could not connect to host
unblocked-networks.org: could not connect to host
unblocked.date: did not receive HSTS header
unblocked.faith: did not receive HSTS header
unblocked.host: could not connect to host
unblocked.party: did not receive HSTS header
unblocked.today: did not receive HSTS header
unblocked.win: could not connect to host
unblocked.works: did not receive HSTS header
@ -5849,6 +5885,7 @@ upaknship.com: did not receive HSTS header
upboard.jp: could not connect to host
upldr.pw: could not connect to host
uporoops.com: could not connect to host
upr.com.ua: could not connect to host
uprotect.it: could not connect to host
upstats.eu: could not connect to host
ur-lauber.de: did not receive HSTS header
@ -5922,6 +5959,7 @@ verifikatorindonesia.com: could not connect to host
vermontcareergateway.org: could not connect to host
versia.ru: did not receive HSTS header
veryhax.de: could not connect to host
ves.vn.ua: could not connect to host
vestacp.top: could not connect to host
vetdnacenter.com: did not receive HSTS header
veterinaire-cazeres-foucault.fr: could not connect to host
@ -5958,6 +5996,7 @@ vipmusic.ga: could not connect to host
virginiacrimeanalysisnetwork.org: did not receive HSTS header
visitbroadstairs.com: could not connect to host
vissanum.com: did not receive HSTS header
vistaalmar.es: could not connect to host
vistarait.com: did not receive HSTS header
vitagenda.nl: could not connect to host
vitalita.cz: did not receive HSTS header
@ -5973,6 +6012,7 @@ vlastimilburian.cz: did not receive HSTS header
vlora.city: could not connect to host
vm0.eu: did not receive HSTS header
vmrdev.com: could not connect to host
vmug.pl: could not connect to host
voceinveste.com: did not receive HSTS header
voicesuk.co.uk: did not receive HSTS header
volcrado.com: did not receive HSTS header
@ -6104,6 +6144,7 @@ whatsstalk.me: could not connect to host
whatsyouroffer.co.uk: did not receive HSTS header
when-release.com: did not receive HSTS header
whisker.network: could not connect to host
whitehat.id: could not connect to host
whiterabbit.org: did not receive HSTS header
whiterabbitcakery.com: could not connect to host
whitestagforge.com: did not receive HSTS header
@ -6175,7 +6216,6 @@ workpermit.com.vn: could not connect to host
workwithgo.com: could not connect to host
worldsbeststory.com: did not receive HSTS header
worldwhisperer.net: did not receive HSTS header
wormdisk.net: could not connect to host
worshapp.com: could not connect to host
wowapi.org: could not connect to host
wpblog.com.tw: did not receive HSTS header
@ -6238,7 +6278,6 @@ xellos.ga: could not connect to host
xellos.ml: could not connect to host
xendo.net: did not receive HSTS header
xenesisziarovky.sk: could not connect to host
xenophile.name: could not connect to host
xett.com: did not receive HSTS header
xf-liam.com: did not receive HSTS header
xfive.de: did not receive HSTS header
@ -6262,6 +6301,7 @@ xn--4dbjwf8c.cf: could not connect to host
xn--4dbjwf8c.ga: could not connect to host
xn--4dbjwf8c.gq: could not connect to host
xn--4dbjwf8c.tk: could not connect to host
xn--6cv66l79sp0n0ibo7s9ne.xyz: did not receive HSTS header
xn--79q87uvkclvgd56ahq5a.net: did not receive HSTS header
xn--7rvz7ku3ppnr.jp: did not receive HSTS header
xn--80aaihqncaejjobbu6v.xn--p1ai: max-age too low: 10000
@ -6289,6 +6329,7 @@ xom.party: could not connect to host
xor-a.net: could not connect to host
xperiacodes.com: did not receive HSTS header
xpi.fr: could not connect to host
xqin.net: could not connect to host
xsmobile.de: could not connect to host
xtom.email: could not connect to host
xtream-hosting.com: could not connect to host
@ -6326,7 +6367,6 @@ yenniferallulli.nl: could not connect to host
yestees.com: did not receive HSTS header
yetcore.io: could not connect to host
yetii.net: could not connect to host
yhori.xyz: could not connect to host
yhrd.org: did not receive HSTS header
yikzu.cn: could not connect to host
yin.roma.it: did not receive HSTS header
@ -6336,7 +6376,6 @@ yjsoft.me: did not receive HSTS header
ynode.co: did not receive HSTS header
ynsn.nl: did not receive HSTS header
yoga.is-an-engineer.com: could not connect to host
yohanesmario.com: could not connect to host
yokeepo.com: max-age too low: 0
yoloboatrentals.com: did not receive HSTS header
yoloprod.fr: could not connect to host
@ -6413,6 +6452,8 @@ zinc-x.com: did not receive HSTS header
zinenapse.info: could not connect to host
zirtue.io: did not receive HSTS header
zittingskalender.be: could not connect to host
zivy-ruzenec.cz: could not connect to host
zivyruzenec.cz: could not connect to host
ziyuanabc.xyz: could not connect to host
zizoo.com: did not receive HSTS header
zju.tv: could not connect to host
@ -6423,7 +6464,6 @@ zkillboard.com: did not receive HSTS header
zking.ga: could not connect to host
zmsastro.co.za: could not connect to host
zmy.im: did not receive HSTS header
znation.nl: could not connect to host
zocken.com: did not receive HSTS header
zoe.vc: could not connect to host
zohar.link: could not connect to host

File diff suppressed because it is too large Load Diff

View File

@ -413,7 +413,7 @@ public:
#if defined(MOZ_GECKO_PROFILER)
static void DoStackCapture(const nsACString& aKey);
#endif
static void RecordThreadHangStats(Telemetry::ThreadHangStats& aStats);
static void RecordThreadHangStats(Telemetry::ThreadHangStats&& aStats);
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf);
struct Stat {
uint32_t hitCount;
@ -1479,11 +1479,6 @@ CreateJSThreadHangStats(JSContext* cx, const Telemetry::ThreadHangStats& thread)
return nullptr;
}
// Create a CombinedStacks instance which will contain all of the stacks
// collected by the BHR. Specify a custom maxStacksCount to ensure that all of
// our native hang stacks fit.
CombinedStacks combinedStacks(Telemetry::kMaximumNativeHangStacks);
// Process the hangs into a hangs object.
JS::RootedObject hangs(cx, JS_NewArrayObject(cx, 0));
if (!hangs) {
@ -1495,13 +1490,9 @@ CreateJSThreadHangStats(JSContext* cx, const Telemetry::ThreadHangStats& thread)
return nullptr;
}
// Check if we have a native stack, and if we do, add it to combinedStacks,
// and store its index in the 'nativeStack' member of the hang object.
const Telemetry::NativeHangStack& stack = thread.mHangs[i].GetNativeStack();
if (!stack.empty() &&
combinedStacks.GetStackCount() < Telemetry::kMaximumNativeHangStacks) {
Telemetry::ProcessedStack processed = Telemetry::GetStackAndModules(stack);
uint32_t index = combinedStacks.AddStack(processed);
// Check if we have a cached native stack index, and if we do record it.
uint32_t index = thread.mHangs[i].GetNativeStackIndex();
if (index != Telemetry::HangHistogram::NO_NATIVE_STACK_INDEX) {
if (!JS_DefineProperty(cx, obj, "nativeStack", index, JSPROP_ENUMERATE)) {
return nullptr;
}
@ -1515,7 +1506,9 @@ CreateJSThreadHangStats(JSContext* cx, const Telemetry::ThreadHangStats& thread)
return nullptr;
}
JS::RootedObject fullReportObj(cx, CreateJSStackObject(cx, combinedStacks));
// We should already have a CombinedStacks object on the ThreadHangStats, so
// add that one.
JS::RootedObject fullReportObj(cx, CreateJSStackObject(cx, thread.mCombinedStacks));
if (!fullReportObj) {
return nullptr;
}
@ -2095,7 +2088,7 @@ TelemetryImpl::CaptureStack(const nsACString& aKey) {
}
void
TelemetryImpl::RecordThreadHangStats(Telemetry::ThreadHangStats& aStats)
TelemetryImpl::RecordThreadHangStats(Telemetry::ThreadHangStats&& aStats)
{
if (!sTelemetry || !TelemetryHistogram::CanRecordExtended())
return;
@ -2791,9 +2784,9 @@ void CaptureStack(const nsACString& aKey)
}
#endif
void RecordThreadHangStats(ThreadHangStats& aStats)
void RecordThreadHangStats(ThreadHangStats&& aStats)
{
TelemetryImpl::RecordThreadHangStats(aStats);
TelemetryImpl::RecordThreadHangStats(Move(aStats));
}

View File

@ -343,7 +343,7 @@ class ThreadHangStats;
* will be moved and aStats should be treated as
* invalid after this function returns
*/
void RecordThreadHangStats(ThreadHangStats& aStats);
void RecordThreadHangStats(ThreadHangStats&& aStats);
/**
* Record a failed attempt at locking the user's profile.

View File

@ -13,6 +13,7 @@
#include "mozilla/Mutex.h"
#include "mozilla/PodOperations.h"
#include "mozilla/Vector.h"
#include "mozilla/CombinedStacks.h"
#include "nsString.h"
#include "prinrval.h"
@ -162,12 +163,20 @@ public:
hang, along with a time histogram of the hang times. */
class HangHistogram : public TimeHistogram
{
public:
// Value used for mNativeStackIndex to represent the absence of a cached
// native stack.
static const uint32_t NO_NATIVE_STACK_INDEX = UINT32_MAX;
private:
static uint32_t GetHash(const HangStack& aStack);
HangStack mStack;
// Native stack that corresponds to the pseudostack in mStack
NativeHangStack mNativeStack;
// Cached index of the native stack in the mCombinedStacks list in the owning
// ThreadHangStats object. A default value of NO_NATIVE_STACK_INDEX means that
// the ThreadHangStats object which owns this HangHistogram doesn't have a
// cached CombinedStacks with this HangHistogram in it.
uint32_t mNativeStackIndex;
// Use a hash to speed comparisons
const uint32_t mHash;
// Annotations attributed to this stack
@ -176,14 +185,7 @@ private:
public:
explicit HangHistogram(HangStack&& aStack)
: mStack(mozilla::Move(aStack))
, mHash(GetHash(mStack))
{
}
explicit HangHistogram(HangStack&& aStack,
NativeHangStack&& aNativeStack)
: mStack(mozilla::Move(aStack))
, mNativeStack(mozilla::Move(aNativeStack))
, mNativeStackIndex(NO_NATIVE_STACK_INDEX)
, mHash(GetHash(mStack))
{
}
@ -191,7 +193,7 @@ public:
HangHistogram(HangHistogram&& aOther)
: TimeHistogram(mozilla::Move(aOther))
, mStack(mozilla::Move(aOther.mStack))
, mNativeStack(mozilla::Move(aOther.mNativeStack))
, mNativeStackIndex(mozilla::Move(aOther.mNativeStackIndex))
, mHash(mozilla::Move(aOther.mHash))
, mAnnotations(mozilla::Move(aOther.mAnnotations))
{
@ -204,11 +206,12 @@ public:
const HangStack& GetStack() const {
return mStack;
}
NativeHangStack& GetNativeStack() {
return mNativeStack;
uint32_t GetNativeStackIndex() const {
return mNativeStackIndex;
}
const NativeHangStack& GetNativeStack() const {
return mNativeStack;
void SetNativeStackIndex(uint32_t aIndex) {
MOZ_ASSERT(aIndex != NO_NATIVE_STACK_INDEX);
mNativeStackIndex = aIndex;
}
const HangMonitor::HangAnnotationsVector& GetAnnotations() const {
return mAnnotations;
@ -228,6 +231,7 @@ public:
- time histogram of all task run times
- hang histograms of individual hangs
- annotations for each hang
- combined native stacks for all hangs
*/
class ThreadHangStats
{
@ -238,10 +242,12 @@ public:
TimeHistogram mActivity;
mozilla::Vector<HangHistogram, 4> mHangs;
uint32_t mNativeStackCnt;
CombinedStacks mCombinedStacks;
explicit ThreadHangStats(const char* aName)
: mName(aName)
, mNativeStackCnt(0)
, mCombinedStacks(Telemetry::kMaximumNativeHangStacks)
{
}
ThreadHangStats(ThreadHangStats&& aOther)
@ -249,6 +255,7 @@ public:
, mActivity(mozilla::Move(aOther.mActivity))
, mHangs(mozilla::Move(aOther.mHangs))
, mNativeStackCnt(aOther.mNativeStackCnt)
, mCombinedStacks(mozilla::Move(aOther.mCombinedStacks))
{
aOther.mNativeStackCnt = 0;
}

View File

@ -45,6 +45,7 @@ EXPORTS.mozilla += [
'!TelemetryHistogramEnums.h',
'!TelemetryProcessEnums.h',
'!TelemetryScalarEnums.h',
'CombinedStacks.h',
'ipc/TelemetryComms.h',
'ipc/TelemetryIPC.h',
'ProcessedStack.h',

View File

@ -1460,7 +1460,6 @@ nsWindow::nsWindow() :
mScreenId(0), // Use 0 (primary screen) as the default value.
mIsVisible(false),
mParent(nullptr),
mAwaitingFullScreen(false),
mIsFullScreen(false)
{
}
@ -1764,12 +1763,6 @@ nsWindow::Resize(double aX,
// Should we skip honoring aRepaint here?
if (aRepaint && FindTopLevel() == nsWindow::TopWindow())
RedrawAll();
nsIWidgetListener* listener = GetWidgetListener();
if (mAwaitingFullScreen && listener) {
listener->FullscreenChanged(mIsFullScreen);
mAwaitingFullScreen = false;
}
}
void
@ -1925,9 +1918,13 @@ nsWindow::MakeFullScreen(bool aFullScreen, nsIScreen*)
}
mIsFullScreen = aFullScreen;
mAwaitingFullScreen = true;
mAndroidView->mEventDispatcher->Dispatch(aFullScreen ?
u"GeckoView:FullScreenEnter" : u"GeckoView:FullScreenExit");
nsIWidgetListener* listener = GetWidgetListener();
if (listener) {
listener->FullscreenChanged(mIsFullScreen);
}
return NS_OK;
}

View File

@ -340,7 +340,6 @@ protected:
nsCOMPtr<nsIIdleServiceInternal> mIdleService;
bool mAwaitingFullScreen;
bool mIsFullScreen;
bool UseExternalCompositingSurface() const override {

View File

@ -162,6 +162,26 @@ public:
mozilla::fallible));
}
/**
* Get the entry associated with a key, or create a new entry using infallible
* allocation and insert that.
* @param aKey the key to retrieve
* @param aEntry will be assigned (if non-null) to the entry that was found
* or created
* @return true if a new entry was created, or false if an existing entry
* was found
*/
MOZ_MUST_USE
bool EnsureInserted(KeyType aKey, EntryType** aEntry = nullptr)
{
auto oldCount = Count();
EntryType* entry = PutEntry(aKey);
if (aEntry) {
*aEntry = entry;
}
return oldCount != Count();
}
/**
* Remove the entry associated with a key.
* @param aKey of the entry to remove
@ -171,6 +191,23 @@ public:
mTable.Remove(EntryType::KeyToPointer(aKey));
}
/**
* Lookup the entry associated with aKey and remove it if found, otherwise
* do nothing.
* @param aKey of the entry to remove
* @return true if an entry was found and removed, or false if no entry
* was found for aKey
*/
bool EnsureRemoved(KeyType aKey)
{
auto* entry = GetEntry(aKey);
if (entry) {
RemoveEntry(entry);
return true;
}
return false;
}
/**
* Remove the entry associated with a key.
* @param aEntry the entry-pointer to remove (obtained from GetEntry)
@ -493,7 +530,6 @@ public:
nsTHashtable(nsTHashtable&&) = default;
/* Wrapper functions */
using Base::GetGeneration;
using Base::Count;
using Base::IsEmpty;
@ -506,6 +542,7 @@ public:
using Base::MarkImmutable;
#endif
/* Wrapper functions */
EntryType* GetEntry(T* aKey) const
{
return reinterpret_cast<EntryType*>(Base::GetEntry(aKey));
@ -528,11 +565,22 @@ public:
Base::PutEntry(aKey, mozilla::fallible));
}
MOZ_MUST_USE
bool EnsureInserted(T* aKey, EntryType** aEntry = nullptr)
{
return Base::EnsureInserted(aKey, reinterpret_cast<::detail::VoidPtrHashKey**>(aEntry));
}
void RemoveEntry(T* aKey)
{
Base::RemoveEntry(aKey);
}
bool EnsureRemoved(T* aKey)
{
return Base::EnsureRemoved(aKey);
}
void RemoveEntry(EntryType* aEntry)
{
Base::RemoveEntry(reinterpret_cast<::detail::VoidPtrHashKey*>(aEntry));

View File

@ -14,6 +14,7 @@
#include "mozilla/Telemetry.h"
#include "mozilla/ThreadHangStats.h"
#include "mozilla/ThreadLocal.h"
#include "mozilla/SystemGroup.h"
#include "prinrval.h"
#include "prthread.h"
@ -24,6 +25,7 @@
#include "nsThreadUtils.h"
#include "nsXULAppAPI.h"
#include "GeckoProfiler.h"
#include "nsNetCID.h"
#include <algorithm>
@ -46,6 +48,8 @@ bool StackScriptEntriesCollapser(const char* aStackEntry, const char *aAnotherSt
namespace mozilla {
class ProcessHangRunnable;
/**
* BackgroundHangManager is the global object that
* manages all instances of BackgroundHangThread.
@ -88,6 +92,10 @@ public:
PRIntervalTime mIntervalNow;
// List of BackgroundHangThread instances associated with each thread
LinkedList<BackgroundHangThread> mHangThreads;
// A reference to the StreamTransportService. This is gotten on the main
// thread, and carried around, as nsStreamTransportService::Init is
// non-threadsafe.
nsCOMPtr<nsIEventTarget> mSTS;
void Shutdown()
{
@ -188,14 +196,18 @@ public:
UniquePtr<HangMonitor::HangAnnotations> mAnnotations;
// Annotators registered for this thread
HangMonitor::Observer::Annotators mAnnotators;
// List of runnables which can hold a reference to us which need to be
// canceled before we can go away.
LinkedList<RefPtr<ProcessHangRunnable>> mProcessHangRunnables;
BackgroundHangThread(const char* aName,
uint32_t aTimeoutMs,
uint32_t aMaxTimeoutMs,
BackgroundHangMonitor::ThreadType aThreadType = BackgroundHangMonitor::THREAD_SHARED);
// Report a hang; aManager->mLock IS locked
Telemetry::HangHistogram& ReportHang(PRIntervalTime aHangTime);
// Report a hang; aManager->mLock IS locked. The hang will be processed
// off-main-thread, and will then be submitted back.
void ReportHang(PRIntervalTime aHangTime);
// Report a permanent hang; aManager->mLock IS locked
void ReportPermaHang();
// Called by BackgroundHangMonitor::NotifyActivity
@ -235,9 +247,11 @@ BackgroundHangManager::BackgroundHangManager()
: mShutdown(false)
, mLock("BackgroundHangManager")
, mIntervalNow(0)
, mSTS(do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID))
{
// Lock so we don't race against the new monitor thread
MonitorAutoLock autoLock(mLock);
mHangMonitorThread = PR_CreateThread(
PR_USER_THREAD, MonitorThread, this,
PR_PRIORITY_LOW, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
@ -417,6 +431,93 @@ BackgroundHangThread::BackgroundHangThread(const char* aName,
autoLock.Notify();
}
// This runnable is used to pre-process a hang, performing any expensive
// operations on it, before submitting it into the BackgroundHangThread object
// for Telemetry.
//
// If this object is canceled, it will submit its payload to the
// BackgroundHangThread without performing the processing.
class ProcessHangRunnable final
: public CancelableRunnable
, public LinkedListElement<RefPtr<ProcessHangRunnable>>
{
public:
ProcessHangRunnable(BackgroundHangManager* aManager,
BackgroundHangThread* aThread,
Telemetry::HangHistogram&& aHistogram,
Telemetry::NativeHangStack&& aNativeStack)
: mManager(aManager)
, mNativeStack(mozilla::Move(aNativeStack))
, mThread(aThread)
, mHistogram(mozilla::Move(aHistogram))
{
MOZ_ASSERT(mThread);
}
NS_IMETHOD
Run() override
{
// Start processing this histogram's native hang stack before we try to lock
// anything, as we can do this without any locks held. This is the expensive
// part of the operation.
Telemetry::ProcessedStack processed;
if (!mNativeStack.empty()) {
processed = Telemetry::GetStackAndModules(mNativeStack);
}
// Lock the manager's lock, so that we can take a look at our mThread
{
MonitorAutoLock autoLock(mManager->mLock);
if (NS_WARN_IF(!mThread)) {
return NS_OK;
}
// If we have a stack, check if we can add it to combined stacks. This is
// a relatively cheap operation, and must occur with the lock held.
if (!mNativeStack.empty() &&
mThread->mStats.mCombinedStacks.GetStackCount() < Telemetry::kMaximumNativeHangStacks) {
mHistogram.SetNativeStackIndex(mThread->mStats.mCombinedStacks.AddStack(processed));
}
// Submit, remove ourselves from the list, and clear out mThread so we
// don't run again.
MOZ_ALWAYS_TRUE(mThread->mStats.mHangs.append(Move(mHistogram)));
remove();
mThread = nullptr;
}
return NS_OK;
}
// Submits hang, and removes from list.
nsresult
Cancel() override
{
mManager->mLock.AssertCurrentThreadOwns();
if (NS_WARN_IF(!mThread)) {
return NS_OK;
}
// Submit, remove ourselves from the list, and clear out mThread so we
// don't run again.
MOZ_ALWAYS_TRUE(mThread->mStats.mHangs.append(Move(mHistogram)));
if (isInList()) {
remove();
}
mThread = nullptr;
return NS_OK;
}
private:
// These variables are constant after initialization, and do not need
// synchronization.
RefPtr<BackgroundHangManager> mManager;
const Telemetry::NativeHangStack mNativeStack;
// These variables are guarded by mManager->mLock.
BackgroundHangThread* MOZ_NON_OWNING_REF mThread; // Will Cancel us before it dies
Telemetry::HangHistogram mHistogram;
};
BackgroundHangThread::~BackgroundHangThread()
{
// Lock here because LinkedList is not thread-safe
@ -431,11 +532,18 @@ BackgroundHangThread::~BackgroundHangThread()
sTlsKey.set(nullptr);
}
// Move our copy of ThreadHangStats to Telemetry storage
Telemetry::RecordThreadHangStats(mStats);
// Cancel any remaining process hang runnables, as they hold a weak reference
// into our mStats variable, which we're about to move.
while (RefPtr<ProcessHangRunnable> runnable = mProcessHangRunnables.popFirst()) {
runnable->Cancel();
}
// Record the ThreadHangStats for this thread before we go away. All stats
// should be in this method now, as we canceled any pending runnables.
Telemetry::RecordThreadHangStats(Move(mStats));
}
Telemetry::HangHistogram&
void
BackgroundHangThread::ReportHang(PRIntervalTime aHangTime)
{
// Recovered from a hang; called on the monitor thread
@ -465,21 +573,30 @@ BackgroundHangThread::ReportHang(PRIntervalTime aHangTime)
mHangStack.erase(mHangStack.begin() + 1, mHangStack.begin() + elementsToRemove);
}
Telemetry::HangHistogram newHistogram(Move(mHangStack), Move(mNativeHangStack));
Telemetry::HangHistogram newHistogram(Move(mHangStack));
for (Telemetry::HangHistogram* oldHistogram = mStats.mHangs.begin();
oldHistogram != mStats.mHangs.end(); oldHistogram++) {
if (newHistogram == *oldHistogram) {
// New histogram matches old one
oldHistogram->Add(aHangTime, Move(mAnnotations));
return *oldHistogram;
return;
}
}
// Add new histogram
newHistogram.Add(aHangTime, Move(mAnnotations));
if (!mStats.mHangs.append(Move(newHistogram))) {
MOZ_CRASH();
// Process the hang off-main thread. We record a reference to the runnable in
// mProcessHangRunnables so we can abort this preprocessing and just submit
// the message if the processing takes too long and our thread is going away.
RefPtr<ProcessHangRunnable> processHang =
new ProcessHangRunnable(mManager, this, Move(newHistogram), Move(mNativeHangStack));
mProcessHangRunnables.insertFront(processHang);
// Try to dispatch the runnable to the StreamTransportService threadpool. If
// we fail, cancel our runnable.
if (!mManager->mSTS || NS_FAILED(mManager->mSTS->Dispatch(processHang.forget()))) {
RefPtr<ProcessHangRunnable> runnable = mProcessHangRunnables.popFirst();
runnable->Cancel();
}
return mStats.mHangs.back();
}
void
@ -488,14 +605,13 @@ BackgroundHangThread::ReportPermaHang()
// Permanently hanged; called on the monitor thread
// mManager->mLock IS locked
Telemetry::HangHistogram& hang = ReportHang(mMaxTimeout);
Telemetry::NativeHangStack& stack = hang.GetNativeStack();
if (stack.empty()) {
mStats.mNativeStackCnt += 1;
if (mStats.mNativeStackCnt <= Telemetry::kMaximumNativeHangStacks) {
mStackHelper.GetNativeStack(stack);
}
}
// NOTE: We used to capture a native stack in this situation if one had not
// already been captured, but with the new ReportHang design that is less
// practical.
//
// We currently don't look at hang reports outside of nightly, and already
// collect native stacks eagerly on nightly, so this should be OK.
ReportHang(mMaxTimeout);
}
MOZ_ALWAYS_INLINE void
@ -587,6 +703,7 @@ BackgroundHangMonitor::DisableOnBeta() {
void
BackgroundHangMonitor::Startup()
{
MOZ_RELEASE_ASSERT(NS_IsMainThread());
#ifdef MOZ_ENABLE_BACKGROUND_HANG_MONITOR
MOZ_ASSERT(!BackgroundHangManager::sInstance, "Already initialized");

View File

@ -370,6 +370,11 @@ NS_IdleDispatchToCurrentThread(already_AddRefed<nsIRunnable>&& aEvent,
{
nsCOMPtr<nsIRunnable> event(Move(aEvent));
NS_ENSURE_TRUE(event, NS_ERROR_INVALID_ARG);
//XXX Using current thread for now as the nsIEventTarget.
nsIEventTarget* target = mozilla::GetCurrentThreadEventTarget();
NS_ENSURE_STATE(target);
nsCOMPtr<nsIIdleRunnable> idleEvent = do_QueryInterface(event);
if (!idleEvent) {
@ -377,9 +382,7 @@ NS_IdleDispatchToCurrentThread(already_AddRefed<nsIRunnable>&& aEvent,
event = do_QueryInterface(idleEvent);
MOZ_DIAGNOSTIC_ASSERT(event);
}
//XXX Using current thread for now as the nsIEventTarget.
idleEvent->SetTimer(aTimeout, NS_GetCurrentThread());
idleEvent->SetTimer(aTimeout, target);
return NS_IdleDispatchToCurrentThread(event.forget());
}